Austin Community College initial line follower program for Freescale car. This is based upon the FRDM-TFC code at mbed.org.
Fork of FRDM-TFC by
Austin Community College - Initial Specs for FRDM-TFC line following car.
This uses the fine library by ELI HUGHES.
Our goal here is to provide the simplest line-follower as a quick car checkout.
First, we limit the run duration for the car, so that you can catch it, if necessary. Right DIP switch (4) sets run time. 0 => 5 sec, 1 => 10 sec.
We provide simple speed selection with the other three DIP switches. I recommend 001 as the slowest real speed, (000 is stop, of course). DIP switches 1 2 3 make a 3 bit speed. 1 is msb, 3 is lsb
The car won't start until you press and release the driver's side PB. Left PB (TFC_PUSH_BUTTON_1) is permissive GO on release using left 3 DIPs for speed 0-7.
The car will stop when the passenger side PB is pressed. Right PB is STOP - TFC_PUSH_BUTTON_0
TFC_Ticker[3] is our run time counter. Like the Code Warrior edition, we use msec tickers.
Left (Driver side) trim pot 1 can be used to trim static steering servo Right trim pot 0 can be used to offset line camera
Back LED reflects drive motor status. The top three are not currently used.
main.cpp
- Committer:
- knalty
- Date:
- 2013-11-11
- Revision:
- 5:9d36b4c896e1
- Parent:
- 4:8a4a3fc59e57
File content as of revision 5:9d36b4c896e1:
#include "mbed.h" #include "TFC.h" /* Austin Community College Initial Specs Left (Driver side) trimpot 1 can be used to trim static steering servo Right trimpot 0 can be used to offset line camera Left PB (TFC_PUSH_BUTTON_1) is permissive GO using left 3 DIPs for speed 0-7 Right DIP switch (4) sets run time. 0 => 5 sec, 1 => 10 sec. DIP switches 1 2 3 make a 3 bit speed. 1 is msb, 3 is lsb TFC_Ticker[3] is our run time counter Right PB is STOP and CENTER_SERVO. TFC_PUSH_BUTTON_0 Back LED reflects drive motor status */ //This ticker code is used to maintain compability with the Codewarrior version of the sample. // This code uses an MBED Ticker for background timing. //This ticker code is used to maintain compability with the Codewarrior version of the sample. This code uses an MBED Ticker for background timing. #define NUM_TFC_TICKERS 4 Ticker TFC_TickerObj; volatile uint32_t TFC_Ticker[NUM_TFC_TICKERS]; void TFC_TickerUpdate() { int i; for(i=0; i<NUM_TFC_TICKERS; i++) { if(TFC_Ticker[i]<0xFFFFFFFF) { TFC_Ticker[i]++; } } } int main(void) { uint32_t i=0; uint32_t MaxRunTime; uint8_t Motor_ON; float Motor_Speed; float Servo_Position; // -1.0 .. +1.0 float Servo_Offset; // -1.0 to +1.0 float Camera_Offset; uint8_t Start_PB_Pressed; // flag to detect release of Start_PB uint8_t DIP_Speed; uint8_t scratch; uint16_t Current_Location; uint16_t Current_Min; float DarkSpot; // Initialization TFC_Init(); TFC_TickerObj.attach_us(&TFC_TickerUpdate,1000); TFC_HBRIDGE_DISABLE; // Explicitly turn off motor TFC_SetMotorPWM(0.0, 0.0 ); // Explicitly zero motor setpoints TFC_SetServo(0, 0.0); // Explicitly center steering servo Motor_ON = 0; Motor_Speed = 0; Start_PB_Pressed = 0; Servo_Position = 0.0; TFC_BAT_LED0_OFF; TFC_BAT_LED1_OFF; TFC_BAT_LED2_OFF; TFC_BAT_LED3_OFF; DIP_Speed = 0; TFC_Ticker[3] = 0; // clear run timer // Main Event Loop for(;;) { //TFC_Task coordinates with communications and periodic interrupt routines // TFC_Task(); // check for stop button pressed if (TFC_PUSH_BUTTON_0_PRESSED) { TFC_HBRIDGE_DISABLE; // Explicitly turn off motor TFC_SetMotorPWM(0.0, 0.0 ); // Explicitly zero motor setpoints TFC_SetServo(0, 0.0); // Explicitly center steering servo Motor_ON = 0; Motor_Speed = 0.0; Start_PB_Pressed = 0; Servo_Position = 0.0; TFC_BAT_LED0_OFF; // turn off motor power indicator LED TFC_BAT_LED1_OFF; TFC_BAT_LED2_OFF; TFC_BAT_LED3_OFF; } // read trimpots to establish servo and camera offsets Camera_Offset = TFC_ReadPot(0); // returns -1.0 to 1.0 Servo_Offset = TFC_ReadPot(1); // returns -1.0 to 1.0 // read SW4 and update MaxRunTime if (TFC_GetDIP_Switch() & 8) MaxRunTime = 10000; else MaxRunTime = 5000; // 10 sec, or 5 sec // check run status, and turn off motors if run time exceeded if (Motor_ON == 0) TFC_Ticker[3] = 0; // clear run timer else if(TFC_Ticker[3] > MaxRunTime) { TFC_HBRIDGE_DISABLE; // Explicitly turn off motor TFC_SetMotorPWM(0.0, 0.0 ); // Explicitly zero motor setpoints TFC_SetServo(0, 0.0); // Explicitly center steering servo Motor_ON = 0; Motor_Speed = 0.0; Start_PB_Pressed = 0; Servo_Position = 0.0; TFC_BAT_LED0_OFF; // turn off motor power indicator LED TFC_BAT_LED1_OFF; TFC_BAT_LED2_OFF; TFC_BAT_LED3_OFF; } //check for the start button (1) pressed, then released. if (TFC_PUSH_BUTTON_1_PRESSED) Start_PB_Pressed = 1; if ((!TFC_PUSH_BUTTON_1_PRESSED) & (Start_PB_Pressed)) // Falling edge detected { TFC_BAT_LED0_ON; // turn on back LED scratch = TFC_GetDIP_Switch(); // read DIP switches for initial speed DIP_Speed = 0; if (scratch & 1) DIP_Speed += 4; // SW1 if (scratch & 2) DIP_Speed += 2; // SW2 if (scratch & 4) DIP_Speed += 1; // SW3 Motor_Speed = 0.125*DIP_Speed; // scale 0..7 to 0.0 .. 0.875 Motor_ON = 1; // set flag used by run duration logic TFC_SetMotorPWM(Motor_Speed, Motor_Speed); // acts like Motor_Speed is zero TFC_HBRIDGE_ENABLE; // enable motors } // scan through the camera array, and find smallest value in the zone 32..96 if(Motor_ON) { Current_Min = TFC_LineScanImage0[32]; // TFC_LineScanImage0 Current_Location = 32; for (i=32;i<96;i++) { if(TFC_LineScanImage0[i] < Current_Min) { Current_Min = TFC_LineScanImage0[i]; Current_Location = i; } } DarkSpot = (64.0 - Current_Location)*0.02; // gain will need to be played with. Servo_Position = DarkSpot + Servo_Offset + Camera_Offset; TFC_SetServo(0,Servo_Position); } } }