Display only one sensor (of several) attached to one device

So, you could either answer my question, or wait until I have the time to do a side-by-side comparison between this and the code that I posted earlier.

Pete.

I used your code. I put my SSID, password and token in. I decommented the Lora Library. I added:

adjusted_reading = (reading - adjustment);

  Serial.print("Selected tank = ");
  Serial.println(tank_to_read);
  Serial.print("Actual reading = ");
  Serial.println(reading);
  Serial.print("Adjustment factor = ");
  Serial.println(adjustment);
  Serial.print("Adjusted reading = ");
  Serial.println(adjusted_reading);

to the void take_a_reading()

Since my last post to you I moved
int packetSize = LoRa.parsePacket();
int reading = LoRa.parseInt();

to the void take_a_reading()
as well.
The program seems to be working okay now. Iā€™ll test it out over the next few hours and get back to you. Thanks for your help. Here is the program as it stands now:

/*
   For this example you'll need the following library:
 *  *
   1) Arduino-LiquidCrystal-I2C-library: https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library
   2) Blynk Library 0.6.1 (if usimg Legacy or latest if using IoT): https://github.com/blynkkk/blynk-library

  Conncetions:
  D0 (GPIO16) -> RST Pin on LoRa Rx module
  D1 (GPIO5) -> LED on U3 connector?
  D2 (GPIO4) -> DIO0 Pin on LoRa Rx Module
  D3 (GPIO0) -> SDA Pin on OLED Display
  D4 (GPIO2) -> SCL Pin on OLED Display
  D5 (GPIO14) -> SCK pin on LoRA Rx module
  D6 (GPIO12) -> MISO pin on LoRA Rx module
  D7 (GPIO13) -> MOSI pin on LoRA Rx module
  D8 (GPIO15) -> nSS pin on LoRA Rx module

*/
#include <LoRa.h>
#define BLYNK_PRINT Serial
#include <SPI.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

#define I2C_SDA 0 // GPIO0  = D3 - redefining I2C pins as D1 is needed by LoRa unit
#define I2C_SCL 2 // GPIO2  = D4

#define ss 15     // GPIO15 = D1
#define rst 16    // GPIO16 = D0
#define dio0 4    // GPIO4  = D2

int adjustment;
int adjusted_reading;
int tank_to_read;

const int ledPin = 5; // GPIO5  = D1 - warning light that water has dropped beyond preset level

char auth[] = "ZFiawkv0a-UnC_tXeO3Ir0n_FRhEXy1v"; //Enter the Auth code which was send by Blink
char ssid[] = "kuggle's_condo_2";  //Enter your WIFI Name
char pass[] = "jakesnak";  //Enter your WIFI Password

int wifi_connect_count = 0;          // Keep track of how many times we've tried to connect to the WiFi
int wifi_connect_max_retries = 20;   // Specify how many attempts we will have at connecting to the WiFi
bool sync_completed = false;         // Flag to track when BLYNK_WRITE(V1) has completed

BlynkTimer timer;

void setup()
{
  pinMode(ledPin, OUTPUT);
  Wire.begin(I2C_SDA, I2C_SCL); // Updated from deprecated wire.pins(sda,scl) command

  Serial.begin(74880); // Native baud rate for the NodemCU

    lcd.begin();   // iInit the LCD for 16 chars 2 lines
    lcd.backlight();   // Turn on the backligt (try lcd.noBaklight() to turn it off)
    delay (1000);

    Serial.println("LoRa Receiver ");
    LoRa.setPins(ss, rst, dio0);
    if (!LoRa.begin(433E6))
    {
      Serial.println("Starting LoRa failed!");
      delay(2000);
      Serial.println("Restarting ESP...");
      ESP.restart(); // Restart the ESP
    }
    Serial.println("LoRa Started");
    lcd.clear();
    lcd.print("Waiting");
    LoRa.setSpreadingFactor(10);
    LoRa.setSignalBandwidth(62.5E3);
    LoRa.crc();

  WiFi_Connect();
  Blynk.config(auth);
  send_to_blynk();  // Connect to Blynk then sync the segmented switch at startup

  timer.setInterval(1000L, take_a_reading); // Existing timer
  timer.setInterval(60000L, check_connections); // Check that we have a WiFi connection every 1 minute
  timer.setInterval(180000L, send_to_blynk); // send data to Blynk every 3 minutes (180,000 m/s)
}

