Core Electronics Forum

Weather shield woes

I wonder if someone can help. I have just bought the Sparkfun Weather Kit and Shield. These are working correctly with a Uno. I have a Pysupply LoRa Arduino Shield - also working correctly with the Uno and connecting to TTN.
I’m testing with the Weather_Basic version for simplicity.
When I combine the two, the program halts midway through. I’ve isolated various sections of the code to identify the problem. The definition section and the void setup are fine. In the void loop it checks the humidity sensor and assigns it to a float. Again fine. But when it attempts to print this
Serial.print(humidity);
it stops. This is despite it being happy to print a string
Serial.print("Humidity = ");
I wonder if this is something to do with the way Arduino prints floats (I think it may convert them to a string first?). Frustrating, I’ve wasted hours on this! TIA

Hi Andrew,

Can you post up some photos of how you’ve got things wired up? In particular, do you have anything connected to your Uno pins 0 and 1? These are used for UART communication, so if you’ve got anything hooked up to these it can prevent it from printing anything to the serial monitor.

Regards,
Oliver
Support | Core Electronics

Hey Andrew,

Can you also please put up the .ino so that we can identify the determination and reference to the variable humidity so that we can troubleshoot any issues that may be occurring within the script?

Thanks

Bryce
Core Electronics | Support

Hi Folks, thanks heaps for the prompt responses.


Not sure whether these will help much.
Code coming up in next post

// aw_uno_Weather_Shield_Basic_V12_LoRa
//  18/7/20
// uses TTN applicaiton "pisupply_test" with OTAA (device is "aw_pisupply_shield")
// LoRa code is from PiSupply/RAK811-Arduino 

/*
  Weather Shield Example
  By: Nathan Seidle
  SparkFun Electronics
  Date: June 10th, 2016
  License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).

  This example prints the current humidity, air pressure, temperature and light levels.

  The weather shield is capable of a lot. Be sure to checkout the other more advanced examples for creating
  your own weather station.

  Updated by Joel Bartlett
  03/02/2017
  Removed HTU21D code and replaced with Si7021

*/

#include "RAK811.h"
#include "SoftwareSerial.h"
#define WORK_MODE LoRaWAN   //  LoRaWAN or LoRaP2P
#define JOIN_MODE OTAA    //  OTAA or ABP
#if JOIN_MODE == OTAA
String DevEui = "XXXXXXXXXXXXXX"; // Fill this out
String AppEui = "XXXXXXXXXXXXXXXXX"; // Fill this out
String AppKey = "XXXXXXXXXXXXXXXXX"; // Fill This out
#else JOIN_MODE == ABP
String NwkSKey = "";
String AppSKey = "";
String DevAddr = "";
#endif
#define TXpin 11   // Set the virtual serial port pins
#define RXpin 10
#define DebugSerial Serial
SoftwareSerial RAKSerial(RXpin,TXpin);    // Declare a virtual serial port
char* buffer = "72616B776972656C657373";
int RESET_PIN = 12;
bool InitLoRaWAN(void);
RAK811 RAKLoRa(RAKSerial,DebugSerial);



#include <Wire.h> //I2C needed for sensors
#include "SparkFunMPL3115A2.h" //Pressure sensor - Search "SparkFun MPL3115" and install from Library Manager
#include "SparkFun_Si7021_Breakout_Library.h" //Humidity sensor - Search "SparkFun Si7021" and install from Library Manager

MPL3115A2 myPressure; //Create an instance of the pressure sensor
Weather myHumidity;//Create an instance of the humidity sensor

//Hardware pin definitions
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
const byte STAT_BLUE = 7;
const byte STAT_GREEN = 8;

const byte REFERENCE_3V3 = A3;
const byte LIGHT = A1;
const byte BATT = A2;

//Global Variables
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
long lastSecond; //The millis counter to see when a second rolls by



