Last active
March 23, 2020 17:12
-
-
Save jywarren/e7394933fe91be656d59b8013ee0e9a9 to your computer and use it in GitHub Desktop.
plantowerPulse.ino
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
/* | |
Pulse a light on briefly, but speed up pulses as PM2.5 values go up. | |
https://learn.adafruit.com/pm25-air-quality-sensor/arduino-code | |
*/ | |
int led = 10; // the PWM pin the LED is attached to | |
int brightness = 0; // how bright the LED is | |
int fadeAmount = 5; // how many points to fade the LED by | |
// #include <SoftModem.h> | |
// SoftModem modem = SoftModem(); | |
// On Leonardo/Micro or others with hardware serial, use those! | |
// uncomment this line: | |
#define pmsSerial Serial1 | |
// For UNO and others without hardware serial, we must use software serial... | |
// pin #2 is IN from sensor (TX pin on sensor), leave pin #3 disconnected | |
// comment these two lines if using hardware serial | |
//#include <SoftwareSerial.h> | |
//SoftwareSerial pmsSerial(2, 3); | |
void setup() { | |
// our debugging output | |
Serial.begin(115200); | |
// sensor baud rate is 9600 | |
pmsSerial.begin(9600); | |
// declare LED pin to be an output: | |
pinMode(led, OUTPUT); | |
// start softmodem | |
delay(100); | |
// modem.begin(); | |
} | |
struct pms5003data { | |
uint16_t framelen; | |
uint16_t pm10_standard, pm25_standard, pm100_standard; | |
uint16_t pm10_env, pm25_env, pm100_env; | |
uint16_t particles_03um, particles_05um, particles_10um, particles_25um, particles_50um, particles_100um; | |
uint16_t unused; | |
uint16_t checksum; | |
}; | |
struct pms5003data data; | |
int delayVal = 30; | |
// the loop routine runs over and over again forever: | |
void loop() { | |
// set the brightness of pin 9: | |
analogWrite(led, brightness); | |
// change the brightness for next time through the loop: | |
brightness = brightness + fadeAmount; | |
// reverse the direction of the fading at the ends of the fade: | |
if (brightness <= 0 || brightness >= 255) { | |
fadeAmount = -fadeAmount; | |
} | |
// only delay when on low brightness | |
if (brightness >= 255) { | |
// wait for some milliseconds to make dimming effect; more delay means slower | |
Serial.print("delay (ms): "); | |
Serial.println(delayVal); | |
delay((int)delayVal); | |
} | |
//Serial.println("connected"); | |
if (readPMSdata(&pmsSerial)) { | |
// reading data was successful! | |
Serial.println(); | |
Serial.println("---------------------------------------"); | |
Serial.println("Concentration Units (standard)"); | |
Serial.print("PM 1.0: "); Serial.print(data.pm10_standard); | |
Serial.print("\t\tPM 2.5: "); Serial.print(data.pm25_standard); | |
Serial.print("\t\tPM 10: "); Serial.println(data.pm100_standard); | |
Serial.println("---------------------------------------"); | |
Serial.println("Concentration Units (environmental)"); | |
Serial.print("PM 1.0: "); Serial.print(data.pm10_env); | |
Serial.print("\t\tPM 2.5: "); Serial.print(data.pm25_env); | |
Serial.print("\t\tPM 10: "); Serial.println(data.pm100_env); | |
Serial.println("---------------------------------------"); | |
Serial.print("Particles > 0.3um / 0.1L air:"); Serial.println(data.particles_03um); | |
Serial.print("Particles > 0.5um / 0.1L air:"); Serial.println(data.particles_05um); | |
Serial.print("Particles > 1.0um / 0.1L air:"); Serial.println(data.particles_10um); | |
Serial.print("Particles > 2.5um / 0.1L air:"); Serial.println(data.particles_25um); | |
Serial.print("Particles > 5.0um / 0.1L air:"); Serial.println(data.particles_50um); | |
Serial.print("Particles > 10.0 um / 0.1L air:"); Serial.println(data.particles_100um); | |
Serial.println("---------------------------------------"); | |
// modem.print((String) data.pm10_standard + "," + data.pm25_standard + "," + data.pm100_standard); | |
int minVal = 0; | |
int maxVal = 30; // arbitrary upper limit | |
delayVal = map(data.pm25_standard, minVal, maxVal, 4 000, 0); | |
delayVal = max(1, delayVal); // never less than 1 | |
} | |
delay(10); | |
} | |
boolean readPMSdata(Stream *s) { | |
if (! s->available()) { | |
return false; | |
} | |
// Read a byte at a time until we get to the special '0x42' start-byte | |
if (s->peek() != 0x42) { | |
s->read(); | |
return false; | |
} | |
// Now read all 32 bytes | |
if (s->available() < 32) { | |
return false; | |
} | |
uint8_t buffer[32]; | |
uint16_t sum = 0; | |
s->readBytes(buffer, 32); | |
// get checksum ready | |
for (uint8_t i=0; i<30; i++) { | |
sum += buffer[i]; | |
} | |
/* debugging | |
for (uint8_t i=2; i<32; i++) { | |
Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", "); | |
} | |
Serial.println(); | |
*/ | |
// The data comes in endian'd, this solves it so it works on all platforms | |
uint16_t buffer_u16[15]; | |
for (uint8_t i=0; i<15; i++) { | |
buffer_u16[i] = buffer[2 + i*2 + 1]; | |
buffer_u16[i] += (buffer[2 + i*2] << 8); | |
} | |
// put it into a nice struct :) | |
memcpy((void *)&data, (void *)buffer_u16, 30); | |
if (sum != data.checksum) { | |
Serial.println("Checksum failure"); | |
return false; | |
} | |
// success! | |
return true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment