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

You won’t be able to use the Edgent features such as WiFi provisioning and OTA updates with your hardware, so the migration will be a simple case of setting-up a template in Blynk IoT and defining the datastreams then creating a device based on that template, adding your Template ID to the top of your existing code, replacing your auth token with the Blynk IoT token.
You’ll need to have the latest Blynk library installed, whereas you should be using the Legacy 0.6.1 library at the moment.

Pete.

Thanks Pete.

Now that I’ve got the segmented program running nicely I’m starting to add the other features that (with a great deal of help) I worked out earlier. One of them was a timer. This was necessitated because in our remote condition we share an internet connection. In my early test version last summer there were complaints that my system was using too much data. That was because the sensor was connected to Blynk 24/7.
I really didn’t need constant monitoring, so I incorporated a millis program that would connect to the internet briefly every ten minutes. That appears to cut down on the internet use a lot. I’ll attach the program at the bottom of this message.
Now that I have the segmented switch program I want to incorporate that timer into the program. Since there is no limit on how often the transmitter and the receiver communicate I don’t see any need in incorporating the timer into the void take_a_reading() loop. My thoughts are it should be incorporated into the BLYNK_WRITE(V1). I guess my question is can it be applied once to cover the four cases, or does it have to be added to each case? Or is there a more elegant way of incorporating this?

/*
 * 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: https://github.com/blynkkk/blynk-library
 *
 * Conncetions:
 * D1 -> SCL of I2C LCD 
 * D2 -> SDA of I2C LCD
 * D3 -> Out of DHT11/22
 *
 */
#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 D3 //redefining I2C pins as D1 is needed by LoRa unit
#define I2C_SCL D4

#define ss 15
#define rst 16
#define dio0 2


unsigned long previousMillis = 0;        // will store last time LED was updated
unsigned long interval = 1000;          





const int ledPin = D1; //warning light that water has dropped beyone preset level

char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; //Enter the Auth code which was send by Blink

char ssid[] = "xxxxxxxxxx";  //Enter your WIFI Name
char pass[] = "xxxxxxxxxx";  //Enter your WIFI Password


void setup()
{
pinMode(ledPin,OUTPUT);
Wire.pins(D3, D4);
  
  //Serial.begin(9600);

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);
  Blynk.begin(auth, ssid, pass);

   Serial.println("LoRa Sender");
 LoRa.setPins(ss, rst, dio0);
  if (!LoRa.begin(433E6)) 
  {
    Serial.println("Starting LoRa failed!");
    delay(100);
    while (1);
  }
  Serial.println("LoRa Started");
  lcd.clear();
  lcd.print("Waiting");
   LoRa.setSpreadingFactor(10);
 LoRa.setSignalBandwidth(62.5E3);
LoRa.crc(); 
}

void loop()
{
 // try to parse packet
  int packetSize = LoRa.parsePacket();
  int targetDistance = LoRa.parseInt();

  if (packetSize)
  {  
    //Serial.print("distance is ");
    // Serial.print(targetDistance);
   // Serial.print(" inches ");
   // Serial.println(" ");
    
 
lcd.setCursor(0,0); //First line
lcd.print("water is down");
lcd.setCursor(0,1); //Second line
lcd.print((targetDistance - 4));
lcd.print(" inches");



unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
Blynk.connect();    
 Blynk.run(); // Initiates Blynk
 Blynk.virtualWrite(V1,(targetDistance - 4)); 
 interval = 10 * 1000UL;
 } 
 else {
  Blynk.disconnect();
 interval = 10 * 60 * 1000UL;
 }
 
delay(1000);

 {
      if ((targetDistance - 4) <= 25 )
      {
        digitalWrite(ledPin,LOW);
      }
      else 
      {
        digitalWrite(ledPin,HIGH);
      }
 }
  }
}

First of all, don’t use millis, and don’t use delays, use BlynkTimer instead.
Do you want to constantly refresh your LCD display, provided this has no impact on internet traffic, or do you only want this to be updated every 10 minutes?

Pete.

In an ideal world I"d like to constantly refresh the LCD display the LED provided it has no effect on the internet traffic.

I started out trying to get the blynktimer working, but had some problems getting it running, so I switched to the millis and found it (for some reason) easier to get running, so I stuck with it.

This is a very useful topic, make sure to check it out

Put me down to be the first to read it, John. That’s exactly what I encountered. The explanation and examples I found for millis were much easier for me to understand and adopt. So I tend to always opt for the easiest (not always the best) solution.
Jeff

1 Like

It’s up to you buddy.

This a a great example of why you should lay-out your overall plan at the beginning, as it may influence how the code is structured.

Currently, using the code from post #33 the value that you wnat to push to Blynk every 10 minutes is adjusted_reading.
This variable is local to the take_a_reading() function, as that is where it is declared…

We need to move this to become a global variable by declaring it near the top of your sketch…

int adjusted_reading;

and not re-declare it in take_a_reading(), so we need to remove the int there…

adjusted_reading = (reading - adjustment);

You already have timer.run(); in your void loop, which is good, but you need to remove Blynk.run(); as you don’t want the Blynk library to talk to the server all the time.

You now need another timer event to be added to your void setup, like this:

timer.setInterval(1000L,take_a_reading); // Existing timer
timer.setInterval(600000L,send_to_blynk); // send data to Blynk every 10 minutes (60,000 m/s)

Your send_to_blynk() function might look something like this…

send_to_blynk()
{
  Blynk.connect();    
  Blynk.run();
  Blynk.virtualWrite(V0, adjusted_reading);  // To Display Widget
  Blynk.run();
  Blynk.disconnect();
}

