mDot / Mbed OS Honneywell_Dust_Simple
Committer:
Roietronics
Date:
Sun Dec 03 00:24:46 2017 +0000
Revision:
16:6550040fbdf4
Merge Jacob's changes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Roietronics 16:6550040fbdf4 1 /* Run Honeywell Dust Sensor in continous Sampling Mode on a mDot or
Roietronics 16:6550040fbdf4 2 Freedom K64 board
Roietronics 16:6550040fbdf4 3 Version 2.2
Roietronics 16:6550040fbdf4 4 Steve Mylroie Roitronic December 2 2017
Roietronics 16:6550040fbdf4 5 @C Copyright 2017 Global Quality Corp
Roietronics 16:6550040fbdf4 6 */
Roietronics 16:6550040fbdf4 7
Roietronics 16:6550040fbdf4 8 #include "mbed.h"
Roietronics 16:6550040fbdf4 9 #include "stdlib.h"
Roietronics 16:6550040fbdf4 10
Roietronics 16:6550040fbdf4 11 #define VERSION "2.2"
Roietronics 16:6550040fbdf4 12
Roietronics 16:6550040fbdf4 13 #define TRACE_MODE
Roietronics 16:6550040fbdf4 14
Roietronics 16:6550040fbdf4 15 //Turn on trace logging to the PC USB port
Roietronics 16:6550040fbdf4 16 #ifdef TRACE_MODE
Roietronics 16:6550040fbdf4 17 //Log level need to be set one level higher than the highest level to be output
Roietronics 16:6550040fbdf4 18 #define LOG_LEVEL 2
Roietronics 16:6550040fbdf4 19 #define DEBUG
Roietronics 16:6550040fbdf4 20 #endif
Roietronics 16:6550040fbdf4 21
Roietronics 16:6550040fbdf4 22
Roietronics 16:6550040fbdf4 23 const uint8_t* measureCommand = "68014057";
Roietronics 16:6550040fbdf4 24 const uint8_t* stopCommand = "68012077";
Roietronics 16:6550040fbdf4 25
Roietronics 16:6550040fbdf4 26 //Sensor command response codes
Roietronics 16:6550040fbdf4 27 #define OK 0xA5A5
Roietronics 16:6550040fbdf4 28 #define BAD 0x9696
Roietronics 16:6550040fbdf4 29
Roietronics 16:6550040fbdf4 30 //Maximum response message lenght
Roietronics 16:6550040fbdf4 31 #define MESSAGE_LEN 32
Roietronics 16:6550040fbdf4 32
Roietronics 16:6550040fbdf4 33 //sensor measurement cycle in millseconds
Roietronics 16:6550040fbdf4 34 #define MEASURE_DELAY 1500
Roietronics 16:6550040fbdf4 35
Roietronics 16:6550040fbdf4 36 Serial pc(USBTX, USBRX, 115200);
Roietronics 16:6550040fbdf4 37
Roietronics 16:6550040fbdf4 38 //Use USB debug pott for the debug stream
Roietronics 16:6550040fbdf4 39 #ifdef DEBUG
Roietronics 16:6550040fbdf4 40 uint32_t debugLevel = LOG_LEVEL;
Roietronics 16:6550040fbdf4 41 #else
Roietronics 16:6550040fbdf4 42 uint32_t debugLevel = 0;
Roietronics 16:6550040fbdf4 43 #endif
Roietronics 16:6550040fbdf4 44
Roietronics 16:6550040fbdf4 45 void logInfo(char* text) {
Roietronics 16:6550040fbdf4 46 if ( debugLevel > 0 ) {
Roietronics 16:6550040fbdf4 47 pc.printf("\n%s\n", text );
Roietronics 16:6550040fbdf4 48 }
Roietronics 16:6550040fbdf4 49 return;
Roietronics 16:6550040fbdf4 50 }
Roietronics 16:6550040fbdf4 51
Roietronics 16:6550040fbdf4 52 void logTrace(uint8_t data) {
Roietronics 16:6550040fbdf4 53 if (debugLevel > 2 ){ pc.putc( data );
Roietronics 16:6550040fbdf4 54 }
Roietronics 16:6550040fbdf4 55 return;
Roietronics 16:6550040fbdf4 56 }
Roietronics 16:6550040fbdf4 57
Roietronics 16:6550040fbdf4 58 //Board specfic serial port pin definitions
Roietronics 16:6550040fbdf4 59
Roietronics 16:6550040fbdf4 60 #ifdef TARGET_Freescale //Freedom Board
Roietronics 16:6550040fbdf4 61
Roietronics 16:6550040fbdf4 62 #define SENSOR_XMT D1
Roietronics 16:6550040fbdf4 63 #define SENSOR_RCV D0
Roietronics 16:6550040fbdf4 64
Roietronics 16:6550040fbdf4 65 #endif
Roietronics 16:6550040fbdf4 66
Roietronics 16:6550040fbdf4 67 #ifdef TARGET_MTS_MDOT_F411RE //Multi Tech mDot
Roietronics 16:6550040fbdf4 68
Roietronics 16:6550040fbdf4 69 #define SENSOR_XMT PA_2
Roietronics 16:6550040fbdf4 70 #define SENSOR_RCV PA_3
Roietronics 16:6550040fbdf4 71
Roietronics 16:6550040fbdf4 72 #endif
Roietronics 16:6550040fbdf4 73
Roietronics 16:6550040fbdf4 74 //Number of character following the
Roietronics 16:6550040fbdf4 75 #define RESPONSE_MSG_LEN 2
Roietronics 16:6550040fbdf4 76 #define AUTO_MSG_LEN 32
Roietronics 16:6550040fbdf4 77
Roietronics 16:6550040fbdf4 78 //Time required to receive one character at 9600 baud
Roietronics 16:6550040fbdf4 79 #define CHAR_TIME (1000 * 10)/9600
Roietronics 16:6550040fbdf4 80
Roietronics 16:6550040fbdf4 81 enum MSG_TYPE{ UNKNOWN,
Roietronics 16:6550040fbdf4 82 ACK_MSG,
Roietronics 16:6550040fbdf4 83 NAK_MSG,
Roietronics 16:6550040fbdf4 84 AUTO_MSG,
Roietronics 16:6550040fbdf4 85 READ_ERROR } msgType;
Roietronics 16:6550040fbdf4 86
Roietronics 16:6550040fbdf4 87
Roietronics 16:6550040fbdf4 88 uint8_t dataBuffer[AUTO_MSG_LEN];
Roietronics 16:6550040fbdf4 89 uint8_t* bufferPtr;
Roietronics 16:6550040fbdf4 90 uint32_t msgLen;
Roietronics 16:6550040fbdf4 91
Roietronics 16:6550040fbdf4 92
Roietronics 16:6550040fbdf4 93 //Use a boards second UART to communicate witb the Honneywell sensor
Roietronics 16:6550040fbdf4 94 //Default UART setting are 8,N,1
Roietronics 16:6550040fbdf4 95 RawSerial sensor( SENSOR_XMT, SENSOR_RCV, 9600);
Roietronics 16:6550040fbdf4 96
Roietronics 16:6550040fbdf4 97 //Serial Received chararter interupt handler
Roietronics 16:6550040fbdf4 98
Roietronics 16:6550040fbdf4 99 void receiveInterrupt() {
Roietronics 16:6550040fbdf4 100 uint8_t data;
Roietronics 16:6550040fbdf4 101 if(sensor.readable()) {
Roietronics 16:6550040fbdf4 102 data = sensor.getc();
Roietronics 16:6550040fbdf4 103 if(msgType == UNKNOWN) { //Start of a new message
Roietronics 16:6550040fbdf4 104 bufferPtr = dataBuffer;
Roietronics 16:6550040fbdf4 105 switch(data) { //Switch on message type character
Roietronics 16:6550040fbdf4 106 case 0x42:
Roietronics 16:6550040fbdf4 107 msgType = AUTO_MSG;
Roietronics 16:6550040fbdf4 108 msgLen = AUTO_MSG_LEN;
Roietronics 16:6550040fbdf4 109 break;
Roietronics 16:6550040fbdf4 110 case 0xA5:
Roietronics 16:6550040fbdf4 111 msgType = ACK_MSG;
Roietronics 16:6550040fbdf4 112 msgLen = RESPONSE_MSG_LEN;
Roietronics 16:6550040fbdf4 113 break;
Roietronics 16:6550040fbdf4 114 case 0x69:
Roietronics 16:6550040fbdf4 115 msgType = NAK_MSG;
Roietronics 16:6550040fbdf4 116 msgLen = RESPONSE_MSG_LEN;
Roietronics 16:6550040fbdf4 117 break;
Roietronics 16:6550040fbdf4 118 }
Roietronics 16:6550040fbdf4 119 }
Roietronics 16:6550040fbdf4 120 if(msgLen-- > 0 ) { //Insert Character into type ahead buffer
Roietronics 16:6550040fbdf4 121 *bufferPtr++ = data;
Roietronics 16:6550040fbdf4 122 }
Roietronics 16:6550040fbdf4 123 }
Roietronics 16:6550040fbdf4 124 return;
Roietronics 16:6550040fbdf4 125 }
Roietronics 16:6550040fbdf4 126
Roietronics 16:6550040fbdf4 127 //Read last message received from type ahead message buffer
Roietronics 16:6550040fbdf4 128 //Mbed 5 Serial class only supports single character read and writes or
Roietronics 16:6550040fbdf4 129 // async buffer reads and wrutes
Roietronics 16:6550040fbdf4 130 MSG_TYPE readBuffer(uint8_t* buffer, uint16_t count)
Roietronics 16:6550040fbdf4 131 {
Roietronics 16:6550040fbdf4 132 if(buffer == NULL || count > AUTO_MSG_LEN ) { //Calling without buffer or
Roietronics 16:6550040fbdf4 133 return READ_ERROR; //asking for too many chars
Roietronics 16:6550040fbdf4 134 } //is an error
Roietronics 16:6550040fbdf4 135 int counter = 0;
Roietronics 16:6550040fbdf4 136 uint8_t* inPointer;
Roietronics 16:6550040fbdf4 137 uint8_t* outPointer;
Roietronics 16:6550040fbdf4 138 int delay;
Roietronics 16:6550040fbdf4 139 logInfo( "Reading last message from sensor\n");
Roietronics 16:6550040fbdf4 140 while(msgType == UNKNOWN ) { //No message received since last read
Roietronics 16:6550040fbdf4 141 Thread::wait(CHAR_TIME); //Wait for new message
Roietronics 16:6550040fbdf4 142 counter++;
Roietronics 16:6550040fbdf4 143 if(counter > 40) { //Timeout exit after 40 character 40 Charcter times
Roietronics 16:6550040fbdf4 144 break;
Roietronics 16:6550040fbdf4 145 }
Roietronics 16:6550040fbdf4 146 }
Roietronics 16:6550040fbdf4 147 counter = 0;
Roietronics 16:6550040fbdf4 148 while(msgLen > 0 ) { //Wait for complete message to arrive
Roietronics 16:6550040fbdf4 149 delay = CHAR_TIME * msgLen;
Roietronics 16:6550040fbdf4 150 Thread::wait(delay);
Roietronics 16:6550040fbdf4 151 counter++;
Roietronics 16:6550040fbdf4 152 if(counter > 40) { //Time out exit after 40 character times
Roietronics 16:6550040fbdf4 153 break;
Roietronics 16:6550040fbdf4 154 }
Roietronics 16:6550040fbdf4 155 }
Roietronics 16:6550040fbdf4 156 if(counter > 40 ) { //Report timeout error
Roietronics 16:6550040fbdf4 157 msgType = UNKNOWN;
Roietronics 16:6550040fbdf4 158 return READ_ERROR;
Roietronics 16:6550040fbdf4 159 }
Roietronics 16:6550040fbdf4 160 else {
Roietronics 16:6550040fbdf4 161 //Copy the message minus type flag to the requesters buffer
Roietronics 16:6550040fbdf4 162 inPointer = &dataBuffer[1];
Roietronics 16:6550040fbdf4 163 outPointer = buffer;
Roietronics 16:6550040fbdf4 164 for(int i = 0; i < count; i++) {
Roietronics 16:6550040fbdf4 165 *outPointer++ = *inPointer++;
Roietronics 16:6550040fbdf4 166 }
Roietronics 16:6550040fbdf4 167 }
Roietronics 16:6550040fbdf4 168 MSG_TYPE temp = msgType;
Roietronics 16:6550040fbdf4 169 //Start Search for the next message
Roietronics 16:6550040fbdf4 170 msgType = UNKNOWN;
Roietronics 16:6550040fbdf4 171 return temp;
Roietronics 16:6550040fbdf4 172 }
Roietronics 16:6550040fbdf4 173
Roietronics 16:6550040fbdf4 174
Roietronics 16:6550040fbdf4 175 void writeBuffer(const uint8_t* buffer, uint16_t count)
Roietronics 16:6550040fbdf4 176 {
Roietronics 16:6550040fbdf4 177 logInfo( "Sending Command to sensor\n");
Roietronics 16:6550040fbdf4 178 uint8_t* pointer = (uint8_t*)buffer;
Roietronics 16:6550040fbdf4 179 uint16_t counter = count;
Roietronics 16:6550040fbdf4 180 while(1)
Roietronics 16:6550040fbdf4 181 {
Roietronics 16:6550040fbdf4 182 if(sensor.writeable())
Roietronics 16:6550040fbdf4 183 {
Roietronics 16:6550040fbdf4 184 logTrace(*pointer);
Roietronics 16:6550040fbdf4 185 sensor.putc(*pointer++);
Roietronics 16:6550040fbdf4 186 counter--;
Roietronics 16:6550040fbdf4 187 }
Roietronics 16:6550040fbdf4 188 if(counter == 0) {
Roietronics 16:6550040fbdf4 189 return;
Roietronics 16:6550040fbdf4 190 }
Roietronics 16:6550040fbdf4 191 }
Roietronics 16:6550040fbdf4 192 }
Roietronics 16:6550040fbdf4 193
Roietronics 16:6550040fbdf4 194 //Validate the received mesurements checksum
Roietronics 16:6550040fbdf4 195
Roietronics 16:6550040fbdf4 196 bool checkValue(uint8_t *thebuf, uint8_t leng)
Roietronics 16:6550040fbdf4 197 {
Roietronics 16:6550040fbdf4 198 bool receiveflag = false;
Roietronics 16:6550040fbdf4 199 uint16_t receiveSum = 0;
Roietronics 16:6550040fbdf4 200
Roietronics 16:6550040fbdf4 201 //Don't include the checksum bytes in the sum
Roietronics 16:6550040fbdf4 202 for(int i=0; i<(leng-3); i++){
Roietronics 16:6550040fbdf4 203 receiveSum=receiveSum+thebuf[i];
Roietronics 16:6550040fbdf4 204 }
Roietronics 16:6550040fbdf4 205 receiveSum=receiveSum + 0x42;
Roietronics 16:6550040fbdf4 206
Roietronics 16:6550040fbdf4 207 if(receiveSum == ((thebuf[leng-2]<<8)+thebuf[leng-1])) //check the debug data
Roietronics 16:6550040fbdf4 208 {
Roietronics 16:6550040fbdf4 209 receiveSum = 0;
Roietronics 16:6550040fbdf4 210 receiveflag = true;
Roietronics 16:6550040fbdf4 211 }
Roietronics 16:6550040fbdf4 212 return receiveflag;
Roietronics 16:6550040fbdf4 213 }
Roietronics 16:6550040fbdf4 214
Roietronics 16:6550040fbdf4 215 //Extract the 1 micron particle count from the messaage
Roietronics 16:6550040fbdf4 216 uint16_t transmitPM01(uint8_t *thebuf)
Roietronics 16:6550040fbdf4 217 {
Roietronics 16:6550040fbdf4 218 uint16_t PM01Val;
Roietronics 16:6550040fbdf4 219 PM01Val=((thebuf[3]<<8) + thebuf[4]); //count PM1.0 value of the air detector module
Roietronics 16:6550040fbdf4 220 return PM01Val;
Roietronics 16:6550040fbdf4 221 }
Roietronics 16:6550040fbdf4 222
Roietronics 16:6550040fbdf4 223 //Extract the 2.5 micron particle count from the messaage
Roietronics 16:6550040fbdf4 224 uint16_t transmitPM2_5(uint8_t *thebuf)
Roietronics 16:6550040fbdf4 225 {
Roietronics 16:6550040fbdf4 226 uint16_t PM2_5Val;
Roietronics 16:6550040fbdf4 227 PM2_5Val=((thebuf[5]<<8) + thebuf[6]);//count PM2.5 value of the air detector module
Roietronics 16:6550040fbdf4 228 return PM2_5Val;
Roietronics 16:6550040fbdf4 229 }
Roietronics 16:6550040fbdf4 230
Roietronics 16:6550040fbdf4 231 //Extract the 10 micron particle count from the messaage
Roietronics 16:6550040fbdf4 232 uint16_t transmitPM10(uint8_t *thebuf)
Roietronics 16:6550040fbdf4 233 {
Roietronics 16:6550040fbdf4 234 uint16_t PM10Val;
Roietronics 16:6550040fbdf4 235 PM10Val=((thebuf[7]<<8) + thebuf[8]); //count PM10 value of the air detector module
Roietronics 16:6550040fbdf4 236 return PM10Val;
Roietronics 16:6550040fbdf4 237 }
Roietronics 16:6550040fbdf4 238
Roietronics 16:6550040fbdf4 239 int main()
Roietronics 16:6550040fbdf4 240 {
Roietronics 16:6550040fbdf4 241 uint8_t dataBuffer[MESSAGE_LEN];
Roietronics 16:6550040fbdf4 242 MSG_TYPE mType;
Roietronics 16:6550040fbdf4 243 uint16_t PM01Value=0; //define PM1.0 value of the air detector module
Roietronics 16:6550040fbdf4 244 uint16_t PM2_5Value=0; //define PM2.5 value of the air detector module
Roietronics 16:6550040fbdf4 245 uint16_t PM10Value=0; //define PM10 value of the air detector module
Roietronics 16:6550040fbdf4 246
Roietronics 16:6550040fbdf4 247 pc.printf("Starting Honeywell Dust Sesor App version %\n", VERSION);
Roietronics 16:6550040fbdf4 248
Roietronics 16:6550040fbdf4 249 #ifdef DEBIG
Roietronics 16:6550040fbdf4 250 pc.printf("Character wait time is %d millseconds", CHAR_TIME);
Roietronics 16:6550040fbdf4 251 #endif
Roietronics 16:6550040fbdf4 252 //Attach a receive interrupt handler
Roietronics 16:6550040fbdf4 253 sensor.attach(receiveInterrupt, Serial::RxIrq);
Roietronics 16:6550040fbdf4 254 msgType = UNKNOWN;
Roietronics 16:6550040fbdf4 255 //Send start command to the sensor
Roietronics 16:6550040fbdf4 256 writeBuffer(measureCommand, 4);
Roietronics 16:6550040fbdf4 257 /*
Roietronics 16:6550040fbdf4 258 Not geting response from sensor - first characters received are measurement data
Roietronics 16:6550040fbdf4 259 //Wait for sensors response
Roietronics 16:6550040fbdf4 260 //while(!sensor.readable());
Roietronics 16:6550040fbdf4 261 readBuffer(dataBuffer, 2);
Roietronics 16:6550040fbdf4 262 response = dataBuffer[0] << 8 || dataBuffer[1];
Roietronics 16:6550040fbdf4 263
Roietronics 16:6550040fbdf4 264 switch(response) {
Roietronics 16:6550040fbdf4 265 case OK:
Roietronics 16:6550040fbdf4 266 logInfo("Sensor Auto Measurement Started");
Roietronics 16:6550040fbdf4 267 break;
Roietronics 16:6550040fbdf4 268 case BAD:
Roietronics 16:6550040fbdf4 269 logInfo("Sensor rejected Start Measurement Commmand");
Roietronics 16:6550040fbdf4 270 return -1;
Roietronics 16:6550040fbdf4 271 default:
Roietronics 16:6550040fbdf4 272 logInfo("Communication Error: Invalid Sensor Response");
Roietronics 16:6550040fbdf4 273 return -2;
Roietronics 16:6550040fbdf4 274 }
Roietronics 16:6550040fbdf4 275 */
Roietronics 16:6550040fbdf4 276
Roietronics 16:6550040fbdf4 277 //Start continous loop
Roietronics 16:6550040fbdf4 278 while(1) {
Roietronics 16:6550040fbdf4 279 if((mType = readBuffer(dataBuffer,MESSAGE_LEN -1)) == AUTO_MSG) {
Roietronics 16:6550040fbdf4 280 if(dataBuffer[0] == 0x4d){
Roietronics 16:6550040fbdf4 281 if(checkValue(dataBuffer, MESSAGE_LEN-1)){
Roietronics 16:6550040fbdf4 282 PM01Value = transmitPM01(dataBuffer); //count PM1.0 value of the air detector module
Roietronics 16:6550040fbdf4 283 PM2_5Value = transmitPM2_5(dataBuffer);//count PM2.5 value of the air detector module
Roietronics 16:6550040fbdf4 284 PM10Value = transmitPM10(dataBuffer); //count PM10 value of the air detector module
Roietronics 16:6550040fbdf4 285 }
Roietronics 16:6550040fbdf4 286 else {
Roietronics 16:6550040fbdf4 287 pc.puts("Message checksum error\n");
Roietronics 16:6550040fbdf4 288 }
Roietronics 16:6550040fbdf4 289 }
Roietronics 16:6550040fbdf4 290 else {
Roietronics 16:6550040fbdf4 291 pc.printf("Error Second Character not 0x4d but #x\n", dataBuffer[0]);
Roietronics 16:6550040fbdf4 292 }
Roietronics 16:6550040fbdf4 293 //Check for exit request
Roietronics 16:6550040fbdf4 294 if(pc.readable()) {
Roietronics 16:6550040fbdf4 295 char input = pc.getc();
Roietronics 16:6550040fbdf4 296 if(input == 'Q' || input == 'q')
Roietronics 16:6550040fbdf4 297 {
Roietronics 16:6550040fbdf4 298 //Shutdown the sensor
Roietronics 16:6550040fbdf4 299 writeBuffer(stopCommand, 4);
Roietronics 16:6550040fbdf4 300 //Unlink the receive interrupt handler
Roietronics 16:6550040fbdf4 301 sensor.attach(0, Serial::RxIrq);
Roietronics 16:6550040fbdf4 302 pc.puts("Exit request received\n");
Roietronics 16:6550040fbdf4 303 return 0;
Roietronics 16:6550040fbdf4 304 }
Roietronics 16:6550040fbdf4 305 }
Roietronics 16:6550040fbdf4 306 // Use MBed wait function instead of Arduino delay loop
Roietronics 16:6550040fbdf4 307 wait_ms(1000);
Roietronics 16:6550040fbdf4 308
Roietronics 16:6550040fbdf4 309 pc.printf("PM1.0: %d ug/m3\n", PM01Value);
Roietronics 16:6550040fbdf4 310
Roietronics 16:6550040fbdf4 311 pc.printf("PM2.5: %d ug/m3\n", PM2_5Value);
Roietronics 16:6550040fbdf4 312
Roietronics 16:6550040fbdf4 313 pc.printf("PM10: %d ug/m3\n", PM10Value);
Roietronics 16:6550040fbdf4 314
Roietronics 16:6550040fbdf4 315 pc.printf("\n");
Roietronics 16:6550040fbdf4 316 }
Roietronics 16:6550040fbdf4 317 else {
Roietronics 16:6550040fbdf4 318 switch(mType) {
Roietronics 16:6550040fbdf4 319 case ACK_MSG:
Roietronics 16:6550040fbdf4 320 if(dataBuffer[0] == 0xA5) {
Roietronics 16:6550040fbdf4 321 pc.puts("Recived ACK response'\n");
Roietronics 16:6550040fbdf4 322 }
Roietronics 16:6550040fbdf4 323 else {
Roietronics 16:6550040fbdf4 324 pc.puts("Received corrupt ACK Response\n");
Roietronics 16:6550040fbdf4 325 }
Roietronics 16:6550040fbdf4 326 break;
Roietronics 16:6550040fbdf4 327 case NAK_MSG:
Roietronics 16:6550040fbdf4 328 if(dataBuffer[0] == 0x69) {
Roietronics 16:6550040fbdf4 329 pc.puts("Recived NAK response'\n");
Roietronics 16:6550040fbdf4 330 }
Roietronics 16:6550040fbdf4 331 else {
Roietronics 16:6550040fbdf4 332 pc.puts("Received corrupt NAK Response\n");
Roietronics 16:6550040fbdf4 333 }
Roietronics 16:6550040fbdf4 334 break;
Roietronics 16:6550040fbdf4 335 case READ_ERROR:
Roietronics 16:6550040fbdf4 336 pc.puts("Data Reading Error\n");
Roietronics 16:6550040fbdf4 337 break;
Roietronics 16:6550040fbdf4 338 }
Roietronics 16:6550040fbdf4 339 }
Roietronics 16:6550040fbdf4 340 }
Roietronics 16:6550040fbdf4 341 }