Tyler Weaver / Mbed 2 deprecated HARP Featured

HARP: High Altitude Recovery Payload

Version 0.1: RC design

/media/uploads/tylerjw/_scaled_2012-07-23_mbed_xbee_breadboard.jpg

By connecting the second xbee to a computer using a terminal command and supplying the characters L, R, C, F the light patterns change on the mbed.

Committer:
tylerjw
Date:
Tue Aug 07 16:03:45 2012 +0000
Revision:
6:2bd373ba18ae
Parent:
5:49ccc75efb93
Child:
7:fcbf263a62b9
Working servo control with time delay.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tylerjw 1:21a6da67311c 1 /* Copyright (c) 2012 Tyler Weaver, MIT License
tylerjw 1:21a6da67311c 2 *
tylerjw 6:2bd373ba18ae 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
tylerjw 6:2bd373ba18ae 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
tylerjw 6:2bd373ba18ae 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
tylerjw 6:2bd373ba18ae 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
tylerjw 1:21a6da67311c 7 * furnished to do so, subject to the following conditions:
tylerjw 1:21a6da67311c 8 *
tylerjw 6:2bd373ba18ae 9 * The above copyright notice and this permission notice shall be included in all copies or
tylerjw 1:21a6da67311c 10 * substantial portions of the Software.
tylerjw 1:21a6da67311c 11 *
tylerjw 6:2bd373ba18ae 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
tylerjw 6:2bd373ba18ae 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
tylerjw 6:2bd373ba18ae 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
tylerjw 6:2bd373ba18ae 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
tylerjw 1:21a6da67311c 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
tylerjw 1:21a6da67311c 17 */
tylerjw 6:2bd373ba18ae 18
tylerjw 2:d1b64b3c9d26 19
tylerjw 0:043ed5bb10f2 20 #include "mbed.h"
tylerjw 0:043ed5bb10f2 21 #include "rtos.h"
tylerjw 0:043ed5bb10f2 22 #include "watchdog.h"
tylerjw 0:043ed5bb10f2 23
tylerjw 0:043ed5bb10f2 24 // Setup the watchdog timer
tylerjw 0:043ed5bb10f2 25 Watchdog wdt;
tylerjw 0:043ed5bb10f2 26
tylerjw 0:043ed5bb10f2 27 // xbee serial connection
tylerjw 0:043ed5bb10f2 28 Serial xbee(p13,p14);
tylerjw 0:043ed5bb10f2 29
tylerjw 0:043ed5bb10f2 30 // status leds
tylerjw 0:043ed5bb10f2 31 BusOut status_led(LED4, LED3, LED2, LED1);
tylerjw 0:043ed5bb10f2 32
tylerjw 0:043ed5bb10f2 33 typedef struct {
tylerjw 0:043ed5bb10f2 34 char msg; // the direction to turn in
tylerjw 6:2bd373ba18ae 35 } message_xbee;
tylerjw 6:2bd373ba18ae 36
tylerjw 6:2bd373ba18ae 37 enum state_p { LEFT, CENTER, RIGHT };
tylerjw 6:2bd373ba18ae 38
tylerjw 6:2bd373ba18ae 39 typedef struct {
tylerjw 6:2bd373ba18ae 40 state_p state;
tylerjw 6:2bd373ba18ae 41 } message_para;
tylerjw 0:043ed5bb10f2 42
tylerjw 6:2bd373ba18ae 43 MemoryPool<message_para, 16> mpool_para;
tylerjw 6:2bd373ba18ae 44 Queue<message_para, 16> queue_para;
tylerjw 0:043ed5bb10f2 45
tylerjw 6:2bd373ba18ae 46 MemoryPool<message_xbee, 16> mpool_xbee;
tylerjw 6:2bd373ba18ae 47 Queue<message_xbee, 16> queue_xbee;
tylerjw 6:2bd373ba18ae 48
tylerjw 6:2bd373ba18ae 49 /**
tylerjw 6:2bd373ba18ae 50 * xbee_thread
tylerjw 6:2bd373ba18ae 51 * this thread reads characters from the xbee serial connection and posts messages containing them
tylerjw 6:2bd373ba18ae 52 */
tylerjw 0:043ed5bb10f2 53 void xbee_thread(void const *argument) {
tylerjw 0:043ed5bb10f2 54 while (true) {
tylerjw 0:043ed5bb10f2 55 if (xbee.readable()) {
tylerjw 6:2bd373ba18ae 56 message_xbee *message = mpool_xbee.alloc();
tylerjw 0:043ed5bb10f2 57 message->msg = xbee.getc();
tylerjw 0:043ed5bb10f2 58
tylerjw 6:2bd373ba18ae 59 queue_xbee.put(message);
tylerjw 0:043ed5bb10f2 60 }
tylerjw 0:043ed5bb10f2 61 Thread::wait(100);
tylerjw 0:043ed5bb10f2 62 }
tylerjw 0:043ed5bb10f2 63 }
tylerjw 0:043ed5bb10f2 64
tylerjw 6:2bd373ba18ae 65 /**
tylerjw 6:2bd373ba18ae 66 parachute_thread
tylerjw 6:2bd373ba18ae 67 this thread recieves messages from the main thread and turns the servos for control of the parachute
tylerjw 6:2bd373ba18ae 68 */
tylerjw 6:2bd373ba18ae 69 void parachute_thread(void const *argument) {
tylerjw 6:2bd373ba18ae 70 PwmOut left(p21);
tylerjw 6:2bd373ba18ae 71 PwmOut right(p22);
tylerjw 6:2bd373ba18ae 72 left.period(0.020);
tylerjw 6:2bd373ba18ae 73 right.period(0.020);
tylerjw 6:2bd373ba18ae 74
tylerjw 6:2bd373ba18ae 75 const float WIND = 0.001;
tylerjw 6:2bd373ba18ae 76 const float STOP = 0.0015;
tylerjw 6:2bd373ba18ae 77 const float UNWIND = 0.002;
tylerjw 6:2bd373ba18ae 78 const int HOLD = 500;
tylerjw 6:2bd373ba18ae 79
tylerjw 6:2bd373ba18ae 80 left.pulsewidth(STOP); // STOP
tylerjw 6:2bd373ba18ae 81 right.pulsewidth(STOP);
tylerjw 6:2bd373ba18ae 82
tylerjw 6:2bd373ba18ae 83 state_p state = CENTER;
tylerjw 6:2bd373ba18ae 84 state_p oldState = CENTER;
tylerjw 6:2bd373ba18ae 85
tylerjw 6:2bd373ba18ae 86 //initalize
tylerjw 6:2bd373ba18ae 87 // left
tylerjw 6:2bd373ba18ae 88 left.pulsewidth(WIND);
tylerjw 6:2bd373ba18ae 89 Thread::wait(HOLD);
tylerjw 6:2bd373ba18ae 90 left.pulsewidth(STOP);
tylerjw 6:2bd373ba18ae 91 Thread::wait(HOLD);
tylerjw 6:2bd373ba18ae 92 left.pulsewidth(UNWIND);
tylerjw 6:2bd373ba18ae 93 Thread::wait(HOLD);
tylerjw 6:2bd373ba18ae 94 left.pulsewidth(STOP);
tylerjw 6:2bd373ba18ae 95 right.pulsewidth(WIND);
tylerjw 6:2bd373ba18ae 96 Thread::wait(HOLD);
tylerjw 6:2bd373ba18ae 97 right.pulsewidth(STOP);
tylerjw 6:2bd373ba18ae 98 Thread::wait(HOLD);
tylerjw 6:2bd373ba18ae 99 right.pulsewidth(UNWIND);
tylerjw 6:2bd373ba18ae 100 Thread::wait(HOLD);
tylerjw 6:2bd373ba18ae 101 right.pulsewidth(STOP);
tylerjw 6:2bd373ba18ae 102
tylerjw 6:2bd373ba18ae 103 while (true) {
tylerjw 6:2bd373ba18ae 104 osEvent evt_para = queue_para.get(10); // 10 millisecond wait
tylerjw 6:2bd373ba18ae 105 if (evt_para.status == osEventMessage) {
tylerjw 6:2bd373ba18ae 106 message_para *message = (message_para*)evt_para.value.p;
tylerjw 6:2bd373ba18ae 107 printf("\nMessage for para: %d\n\r", message->state);
tylerjw 6:2bd373ba18ae 108 oldState = state;
tylerjw 6:2bd373ba18ae 109 state = message->state;
tylerjw 6:2bd373ba18ae 110 }
tylerjw 6:2bd373ba18ae 111 switch (state) {
tylerjw 6:2bd373ba18ae 112 case CENTER: // HOLD
tylerjw 6:2bd373ba18ae 113 if (oldState == LEFT) { // previous left turn
tylerjw 6:2bd373ba18ae 114 left.pulsewidth(UNWIND); // wind forward
tylerjw 6:2bd373ba18ae 115 Thread::wait(HOLD);
tylerjw 6:2bd373ba18ae 116 } else if (oldState == RIGHT) { // previous right turn
tylerjw 6:2bd373ba18ae 117 right.pulsewidth(UNWIND); // wind forward
tylerjw 6:2bd373ba18ae 118 Thread::wait(HOLD);
tylerjw 6:2bd373ba18ae 119 }
tylerjw 6:2bd373ba18ae 120 break;
tylerjw 6:2bd373ba18ae 121 case LEFT: // left
tylerjw 6:2bd373ba18ae 122 if (oldState == RIGHT) { // previous right turn
tylerjw 6:2bd373ba18ae 123 right.pulsewidth(UNWIND); // wind forward
tylerjw 6:2bd373ba18ae 124 Thread::wait(HOLD);
tylerjw 6:2bd373ba18ae 125 right.pulsewidth(STOP); // HOLD
tylerjw 6:2bd373ba18ae 126 } else if (oldState == LEFT) // previous left
tylerjw 6:2bd373ba18ae 127 break;
tylerjw 6:2bd373ba18ae 128 //initiate left turn
tylerjw 6:2bd373ba18ae 129 left.pulsewidth(WIND); // wind back
tylerjw 6:2bd373ba18ae 130 Thread::wait(HOLD); // 0.5 second turn (TODO: compass feedback)
tylerjw 6:2bd373ba18ae 131 break;
tylerjw 6:2bd373ba18ae 132 case RIGHT: // right
tylerjw 6:2bd373ba18ae 133 if (oldState == LEFT) { // previous left turn
tylerjw 6:2bd373ba18ae 134 left.pulsewidth(UNWIND); // wind forward
tylerjw 6:2bd373ba18ae 135 Thread::wait(HOLD);
tylerjw 6:2bd373ba18ae 136 left.pulsewidth(STOP); // HOLD
tylerjw 6:2bd373ba18ae 137 } else if (oldState == RIGHT) // previous right turn
tylerjw 6:2bd373ba18ae 138 break;
tylerjw 6:2bd373ba18ae 139 //initiate right turn
tylerjw 6:2bd373ba18ae 140 right.pulsewidth(WIND); // wind back
tylerjw 6:2bd373ba18ae 141 Thread::wait(HOLD); // 0.5 second turn (TODO: compass feedback)
tylerjw 6:2bd373ba18ae 142 break;
tylerjw 6:2bd373ba18ae 143 }
tylerjw 6:2bd373ba18ae 144 oldState = state;
tylerjw 6:2bd373ba18ae 145 right.pulsewidth(STOP);
tylerjw 6:2bd373ba18ae 146 left.pulsewidth(STOP);
tylerjw 6:2bd373ba18ae 147 }
tylerjw 6:2bd373ba18ae 148
tylerjw 6:2bd373ba18ae 149 }
tylerjw 6:2bd373ba18ae 150
tylerjw 6:2bd373ba18ae 151 /**
tylerjw 6:2bd373ba18ae 152 main thread
tylerjw 6:2bd373ba18ae 153 this thread initializes everything then recieves messages from the xbee and sends messages to the parachute
tylerjw 6:2bd373ba18ae 154 */
tylerjw 0:043ed5bb10f2 155 int main (void) {
tylerjw 0:043ed5bb10f2 156 status_led = 0x9;
tylerjw 0:043ed5bb10f2 157 // setup watchdog
tylerjw 0:043ed5bb10f2 158 wdt.kick(2.0); // 2 second watchdog
tylerjw 0:043ed5bb10f2 159 // setup xbee serial
tylerjw 0:043ed5bb10f2 160 xbee.baud(9600);
tylerjw 0:043ed5bb10f2 161
tylerjw 0:043ed5bb10f2 162 Thread thread1(xbee_thread);
tylerjw 6:2bd373ba18ae 163 Thread thread2(parachute_thread);
tylerjw 0:043ed5bb10f2 164
tylerjw 0:043ed5bb10f2 165 while (true) {
tylerjw 0:043ed5bb10f2 166
tylerjw 6:2bd373ba18ae 167 osEvent evt_xbee = queue_xbee.get(1000); // wait for 1 second
tylerjw 0:043ed5bb10f2 168
tylerjw 6:2bd373ba18ae 169 if (evt_xbee.status == osEventMessage) {
tylerjw 6:2bd373ba18ae 170 message_xbee *message_x = (message_xbee*)evt_xbee.value.p;
tylerjw 6:2bd373ba18ae 171 printf("\nMessage from xbee: %c\n\r", message_x->msg);
tylerjw 6:2bd373ba18ae 172
tylerjw 6:2bd373ba18ae 173 message_para *message_p = mpool_para.alloc();
tylerjw 6:2bd373ba18ae 174
tylerjw 6:2bd373ba18ae 175 switch (message_x->msg) {
tylerjw 0:043ed5bb10f2 176 case 'L': // turn left
tylerjw 0:043ed5bb10f2 177 status_led = 0x3;
tylerjw 6:2bd373ba18ae 178 message_p->state = LEFT;
tylerjw 0:043ed5bb10f2 179 break;
tylerjw 0:043ed5bb10f2 180 case 'C': // center
tylerjw 0:043ed5bb10f2 181 status_led = 0x6;
tylerjw 6:2bd373ba18ae 182 message_p->state = CENTER;
tylerjw 0:043ed5bb10f2 183 break;
tylerjw 0:043ed5bb10f2 184 case 'R': // turn right
tylerjw 0:043ed5bb10f2 185 status_led = 0xC;
tylerjw 6:2bd373ba18ae 186 message_p->state = RIGHT;
tylerjw 0:043ed5bb10f2 187 break;
tylerjw 0:043ed5bb10f2 188 case 'F': // flare
tylerjw 0:043ed5bb10f2 189 status_led = 0xF;
tylerjw 6:2bd373ba18ae 190 message_p->state = CENTER;
tylerjw 0:043ed5bb10f2 191 break;
tylerjw 0:043ed5bb10f2 192 }
tylerjw 0:043ed5bb10f2 193
tylerjw 6:2bd373ba18ae 194 queue_para.put(message_p);
tylerjw 6:2bd373ba18ae 195 mpool_xbee.free(message_x);
tylerjw 0:043ed5bb10f2 196 }
tylerjw 0:043ed5bb10f2 197 wdt.kick();
tylerjw 0:043ed5bb10f2 198 }
tylerjw 0:043ed5bb10f2 199 }