M1DK Skywire Demo

Dependencies:   SHT30-DIS-B mbed

Fork of M1DK_Skywire_Demo by Greg Nash

Committer:
kylerodgers
Date:
Fri Jun 08 20:31:12 2018 +0000
Revision:
14:6a94410202bb
Parent:
13:f827f384f0a1
Increased verbosity and added in socket and Skywire network setup commands.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kholland 4:e7a79d3542e1 1 /* main.cpp */
kylerodgers 14:6a94410202bb 2 /* V2 */
kylerodgers 14:6a94410202bb 3 /* Copyright (C) 2018 nimbelink.com, MIT License
kholland 4:e7a79d3542e1 4 *
kholland 4:e7a79d3542e1 5 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
kholland 4:e7a79d3542e1 6 * and associated documentation files (the "Software"), to deal in the Software without restriction,
kholland 4:e7a79d3542e1 7 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
kholland 4:e7a79d3542e1 8 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
kholland 4:e7a79d3542e1 9 * furnished to do so, subject to the following conditions:
kholland 4:e7a79d3542e1 10 *
kholland 4:e7a79d3542e1 11 * The above copyright notice and this permission notice shall be included in all copies or
kholland 4:e7a79d3542e1 12 * substantial portions of the Software.
kholland 4:e7a79d3542e1 13 *
kholland 4:e7a79d3542e1 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
kholland 4:e7a79d3542e1 15 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
kholland 4:e7a79d3542e1 16 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
kholland 4:e7a79d3542e1 17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
kholland 4:e7a79d3542e1 18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
kholland 4:e7a79d3542e1 19 */
kholland 0:3095958bc639 20
kholland 10:5974a7b2cf38 21 /*
kholland 10:5974a7b2cf38 22 * DESCRIPTION
kylerodgers 13:f827f384f0a1 23 * This code sends sensor data to Dweet.io on the NL-M1DK.
kholland 10:5974a7b2cf38 24 */
kholland 10:5974a7b2cf38 25
kholland 10:5974a7b2cf38 26 /*
kholland 10:5974a7b2cf38 27 * INSTRUCTIONS FOR USING THIS CODE
kylerodgers 13:f827f384f0a1 28 * 1. Change the "DeviceID" to a unique identifier for your Nucleo board. One recommendation
kholland 10:5974a7b2cf38 29 * would be to use the MEID/IMEI of your Skywire Modem.
kholland 10:5974a7b2cf38 30 */
kholland 10:5974a7b2cf38 31
GregNash 11:78a28ca6409f 32 #include "mbed.h" // mbed Library
GregNash 11:78a28ca6409f 33 #include "pinmap.h" // pinmap needed for hardware flow control
GregNash 11:78a28ca6409f 34
GregNash 11:78a28ca6409f 35 #include "SHT30DISB.h"
kholland 0:3095958bc639 36
GregNash 11:78a28ca6409f 37 // --CHANGE THIS FOR YOUR SETUP--
kylerodgers 14:6a94410202bb 38 #define DeviceID "thingname" //DweetIO unique ID
GregNash 11:78a28ca6409f 39
GregNash 11:78a28ca6409f 40 // --CHANGE THIS FOR YOUR SETUP (IF APPLICABLE)--
kylerodgers 13:f827f384f0a1 41 const char *APN = "NIMBLINK.GW12.VZWENTP";
kholland 0:3095958bc639 42
kholland 10:5974a7b2cf38 43 DigitalOut myled(LED1); // Main LED
kylerodgers 13:f827f384f0a1 44 DigitalOut skywire_rts(PB_5); // Skywire Send
kylerodgers 13:f827f384f0a1 45 DigitalOut green_LED(D7); // Green LED
kylerodgers 13:f827f384f0a1 46 DigitalOut red_LED(D10); // Red LED
kholland 0:3095958bc639 47
kylerodgers 13:f827f384f0a1 48 DigitalOut nRESET(PB_4); // Skywire Reset line
kylerodgers 13:f827f384f0a1 49
kylerodgers 13:f827f384f0a1 50 AnalogIn photo_trans(A3); // Photo Transistor
kylerodgers 13:f827f384f0a1 51 DigitalOut photo_trans_nEN(D11); // Photo Transistor Enable
kylerodgers 13:f827f384f0a1 52 DigitalIn button1(PA_5); // Button 1
kholland 10:5974a7b2cf38 53
kholland 10:5974a7b2cf38 54 Serial skywire(PA_9,PA_10); // Serial comms to Skywire
kholland 10:5974a7b2cf38 55 Serial debug_pc(USBTX, USBRX); // USB connection to PC
kholland 10:5974a7b2cf38 56
kholland 10:5974a7b2cf38 57 I2C i2c(PB_9,PB_8); // Setup I2C bus for sensors
GregNash 11:78a28ca6409f 58
kylerodgers 13:f827f384f0a1 59 // SHT30 Sensor Setup
kylerodgers 13:f827f384f0a1 60 SHT30DISB SHT30(i2c);
kholland 10:5974a7b2cf38 61
kylerodgers 13:f827f384f0a1 62 // variable to switch state
kylerodgers 13:f827f384f0a1 63 bool sw1;
kholland 0:3095958bc639 64
kholland 10:5974a7b2cf38 65 // char array for reading from Skywire
kholland 3:4b2176f6474c 66 char str[255];
kylerodgers 13:f827f384f0a1 67
kylerodgers 13:f827f384f0a1 68 // Variables for checking CSQ
GregNash 11:78a28ca6409f 69 char csq[3]="99";
GregNash 11:78a28ca6409f 70 int csq_val = 99;
kholland 3:4b2176f6474c 71
kholland 10:5974a7b2cf38 72 // Variables for UART comms
kholland 3:4b2176f6474c 73 volatile int rx_in=0;
kholland 3:4b2176f6474c 74 volatile int rx_out=0;
kholland 10:5974a7b2cf38 75 const int buffer_size = 600;
kholland 3:4b2176f6474c 76 char rx_buffer[buffer_size+1];
kholland 3:4b2176f6474c 77 char rx_line[buffer_size];
kholland 3:4b2176f6474c 78
kholland 10:5974a7b2cf38 79 // Interrupt for the Skywire
kholland 10:5974a7b2cf38 80 void Skywire_Rx_interrupt()
kholland 10:5974a7b2cf38 81 {
kholland 3:4b2176f6474c 82 // Loop just in case more than one character is in UART's receive FIFO buffer
kholland 3:4b2176f6474c 83 // Stop if buffer full
kholland 3:4b2176f6474c 84 while ((skywire.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) {
kholland 3:4b2176f6474c 85 rx_buffer[rx_in] = skywire.getc();
kholland 3:4b2176f6474c 86 rx_in = (rx_in + 1) % buffer_size;
kholland 3:4b2176f6474c 87 }
kholland 3:4b2176f6474c 88 return;
kholland 3:4b2176f6474c 89 }
kholland 3:4b2176f6474c 90
kholland 10:5974a7b2cf38 91 // Read line from the UART
kholland 10:5974a7b2cf38 92 void read_line()
kholland 10:5974a7b2cf38 93 {
kholland 3:4b2176f6474c 94 int i;
kholland 3:4b2176f6474c 95 i = 0;
kholland 3:4b2176f6474c 96 // Start Critical Section - don't interrupt while changing global buffer variables
kholland 3:4b2176f6474c 97 __disable_irq();
kholland 3:4b2176f6474c 98 // Loop reading rx buffer characters until end of line character
kholland 3:4b2176f6474c 99 while ((i==0) || (rx_line[i-1] != '\n')) {
kholland 3:4b2176f6474c 100 // Wait if buffer empty
kholland 3:4b2176f6474c 101 if (rx_in == rx_out) {
kholland 3:4b2176f6474c 102 // End Critical Section - need to allow rx interrupt to get new characters for buffer
kholland 3:4b2176f6474c 103 __enable_irq();
kholland 3:4b2176f6474c 104 while (rx_in == rx_out) {
kholland 3:4b2176f6474c 105 }
kholland 3:4b2176f6474c 106 // Start Critical Section - don't interrupt while changing global buffer variables
kholland 3:4b2176f6474c 107 __disable_irq();
kholland 3:4b2176f6474c 108 }
kholland 3:4b2176f6474c 109 rx_line[i] = rx_buffer[rx_out];
kholland 3:4b2176f6474c 110 i++;
kholland 3:4b2176f6474c 111 rx_out = (rx_out + 1) % buffer_size;
kholland 3:4b2176f6474c 112 }
kholland 3:4b2176f6474c 113 // End Critical Section
kholland 3:4b2176f6474c 114 __enable_irq();
kholland 3:4b2176f6474c 115 rx_line[i-1] = 0;
kholland 3:4b2176f6474c 116 return;
kholland 3:4b2176f6474c 117 }
kholland 10:5974a7b2cf38 118
kholland 10:5974a7b2cf38 119 // Wait for specific response
GregNash 11:78a28ca6409f 120 int WaitForResponse(const char *response)
kholland 10:5974a7b2cf38 121 {
GregNash 11:78a28ca6409f 122 debug_pc.printf("Command sent. Waiting for: %s\r\n", response);
kholland 3:4b2176f6474c 123 do {
kholland 3:4b2176f6474c 124 read_line();
kylerodgers 13:f827f384f0a1 125 // If we get ERROR, return with 1
kylerodgers 13:f827f384f0a1 126 if (strncmp(rx_line, "ERROR", strlen("ERROR")) == 0) {
kylerodgers 13:f827f384f0a1 127 debug_pc.printf("ERROR\r\n");
kylerodgers 13:f827f384f0a1 128 return 1;
kylerodgers 13:f827f384f0a1 129 }
kholland 3:4b2176f6474c 130 debug_pc.printf("Waiting for: %s, Recieved: %s\r\n", response, rx_line);
GregNash 11:78a28ca6409f 131 } while (strncmp(rx_line, response, strlen(response)));
GregNash 11:78a28ca6409f 132 return 0;
GregNash 11:78a28ca6409f 133 }
GregNash 11:78a28ca6409f 134
kylerodgers 13:f827f384f0a1 135 // Send AT+CSQ until we get a good signal
GregNash 11:78a28ca6409f 136 int GetCSQResponse()
GregNash 11:78a28ca6409f 137 {
GregNash 11:78a28ca6409f 138 do {
GregNash 11:78a28ca6409f 139 skywire.printf("AT+CSQ\r");
GregNash 11:78a28ca6409f 140 WaitForResponse("OK");
GregNash 11:78a28ca6409f 141 csq[0]=rx_line[6];
GregNash 11:78a28ca6409f 142 csq[1]=rx_line[7];
GregNash 11:78a28ca6409f 143 csq_val=atoi(csq);
GregNash 11:78a28ca6409f 144 } while (!strncmp(rx_line, "CSQ: 99,", 8));
GregNash 11:78a28ca6409f 145 return csq_val;
GregNash 11:78a28ca6409f 146 }
GregNash 11:78a28ca6409f 147
kholland 10:5974a7b2cf38 148 int main()
kholland 0:3095958bc639 149 {
GregNash 11:78a28ca6409f 150 red_LED = 1;
GregNash 11:78a28ca6409f 151
kholland 0:3095958bc639 152 float temp;
kylerodgers 7:00d66e743603 153 float humi;
GregNash 11:78a28ca6409f 154 float photo;
kholland 0:3095958bc639 155
kholland 10:5974a7b2cf38 156 // Setup serial comms with Skywire and PC
kholland 0:3095958bc639 157 debug_pc.baud(115200);
kylerodgers 13:f827f384f0a1 158 skywire.baud(921600);
kylerodgers 13:f827f384f0a1 159 skywire_rts = 0;
kholland 10:5974a7b2cf38 160 debug_pc.printf("SystemCoreClock = %d Hz\r\n", SystemCoreClock);
kylerodgers 13:f827f384f0a1 161 debug_pc.printf("Attaching interrupt...\r\n");
kholland 3:4b2176f6474c 162 skywire.attach(&Skywire_Rx_interrupt, Serial::RxIrq);
kylerodgers 13:f827f384f0a1 163 debug_pc.printf("Interrupt attached...\r\n");
kholland 10:5974a7b2cf38 164
kylerodgers 13:f827f384f0a1 165 // Reset the Skywire to get AT commands, and recover from any previous state
kylerodgers 14:6a94410202bb 166 debug_pc.printf("Resetting Skywire. This gets the Skywire into a known state.\r\n");
kylerodgers 14:6a94410202bb 167 wait_ms(1000);
kylerodgers 13:f827f384f0a1 168 nRESET = 1;
kylerodgers 13:f827f384f0a1 169 wait_ms(100);
kylerodgers 13:f827f384f0a1 170 nRESET = 0;
kylerodgers 13:f827f384f0a1 171 wait(3);
kylerodgers 14:6a94410202bb 172 debug_pc.printf("\r\n");
kylerodgers 14:6a94410202bb 173 debug_pc.printf("Resetting baud. This reduced the baudrate on your Skywire for reliability\r\n");
kylerodgers 13:f827f384f0a1 174 skywire.printf("\rAT+IPR=115200\r");
kylerodgers 13:f827f384f0a1 175 wait_ms(100);
kylerodgers 13:f827f384f0a1 176 skywire.baud(115200);
kylerodgers 13:f827f384f0a1 177 wait_ms(100);
kylerodgers 14:6a94410202bb 178 debug_pc.printf("\r\n");
kylerodgers 13:f827f384f0a1 179 debug_pc.printf("Baud reset!\r\n");
kholland 0:3095958bc639 180 myled=0;
kylerodgers 14:6a94410202bb 181 debug_pc.printf("\r\n");
kholland 3:4b2176f6474c 182 debug_pc.printf("Starting Demo...\r\n");
kylerodgers 13:f827f384f0a1 183 green_LED = !green_LED;
kholland 3:4b2176f6474c 184 myled=1;
kylerodgers 13:f827f384f0a1 185 wait_ms(100);
kylerodgers 14:6a94410202bb 186
kylerodgers 14:6a94410202bb 187 debug_pc.printf("\r\n");
kylerodgers 14:6a94410202bb 188 debug_pc.printf("Generally, you send a command and wait for a response.\r\n");
kylerodgers 14:6a94410202bb 189 debug_pc.printf("Depending on the response, you may need to take action.\r\n");
kylerodgers 14:6a94410202bb 190 debug_pc.printf("You'll need to wait for the response to the previous command\r\n");
kylerodgers 14:6a94410202bb 191 debug_pc.printf("to finish before continuing on to the next command.\r\n");
kylerodgers 14:6a94410202bb 192 debug_pc.printf("Sending AT to clear out previous commands.\r\n");
kylerodgers 14:6a94410202bb 193 debug_pc.printf("\r\n");
kylerodgers 14:6a94410202bb 194 wait_ms(1000);
kylerodgers 14:6a94410202bb 195 skywire.printf("\r\r");
kylerodgers 14:6a94410202bb 196 skywire.printf("AT\r");
kylerodgers 14:6a94410202bb 197 WaitForResponse("OK");
kylerodgers 14:6a94410202bb 198 debug_pc.printf("\r\n");
kylerodgers 14:6a94410202bb 199 debug_pc.printf("Enabling echo to make it easier to see commands\r\n");
kylerodgers 14:6a94410202bb 200 skywire.printf("ATE1\r");
kylerodgers 14:6a94410202bb 201 WaitForResponse("OK");
kylerodgers 14:6a94410202bb 202 debug_pc.printf("\r\n");
kylerodgers 14:6a94410202bb 203 debug_pc.printf("Setting up Skywire network settings\r\n");
kylerodgers 14:6a94410202bb 204 skywire.printf("AT+SQNAUTOINTERNET=1\r");
kylerodgers 14:6a94410202bb 205 WaitForResponse("OK");
kylerodgers 14:6a94410202bb 206 skywire.printf("AT^AUTOATT=1\r");
kylerodgers 14:6a94410202bb 207 WaitForResponse("OK");
kylerodgers 14:6a94410202bb 208 skywire.printf("AT+SQNAUTOCONNECT=1\r");
kylerodgers 14:6a94410202bb 209 WaitForResponse("OK");
kholland 10:5974a7b2cf38 210
kylerodgers 14:6a94410202bb 211 debug_pc.printf("\r\n");
kylerodgers 14:6a94410202bb 212 debug_pc.printf("Setting up socket...\r\n");
kylerodgers 14:6a94410202bb 213 skywire.printf("AT+SQNSCFG=3,3,300,90,600,5\r");
GregNash 11:78a28ca6409f 214 WaitForResponse("OK");
kylerodgers 14:6a94410202bb 215 debug_pc.printf("\r\n");
kylerodgers 14:6a94410202bb 216 debug_pc.printf("Resetting Skywire to get into known state\r\n");
kylerodgers 14:6a94410202bb 217 skywire.printf("AT^RESET\r");
kylerodgers 14:6a94410202bb 218 WaitForResponse("OK");
kylerodgers 14:6a94410202bb 219 WaitForResponse("+SYSSTART");
kylerodgers 13:f827f384f0a1 220 WaitForResponse("+CEREG: 1");
GregNash 11:78a28ca6409f 221
kylerodgers 13:f827f384f0a1 222 // Check CSQ
GregNash 11:78a28ca6409f 223 debug_pc.printf("Getting CSQ...\r\n");
GregNash 11:78a28ca6409f 224 GetCSQResponse();
kylerodgers 13:f827f384f0a1 225 green_LED = !green_LED;
GregNash 11:78a28ca6409f 226 while(csq_val==99 || csq_val==0)
GregNash 11:78a28ca6409f 227 {
GregNash 11:78a28ca6409f 228
GregNash 11:78a28ca6409f 229 debug_pc.printf("CSQ Value: %i\r\n",csq_val);
GregNash 11:78a28ca6409f 230 debug_pc.printf("No network sginal detected. \r\n");
GregNash 11:78a28ca6409f 231 debug_pc.printf("Waiting for device to connect to the network. \r\n");
GregNash 11:78a28ca6409f 232 debug_pc.printf("Please check antenna connections if network is not found after 30 seconds. \r\n");
GregNash 11:78a28ca6409f 233 wait(1);
GregNash 11:78a28ca6409f 234 //add elapsed time
GregNash 11:78a28ca6409f 235 debug_pc.printf("Checking network connectrion. \r\n");
GregNash 11:78a28ca6409f 236 GetCSQResponse();
GregNash 11:78a28ca6409f 237 red_LED = !red_LED;
kylerodgers 14:6a94410202bb 238 }
GregNash 11:78a28ca6409f 239
kylerodgers 14:6a94410202bb 240 debug_pc.printf("\r\n");
GregNash 11:78a28ca6409f 241 debug_pc.printf("Network detected. Checking authorization...\r\n");
kylerodgers 13:f827f384f0a1 242 skywire.printf("AT+CEREG?\r");
GregNash 11:78a28ca6409f 243 WaitForResponse("OK");
kylerodgers 7:00d66e743603 244
GregNash 11:78a28ca6409f 245 red_LED = 1;
GregNash 11:78a28ca6409f 246 green_LED = 0;
GregNash 11:78a28ca6409f 247
kylerodgers 14:6a94410202bb 248 debug_pc.printf("\r\n");
kylerodgers 14:6a94410202bb 249 debug_pc.printf("Everything is setup, and you're registered on the network.\r\n");
kylerodgers 14:6a94410202bb 250 debug_pc.printf("Entering the socket dial loop.\r\n");
kylerodgers 14:6a94410202bb 251
kholland 0:3095958bc639 252 while(1) {
kholland 10:5974a7b2cf38 253 // Green on to indicate code position
kholland 10:5974a7b2cf38 254 // Start of loop. Either entered loop for the first time or just sent to dweet.io
kholland 10:5974a7b2cf38 255 red_LED = 0;
kholland 10:5974a7b2cf38 256 green_LED = 1;
kylerodgers 13:f827f384f0a1 257
kylerodgers 14:6a94410202bb 258 debug_pc.printf("Opening the socket\r\n");
kylerodgers 13:f827f384f0a1 259 int retries = 0;
kylerodgers 13:f827f384f0a1 260 while (retries < 5) {
kylerodgers 13:f827f384f0a1 261 skywire.printf("AT+SQNSD=3,0,80,\"dweet.io\"\r");
kylerodgers 13:f827f384f0a1 262 if (WaitForResponse("CONNECT") == 1) {
kylerodgers 13:f827f384f0a1 263 retries += 1;
kylerodgers 13:f827f384f0a1 264 wait(1);
kylerodgers 14:6a94410202bb 265 } else {
kylerodgers 14:6a94410202bb 266
kylerodgers 13:f827f384f0a1 267 break;
kylerodgers 14:6a94410202bb 268 }
GregNash 11:78a28ca6409f 269 }
kylerodgers 14:6a94410202bb 270 debug_pc.printf("\r\n");
kylerodgers 14:6a94410202bb 271 debug_pc.printf("Socket open!\r\n");
kylerodgers 14:6a94410202bb 272 debug_pc.printf("\r\n");
kylerodgers 14:6a94410202bb 273 debug_pc.printf("Updating sensors\r\n");
kylerodgers 13:f827f384f0a1 274 //get temp and humi
GregNash 11:78a28ca6409f 275 temp=SHT30.cTemp();
GregNash 11:78a28ca6409f 276 humi=SHT30.humidity();
GregNash 11:78a28ca6409f 277 photo_trans_nEN=0;
GregNash 11:78a28ca6409f 278 photo=photo_trans*200;
kholland 10:5974a7b2cf38 279 wait(1);
kholland 10:5974a7b2cf38 280
kholland 10:5974a7b2cf38 281 // Check buttons for presses
kholland 10:5974a7b2cf38 282 if (button1 == 0)
kylerodgers 13:f827f384f0a1 283 sw1 = 1;
kholland 10:5974a7b2cf38 284 else
kylerodgers 13:f827f384f0a1 285 sw1 = 0;
kholland 3:4b2176f6474c 286
kholland 10:5974a7b2cf38 287 // Green on to indicate code position:
kholland 10:5974a7b2cf38 288 // Sensors updated, have not sent to dweet.io
kholland 10:5974a7b2cf38 289 red_LED = 1;
kholland 10:5974a7b2cf38 290 green_LED = 0;
kylerodgers 14:6a94410202bb 291 debug_pc.printf("\r\n");
kylerodgers 14:6a94410202bb 292 debug_pc.printf("Sensors updated!\r\n");
kylerodgers 14:6a94410202bb 293 debug_pc.printf("\r\n");
kylerodgers 14:6a94410202bb 294 debug_pc.printf("Sending information\r\n");
kylerodgers 13:f827f384f0a1 295 if (retries != 5) {
kylerodgers 14:6a94410202bb 296 retries = 0;
GregNash 11:78a28ca6409f 297 debug_pc.printf("Sending information...\r\n");
GregNash 11:78a28ca6409f 298 // Report the sensor data to dweet.io
GregNash 11:78a28ca6409f 299 skywire.printf("POST /dweet/for/%s?temp=%.3f&sw1=%d&photo=%.3f&humidity=%.3f HTTP/1.0\r\n\r\n", DeviceID, temp, sw1, photo, humi);
GregNash 11:78a28ca6409f 300 WaitForResponse("NO CARRIER");
kylerodgers 13:f827f384f0a1 301 }
kylerodgers 14:6a94410202bb 302
kylerodgers 14:6a94410202bb 303 debug_pc.printf("\r\n");
kylerodgers 14:6a94410202bb 304 debug_pc.printf("Information sent!\r\n");
kylerodgers 14:6a94410202bb 305
kylerodgers 14:6a94410202bb 306 debug_pc.printf("\r\n");
kylerodgers 13:f827f384f0a1 307 debug_pc.printf("Closing socket...\r\n");
kylerodgers 13:f827f384f0a1 308 skywire.printf("AT+SQNSH=3\r");
kylerodgers 13:f827f384f0a1 309 WaitForResponse("OK");
kholland 10:5974a7b2cf38 310 red_LED = 0;
GregNash 11:78a28ca6409f 311 green_LED = 1;
kholland 3:4b2176f6474c 312 }
GregNash 11:78a28ca6409f 313 }