Hi, this will be my first post in the forum. badly need help
so i knew that nano 33 IoT does not support SoftwareSerial library.
Can you guys help me figure out what changes shall be made so that the code below can be functional to the nano 33 IoT? It works perfectly fine when uploaded to the basic nano.
i used the softwareserial to the particulate matter sensor (PMS7003).
#include <SoftwareSerial.h>
#include "Adafruit_Si7021.h"
#include <SPI.h>
#include <SD.h>
#include <ThreeWire.h>
#include <RtcDS1302.h>
//pin connections
//DS1302 RTC
ThreeWire myWire(4,5,2); //5 clk 4 dat 2 rst
RtcDS1302<ThreeWire> Rtc(myWire);
//Grove LED Button
const byte ledStatusPin = 8;
const byte buttonPin = 9;
//5V DC Fan
const byte fanPin = 10;
//SD card module
const byte csPin = 14;
/*
sck -> d13
miso -> d12
mosi -> d11
*/
//PM Sensor
SoftwareSerial pmsSerial(16,17);
//Si7021 Temp&RH Sensor
Adafruit_Si7021 sensor = Adafruit_Si7021();
//constant
const unsigned int PPSActiveDuration = 3300; // 55 mins
const unsigned int interval = 1000;
unsigned int counter = 0;
File dataFile;
//bool states
boolean ledState = false;
boolean PPSActive = false;
boolean filewrite = false;
unsigned long previousMillis = 0;
void setup() {
Serial.begin(115200);
pmsSerial.begin(9600);
pinMode(buttonPin, INPUT);
pinMode(ledStatusPin, OUTPUT);
pinMode(fanPin, OUTPUT);
while (!Serial) {
delay(10);
}
//initialize humidity and temperature
//humidity and temperature
if (!sensor.begin()) {
Serial.println("No sensor");
while (1);
}
if (!SD.begin(csPin)){
Serial.println("SD CARD FAILED, OR NOT PRESENT");
while(1);
}
Rtc.Begin();
RtcDateTime compiled = RtcDateTime(__DATE__,__TIME__);
if (!Rtc.IsDateTimeValid()){
Serial.println("RTC lost confidence in the Datetime!");
Rtc.SetDateTime(compiled);
}
if (Rtc.GetIsWriteProtected()) {
Serial.println(F("RTC was write protected, enabling writing now"));
Rtc.SetIsWriteProtected(false);
}
if (!Rtc.GetIsRunning()) {
Serial.println(F("RTC was not actively running, starting now"));
Rtc.SetIsRunning(true);
}
RtcDateTime now = Rtc.GetDateTime();
if (now < compiled) {
Serial.println(F("RTC is older than compile time! (Updating DateTime)"));
Rtc.SetDateTime(compiled);
}
Serial.println("Initializing Complete!");
}
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;
char datestring[13];
void loop() {
unsigned long currentMillis = millis();
if (digitalRead(buttonPin) == LOW && !PPSActive) {
//Set LED to ON and start Timer
Serial.println("Button pushed!");
PPSActive = true;
digitalWrite(ledStatusPin, HIGH);
counter = 0 ;
RtcDateTime dt = Rtc.GetDateTime();
// Convert month, day, and year to strings and concatenate them with buffer
itoa(dt.Month(), datestring + strlen(datestring), 10);
itoa(dt.Day(), datestring + strlen(datestring), 10);
itoa(dt.Hour(), datestring + strlen(datestring), 10);
itoa(dt.Minute(), datestring + strlen(datestring), 10);
// Append ".txt" to the buffer
strcat(datestring, ".txt");
// Print the result
Serial.println(datestring);
dataFile = SD.open(datestring, FILE_WRITE);
if (!dataFile) {
while (1);
}
}
//1 second interval
if (PPSActive && (currentMillis - previousMillis >= interval)) {
previousMillis = currentMillis;
if (counter >= PPSActiveDuration) {
PPSActive = false;
analogWrite(fanPin, 0);
digitalWrite(ledStatusPin, LOW);
datestring[0] = '\0'; // Clearing the datestring
dataFile.close();
} else {
Serial.print(F("Counter: "));
Serial.print(counter);
Serial.print('\t');
Serial.print(F("PPS Status: "));
Serial.println(PPSActive);
}
counter++;
}
if ((counter % 5 == 1) && readPMSdata(&pmsSerial) && PPSActive) {
if ((counter > 900 && counter < 1200) || (counter > 2100 && counter < 2400)) {
// Do nothing
} else {
char dateReturn[20];
analogWrite(fanPin, 255);
RtcDateTime dt = Rtc.GetDateTime();
snprintf_P(dateReturn,
countof(dateReturn),
PSTR("%02u/%02u/%04u\t%02u:%02u:%02u"),
dt.Month(),
dt.Day(),
dt.Year(),
dt.Hour(),
dt.Minute(),
dt.Second() );
Serial.print(F("Free SRAM: "));
Serial.print(freeMemory());
Serial.println(F(" bytes"));
if (dataFile) {
dataFile.seek(dataFile.size());
dataFile.print(data.particles_25um);
dataFile.print('\t');
dataFile.print(sensor.readHumidity(), 2);
dataFile.print('\t');
dataFile.print(sensor.readTemperature(), 2);
dataFile.print('\t');
dataFile.println(dateReturn);
} else {
Serial.println(F("SD Card Failed"));
}
}
}
}
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;
}
#define countof(a) (sizeof(a) / sizeof(a[0]))
int freeMemory() {
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}