Nano Every Hanging after DigitalWrite

Hi,

I have got bored during lockdown and decided to make a weather station using some bits I had lying around and tried to learn some arduino programming as I go, certainly no expert!!!

My code is still a work in progress but I am pulling my hair out with one section that is causing the Nano Every to hang and I cannot work out why it is failing on such a basic command. To measure rainfall I have got a picaxe 08m2 that counts bucket tips and sends the number via serial to the Nano when the Nano puts a pin high.

If I upload the below code to the Nano Every it runs perfectly.

#define RAINGET 2 // Digital pin to trigger collecting of number of rain tips from picaxe
#define RAINZERO 3 //Digital pin to trigger zeroing of rain tip count when RAINGET is sent to picaxe
int RainCount = 0;

void setup() {
  pinMode(RAINGET, OUTPUT);
  Serial.begin(9600);
  Serial1.begin(4800); // Open serial receiving from picaxe
}

void loop() {
  Serial.println("Test1");
  digitalWrite(RAINGET, HIGH);
  Serial.println("Test2");
  while (!Serial1.available()) {
  }
  RainCount = Serial1.read();
  Serial.println("Test3");
  digitalWrite(RAINGET, LOW);
  Serial.println("Test4");
  Serial.println(RainCount);
  delay(5000); 
}

However when I insert that piece of code in to my larger project code it hangs after the DigitalWrite High command. It sends “Test 2” and puts the pin HIGH but then hangs. I originally used a delay after the high command and then a low command before checking to anything if had been received on Serial1 but it would still hang after the HIGH command before the Delay. Full code posted below, parts are still a work in progress!!

#include <SPI.h>
#include "printf.h"
#include "RF24.h"
#include <Adafruit_Sensor.h>
#include <DHT.h>

#define DHTTYPE   DHT22 // Temperature & Humidity Sensor type
#define DHTPIN 21 // Digital pin Temperature and Humidity Sensor
#define CEPIN 9 // Digital pin RF24 Module Chip Enable
#define CSNPIN 10 // Digital pin RF24 Module Chip Select Not
#define IRQ_PIN 8 // Digital pin RF24 Module Interrupt Input
#define RAINGET 2 // Digital pin to trigger collecting of number of rain tips from picaxe
#define RAINZERO 3 //Digital pin to trigger zeroing of rain tip count when RAINGET is sent to picaxe

DHT dht;

RF24 radio(CEPIN, CSNPIN); // setup RF24 Module pins

uint8_t address[][6] = {"1Node", "2Node"};

bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit

int WindDirA = A0; // Analog input pin for wind direction resistance sensor A
int WindDirB = A1; // Analog input pin for wind direction resistance sensor B
int LightSens = A3; // Analog input pin for light level

char Received[5] = ""; // Used to store messages received from Weather Main
float Data[10] = {}; // Data string to send to Weather Main
float OTemp = 0; // Used to store temp value received from DHT
float OTempSum = 0; // Used to sum temp values read over sampling period
float AvTemp = 0; // Average temp over sampling period
float OHumid = 0;
float OHumidSum = 0;
float AvHumid = 0;
int OLight = 0;
int OLightSum = 0;
float AvLight = 0;
int RainCount = 0;
int samples = 0;
int WindRefA[36] = {367, 534, 351, 508, 336, 484, 322, 461, 308, 440, 295, 421, 282, 402, 270, 385, 259, 368, 248, 353, 236, 337, 227, 323, 216, 309, 206, 296, 196, 283, 187, 270, 177, 258, 168, 460};
int WindRefB[36] = {168, 257, 177, 270, 187, 283, 196, 296, 206, 309, 216, 323, 226, 337, 237, 353, 247, 368, 259, 384, 270, 402, 282, 420, 294, 440, 308, 461, 321, 483, 336, 508, 351, 534, 367, 460};
int WindCalA = 0;
int WindCalB = 0;
int WindDirCal[36] = {0};
int WindDA = 0;
int WindDB = 0;
int WindComp = 0;
int WindDir = 0;
int WindDirSum = 0;
float AvWindDir = 0;

