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.
Main.cpp
- Committer:
- Roietronics
- Date:
- 2017-11-29
- Revision:
- 10:43337cc2ac79
- Parent:
- 8:494f6fcecfbc
- Child:
- 11:00cb0217ce8a
File content as of revision 10:43337cc2ac79:
/* Run Honeywell Dust Sensor in continous Sampling Mode on a mDot
Version 1.1
Steve Mylroie Roitronic August 1st 2017
@C Copyright Global Quality Corp
*/
#include "mbed.h"
#include "stdlib.h"
#define VERSION "2.0"
#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 high 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
//Auto Mode measurement response 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
#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
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 and wrutes
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");
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");
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 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);
/*
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("Second Character was %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:
puts("Data Reading Error");
break;
}
}
}
}