Hiskey.us

 

CS 500: Physical Computing Week 10

Light Finder Robot

This little robot seeks out light trying to find the brightest spot in it's field of view. The robot also constantly sends its state back to a main computer using an RF transmitter. Originally this was supposed to be a solar charged robot, hence the light finding characterstic, but given that is pointless indoors and it's cold outside I decided not to add that in. However, see at the bottom of this page to see how to add that in including charge controller code.

This robot basically uses 4 photo resistors to detect where the light is brightest; in front of it, to the left, to the right, or directly above. It roams around searching for the brightest spot. If the brightest spot is above it, it stops and sits there. The robot also features a custom touch sensor I made, which tells it if something is in its way. I originally created a little tank robot out of a pencil box and some spare printer motors, but they ended up taking a lot of current to power them. So short of adding 6 9 volt batteries in parrallel, it didn't move. Instead, I went to fred meyer and bought a $10 remote control car and stripped off the top and disconnected the motors from the original RC circuit. This worked much better and took an extremely small amount of power and was very zippy. For more details see the images below.

In each of these images you can click to see the full-sized view:

This remote control car cost about $10 at fred meyer, which was interestingly cheaper than buying equivalent wheels / motors / base seperatley.

Remote Control Car Box


To power this device and the microcontroller I attached 4 AA batteries in series. Technically this provides about double the voltage the original RC circuit needed, but it didn't seem to hurt the motors any running them at this voltage level. 4 AA's were needed in order to provide the appropriate voltage for the Basic Atom Pro 24. I just duct taped the battery holder to the back of the robot, which worked well.

Power Unit


In this picture you can see the front of the robot with the light sensitive resistors and my custom made touch sensor. The touch sensor basically works by having the basic atom pro reading the voltage on that line, if the front part is pressed it closes the circuit and so pulls the voltage high. There is a resistor there as well on the actual circuit part to prevent short circuiting. Again we see obligatory judicious usage of gorrilla duct tape, which is essential for any project.

Front Custom Touch Sensor


In this picture you can see the circuit itself mounted on the RC car with gorilla duct tape. For significantly greater detail click the image. Basically though, as I said above, it just has 4 light sensitive resistors (see week 3) pointed forward, left/forward, right/forward, and up. The RF transmitter there is connected up to send robot state back to a reciever (see week 7 for more details). The chip you see there is an H-Bridge (see week 5 for more details) which controls the motors. The H-bridge handles inductive flow from the motors as well as allows for very easy switching of directions of the motors. One side is connected to the rear motors for going forward/backward. The other side of the H-bridge is connected to the front wheels motor which handles turning left or right. The front wheels are spring loaded to return to the centered position if the motor is off. I added a bunch of capacitors there on the power lines to even out the power flow as in the past I've found when dealing with battery powered motors connected on the same line as the basic atom pro 24 microcontroller that tends to be needed to avoid some weird microcontroller behavior such as resetting and what not. In this case it might not have been needed as usually I use a 9 volt battery to power and that only gives .3 amps, but in this case with the AA's that provide about 2.5 amps and plenty of voltage, it probably wouldn't have been a problem. But just in case I added the cap's anyways.

Light Finder Robot

Light Finder Robot



Robot Code:

LightLeft VAR WORD
LightRight VAR WORD
LightFront VAR WORD
LightTop VAR WORD
TouchFront VAR BIT
TouchFront2 VAR WORD

MotorStateForward CON 0
MotorStateBackward CON 1
MotorStateLeft CON 2
MotorStateRight CON 3
MotorStateStraight CON 4

MotorStateCurrent VAR BYTE

TransmitterPin CON P14

TouchFrontPin CON P11

LightLeftPin CON P0
LightRightPin CON P3
LightFrontPin CON P1
LightTopPin CON P2

MotorRearPin1 CON P7
MotorRearPin2 CON P6
MotorRearEnablePin CON P5

MotorFrontPin1 CON P8
MotorFrontPin2 CON P9
MotorFrontEnablePin CON P10

TurnToggle VAR BYTE

Initialize:
    Input LightLeftPin
    Input LightRightPin
    Input LightFrontPin
    Input LightTopPin

    MotorStateCurrent = MotorStateForward
    TurnToggle = 0
;end initialize

Main:

    GoSub FollowLight

goto main

FollowLight

    GoSub SetTouchValue

    if(TouchFront = 1) then
        GoSub TurnRandom
    endif

    if((LightRight > LightLeft) AND (LightRight > LightFront) AND (LightRight > LightTop)) then
        GoSub GoForward
        GoSub TurnRight
    elseif((LightFront > LightLeft) AND (LightFront > LightRight) AND (LightFront > LightTop))
        GoSub GoForward
        GoSub GoForward
    elseif((LightLeft > LightFront) AND (LightLeft > LightRight) AND (LightLeft > LightTop))
        GoSub GoForward
        GoSub TurnLeft
    elseif((LightTop > LightFront) AND (LightTop > LightRight) AND (LightTop > LightLeft))
        GoSub StopMotors
    endif

    GoSub SendState

