Test firmware for the Supermote hardware.
Dependencies: K30_I2C libxDot-mbed5
Fork of K30_I2C_Program by
Diff: HPM/hpm.cpp
- Revision:
- 2:680fc2690d10
- Child:
- 3:2ab969b31f6b
diff -r 15a68a12eb1e -r 680fc2690d10 HPM/hpm.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HPM/hpm.cpp Fri Sep 07 02:54:05 2018 +0000 @@ -0,0 +1,205 @@ +#include "mbed.h" +#include "hpm.h" + + +HPM::HPM(Serial* device, Serial* debug): _device(device), _debug(debug) +{ + _device->baud(9600); + wait(0.1); +} + +bool HPM::init(void) +{ + // Stop autosend + if (!this->stop_autosend()) + { + _debug->printf("Stop autosend failed\r\n"); + return 0; + } + + // Start fan + if (!this->start_measurement()) + { + _debug->printf("Start measurement failed\r\n"); + return 0; + } + + return 1; +} + +bool HPM::start_measurement(void) +{ + // First, we send the command + unsigned char start_measurement[] = {0x68, 0x01, 0x01, 0x96 }; + for (int i=0; i<sizeof(start_measurement); i++) + { + _device->putc(start_measurement[i]); + } + + //Then we wait for the response + while (!_device->readable()) {} // wait until chars arrive + char read1 = _device->getc(); + char read2 = _device->getc(); + + // Test the response + if ((read1 == 0xA5) && (read2 == 0xA5)){ + return 1; // ACK + } + else if ((read1 == 0x96) && (read2 == 0x96)) + { + _debug->printf ("NACK\r\n"); + return 0; // NACK + } + else return 0; +} + +bool HPM::stop_measurement(void) +{ + // First, we send the command + unsigned char stop_measurement[] = {0x68, 0x01, 0x01, 0x95 }; + for (int i=0; i<sizeof(stop_measurement); i++) + { + _device->putc(stop_measurement[i]); + } + + + //Then we wait for the response + while (!_device->readable()) {} // wait until chars arrive + char read1 = _device->getc(); + char read2 = _device->getc(); + + // Test the response + if ((read1 == 0xA5) && (read2 == 0xA5)){ + return 1; // ACK + } + else if ((read1 == 0x96) && (read2 == 0x96)) + { + _debug->printf ("NACK\r\n"); + return 0; // NACK + } + else return 0; +} + +bool HPM::read_measurement (long int &PM25, long int &PM10) +{ + // Send the command 0x68 0x01 0x04 0x93 + unsigned char read_particle[] = {0x68, 0x01, 0x04, 0x93 }; + for (int i=0; i<sizeof(read_particle); i++) + { + _device->putc(read_particle[i]); + } + + // A measurement can return 0X9696 for NACK + // Or can return eight bytes if successful + // We wait for the first two bytes + while(!_device->readable()); + unsigned char HEAD = _device->getc(); + + while(!_device->readable()); + unsigned char LEN = _device->getc(); + + // Test the response + if ((HEAD == 0x96) && (LEN == 0x96)) + { + _debug->printf("NACK"); + return 0; + } + else if ((HEAD == 0x40) && (LEN == 0x05)) + { + // The measuremet is valid, read the rest of the data + // wait for the next byte + while(!_device->readable()); + unsigned char COMD = _device->getc(); + + while(!_device->readable()); + unsigned char DF1 = _device->getc(); + + while(!_device->readable()); + unsigned char DF2 = _device->getc(); + + while(!_device->readable()); + unsigned char DF3 = _device->getc(); + + while(!_device->readable()); + unsigned char DF4 = _device->getc(); + + while(!_device->readable()); + unsigned char CS = _device->getc(); + + // Now we shall verify the checksum + unsigned int cs_calc = 65536; + cs_calc -= HEAD - LEN - COMD - DF1 - DF2 - DF3 - DF4; + cs_calc %= 256; + + if (((0x10000 - HEAD - LEN - COMD - DF1 - DF2 - DF3 - DF4) % 0XFF) != CS) + { + _debug->printf("Checksum fail\r\n"); + _debug->printf ("HEAD=%02x LEN=%02x COMD=%02x DF1=%02x DF2=%02x DF3=%02x DF4=%02x CS=%02x, cs_calc=%02x\r\n", HEAD, LEN, COMD, DF1, DF2, DF3, DF4, CS, cs_calc); + return 0; + } + else + { + // Checksum OK, we compute PM2.5 and PM10 values + PM25 = DF1 * 256 + DF2; + PM10 = DF3 * 256 + DF4; + return 1; + } + } + return 0; +} + +bool HPM::stop_autosend(void) +{ + // Stop auto send + unsigned char stop_autosend[] = {0x68, 0x01, 0x20, 0x77 }; + for (int i=0; i<sizeof(stop_autosend); i++) + { + _device->putc(stop_autosend[i]); + } + + //Then we wait for the response + while(!_device->readable()); + char read1 = _device->getc(); + char read2 = _device->getc(); + + // Test the response + if ((read1 == 0xA5) && (read2 == 0xA5)){ + // ACK + return 1; + } + else if ((read1 == 0x96) && (read2 == 0x96)) + { + // NACK + _debug->printf ("NACK\r\n"); + return 0; + } + else return 0; +} + +bool HPM::start_autosend(void) +{ + // Start auto send + unsigned char start_autosend[] = {0x68, 0x01, 0x40, 0x57 }; + for (int i=0; i<sizeof(start_autosend); i++) + { + _device->putc(start_autosend[i]); + } + + //Then we wait for the response + while(!_device->readable()); + char read1 = _device->getc(); + char read2 = _device->getc(); + // Test the response + if ((read1 == 0xA5) && (read2 == 0xA5)){ + // ACK + return 1; + } + else if ((read1 == 0x96) && (read2 == 0x96)) + { + // NACK + _debug->printf ("NACK\r\n"); + return 0; + + } + else return 0; +} \ No newline at end of file