RC-car remotely controlled from a computer. A demonstration of the power of Pytelemetry/telemetry. MIT Licensing.

Dependencies:   BufferedSerial FRDM-TFC mbed telemetry

Example of the 'Telemetry' library, a portable communication library for embedded devices. The PC-side of this code is hosted a github.com/Overdrivr/telemetry-examples

This code uses the car from the Freescale Cup competition initially dedicated to be a line-following racing car, and turns it into a full-blown radio-controlled car.

It is using a Bluetooth serial module to provide wireless connectivity. See the repository at github.com/Overdrivr/telemetry-examples for complete instructions on wiring everthing together.

Repo : TO BE DONE

Committer:
Overdrivr
Date:
Mon Feb 22 21:24:52 2016 +0000
Revision:
1:5a07069e17b6
Parent:
0:c5e974040f21
Child:
2:74d5233b6284
Updated code for new interface + comments and description

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Overdrivr 0:c5e974040f21 1 #include "mbed.h"
Overdrivr 0:c5e974040f21 2 #include "FRDM-TFC/TFC.h"
Overdrivr 1:5a07069e17b6 3 #include "telemetry/Telemetry.h"
Overdrivr 1:5a07069e17b6 4
Overdrivr 1:5a07069e17b6 5 /*
Overdrivr 1:5a07069e17b6 6 Example of the 'Telemetry' library, a portable communication library for embedded devices.
Overdrivr 1:5a07069e17b6 7 The PC-side of this code is hosted a github.com/Overdrivr/telemetry-examples
Overdrivr 1:5a07069e17b6 8
Overdrivr 1:5a07069e17b6 9 This code uses the car from the Freescale Cup competition initially dedicated to be a
Overdrivr 1:5a07069e17b6 10 line-following racing car, and turns it into a full-blown radio-controlled car.
Overdrivr 1:5a07069e17b6 11
Overdrivr 1:5a07069e17b6 12 It is using a Bluetooth serial module to provide wireless connectivity. See the repository at
Overdrivr 1:5a07069e17b6 13 github.com/Overdrivr/telemetry-examples for complete instructions on wiring everthing together.
Overdrivr 1:5a07069e17b6 14
Overdrivr 1:5a07069e17b6 15 Repo : TO BE DONE
Overdrivr 1:5a07069e17b6 16 */
Overdrivr 0:c5e974040f21 17
Overdrivr 0:c5e974040f21 18 DigitalOut led(LED1);
Overdrivr 0:c5e974040f21 19
Overdrivr 0:c5e974040f21 20 struct TM_state {
Overdrivr 0:c5e974040f21 21 float direction;
Overdrivr 0:c5e974040f21 22 float throttle;
Overdrivr 0:c5e974040f21 23 };
Overdrivr 0:c5e974040f21 24
Overdrivr 1:5a07069e17b6 25 // Definition of the callback function
Overdrivr 0:c5e974040f21 26 void process(TM_state* carState, TM_msg* msg);
Overdrivr 0:c5e974040f21 27
Overdrivr 0:c5e974040f21 28 int main()
Overdrivr 0:c5e974040f21 29 {
Overdrivr 1:5a07069e17b6 30 // Create a Telemetry instance, running on uart at 115200 bauds
Overdrivr 1:5a07069e17b6 31 Telemetry TM(115200);
Overdrivr 1:5a07069e17b6 32
Overdrivr 1:5a07069e17b6 33 // a data structure to hold writeable parameters
Overdrivr 1:5a07069e17b6 34 // i.e. the car direction and throttle that will be both be controlled from the laptop
Overdrivr 0:c5e974040f21 35 TM_state carState;
Overdrivr 0:c5e974040f21 36 carState.direction = 0;
Overdrivr 0:c5e974040f21 37 carState.throttle = 0;
Overdrivr 1:5a07069e17b6 38
Overdrivr 1:5a07069e17b6 39 // Suscribe our custom processing function (= callback function), and pass the data structure
Overdrivr 1:5a07069e17b6 40 // so that we can access it inside
Overdrivr 1:5a07069e17b6 41 // This way, everytime a frame is received, Telemetry will call this function for us,
Overdrivr 1:5a07069e17b6 42 // and pass the TM_state data structure to it.
Overdrivr 1:5a07069e17b6 43 TM.sub(process, &carState);
Overdrivr 0:c5e974040f21 44
Overdrivr 0:c5e974040f21 45 led = 1;
Overdrivr 1:5a07069e17b6 46
Overdrivr 1:5a07069e17b6 47 // Init the TheFreescaleCup shield
Overdrivr 0:c5e974040f21 48 TFC_Init();
Overdrivr 0:c5e974040f21 49
Overdrivr 1:5a07069e17b6 50 // Some timers... for timing :p
Overdrivr 0:c5e974040f21 51 Timer servo_timer;
Overdrivr 0:c5e974040f21 52 Timer motor_timer;
Overdrivr 0:c5e974040f21 53 Timer tm_timer;
Overdrivr 0:c5e974040f21 54 Timer print_timer;
Overdrivr 0:c5e974040f21 55
Overdrivr 0:c5e974040f21 56 servo_timer.start();
Overdrivr 0:c5e974040f21 57 motor_timer.start();
Overdrivr 0:c5e974040f21 58 tm_timer.start();
Overdrivr 0:c5e974040f21 59 print_timer.start();
Overdrivr 1:5a07069e17b6 60
Overdrivr 1:5a07069e17b6 61 // Activate the engines !
Overdrivr 0:c5e974040f21 62 TFC_HBRIDGE_ENABLE;
Overdrivr 1:5a07069e17b6 63
Overdrivr 0:c5e974040f21 64 for(;;)
Overdrivr 0:c5e974040f21 65 {
Overdrivr 0:c5e974040f21 66 // update telemetry
Overdrivr 0:c5e974040f21 67 if(tm_timer.read_ms() > 50)
Overdrivr 0:c5e974040f21 68 {
Overdrivr 0:c5e974040f21 69 tm_timer.reset();
Overdrivr 0:c5e974040f21 70 TM.update();
Overdrivr 0:c5e974040f21 71 }
Overdrivr 0:c5e974040f21 72
Overdrivr 0:c5e974040f21 73 // update servo control
Overdrivr 0:c5e974040f21 74 if(servo_timer.read_ms() > 10)
Overdrivr 0:c5e974040f21 75 {
Overdrivr 0:c5e974040f21 76 servo_timer.reset();
Overdrivr 0:c5e974040f21 77 TFC_SetServo(0, carState.direction);
Overdrivr 0:c5e974040f21 78 }
Overdrivr 0:c5e974040f21 79
Overdrivr 0:c5e974040f21 80 // update motor control
Overdrivr 0:c5e974040f21 81 if(motor_timer.read_ms() > 5)
Overdrivr 0:c5e974040f21 82 {
Overdrivr 0:c5e974040f21 83 motor_timer.reset();
Overdrivr 0:c5e974040f21 84 TFC_SetMotorPWM(carState.throttle , carState.throttle);
Overdrivr 0:c5e974040f21 85 }
Overdrivr 0:c5e974040f21 86
Overdrivr 0:c5e974040f21 87 // publish car state & blink a led
Overdrivr 0:c5e974040f21 88 if(print_timer.read_ms() > 500)
Overdrivr 0:c5e974040f21 89 {
Overdrivr 0:c5e974040f21 90 print_timer.reset();
Overdrivr 1:5a07069e17b6 91 // Publish the car parameters, so we can access them from the computer
Overdrivr 1:5a07069e17b6 92 TM.pub_f32("direction",carState.direction);
Overdrivr 0:c5e974040f21 93 TM.pub_f32("throttle",carState.throttle);
Overdrivr 1:5a07069e17b6 94 led = (led == 0) ? 1 : 0; // Toggle the led
Overdrivr 0:c5e974040f21 95 }
Overdrivr 0:c5e974040f21 96 }
Overdrivr 0:c5e974040f21 97 }
Overdrivr 0:c5e974040f21 98
Overdrivr 1:5a07069e17b6 99 // This is our processing function called every time a frame is received
Overdrivr 1:5a07069e17b6 100 // First parameter is a pointer to the data structure we defined in main
Overdrivr 1:5a07069e17b6 101 // Second parameter is a pointer to a data structure containing all info about received frame
Overdrivr 0:c5e974040f21 102 void process(TM_state* carState, TM_msg* msg)
Overdrivr 0:c5e974040f21 103 {
Overdrivr 1:5a07069e17b6 104 // temp variable
Overdrivr 0:c5e974040f21 105 float value = 0.f;
Overdrivr 1:5a07069e17b6 106 // If received topic == 'direction'
Overdrivr 0:c5e974040f21 107 if(strcmp(msg->topic,"direction") == 0)
Overdrivr 0:c5e974040f21 108 {
Overdrivr 1:5a07069e17b6 109 // If data type matches 'float32'
Overdrivr 0:c5e974040f21 110 if(emplace_f32(msg,&value))
Overdrivr 0:c5e974040f21 111 {
Overdrivr 1:5a07069e17b6 112 // Check values in order to avoid going beyond servomotor limits
Overdrivr 0:c5e974040f21 113 if(value > 1.f)
Overdrivr 0:c5e974040f21 114 value = 1.f;
Overdrivr 0:c5e974040f21 115 if(value < -1.f)
Overdrivr 0:c5e974040f21 116 value = -1.f;
Overdrivr 0:c5e974040f21 117 carState->direction = value;
Overdrivr 0:c5e974040f21 118 }
Overdrivr 0:c5e974040f21 119 }
Overdrivr 1:5a07069e17b6 120 // Idem for throttle
Overdrivr 0:c5e974040f21 121 else if(strcmp(msg->topic,"throttle") == 0)
Overdrivr 0:c5e974040f21 122 {
Overdrivr 0:c5e974040f21 123 if(emplace_f32(msg,&value))
Overdrivr 0:c5e974040f21 124 {
Overdrivr 0:c5e974040f21 125 if(value > 1.f)
Overdrivr 0:c5e974040f21 126 value = 1.f;
Overdrivr 0:c5e974040f21 127 if(value < -1.f)
Overdrivr 0:c5e974040f21 128 value = -1.f;
Overdrivr 0:c5e974040f21 129 carState->throttle = value;
Overdrivr 0:c5e974040f21 130 }
Overdrivr 0:c5e974040f21 131 }
Overdrivr 0:c5e974040f21 132 }