This is an example program that actually allows the car to race using the FRDM-TFC library!

Dependencies:   FRDM-TFC

Fork of TFC-RACING-DEMO by Daniel Hadad

Overview

This is an example program that uses the FRDM-TFC library to actually permit a car using the FDRM-TFC shield + FRDM-KL25Z to race around a center line track.

Exercises designed for Mentoring Matters Car Summer Camp for Summer 2014 at Freescale, Inc. in Austin, Texas

Car MODES

5 MODES OR EXERCISES THAT WILL ALIGN WITH DIP SWITCH SETTINGS IN BINARY FASHION e.g. Mode 1 = 001 = switch 1 is on, switch 2 is off, switch 3 is off

0 = 000 = Garage Mode, button light test to see if car alive!!

  • PUSHBUTTON A - Light LEDs 0 and 1
  • PUSHBUTTON B - Light LEDs 2 and 3
  • (switch 4 does nothing)

1 = 001 = Garage Mode, forward/reverse adjust, no auto steer, terminal output

  • POT 1 - Controls speed of right wheel: CCW = reverse; CW = forward
  • POT 2 - Controls speed of left wheel: CCW = reverse; CW = forward
  • NOTE In this mode the high pitched whine heard is of the H-bridge being active. To disable whine, briefly put into demo mode 1 above.
  • (switch 4 does nothing)

2 = 010 = Garage Mode, steering adjust, no auto steer, terminal output

  • POT 1 - Controls Servo: CCW = left; CW = right
  • (switch 4 does nothing)

3 = 011 = Garage Mode, Camera test, some auto steer, terminal output

  • switch 4 : OFF = normal dec data, ON = o-scope mode

4 = 100 = Track Mode, Auto Steer, safe settings

  • LIGHT SPEED = 0.4 default
  • switch 4 = terminal output on/off
  • Pot0 = controls motor speed
  • Pot1 = controls value to multiply with Kp for proportional control

5 = 101 = Track Mode, Auto Steer, fast settings

  • LUDICROUS SPEED = 0.6 default
  • switch 4 = terminal output on/off
  • Pot0 = controls motor speed
  • Pot1 = controls value to multiply with Kp for proportional control

6 = 110 = future upgrades

7 = 111 = future upgrades

Car Hookup

Motors

  • Code written assuming left motor hooked to B1(red)/B2(black) and right motor hooked to A1(red)/A2(black).

Battery

  • Be sure to hook positive (red) to 'Vbat' and negative (black) to 'Gnd'

Steering Servo

  • Servo must be hooked up with black wire innermost (away from LEDs).
  • Also be sure to mount servo on chassis with wire coming out the right side of the car.

Camera

  • Camera must be hooked up with black wire towards LEDs on the shield board.
  • Be sure to mount camera on tower with connector down towards the bottom.

Potentiometers (Pots)

  • Pots by default should have arrows pointing toward battery/motor hookup (for demo mods default).

Car Calibration

