Test-Drive the Tilt Controller

Radio Controlled Boe-Bot Application

Figure 3 - Tilt Controlled RF Boe-Bot (S-curves not shown)

To keep the message rate in the 40 ms range, all the pauses and DEBUG commands in TestTiltTransmitter.bs2 have been removed, and the modified program was saved as RfTiltTransmitter.bs2.  This program sends x and y coordinates every 40.6 ms, which will keep the Boe-Bot's servos going at a reasonable rate.  RfTiltControlledBoeBot.bs2 receives and stores the x and y-axis values sent by the transmitter.  Then, it uses these values to decide what pulses to send to the servos.

Example Program – RfTiltTransmitter.bs2

  • Connect the RF tilt controller to your programming cable.
  • Enter, save, and run RfTiltTransmitter.bs2
  • Disconnect the programming cable from the tilt controller.
' RfTiltTransmitter.bs2

' Transmit tilt data every 41 ms.


'{$STAMP BS2}

'{$PBASIC 2.5}


x              VAR     Word                  ' Left/right tilt

y              VAR     Word                  ' Forward/backward tilt


HIGH 11                                      ' T/R Line High - Transmit


DEBUG "Program running..."                   ' Test piezospeaker

FREQOUT 4, 2000, 3000


DO                                           ' Begin main routine


  PULSIN 6, 1, x                             ' Get X-axis tilt

  PULSIN 7, 1, y                             ' Get Y-axis tilt


  ' Send tilt at 2400 bps, non-inverted.

  PULSOUT 10, 1200                           ' Sync pulse for the receiver

  SEROUT 10, 16780, [ "!",                   ' Start character

                      x.HIGHBYTE, x.LOWBYTE, ' X-axis word

                      y.HIGHBYTE, y.LOWBYTE] ' Y-axis word


  ' DO NOT Display x AND y tilt measurements; DO NOT pause.


LOOP                                         ' Repeat main routine

Example Program – RfTiltControlledBoeBot.bs2

  • Connect your radio controlled Boe-Bot to the programming cable.
  • Enter, save, and run RfTiltControlledBoeBot.bs2.
  • Disconnect the radio controlled Boe-Bot from the programming cable.
  • Take your Boe-Bot for a test drive using your RF tilt controller to guide it.
' -----[ Title ]--------------------------------------------------------------

' RfTiltControlledBoeBot.bs2

' Boe-Bot navigates based on signals from an RF tilt controller.  The

' tilt controller should be running RfTiltTransmitter.bs2


'{$STAMP BS2}

'{$PBASIC 2.5}


' -----[ Constants ]----------------------------------------------------------


Negative       CON     1                     ' Left/right tilt


' -----[ Variables ]----------------------------------------------------------


x              VAR     Word                  ' Left/right tilt

y              VAR     Word                  ' Uphill/downhill tilt

ySign          VAR     y.BIT15               ' Sign bit for y


pulseLeft      VAR     Word                  ' Current left pulse value

pulseLeftOld   VAR     Word                  ' Previous left pulse value


pulseRight     VAR     Word                  ' Current right pulse value

pulseRightOld  VAR     Word                  ' Previous right pulse value


' -----[ Initialization ]-----------------------------------------------------


LOW 11                                       ' T/R Line low - receive


FREQOUT 4, 2000, 3000                        ' Beep to signify program start


pulseLeft     = 750                          ' Start with all pulses centered

pulseRight    = 750

pulseLeftOld  = 750

pulseRightOld = 750


' -----[ Main Routine ]-------------------------------------------------------


DO                                           ' Begin main routine.


  ' This SERIN command gets the x and y-axis values


  SERIN 10, 16780, [WAIT("!"), x.HIGHBYTE, x.LOWBYTE, y.HIGHBYTE, y.LOWBYTE]



  ' Scale to -62 to 62 with 0 -> level.

  x = 62 - ((x MIN 1875 MAX 3125) - 1875 / 10)

  y = 62 - ((y MIN 1875 MAX 3125) - 1875 / 10)


  ' Navigation decisions

  IF (ABS(x) > 12) OR (ABS(y) > 12) THEN     ' Is it tilted enough?

    pulseLeft  = 750 - y                     ' Forward/backward pulses

    pulseRight = 750 + y

    IF (ySign = Negative) OR (ABS(y) < 12) THEN  ' Turning for forward.

      pulseLeft =  pulseLeft  - x

      pulseRight = pulseRight - x

    ELSE                                     ' Turning for backward.

      pulseLeft  = pulseLeft  + x

      pulseRight = pulseRight + x

    ENDIF

  ELSE                                       ' Stay still

    pulseLeft  = 750

    pulseRight = 750

  ENDIF


  ' Increment/decrement routine only adjusts pulse durations by 8 at a time.

  IF pulseLeft  > (pulseLeftOld  + 6) THEN pulseleft  = pulseLeftOld  + 6

  IF pulseLeft  < (pulseLeftOld  - 6) THEN pulseLeft  = pulseLeftOld  - 6

  IF pulseRight > (pulseRightOld + 6) THEN pulseRight = pulseRightOld + 6

  IF pulseRight < (pulseRightOld - 6) THEN pulseRight = pulseRightOld - 6


  pulseLeft  = pulseLeft  MIN 650 MAX 850    ' Keep 650 <= durations <= 850

  pulseRight = pulseRight MIN 650 MAX 850


  pulseLeftOld  = pulseLeft                  ' Remember old values

  pulseRightOld = pulseRight


  PULSOUT 13, pulseLeft                      ' Send control pulses to servos

  PULSOUT 12, pulseRight


