Changed board from basic nano to nano 33 IoT

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);
}




Welcome to the forum

The Nano 33 IOT has 2 serial ports. The simplest change. therefore, would be to connect the sensor to pins 0 and 1 and to use the Serial1 interface to communicate with it

However, you should not disregard the fact that the Nano 33 IOT is, as its name suggests, a 3.3V device rather than a 5V device so voltage level shifting between the sensor and Nano may be required

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.