void setup()////////////////////////////////////////////////////////////////////////////////////////
{
  DebugSerial.begin(9600);
 
 
// Serial.begin(9600);
  DebugSerial.println("Weather Shield Example");

  pinMode(STAT_BLUE, OUTPUT); //Status LED Blue
  pinMode(STAT_GREEN, OUTPUT); //Status LED Green

  pinMode(REFERENCE_3V3, INPUT);
  pinMode(LIGHT, INPUT);

  //Configure the pressure sensor
  myPressure.begin(); // Get sensor online
  myPressure.setModeBarometer(); // Measure pressure in Pascals from 20 to 110 kPa
  myPressure.setOversampleRate(7); // Set Oversample to the recommended 128
  myPressure.enableEventFlags(); // Enable all three pressure and temp event flags

  //Configure the humidity sensor
  myHumidity.begin();

  lastSecond = millis();

  DebugSerial.println("Weather Shield online!");



  
 //Define Reset Pin
 pinMode(RESET_PIN, OUTPUT);
 //Setup Debug Serial on USB Port
 //DebugSerial.begin(9600);
 //while(DebugSerial.read()>= 0) {}
 //while(!DebugSerial);
 //Print debug info
 DebugSerial.println("StartUP");
 DebugSerial.println("Reset");
 //Reset the RAK Module
 digitalWrite(RESET_PIN, LOW);   // turn the pin low to Reset
 digitalWrite(RESET_PIN, HIGH);    // then high to enable
 DebugSerial.println("Success");
 RAKSerial.begin(9600); // Arduino Shield
 delay(100);
 DebugSerial.println(RAKLoRa.rk_getVersion());
 delay(200);
 DebugSerial.println(RAKLoRa.rk_getBand());
 delay(200);

 while (!InitLoRaWAN());

 

}


 bool InitLoRaWAN(void)/////////////////////////////////////////////////////////////////////////
{
  RAKLoRa.rk_setWorkingMode(WORK_MODE);
  RAKLoRa.rk_recvData();
  RAKLoRa.rk_recvData();
  if ( RAKLoRa.rk_recvData() == "OK")
  {

    if (RAKLoRa.rk_initOTAA(DevEui, AppEui, AppKey))
    {
      DebugSerial.println("You init OTAA parameter is OK!");
      while (RAKLoRa.rk_joinLoRaNetwork(JOIN_MODE))
      {
        bool flag = false;
        for (unsigned long start = millis(); millis() - start < 90000L;)
        {
          String ret = RAKLoRa.rk_recvData();
          if (ret.startsWith(STATUS_JOINED_SUCCESS))
          {
            DebugSerial.println("You join Network success!");
            return true;
          }
          else if (ret.startsWith(STATUS_RX2_TIMEOUT) || ret.startsWith(STATUS_JOINED_FAILED))
          {
            DebugSerial.println("You join Network Fail!");
            flag = true;
            DebugSerial.println("The device will try to join again after 5s");
            delay(1000);
          }
        }
        if (flag == false)
        {
          DebugSerial.println("Pleases Reset the module!");
          delay(1000);
          return false;
        }
      }
    }
  }
     return false;
}
    
  
 
  




void loop()///////////////////////////////////////////////////////////////////////////////////////////
{
//Print readings every second  (aw changed to 10 sec)
 /* if (millis() - lastSecond >= 10000)
  {
    digitalWrite(STAT_BLUE, HIGH); //Blink stat LED

    lastSecond += 10000;
*/
    //Check Humidity Sensor
    float humidity = myHumidity.getRH();      
    if (humidity == 998) //Humidty sensor failed to respond
    {
      DebugSerial.println("I2C communication to sensors is not working. Check solder connections.");

      //Try re-initializing the I2C comm and the sensors
      myPressure.begin();
      myPressure.setModeBarometer();
      myPressure.setOversampleRate(7);
      myPressure.enableEventFlags();
      myHumidity.begin();
    }
   else
    {
      DebugSerial.print("Humidity = ");
      DebugSerial.print(humidity);
      DebugSerial.print("%,");
    }/*
   //aw read celcius not f
   //   float temp_h = myHumidity.getTempF();
   //   Serial.print(" temp_h = ");
   //   Serial.print(temp_h, 2);
   //   Serial.print("F,");
          
      float tempC_h = myHumidity.getTemp();
      DebugSerial.print(" tempC_h = ");
     // DebugSerial.print(tempC_h, 2);
      DebugSerial.print("C,");
    
      //Check Pressure Sensor
      float pressure = myPressure.readPressure();
      //aw read hectopascal
      pressure = pressure/100;
      DebugSerial.print(" Pressure = ");
      DebugSerial.print(pressure);
      DebugSerial.print("hPa,");
         
      //aw pressure temp giving -1766 reading (!) so commented out
      //Check tempf from pressure sensor
      //float tempf = myPressure.readTempF();
      //Serial.print(" temp_p = ");
      //Serial.print(tempf, 2);
      //Serial.print("F,");

      //Check light sensor
      float light_lvl = get_light_level();
      DebugSerial.print(" light_lvl = ");
      DebugSerial.print(light_lvl);
      DebugSerial.print("V,");

      //Check batt level
      float batt_lvl = get_battery_level();
      DebugSerial.print(" VinPin = ");
      DebugSerial.print(batt_lvl);
      DebugSerial.print("V");

      DebugSerial.println();
   }
*/
    digitalWrite(STAT_BLUE, LOW); //Turn off stat LED
  
  

  delay(100);


  DebugSerial.println("starting send inside void loop!");
  int packetsflag = 0; // 0: unconfirmed packets, 1: confirmed packets
  if (RAKLoRa.rk_sendData(packetsflag, 1, buffer))
  {
    for (unsigned long start = millis(); millis() - start < 90000L;)
    {
      String ret = RAKLoRa.rk_recvData();
      if (ret.startsWith(STATUS_TX_COMFIRMED) || ret.startsWith(STATUS_TX_UNCOMFIRMED))
      {
        DebugSerial.println("Send data ok!");
       //aw changed to 30 sec  delay(5000);
       delay(30000);
        return;
      }
    }
    DebugSerial.println("Send data error!");
    while (1);
  }



  
} //end of void loop//






