Arduino Photovore Tutorial?

Hey buds, so i made the jump from Picaxe to Arduino and Im trying to relearn basic programming. Has anyone seen a detailed tutorial on making a simple phtotvore? Im walking through this with my little bro and its hard to figure things out. I tried looking aorund  but have yet to find a nicely documented build.... maybe Im just missing it. 

 

Trying not to be a bother, just looking to get the ball rolling on building bots with Arduino! Thanks LMR!!!

I believe I saw you say you have a motor driver shield

in the shout box. Could you let us know what shield it is?

Once you have told us what motor shield you have we could help you figure out the rest of the process.

While you are working on that, how about learning to check the values you are getting from an LDR (light dependent resistor) connected to an analog input as a voltage divider with a standard resistor. You will need a pair of those circuits set up. Once you start understanding the numbers you are getting you can begin to write your program. It will boil down to setting up a function to read your LDRs, and then, using the input to influence your robot to respond; forward, reverse, left, right.

It will be something along the lines of:

loop() {
   leftSensor = analogRead(leftSensorPin);
   rightSensor = analogRead(rightSensorPin);

   if ((leftSensor == rightSensor) && (leftSensor >= brightEnough)) { // thanks to mogul for catching my error it was == before >=
      move(255,255);
   }

   if ((leftSensor == rightSensor) && (leftSensor <= dark)) { // thanks to mogul for catching my error it was == before <=
      move(0,0);
   }

   if (leftSensor > rightSensor) {
      move(0,255);
   }

   if (leftSensor < rightSensor) {
      move(255,0);
   }
}

void move(int A, int B) {
   int newA, newB;

//motorA moves forward
   if (A > 128) {
      newA = map(A, 129, 255, 1, 255);
      analogWrite(enableA, newA);
      digitalWrite(motorA1, 1);
      digitalWrite(motorA2, 0);
   }

//motorA moves in reverse
   if (A <= 127) {
      newA = map(A, 127, 0, 1, 255);
      analogWrite(enableA, newA);
      digitalWrite(motorA1, 0);
      digitalWrite(motorA2, 1);
   }

 

//motorB moves forward
   if (B > 128) {
      newB = map(B, 129, 255, 1, 255);
      analogWrite(enableB, newB);
      digitalWrite(motorB1, 1);
      digitalWrite(motorB2, 0);
   }

//motorB moves in reverse
   if (B <= 127) {
      newB = map(B, 127, 0, 1, 255);
      analogWrite(enableB, newB);
      digitalWrite(motorB1, 0);
      digitalWrite(motorB2, 1);
   }

//stop the motor/s
   if (A == 128) {
      analogWrite(enableA, 0);
      digitalWrite(motorA1, 1);
      digitalWrite(motorA2, 0);
   }

   if (B == 128) {
      analogWrite(enableB, 0);
      digitalWrite(motorB1, 1);
      digitalWrite(motorB2, 0);
   }
}

You will need to define enableA, enableB, motorA1, motorA2, motorB1, motorB2, leftSensorPin, rightSensorPin. These will all be int. Integers in this case are numbers below 256. **NOTE: the enable pins do not need to be analog. PWM would be nice though. The probably are already connected to PWM pins like 9(?) and 10(?).

brightEnough, dark, leftSensor, and rightSensor can also be int, if you use 8 bit ADC. Otherwise, you will need to define them as long. You will need to do some testing as I mentioned earlier to know what dark and brightEnough numbers actually are. All of your declaration statements should appear before the setup() statement. I would suggest something along the lines of:

const int enableA = 9; //this will define the number nine as enableA, and, it will also be a constant so you won’t be able to reassign enableA later in the program

I wrote the program as I did, because once you can get a handle on it, you can get your robot to move faster or slower depending on the intensity or lack thereof of light hitting your LDRs.

Maybe someone will set me straight if I get something wrong. :smiley:

 

One of the most

One of the most comprehensive tutorials out there is probably the one you find here http://tronixstuff.wordpress.com/
So if you want to learn about Arduino, this is probably a good place to start.

Sketch of the Concept

Doug - would this drawing of the concept make the photovore behavior more clear? The steering is dependent on your solution. This one is an assumption that the robot body and motor setup is like the Start Here Robot (Left turn is right motor run and left motor stop).

PhotovoreBehavior.png

If you got this concept then Birdmuns code below is what you need.

 

I should give some more props to mogul.

He also mentioned in the shout box that some of my variable names could be much better.

Variable names should be self descriptive. My A and B variables are not exactly descriptive. When you write code you should do better than I did with my simple non-descript variables. I could have also probably added more, useful comments to the code I typed.

The Epsilon. A bit fuzziness is fine.

There is one possible issue here regarding the comparison of analog sensor value equality. Making an == on two analog sensor values is very absolute. There are many possibilities why two sensors of the same type have little nuances in their results. You might consider using the principle of range matching and accept a little fuzziness. This is commonly known as machine epsilon or just epsilon. 

Instead of having code like this

if(analogRead(leftLdrPin) == analogRead(rightLdrPin)){}

you would write the code like that:

if( equals( analogRead(leftLdrPin), analogRead(rightLdrPin))){}

and having your own equals(int leftValue, int rightValue) like this one:

boolean equals(int leftValue, int rightValue){
if(leftValue > rightValue){
return (leftValue - rightValue) <= EPSILON;
}else if(leftValue < rightValue){
return (rightValue - leftValue) <= EPSILON;
}
return true;
}

The value of EPSILON is empirically explored… and basically represents what you consider is-equal.

 

thanks a ton guys!

Im going through the wordpress tutorial right now and Ill keep you guys posted! Currently Im build a simple quadreped that will react to light and distance.