return

SendState

    PULSOUT 0, 1200 'used for synchronization
    SEROUT 0, I9600, ["!", LightRight.HIGHBYTE, LightRight.LOWBYTE, LightFront.HIGHBYTE, LightFront.LOWBYTE, LightLeft.HIGHBYTE, LightLeft.LOWBYTE, LightTop.HIGHBYTE, LightTop.LOWBYTE, TouchFront2.HIGHBYTE, TouchFront2.LOWBYTE, MotorStateCurrent.HIGHBYTE, MotorStateCurrent.LOWBYTE]

return

SetTouchValue

    TouchFront = In11
    if(TouchFront = 1) then
        TouchFront2 = 1
    else
        TouchFront2 = 0
    endif

return

SetLightValues
    ADIN LightLeftPin, LightLeft
    ADIN LightRightPin, LightRight
    ADIN LightFrontPin, LightFront
    ADIN LightTopPin, LightTop
return

TurnRandom
    GoSub Gobackward

    if(TurnToggle = 0) then
        GoSub TurnRight
        TurnToggle = 1
    else
        GoSub TurnLeft
        TurnToggle = 0
    endif

    Pause 1000
return

GoForward
    High 8
    Low 7

    MotorStateCurrent = MotorStateForward
return

GoBackward
    High 7
    Low 8

    MotorStateCurrent = MotorStateBackward
return

TurnRight
    High 2
    Low 1

    MotorStateCurrent = MotorStateRight
return

TurnLeft
    High 1
    Low 2

    MotorStateCurrent = MotorStateLeft
return

GoStraight
    Low 1
    Low 2

    MotorStateCurrent = MotorStateStraight
return

StopMotors
    Low 1
    Low 2

    Low 7
    Low 8
return

EnableMotors
    High 0
    High 9
return

DisableMotors
    Low 0
    Low 9

    Low 8
    Low 7

    Low 1
    Low 2

return



Reciever Code for recieving state of the robot on a main computer:

LightRight VAR WORD
LightFront VAR WORD
LightLeft VAR WORD
LightTop VAR WORD
TouchFront VAR WORD
MotorState VAR WORD

main:

    SERIN 0, I9600, [Wait("!"), LightRight.HIGHBYTE, LightRight.LOWBYTE, LightFront.HIGHBYTE, LightFront.LOWBYTE, LightLeft.HIGHBYTE, LightLeft.LOWBYTE, LightTop.HIGHBYTE, LightTop.LOWBYTE, TouchFront.HIGHBYTE, TouchFront.LOWBYTE, MotorState.HIGHBYTE, MotorState.LOWBYTE]
    SEROUT s_out, I4800, ["LightRight: ", DEC LightRight, 10, 13, "LightLeft: ", DEC LightLeft, 10, 13, "LightFront: ", DEC LightFront, 10, 13, "LightTop: ", DEC LightTop, 10, 13, "TouchFront: ", DEC TouchFront, 10, 13, "MotorState: ", DEC MotorState, 10, 13]

goto main






Adding Solar Charger and Charge Regulator

I originally was going to have this robot have a solar charger built in. However, it was kind of pointless indoors and freazing cold outside, so I didn't add this. The AA solar charger on "week 9" was originally going to be used to run this robot. Hence why the robot tries to seek light, its 'food'. In order to add this though, I needed a charge regulator which the panel/circuit from week 9 did not have. So to support this I built a simple circuit that would read the voltage coming from the batteries and if they dropped below a certain point would switch on charging from the solar panel. I didn't take any pictures of this circuit, because I was originally going to add it to the main robot circuit, so I didn't see any point at the time. However, here's my code for that circuit, which detects voltage levels and switches on charging or not depending on the battery voltage. If put on the actual robot a slight modification would need to be made adding a "critical voltage" level where the robot would go in low power mode putting the basic atom pro in standbye mode for a time and obviously thus switching everything off while it charged the batteries. It could then wake up every so often to check whether the battery level was at an appropriate level to continue on. If this modification was added then I wouldn't be able to use the transistor switch type system I used here as it requires a pin to be high to enable the flow, but obviously that problem vould be worked around easily by using a relay. But this basic code/circuit would work excepting the extreme low voltage level case.

Vlt CON 200 'after testing with multi-meter with various voltages found that the basic atom pro 24 AD converter roughly reads 200 per volt

X VAR WORD

Main:

    ADIN 0, X 'read in voltage value from the batteries

    if(X < (Vlt * 5)) then
        High 10 'switches on charging using a transistor and solar panel
    else
        Low 10
    endif

    Pause 60000 'pause for one minute before checking again

goto Main