Last active
March 10, 2020 00:09
-
-
Save jywarren/a4f5860c52dd1f8fe47f398558a8856e to your computer and use it in GitHub Desktop.
hazePedal.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
/* | |
* Jeffrey Yoo Warren & Andy Lee | |
* https://learn.adafruit.com/pm25-air-quality-sensor/arduino-code | |
* digipot https://forum.arduino.cc/index.php?topic=430818.0 | |
*/ | |
#define chipselect 15 | |
#define updown 14 | |
#define inc 16 | |
// from FADE | |
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); | |
int potSetting = 0; | |
int potGoal = 0; | |
void setup() { | |
potentiometerstart(); | |
pinMode(3,OUTPUT); // signal | |
// 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(); | |
// set pot to initial position 0 | |
int resetCounter = 100; | |
int resetVal = 0; | |
while (resetVal != resetCounter) { | |
potDown(); | |
delay(50); | |
resetCounter -= 1; | |
} | |
} | |
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; | |
// the loop routine runs over and over again forever: | |
void loop() { | |
while (potSetting != potGoal) { | |
if (potSetting < potGoal) { | |
potUp(); | |
potSetting += 1; | |
} else { | |
potDown(); | |
potSetting -= 1; | |
} | |
} | |
//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 = 120; // arbitrary upper limit | |
potGoal = max(0, min(60, map(data.pm25_standard, minVal, maxVal, 0, 60))); | |
Serial.print("setting: "); | |
Serial.print(potSetting); | |
Serial.print(" goal: "); | |
Serial.println(potGoal); | |
Serial.print("pot: "); | |
Serial.println(potSetting); | |
} | |
} | |
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; | |
} | |
void potentiometerstart(){ | |
pinMode(chipselect, OUTPUT); | |
pinMode(updown,OUTPUT); | |
pinMode(inc,OUTPUT); | |
digitalWrite(inc,HIGH); | |
digitalWrite(updown,LOW); | |
digitalWrite(chipselect,LOW); | |
} | |
void potUp(){ | |
digitalWrite(updown,HIGH); | |
increment(); | |
} | |
void potDown(){ | |
digitalWrite(updown,LOW); | |
increment(); | |
} | |
void increment() { | |
digitalWrite(inc,LOW); | |
delay(50); | |
digitalWrite(inc,HIGH); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment