Austin Community College initial line follower program for Freescale car. This is based upon the FRDM-TFC code at mbed.org.

Dependencies:   mbed

Fork of FRDM-TFC by Eli Hughes

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);
        }

    }
}