void setup() {

  Serial.begin(115200);
  Serial1.begin(4800); // Open serial receiving from picaxe

  // initialize the transceiver on the SPI bus
  if (!radio.begin()) {
    Serial.println(F("radio hardware is not responding!!"));
    while (1) {} // hold in infinite loop
  }

  dht.setup(DHTPIN);

  // print example's introductory prompt
  Serial.println(F("Weather Remote"));

  pinMode(RAINGET, OUTPUT);
  pinMode(RAINZERO, OUTPUT);
  pinMode(IRQ_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(IRQ_PIN), interruptHandler, FALLING);
  radio.setPALevel(RF24_PA_LOW);  // RF24_PA_MAX is default.
  radio.enableDynamicPayloads();    // ACK payloads are dynamically sized
  radio.enableAckPayload();
  radio.openWritingPipe(address[radioNumber]);     // always uses pipe 0
  radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1

  // let IRQ pin only trigger on "data ready" event in RX mode
  radio.maskIRQ(1, 1, 0); // args = "data_sent", "data_fail", "data_ready"
  radio.startListening(); // put radio in RX mode
}

void loop() {

}

void SampleData() {
  ReadTemp();
  ReadHumid();
  ReadLight();
  ReadWindDir();
  samples = samples + 1;
  Serial.println(OTempSum);
  Serial.println(OHumidSum);
  Serial.println(OLightSum);
  Serial.println(WindDir);
}

void SendData() {
  ReadTemp();
  ReadHumid();
  ReadLight();
  ReadWindDir();
  ReadRain();
  samples = samples + 1;
  Serial.println(OTempSum);
  Serial.println(OHumidSum);
  Serial.println(OLightSum);
  Serial.println(WindDirSum);
  AvTemp = OTempSum / samples;
  OTempSum = 0;
  AvHumid = OHumidSum / samples;
  OHumidSum = 0;
  AvLight = OLightSum / samples;
  OLightSum = 0;
  AvWindDir = WindDirSum / samples;
  WindDirSum = 0;
  samples = 0;
  Serial.println(AvTemp);
  Serial.println(AvHumid);
  Serial.println(AvLight);
  Serial.println(AvWindDir);
  Serial.println(RainCount);
  Data[0] = AvTemp;
  Data[1] = AvHumid;
  Data[2] = AvLight;
  Data[3] = AvWindDir;
  //  Data[4] = AvWindSpd;
  Data[5] = RainCount;
  radio.stopListening();
  bool report = radio.write(&Data, sizeof(Data));      // transmit & save the report
  if (report) {
    Serial.print(F("Transmission successful! "));          // payload was delivered
    for (byte i = 0; i < 10; i = i + 1) {
      Serial.println(Data[i]);
    }                             // print payload sent
  } else {
    Serial.println(F("Transmission failed or timed out")); // payload was not delivered
  }
  radio.startListening();
}

float ReadTemp() {
  OTemp = dht.getTemperature();
  OTempSum = OTempSum + OTemp;
}

float ReadHumid() {
  OHumid = dht.getHumidity();
  OHumidSum = OHumidSum + OHumid;
}

int ReadLight() {
  OLight = analogRead(LightSens);
  OLightSum = OLightSum + OLight;
}

int ReadWindDir() {
  WindDA = analogRead(WindDirA);
  WindDB = analogRead(WindDirB);
  for (int i = 0; i < 37; i++)
  {
    WindCalA = WindRefA[i] - WindDA;
    WindCalB = WindRefB[i] - WindDB;
    WindDirCal[i] = abs(WindCalA) + abs(WindCalB);
  }
  WindComp = WindDirCal[35];
  for (int i = 0; i < 37; i++)
  {
    if (WindDirCal[i] <= WindComp)
    {
      WindComp = WindDirCal[i];
      WindDir = i * 10;
    }
  }
  WindDirSum = WindDirSum + WindDir;
}

int ReadRain() {
  Serial.println("Test1");
  digitalWrite(RAINGET, HIGH);
  Serial.println("Test2");
  while (!Serial1.available()) {
  }
  RainCount = Serial1.read();
  Serial.println("Test3");
  digitalWrite(RAINGET, LOW);
  Serial.println("Test4");
  Serial.println(RainCount);
}

void interruptHandler() {
  if (radio.available()) {
    radio.read(&Received, sizeof(Received));
    Serial.print(F("Received "));
    Serial.print(F(": "));
    Serial.println(Received);// print the payload's value
    Serial.println(Received[4]);
    if (Received[4] == 'S') {
      SampleData();
    } else if (Received[4] == 'T') {
      SendData();
    }
  }
}

It seems like something so trivial I am pulling my hair out, I am sure it is something really simple I have missed.

Any help much appreciated,

Mark

Serial.print in an interrupt service routine will cause unpredictable behaviour.
Set a (volatile) flag in the ISR and print an interpretation of it in the loop()

Hi @6v6gt,

Thank you for the prompt reply, I thought it would probably be something simple, I’ve amended as you suggested and works perfectly.

Thank you