void loop()
{
  timer.run();
}


void take_a_reading()
{
  int packetSize = LoRa.parsePacket();
  int reading = LoRa.parseInt();

 

  if (packetSize)
  {
    adjusted_reading = (reading - adjustment);

Serial.print("Selected tank = ");
  Serial.println(tank_to_read);
  Serial.print("Actual reading = ");
  Serial.println(reading);
 Serial.print("Adjustment factor = ");
  Serial.println(adjustment);
 Serial.print("Adjusted reading = ");
Serial.println(adjusted_reading);


  
    lcd.setCursor(0, 0); //First line
    lcd.print("water is down");
    lcd.setCursor(0, 1); //Second line
    lcd.print(adjusted_reading);
    lcd.print(" inches");
  }
}

void send_to_blynk()
{
  if (WiFi.status() == WL_CONNECTED)
  {
    Serial.println ("Connecting to Blynk");
    Blynk.connect();
    if (Blynk.connected())
    {
      Serial.println ("Connected");
      sync_completed = false;

      Blynk.syncVirtual(V1); // force the server to send the latest value for the segmented switch

      while (!sync_completed) // Wait until BLYNK_WRITE(V1) has completed
      {
        Blynk.run();
      }
      take_a_reading(); // take a reading from the tank indicated by the segmented switch
      Blynk.virtualWrite(V0, adjusted_reading); // To Display Widget
      Blynk.run();
      Blynk.disconnect();
      Serial.println ("Blynk Disconnected");
    }
    else
    {
      Serial.println (">>>>>>>>>>>> Unable to connect to Blynk <<<<<<<<<<<<");
    }
  }
  else
  {
    // we get here if we there is no WiFi connection
    Serial.println (">>>>>>>>>>>> No WiFi Connection, so Blynk connection not attempted <<<<<<<<<<<<");
  }
}

BLYNK_WRITE(V1) // Segmented switch to select tank
{
  Serial.println("BLYNK_WRITE(V1) Executed");
  tank_to_read = param.asInt();
  switch (tank_to_read)
  {
    case 1:
      {
        adjustment = 0;
        sync_completed = true;
        break;
      }

    case 2:
      {
        adjustment = 4;
        sync_completed = true;
        break;
      }

    case 3:
      {
        adjustment = 8;
        sync_completed = true;
        break;
      }

    case 4:
      {
        adjustment = 12;
        sync_completed = true;
        break;
      }
  }
}

void check_connections()
{
  if (WiFi.status() != WL_CONNECTED)
  {
    WiFi_Connect();
  }
  else
  {
    Serial.println(F(">>>> WiFi checked - all good <<<<"));
  }
}

void WiFi_Connect() // New functon to handle the connectuon to the WiFi network
{
  wifi_connect_count=0; // reset the counter
  Serial.println(F("Connecting to WiFi"));

  if (WiFi.status() != WL_CONNECTED)
  {
    WiFi.begin(ssid, pass); // connect to the network
  }
  while (WiFi.status() != WL_CONNECTED  && wifi_connect_count < wifi_connect_max_retries) // Loop until we've connected, or reached the maximum number of attemps allowed
  {
    delay(500);
    wifi_connect_count++;
    Serial.print(F("WiFi connection - attempt number "));
    Serial.println(wifi_connect_count);
  }

  if (WiFi.status() == WL_CONNECTED)
  {
    WiFi.mode(WIFI_STA);
    Serial.println(F("Wi-Fi CONNECTED"));
    Serial.println();
  }
  else
  {
    Serial.println(F(">>>>>>>>>>>> Unable to connect to WiFi <<<<<<<<<<<<"));
  }
}
1 Like

Everything seems to be working now! One question. I took out the LED alarm section before we started trying to fix the problems.

//Alarm LED on receiving unit for tank 3
   if (reading <= warning_level )
   {
      digitalWrite(ledPin,LOW);
   }
   else 
   {
      digitalWrite(ledPin,HIGH);
   }

if I want to reintroduce it in the program where do you think it should go?
Jeff

In take_a_reading but you need to use adjusted_reading

Pete.

Okay. Thanks again. It took a lot of effort on your part. Much appreciated.
Jeff

