Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
HARP: High Altitude Recovery Payload
Information
Version 0.1: RC design

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.
main.cpp@6:2bd373ba18ae, 2012-08-07 (annotated)
- 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?
| User | Revision | Line number | New 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 | } | 
