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
main.cpp@2:74d5233b6284, 2016-03-09 (annotated)
- Committer:
- Overdrivr
- Date:
- Wed Mar 09 15:45:28 2016 +0000
- Revision:
- 2:74d5233b6284
- Parent:
- 1:5a07069e17b6
headers include update
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Overdrivr | 0:c5e974040f21 | 1 | #include "mbed.h" |
Overdrivr | 2:74d5233b6284 | 2 | #include "TFC.h" |
Overdrivr | 2:74d5233b6284 | 3 | #include "Telemetry.hpp" |
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 | struct TM_state { |
Overdrivr | 0:c5e974040f21 | 19 | float direction; |
Overdrivr | 0:c5e974040f21 | 20 | float throttle; |
Overdrivr | 0:c5e974040f21 | 21 | }; |
Overdrivr | 0:c5e974040f21 | 22 | |
Overdrivr | 1:5a07069e17b6 | 23 | // Definition of the callback function |
Overdrivr | 0:c5e974040f21 | 24 | void process(TM_state* carState, TM_msg* msg); |
Overdrivr | 0:c5e974040f21 | 25 | |
Overdrivr | 0:c5e974040f21 | 26 | int main() |
Overdrivr | 0:c5e974040f21 | 27 | { |
Overdrivr | 1:5a07069e17b6 | 28 | // Create a Telemetry instance, running on uart at 115200 bauds |
Overdrivr | 1:5a07069e17b6 | 29 | Telemetry TM(115200); |
Overdrivr | 1:5a07069e17b6 | 30 | |
Overdrivr | 1:5a07069e17b6 | 31 | // a data structure to hold writeable parameters |
Overdrivr | 1:5a07069e17b6 | 32 | // i.e. the car direction and throttle that will be both be controlled from the laptop |
Overdrivr | 0:c5e974040f21 | 33 | TM_state carState; |
Overdrivr | 0:c5e974040f21 | 34 | carState.direction = 0; |
Overdrivr | 0:c5e974040f21 | 35 | carState.throttle = 0; |
Overdrivr | 1:5a07069e17b6 | 36 | |
Overdrivr | 1:5a07069e17b6 | 37 | // Suscribe our custom processing function (= callback function), and pass the data structure |
Overdrivr | 1:5a07069e17b6 | 38 | // so that we can access it inside |
Overdrivr | 1:5a07069e17b6 | 39 | // This way, everytime a frame is received, Telemetry will call this function for us, |
Overdrivr | 1:5a07069e17b6 | 40 | // and pass the TM_state data structure to it. |
Overdrivr | 1:5a07069e17b6 | 41 | TM.sub(process, &carState); |
Overdrivr | 0:c5e974040f21 | 42 | |
Overdrivr | 2:74d5233b6284 | 43 | DigitalOut led(LED1); |
Overdrivr | 0:c5e974040f21 | 44 | led = 1; |
Overdrivr | 1:5a07069e17b6 | 45 | |
Overdrivr | 1:5a07069e17b6 | 46 | // Init the TheFreescaleCup shield |
Overdrivr | 0:c5e974040f21 | 47 | TFC_Init(); |
Overdrivr | 0:c5e974040f21 | 48 | |
Overdrivr | 1:5a07069e17b6 | 49 | // Some timers... for timing :p |
Overdrivr | 0:c5e974040f21 | 50 | Timer servo_timer; |
Overdrivr | 0:c5e974040f21 | 51 | Timer motor_timer; |
Overdrivr | 0:c5e974040f21 | 52 | Timer tm_timer; |
Overdrivr | 0:c5e974040f21 | 53 | Timer print_timer; |
Overdrivr | 0:c5e974040f21 | 54 | |
Overdrivr | 0:c5e974040f21 | 55 | servo_timer.start(); |
Overdrivr | 0:c5e974040f21 | 56 | motor_timer.start(); |
Overdrivr | 0:c5e974040f21 | 57 | tm_timer.start(); |
Overdrivr | 0:c5e974040f21 | 58 | print_timer.start(); |
Overdrivr | 1:5a07069e17b6 | 59 | |
Overdrivr | 1:5a07069e17b6 | 60 | // Activate the engines ! |
Overdrivr | 0:c5e974040f21 | 61 | TFC_HBRIDGE_ENABLE; |
Overdrivr | 1:5a07069e17b6 | 62 | |
Overdrivr | 0:c5e974040f21 | 63 | for(;;) |
Overdrivr | 0:c5e974040f21 | 64 | { |
Overdrivr | 2:74d5233b6284 | 65 | TM.update(); |
Overdrivr | 0:c5e974040f21 | 66 | |
Overdrivr | 0:c5e974040f21 | 67 | // update servo control |
Overdrivr | 0:c5e974040f21 | 68 | if(servo_timer.read_ms() > 10) |
Overdrivr | 0:c5e974040f21 | 69 | { |
Overdrivr | 0:c5e974040f21 | 70 | servo_timer.reset(); |
Overdrivr | 0:c5e974040f21 | 71 | TFC_SetServo(0, carState.direction); |
Overdrivr | 0:c5e974040f21 | 72 | } |
Overdrivr | 0:c5e974040f21 | 73 | |
Overdrivr | 0:c5e974040f21 | 74 | // update motor control |
Overdrivr | 0:c5e974040f21 | 75 | if(motor_timer.read_ms() > 5) |
Overdrivr | 0:c5e974040f21 | 76 | { |
Overdrivr | 0:c5e974040f21 | 77 | motor_timer.reset(); |
Overdrivr | 0:c5e974040f21 | 78 | TFC_SetMotorPWM(carState.throttle , carState.throttle); |
Overdrivr | 0:c5e974040f21 | 79 | } |
Overdrivr | 0:c5e974040f21 | 80 | |
Overdrivr | 0:c5e974040f21 | 81 | // publish car state & blink a led |
Overdrivr | 2:74d5233b6284 | 82 | if(print_timer.read_ms() > 200) |
Overdrivr | 0:c5e974040f21 | 83 | { |
Overdrivr | 0:c5e974040f21 | 84 | print_timer.reset(); |
Overdrivr | 1:5a07069e17b6 | 85 | // Publish the car parameters, so we can access them from the computer |
Overdrivr | 1:5a07069e17b6 | 86 | TM.pub_f32("direction",carState.direction); |
Overdrivr | 0:c5e974040f21 | 87 | TM.pub_f32("throttle",carState.throttle); |
Overdrivr | 1:5a07069e17b6 | 88 | led = (led == 0) ? 1 : 0; // Toggle the led |
Overdrivr | 0:c5e974040f21 | 89 | } |
Overdrivr | 0:c5e974040f21 | 90 | } |
Overdrivr | 0:c5e974040f21 | 91 | } |
Overdrivr | 0:c5e974040f21 | 92 | |
Overdrivr | 1:5a07069e17b6 | 93 | // This is our processing function called every time a frame is received |
Overdrivr | 1:5a07069e17b6 | 94 | // First parameter is a pointer to the data structure we defined in main |
Overdrivr | 1:5a07069e17b6 | 95 | // Second parameter is a pointer to a data structure containing all info about received frame |
Overdrivr | 0:c5e974040f21 | 96 | void process(TM_state* carState, TM_msg* msg) |
Overdrivr | 0:c5e974040f21 | 97 | { |
Overdrivr | 1:5a07069e17b6 | 98 | // temp variable |
Overdrivr | 0:c5e974040f21 | 99 | float value = 0.f; |
Overdrivr | 1:5a07069e17b6 | 100 | // If received topic == 'direction' |
Overdrivr | 0:c5e974040f21 | 101 | if(strcmp(msg->topic,"direction") == 0) |
Overdrivr | 0:c5e974040f21 | 102 | { |
Overdrivr | 1:5a07069e17b6 | 103 | // If data type matches 'float32' |
Overdrivr | 0:c5e974040f21 | 104 | if(emplace_f32(msg,&value)) |
Overdrivr | 0:c5e974040f21 | 105 | { |
Overdrivr | 1:5a07069e17b6 | 106 | // Check values in order to avoid going beyond servomotor limits |
Overdrivr | 0:c5e974040f21 | 107 | if(value > 1.f) |
Overdrivr | 0:c5e974040f21 | 108 | value = 1.f; |
Overdrivr | 0:c5e974040f21 | 109 | if(value < -1.f) |
Overdrivr | 0:c5e974040f21 | 110 | value = -1.f; |
Overdrivr | 0:c5e974040f21 | 111 | carState->direction = value; |
Overdrivr | 0:c5e974040f21 | 112 | } |
Overdrivr | 0:c5e974040f21 | 113 | } |
Overdrivr | 1:5a07069e17b6 | 114 | // Idem for throttle |
Overdrivr | 0:c5e974040f21 | 115 | else if(strcmp(msg->topic,"throttle") == 0) |
Overdrivr | 0:c5e974040f21 | 116 | { |
Overdrivr | 0:c5e974040f21 | 117 | if(emplace_f32(msg,&value)) |
Overdrivr | 0:c5e974040f21 | 118 | { |
Overdrivr | 0:c5e974040f21 | 119 | if(value > 1.f) |
Overdrivr | 0:c5e974040f21 | 120 | value = 1.f; |
Overdrivr | 0:c5e974040f21 | 121 | if(value < -1.f) |
Overdrivr | 0:c5e974040f21 | 122 | value = -1.f; |
Overdrivr | 0:c5e974040f21 | 123 | carState->throttle = value; |
Overdrivr | 0:c5e974040f21 | 124 | } |
Overdrivr | 0:c5e974040f21 | 125 | } |
Overdrivr | 0:c5e974040f21 | 126 | } |