Sunday, June 5, 2016

41: Stepper Motors

I have a mad urge to build an interactive amusement for the left-at-home dogs in my extended family. Yeah, I know other people have-done/are-doing this. So what. Details at http://dicks-raspberry-pi.blogspot.com/, post 99.

Anyway, one feature has to be the ability of the device to spit out doggie treats. I expect the main computer for this will be a Raspberry Pi. And I started stepper programming in Python on the Pi but realized quickly that precise timing is a problem again. Mostly because I want to be able to calibrate the motor position using a photo sensor. Reading such a sensor on the non-analog Pi is slow. So I'll add an Arduino for the motor and the photo sensor chore.

Stepper 28BYJ-48 5V DC + ULN2003 Driver Board
-- don't buy without the driver board --
(otherwise the wiring will drive you nuts)

Here's some C++ I'm currently using (9th try from downloaded sources, I forget which):

int motorPin1 = 8;    // Blue   - 28BYJ48 pin 1
int motorPin2 = 9;    // Pink   - 28BYJ48 pin 2
int motorPin3 = 10;    // Yellow - 28BYJ48 pin 3
int motorPin4 = 11;    // Orange - 28BYJ48 pin 4
                       // Red    - 28BYJ48 pin 5 (VCC), not used
int bits[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};

int photo = A5;

void setup() {
  //declare the motor pins as outputs
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);
  Serial.begin(9600);
  pinMode(photo, INPUT);
}

char ch;

void loop() {
  // wait for any typed character
  if(!Serial.available()) return;
  ch = Serial.read();
  spr(ch);
  clockwise(128); // not exactly 1 rotation
  delay(1000);
  anticlockwise(128);
  delay(1000);
}

void clockwise(int n) {
  for(int j = 0; j < n; ++j) {
    for(int i = 7; i >= 0; i--) {
      setOutput(i);
      delay(2);
    }
  }
}

void anticlockwise(int n) {
  for(int j = 0; j < n; ++j) {
    for(int i = 0; i < 8; i++) {
      setOutput(i);
      // read photo pin & stop on overrun
      delay(2);
    }
  }
}
void setOutput(int out)
{
  digitalWrite(motorPin1, bitRead(bits[out], 0));
  digitalWrite(motorPin2, bitRead(bits[out], 1));
  digitalWrite(motorPin3, bitRead(bits[out], 2));
  digitalWrite(motorPin4, bitRead(bits[out], 3));
}
==============
To be added to Arduino code: serial command from the Pi.

Question: anyone know how to change the steps per rotation?