Test firmware for the Supermote hardware.
Dependencies: K30_I2C libxDot-mbed5
Fork of K30_I2C_Program by
HPM/hpm.cpp
- Committer:
- bjenkins
- Date:
- 2018-09-14
- Revision:
- 3:2ab969b31f6b
- Parent:
- 2:680fc2690d10
File content as of revision 3:2ab969b31f6b:
#include "mbed.h" #include "hpm.h" HPM::HPM(Serial* device, Serial* debug): _device(device), _debug(debug) { } bool HPM::init(void) { _debug->printf("Initialising the PM sensor\r\n"); wait(1.0); _debug->printf("PM baud rate set to 9600\r\n"); _device->baud(9600); wait(0.1); // Stop autosend if (!this->stop_autosend()) { _debug->printf("Stop autosend failed\r\n"); return 0; } _debug->printf("Stop autosend success\r\n"); // Start fan if (!this->start_measurement()) { _debug->printf("Start measurement failed\r\n"); return 0; } _debug->printf("Start measurement success\r\n"); return 1; } bool HPM::start_measurement(void) { clear_rx_buffer(); // First, we send the command unsigned char start_measurement[] = {0x68, 0x01, 0x01, 0x96 }; for (int i=0; i<sizeof(start_measurement); i++) { while (!_device->writeable()); // wait until we can write to the port _device->putc(start_measurement[i]); } //Then we wait for the response while (!_device->readable()) {} // wait until chars arrive char read1 = _device->getc(); while (!_device->readable()) {} // wait until chars arrive 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) { clear_rx_buffer(); // First, we send the command unsigned char stop_measurement[] = {0x68, 0x01, 0x01, 0x95 }; for (int i=0; i<sizeof(stop_measurement); i++) { while (!_device->writeable()); // wait until we can write to the port _device->putc(stop_measurement[i]); } //Then we wait for the response while (!_device->readable()) {} // wait until chars arrive char read1 = _device->getc(); while(!_device->readable()); 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) { clear_rx_buffer(); // Send the command 0x68 0x01 0x04 0x93 unsigned char read_particle[] = {0x68, 0x01, 0x04, 0x93 }; for (int i=0; i<sizeof(read_particle); i++) { while (!_device->writeable()); // wait until we can write to the port _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; } } _debug->printf ("HEAD=%X, LEN=%X\r\n", HEAD, LEN); return 0; } bool HPM::stop_autosend(void) { clear_rx_buffer(); // Stop auto send unsigned char stop_autosend[] = {0x68, 0x01, 0x20, 0x77 }; for (int i=0; i<sizeof(stop_autosend); i++) { while (!_device->writeable()); // wait until we can write to the port _device->putc(stop_autosend[i]); } //Then we wait for the response while(!_device->readable()); char read1 = _device->getc(); while(!_device->readable()); 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 { _debug->printf ("stop_autosend() output is %X%X\r\n", read1, read2); return 0; } } bool HPM::start_autosend(void) { clear_rx_buffer(); // Start auto send unsigned char start_autosend[] = {0x68, 0x01, 0x40, 0x57 }; for (int i=0; i<sizeof(start_autosend); i++) { while (!_device->writeable()); // wait until we can write to the port _device->putc(start_autosend[i]); } //Then we wait for the response while(!_device->readable()); char read1 = _device->getc(); while(!_device->readable()); 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 { _debug->printf ("start_autosend() output is %X%X\r\n", read1, read2); return 0; } } void HPM::clear_rx_buffer(void) { // ensure the Rx buffer is empty. clear out the crap while (_device->readable()) { unsigned char dummy = _device->getc(); } }