Itā€™s been a few months since Iā€™ve reported in. Again a BIG thanks to Pete for all the help. I finally made it up to the cottage last week and had a chance to try out the water monitoring system for real. And of course what worked on the bench didnā€™t quite work in the field. Peteā€™s sketch above worked fine. However my minor tinkering caused some problems. I wanted to add a notification widget which would notify me if the water dropped below a certain level. Shouldnā€™t be a problem. However, the problem was the notification (where I put it in the sketch) somehow interferes with the four tank display. After I added that to the program I only see the basic depthā€¦ That is the depth displayed in Tank One. If I choose any of the other tanks I still see only that depth. Hereā€™s is the program. Any suggestions on where to move the notification section so it doesnā€™t interfere with displaying the correct value for each of the tanks?
Jeff

/*
   For this example you'll need the following library:
 *  *
   1) Arduino-LiquidCrystal-I2C-library: https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library
   2) Blynk Library 0.6.1 (if usimg Legacy or latest if using IoT): https://github.com/blynkkk/blynk-library

  Conncetions:
  D0 (GPIO16) -> RST Pin on LoRa Rx module
  D1 (GPIO5) -> LED on U3 connector?
  D2 (GPIO4) -> DIO0 Pin on LoRa Rx Module
  D3 (GPIO0) -> SDA Pin on OLED Display
  D4 (GPIO2) -> SCL Pin on OLED Display
  D5 (GPIO14) -> SCK pin on LoRA Rx module
  D6 (GPIO12) -> MISO pin on LoRA Rx module
  D7 (GPIO13) -> MOSI pin on LoRA Rx module
  D8 (GPIO15) -> nSS pin on LoRA Rx module

*/
#include <LoRa.h>
#define BLYNK_PRINT Serial
#include <SPI.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

#define I2C_SDA 0 // GPIO0  = D3 - redefining I2C pins as D1 is needed by LoRa unit
#define I2C_SCL 2 // GPIO2  = D4

#define ss 15     // GPIO15 = D1
#define rst 16    // GPIO16 = D0
#define dio0 4    // GPIO4  = D2
int LEDPin=5; //Relay and LED pin

int adjustment;
int adjusted_reading;
int tank_to_read;

const int ledPin = 5; // GPIO5  = D1 - warning light that water has dropped beyond preset level

char auth[] = "ZFiawkv0a-UnC_tXeO3Ir0n_FRhEXy1v"; //Enter the Auth code which was send by Blink
char ssid[] = "fernhill2";  //Enter your WIFI Name
char pass[] = "jakesnak";  //Enter your WIFI Password

int wifi_connect_count = 0;          // Keep track of how many times we've tried to connect to the WiFi
int wifi_connect_max_retries = 20;   // Specify how many attempts we will have at connecting to the WiFi
bool sync_completed = false;         // Flag to track when BLYNK_WRITE(V1) has completed

BlynkTimer timer;

void setup()
{
  pinMode(ledPin, OUTPUT);
  Wire.begin(I2C_SDA, I2C_SCL); // Updated from deprecated wire.pins(sda,scl) command

  Serial.begin(74880); // Native baud rate for the NodemCU

    lcd.begin();   // iInit the LCD for 16 chars 2 lines
    lcd.backlight();   // Turn on the backligt (try lcd.noBaklight() to turn it off)
    delay (1000);

    Serial.println("LoRa Receiver ");
    LoRa.setPins(ss, rst, dio0);
    if (!LoRa.begin(433E6))
    {
      Serial.println("Starting LoRa failed!");
      delay(2000);
      Serial.println("Restarting ESP...");
      ESP.restart(); // Restart the ESP
    }
    Serial.println("LoRa Started");
    lcd.clear();
    lcd.print("Waiting");
    LoRa.setSpreadingFactor(10);
    LoRa.setSignalBandwidth(62.5E3);
    LoRa.crc();

  WiFi_Connect();
  Blynk.config(auth);
  send_to_blynk();  // Connect to Blynk then sync the segmented switch at startup

  timer.setInterval( 1 * 1000L, take_a_reading); // Existing timer
  timer.setInterval(1 * 60 * 1000L, check_connections); // Check that we have a WiFi connection every 1 minute
  timer.setInterval(3 * 60 * 1000L, send_to_blynk); // send data to Blynk every 3 minutes (180,000 m/s)
}

void loop()
{
  timer.run();
}


