Test firmware for the Supermote hardware.
Dependencies: K30_I2C libxDot-mbed5
Fork of K30_I2C_Program by
HPM/hpm.cpp@2:680fc2690d10, 2018-09-07 (annotated)
- Committer:
- bjenkins
- Date:
- Fri Sep 07 02:54:05 2018 +0000
- Revision:
- 2:680fc2690d10
- Child:
- 3:2ab969b31f6b
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
bjenkins | 2:680fc2690d10 | 1 | #include "mbed.h" |
bjenkins | 2:680fc2690d10 | 2 | #include "hpm.h" |
bjenkins | 2:680fc2690d10 | 3 | |
bjenkins | 2:680fc2690d10 | 4 | |
bjenkins | 2:680fc2690d10 | 5 | HPM::HPM(Serial* device, Serial* debug): _device(device), _debug(debug) |
bjenkins | 2:680fc2690d10 | 6 | { |
bjenkins | 2:680fc2690d10 | 7 | _device->baud(9600); |
bjenkins | 2:680fc2690d10 | 8 | wait(0.1); |
bjenkins | 2:680fc2690d10 | 9 | } |
bjenkins | 2:680fc2690d10 | 10 | |
bjenkins | 2:680fc2690d10 | 11 | bool HPM::init(void) |
bjenkins | 2:680fc2690d10 | 12 | { |
bjenkins | 2:680fc2690d10 | 13 | // Stop autosend |
bjenkins | 2:680fc2690d10 | 14 | if (!this->stop_autosend()) |
bjenkins | 2:680fc2690d10 | 15 | { |
bjenkins | 2:680fc2690d10 | 16 | _debug->printf("Stop autosend failed\r\n"); |
bjenkins | 2:680fc2690d10 | 17 | return 0; |
bjenkins | 2:680fc2690d10 | 18 | } |
bjenkins | 2:680fc2690d10 | 19 | |
bjenkins | 2:680fc2690d10 | 20 | // Start fan |
bjenkins | 2:680fc2690d10 | 21 | if (!this->start_measurement()) |
bjenkins | 2:680fc2690d10 | 22 | { |
bjenkins | 2:680fc2690d10 | 23 | _debug->printf("Start measurement failed\r\n"); |
bjenkins | 2:680fc2690d10 | 24 | return 0; |
bjenkins | 2:680fc2690d10 | 25 | } |
bjenkins | 2:680fc2690d10 | 26 | |
bjenkins | 2:680fc2690d10 | 27 | return 1; |
bjenkins | 2:680fc2690d10 | 28 | } |
bjenkins | 2:680fc2690d10 | 29 | |
bjenkins | 2:680fc2690d10 | 30 | bool HPM::start_measurement(void) |
bjenkins | 2:680fc2690d10 | 31 | { |
bjenkins | 2:680fc2690d10 | 32 | // First, we send the command |
bjenkins | 2:680fc2690d10 | 33 | unsigned char start_measurement[] = {0x68, 0x01, 0x01, 0x96 }; |
bjenkins | 2:680fc2690d10 | 34 | for (int i=0; i<sizeof(start_measurement); i++) |
bjenkins | 2:680fc2690d10 | 35 | { |
bjenkins | 2:680fc2690d10 | 36 | _device->putc(start_measurement[i]); |
bjenkins | 2:680fc2690d10 | 37 | } |
bjenkins | 2:680fc2690d10 | 38 | |
bjenkins | 2:680fc2690d10 | 39 | //Then we wait for the response |
bjenkins | 2:680fc2690d10 | 40 | while (!_device->readable()) {} // wait until chars arrive |
bjenkins | 2:680fc2690d10 | 41 | char read1 = _device->getc(); |
bjenkins | 2:680fc2690d10 | 42 | char read2 = _device->getc(); |
bjenkins | 2:680fc2690d10 | 43 | |
bjenkins | 2:680fc2690d10 | 44 | // Test the response |
bjenkins | 2:680fc2690d10 | 45 | if ((read1 == 0xA5) && (read2 == 0xA5)){ |
bjenkins | 2:680fc2690d10 | 46 | return 1; // ACK |
bjenkins | 2:680fc2690d10 | 47 | } |
bjenkins | 2:680fc2690d10 | 48 | else if ((read1 == 0x96) && (read2 == 0x96)) |
bjenkins | 2:680fc2690d10 | 49 | { |
bjenkins | 2:680fc2690d10 | 50 | _debug->printf ("NACK\r\n"); |
bjenkins | 2:680fc2690d10 | 51 | return 0; // NACK |
bjenkins | 2:680fc2690d10 | 52 | } |
bjenkins | 2:680fc2690d10 | 53 | else return 0; |
bjenkins | 2:680fc2690d10 | 54 | } |
bjenkins | 2:680fc2690d10 | 55 | |
bjenkins | 2:680fc2690d10 | 56 | bool HPM::stop_measurement(void) |
bjenkins | 2:680fc2690d10 | 57 | { |
bjenkins | 2:680fc2690d10 | 58 | // First, we send the command |
bjenkins | 2:680fc2690d10 | 59 | unsigned char stop_measurement[] = {0x68, 0x01, 0x01, 0x95 }; |
bjenkins | 2:680fc2690d10 | 60 | for (int i=0; i<sizeof(stop_measurement); i++) |
bjenkins | 2:680fc2690d10 | 61 | { |
bjenkins | 2:680fc2690d10 | 62 | _device->putc(stop_measurement[i]); |
bjenkins | 2:680fc2690d10 | 63 | } |
bjenkins | 2:680fc2690d10 | 64 | |
bjenkins | 2:680fc2690d10 | 65 | |
bjenkins | 2:680fc2690d10 | 66 | //Then we wait for the response |
bjenkins | 2:680fc2690d10 | 67 | while (!_device->readable()) {} // wait until chars arrive |
bjenkins | 2:680fc2690d10 | 68 | char read1 = _device->getc(); |
bjenkins | 2:680fc2690d10 | 69 | char read2 = _device->getc(); |
bjenkins | 2:680fc2690d10 | 70 | |
bjenkins | 2:680fc2690d10 | 71 | // Test the response |
bjenkins | 2:680fc2690d10 | 72 | if ((read1 == 0xA5) && (read2 == 0xA5)){ |
bjenkins | 2:680fc2690d10 | 73 | return 1; // ACK |
bjenkins | 2:680fc2690d10 | 74 | } |
bjenkins | 2:680fc2690d10 | 75 | else if ((read1 == 0x96) && (read2 == 0x96)) |
bjenkins | 2:680fc2690d10 | 76 | { |
bjenkins | 2:680fc2690d10 | 77 | _debug->printf ("NACK\r\n"); |
bjenkins | 2:680fc2690d10 | 78 | return 0; // NACK |
bjenkins | 2:680fc2690d10 | 79 | } |
bjenkins | 2:680fc2690d10 | 80 | else return 0; |
bjenkins | 2:680fc2690d10 | 81 | } |
bjenkins | 2:680fc2690d10 | 82 | |
bjenkins | 2:680fc2690d10 | 83 | bool HPM::read_measurement (long int &PM25, long int &PM10) |
bjenkins | 2:680fc2690d10 | 84 | { |
bjenkins | 2:680fc2690d10 | 85 | // Send the command 0x68 0x01 0x04 0x93 |
bjenkins | 2:680fc2690d10 | 86 | unsigned char read_particle[] = {0x68, 0x01, 0x04, 0x93 }; |
bjenkins | 2:680fc2690d10 | 87 | for (int i=0; i<sizeof(read_particle); i++) |
bjenkins | 2:680fc2690d10 | 88 | { |
bjenkins | 2:680fc2690d10 | 89 | _device->putc(read_particle[i]); |
bjenkins | 2:680fc2690d10 | 90 | } |
bjenkins | 2:680fc2690d10 | 91 | |
bjenkins | 2:680fc2690d10 | 92 | // A measurement can return 0X9696 for NACK |
bjenkins | 2:680fc2690d10 | 93 | // Or can return eight bytes if successful |
bjenkins | 2:680fc2690d10 | 94 | // We wait for the first two bytes |
bjenkins | 2:680fc2690d10 | 95 | while(!_device->readable()); |
bjenkins | 2:680fc2690d10 | 96 | unsigned char HEAD = _device->getc(); |
bjenkins | 2:680fc2690d10 | 97 | |
bjenkins | 2:680fc2690d10 | 98 | while(!_device->readable()); |
bjenkins | 2:680fc2690d10 | 99 | unsigned char LEN = _device->getc(); |
bjenkins | 2:680fc2690d10 | 100 | |
bjenkins | 2:680fc2690d10 | 101 | // Test the response |
bjenkins | 2:680fc2690d10 | 102 | if ((HEAD == 0x96) && (LEN == 0x96)) |
bjenkins | 2:680fc2690d10 | 103 | { |
bjenkins | 2:680fc2690d10 | 104 | _debug->printf("NACK"); |
bjenkins | 2:680fc2690d10 | 105 | return 0; |
bjenkins | 2:680fc2690d10 | 106 | } |
bjenkins | 2:680fc2690d10 | 107 | else if ((HEAD == 0x40) && (LEN == 0x05)) |
bjenkins | 2:680fc2690d10 | 108 | { |
bjenkins | 2:680fc2690d10 | 109 | // The measuremet is valid, read the rest of the data |
bjenkins | 2:680fc2690d10 | 110 | // wait for the next byte |
bjenkins | 2:680fc2690d10 | 111 | while(!_device->readable()); |
bjenkins | 2:680fc2690d10 | 112 | unsigned char COMD = _device->getc(); |
bjenkins | 2:680fc2690d10 | 113 | |
bjenkins | 2:680fc2690d10 | 114 | while(!_device->readable()); |
bjenkins | 2:680fc2690d10 | 115 | unsigned char DF1 = _device->getc(); |
bjenkins | 2:680fc2690d10 | 116 | |
bjenkins | 2:680fc2690d10 | 117 | while(!_device->readable()); |
bjenkins | 2:680fc2690d10 | 118 | unsigned char DF2 = _device->getc(); |
bjenkins | 2:680fc2690d10 | 119 | |
bjenkins | 2:680fc2690d10 | 120 | while(!_device->readable()); |
bjenkins | 2:680fc2690d10 | 121 | unsigned char DF3 = _device->getc(); |
bjenkins | 2:680fc2690d10 | 122 | |
bjenkins | 2:680fc2690d10 | 123 | while(!_device->readable()); |
bjenkins | 2:680fc2690d10 | 124 | unsigned char DF4 = _device->getc(); |
bjenkins | 2:680fc2690d10 | 125 | |
bjenkins | 2:680fc2690d10 | 126 | while(!_device->readable()); |
bjenkins | 2:680fc2690d10 | 127 | unsigned char CS = _device->getc(); |
bjenkins | 2:680fc2690d10 | 128 | |
bjenkins | 2:680fc2690d10 | 129 | // Now we shall verify the checksum |
bjenkins | 2:680fc2690d10 | 130 | unsigned int cs_calc = 65536; |
bjenkins | 2:680fc2690d10 | 131 | cs_calc -= HEAD - LEN - COMD - DF1 - DF2 - DF3 - DF4; |
bjenkins | 2:680fc2690d10 | 132 | cs_calc %= 256; |
bjenkins | 2:680fc2690d10 | 133 | |
bjenkins | 2:680fc2690d10 | 134 | if (((0x10000 - HEAD - LEN - COMD - DF1 - DF2 - DF3 - DF4) % 0XFF) != CS) |
bjenkins | 2:680fc2690d10 | 135 | { |
bjenkins | 2:680fc2690d10 | 136 | _debug->printf("Checksum fail\r\n"); |
bjenkins | 2:680fc2690d10 | 137 | _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); |
bjenkins | 2:680fc2690d10 | 138 | return 0; |
bjenkins | 2:680fc2690d10 | 139 | } |
bjenkins | 2:680fc2690d10 | 140 | else |
bjenkins | 2:680fc2690d10 | 141 | { |
bjenkins | 2:680fc2690d10 | 142 | // Checksum OK, we compute PM2.5 and PM10 values |
bjenkins | 2:680fc2690d10 | 143 | PM25 = DF1 * 256 + DF2; |
bjenkins | 2:680fc2690d10 | 144 | PM10 = DF3 * 256 + DF4; |
bjenkins | 2:680fc2690d10 | 145 | return 1; |
bjenkins | 2:680fc2690d10 | 146 | } |
bjenkins | 2:680fc2690d10 | 147 | } |
bjenkins | 2:680fc2690d10 | 148 | return 0; |
bjenkins | 2:680fc2690d10 | 149 | } |
bjenkins | 2:680fc2690d10 | 150 | |
bjenkins | 2:680fc2690d10 | 151 | bool HPM::stop_autosend(void) |
bjenkins | 2:680fc2690d10 | 152 | { |
bjenkins | 2:680fc2690d10 | 153 | // Stop auto send |
bjenkins | 2:680fc2690d10 | 154 | unsigned char stop_autosend[] = {0x68, 0x01, 0x20, 0x77 }; |
bjenkins | 2:680fc2690d10 | 155 | for (int i=0; i<sizeof(stop_autosend); i++) |
bjenkins | 2:680fc2690d10 | 156 | { |
bjenkins | 2:680fc2690d10 | 157 | _device->putc(stop_autosend[i]); |
bjenkins | 2:680fc2690d10 | 158 | } |
bjenkins | 2:680fc2690d10 | 159 | |
bjenkins | 2:680fc2690d10 | 160 | //Then we wait for the response |
bjenkins | 2:680fc2690d10 | 161 | while(!_device->readable()); |
bjenkins | 2:680fc2690d10 | 162 | char read1 = _device->getc(); |
bjenkins | 2:680fc2690d10 | 163 | char read2 = _device->getc(); |
bjenkins | 2:680fc2690d10 | 164 | |
bjenkins | 2:680fc2690d10 | 165 | // Test the response |
bjenkins | 2:680fc2690d10 | 166 | if ((read1 == 0xA5) && (read2 == 0xA5)){ |
bjenkins | 2:680fc2690d10 | 167 | // ACK |
bjenkins | 2:680fc2690d10 | 168 | return 1; |
bjenkins | 2:680fc2690d10 | 169 | } |
bjenkins | 2:680fc2690d10 | 170 | else if ((read1 == 0x96) && (read2 == 0x96)) |
bjenkins | 2:680fc2690d10 | 171 | { |
bjenkins | 2:680fc2690d10 | 172 | // NACK |
bjenkins | 2:680fc2690d10 | 173 | _debug->printf ("NACK\r\n"); |
bjenkins | 2:680fc2690d10 | 174 | return 0; |
bjenkins | 2:680fc2690d10 | 175 | } |
bjenkins | 2:680fc2690d10 | 176 | else return 0; |
bjenkins | 2:680fc2690d10 | 177 | } |
bjenkins | 2:680fc2690d10 | 178 | |
bjenkins | 2:680fc2690d10 | 179 | bool HPM::start_autosend(void) |
bjenkins | 2:680fc2690d10 | 180 | { |
bjenkins | 2:680fc2690d10 | 181 | // Start auto send |
bjenkins | 2:680fc2690d10 | 182 | unsigned char start_autosend[] = {0x68, 0x01, 0x40, 0x57 }; |
bjenkins | 2:680fc2690d10 | 183 | for (int i=0; i<sizeof(start_autosend); i++) |
bjenkins | 2:680fc2690d10 | 184 | { |
bjenkins | 2:680fc2690d10 | 185 | _device->putc(start_autosend[i]); |
bjenkins | 2:680fc2690d10 | 186 | } |
bjenkins | 2:680fc2690d10 | 187 | |
bjenkins | 2:680fc2690d10 | 188 | //Then we wait for the response |
bjenkins | 2:680fc2690d10 | 189 | while(!_device->readable()); |
bjenkins | 2:680fc2690d10 | 190 | char read1 = _device->getc(); |
bjenkins | 2:680fc2690d10 | 191 | char read2 = _device->getc(); |
bjenkins | 2:680fc2690d10 | 192 | // Test the response |
bjenkins | 2:680fc2690d10 | 193 | if ((read1 == 0xA5) && (read2 == 0xA5)){ |
bjenkins | 2:680fc2690d10 | 194 | // ACK |
bjenkins | 2:680fc2690d10 | 195 | return 1; |
bjenkins | 2:680fc2690d10 | 196 | } |
bjenkins | 2:680fc2690d10 | 197 | else if ((read1 == 0x96) && (read2 == 0x96)) |
bjenkins | 2:680fc2690d10 | 198 | { |
bjenkins | 2:680fc2690d10 | 199 | // NACK |
bjenkins | 2:680fc2690d10 | 200 | _debug->printf ("NACK\r\n"); |
bjenkins | 2:680fc2690d10 | 201 | return 0; |
bjenkins | 2:680fc2690d10 | 202 | |
bjenkins | 2:680fc2690d10 | 203 | } |
bjenkins | 2:680fc2690d10 | 204 | else return 0; |
bjenkins | 2:680fc2690d10 | 205 | } |