I have programmed it to use Pin D2 over software serial already. See my diagram attached (sorry for this drawing, haven't started doing schematics online yet..). see code at end
//********************Start of code for TPH sensor***********************
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <SPI.h>
#include <SD.h>
#include <SoftwareSerial.h>
#include "Adafruit_PM25AQI.h"
#include "RTClib.h"
#define Aout A0 //Define pins for TVOC sensor
#define Dout 4
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
// Temp, pressure, humidity sensor.
Adafruit_BME280 bme;
// Real time clock.
RTC_DS1307 rtc;
// Particular Matter sensor.
SoftwareSerial pmsSerial(2,3);
Adafruit_PM25AQI aqi = Adafruit_PM25AQI();
// TVOC Sensor - come back to this
uint32_t delayMS;
const int chipSelect = 10;
const int pingPin = 7;
unsigned int rtcd;
unsigned int rtcm;
unsigned int rtcy;
unsigned int rtcs;
unsigned int rtcmin;
unsigned int rtchr;
// Structure to hold pms sensor data.
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;
} pms5003dataStruct;
void setup() {
// TVOC Setup
pinMode(Aout, INPUT); //Analog output of TVOC
pinMode(Dout, INPUT); //Digital output of TVOC
// Open serial communications and wait for port to open:
//Serial.begin(9600);
// our debugging output
Serial.begin(115200);
while (!Serial) delay(10);
// sensor baud rate is 9600
pmsSerial.begin(9600);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2020, 12, 16, 10, 36, 0));
} else
Serial.println("RTC ready.");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
delay(1000);
// if (! aqi.begin_I2C()) { // connect to the sensor over I2C
//if (! aqi.begin_UART(&Serial1)) { // connect to the sensor over hardware serial
if (! aqi.begin_UART(&pmsSerial)) { // connect to the sensor over software serial
Serial.println("Could not find PM 2.5 sensor!");
while (1) delay(10);
}
Serial.println("PM25 found!");
while (!bme.begin(0x76)){
Serial.println("Could not find BME280 sensor!");
delay(1000);
}
Serial.println("BME sensor ready.");
Serial.println("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
while (1);
}
Serial.println("SD card initialized.");
}
void loop() {
//if ( millis() > event_1 ){
/*******************GET PLANTPOWER PM***********************************/
boolean ret = readPMSdata(&pmsSerial);
Serial.println(ret);
if (ret) {
// reading data was successful!
// Serial.println("---------------------------------------");
// Serial.println("Concentration Units (standard)");
// Serial.print("PM 1.0: "); Serial.print(pms5003dataStruct.pm10_standard);
// Serial.print("\t\tPM 2.5: "); Serial.print(pms5003dataStruct.pm25_standard);
// Serial.print("\t\tPM 10: "); Serial.println(pms5003dataStruct.pm100_standard);
Serial.println("---------------------------------------");
Serial.println("Concentration Units (environmental)");
Serial.print("PM 1.0: "); Serial.print(pms5003dataStruct.pm10_env);
Serial.print("\t\tPM 2.5: "); Serial.print(pms5003dataStruct.pm25_env);
Serial.print("\t\tPM 10: "); Serial.println(pms5003dataStruct.pm100_env);
Serial.println("---------------------------------------");
// Serial.print("Particles > 0.3um / 0.1L air:"); Serial.println(pms5003dataStruct.particles_03um);
// Serial.print("Particles > 0.5um / 0.1L air:"); Serial.println(pms5003dataStruct.particles_05um);
// Serial.print("Particles > 1.0um / 0.1L air:"); Serial.println(pms5003dataStruct.particles_10um);
// Serial.print("Particles > 2.5um / 0.1L air:"); Serial.println(pms5003dataStruct.particles_25um);
// Serial.print("Particles > 5.0um / 0.1L air:"); Serial.println(pms5003dataStruct.particles_50um);
// Serial.print("Particles > 10.0 um / 0.1L air:"); Serial.println(pms5003dataStruct.particles_100um);
// Serial.println("---------------------------------------");
}
// /*********GET VOC ************/
// int a = analogRead(Aout);
// int b = digitalRead(Dout);
// Serial.print("D0:");
// Serial.print(b);
// Serial.print(" A0:");
// Serial.println(a);
//
//
// /*****************Get Temp, Pressure and Humidity********************/
//
//
// float temp;
// float pres;
// float hum;
// temp = bme.readTemperature();
// pres = bme.readPressure();
// hum = bme.readHumidity();
//
// /*
// float temp(NAN), hum(NAN), pres(NAN);
//
// BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
// BME280::PresUnit presUnit(BME280::PresUnit_Pa);
//
//bme.read(pres, temp, hum, tempUnit, presUnit);
//
// float preshpa = (pres / 100); //create space for conversion of pascals to hectopascals (hPa) which is more usual measure
// float corr_temp = (temp - 0.0); //create space for correction of temperature according to unique sensor validation (will be different for each sensor)
// float corr_hum = (hum + 0); //create space for correction of humidity according to unique sensor validation (will be different for each sensor)
// float corr_preshpa = (preshpa + 10); //create space for correction of pressure according to unique sensor validation (will be different for each sensor)
//
// Serial.print("Temp: ");
// Serial.print(corr_temp);
// Serial.print("°" + String(tempUnit == BME280::TempUnit_Celsius ? 'C' : 'F'));
// Serial.print("\t\tHumidity: ");
// Serial.print(corr_hum);
// Serial.print("% RH");
// Serial.print("\t\tPressure: ");
// Serial.print(corr_preshpa);
// Serial.println(" hPa");
// */
// /*********GET TIME ************/
// //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
//
// DateTime now = rtc.now();
// /*
// Serial.print(now.year(), DEC);
// Serial.print('/');
// Serial.print(now.month(), DEC);
// Serial.print('/');
// Serial.print(now.day(), DEC);
// Serial.print(" (");
// Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
// Serial.print(") ");
// Serial.print(now.hour(), DEC);
// Serial.print(':');
// */
// Serial.print(now.minute(), DEC);
// Serial.print(':');
// Serial.print(now.second(), DEC);
// Serial.println();
//
// //Serial.print(" since midnight 1/1/1970 = ");
// //Serial.print(now.unixtime());
// //Serial.print("s = ");
// //Serial.print(now.unixtime() / 86400L);
// //Serial.println("d");
//
//
// // DateTime now = rtc.now();
// rtcs = now.second();
// rtcmin = now.minute();
// rtchr = now.hour();
// rtcy = now.year();
// rtcm = now.month();
// rtcd = now.day();
//
//
// /*********STORE DATA TO SD CARD ************/
//
// // open the file. note that only one file can be open at a time,
// // so you have to close this one before opening another.
// File dataFile = SD.open("datalog.txt", FILE_WRITE);
//
//
// // if the file is available, write to it:
// if (dataFile) {
//
// //dataFile.print(cm); dataFile.print(",CM,");
// dataFile.print(rtchr); dataFile.print(":");
// dataFile.print(rtcmin); dataFile.print(":");
// dataFile.print(rtcs); dataFile.print(",TIME,");
// dataFile.print(rtcd); dataFile.print("/");
// dataFile.print(rtcm); dataFile.print("/");
// dataFile.print(rtcy); dataFile.print(",DATE,");
// dataFile.print(temperature); dataFile.print(",Temperature,");
// dataFile.print(pressure); dataFile.print(",Pressure,");
// dataFile.print(humidity); dataFile.println(",Humidity");
// dataFile.print(b); dataFile.print(",TVOC Digital,");
// dataFile.print(a); dataFile.println(",TVOC Analogue");
// dataFile.print(pms5003dataStruct.particles_10um); dataFile.print(",PM 10um,");
// dataFile.print(pms5003dataStruct.particles_25um); dataFile.print(",PM 25um,");
// dataFile.print(pms5003dataStruct.particles_100um); dataFile.println(",PM 100um");
// //delay(899270);
// delay(5000);
// dataFile.close();
// delay(10);
// // print to the serial port too:
// //Serial.println(cm);
// }
// // if the file isn't open, pop up an error:
// else {
// Serial.println("error opening datalog.txt");
// }
delay(2000);
}
boolean readPMSdata(Stream *s) {
Serial.println(s->available());
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 *)&pms5003dataStruct, (void *)buffer_u16, 30);
if (sum != pms5003dataStruct.checksum) {
Serial.println("Checksum failure");
return false;
}
// success!
return true;
}
// ***********************End of Code -- you are DONE!*******************************