void take_a_reading()
{
  int packetSize = LoRa.parsePacket();
  int reading = LoRa.parseInt();

 

  if (packetSize)
  {
    adjusted_reading = (reading - adjustment);

Serial.print("Selected tank = ");
  Serial.println(tank_to_read);
  Serial.print("Actual reading = ");
  Serial.println(reading);
 Serial.print("Adjustment factor = ");
  Serial.println(adjustment);
 Serial.print("Adjusted reading = ");
Serial.println(adjusted_reading);


  
    lcd.setCursor(0, 0); //First line
    lcd.print("water is down");
    lcd.setCursor(0, 1); //Second line
    lcd.print(adjusted_reading);
    lcd.print(" inches");
  }

if (adjusted_reading >=28 ) //ALARM
     {
    digitalWrite(LEDPin,HIGH); //ALARM
    if(adjusted_reading >=28)
    {
    Blynk.notify("water level has dropped below 28 inches");
    }
timer.setTimeout(1600L, [](){
 Blynk.email("jgroberm@shaw.ca", "water level has dropped below 28 inches");
});



   
      }
 else {
  digitalWrite(LEDPin,LOW);              // play tone of 400Hz for 500 ms
  }

  
}

void send_to_blynk()
{
  if (WiFi.status() == WL_CONNECTED)
  {
    Serial.println ("Connecting to Blynk");
    Blynk.connect();
    if (Blynk.connected())
    {
      Serial.println ("Connected");
      sync_completed = false;

      Blynk.syncVirtual(V1); // force the server to send the latest value for the segmented switch

      while (!sync_completed) // Wait until BLYNK_WRITE(V1) has completed
      {
        Blynk.run();
      }
      take_a_reading(); // take a reading from the tank indicated by the segmented switch
      Blynk.virtualWrite(V0, adjusted_reading); // To Display Widget
      Blynk.run();
      Blynk.disconnect();
      Serial.println ("Blynk Disconnected");
    }
    else
    {
      Serial.println (">>>>>>>>>>>> Unable to connect to Blynk <<<<<<<<<<<<");
    }
  }
  else
  {
    // we get here if we there is no WiFi connection
    Serial.println (">>>>>>>>>>>> No WiFi Connection, so Blynk connection not attempted <<<<<<<<<<<<");
  }
}

BLYNK_WRITE(V1) // Segmented switch to select tank
{
  Serial.println("BLYNK_WRITE(V1) Executed");
  tank_to_read = param.asInt();
  switch (tank_to_read)
  {
    case 1:
      {
        adjustment = 0;
        sync_completed = true;
        break;
      }

    case 2:
      {
        adjustment = 4;
        sync_completed = true;
        break;
      }

    case 3:
      {
        adjustment = 8;
        sync_completed = true;
        break;
      }

    case 4:
      {
        adjustment = 12;
        sync_completed = true;
        break;
      }
  }
}

void check_connections()
{
  if (WiFi.status() != WL_CONNECTED)
  {
    WiFi_Connect();
  }
  else
  {
    Serial.println(F(">>>> WiFi checked - all good <<<<"));
  }
}

void WiFi_Connect() // New functon to handle the connectuon to the WiFi network
{
  wifi_connect_count=0; // reset the counter
  Serial.println(F("Connecting to WiFi"));

  if (WiFi.status() != WL_CONNECTED)
  {
    WiFi.begin(ssid, pass); // connect to the network
  }
  while (WiFi.status() != WL_CONNECTED  && wifi_connect_count < wifi_connect_max_retries) // Loop until we've connected, or reached the maximum number of attemps allowed
  {
    delay(500);
    wifi_connect_count++;
    Serial.print(F("WiFi connection - attempt number "));
    Serial.println(wifi_connect_count);
  }

  if (WiFi.status() == WL_CONNECTED)
  {
    WiFi.mode(WIFI_STA);
    Serial.println(F("Wi-Fi CONNECTED"));
    Serial.println();
  }
  else
  {
    Serial.println(F(">>>>>>>>>>>> Unable to connect to WiFi <<<<<<<<<<<<"));
  }
}

You can move them to a separate void function.

First of all, your notification and email code needs to be executed when the device is connected to Blynk. As this only occurs when your send_to_Blynk function is executed, this is where your notification and email code should go.

Iā€™m not sure why youā€™ve added a non-blocking timeout timer between the notification and email, it serves no purpose.

