mDot / Mbed OS Honneywell_Dust_Simple
Revision:
8:494f6fcecfbc
Parent:
7:5f612ed18852
Child:
10:43337cc2ac79
--- a/Main.cpp	Sat Aug 12 00:28:20 2017 +0000
+++ b/Main.cpp	Sun Aug 13 06:09:03 2017 +0000
@@ -7,7 +7,7 @@
 #include "mbed.h"
 #include "stdlib.h"
 
-#define VERSION  "1.4"
+#define VERSION  "2.0"
 
 #define TRACE_MODE
 
@@ -70,39 +70,108 @@
 
 #endif
 
+#define RESPONSE_MSG_LEN 2
+#define AUTO_MSG_LEN 32
+
+//Time required to receive one character at 9600 baud
+#define CHAR_TIME 1000/9600 & 10
+
+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
-Serial sensor( SENSOR_XMT, SENSOR_RCV);
+RawSerial sensor( SENSOR_XMT, SENSOR_RCV, 9600);
+
+//Received chararter interupt handler
+
+void receiveInterrupt() {
+    uint8_t data;
+    if(sensor.readable()) {
+        data = sensor.getc();
+        if(msgType == UNKNOWN) {
+            switch(data) {
+                case 0x42:
+                    msgType = AUTO_MSG;
+                    msgLen = AUTO_MSG_LEN;
+                    bufferPtr = dataBuffer;
+                    break;
+                case 0xA5:
+                    msgType = ACK_MSG;
+                    msgLen = RESPONSE_MSG_LEN;
+                    bufferPtr = dataBuffer;
+                    break;
+                case 0x69:
+                    msgType = NAK_MSG;
+                    msgLen = RESPONSE_MSG_LEN;
+                    bufferPtr = dataBuffer;
+                    break;
+                }
+            }
+        if(msgLen--  > 0 ) {
+            *bufferPtr++ = data;
+            }
+        }
+    return;    
+    }    
 
 //synchrnous serial read and writes
 //Mbed 5 Serial class only supports single character read and writes or
 // async buffer reads abd wrutes
-void readBuffer(uint8_t* buffer, uint16_t count)
+MSG_TYPE readBuffer(uint8_t* buffer, uint16_t count)
 {
+    if(buffer == NULL || count > AUTO_MSG_LEN ) {
+        return READ_ERROR;
+        }
+    int counter = 0;
+    uint8_t* inPointer;
+    uint8_t* outPointer;
+    int delay;
     logInfo( "Receiving Data from sensor\n");
-    uint8_t* pointer = buffer;
-    uint16_t counter = count;
-    bool firstchar = true;
-    uint8_t foo;
-    while(1)
-    {
-        if(sensor.readable())
-        {
-            foo  = sensor.getc();
-            if(firstchar) {
-                pc.putc(foo);
-                firstchar =  false;
-                }
-            *pointer++ = foo;
-            logTrace(*pointer);
-            counter--;
-            }
-        if(counter == 0) {
-            return;
+    while(msgType == UNKNOWN ) {
+        wait(CHAR_TIME);
+        counter++;
+        if(counter > 40) {
+            break;
             }
         }
+    counter = 9;    
+    while(msgLen > 0 ) {
+        delay = CHAR_TIME * msgLen;
+        wait(delay);
+        counter++;
+        if(counter > 40) {
+            break;
+            }
+        }
+    if(counter > 40 ) {
+       msgType = UNKNOWN;
+       return READ_ERROR;
+         }
+    else {
+        //Copy the message 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 Data to sensor\n");
@@ -170,13 +239,16 @@
 int main()
 {
     uint8_t dataBuffer[MESSAGE_LEN];
+    MSG_TYPE mType;
     uint16_t response;
     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);
-
+    //Attach a receive interrupt handler
+    sensor.attach(receiveInterrupt, Serial::RxIrq);
+    msgType = UNKNOWN;
     //Send start command to the sensor
     writeBuffer(measureCommand, 4);
  /*
@@ -200,19 +272,17 @@
 */    
 
     //Start continous loop 
-    while(1)
-    {
-       if(sensor.getc() == 0x42){    //start to read when detect 0x42
-            readBuffer(dataBuffer,MESSAGE_LEN -1);
+    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.printf("Message checksum error\n");
-                  }
+                pc.puts("Message checksum error\n");
+                }
               }
             else {
               pc.printf("Second Character was %x\n", dataBuffer[0]);
@@ -222,21 +292,47 @@
                 char input = pc.getc();
                 if(input == 'Q' || input == 'q')
                 { 
+                    //Shutdown the sensor
                     writeBuffer(stopCommand, 4);
-                    pc.printf("Exit request received\n");
+                    //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");
             }
-    // 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");
-      }
-    }
- }
\ No newline at end of file
+            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:
+                    puts("Data Reading Error");
+                    break;
+                    }
+                }
+        }
+    }
\ No newline at end of file