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