float get_light_level()/////////////////////////////////////////////////////////////////////////////////////////////////
//Returns the voltage of the light sensor based on the 3.3V rail
//This allows us to ignore what VCC might be (an Arduino plugged into USB has VCC of 4.5 to 5.2V)
{
  float operatingVoltage = analogRead(REFERENCE_3V3);

  float lightSensor = analogRead(LIGHT);

  operatingVoltage = 3.3 / operatingVoltage; //The reference voltage is 3.3V

  lightSensor = operatingVoltage * lightSensor;

  return (lightSensor);
}





float get_battery_level()////////////////////////////////////////////////////////////////////////////////////////////////
//Returns the voltage of the raw pin based on the 3.3V rail
//This allows us to ignore what VCC might be (an Arduino plugged into USB has VCC of 4.5 to 5.2V)
//Battery level is connected to the RAW pin on Arduino and is fed through two 5% resistors:
//3.9K on the high side (R1), and 1K on the low side (R2)
{
  float operatingVoltage = analogRead(REFERENCE_3V3);

  float rawVoltage = analogRead(BATT);

  operatingVoltage = 3.30 / operatingVoltage; //The reference voltage is 3.3V

  rawVoltage = operatingVoltage * rawVoltage; //Convert the 0 to 1023 int to actual voltage on BATT pin

  rawVoltage *= 4.90; //(3.9k+1k)/1k - multiple BATT voltage by the voltage divider to get actual system voltage

  return (rawVoltage);
}

Hi Andrew,

Hmm, after taking a bit of a look at the si7021 Hookup guide and library code my first guess is library and/or serial port clashes. I’ve noticed the library actually tries to use the hardware serial output to display some text, which is the same one you’re using for your DebugSerial.

You could also be running out of memory, because there’s a whole lot of stuff going on.

FYI Serial.print() converts floats to ASCII before printing them (by default, truncates to 2 decimal places). I couldn’t see anything specific that should cause an error there.

I’d also suggest turning on verbose output for the compiler, and seeing if you get any warnings there.

I recommend you start from the ground up, adding one piece at a time using the most basic code you can until it breaks then back tracking and diving into the libraries. There’s no way around it, this is going to be time consuming and painstaking!

Regards,
Oliver
Support | Core Electronics

thanks I’ll have another go at this tomorrow. I’ve also got an ESP13 WiFi shield which I can try, but having looked into this for the first time, it seems like another rabbit hole to go down. Still, with Covid erupting outside, I’ve got nothing better to do.
Cheers, Andrew

1 Like

I tried turning on verbose compile and upload. There was a section in orange which looks like a warning (see below) but overall it looked fairly happy.

In file included from C:\Users\andre\Documents\Arduino\libraries\SparkFun_MPL3115A2_Breakout_Arduino_Library-master\src\SparkFunMPL3115A2.cpp:36:0:

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src/Wire.h: In member function 'float MPL3115A2::readAltitude()':

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src/Wire.h:64:13: note: candidate 1: uint8_t TwoWire::requestFrom(int, int)

     uint8_t requestFrom(int, int);

             ^~~~~~~~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src/Wire.h:61:13: note: candidate 2: uint8_t TwoWire::requestFrom(uint8_t, uint8_t)

     uint8_t requestFrom(uint8_t, uint8_t);

             ^~~~~~~~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src/Wire.h: In member function 'float MPL3115A2::readPressure()':

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src/Wire.h:64:13: note: candidate 1: uint8_t TwoWire::requestFrom(int, int)

     uint8_t requestFrom(int, int);

             ^~~~~~~~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src/Wire.h:61:13: note: candidate 2: uint8_t TwoWire::requestFrom(uint8_t, uint8_t)

     uint8_t requestFrom(uint8_t, uint8_t);

             ^~~~~~~~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src/Wire.h: In member function 'float MPL3115A2::readTemp()':

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src/Wire.h:64:13: note: candidate 1: uint8_t TwoWire::requestFrom(int, int)

     uint8_t requestFrom(int, int);

             ^~~~~~~~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src/Wire.h:61:13: note: candidate 2: uint8_t TwoWire::requestFrom(uint8_t, uint8_t)

     uint8_t requestFrom(uint8_t, uint8_t);

             ^~~~~~~~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src/Wire.h: In member function 'byte MPL3115A2::IIC_Read(byte)':

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src/Wire.h:64:13: note: candidate 1: uint8_t TwoWire::requestFrom(int, int)

     uint8_t requestFrom(int, int);

             ^~~~~~~~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src/Wire.h:61:13: note: candidate 2: uint8_t TwoWire::requestFrom(uint8_t, uint8_t)

     uint8_t requestFrom(uint8_t, uint8_t);

             ^~~~~~~~~~~