LOOP                                         ' Repeat main routine.

 

How RfTiltControlledBoeBot.bs2 Works

This is a modified version of the program UphillBoeBot.bs2 from Boe-Bot Robot Navigation with Accelerometer Incline Sensing.  If you have not already done so, it would be a good idea to try out this activity and familiarize yourself with the coding techniques.

Instead of two PULSIN commands to get the x and y-axis tilt values, this program uses a SERIN command to get the x and y-axis tilt values that are relayed by the RF receiver.  The SERIN command waits to receive the "!" character, then stores the next four bytes to reconstruct the x and y-axis word variable values.  After this SERIN command, the x and y variables store the raw accelerometer measurements.  This makes the rest of the program easier because it can be written as though the accelerometer is on-board.

    SERIN 11, 16780, [WAIT("!"), x.HIGHBYTE, x.LOWBYTE, y.HIGHBYTE, y.LOWBYTE]

These scaling and offset commands differ from UphillBoeBot.bs2.  The narrower range of values makes the RF tilt controller friendlier in terms of fine motor control with a range of -62 to + 62 instead of -625 to + 625.  The statements now convert the highest measurement into the lowest result, and vice versa.  They do so by subtracting the scaled accelerometer measurements from 62 instead of subtracting 62 from the scaled accelerometer measurements.  This change converts a hill climbing Boe-Bot into a hill descending Boe-Bot. 

    x = 62 - ((x MIN 1875 MAX 3125) - 1875 / 10)

    y = 62 - ((y MIN 1875 MAX 3125) - 1875 / 10)

The navigation decisions are also slightly different from UphillBoeBot.bs2.  They have been modified to make driving your Boe-Bot with a tilt controller easier and more intuitive.  The statement IF (ABS(x) > 12) OR (ABS(y) > 12) THEN creates a deadband so that the Boe-Bot doesn't immediately react as soon as you just barely tilt the RF tilt controller.  When both x and y are in this range, the ELSE statement at the bottom of the code block makes the Boe-Bot hold still.  Once you tilt the controller far enough to make x or y greater than 12 or less than -12, y is subtracted from pulseLeft and added to pulseRight.  When y is negative, it makes the Boe-Bot go backwards, if it's positive, the Boe-Bot goes forwards.  After the forward pulse values have been determined, the turn can be mixed in.  For forward motion, the x tilt values have to be subtracted from both pulseLeft and pulseRight to get that natural forward turning control.  When the Boe-Bot is backing up, the turn directions have to be reversed to keep the control intuitive, so instead of subtracting x from pulseLeft and pulseRight, x is added to these variables. 

    IF (ABS(x) > 12) OR (ABS(y) > 12) THEN    

      pulseLeft  = 750 - y                    

      pulseRight = 750 + y

      IF (ySign = Negative) OR (ABS(y) < 12) THEN 

        pulseLeft =  pulseLeft  - x

        pulseRight = pulseRight - x

      ELSE                                    

        pulseLeft  = pulseLeft  + x

        pulseRight = pulseRight + x

      ENDIF

    ELSE                                      

      pulseLeft  = 750

      pulseRight = 750

  ENDIF

The remainder of the program, especially the ramping routine, is introduced and explained in more detail in Boe-Bot Robot Navigation with Accelerometer Incline Sensing.

 

Your Turn – Making Time for Sensors

There are many ways to make time for other sensors.  The easiest is to check RF messages and read the sensors between alternate servo pulses.     

  • Add the declaration operation VAR Bit to the variables section.
  • Add this command operation = ~ operation at the beginning of the main routine, on the line just below DO
  • Using a SELECT...CASE statement evaluates the operation variable that executes the existing main routine for when CASE is 0, and a new routine (add PAUSE 40 for now) when CASE is 1.  That's enough time to check a lot of sensors.
  • Try your modified code out and decide whether or not the change in performance is acceptable.