Thursday, October 31, 2013

Arduino Round V: Light Seeking Robot

Having received a stepper motor in the mail the other day, I started playing around with the built in stepper motor library, "stepper.h". Using a dual H-Bridge drive that can source and sink current

Stepper motor(768, in1Pin, in2Pin, in3Pin, in4Pin); // These pins are the outputs from the arduino. '768, refers to then number of steps per full motor rotation
motor.setSpeed(speed); // After about a speed of 20, it barfs
motor.step(N); // With a bipolar driver, a positive or negative N can be used for clockwise/counter clockwise rotation

The project I decided on to have a little fun with the motor was a "light-seeking robot". The robot would have a left and right eye (photoresistors) and would rotate via the stepper motor until both eyes measured equal brightness.

To accomplish this, we can subtract the right-eye's voltage from the left-eye's voltage to for an error signal. If there is more light to the right than to the left, a positive error signal results and the motor turns right. If the left side is brighter, the difference is negative and the motor turns left. At some point, the difference goes to zero at which point the motor doesn't turn at all. Furthermore, as the balance gets better, and the difference gets smaller, the robot slows down and smoothly approaches the Goldie-Locks amount of light on each eye. On the other hand, when the balance is way off, the error signal is huge and the motor corrects more strongly, a situation known as proportional feedback. If the motor had some inertia we'd have to add a little lag (integration) to the loop so that the robot didn't overshoot when it got to zero and oscillate back and forth but for a stepper motor, which is heavily damped, this is not a problem.
 
The eyes of the circuit are shown here: the photodiodes each are part of a voltage divider which go to separate arduino inputs. The eyes are attached to a decapitated lego figure (you gotta use what you got) whose rectangular feet fit nicely into the stepper motor.


The motor is driven by the following code:
#include "stepperh.h"

int in1Pin = 4;
int in2Pin = 5;
int in3Pin = 6;
int in4Pin = 7;

const int LEFT = A0;  // Analog input pin
const int RIGHT = A1;  // Analog input pin
int vL = 0;
int vR = 0;

int j = 1;
int m = 1; // polarity. If turning the wrong way, switch sign
int speed = 20;

Stepper motor(768, in1Pin, in2Pin, in3Pin, in4Pin);

void setup()
{
  Serial.begin(9600);
  pinMode(in1Pin, OUTPUT);
  pinMode(in2Pin, OUTPUT);
  pinMode(in3Pin, OUTPUT);
  pinMode(in4Pin, OUTPUT);
  pinMode(LEFT, INPUT);
  pinMode(RIGHT, INPUT);  
  
  motor.setSpeed(speed);
}

void loop()
{
  vL = analogRead(LEFT); // 0-5v <-> 0-1023
  vR = analogRead(RIGHT); // 0-5v <-> 0-1023
  Serial.print("Left = ");Serial.print(vL);  // Log the measured values for debugging
  Serial.print(", Right = ");Serial.print(vR); 
  Serial.print(", Difference = ");Serial.print(vR-vL);
  Serial.print("\n");
  motor.step(m*(vR-vL));
  delay(250);    // update at 4 Hz
}

The circuit layout is sketched here:



... and here's a video of the light seeking robot seeking light:


No comments:

Post a Comment