Also, the way that your notification code is written, youā€™ll get a notification and email every 3 minutes while the alarm condition exists.
You really need to add a flag which indicates that a notification has been sent for that alarm condition then donā€™t send another notification until the alarm condition has been cleared.

More on that here (this is written for Blynk IoT, which does notifications in a very different way, but the flag variable process is exactly the same)ā€¦

Secondly, your sketch is now very difficult to follow, especially when it comes to your if statements, as youā€™ve not followed any sort of formatting protocol when it comes to indenting your code. If you take a look at the code examples I provided, youā€™ll see that itā€™s easy which if statements are nested inside each other, and which are free standing.
But, your indents are all over the place with your other code too, which makes it extremely difficult to read.

Also, Iā€™m not clear from this commentā€¦

whether youā€™re referring to your LCD display, or the Blynk app, or both. Also, youā€™ve not really confirmed that this functionality worked as required before your code changes. Did you do sufficient testing to prove that it worked as required before making your changes?

Pete.

As always thank you, Pete, for your insightful analysis. I have tried the sketch referenced in the December 21st post above and it appears to work. One thing Iā€™m not clear on is the LCD readings. Iā€™m not sure if they reflect the adjustment levels (referenced in the cases, or the actual level transmitted from the well.
Given Iā€™d like to get the unit operational as soon as possible Iā€™ll hold off using sketch with notifications .
Best
Jeff

1 Like

An update and a couple of questions.
Thanks to your help the water monitoring device works well (pardon the pun) and at least once this summer saved our water supply. However now with the phasing out of the legacy Blynk Iā€™m faced with having to migrate it to the new blynk which raises a couple of questions. The current device uses a segmented switch. I donā€™t see that option available on the new blynk (in the free version). Am I missing it somehow? Also in the legacy blynk it was possible to share the app (for an energy ā€œfeeā€) I donā€™t see that option available here - which I need as I share the app with a few neighbours who also share our water supply.
Jeff

Thatā€™s correct, itā€™s only available with a Plus or Pro subscription.

You can add users to your organisation. Maximum 5 users in total (including yourself) for the free version, 10 for the Plus version.
However, you canā€™t change the permissions for the users in either the free or Plus version, a Pro subscription is needed for that.

More details here:

Pete.

As always thanks Pete. Iā€™ll buy the plus. I hope it wonā€™t be too difficult to migrate the existing project to the new platform.

It should be fairly easy.
The only thing thatā€™s significantly different is notifications. Have a read of this to get more infoā€¦

Pete.

HI Pete:
One question. In the program (May 28th above) We check that we have a wifi connection every minute. What is the maximum time that one minute could be expanded to? Does that checking actually check to see if the wifi connection is connected to the internet? Iā€™m still trying to cut back on actual internet useage.
Thanks
Jeff

The if (WiFi.status() != WL_CONNECTED) test simply checks if the board is connected to the router.
Try unplugging the router from the internet and watching the serial monitor. Youā€™ll se that the board is still connected to the WiFi network.

Pete.

thanks

Well the tank monitor has been working at the cottage for the summer and itā€™s performed very well. It alerted us of a leak and we were able to get to the problem without losing all our water. The neighbours were very impressed and grateful. So thanks to all who helped - Particulary Pete.
One problem did occur at the end of summer. The sensor suddenly went offline. We deduced the problem was due to a battery or solar controller problem. Not to difficult to fix. The battery was old to begin with. However that did bring up the possibility of being able to monitor the voltage at the same time. That would probably mean using a second device like a 1NA219 to monitor the voltage. Iā€™m wondering how difficult would it be to add that second device into the master program (above). So that when the program sends the depth info it would also send the voltage?

1 Like

Is this battery connected to your ESP8266 device, or Nano sensor device?

Also, is it the voltage that itā€™s supplying to the board, or the actual battery voltage (assuming that they are different)?

Pete.

Hi Pete:
Thanks for the answer and advice. The sensor unit at the well is quite simple. Itā€™s a Nano connected to a Ra-02. Itā€™s powered by a 12v sealed battery thatā€™s powered by a solar panel that is connected to the battery through a solar controller.
The unit transmits to the ESP8266 unit at the cottage that transmits the data from the sensor unit to Blynk.
Jeff

You didnā€™t really answer my questions.

Pete.