The only potential problem with this approach is that the data might not arrive at the Blynk server, because the Blynk.disconnect() is actioned before the virtualWrite has completed. I’ve added an additional Blynk.run() before the disconnect, but you’ll have to see if the data is reliably written to Blynk using this approach.
If not, we may need to move the code into a BLYNK_CONNECTED() callback.

Pete.

Thanks again, Pete. I’ll play with it tomorrow. Regarding the overall plan in advance, it makes sense if you’re totally competent in the coding Me, I’m still plodding along, so I find it easier to break it down. If I can’t get a basic system going, it’s easier to troubleshoot. Then, if I add an additional task, and it doesn’t work, I don’t have to go back to the very beginning. I just have to go back a step. As you know,I’ve been working on this for more than 3 years. thanks to your help and others we now have a working system. Now I’m trying to make it more user friendly.
Again thanks for your time.
Jeff

Yes, but being fed requirements piecemeal doesn’t help people like me who are trying to assist you, as we can’t see the bigger picture.

Pete.

1 Like

Okay. I’ll keep that in mind. Looking at your code suggestions I’m wondering where in the sketch the Void send_to_blynk() would be placed?
Jeff

Anywhere you like, provided it’s not inside another function.

Pete.

Hi Pete:
I’ve made the changes you suggested. The sketch compiles, but only shows 0 as a depth (on all four tanks) bot on the LCD display and on the android device. I know the transmitter is working because I have a receiver (not hooked to the net) that is showing the correct depth.

I commented out the notification addition I made to make sure that the sketch was the same as the one that runs fine without the blynktimer. I changed the time to 5 minutes just so I don’t have to wait too long to see if the program is working. Just in case the timer didn’t take it’s first timing for 5 minutes. No luck. the only thing I can think of is the int adjustment might not be in the right place.
Any ideas what I’m doing wrong?

/*
 * 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: https://github.com/blynkkk/blynk-library
 *
 * Conncetions:
 * D1 -> SCL of I2C LCD 
 * D2 -> SDA of I2C LCD
 * D3 -> Out of DHT11/22
 *
 */
#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 D3 //redefining I2C pins as D1 is needed by LoRa unit
#define I2C_SCL D4

#define ss 15
#define rst 16
#define dio0 2
int adjustment;
int adjusted_reading;

int tank_to_read;

const int ledPin = D1; //warning light that water has dropped beyone preset level
char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"; //Enter the Auth code which was send by Blink
char ssid[] = "xxxxxxxxxxxxxxxxxxxx";  //Enter your WIFI Name
char pass[] = "xxxxxxxxxxxxxxxxx";  //Enter your WIFI Password

BlynkTimer timer;

void setup()
{
timer.setInterval(1000L,take_a_reading);
  
pinMode(ledPin,OUTPUT);
Wire.pins(D3, D4);
  
Serial.begin(9600);

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);
Blynk.begin(auth, ssid, pass);

Serial.println("LoRa Sender");
LoRa.setPins(ss, rst, dio0);
if (!LoRa.begin(433E6)) 
  {
Serial.println("Starting LoRa failed!");
delay(100);
while (1);
  }
Serial.println("LoRa Started");
lcd.clear();
lcd.print("Waiting");
LoRa.setSpreadingFactor(10);
LoRa.setSignalBandwidth(62.5E3);
LoRa.crc(); 

timer.setInterval(1000L,take_a_reading); // Existing timer
timer.setInterval(300000L,send_to_blynk); // send data to Blynk every 5 minutes (30,000 m/s)
}

void send_to_blynk()
{
  Blynk.connect();    
  Blynk.run();
  Blynk.virtualWrite(V0, adjusted_reading);  // To Display Widget
  Blynk.run();
  Blynk.disconnect();
}

void take_a_reading()
{
  int packetSize = LoRa.parsePacket();
  int reading = LoRa.parseInt();
  int warning_level = 25 - 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);
   
  if (packetSize)
  {
    Blynk.virtualWrite(V0, adjusted_reading);  // To Display Widget
    lcd.setCursor(0,0); //First line
    lcd.print("water is down");
    lcd.setCursor(0,1); //Second line
    lcd.print(adjusted_reading);
    lcd.print(" inches"); 

//String notification_body = "";
//notification_body += "The water is down ";
//notification_body += String(adjusted_reading);
//notification_body += "  inches";
//Blynk.notify (notification_body); 
   } 
   
//Alarm LED on receiving unit for tank 3
   if (reading <= warning_level )
   {
      digitalWrite(ledPin,LOW);
   }
   else 
   {
      digitalWrite(ledPin,HIGH);
   }
}

void loop()
{
timer.run();
  }
  
BLYNK_WRITE(V1)
{
 tank_to_read = param.asInt();
 switch (tank_to_read)
  {
    case 1:
   {   
     adjustment = 0;
     break;      
   }

    case 2:
   {   
     adjustment = 4;
     break;      
   }

    case 3:
   {   
     adjustment = 8;
     break;      
   }

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

How did you configure your datastream ?
Post some screenshots please.
also you need a timer.run(); in the void loop.

John, you need to follow the whole conversation, not just the code. Please read Pete’s explanation a couple of posts up for explanation.

Yes it was a mistake, my bad :sweat_smile:

No problem. I’m following Pete’s advice on this, and he’s pretty good about explaining what he’s doing, so if you have questions, direct them towards the post and I’m sure he’ll see them. I’m still a bit of a neophyte. Once I see it, I can understand what was done, and usually why. Thanks for following this and your input.

You previously had this line of code in your take_a_reading() function…

I told you that you needed to remove the int from the beginning of this line of code, so that you weren’t re-declaring the variable that we’ve now made global.
Instead, you’ve removed the line of code altogether.

Pete.

I would use a segmented switch, process input from it in sketch and then send the correct value to the gauge. This would minimize the coding for enabling/disabling buttons.