1 Like

I’m considering turning off the serial output altogether and just allowing it to send to the LoRa (software serial) to see if there is a serial conflict.

1 Like

Hey Andrew,

Yes, that would be an excellent way to be able to confirm what’s causing the issue, and whether it’s a conflict based on the use of both boards simultaneously, this likely isn’t the case but would be worth confirming. Please let us know how you go. Also, could you try using the lines edited below so that we can check that the issue is not to do with how the script is converting floats in this example?

Thanks

else
    {
      DebugSerial.print("Humidity = ");
      float testFloat = 0;
      DebugSerial.print(testFloat);
      DebugSerial.print("%,");`
    }/*
else
    {
      DebugSerial.print("Humidity = ");
      int testInt = 0;
      DebugSerial.print(testInt);
      DebugSerial.print("%,");
    }/*

Bryce
Core Electronics | Support

1 Like

OK getting somewhere! Took out all the
DebugSerial.print();
statements and it is looping and sending to LoRa.
And it still prints if I add back
Serial.print(humidity);
Now to add things back gradually. Thanks for your help and support.

3 Likes

Hey Andrew,

Excellent news! Glad to hear that it’s now working correctly. All the best!

Bryce
Core Electronics | Support

Two things to consider here I think.

Buffer over-run for the transmit side of the serial ports. Increasing the buffer can help, but can be difficult if using a library. Otherwise try increasing the baud rate, so the buffer empties faster.

Secondly software serial sometimes doesn’t play nice with the delay function (which you seem to have removed in your revised code).

Try using the millis function instead. Here’s a nice link on the matter:

3 Likes

thanks for this and for joining in the discussion. I haven’t really addressed the timing of the loop yet. The weather program prints to serial every second, but this will fall foul of TTN Fair Use policy. So I’m going to have to change this and of course it will change the averaging windspeed/direction routines. So I’ll explore gently and report back when I find out more.

2 Likes

Seems to be working well using Serial rather than DebugSerial. Not sure why this should be.

Have got it sending to TTN with the LoRa now - yay!

Thanks for help.

3 Likes

I have been stuck with this. My LoRa version works perfectly for 6 transmissions and then stops. I have tried to get the LoRa board manufacturer involved but they seem too busy. So I’m looking at ditching the Weather Shield and just using the wind and rain sensors with another LoRa board (which I’m sure will also be lower power consumption than a Uno).
Can you help me with the connections please. I’ve looked at the WeatherShield Schematic and the PCB and I don’t quite understand how it works (sorry for my ignorance). There seem to be a lot of connections through resistors to ground. I think I just want to connect the rain sensor to D2 and presumably give it some power and grounding. And the wind meter to A0 and D3 as well as power and GND.
For instance for the rain sensor, do I have to recreate the set up with R11, R12 and D5 and D6? What is Rain5 connected to on the RJ11?
Thanks for your help with this.

OK this no longer relevant as problem with LoRa board now fixed (it was a memory leak in the library).
But the Uno is running out of memory - it seems it can’t manage both the WeatherShield and LoRa libraries in the same sketch. So rather than faff about trying to reduce the number of global variables in the code, I’m going to try a Mega.

1 Like

Hey Andrew,

I know this has been a while since we’ve discussed the project, but did the Mega switch work for the project?

Bryce
Core Electronics | Support

Hi Bryce, thanks for your interest. Yes the Mega works well and I have a functional weatherstation. The only problem now is the LiPo Rider doesn’t seem to supply enough power to keep the LoRa connection going indefinitely. So don’t think I can run it on solar, but it works well with a mains charger.
Cheers, Andrew

1 Like

Hey Andrew,

That’s excellent, well done! Hm, other than simply increasing the capacity of the cells and the power output of the solar panels it may be stuck with using mains in this case, however, that’s still great that it’s now running continuously. Have a great day!

Bryce
Core Electronics | Support