Serial Terminal

  • Download your favorite Terminal application (I use TeraTerm. Set it for 115200 baud, 8bit, none, 1bit.
  • But first you have to be sure that Windows mbed serial driver has been installed: Windows serial config.

Camera

Servo/Steering

  • You will need to put the car into demo mode 1 and connect up a terminal to the serial port in order to get feedback on the values for your particular servo as hooked up. Then change MAX_STEER_LEFT and MAX_STEER_RIGHT in Spices.cpp with these values to tell the program how your servo is hooked up.

Speed Control

  • This program does not have proper speed control but does modify the speed slightly based on recent error results from the camera. It also modifies the differential speed to each wheel to have better control around curves.
  • While debugging your car you may want to lower the speed. See the constants LIGHT_SPEED and LUDICROUS_SPEED in Spices.cpp. There you can change the speeds used for Modes 4 and 5 above. Range of valid values are 0.4-0.7. Lower is better when debugging the car around the track (mainly to minimize crash forces!).

Strange Gotchas

Glitchy Motors

  • Apparently there is contention between TPM0_CH0 and OpenSDA micro that causes strange issues with Motors (PWM interference). This will cause glitches in motor activty when hooked up to USB only: Found contention

More Info

Committer:
simonchow
Date:
Wed Jun 25 18:25:18 2014 +0000
Revision:
2:999ca57934bf
Parent:
1:87b28e8b9941
Track mode: Speed controlled with pot0; Kp controlled with pot1;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
redxeth 0:98e98e01a6ce 1 #include "mbed.h"
redxeth 0:98e98e01a6ce 2 #include "TFC.h"
redxeth 0:98e98e01a6ce 3
redxeth 0:98e98e01a6ce 4 #include "common.h"
redxeth 0:98e98e01a6ce 5 #include "Spices.h"
redxeth 0:98e98e01a6ce 6
redxeth 1:87b28e8b9941 7 // Exercises designed for Mentoring Matters Car Summer Camp
redxeth 1:87b28e8b9941 8 // for Summer 2014
redxeth 1:87b28e8b9941 9 // at Freescale, Inc.
redxeth 1:87b28e8b9941 10 // in Austin, Texas
redxeth 1:87b28e8b9941 11 //
redxeth 1:87b28e8b9941 12 // 5 MODES OR EXERCISES THAT WILL ALIGN WITH DIP SWITCH SETTINGS IN BINARY FASHION
redxeth 1:87b28e8b9941 13 // e.g. Mode 1 = 001 = switch 1 is on, switch 2 is off, switch 3 is off
redxeth 1:87b28e8b9941 14 //
redxeth 1:87b28e8b9941 15 // Modes:
redxeth 1:87b28e8b9941 16 // 0 = 000 = Garage Mode, button light test to see if car alive!!
redxeth 1:87b28e8b9941 17 // PUSHBUTTON A - Light LEDs 0 and 1
redxeth 1:87b28e8b9941 18 // PUSHBUTTON B - Light LEDs 2 and 3
redxeth 1:87b28e8b9941 19 // -switch 4 does nothing-
redxeth 1:87b28e8b9941 20 //
redxeth 1:87b28e8b9941 21 // 1 = 001 = Garage Mode, forward/reverse adjust, no auto steer, terminal output
redxeth 1:87b28e8b9941 22 // -switch 4 does nothing-
redxeth 1:87b28e8b9941 23 //
redxeth 1:87b28e8b9941 24 // 2 = 010 = Garage Mode, steering adjust, no auto steer, terminal output
redxeth 1:87b28e8b9941 25 // POT 1 - Controls Servo:
redxeth 1:87b28e8b9941 26 // CCW = turn left
redxeth 1:87b28e8b9941 27 // CW = turn right
redxeth 1:87b28e8b9941 28 // -switch 4 does nothing-
redxeth 1:87b28e8b9941 29 //
redxeth 1:87b28e8b9941 30 // 3 = 011 = Garage Mode, Camera test, some auto steer, terminal output
redxeth 1:87b28e8b9941 31 // switch 4:
redxeth 1:87b28e8b9941 32 // OFF = normal dec data
redxeth 1:87b28e8b9941 33 // ON = o-scope mode
redxeth 1:87b28e8b9941 34 //
redxeth 1:87b28e8b9941 35 // 4 = 100 = Track Mode, Auto Steer, safe settings
redxeth 1:87b28e8b9941 36 // switch 4 = terminal output on/off
redxeth 1:87b28e8b9941 37 //
redxeth 1:87b28e8b9941 38 // 5 = 101 = Track Mode, Auto Steer, fast settings
redxeth 1:87b28e8b9941 39 // switch 4 = terminal output on/off
redxeth 1:87b28e8b9941 40 //
redxeth 1:87b28e8b9941 41 // 6 = 110 = future upgrades
redxeth 1:87b28e8b9941 42 //
redxeth 1:87b28e8b9941 43 // 7 = 111 = future upgrades
redxeth 1:87b28e8b9941 44
redxeth 1:87b28e8b9941 45 /* NOTES
redxeth 1:87b28e8b9941 46 Camera unmounted
redxeth 1:87b28e8b9941 47 motors unhooked
redxeth 1:87b28e8b9941 48 only servo / steering hooked up
redxeth 1:87b28e8b9941 49
redxeth 1:87b28e8b9941 50 exercise 1 - garage drive
redxeth 1:87b28e8b9941 51 - manual motors forward / reverse
redxeth 1:87b28e8b9941 52 - ensure motors hooked up properly - forward/reverse/left/right
redxeth 1:87b28e8b9941 53 - show terminal value
redxeth 1:87b28e8b9941 54
redxeth 1:87b28e8b9941 55 exercise 2 - garage steer
redxeth 1:87b28e8b9941 56 - manual steering - left /right
redxeth 1:87b28e8b9941 57 - calibrate steering
redxeth 1:87b28e8b9941 58 - show terminal to get feedback
redxeth 1:87b28e8b9941 59
redxeth 1:87b28e8b9941 60 exercise 3 - garage see
redxeth 1:87b28e8b9941 61 - focus camera
redxeth 1:87b28e8b9941 62 - mount camera
redxeth 1:87b28e8b9941 63 - camera + servo line tracking (race mode)
redxeth 1:87b28e8b9941 64 garage mode use paper show following
redxeth 1:87b28e8b9941 65 - bad Kp value
redxeth 1:87b28e8b9941 66 - min speed = 0.5
redxeth 1:87b28e8b9941 67
redxeth 1:87b28e8b9941 68 exercise 4 - track - slow
redxeth 1:87b28e8b9941 69 - fine tuning max speed
redxeth 1:87b28e8b9941 70 - fine tune proportional control - Kp
redxeth 1:87b28e8b9941 71
redxeth 1:87b28e8b9941 72 exercise 5 - track - fast
redxeth 1:87b28e8b9941 73 - ratio of differential motor speed on curves
redxeth 1:87b28e8b9941 74 - dead zone with high speed on straights
redxeth 1:87b28e8b9941 75
redxeth 1:87b28e8b9941 76 */
redxeth 0:98e98e01a6ce 77
redxeth 0:98e98e01a6ce 78 void TFC_TickerUpdate()
redxeth 0:98e98e01a6ce 79 {
redxeth 0:98e98e01a6ce 80 int i;
redxeth 0:98e98e01a6ce 81
redxeth 0:98e98e01a6ce 82 for(i=0; i<NUM_TFC_TICKERS; i++)
redxeth 0:98e98e01a6ce 83 {
redxeth 0:98e98e01a6ce 84 if(TFC_Ticker[i]<0xFFFFFFFF)
redxeth 0:98e98e01a6ce 85 {
redxeth 0:98e98e01a6ce 86 TFC_Ticker[i]++;
redxeth 0:98e98e01a6ce 87 }
redxeth 0:98e98e01a6ce 88 }
redxeth 0:98e98e01a6ce 89 }
redxeth 0:98e98e01a6ce 90
redxeth 1:87b28e8b9941 91 // Garage Mode
redxeth 1:87b28e8b9941 92 // Car not meant to run on track
redxeth 1:87b28e8b9941 93 // Use this to test out car features
redxeth 1:87b28e8b9941 94 // and calibrate car
redxeth 1:87b28e8b9941 95 //
redxeth 1:87b28e8b9941 96 void GarageMode()
redxeth 0:98e98e01a6ce 97 {
redxeth 1:87b28e8b9941 98 uint32_t i,j = 0;
redxeth 0:98e98e01a6ce 99 float ReadPot0, ReadPot1;
redxeth 0:98e98e01a6ce 100
redxeth 0:98e98e01a6ce 101
redxeth 1:87b28e8b9941 102 //This Demo program will look at the first 2 switches to select one of 4 demo / garage modes
redxeth 1:87b28e8b9941 103 switch(TFC_GetDIP_Switch()&0x03)
redxeth 0:98e98e01a6ce 104 {
redxeth 0:98e98e01a6ce 105 default:
redxeth 1:87b28e8b9941 106 case 0 : // Mode 0
redxeth 1:87b28e8b9941 107 TFC_HBRIDGE_DISABLE;
redxeth 1:87b28e8b9941 108
redxeth 1:87b28e8b9941 109 TERMINAL_PRINTF("MODE 0\r\n");
redxeth 1:87b28e8b9941 110
redxeth 0:98e98e01a6ce 111 if(TFC_PUSH_BUTTON_0_PRESSED)
redxeth 1:87b28e8b9941 112 {
redxeth 0:98e98e01a6ce 113 TFC_BAT_LED0_ON;
redxeth 1:87b28e8b9941 114 TFC_BAT_LED1_ON;
redxeth 1:87b28e8b9941 115 } else {
redxeth 0:98e98e01a6ce 116 TFC_BAT_LED0_OFF;
redxeth 1:87b28e8b9941 117 TFC_BAT_LED1_OFF;
redxeth 1:87b28e8b9941 118 }
redxeth 0:98e98e01a6ce 119
redxeth 0:98e98e01a6ce 120 if(TFC_PUSH_BUTTON_1_PRESSED)
redxeth 1:87b28e8b9941 121 {
redxeth 1:87b28e8b9941 122 TFC_BAT_LED2_ON;
redxeth 0:98e98e01a6ce 123 TFC_BAT_LED3_ON;
redxeth 1:87b28e8b9941 124 } else {
redxeth 1:87b28e8b9941 125 TFC_BAT_LED2_OFF;
redxeth 0:98e98e01a6ce 126 TFC_BAT_LED3_OFF;
redxeth 1:87b28e8b9941 127 }
redxeth 0:98e98e01a6ce 128 break;
redxeth 0:98e98e01a6ce 129
redxeth 1:87b28e8b9941 130 case 1 : // Mode 1
redxeth 0:98e98e01a6ce 131 TFC_HBRIDGE_ENABLE;
redxeth 0:98e98e01a6ce 132
redxeth 0:98e98e01a6ce 133 ReadPot0 = TFC_ReadPot(0);
redxeth 0:98e98e01a6ce 134 ReadPot1 = TFC_ReadPot(1);
redxeth 1:87b28e8b9941 135 TERMINAL_PRINTF("MODE 1: ");
redxeth 1:87b28e8b9941 136 TERMINAL_PRINTF("Left drive setting = %1.2f\t\t", ReadPot1);
redxeth 1:87b28e8b9941 137 TERMINAL_PRINTF("Right drive setting = %1.2f\r\n", ReadPot0);
redxeth 0:98e98e01a6ce 138 TFC_SetMotorPWM(ReadPot0,ReadPot1);
redxeth 0:98e98e01a6ce 139
redxeth 0:98e98e01a6ce 140 break;
redxeth 0:98e98e01a6ce 141
redxeth 1:87b28e8b9941 142 case 2:
redxeth 1:87b28e8b9941 143 //Make sure motors are off
redxeth 1:87b28e8b9941 144 TFC_SetMotorPWM(0,0);
redxeth 1:87b28e8b9941 145 TFC_HBRIDGE_DISABLE;
redxeth 1:87b28e8b9941 146
redxeth 1:87b28e8b9941 147 if(TFC_Ticker[0]>=20) // every 40mS output data to terminal
redxeth 1:87b28e8b9941 148 {
redxeth 1:87b28e8b9941 149 TFC_Ticker[0] = 0; //reset the Ticker
redxeth 1:87b28e8b9941 150 //update the Servos
redxeth 1:87b28e8b9941 151 TERMINAL_PRINTF("MODE 2: ");
redxeth 1:87b28e8b9941 152 ReadPot0 = TFC_ReadPot(0);
redxeth 1:87b28e8b9941 153 // ReadPot1 = TFC_ReadPot(1);
redxeth 1:87b28e8b9941 154 TFC_SetServo(0,ReadPot0);
redxeth 1:87b28e8b9941 155 // TFC_SetServo(1,ReadPot1);
redxeth 1:87b28e8b9941 156 TERMINAL_PRINTF("Steer1 setting = %1.2f\r\n", ReadPot0);
redxeth 1:87b28e8b9941 157 // TERMINAL_PRINTF("Steer2 setting = %1.2f\r\n", ReadPot0);
redxeth 1:87b28e8b9941 158 }
redxeth 1:87b28e8b9941 159 break;
redxeth 1:87b28e8b9941 160
redxeth 1:87b28e8b9941 161 case 3 :
redxeth 1:87b28e8b9941 162 TFC_HBRIDGE_DISABLE;
redxeth 1:87b28e8b9941 163
redxeth 1:87b28e8b9941 164 if(TFC_Ticker[0]>1000 && TFC_LineScanImageReady>0) // every 1000 ticks (1s if 10ms)
redxeth 0:98e98e01a6ce 165 {
redxeth 1:87b28e8b9941 166 // TERMINAL_PRINTF("MODE 3:\r\n");
redxeth 0:98e98e01a6ce 167 TFC_Ticker[0] = 0;
redxeth 0:98e98e01a6ce 168 TFC_LineScanImageReady=0; // must reset to 0 after detecting non-zero
redxeth 1:87b28e8b9941 169
redxeth 1:87b28e8b9941 170 if (terminalMode()) {
redxeth 1:87b28e8b9941 171 // print values to terminal as if were o-scope...
redxeth 1:87b28e8b9941 172
redxeth 1:87b28e8b9941 173 for(j=20;j>0;j--) {
redxeth 1:87b28e8b9941 174 for(i=0;i<128;i++) {
redxeth 1:87b28e8b9941 175 if ((TFC_LineScanImage0[i]<=(4096*j/20)) && (TFC_LineScanImage0[i]>=(4096*(j-1)/20)))
redxeth 1:87b28e8b9941 176 TERMINAL_PRINTF("*");
redxeth 1:87b28e8b9941 177 else
redxeth 1:87b28e8b9941 178 TERMINAL_PRINTF(" ");
redxeth 1:87b28e8b9941 179 }
redxeth 1:87b28e8b9941 180 TERMINAL_PRINTF("\r\n");
redxeth 1:87b28e8b9941 181 }
redxeth 1:87b28e8b9941 182
redxeth 1:87b28e8b9941 183 } else {
redxeth 1:87b28e8b9941 184 for(i=0;i<128;i++) // print one line worth of data (128) from Camera 0
redxeth 1:87b28e8b9941 185 {
redxeth 1:87b28e8b9941 186 TERMINAL_PRINTF("%d",TFC_LineScanImage0[i]);
redxeth 0:98e98e01a6ce 187
redxeth 1:87b28e8b9941 188 if(i==127) // when last data reached put in line return
redxeth 1:87b28e8b9941 189 TERMINAL_PRINTF("\r\n",TFC_LineScanImage0[i]);
redxeth 1:87b28e8b9941 190 else
redxeth 1:87b28e8b9941 191 TERMINAL_PRINTF(",",TFC_LineScanImage0[i]);
redxeth 1:87b28e8b9941 192 }
redxeth 1:87b28e8b9941 193 TERMINAL_PRINTF("============================================================================================\r\n");
redxeth 1:87b28e8b9941 194 wait_ms(10);
redxeth 1:87b28e8b9941 195 }
redxeth 0:98e98e01a6ce 196
redxeth 1:87b28e8b9941 197
redxeth 0:98e98e01a6ce 198
redxeth 0:98e98e01a6ce 199 }
redxeth 0:98e98e01a6ce 200
redxeth 0:98e98e01a6ce 201
redxeth 0:98e98e01a6ce 202
redxeth 0:98e98e01a6ce 203 break;
redxeth 0:98e98e01a6ce 204 } // end case
redxeth 0:98e98e01a6ce 205
redxeth 0:98e98e01a6ce 206 }
redxeth 0:98e98e01a6ce 207
redxeth 0:98e98e01a6ce 208
redxeth 0:98e98e01a6ce 209 int main()
redxeth 0:98e98e01a6ce 210 {
redxeth 0:98e98e01a6ce 211 // TERMINAL TYPE
redxeth 0:98e98e01a6ce 212 PC.baud(115200); // works with Excel and TeraTerm
redxeth 0:98e98e01a6ce 213 //PC.baud(9600); // works with USB Serial Monitor Lite: https://play.google.com/store/apps/details?id=jp.ksksue.app.terminal; doesn't work > 9600
redxeth 0:98e98e01a6ce 214 TFC_TickerObj.attach_us(&TFC_TickerUpdate,2000); // update ticker array every 2mS (2000 uS)
redxeth 0:98e98e01a6ce 215
redxeth 0:98e98e01a6ce 216 TFC_Init();
redxeth 0:98e98e01a6ce 217
redxeth 0:98e98e01a6ce 218 for(;;)
redxeth 1:87b28e8b9941 219 {
redxeth 1:87b28e8b9941 220 if(getMode() < 4)
redxeth 1:87b28e8b9941 221 // Run Garage Mode
redxeth 1:87b28e8b9941 222 GarageMode();
redxeth 0:98e98e01a6ce 223 else
redxeth 1:87b28e8b9941 224 // Run Track Mode
redxeth 1:87b28e8b9941 225 TrackMode();
redxeth 0:98e98e01a6ce 226
redxeth 0:98e98e01a6ce 227 } // end of infinite for loop
redxeth 0:98e98e01a6ce 228
redxeth 0:98e98e01a6ce 229
redxeth 0:98e98e01a6ce 230 }
redxeth 0:98e98e01a6ce 231