I want to run the float sensors in loop but send telegram bot message only once. i tried with bool and still could not make it work.
i tried this for hours and cant fix.. please hope someone could help me here
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
const char* ssid = "xxxx";
const char* password = "xxxxxxxxx";
const int FloatSensor = 5;
const int Relay = 4;
int FloatState =0;
#define BOTtoken "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
#define CHAT_ID "xxxxxx"
X509List cert(TELEGRAM_CERTIFICATE_ROOT);
WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);
void setup() {
Serial.begin(115200);
pinMode(FloatSensor, INPUT_PULLUP);
pinMode (Relay, OUTPUT);
configTime(0, 0, "pool.ntp.org"); // get UTC time via NTP
client.setTrustAnchors(&cert); // Add root certificate for api.telegram.org
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
int a = 0;
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
a++;
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
delay(500);
bot.sendMessage(CHAT_ID, "System started", "");
delay(1000);
}
void loop() {
bool FloatState = digitalRead(FloatSensor);
if (FloatState == LOW){
Serial.println("Water level HIGH & Pressure pump ON");
digitalWrite(Relay, HIGH);
bot.sendMessage(CHAT_ID, "Water level HIGH & Pressure pump ON"); // only once i want to send message to bot
}
else if (FloatState == HIGH){
Serial.println("Water level LOW & Pressure pump OFF");
digitalWrite(Relay, LOW);
bot.sendMessage(CHAT_ID, "Water level LOW & Pressure pump OFF"); // only once i want to send message to bot
}
}
}
this is the only part where i want to run only once
you have to verify a "staus change" not a status itself...I mean...you have to read the status of the sensor then save this in a variable with a global scope...called something like "oldState"... then verify if the new read has a different value of the "oldState" variable...so...if the new valie is HIGH do something otherwise do semthing else....
thanks for replying . i even tried statechangedetection before and their is a issue with this too.
while float switch is high and when their is a power outage , when power gets back and float is high
it does nothing because it only works with change of state.
this happens same when float is LOW. after power outage it never reads the float sensor .unless their is change in state.
could yu help me on this.?
do you need that at the start up of the arduino the message is sent about all possible status of th efloat then just if this will change?...or do you want that the message is sent always for te status chagement also after a power off of the arduino?...for this last I mean...before the power off the float was low...at the start up it rise to high...so this is a status change...so arduino has to send a message...what of the two options?
thanks for replying, what i need is even after power outage or after boot i want to check for float sensor change first and the telegram bot should send msg only once.
eeprom is something limited with esp8266 and i dont want to run that in flash memory .
better what im asking is...not to recover the last state rather let it start checking for sensor states (if float is HIGH or LOW) from start and send telegram bot msg once
this works but not completely, have tried the same in past. but what happens is when float is LOW and once esp boots and its connected to wifi and when bot sends system started.
then it send float to HIGH for a sec . after that it reads and gets back to LOW.
*relay dosnt turn on while boot.( for LTR does happen)
Im using ssr
beacuse of this relay turns on for a sec and turns off also telegram bot sends its high .only after a sec it sends low
i am not sure to have properly understood your situation...but maybe you can start to read the status of the fload only after that you are sure that the whole system is ready...maybe a "delay" will help...
In this code when esp boots up && float is HIGH. it sends LOW once and sends HIGH . Any suggestions to fix this issue?
On serial monitor
WiFi connected
IP address: 192.168.169.210
Water level LOW & Pressure pump OFF // float is HIGH but still runs LOW for once
Water level HIGH & Pressure pump ON // actual state of float
code is as follows
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
const char* ssid = "xxx";
const char* password = "xxxxxx";
const int FloatSensor = 5;
const int Relay = 4;
static bool prevFloatState = 1;
//bool prevFloatState = digitalRead(FloatSensor);
#define BOTtoken "xxxxxxxxxx"
#define CHAT_ID "xxx"
X509List cert(TELEGRAM_CERTIFICATE_ROOT);
WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);
void setup() {
Serial.begin(115200);
pinMode(FloatSensor, INPUT_PULLUP);
pinMode (Relay, OUTPUT);
configTime(0, 0, "pool.ntp.org"); // get UTC time via NTP
client.setTrustAnchors(&cert); // Add root certificate for api.telegram.org
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
int a = 0;
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
a++;
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
delay(500);
bot.sendMessage(CHAT_ID, "System started", "");
delay(2000);
if (prevFloatState == LOW) {
Serial.println("Water level HIGH & Pressure pump ON");
digitalWrite(Relay, HIGH);
bot.sendMessage(CHAT_ID, "Water level HIGH & Pressure pump ON"); // only once i want to send message to bot
}
else {
Serial.println("Water level LOW & Pressure pump OFF");
digitalWrite(Relay, LOW);
bot.sendMessage(CHAT_ID, "Water level LOW & Pressure pump OFF"); // only once i want to send message to bot
}
}
void loop() {
bool FloatState = digitalRead(FloatSensor);
if (FloatState != prevFloatState) {
prevFloatState = FloatState;
if (FloatState == LOW) {
Serial.println("Water level HIGH & Pressure pump ON");
digitalWrite(Relay, HIGH);
bot.sendMessage(CHAT_ID, "Water level HIGH & Pressure pump ON"); // only once i want to send message to bot
}
else {
Serial.println("Water level LOW & Pressure pump OFF");
digitalWrite(Relay, LOW);
bot.sendMessage(CHAT_ID, "Water level LOW & Pressure pump OFF"); // only once i want to send message to bot
}
}
}
This looks like a good idea. Why not actually digitalRead() the FloatSensor before the if statement in you setup()?
You could read the sensor and set the FloatState and the prevFloatState would be the logical opposite.
Declare both global variables global, read the sensor and set both values in setup(). Artificial instate state transition when you hit the loop().
Sry typing with my nose here, I'll try to make an examlpe if you can't get that to work, but it also sounds like you have some warming up issues, perhaps as suggested a bit of delay in the setup portion so everything is in a known state settled ready for action.
Thanks for your response @alto777 . I appreciate if you could share some help with example .
I even tried out delay in setup..and read float sensor in setup ...nothings works ...Still the same issue ...The last code I shared in last post I what I use for now . When float is LOW . It runs low and perfect...but when it's Float is HIGH on boot it goes low and then goes high...really not sure what's the issue .
I even set previous state = 1 soo this won't affect when float is LOW .
It would be great if you help to fix the duplicate reading of low when Float is HIGH .
My beach buddy is on her way to pick me up, but I did write this
const int FloatSensor = 5;
const int Relay = 4;
bool prevFloatState = 1;
void setup() {
Serial.begin(115200);
pinMode(FloatSensor, INPUT_PULLUP);
pinMode(Relay, OUTPUT);
prevFloatState = digitalRead(FloatSensor);
Serial.print("System started with... ");
bool initialFloatState = digitalRead(FloatSensor);
if (initialFloatState == LOW) {
Serial.println("Water level HIGH & Pressure pump ON");
digitalWrite(Relay, HIGH);
}
else {
Serial.println("Water level LOW & Pressure pump OFF");
digitalWrite(Relay, LOW);
}
}
void loop() {
static unsigned long lastTime;
unsigned long now = millis();
if (now - lastTime < 20) return; // run loop at 50 Hz, automatic swtich debouncing.
lastTime = now;
bool FloatState = digitalRead(FloatSensor);
if (FloatState != prevFloatState) {
prevFloatState = FloatState;
if (FloatState == LOW) {
Serial.println("Water level HIGH & Pressure pump ON");
digitalWrite(Relay, HIGH);
}
else {
Serial.println("Water level LOW & Pressure pump OFF");
digitalWrite(Relay, LOW);
}
}
}
and simulate it here. Take the link and play with it:
It respects the initial setting of the slide switch. Run it and leave the switch on or off for the next test.
This is the suggestion I made and @ToddL1962 also made put into the simplest expression of the logic needed to send a message once, to react to state changes and to boot up into an approriate mode.
This is the logic I believe you need. If is and it doesn't work when you put it into the more complex context which is your sketch, it is something else that is the problem.