Created
March 3, 2022 07:53
-
-
Save neosarchizo/ab0061c8a287ba907c1f6c3cd701cb7d to your computer and use it in GitHub Desktop.
[Arduino] PM2008 packet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "packet.h" | |
void PACKET_generate(uint8_t cmd, uint8_t length, uint8_t *data) { | |
// STX | |
*data = PACKET_STX; | |
// LEN | |
*(data + PACKET_POS_LEN) = length - 2; | |
// CMD | |
*(data + 2) = cmd; | |
// CS : STX ^ LEN ^ CMD ^ D... | |
*(data + length - 2) = *data; | |
for (uint8_t i = 1; i < length - 2; ++i) { | |
*(data + length - 2) ^= *(data + i); | |
} | |
*(data + length - 1) = PACKET_ETX; | |
} | |
bool PACKET_check(uint8_t length, uint8_t *data) { | |
// STX | |
if (*data != PACKET_STX) { | |
return false; | |
} | |
// ETX | |
if (*(data + length - 1) != PACKET_ETX) { | |
return false; | |
} | |
// LEN | |
if (*(data + 1) + 2 != length) { | |
return false; | |
} | |
// CMD | |
switch (*(data + 2)) { | |
case PACKET_CMD_GET_PM2008: | |
break; | |
default: | |
return false; | |
} | |
// CS | |
uint8_t cs = *data; | |
for (uint8_t i = 1; i < length - 2; ++i) { | |
cs ^= *(data + i); | |
} | |
if (cs != *(data + length - 2)) { | |
return false; | |
} | |
return true; | |
} | |
uint8_t PACKET_getDataLength(uint8_t *data) { | |
return *(data + PACKET_POS_LEN) - 3; | |
} | |
uint8_t PACKET_getCmd(uint8_t *data) { | |
return *(data + PACKET_POS_CMD); | |
} | |
void PACKET_getData(uint8_t *src, uint8_t length, uint8_t *dst) { | |
for (uint8_t i = 0; i < length; ++i) { | |
*(dst + i) = *(src + PACKET_POS_DAT + i); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef PACKET_H__ | |
#define PACKET_H__ | |
#ifdef __cplusplus | |
extern "C" | |
{ | |
#endif | |
#include <stdint.h> | |
#include <stdbool.h> | |
#define PACKET_STX 0xAB | |
#define PACKET_ETX 0x7D | |
#define PACKET_CMD_GET_PM2008 0 | |
// CM1106 | |
// AM1008W-K | |
#define PACKET_POS_LEN 1 | |
#define PACKET_POS_CMD 2 | |
#define PACKET_POS_DAT 3 | |
extern void PACKET_generate(uint8_t cmd, uint8_t length, uint8_t *data); | |
extern bool PACKET_check(uint8_t length, uint8_t *data); | |
extern uint8_t PACKET_getDataLength(uint8_t *data); | |
extern uint8_t PACKET_getCmd(uint8_t *data); | |
extern void PACKET_getData(uint8_t *src, uint8_t length, uint8_t *dst); | |
#ifdef __cplusplus | |
} | |
#endif | |
#endif // PACKET_H__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <pm2008_i2c.h> | |
#include "packet.h" | |
PM2008_I2C pm2008_i2c; | |
static uint8_t txBuffer[256]; | |
static uint8_t rxBuffer[256]; | |
static volatile uint8_t idxBuffer = 0; | |
static volatile uint8_t rearLength = 0; | |
static uint8_t data[256]; | |
void setup() { | |
pm2008_i2c.begin(); | |
Serial.begin(9600); | |
pm2008_i2c.command(); | |
delay(1000); | |
} | |
void loop() { | |
if (Serial.available()) { | |
uint8_t b = Serial.read(); | |
switch (idxBuffer) { | |
case 0: { | |
if (b != PACKET_STX) { | |
break; | |
} | |
rxBuffer[idxBuffer++] = b; | |
break; | |
} | |
case 1: { // LEN | |
// (STX), (LEN), CMD, DAT, CS, ETX | |
// Total length = LEN + 2 | |
if (b < 3) { | |
idxBuffer = 0; | |
break; | |
} | |
rxBuffer[idxBuffer++] = b; | |
rearLength = b; // buffer[PACKET_POS_LEN] | |
break; | |
} | |
case 2: { // CMD | |
if (b != PACKET_CMD_GET_PM2008 ) { | |
idxBuffer = 0; | |
break; | |
} | |
rxBuffer[idxBuffer++] = b; | |
break; | |
} | |
default: { | |
// DAT, CS, ETX | |
rxBuffer[idxBuffer++] = b; | |
if (idxBuffer >= rearLength + 2) { | |
idxBuffer = 0; | |
if (b != PACKET_ETX) { | |
break; | |
} | |
if (!PACKET_check(rearLength + 2, rxBuffer)) { | |
break; | |
} | |
uint8_t dataLength = PACKET_getDataLength(rxBuffer); | |
uint8_t cmd = PACKET_getCmd(rxBuffer); | |
if ( dataLength > 0 ) { | |
PACKET_getData(rxBuffer, dataLength, data); | |
} | |
switch (cmd) { | |
case PACKET_CMD_GET_PM2008: { | |
// length = 0 | |
uint8_t ret = pm2008_i2c.read(); | |
// D0 : error ( 0 : none, 1 : wrong) | |
if (ret != 0 ) { | |
txBuffer[PACKET_POS_DAT] = 1; | |
PACKET_generate(PACKET_CMD_GET_PM2008, 6, txBuffer); | |
Serial.write(txBuffer, 6); | |
break; | |
} | |
// parsing | |
// D0 : 0 | |
// D1 ~ | |
txBuffer[PACKET_POS_DAT] = 0; | |
// GRIMM | |
txBuffer[PACKET_POS_DAT + 1] = pm2008_i2c.pm1p0_grimm & 0xff; | |
txBuffer[PACKET_POS_DAT + 2] = (pm2008_i2c.pm1p0_grimm >> 8) & 0xff; | |
txBuffer[PACKET_POS_DAT + 3] = pm2008_i2c.pm2p5_grimm & 0xff; | |
txBuffer[PACKET_POS_DAT + 4] = (pm2008_i2c.pm2p5_grimm >> 8) & 0xff; | |
txBuffer[PACKET_POS_DAT + 5] = pm2008_i2c.pm10_grimm & 0xff; | |
txBuffer[PACKET_POS_DAT + 6] = (pm2008_i2c.pm10_grimm >> 8) & 0xff; | |
// TSI | |
txBuffer[PACKET_POS_DAT + 7] = pm2008_i2c.pm1p0_tsi & 0xff; | |
txBuffer[PACKET_POS_DAT + 8] = (pm2008_i2c.pm1p0_tsi >> 8) & 0xff; | |
txBuffer[PACKET_POS_DAT + 9] = pm2008_i2c.pm2p5_tsi & 0xff; | |
txBuffer[PACKET_POS_DAT + 10] = (pm2008_i2c.pm2p5_tsi >> 8) & 0xff; | |
txBuffer[PACKET_POS_DAT + 11] = pm2008_i2c.pm10_tsi & 0xff; | |
txBuffer[PACKET_POS_DAT + 12] = (pm2008_i2c.pm10_tsi >> 8) & 0xff; | |
// size | |
txBuffer[PACKET_POS_DAT + 13] = pm2008_i2c.number_of_0p3_um & 0xff; | |
txBuffer[PACKET_POS_DAT + 14] = (pm2008_i2c.number_of_0p3_um >> 8) & 0xff; | |
txBuffer[PACKET_POS_DAT + 15] = pm2008_i2c.number_of_0p5_um & 0xff; | |
txBuffer[PACKET_POS_DAT + 16] = (pm2008_i2c.number_of_0p5_um >> 8) & 0xff; | |
txBuffer[PACKET_POS_DAT + 17] = pm2008_i2c.number_of_1_um & 0xff; | |
txBuffer[PACKET_POS_DAT + 18] = (pm2008_i2c.number_of_1_um >> 8) & 0xff; | |
txBuffer[PACKET_POS_DAT + 19] = pm2008_i2c.number_of_2p5_um & 0xff; | |
txBuffer[PACKET_POS_DAT + 20] = (pm2008_i2c.number_of_2p5_um >> 8) & 0xff; | |
txBuffer[PACKET_POS_DAT + 21] = pm2008_i2c.number_of_5_um & 0xff; | |
txBuffer[PACKET_POS_DAT + 22] = (pm2008_i2c.number_of_5_um >> 8) & 0xff; | |
txBuffer[PACKET_POS_DAT + 23] = pm2008_i2c.number_of_10_um & 0xff; | |
txBuffer[PACKET_POS_DAT + 24] = (pm2008_i2c.number_of_10_um >> 8) & 0xff; | |
PACKET_generate(PACKET_CMD_GET_PM2008, 30, txBuffer); | |
Serial.write(txBuffer, 30); | |
break; | |
} | |
default: | |
break; | |
} | |
} | |
break; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment