Let's Make Robots!

Reading light direction off a servo. Arduino C++

Hi there smiley I am fiddling with my second light follower robot on my 2WD chassis
the first one was the classic "3 photo resistors" model.
Now iI have fitted a servo onto the chassis, and have mounted a single photo resistor onto the servo.



https://fbcdn-sphotos-e-a.akamaihd.net/hphotos-ak-ash3/178416_637341408647_239375050_o.jpg

The servo scans from 40 degrees, to 130 degrees (90 is the centre, both of these values are the extents possible without fouling the photo resistor on the bodywork)

I want the photo resistor to take a reading for each increment of servo movement, compare it to the previous reading, and once the light level starts to drop down again (as in once the photo resistor has scanned past the light, and starts to scan away from the light source), it notes the position of the servo, and logs it as a "direction" to the light source.

currently 130 is left, 90 is straight forward, and 40 is right. I would build "windows" into the factors, as in "if the light is between 80 and 100, straight forward, else steer, depending on value)

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I do set PrevLightLevel to 0 because i thought 0 was the lowest value it could have. and if that was the case it would work because the new higher value would always overwrite the old one and wont print it till the for loop is done but now i see the Prevlight must be changed in ALL OF THE CODE i have written. i think he will get the idea though set PrevLightLevel to the lowest value or highest depending on how your lighthingy works. mail me if you have any questions anyway or just post it here.

So to make it short. if a strong light give you a low value set PrevLightLevel to a high value and change the if so it makes sense with this value.

 

Edit----

In the code above birdmuns comment it should now be fixed. In the pastebin code it is also fixed. Good luck

well the way i wrote it above was pretty much the way you wanted it but i can give you a more complete snippet and explain better how it works. a "enhanced" version is also found here which i wrote for you. http://pastebin.com/NRRhUuHk

 

PrevLightLevel=analogRead(PR); //i just set this to a read value for comparison
for(HoriPos = 40; HoriPos <= 130; HoriPos += 1)
  {   

    Hori.write(HoriPos);
   
    LightLevel = analogRead(PR);    // your reading is stored in LightLevel

    if (LightLevel < PrevLightLevel) { // i dont now if you get a high reading when theres much light and a low if less light just change
// this if its the other way around. now when you get a lower value than the previous one(more light)
PrevLightLevel = LightLevel; // we store the new highest value in PrevLightLevel.

      Direction = HoriPos; // and the direction where the light was strong
    }

    }
    delay(50);                         


  }
//since it's done with the sweep (one way) we dont print it yet.if you want to you could make a
//CCW_Direction and a CW_Direction integer to save the sweeps in.(CCW=counter clockwise sweep and , yeah you get the rest...)


//here you do the same for the the sweep going back.but without setting previous to 0.



for(HoriPos = 130; HoriPos > 40; HoriPos -= 1)
  {   

    Hori.write(HoriPos);
   
    LightLevel = analogRead(PR);    // your reading is stored in LightLevel

    if (LightLevel < PrevLightLevel) { // i dont now if you get a high reading when theres much light and a low if less light just change
// this if its the other way around. now when you get a lower value than the previous one(more light)
PrevLightLevel = LightLevel; // we store the new highest value in PrevLightLevel.

      Direction = HoriPos; // and the direction where the light was strong
    }

    }
    delay(50);                         


  }
Serial.println(Direction)

//now you sweep both ways and the strongest lightvalue is stored in previousLightLevel and position of the servo is now in
// Direction.

I also came to think of that this way of scanning might take a while so i just wanna make a suggestion
to scan in increments of maybe 10 steps on the servo and then in the strongest areas of the sweep you
might wanna do a 1 step scan.

like this-------------------------------------------------
PrevLightLevel=analogRead(PR);
for(HoriPos = 40; HoriPos <= 130; HoriPos += 10)
  {   

    Hori.write(HoriPos);
   
    LightLevel = analogRead(PR);   

    if (LightLevel < PrevLightLevel) {

PrevLightLevel = LightLevel;

      Direction = HoriPos;
    }

    }
    delay(50);                         


  }
PrevLightLevel=analogRead(PR);
int Temp = Direction;
for(Horipos=Temp-5;Horipos>=Temp+5;Horipos+=1){
Hori.write(HoriPos);
   
    LightLevel = analogRead(PR);   
    if (LightLevel < PrevLightLevel) {

PrevLightLevel = LightLevel;

      Direction = HoriPos; // and the direction where the light was strongest is stored here :)
}
---------------------------------------------------------------

// this way if the light is strongest at lets say Direction 70 you would only
 have to scan 9+10 times, 19 times instead of 90.
which means you can make faster scans.
Good luck

I am kinda curious about this 'classic "3 photo resistors" model'.

I did some searching and it seems it may not be as "classic" as you think. I have found tons of 2-sensor examples, but not so much on the 3-sensor style of which you speak.

Can I get a link? I may help me in a related project.

I would have thought it was quite common!

 

my setup was 3 PRs, each with its own Analogue read pin, and pointed indifferent directions (Left sightly, Central, Right Slightly)

The sketch compared the three values, and then depending on what was strongest ran the motors. Left ran the right motor only, central ran both, and Right ran left motor only.

I suppose if you had two, you would have it run forward if they were equal?

or just let it bounce between left and right, so it would waddle in the right direction, rather than run both motors at the same time?