mDot
/
Honneywell_Dust_Simple
Initial checkin
Revision 16:6550040fbdf4, committed 2017-12-03
- Comitter:
- Roietronics
- Date:
- Sun Dec 03 00:24:46 2017 +0000
- Parent:
- 15:5ba877be4304
- Parent:
- 14:0e9566546fda
- Commit message:
- Merge Jacob's changes
Changed in this revision
Main.cpp | Show annotated file Show diff for this revision Revisions of this file |
Main.cpp.orig | Show annotated file Show diff for this revision Revisions of this file |
--- a/Main.cpp Sun Dec 03 00:05:11 2017 +0000 +++ b/Main.cpp Sun Dec 03 00:24:46 2017 +0000 @@ -50,10 +50,11 @@ } void logTrace(uint8_t data) { - if (debugLevel > 2 ){ pc.putc( data ); - } - return; - } + if (debugLevel > 2 ){ + pc.putc( data ); + } + return; +} //Board specfic serial port pin definitions @@ -115,14 +116,14 @@ msgType = NAK_MSG; msgLen = RESPONSE_MSG_LEN; break; - } } + } if(msgLen-- > 0 ) { //Insert Character into type ahead buffer *bufferPtr++ = data; - } } + } return; - } +} //Read last message received from type ahead message buffer //Mbed 5 Serial class only supports single character read and writes or @@ -130,8 +131,8 @@ MSG_TYPE readBuffer(uint8_t* buffer, uint16_t count) { if(buffer == NULL || count > AUTO_MSG_LEN ) { //Calling without buffer or - return READ_ERROR; //asking for too many chars - } //is an error + return READ_ERROR; //asking for too many chars + } //is an error int counter = 0; uint8_t* inPointer; uint8_t* outPointer; @@ -142,34 +143,35 @@ counter++; if(counter > 40) { //Timeout exit after 40 character 40 Charcter times break; - } } + } counter = 0; while(msgLen > 0 ) { //Wait for complete message to arrive delay = CHAR_TIME * msgLen; Thread::wait(delay); counter++; if(counter > 40) { //Time out exit after 40 character times + pc.printf("msgLen: %d", msgLen); break; - } } + } if(counter > 40 ) { //Report timeout error msgType = UNKNOWN; return READ_ERROR; - } + } else { //Copy the message minus type flag to the requesters buffer inPointer = &dataBuffer[1]; outPointer = buffer; for(int i = 0; i < count; i++) { *outPointer++ = *inPointer++; - } } + } MSG_TYPE temp = msgType; //Start Search for the next message msgType = UNKNOWN; return temp; - } +} void writeBuffer(const uint8_t* buffer, uint16_t count) @@ -184,56 +186,56 @@ logTrace(*pointer); sensor.putc(*pointer++); counter--; - } + } if(counter == 0) { return; - } } - } + } +} //Validate the received mesurements checksum bool checkValue(uint8_t *thebuf, uint8_t leng) { - bool receiveflag = false; - uint16_t receiveSum = 0; - - //Don't include the checksum bytes in the sum - for(int i=0; i<(leng-3); i++){ - receiveSum=receiveSum+thebuf[i]; - } - receiveSum=receiveSum + 0x42; - - if(receiveSum == ((thebuf[leng-2]<<8)+thebuf[leng-1])) //check the debug data - { - receiveSum = 0; - receiveflag = true; - } - return receiveflag; + bool receiveflag = false; + uint16_t receiveSum = 0; + + //Don't include the checksum bytes in the sum + for(int i=0; i<(leng-3); i++){ + receiveSum=receiveSum+thebuf[i]; + } + receiveSum=receiveSum + 0x42; + + if(receiveSum == ((thebuf[leng-2]<<8)+thebuf[leng-1])) //check the debug data + { + receiveSum = 0; + receiveflag = true; + } + return receiveflag; } //Extract the 1 micron particle count from the messaage uint16_t transmitPM01(uint8_t *thebuf) { - uint16_t PM01Val; - PM01Val=((thebuf[3]<<8) + thebuf[4]); //count PM1.0 value of the air detector module - return PM01Val; + uint16_t PM01Val; + PM01Val=((thebuf[3]<<8) + thebuf[4]); //count PM1.0 value of the air detector module + return PM01Val; } //Extract the 2.5 micron particle count from the messaage uint16_t transmitPM2_5(uint8_t *thebuf) { - uint16_t PM2_5Val; - PM2_5Val=((thebuf[5]<<8) + thebuf[6]);//count PM2.5 value of the air detector module - return PM2_5Val; - } + uint16_t PM2_5Val; + PM2_5Val=((thebuf[5]<<8) + thebuf[6]);//count PM2.5 value of the air detector module + return PM2_5Val; +} //Extract the 10 micron particle count from the messaage uint16_t transmitPM10(uint8_t *thebuf) { - uint16_t PM10Val; - PM10Val=((thebuf[7]<<8) + thebuf[8]); //count PM10 value of the air detector module - return PM10Val; + uint16_t PM10Val; + PM10Val=((thebuf[7]<<8) + thebuf[8]); //count PM10 value of the air detector module + return PM10Val; } int main() @@ -276,22 +278,22 @@ //Start continous loop while(1) { - if((mType = readBuffer(dataBuffer,MESSAGE_LEN -1)) == AUTO_MSG) { + if((mType = readBuffer(dataBuffer, MESSAGE_LEN -1)) == AUTO_MSG) { if(dataBuffer[0] == 0x4d){ - if(checkValue(dataBuffer, MESSAGE_LEN-1)){ - PM01Value = transmitPM01(dataBuffer); //count PM1.0 value of the air detector module - PM2_5Value = transmitPM2_5(dataBuffer);//count PM2.5 value of the air detector module - PM10Value = transmitPM10(dataBuffer); //count PM10 value of the air detector module + if(checkValue(dataBuffer, MESSAGE_LEN-1)){ + PM01Value = transmitPM01(dataBuffer); //count PM1.0 value of the air detector module + PM2_5Value = transmitPM2_5(dataBuffer);//count PM2.5 value of the air detector module + PM10Value = transmitPM10(dataBuffer); //count PM10 value of the air detector module } - else { - pc.puts("Message checksum error\n"); + else { + pc.puts("Message checksum error\n"); } - } + } else { pc.printf("Error Second Character not 0x4d but #x\n", dataBuffer[0]); } //Check for exit request - if(pc.readable()) { + if(pc.readable()) { // Returning false here char input = pc.getc(); if(input == 'Q' || input == 'q') { @@ -301,9 +303,9 @@ sensor.attach(0, Serial::RxIrq); pc.puts("Exit request received\n"); return 0; - } } - // Use MBed wait function instead of Arduino delay loop + } + // Use MBed wait function instead of Arduino delay loop wait_ms(1000); pc.printf("PM1.0: %d ug/m3\n", PM01Value); @@ -313,29 +315,36 @@ pc.printf("PM10: %d ug/m3\n", PM10Value); pc.printf("\n"); - } - else { - switch(mType) { - case ACK_MSG: + } + else { + switch(mType) { + case ACK_MSG: if(dataBuffer[0] == 0xA5) { pc.puts("Recived ACK response'\n"); - } + } else { pc.puts("Received corrupt ACK Response\n"); - } + } break; - case NAK_MSG: + case NAK_MSG: if(dataBuffer[0] == 0x69) { pc.puts("Recived NAK response'\n"); - } + } else { pc.puts("Received corrupt NAK Response\n"); - } + } break; - case READ_ERROR: - pc.puts("Data Reading Error\n"); + case READ_ERROR: + pc.puts("Data Reading Error\n"); +#ifdef DEBUG + pc.printf("\nMESSAGE_LEN: %d\n",msgLen); + for (int index = 0; index < MESSAGE_LEN - msgLen; index++) { + pc.putc(dataBuffer[index]); + } + pc.putc('\n'); +#endif break; - } } + } } } \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Main.cpp.orig Sun Dec 03 00:24:46 2017 +0000 @@ -0,0 +1,341 @@ +/* Run Honeywell Dust Sensor in continous Sampling Mode on a mDot or + Freedom K64 board + Version 2.2 + Steve Mylroie Roitronic December 2 2017 + @C Copyright 2017 Global Quality Corp +*/ + +#include "mbed.h" +#include "stdlib.h" + +#define VERSION "2.2" + +#define TRACE_MODE + +//Turn on trace logging to the PC USB port +#ifdef TRACE_MODE +//Log level need to be set one level higher than the highest level to be output +#define LOG_LEVEL 2 +#define DEBUG +#endif + + +const uint8_t* measureCommand = "68014057"; +const uint8_t* stopCommand = "68012077"; + +//Sensor command response codes +#define OK 0xA5A5 +#define BAD 0x9696 + +//Maximum response message lenght +#define MESSAGE_LEN 32 + +//sensor measurement cycle in millseconds +#define MEASURE_DELAY 1500 + +Serial pc(USBTX, USBRX, 115200); + +//Use USB debug pott for the debug stream +#ifdef DEBUG +uint32_t debugLevel = LOG_LEVEL; +#else +uint32_t debugLevel = 0; +#endif + +void logInfo(char* text) { + if ( debugLevel > 0 ) { + pc.printf("\n%s\n", text ); + } + return; + } + +void logTrace(uint8_t data) { + if (debugLevel > 2 ){ pc.putc( data ); + } + return; + } + +//Board specfic serial port pin definitions + +#ifdef TARGET_Freescale //Freedom Board + +#define SENSOR_XMT D1 +#define SENSOR_RCV D0 + +#endif + +#ifdef TARGET_MTS_MDOT_F411RE //Multi Tech mDot + +#define SENSOR_XMT PA_2 +#define SENSOR_RCV PA_3 + +#endif + +//Number of character following the +#define RESPONSE_MSG_LEN 2 +#define AUTO_MSG_LEN 32 + +//Time required to receive one character at 9600 baud +#define CHAR_TIME (1000 * 10)/9600 + +enum MSG_TYPE{ UNKNOWN, + ACK_MSG, + NAK_MSG, + AUTO_MSG, + READ_ERROR } msgType; + + +uint8_t dataBuffer[AUTO_MSG_LEN]; +uint8_t* bufferPtr; +uint32_t msgLen; + + +//Use a boards second UART to communicate witb the Honneywell sensor +//Default UART setting are 8,N,1 +RawSerial sensor( SENSOR_XMT, SENSOR_RCV, 9600); + +//Serial Received chararter interupt handler + +void receiveInterrupt() { + uint8_t data; + if(sensor.readable()) { + data = sensor.getc(); + if(msgType == UNKNOWN) { //Start of a new message + bufferPtr = dataBuffer; + switch(data) { //Switch on message type character + case 0x42: + msgType = AUTO_MSG; + msgLen = AUTO_MSG_LEN; + break; + case 0xA5: + msgType = ACK_MSG; + msgLen = RESPONSE_MSG_LEN; + break; + case 0x69: + msgType = NAK_MSG; + msgLen = RESPONSE_MSG_LEN; + break; + } + } + if(msgLen-- > 0 ) { //Insert Character into type ahead buffer + *bufferPtr++ = data; + } + } + return; + } + +//Read last message received from type ahead message buffer +//Mbed 5 Serial class only supports single character read and writes or +// async buffer reads and wrutes +MSG_TYPE readBuffer(uint8_t* buffer, uint16_t count) +{ + if(buffer == NULL || count > AUTO_MSG_LEN ) { //Calling without buffer or + return READ_ERROR; //asking for too many chars + } //is an error + int counter = 0; + uint8_t* inPointer; + uint8_t* outPointer; + int delay; + logInfo( "Reading last message from sensor\n"); + while(msgType == UNKNOWN ) { //No message received since last read + Thread::wait(CHAR_TIME); //Wait for new message + counter++; + if(counter > 40) { //Timeout exit after 40 character 40 Charcter times + break; + } + } + counter = 0; + while(msgLen > 0 ) { //Wait for complete message to arrive + delay = CHAR_TIME * msgLen; + Thread::wait(delay); + counter++; + if(counter > 40) { //Time out exit after 40 character times + break; + } + } + if(counter > 40 ) { //Report timeout error + msgType = UNKNOWN; + return READ_ERROR; + } + else { + //Copy the message minus type flag to the requesters buffer + inPointer = &dataBuffer[1]; + outPointer = buffer; + for(int i = 0; i < count; i++) { + *outPointer++ = *inPointer++; + } + } + MSG_TYPE temp = msgType; + //Start Search for the next message + msgType = UNKNOWN; + return temp; + } + + +void writeBuffer(const uint8_t* buffer, uint16_t count) +{ + logInfo( "Sending Command to sensor\n"); + uint8_t* pointer = (uint8_t*)buffer; + uint16_t counter = count; + while(1) + { + if(sensor.writeable()) + { + logTrace(*pointer); + sensor.putc(*pointer++); + counter--; + } + if(counter == 0) { + return; + } + } + } + +//Validate the received mesurements checksum + +bool checkValue(uint8_t *thebuf, uint8_t leng) +{ + bool receiveflag = false; + uint16_t receiveSum = 0; + + //Don't include the checksum bytes in the sum + for(int i=0; i<(leng-3); i++){ + receiveSum=receiveSum+thebuf[i]; + } + receiveSum=receiveSum + 0x42; + + if(receiveSum == ((thebuf[leng-2]<<8)+thebuf[leng-1])) //check the debug data + { + receiveSum = 0; + receiveflag = true; + } + return receiveflag; +} + +//Extract the 1 micron particle count from the messaage +uint16_t transmitPM01(uint8_t *thebuf) +{ + uint16_t PM01Val; + PM01Val=((thebuf[3]<<8) + thebuf[4]); //count PM1.0 value of the air detector module + return PM01Val; +} + +//Extract the 2.5 micron particle count from the messaage +uint16_t transmitPM2_5(uint8_t *thebuf) +{ + uint16_t PM2_5Val; + PM2_5Val=((thebuf[5]<<8) + thebuf[6]);//count PM2.5 value of the air detector module + return PM2_5Val; + } + +//Extract the 10 micron particle count from the messaage +uint16_t transmitPM10(uint8_t *thebuf) +{ + uint16_t PM10Val; + PM10Val=((thebuf[7]<<8) + thebuf[8]); //count PM10 value of the air detector module + return PM10Val; +} + +int main() +{ + uint8_t dataBuffer[MESSAGE_LEN]; + MSG_TYPE mType; + uint16_t PM01Value=0; //define PM1.0 value of the air detector module + uint16_t PM2_5Value=0; //define PM2.5 value of the air detector module + uint16_t PM10Value=0; //define PM10 value of the air detector module + + pc.printf("Starting Honeywell Dust Sesor App version %\n", VERSION); + + #ifdef DEBIG + pc.printf("Character wait time is %d millseconds", CHAR_TIME); + #endif + //Attach a receive interrupt handler + sensor.attach(receiveInterrupt, Serial::RxIrq); + msgType = UNKNOWN; + //Send start command to the sensor + writeBuffer(measureCommand, 4); + /* + Not geting response from sensor - first characters received are measurement data + //Wait for sensors response + //while(!sensor.readable()); + readBuffer(dataBuffer, 2); + response = dataBuffer[0] << 8 || dataBuffer[1]; + + switch(response) { + case OK: + logInfo("Sensor Auto Measurement Started"); + break; + case BAD: + logInfo("Sensor rejected Start Measurement Commmand"); + return -1; + default: + logInfo("Communication Error: Invalid Sensor Response"); + return -2; + } +*/ + + //Start continous loop + while(1) { + if((mType = readBuffer(dataBuffer,MESSAGE_LEN -1)) == AUTO_MSG) { + if(dataBuffer[0] == 0x4d){ + if(checkValue(dataBuffer, MESSAGE_LEN-1)){ + PM01Value = transmitPM01(dataBuffer); //count PM1.0 value of the air detector module + PM2_5Value = transmitPM2_5(dataBuffer);//count PM2.5 value of the air detector module + PM10Value = transmitPM10(dataBuffer); //count PM10 value of the air detector module + } + else { + pc.puts("Message checksum error\n"); + } + } + else { + pc.printf("Error Second Character not 0x4d but #x\n", dataBuffer[0]); + } + //Check for exit request + if(pc.readable()) { + char input = pc.getc(); + if(input == 'Q' || input == 'q') + { + //Shutdown the sensor + writeBuffer(stopCommand, 4); + //Unlink the receive interrupt handler + sensor.attach(0, Serial::RxIrq); + pc.puts("Exit request received\n"); + return 0; + } + } + // Use MBed wait function instead of Arduino delay loop + wait_ms(1000); + + pc.printf("PM1.0: %d ug/m3\n", PM01Value); + + pc.printf("PM2.5: %d ug/m3\n", PM2_5Value); + + pc.printf("PM10: %d ug/m3\n", PM10Value); + + pc.printf("\n"); + } + else { + switch(mType) { + case ACK_MSG: + if(dataBuffer[0] == 0xA5) { + pc.puts("Recived ACK response'\n"); + } + else { + pc.puts("Received corrupt ACK Response\n"); + } + break; + case NAK_MSG: + if(dataBuffer[0] == 0x69) { + pc.puts("Recived NAK response'\n"); + } + else { + pc.puts("Received corrupt NAK Response\n"); + } + break; + case READ_ERROR: + pc.puts("Data Reading Error\n"); + break; + } + } + } + } \ No newline at end of file