text:
Why does HC-SR04 return 0s in this sketch
I am building a robot with multiple sensors, abilities etc. Since I had a bug with a HC-SR04 rotated by a servo, I experimented in a different sketch. If the distance is less than 30cm, the servo turns left and right. Since I need continuous readings of other sensors, I cannot use delays so I used millis in order to keep time. The sensor worked correctly in a different sketch, but something in the full one conflicts with it.
#include <LiquidCrystal.h>
#include <Wire.h>
#include <RTClib.h>
#include <Servo.h>
#include <IRremote.h>

RTC_DS1307 rtc;

/*const int blue2 = 12;
const int blue1 = 11;
const int red1 = 10;
const int red2 = 9;
*/
Servo servo;

byte leds[4] = {8, 7, 6, 9};

const int STBY1=45;
const int ain11=47;
const int ain12=43;
const int aPWM1=2;
const int bin11=41;
const int bin12=40;
const int bPWM1=4;
const int STBY2 = 39;
const int ain21=33;
const int ain22=31;
const int aPWM2=5;
const int bin21=35;
const int bin22=37;
const int bPWM2=3;

const int piezo = 32;

const int flamePin = A7;

int flameState;

const int photoResistor = A1;

int photoState;

const int temp = A2;

float temperature;

int ledAnalog;

const int irGnd = 52;

const int irVcc = 50;

const int irSignal = 48;

decode_results results;

IRrecv irrecv(irSignal);

boolean manualLeds = false;

boolean ledsOn = false;

unsigned long counter;

unsigned long prevMillis = 0;

int piezoInterval = 200;

int drivingMode = 0;

boolean playPiezo=false;

#define trig 22
#define echo 24
long duration;
boolean turned150 = false;
int cm30, cm, cm150;
bool checkLeft = false;
boolean checkRight = false;
boolean mainPing = true;
unsigned long servoTimer = millis();

void setup(){
  Wire.begin();
  rtc.begin();
  pinMode(piezo, OUTPUT);
pinMode(STBY1, OUTPUT);
  pinMode(aPWM1, OUTPUT);
  pinMode(ain11, OUTPUT);
  pinMode(ain12, OUTPUT);
  pinMode(bPWM1, OUTPUT);
  pinMode(bin11, OUTPUT);
  pinMode(bin12, OUTPUT);

  pinMode(STBY2, OUTPUT);
  pinMode(aPWM2, OUTPUT);
  pinMode(ain21, OUTPUT);
  pinMode(ain22, OUTPUT);
  pinMode(bPWM2, OUTPUT);
  pinMode(bin21, OUTPUT);
  pinMode(bin22, OUTPUT);

 servo.attach(12);
 for(int i=0;i<sizeof(leds)/sizeof(leds[0]);i++){
    pinMode(leds[i], OUTPUT);
 }

  pinMode(flamePin, INPUT);
  pinMode(photoResistor, INPUT);
  pinMode(temp, INPUT);
  pinMode(irGnd, OUTPUT);
  digitalWrite(irGnd, LOW);
  pinMode(irVcc, OUTPUT);
  digitalWrite(irVcc, HIGH);
  pinMode(irSignal, INPUT);
 Serial.begin(9600);
  irrecv.enableIRIn();
  digitalWrite(STBY1, LOW);
    digitalWrite(STBY2, LOW);
servo.write(90);
delay(200);
}

void loop(){

 counter=millis();
 //Serial.print("Millis1: ");
 //Serial.println(millis());
 if(irrecv.decode(&results)){
    translateIR();
    irrecv.resume();
  }
 // Serial.print("Millis2: ");
 //Serial.println(millis());
if(drivingMode == 1){
   if(((counter-servoTimer) >= 150) && mainPing){
    ping();
    cm=duration/29.1/2;
    Serial.println(cm);
    counter=millis();
    servoTimer=counter;
  }
  if((cm<30) && mainPing){

    mainPing=false;
    checkRight = true;
    counter=millis();
    servoTimer=millis();
    servo.write(150);
    cm=30;

  }
  if(checkRight && !checkLeft && ((counter-servoTimer) >= 170)){

    ping();
    checkLeft=true;
    cm150 = duration/29.1/2;
    counter=millis();
    servoTimer=millis();
    servo.write(50);
  }
  if(checkRight && checkLeft && ((counter-servoTimer) >= 340)){
  checkRight=false;
  checkLeft=false;
  mainPing=true;
  ping();
  cm30 = duration/29.1/2;
  counter=millis();
  servoTimer=millis();
  servo.write(90);

  }

 }

//getTime();
//existsFire();
/*if(!manualLeds){
readPhoto();
}*/

}

void readPhoto(){

  photoState = analogRead(photoResistor);
  if(photoState>600){
    ledAnalog=0;
  }
  else if(photoState<300){
    ledAnalog=255;
  }
  else{
    ledAnalog = 150 - photoState/4;
  }
  for(int x = 0;x<sizeof(leds)/sizeof(leds[0]);x++){
  analogWrite(leds[x], ledAnalog);
  }

}

void existsFire(){
flameState = analogRead(flamePin);
Serial.println(flameState);
if(flameState <= 50){
  static boolean playingBuzzer = true;
  if(counter - prevMillis > piezoInterval){

     prevMillis = counter;
     playingBuzzer=!playingBuzzer;

  }
  if(playingBuzzer){

    digitalWrite(piezo, HIGH);

  }
  else{
    digitalWrite(piezo, LOW);
  }

}
else if(!playPiezo){
  digitalWrite(piezo, LOW);
}
else if(playPiezo){
  digitalWrite(piezo, HIGH);
}

}

void checkTemp(){

  temperature = ((analogRead(temp) / 1024.0 * 5.0) - .5) * 100;
  Serial.println(temperature);

}
void ping(){

    digitalWrite(trig, LOW);
    delayMicroseconds(2);
    digitalWrite(trig, HIGH);
    delayMicroseconds(10);
    digitalWrite(trig, LOW);
    duration = pulseIn(echo, HIGH);

}
void getTime(){

  DateTime now = rtc.now();

  Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
}
void forward(){
digitalWrite(STBY1, HIGH);
digitalWrite(ain11, HIGH);
digitalWrite(ain12, LOW);
analogWrite(aPWM1, 255);

digitalWrite(bin11, LOW);
digitalWrite(bin12, HIGH);
analogWrite(bPWM1, 234);

digitalWrite(STBY2, HIGH);
digitalWrite(ain21, LOW);
digitalWrite(ain22, HIGH);
analogWrite(aPWM2, 255);

digitalWrite(bin21, LOW);
digitalWrite(bin22, HIGH);
analogWrite(bPWM2, 234);
}
void backward(){

digitalWrite(STBY1, HIGH);
digitalWrite(ain11, LOW);
digitalWrite(ain12, HIGH);
analogWrite(aPWM1, 255);

digitalWrite(bin11, HIGH);
digitalWrite(bin12, LOW);
analogWrite(bPWM1, 235);

digitalWrite(STBY2, HIGH);
digitalWrite(ain21, HIGH);
digitalWrite(ain22, LOW);
analogWrite(aPWM2, 255);

digitalWrite(bin21, HIGH);
digitalWrite(bin22, LOW);
analogWrite(bPWM2, 235);

}
void left(){

digitalWrite(STBY1, HIGH);
digitalWrite(ain11, HIGH);
digitalWrite(ain12, LOW);
analogWrite(aPWM1, 255);

digitalWrite(bin11, HIGH);
digitalWrite(bin12, LOW);
analogWrite(bPWM1, 255);

digitalWrite(STBY2, HIGH);
digitalWrite(ain21, LOW);
digitalWrite(ain22, HIGH);
analogWrite(aPWM2, 255);

digitalWrite(bin21, HIGH);
digitalWrite(bin22, LOW);
analogWrite(bPWM2, 255);

}
void right(){
digitalWrite(STBY1, HIGH);
digitalWrite(ain11, LOW);
digitalWrite(ain12, HIGH);
analogWrite(aPWM1, 255);

digitalWrite(bin11, LOW);
digitalWrite(bin12, HIGH);
analogWrite(bPWM1, 255);

digitalWrite(STBY2, HIGH);
digitalWrite(ain21, HIGH);
digitalWrite(ain22, LOW);
analogWrite(aPWM2, 255);

digitalWrite(bin21, LOW);
digitalWrite(bin22, HIGH);
analogWrite(bPWM2, 255);

}
void brake(){

digitalWrite(STBY1, LOW);
digitalWrite(ain11, LOW);
digitalWrite(ain12, LOW);
analogWrite(aPWM1, 0);

digitalWrite(bin11, LOW);
digitalWrite(bin12, LOW);
analogWrite(bPWM1, 0);

digitalWrite(STBY2, LOW);
digitalWrite(ain21, LOW);
digitalWrite(ain22, LOW);
analogWrite(aPWM2, 0);

digitalWrite(bin21, LOW);
digitalWrite(bin22, LOW);
analogWrite(bPWM2, 0);

}
void translateIR(){
//Serial.println(results.value, HEX);
switch(results.value){
case 0xFF02FD:
case 0x20DF22DD:
//stop(ok)
if(drivingMode==0){
brake();
//Serial.println("brake");

}
break;
case 0xFF629D:
case 0x20DF02FD:
//forward
if(drivingMode==0){
forward();
//Serial.println("forward");
}
break;
case 0x20DF827D:
case 0xFFA857:
//back
if(drivingMode==0){
backward();
//Serial.println("back");

}
break;
case 0xFF22DD:
case 0x20DFE01F:
//left
if(drivingMode==0){
left();
//Serial.println("left");
}
break;
case 0x20DF609F:
case 0xFFC23D:
//right
if(drivingMode==0){
right();
//Serial.println("right");

}
break;
case 0xFF6897:
case 0x20DF8877:
if(drivingMode==0){
  brake();
  drivingMode=1;
}
else{
  brake();
  servo.write(90);
  drivingMode=0;
}
//1(switch driving mode)
break;
case 0xFF9867:
case 0x20DF48B7:
//2(switch led mode)
if(!manualLeds){
manualLeds=true;
    for(int x = 0;x<sizeof(leds)/sizeof(leds[0]);x++){
  digitalWrite(leds[x], LOW);
  }
}
else{
manualLeds=false;
}

break;
case 0xFFB04F:
case 0x20DFC837:
if(manualLeds){
  if(!ledsOn){
    for(int x = 0;x<sizeof(leds)/sizeof(leds[0]);x++){
  digitalWrite(leds[x], HIGH);
  }

  ledsOn=true;
  }
  else{
       for(int x = 0;x<sizeof(leds)/sizeof(leds[0]);x++){
  digitalWrite(leds[x], LOW);
  }
  ledsOn=false;
  }
}
//3(toggle leds if mode is on)
break;
case 0xFF30CF:
case 0x20DF28D7:
//4(play sound)
playPiezo = !playPiezo;

}

}

EDIT 2:
I decided to see what will happen if I start removing code. I removed most of the code that I did not need for this experiment. After the removal, the issue persisted. The sensor is still giving me 0s. This is all the code that was left after I removed stuff:
#include <Servo.h>

//RTC_DS1307 rtc;

/*const int blue2 = 12;
const int blue1 = 11;
const int red1 = 10;
const int red2 = 9;
*/
Servo servo;

unsigned long counter;

unsigned long prevMillis = 0;

int piezoInterval = 200;

int drivingMode = 0;

boolean playPiezo=false;

#define trig 22
#define echo 24
long duration;
boolean turned150 = false;
int cm30, cm, cm150;
bool checkLeft = false;
boolean checkRight = false;
boolean mainPing = true;
unsigned long servoTimer = millis();

void setup(){

 servo.attach(12);
/* for(int i=0;i<sizeof(leds)/sizeof(leds[0]);i++){
    pinMode(leds[i], OUTPUT);
 }
*/
 Serial.begin(9600);

servo.write(90);
delay(200);
}

void loop(){

 counter=millis();
 //Serial.print("Millis1: ");
 //Serial.println(millis());
/* if(irrecv.decode(&results)){
    translateIR();
    irrecv.resume();
  }*/
//  Serial.print("Millis2: ");

if(drivingMode == 0){
   if(((counter-servoTimer) >= 150) && mainPing){
    ping();
    cm=duration/29.1/2;
    Serial.println(cm);
    counter=millis();
    servoTimer=counter;
  }
  if((cm<30) && mainPing){

    mainPing=false;
    checkRight = true;
    counter=millis();
    servoTimer=millis();
    servo.write(150);
    cm=30;

  }
  if(checkRight && !checkLeft && ((counter-servoTimer) >= 170)){

    ping();
    checkLeft=true;
    cm150 = duration/29.1/2;
    counter=millis();
    servoTimer=millis();
    servo.write(50);
  }
  if(checkRight && checkLeft && ((counter-servoTimer) >= 340)){
  checkRight=false;
  checkLeft=false;
  mainPing=true;
  ping();
  cm30 = duration/29.1/2;
  counter=millis();
  servoTimer=millis();
  servo.write(90);

  }

 }

//getTime();
//existsFire();
/*if(!manualLeds){
readPhoto();
}*/

delay(2);
}

//}
void ping(){

    digitalWrite(trig, LOW);
    delayMicroseconds(2);
    digitalWrite(trig, HIGH);
    delayMicroseconds(10);
    digitalWrite(trig, LOW);
    duration = pulseIn(echo, HIGH, 24000L);

}

Maybe this means that the issue is within this remaining code. Of course I will need all of the code that I removed for the final project, but I was just trying to debug.
I made my code a lot more concise since the posted code draft, but the ultrasonic sensor still gives me 0s. I do not understand what can affect its performance as it works fine in my other sketch.
I tried connecting the sensor to an external 5 volt power source and the same thing happened. The reason for the issue is not because if my power source.
I used to have a small delay at the end of my code and I removed that in order to make it run faster. Since pulseIn is blocking for 24ms, the delays do not affect it and it should work normally. But it does not.
Also, the sensor is giving 0s not because the target is too far away. Even if I put my hand close, it still gives 0s. If I make the cm equal 400 if the duration equals 0, the cm are always 400 regardless of the distance from the sensor.

There seems to be a lot going on in your full program, which can explain why it is slower. If you want to minimize the problem, avoid floating point and – most importantly – blocking calls. delay() is not the only blocking function: pulseIn() is also blocking, and Serial.print() becomes blocking is the output buffer fills up.

@EdgarBonet I cannot really avoid using pulseIn() - it is needed for the sensor. Even if I remove Serial.print(), it makes no difference to the servo and sensor.

I cannot really avoid using pulseIn() - Yes you can, easily. pulseIn is just a blocking way of measuring the time between two events. You could use interrupts and not block.

@NickGammon Ok. If this is the source of the issue, I guess I will change it. But I am not sure if it is. After I followed the suggestion below, the servos work, but the sensor still gives me 0s.

Well it sounds like you have more than one problem then. :)

What is the value of the duration variable after the pulse and before your calculations?

@RobertoLoGiacco If cm is 0, then duration must be 0 as well. Since x/2/29.1 = 0, then x = 0.

@NickSolonko did you actually check the duration is 0? Because you are operating on integers and 50 / 2 / 29.1 cast into an int is actually 0...

I think you'll need an Oscillograph or a Digital Analyzer to observe what happens on TRIG and ECHO pins. In particular, it might be interesting to check timing of TRIG pin is correct (10us HIGH) and observe if there is or not an ECHO signal. My belief is that servo interrupts may negatively impact your ping() method.

In the setup() function add a setPin(echo, INPUT) statement.
UPDATE
Have you checked the wiring? A loose connection of either the trig or echo pins would cause this behavior.
I know it might seem obvious, but double checking continuity between the Arduino pins and the HC-SR04 module with a basic multimeter (while your board is not powered) is not going to hurt, right?

Although it is often considered good practice to explicitly set the mode of every pin you use, here it doesn't make any difference, as all the pins are initialized to INPUT by the hardware.

You are right @EdgarBonet, default state for pins is INPUT, but he might have includes or other non displayed code which changes the pin state.
Also the pulseIn(...) function should actually change the pinMode implicitly via the call to portInputRegister(...) contained inside it, but that depends on the version of Arduino libraries he is using...

Thank you for pointing out to me something so obvious. I indeed forgot to set the pinMode to INPUT for echo AND set it as OUTPUT for trig. The trig pinMode caused the issue I am guessing. I spend so much time trying to find a flaw and it was just one line of code.

pulseIn() may block up to 1 second (by default), which would happen everytime the HC-SR04 receives no echo, which might be the case if ultrasounds do not get properly reflected on a flat surface or if the nearest echoing surface is over ~4 meters away from it.
In this situation, not only would pulseIn block for one second, but it would also return 0 to indicate the pin never changed level during that time (which can explain the 0cm distance you calculated).
Since the HC-SR04 range is maximum 4 meters, the max ultrasound distance echoed should be then less than 8 meters. Under normal atmospheric conditions, sound propagates at ~340m/s, that means in the worst case, i.e. an obstacle found 4 meters away, the sound roundtrip should take less than 8/340s, i.e. ~24ms rounded up.
This shows it is pointless to have pulseIn wait for 1 second, where 24ms would be enough. To tell pulseIn to use a shorter timeout, just pass it an extra argument:
duration = pulseIn(echo, HIGH, 24000L);

Note that timeout must be expressed in us.
Then, in other parts of your code, before using duration, you should check that it is not 0 (which means no obstacle found less than 4 meters away), for example you might consider in this case the distance is 4 meters (or anything larger).
E.g. you could replace:
cm150 = duration/29.1/2;

with:
cm150 = duration == 0 ? 400 : duration/29.1/2;

Since this calculation is found several times you should probably create a function for it, that would improve code maintainability and maybe code size as well.

So you are saying that the HC-SR04 is sending me a 0 because of an uneven surface? I just tested it without servo rotation and commented everything extra out and it still gave me 0. When I tried running the same code in a separate sketch, the sensor gives me actual values. So I am still not sure why it is giving me 0s. The surface and distance are not the ones causing the issue. I also changed pulsein to 24000L. I saw no change with servo rotation.

Never mind, the servos rotate normally now after I added 24000L. The sensor still does not work.

You may have a voltage drop issue (this happened to me in the past, due to the number of devices you are driving. Did you use decoupling caps for each device?

It is possible. When I removed all the code for those devices, it still gave me 0. Those devices were still connected up though. They were also connected up when I uploaded the first sketch and everything worked.  I am using capacitors.

It is hard to tell, without seeing your wiring. If you have an oscillograph, then you can check voltage of HC-SR04 power pins and see if it's stable. If you don't, just add a 10uF cap as near the HC-SR04 as possible.

What cap values do you use? Are caps near each device? Could you consider (for testing only) providing voltage to the HC-SR04 through a separate power supply (you'll need to join GND pins of course)?

Sorry for not responding. I connected the sensor to another 5 volt power source and the same thing occurred.

Why does the same block of code act differently in different sketches?

There are different interrupt sources in the sketches that may affect pulseIn(). Try using a more advanced method to measure the pulse width such as Timer Capture.
Cheers!


text:
How come my code does not wait for a specific time before going into an if statement?
I have an HC-SR04 attached to a servo. When the 90 degree reading is less than 30 cm, I want the motor to take 2 seconds to turn to 130 degrees, get a measurement on the right, and turn back to 90 degrees. My code does not seem to work. Even though I tell it to wait for 2000 ms, it skips directly to the if statement where the turning to 90 degrees is done. Here is the main code:
 #include <Servo.h>
#define trig 22
#define echo 24
long duration;
boolean turned130 = false;
int cm50, cm, cm130;
Servo servo;
boolean checkRight = false;
boolean mainPing = true;
unsigned long counter;
unsigned long servoTimer = millis();
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
pinMode(echo, INPUT);
pinMode(trig, OUTPUT);
servo.attach(12);
servo.write(90);
delay(2000);

}

void loop(){
counter=millis();//my timer
  if(((counter-servoTimer) >= 250) && mainPing){//distance measured 4 times a second
    ping();
    cm=duration/29.1/2;
    Serial.println(cm);
    servoTimer=counter;//this if statement works fine
  }
  if((cm<30) && mainPing){

    mainPing=false;//makes the 90 degree ping and this if statement unable to run
    checkRight = true;//enables next if statement to run
    servoTimer=millis();
    servo.write(130);
    cm=30;//so that this if statement does not get called again until distance is obtained
    Serial.println("Inside less than 30 loop");//I added this for debugging, to let me know when the loop is called

  }
  if(checkRight && ((counter-servoTimer) >= 2000)){//after 2 seconds passes

    checkRight=false;
    ping();
    cm130 = duration/29.1/2;
    mainPing = true;//enable to other 2 if statements to run
    servoTimer=millis();
    Serial.println(cm130);
    servo.write(90);//turn motor back
    Serial.println("Inside other loop");//for debugging

  }

  delay(2);
  }

void ping(){

    digitalWrite(trig, LOW);
    delayMicroseconds(2);
    digitalWrite(trig, HIGH);
    delayMicroseconds(10);
    digitalWrite(trig, LOW);
    duration = pulseIn(echo, HIGH);

}

This is what I got in the Serial monitor:
25//distance triggers 2nd if statement
Inside less than 30 loop
261
Inside other loop
13
Inside less than 30 loop
14
Inside other loop
14
Inside less than 30 loop
14
Inside other loop
3242
13
Inside less than 30 loop
14
Inside other loop

This all happened within milliseconds. There was no 2 second pause and the servo never turned. What is wrong with my code that prevents the motor from turning and waiting 2 seconds? The order of the Serial messages is correct, but it is happening fast.
EDIT:
When I remove the Serial messages and disconnect from the computer, it kind of works. By that, I mean it turns and waits for 2 seconds 50% of the time. Other times, the servo just shakes a little bit and stops.
Another thing I noticed is that if I leave only Serial.println(cm) message and Serial.println("Inside less than 30 loop"), this is the result that I observe.
    12
    13
    Inside less than 30 loop

    15
    3
    Inside less than 30 loop

For some reason the loop does not get triggered the first time. Is there a possibility that I have a defective Arduino Mega?
EDIT 2:
I tested the same setup on an official Arduino Uno and it did not work either. This means that I do not have a broken Arduino. Could the servo motor be broken? That won't explain the Serial messages though.

Try adding some parentheses; if( checkRight && ((counter-servoTimer)>=2000) )

@Gerben I added parentheses. When I removed the Serial messages, it kind of worked like 50% of the time. When I add them back in, the same thing happens. There is no interval between the messages and the servo just shakes, but does not rotate.

Could you post the entire sketch? Make sure servoTimer isn't a local variable.

@Gerben I posted the entire sketch.

That isn't the whole sketch. The lines counter=millis();//my timer onwards are outside any function. Try compiling what you posted.

@NickGammon When I was copying/pasting, I forgot the void loop(). I added it in. I still have it in my code like it should be.

Could it be that the arduino is reseting, because the servo uses too much power? Try adding  something like Serial.println("start"); to the setup function, so you can detect resets.

@Gerben I will try that. Do you think a 4AA battery pack of rechargeable batteries will work for a 5v servo? Because on full charge, they can be nearly 6 volts.

@Gerben I tried and the Arduino does not reset.

I added some more debugging, and I think I have your issues detected.
Amended code:
#include <Servo.h>
#define trig 22
#define echo 24
long duration;
boolean turned130 = false;
int cm50, cm, cm130;
Servo servo;
boolean checkRight = false;
boolean mainPing = true;
unsigned long counter;
unsigned long servoTimer = millis();
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(echo, INPUT);
  pinMode(trig, OUTPUT);
  servo.attach(12);
  servo.write(90);
  delay(2000);
}

void loop() {
  counter = millis(); //my timer
  if (((counter - servoTimer) >= 250) && mainPing) { //distance measured 4 times a second
    Serial.print ("Doing ping at time ");
    Serial.println (counter);
    ping();
    cm = duration / 29.1 / 2;
    Serial.println(cm);
    servoTimer = counter; //this if statement works fine
  }
  if ((cm < 30) && mainPing) {

    mainPing = false; //makes the 90 degree ping and this if statement unable to run
    checkRight = true;//enables next if statement to run
    servoTimer = millis();
    servo.write(130);
    cm = 30; //so that this if statement does not get called again until distance is obtained
    Serial.println("Inside less than 30 loop");//I added this for debugging, to let me know when the loop is called
  }
  if (checkRight && ((counter - servoTimer) >= 2000)) { //after 2 seconds passes
    Serial.print ("counter = ");
    Serial.println (counter);
    Serial.print ("servoTimer = ");
    Serial.println (servoTimer);
    checkRight = false;
    ping();
    cm130 = duration / 29.1 / 2;
    mainPing = true;//enable to other 2 if statements to run
    servoTimer = millis();
    Serial.print ("cm130 = ");
    Serial.println(cm130);
    servo.write(90);//turn motor back
    Serial.println("Inside other loop");//for debugging
  }
  delay(2);
}

void ping() {
  digitalWrite(trig, LOW);
  delayMicroseconds(2);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
}

With no server (or anything) attached I get this output:
Doing ping at time 1999
0
Inside less than 30 loop
counter = 1999
servoTimer = 2693
cm130 = 0
Inside other loop

First note that servoTimer is somewhat higher than counter because the pulseIn function takes a while to execute (times out after 1 second allegedly, although that was less than a second).
Now we come to the problem "if" statement.
  if (checkRight && ((counter - servoTimer) >= 2000)) { //after 2 seconds passes

That can't be right, eh? counter is 1999 and servoTimer is 2693, and there is not 2000 difference. However you are doing the maths the other way:
counter - servoTimer =  1999 - 2693 = -694

Since we are using unsigned long, it cannot hold negative numbers so the result of the subtraction is 4294966602.

That is much larger than 2000, so the "if" branch is taken.

Your answer makes a lot of sense. What I did to address the issue is put counter=millis(); after each ping before I set the servoTimer. This seemed to fix the issue. Works really well now! Now I have to make it turn left as well and record distances. It should not be a problem with this issue taken care of. Quick question, what is "" for? Is it necessary? Thank you for your help!

The language tag is just a hint to Stack Exchange to syntax-colour the code. Look at the posts. Mine is coloured, yours isn't. :) However I notice now that I put it in the wrong place. I must have hit "paste" at the wrong time. I've edited it out of the code.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

sort: votes


text:
Debugging arduino shield for varying voltage
I'm using this motor shield for arduino from adafruit. It says it can drive 4 DC motors with it. However, two terminals M3 & M4 (as marked in the image) seem to be supplying lesser voltage.

To avoid this becoming an XY problem, some more details:
The entire setup consists of an arduino, shield, raspberry Pi 3 & the motors being  powered with a 2200 mAh 12v supply. The raspberry pi is powered from the 5v supply of this shield.
Now the problem as mentioned is that even though M1 & M2 get the 12v, M3 & M4 don't. When I measured they give varying degree of voltage (3v - 6v). I tried disconnecting & connecting various combinations, with & without motors connected, pi removed, etc. All are giving same result. When I supplied 5v as external power, these pins in question dropped to 2v-3v.
As per this documentation, there seems to be a difference in M3, M4 in that they run at 1KHZ, to save power. But my knowledge to make of this info seems to be limited. Can anyone point me to the right direction here?
The complete setup.

L293D & L298 type bipolar drivers have absurdly high internal losses and should basically be considered to be obsolete by at least a decade and unsuited to low voltage applications.  You will have much better results with an FET bridge.  If you want to try to use the bipolar bridge in the meantime supply it with 2v or so more than you want the connected motors to see.  Of course the bridge and your supply must be rated for the expected current!

Also, a voltmeter measurement of a PWM type output is only going to be truly meaningful when the PWM is set to 0 or 100%.  An analog meter might average something in between to a degree, but a digital one (and even more so if it is a budget model as pictured) could have sampling effects leading to misleading readings.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Standard deviation and variance of an array of numbers
Looking for a simple way to get the variance of an array of numbers,
that will compile with the Arduino compiler.
Something like this c#:
static float variance(double []a, int n)
{
    // Compute mean (average of elements)
    double sum = 0;

    for (int i = 0; i < n; i++) sum += a[i];
    double mean = (double)sum / (double)n;
    // Compute sum squared differences with mean.
    double sqDiff = 0;
    for (int i = 0; i < n; i++)
        sqDiff += (a[i] - mean) * (a[i] - mean);
    return (float)sqDiff / n;
}

// Driver Code
public static void Main ()
{
    double []arr = {10, 11, 12, 13};
    int n = arr.Length;
    Console.WriteLine( "Variance: " + variance(arr, n));
}

To keep it simple, and thanks for all your help....
it is a platform with actuators in each corner to raise and lower
the platform....
Each actuator sends a feed back via modbus to the main micro processor at its request
Which is stored to a array, which is processed and then sent via modbus
Back to control (simple on/off) each actuator to keep platform in somewhat of a level position +/- a set number....
I already use the min/max  (max – min =  ) in the my code to limit a set, simple differential between the
Actuators....  I am thinking that using the variance differential would work better for the application....
Thinking it would also detect a jammed or faulty actuator faster than the max/min difference with
Less platform twisting....
(Response to Edgar), You could look at it as XYZ,…  X= position.. Y= actuator.. Z=sample rate
This is my code snip it for the max/min
example 1  —  adj_str =  actuators position = (10,11,10,9) run level flag 1
example 2  —  adj_str =  actuators position = (10,14,10,9) run level flag 0
void min_max()
{
    int max = adj_str[0];
    int min = adj_str[0];
    for (int i = 0; i <= 3; i++)
    {
        const int value = adj_str[i];
        if (value > max) max = value ;
        if (value < min) min = value ;
    }
    //-
    adj_str_dif = max - min;
    //-
    if (adj_str_dif < 1) level_flag = 1;
    //-
    if ((level_flag == 1)&&(adj_str_dif > 4))  // 4 = the differential
    { level_flag = 0;}
    //-
    if (level_flag == 0)           // Level Till Max or Min (re-level)
    {
        // -- Lower --
        if (adj_str_dif > 0 && (digitalRead(but_pin[1]) == LOW))
            base = (max);
        // -- Raise --
        if (adj_str_dif > 0 && (digitalRead(but_pin[2]) == LOW))
            base = (min);
    }
    //-
    if (level_flag == 1)       // Run Till full retract or full extend
    {
        // -- Lower --
        if (adj_str_dif < 1 && (digitalRead(but_pin[1]) == LOW))
            base = 1023;
        // -- Raise --
        if (adj_str_dif < 1 && (digitalRead(but_pin[2]) == LOW))
            base = 0;
    }
}

general programming question ... not an arduino related question ... off topic here ... please post at https://stackoverflow.com/questions instead

Your example code takes an array of doubles; do you really want to take your input from a string? From a single string containing all of the data? Perhaps comma separated? Perhaps with white-space permitted but ignored (only between values, not within any), .... So your question, not only not Arduino-specific, is also not sufficiently specified to be able to answer it. Assuming I guessed right, you'd need to read the string, collect each value, convert it to double, and stash it in an array to be passed as 'a' to your function 'variance()'.

the example code is from https://www.geeksforgeeks.org/program-for-variance-and-standard-deviation-of-an-array/

JRoberts..... the example code is from                                 [link] https://www.geeksforgeeks.org/program-for-variance-and-standard-deviation-of-an-array/)  ..... i was hoping to change this a bit to run some tests on the Arduino IDE.... i  already have a string setup that contains multiple ADC readings, and if i am correct in my assumption i can use the variance result to flag an execution.. i do like the bell curve it creates and thinking it may work for my project

This looks very much like an XY Problem. You seem to be asking the wrong question, for several reasons: 1. If your data comes from the Arduino's ADC, converting the numbers to a string, only to convert them back to numbers, is both useless and incredibly wasteful. 2. This algorithm for the variance requires you to read the array twice. Not the method you want to use on a microcontroller. You want to do it in a single pass, as you read the ADC, so you do not have to ever store the measurements. Please, tell us what you actually want to achieve.

Eric, where you write string you meant array?

@Juraj: As evidenced by his example code (mostly the type adj_str), he indeed means “array of numbers”. I edited the question to avoid confusion.

Please note that calculating an average by adding all the numbers and dividing by count is not a good method when using floating point arithmetic. To then use that average in variance calculations risks bigger errors. The online algorithm performs much better as well as being memory friendly. The numerical stability and correctness of the algorithm starts mattering a lot of you using calculations to control external devices.

I miss a description of your problem regarding "doesn't compile with the Arduino compiler" (Besides c# to arduino c++ changes)

The ( int adj_str [4]; )  is updated every polling of the slave's, to clarify... i have been treating this as the entire dataset for that point in time of travel.... i will cheek out further the Welford's online algorithm, may work better than the standard deviation variance that was posted and like the single pass ! ..... i may seem a bit Dyslexia but i like the term ambidextrous....have not had a chance yet to test Juraj updated version

C++ and C# (or Java) basic language constructs are very similar. Here is the Arduino version of your C# code with minimal required modifications. There is no change in the function implementation.

float variance(double a[], int n)
{
    // Compute mean (average of elements)
    double sum = 0;

    for (int i = 0; i < n; i++) sum += a[i];
    double mean = (double)sum / (double)n;
    // Compute sum squared differences with mean.
    double sqDiff = 0;
    for (int i = 0; i < n; i++)
        sqDiff += (a[i] - mean) * (a[i] - mean);
    return (float)sqDiff / n;
}

void setup() {
    Serial.begin(115200);
    double arr[] = {10, 11, 12, 13};
    int n = sizeof(arr) / sizeof(double);
    Serial.print( "Variance: ");
    Serial.println(variance(arr, n));
}

void loop() {

}

Thanks ... will try running this later tonite

Works as posted

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
ESP8266-01 module "AT" command testing not responding
Firstly I have connected the Arduino UNo to Esp8266-01 Module and uploaded the Simple Blink Sketch using Arduino Uno and It responded correctly as in the Blue Led Light on Esp8266-01 was blinking correctly. Now for AT Commands I uploaded Blank Sketch to Arduino Uno and then on serial monitor with baud rate as 115200 typed in AT but no output is seen on Serial Monitor , Please Help Why Esp8266-01 Module not responding to AT Commands

the sketch replaced the AT firmware

When using it as a WiFi modem, you communicate with it using AT-command, and by default that is what most of ESP8266 module does, it shipped with At-command firmware. When you using an ESP8266 as an MCU, you flash the ESP8266 with Arduino sketch, which overrides the AT-Command firmware and upload it with Arduino bootloader, and allow the ESP8266 to be used as a stand-alone MCU like an Arduino.

The "AT" commands are provided by a specific sketch (firmware). The chip can only hold one sketch at a time - that sketch currently is your "blink" sketch.
If you want to have AT commands then you have to put the correct AT command firmware on the chip, removing your Blink sketch in the process.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Problem uploading my sketch onto my arduino. Arduino 1.8.13, Linux Ubuntu 20.4
This is my log, honestly no idea what the problem is here, tried updating java, didnt work.

Sketch uses 11216 bytes (4%) of program storage space. Maximum is 262144 bytes.
Global variables use 2384 bytes (7%) of dynamic memory, leaving 30384 bytes for local variables. Maximum is 32768 bytes.
processing.app.debug.RunnerException
    at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:152)
    at cc.arduino.UploaderUtils.upload(UploaderUtils.java:77)
    at processing.app.SketchController.upload(SketchController.java:732)
    at processing.app.SketchController.exportApplet(SketchController.java:703)
    at processing.app.Editor$UploadHandler.run(Editor.java:2055)
    at java.lang.Thread.run(Thread.java:748)
Caused by: processing.app.SerialException: Error touching serial port '/dev/ttyACM0'.
    at processing.app.Serial.touchForCDCReset(Serial.java:107)
    at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:136)
    ... 5 more
Caused by: jssc.SerialPortException: Port name - /dev/ttyACM0; Method name - openPort(); Exception type - Permission denied.
    at jssc.SerialPort.openPort(SerialPort.java:170)
    at processing.app.Serial.touchForCDCReset(Serial.java:101)
    ... 6 more

look at the second caused by line

https://www.arduino.cc/en/Guide/Linux#please-read

Is your user in the dailout group? That is required for you to use the serial devices. And after you added the group to your user, you need to relogon to get thar change active

How do i find out if i am in the dailout group

I added my user using  [ $ sudo adduser "user" dialout  ] and it worked thank you


text:
error: expected primary-expression before ',' token edit status 1
Im using tinkercad for my robotics class and I can't seem to figure out a solution for this problem.
Heres my codes:
#include <LiquidCrystal.h> //LCD library
#define echo 2
#define trig 3

// Gas Sensor
#define GREEN 4
#define Yellow 6
#define RED 7
#define Buzzer 5
#define Sensor A0

float duration;
float distance;

LiquidCrystal lcd(13,,12,11,10,9,8);

int sensor_Input;
float temp;

void setup()
{
  // Ultrasonic sensor
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  Serial.begin(9600);
  lcd.begin(13, 2);

  //temp
  measure_Temp();
  display_Temp();

  // Gas Sensor
  for (int i = 0; i < 6; i++)
    pinMode(i, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  // Ultrasonic Sensor
  time_Measurement();
  distance = duration * (0.0343) /2;

  display_distance();

  // Gas Sensor
  for (int i = 0; i < 6; i++)
    digitalWrite(i, LOW);

  status_Indicator();
}

void status_Indicator()
{
  // Gas Sensor
  int sensor_In = analogRead(A0);
  Serial.println(sensor_In);

  if ( sensor_In>=40 )
  {
    digitalWrite(RED, HIGH);
    digitalWrite(Buzzer, HIGH);
  }
  else if (sensor_In >=25 )
  {
    digitalWrite(Yellow, HIGH);
  }
  else
  {
    digitalWrite(GREEN, HIGH);
  }
  delay(10);
}

void time_Measurement()
{
  // Ultrasonic Sensor
  digitalWrite(trig, LOW);
  delayMicroseconds(2);

  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);

  duration = pulseIn(echo, HIGH);
}

void display_distance()
{
  lcd.clear();
    lcd.setCursor(0, 0);
  Serial.print("Distance in m: ");
  Serial.print(distance);
  Serial.println();
  lcd.print("distance in m: ");
  lcd.setCursor(5, 1);
  lcd.print(distance);
  delay(1000);
}

void measure_Temp()
{
  //Temp
  sensor_Input = analogRead(A0);
  temp = (float)sensor_Input / 1024;
  temp = temp *5;
  temp = temp - 0.5;
  temp = temp *100;
}

void display_Temp()
{
  //temp
  lcd.setCursor(0, 0);
  Serial.print("Temp. in Celcius: ");
  Serial.print(temp);
  Serial.println();
  lcd.print("Temp. in Celcius: ");
  lcd.setCursor(5, 1);
  lcd.print(temp);
  delay(500);
}

@ user77041 Please provide the full error output.

You have two commas in the command when making the lcd object:
LiquidCrystal lcd(13,,12,11,10,9,8);

Probably just a typo, delete the comma and you should be good to go.
LiquidCrystal lcd(13,12,11,10,9,8);


text:
PWM with a TRANSISTOR on flexible LED filament
I would like to create a custom lighting, with PWM capability, powered from battery. I would like to use flexible led filaments, and since those consumes more than 40mA, I can't use them directly on a board. I found a link explaining to use a MOSFET transistor, to dim my leds. So the transistor that I need would be one with a 5v power supply, and a 5v Voltage input.
The problem is that I can't find any transistor matching those specs. I also noticed that they have a heatsink, which mean that they need to dissipate heat, and are therefore not power efficient (which i do not like). Am I missing something ?
Any help will be apreciated, thanks !

look for DC motor drive circuits or relay drive circuits ... there are many examples

You cannot find a MOSFET with that exact rating, because transistors can be used with all voltages inside of their specific limits. Most MOSFETs can be used with way higher voltages than 5V.
What you need is a logic level MOSFET, which means, that it will be in saturation (aka being fully ON) at the typical logic level of 5V on its gate. In the datasheet of a MOSFET you will find a diagram which shows the drain current depending on the gate-source voltage. At your logic level (5V in this case) you want the curve approaching a plateau.
Another important value is R_DS(on). That is the resistance of the MOSFET when its on. The lower the resistance, the lower will the power lost to heat.

I also noticed that they have a heatsink, which mean that they need to dissipate heat, and are therefore not power efficient (which i do not like).

Every MOSFET dissipates some energy as heat, since no MOSFET can have R_DS(on) of zero. The typical heat sink flap is meant to dissipate the heat for keeping the MOSFETs temperature in the specified range, even when drawing the maximum specified current. The datasheet of a MOSFET has a section with maximum ratings. There you should see the maximum drain current I_D with its corresponding needed temperatures. For example have a look at this datasheet of a random logic level MOSFET from mouser. There is no specification of how hot the case gets with a specific current, since this depends on the suroundings, but the datasheet states, that it will support up to 80A, when you keep the case to a temperature of 25°C.
It also states what electrical power it can dissipate with its package: P_D. You should look at how much current you need for your LED filament. You can calculate the dissipating power with P = R * I² (P being power, R the resistance R_DS(on) and I the current through the MOSFET).

Thanks for the clarification ! So if I need to check for power dissipation, there will be in the datasheet a graph with temperatures at specific currents drains (I_D) ? In the link you gave, I found a graph named "FIGURE 10. Maximum drain current vs. Case temperature". Is it the right graph ? Because It seem inverted, is that normal ? And how can I get those MOSFETs ? I tried search engines but i can't find much of them on internet

Thats the point, that I wanted to make clear. There is no diagram for how hot the MOSFET gets with a given current, because that also depends on how fast the suroundings can move the heat away. Its affected by things like airflow, air temperature, air humidity, ... . So instead they give you information on the current, that the MOSFET will sustain at a given temperature. To find out how hot it will get in your application, you need to test it. The actual power loss is only determined by current and R_DS(on)

And you can find such MOSFETs at any good supplier for electronic components in your region. Mouser would be one, that at least is available in europe. I don't know, where you are and what the relevant suppliers are in that region.

Ok thanks, it is a lot more clearer now. I'm a student, I live near paris, but it is a bit complicated to find such electronics stores. They're usually not opened the weekend or so. I'll try Mouser !

Welcome! You are missing some information. A transistor will work but you will lose about 0.7 Volts when it is on. That voltage times the current will tell you how many watts it needs to dissipate. The data sheet will give you all this information.  The transistor is a current controlled device so there will not be a Base voltage rating. You can determine the current for the base by dividing the load current by the HFE then adding a bit.
By connecting more than 20 mA to the port pins especially more than 1 may destroy the Arduino. Surprise the LED is also a current device so you need to limit the current into it. This can easily be done with a resistor.
The MOSFET would be the easiest solution. Put a resistor maybe 10K from the port pin to ground. The reason is the port pins are floating from power on until your software defines and sets there level. Then connect the port of the Arduino to the gate of the MOSFET which has its source grounded. Connect the LED(s) to the drain and place a resistor in series with the LED and + voltage. It can be 12 Volts or whatever you like. You will need to size the current limiting resistor to the LED(S) appropriately and be sure the voltage rating of the MOSFET is at least 10% higher then the voltage.
There is a great book available called the Arduino Cookbook, getting that and reading it will be a big help to you.

Though MOSFETs are voltage controlled, while Bipolar transistors are current controlled.

Hi, thank you for your answer ! I was indeed a bit confused about transistors. As i'm searching a MOSFET with specific specs, I went on that website ROHM tool, and filled the specs, and it says "voltage power supply". Is that the right way to search for a MOSFET ?


text:
Prevent Resetting of Null Weight when using HX711 with a load cell
Helllo,
I am using the HX711 module and load cell with an arduino uno for force measurements.
I am using this library.
I first use the example "Calibration" code for calibration with a 200 g weight.
Then I save the calibration constant to the eeprom (choosing yes on the serial monitor).
Then the load cell is able to measure weights accurately.
After that I remove the weight from the load cell and run this code after uncommenting the last line of this part of the above code:
LoadCell.begin();
  //LoadCell.setReverseOutput();
  float calibrationValue;
  calibrationValue = 696.0;
#if defined(ESP8266)|| defined(ESP32)
  //EEPROM.begin(512);
#endif
  EEPROM.get(calVal_eepromAdress, calibrationValue); // I have uncommented this

The weights are measured accurately.
But when before powering the arduino, if I keep a weight on the load cell that weight is taken to be 0.
For this I have done the following change to the code:
boolean _tare = false;

But I get the following output on the serial monitor (Note: The following output is obtained on startup when there is/there is no weight on the load cell):

Questions:
What is the use of the following line:
calibrationValue = 696.0; // uncomment this if you want to set the calibration value in the sketch

Is it useless for the code I am using above? Because I am using the calibration value from the eeprom.
Q2) Why is it showing -39000 as an output value?
And how to correct it?
Alternate Statement:
In other words, I want to use the HX711 module with the arduino and a load cell. I will first calibrate it with a known weight and save the calibration value.
Before powering up the arduino I will keep a weight on the load cell. After powering up the weight value should be the absolute value instead of making the Weight Null.
EDIT1:
I incorporate the changes suggested in the answers by @Edgar Bonet and also make the problem more clear just in case.
According to suggestions I have made the corresponding changes to the calibration code. Then I run that and the values are saved to eeprom. Code changes:
const int calVal_eepromAdress = 0;
const int tare_eepromAdress = sizeof(float);

and
#endif
        EEPROM.put(calVal_eepromAdress, newCalibrationValue);
        EEPROM.put(tare_eepromAdress, LoadCell.getTareOffset());
#if defined(ESP8266)|| defined(ESP32)
        EEPROM.commit();

Now, I wish to run the second script and for this to display the correct weights.
This should work in all cases regardless of whether a weight has not been kept on the load cell or has been kept and should be independent of the weight that has been kept.
To this script I have made the following changes:
const int calVal_eepromAdress = 0;
const int tare_eepromAdress = sizeof(float);

and
// Inside void setup()
void setup() {
  Serial.begin(57600); delay(10);
  Serial.println();
  Serial.println("Starting...");

  LoadCell.begin();
  //LoadCell.setReverseOutput(); //uncomment to turn a negative output value to positive
  float calibrationValue; // calibration value (see example file "Calibration.ino")
  float tareValue;
  calibrationValue = 696.0; // uncomment this if you want to set the calibration value in the sketch
  tareValue = 0;
#if defined(ESP8266)|| defined(ESP32)
  //EEPROM.begin(512); // uncomment this if you use ESP8266/ESP32 and want to fetch the calibration value from eeprom
#endif
  EEPROM.get(calVal_eepromAdress, calibrationValue); // uncomment this if you want to fetch the calibration value from eeprom
  EEPROM.get(tare_eepromAdress, tareValue);

  unsigned long stabilizingtime = 2000; // preciscion right after power-up can be improved by adding a few seconds of stabilizing time
  boolean _tare = true; //set this to false if you don't want tare to be performed in the next step
  LoadCell.start(stabilizingtime, _tare);
  if (LoadCell.getTareTimeoutFlag()) {
    Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
    while (1);
  }
  else {
    LoadCell.setCalFactor(calibrationValue); // set calibration value (float)
    LoadCell.setTareOffset(tareValue);
    Serial.println("Startup is complete");
  }
}

EDIT2:
#if defined(ESP8266)|| defined(ESP32)
        EEPROM.begin(512);
#endif
        EEPROM.put(calVal_eepromAdress, newCalibrationValue);
        EEPROM.put(tare_eepromAdress, LoadCell.getTareOffset());

        Serial.println(newCalibrationValue);
        Serial.println(LoadCell.getTareOffset());

Output:
-206.90
8368790

In the second script:
#if defined(ESP8266)|| defined(ESP32)
  //EEPROM.begin(512); // uncomment this if you use ESP8266/ESP32 and want to fetch the calibration value from eeprom
#endif
  EEPROM.get(calVal_eepromAdress, calibrationValue); // uncomment this if you want to fetch the calibration value from eeprom
  EEPROM.get(tare_eepromAdress, tareValue);
  Serial.println(calibrationValue);
  Serial.println(tareValue);

Output:
-206.90
0.00

I am uploading my codes onto Github just in case. They can be found here.
Q) What is happening here?
EDIT3:
The following changes make it work like a charm:
In the "Calibration" script:
long tareValue = LoadCell.getTareOffset(); // Instead of float tareValue

Similarly in the second script:
long tareValue; // Instead of float tareValue

Have you checked which value the calibrationValue has before you write to EEPROM and after you read it from EEPROM? Just to check if the storage of the value works correctly. And you need to begin the EEPROM for it to work correctly

@chrisl yes, it is being read correctly.

see the library example file Persistent_zero_offset.ino.

In order to convert the raw ADC readings to a weight, the library needs
two coefficients:

a “tare offset”, which is the raw reading when there is no weight on
the scale
a gain, or “calibration factor”, which is the ratio of a change in the
ADC reading to the corresponding change in weight.

The examples provided with the library use the EPPROM to store and
retrieve the calibration factor, but not the tare offset. This makes
sense as, in common usage, a weight scale is always zeroed at power up,
or right after power up. This is usually desirable as one would often
place an empty container on the scale which should not affect the
displayed weight.
If you do not want to zero the scale at power-up, then you need your
sketch to remember the tare offset in addition to the calibration
factor. For this, you can use the methods of LoadCell:
// Get the tare offset (raw data value output without
// the scale "calFactor").
long getTareOffset();

// Set new tare offset (raw data value input without
// the scale "calFactor").
void setTareOffset(long newoffset);

Now, to the more specific questions:

What is the use of the following line:
calibrationValue = 696.0;

None. It is just an example. You are supposed to either replace this
number with your measured calibration factor, or remove this line and
read calibrationValue from the EEPROM.

Why is it showing -39000 as an output value?

Because the tare offset has not been set, so it presumably defaults to
zero.

Edit: Answering extra questions in comment.

Do I need to store this value to the eeprom when running the
calibration script?

You can store it whenever it is convenient to you. The calibration
script seems a good place.

I am not able to get this into code. I read the source files but I am
unsure about what changes to make.

What you may try (untested):

right after the line
const int calVal_eepromAdress = 0;

add this:
const int tare_eepromAdress = sizeof(float);

Right after this:
EEPROM.put(calVal_eepromAdress, newCalibrationValue);

add this:
EEPROM.put(tare_eepromAdress, LoadCell.getTareOffset());

Thanks that makes sense. Do I need to store this value to the eeprom when running the calibration script? I am not able to get this into code. I read the source files but I am unsure about what changes to make to the calibration and the second script. Any help is greatly appreciated.

I have made the changes you suggested and have added changes to the second script as well. I clarify the changes in the original question. Please have a look

Regarding your changes, you should probably set _tare to false in order to avoid setting the tare offset twice. You cal also get rid of the if (LoadCell.getTareTimeoutFlag()) part and unconditionally set both the calibration factor and the tare offset.

It's still not working. I get -40000 on the Serial Monitor. I show the changes and the results here.

Ok it seems the right value is not being stored for the tare value. I show this in EDIT2 in my post.

@Atharva: Re “EDIT2”: The method getTareOffset() returns a long, and that is what you are storing in the EEPROM. In LoadCell_Read.ino, you EEPROM.get() that value into a float. This is basically reinterpreting the bit pattern of the long as if it was a float. The resulting value is about 1.17e-38, which gets printed as “0.00”.


text:
How to correctly synchronize time with NTP server?
I want to synchronize time with NTP server once in some time. I am using DOIT ESP32 DEVKIT V1, I tried with getLocalTime() function but it returned true even without wifi, but as I know without wifi it can not conect to NTP server. Can anyone say if it is possible how to correctly synchronize time with NTP server? Maybe with some other libraries or with other functions.
    #include <WiFi.h>
    #include "time.h"

    const int  gmtOffset_sec = 7200;
    const int  daylightOffset_sec = 3600;
    const char* ntpServer = "pool.ntp.org";

    void setup() {
        Serial.begin(115200);
        Serial.println("Board started\n");
        WiFi.begin("<ssid>", "<password>");
        struct tm timeinfo;

        Serial.print("Connecting...");
        while (WiFi.status() != WL_CONNECTED) {
            delay(500);
            Serial.print(".");
        }
        Serial.println("");
        Serial.println("WiFi connected.");
        configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
        if (!getLocalTime(&timeinfo)) {
            Serial.println("Failed to obtain time 1");
        } else {
            Serial.println("Time obtained 1");
        }
        WiFi.disconnect(true);
        WiFi.mode(WIFI_OFF);
        if (!getLocalTime(&timeinfo)) {
            Serial.println("Failed to obtain time 2");
        } else {
            Serial.println("Time obtained 2");
        }
    }

    void loop() {
    }

The output to console is:
Board started
Connecting....
WiFi connected.
Time obtained 1
Time obtained 2

But I would expect 2nd output to be Failed to obtain time 2.

Also, why the code I posted does not have syntax highlighted?

You can get syntax highlighting with a line \``c++before the code, and```` after it.

upvote for asking how to present readable code

what is the question? it can take some seconds until time is retrieved after connected to WiFi and Internet.  getLocalTime returns time from internal RTC which is set with time retrieved from NTC server

This link may help: https://linuxconfig.org/stay-time-synchronized-with-internet-time-server

@Juraj I want to update rtc time with NTP server time periodically. How to do it the first time - is known, just call getLocalTime() after setting parameters with configTime(). But how to do it the 2nd, 3rd, ... time? getLocalTime() will return the local time and will not sync it with NTP server, am I right?

getLocalTime has nothing to do with NTP. It gets time from RTC. the SDK retrieves time from the Internet and sets it to RTC periodically. study this example https://github.com/esp8266/Arduino/blob/master/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino


text:
DHT11 stops working when power comes from a power supply board
I had a mini project with a DHT11, a temperature and humidity sensor, working perfectly on my Arduino UNO clone. Then, I bought a power supply board, that can feed the sensor with the 5V it requires, but for some reason, it does not work. Powering the sensor with the Arduino makes it get the correct values, powering it with the board makes it to stop working at all.
I have used a multimeter for checking the volts and amps. The readings on the sensor are the same with the Arduino and the board, 5V, but the amps are not. It seems that the sensor only uses power for an instant, while "sensing". Using Arduino, a 1.62mA current flows to the sensor and then drops to 0, but using the board it never gets higher than 0.001mA.
I repeated the test with different wires, protoboards and even power supply boards. I have three of them, all working apparently ok and reading the same on the multimeter. The board have the jumpers in the correct position: 5V.
I am just an amateur learning how electronics works, and I do not understand what is happening here. Some ideas?
Working:

Not working:

I don't think the problem is in the code, but just in case...
#include "DHTStable.h"

DHTStable DHT;

#define DHT11_PIN 5

void setup() {
    Serial.begin(115200);
    Serial.println(__FILE__);
    Serial.print("LIBRARY VERSION: ");
    Serial.println(DHTSTABLE_LIB_VERSION);
    Serial.println();
    Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");
}

void loop() {

    // READ DATA
    Serial.print("DHT11, \t");
    int chk = DHT.read11(DHT11_PIN);

    switch (chk)
    {
        case DHTLIB_OK:
            Serial.print("OK,\t");
            break;
        case DHTLIB_ERROR_CHECKSUM:
            Serial.print("Checksum error,\t");
            break;
        case DHTLIB_ERROR_TIMEOUT:
            Serial.print("Time out error,\t");
            break;
        default:
            Serial.print("Unknown error,\t");
            break;
    }

    // DISPLAY DATA
    Serial.print(DHT.getHumidity(), 1);
    Serial.print(",\t");
    Serial.println(DHT.getTemperature(), 1);

    delay(2000);
}

Sensors needs to be connected to the same ground as the Arduino. In the image below that is not the case. Connect the ground (and only the ground, not the +5V) of your external power supply to the ground of the Arduino and the DHT11 will probably work again.

@StarCat That was it! Adding a wire for connecting the power supply board ground to the Arduino ground made it work. Could you post your comment as an answer for me to mark it as the correct one? Also, if you could explain a little why was that necessary it would be great. Thank you.

In your question in the image below your grounds are not connected. The solution to your problem is to connect the ground (and only the ground, not the +5V) of your external power supply to the ground of the Arduino and the DHT11 will probably work again.
A bit of background
Sensors needs to be connected to the same ground as the Arduino. This is true in general with all parts of an electronic circuit. Ground functions as a fixed, common, reference voltage by which other signals (such as the digital data that's exchanged between the DHT11 sensor and the Arduino) are measured.
By connecting grounds, you make sure that a "high" that is output by the DHT11 is read as a "high" by Arduino and vice versa. When grounds are not connected, voltages between two parts of the circuit would "float" relative to each other and they would not be able to communicate. This link explains a bit more.

Thank you very much! I learned something today.


text:
Can't connect esp8266 via USB to Linux Mint 21.1
What was my problem
I had a big problem with my esp8266. I couldn't upload anything to it using the Arduino IDE 2.2.1, the ttyUSB port couldn't be found.
When I plug my esp8266 into the USB Port, it shows up in the port selection in the Arduino IDE but then disappears imminently.
dmesg | grep ch34
[    7.286317] usbcore: registered new interface driver ch341
[    7.286328] usbserial: USB Serial support registered for ch341-uart
[    7.286342] ch341 1-3:1.0: ch341-uart converter detected
[    7.304530] usb 1-3: ch341-uart converter now attached to ttyUSB0
[    7.804730] usb 1-3: usbfs: interface 0 claimed by ch341 while 'brltty' sets config #1
[    7.811803] ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0
[    7.811814] ch341 1-3:1.0: device disconnected

As shown above, the esp8266 is connecting, but then disconnects.

The solution
https://www.linux.org/threads/ch340-driver-on-linux-mint.44961/post-204493
sudo apt-get remove -y brltty
Just remove the brltty package.
What is brltty?
https://brltty.app/
"BRLTTY is a background process (daemon) which provides access to the Linux/Unix console (when in text mode) for a blind person using a refreshable braille display. It drives the braille display, and provides complete screen review functionality. Some speech capability has also been incorporated."
So as long as you don't need the abilty for displaying something on a braille display, you'll good to go wit that solution.
I hope, that this will help anyone :D I posted this here, because I was searching for that very long, so it might be useful to have short solution for that.


text:
Arduino Timer Drift Issue
I have two Arduinos that communicate over serial. Each arduino runs a TDMA algorithm where each arduino is assigned one timeslot. The arduinos should transmit during their timeslot, which does work fine. However, over time, say 10-15 minutes the arduinos start to overlap their timeslots. To keep time I am using the millis() function to determine when to send a message. I have tried both delay() and manually setting up counters but getting the same drifting behavior. On one of the iterations of the code I had a Serial.readStringUntil() function that was being called during every timeslot and the arduinos stayed in sync for over 13 hours with no detected drift, with an exact timeslot of 1000ms. I now am aware that the delay I was seeing is caused by the timeout parameter, which defaults to 1000ms, in the readStringUntil function, but it does not make sense that there would be no drift when the arduino was delayed in this way. I know that the stability of the ceramic resonator on each arduino would cause drift.
Why would delay(), millis(), and manually configuring timer1 cause drift, but the timeout functionality of the readStringUntil function seemingly does not drift?
Also, is there a better way to setup the timing functionality, the goal is to have the nodes go as long as possible without needing a resync?
The following psuedo is how the timing is currently setup.
count = 0;

if(millis() - previous_action >= TIME_SLOT) {
   count++;
   if(correct timeslot) {
       TRANSMIT();
   }
   previous_action = millis();
   loop_back_to_check;
}

EDIT:
RTC and other devices that can keep the devices sync'd are not in the scope of the project.

what device do the arduinos communicate to?

@jsotola they send messages to a receiver which collects packets and prints to a file.

What kind of Arduino are you using? Is it clocked off a crystal or a ceramic resonator?

Similar to @NickS below. Modify the TDM algorithm running on both devices so that the transmissions can be used also to keep the devices in sync. For example, if each transmission starts exactly 100ms into the timeslot, the other side can adjust its clock to match. In this case, the next full second rollover should be in 900ms.

Any fee-running clock will drift. Worse yet: its drift rate will not be
constant. This is a fact of life, and there is nothing you can do about
it. There is no software solution, although your software can certainly
make things worse. What you can do is:

Synchronize the clocks of both Arduinos to an external time source.
The time source doesn't have be accurate if you only care about the
relative drift between the Arduinos. This could be the receiver of
the messages sending an acknowledgement at a specific time, or the
same receiver sending a pulse on a dedicated line, or an NTP server
if your Arduinos are networked, or a radio-broadcast time signal, or
a GPS receiver...

Use clocks that are so good that their drift becomes irrelevant. The
drift rate has to be less than the timing tolerance of your TDMA
protocol divided by the expected service life of your devices. A good
RTC can give you a drift rate less than about 2 ppm (i.e.
2×10−6). If that is not good enough, you may consider an
OCXO (oven-controlled crystal oscillator) or an atomic clock (the
rubidium-based ones are the most affordable).

Calibrate your clocks. As the variations of the drift rate are
typically much less than the average drift rate, you can remove most
of the drift by first measuring it and then removing in software the
value you measured. You are then left with the random variations of
the drift rate (“frequency wander”). I suggest you read Arduino
clock frequency accuracy to get an idea of the kind of
accuracy you can expect.

Use temperature control: keep you clocks at constant temperature, as
temperature variations are often the main cause of frequency wander.
Alternatively, use temperature compensation: measure the drift rate
at multiple temperatures, fit a continuous curve through these
measurements and use this curve (and continuous temperature
measurements) to correct the drift in software.

Avoid making things worse with your software: update
previous_action with
previous_action += TIME_SLOT;

rather than assigning millis() to it, as this approach is
guaranteed to cause drift.

Why [...] the timeout functionality of the readStringUntil function
seemingly does not drift?

Nobody can answer this question without a careful examination of both
the specific version of the software you used and the physical setup. It
could be that you accidentally implemented a synchronization mechanism.
It could be that your measurements were not accurate enough to reveal
the drift.

You can use one of the many RTC (Real Time Clock) modules, they are crystal controlled where your Arduino is not. There are several varieties, pick the one you like. There is a large difference in stability between the Arduino timing and the RTC timing. You can update the clocks on a regular basis. Using NTP (Network Time Protocol) which would be very accurate and reliable. You can do the NTP on a regular basis on one unit and have it update the others. Side benefit they will not drift much as the temperature changes.

See edit. The goal of this is to avoid RTC and only use the internal clock of the arduino to keep time of the device

@roberthayek then it sounds like you'll have to expand on your TDMA algorithm and have the two devices generate overhead and maybe have one be the "server" and the other a "client" - the client device will be doing all the scheduling and the server device will have to adjust its time slots based on the information provided by the client. The two devices have different clocks and thus different drifts, you really can't just fix that.

According to my experience, they are the clients that should follow the server's timing.
On the client side:

On each server transmission, calculate the ETA (Estimated Time of Arrival and ATA (Actual Time of Arrival) of the message, based on your time slot scheduling and adjust your local clock accordingly.
It would be nice to treat all transmissions as timing messages, no matter the destination, just ignore the payload.
It is obvious that the client should be a little overhead timed, in case the server's clock is a little faster.
For long inactive periods, the server should broadcast a periodic timing message, so that the error will be kept to a minimum.
It would be convenient to add a "timing preamble" in each transmission.

With all that in mind, the readStringUntil function is your friend in many ways. By waiting for the timing preamble, you can determine easily the timing error. By waiting for a known postamble, you read "late" messages (don't forget the timeout value!).
Use a bi-numbering scheme for each transmission, one for each client's message and one for each broadcast (total transmissions). Calculate the minimum convenient modulo (overflow) values. Each client will know if there's something missing. (usually, a too-early transmission or a collision)
Although it is communications-medium agile, I would recommend a preamble like:
$FF $00 $FF $00 AA BB CC DD EE $FF $FF FF with PAYLOAD following, where:

AA = 1 byte, the destination addr, $00 = Broadcast

BB = 1 byte, message type (optional, $00 for timing msg)

CC = 1..2 bytes, msg no. to this dest.

DD = 1..2 (3?) bytes, total msg no., no matter the dest.

EE = 1 byte, payload length, if variable. (EE<$FF, $00 for timing msg)

FF = 1 byte checksum (optional). (Why should you place it AFTER the "$FF
$FF" combination?)

Use the time you receive the "$FF $FF" combination as a time-mark to calculate ATA & ETA. (It is common sense to treat your values so that this combination cannot show before the end of the preamble)
Consider using a postamble, with redundant info & End-Of-Message mark.


text:
Prevent flicker - Lcd with I2C module?
I have a 16x2 LCD with a I2C interface, and a Esp8266 based NodeMCU.
I Have an issue where the second line of the LCD is flickering, but somehow the first line does not flicker.
Why does this happen and how do I prevent it?
My code :-
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include "DHT.h"
#include "LiquidCrystal_PCF8574.h"
#include <EEPROM.h>

#define BLYNK_PRINT Serial
#define DHT_PIN_DATA  12
// LCD definations
#define LCD_ADDRESS 0x27
#define LCD_ROWS 2
#define LCD_COLUMNS 16
#define SCROLL_DELAY 150
#define BACKLIGHT 25
#define DHTTYPE DHT22

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "ymri80lbh9_xZhf6WIRHtQ1qHYOt9zBy";
char ssid[] = "DB";
char pass[] = "bkg88q";
int autoSch;
int waterNow;
int morTime;
int afterTime;
int postNoon;
int eveTime;
int schTime;
int minStep;
int interval;
int count;
int flag = 0;
unsigned long previousMillis = 0;

DHT dht(DHT_PIN_DATA, DHTTYPE);
LiquidCrystal_PCF8574 lcdI2C;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "in.pool.ntp.org", 19800, 600000);
// This function will be called every time Slider Widget
// in Blynk app writes values to the Virtual Pin 1

BLYNK_CONNECTED() {
  Blynk.syncAll();
}

BLYNK_WRITE(V0)
{
  autoSch = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V1)
{
  morTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V2)
{
  afterTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V6)
{
  postNoon = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V3)
{
  eveTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V10)
{
  waterNow = param.asInt(); // assigning incoming value from pin V1 to a variable

}

BLYNK_WRITE(V4)
{
  schTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V7)
{
  minStep = param.asInt(); // assigning incoming value from pin V1 to a variable
}

void setup()
{
  dht.begin();
  lcdI2C.begin(LCD_COLUMNS, LCD_ROWS, LCD_ADDRESS, BACKLIGHT);
lcdI2C.setBacklight(2);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  pinMode(14, OUTPUT);
  digitalWrite(14, LOW);
  Blynk.virtualWrite(V5, 0);
  Blynk.virtualWrite(V8, 0);
  pinMode(2, INPUT_PULLUP);
  Serial.begin(9600);
  EEPROM.begin(512);
  //WiFi.begin(ssid, password);
  Blynk.begin(auth, ssid, pass);
  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }
  timeClient.begin();
  Blynk.syncAll();
}

void loop()
{
  Blynk.run();
  time_run();
  lcd();
  butPress();
  //test();
  timeClient.update();
  if (waterNow == 1) {
    waterNowrun();
  } else if (autoSch == 0) {
    auto_run1();
  } else if (autoSch == 1) {
    sch_run2();
  } else {
    Blynk.virtualWrite(V10, 0);
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.syncAll();
  }
  Blynk.syncAll();
}

void lcd() {
  lcdI2C.clear();

  timeClient.update();
  lcdI2C.print(timeClient.getFormattedTime());

  if (autoSch == 0) {
    lcdI2C.setCursor(9, 0);
    lcdI2C.print("Auto");
  } else {
    lcdI2C.print(" Sch");
  }

  if (digitalRead(14) == 1) {
    lcdI2C.selectLine(2);
    lcdI2C.print("Wtr Now           ");
  }
  else
  {

    if (int(timeClient.getHours()) < 6 && morTime == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 6a");
    } else if (int(timeClient.getHours()) < 12 && afterTime == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 12n");
    } else if (int(timeClient.getHours()) < 14 && postNoon == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at:14pn");
    } else if (int(timeClient.getHours()) < 18 && eveTime == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 18e");
    } else if (int(timeClient.getHours()) >= 18 && morTime == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 6a");
    } else {

    }

  }

}

void waterNowrun() {
  interval = minStep * 60 * 1000;
  unsigned long currentMillis = millis();
  Serial.println (currentMillis);
  Serial.println (previousMillis);
  Blynk.syncAll();
  if (((currentMillis - previousMillis) >= interval) || waterNow == 0) {
    previousMillis = currentMillis;
    Blynk.virtualWrite(V10, 0);
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.virtualWrite(V8, 0);
    Blynk.syncAll();
  } else {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    lcdI2C.selectLine(2);
    lcdI2C.print("Wtr Now :");
    lcdI2C.print((minStep * 60) - ((currentMillis - previousMillis) / 1000));
    Blynk.virtualWrite(V8, ((interval / 1000) - ((currentMillis - previousMillis) / 1000)));
    Blynk.syncAll();
  }
}

void sch_run2() {
  if (schTime == 1) {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  } else if (schTime == 0) {
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.syncAll();
  }

}

void time_run() {
  Blynk.virtualWrite(V11, int(timeClient.getHours()));
  Blynk.virtualWrite(V12, int(timeClient.getMinutes()));
  Blynk.virtualWrite(V13, float(dht.readTempC()));
  Blynk.virtualWrite(V14, float(dht.readHumidity()));

}

void butPress() {
  if (digitalRead(2) == LOW) {
    if (flag == 0) {

      flag = 1;
      digitalWrite(14, HIGH);
    }
    else {
      digitalWrite(14, LOW);
      flag = 0;
    }
    int y = 10;
    int x = 0;
    if (digitalRead(14) == HIGH) {
      for (x = 0; x < y; x++) {
        delay(500);
        Serial.println("x:  ");         Serial.println(x);
      }
    }else{
      digitalWrite(14, LOW);
      }

  }
}

void test() {
  if (digitalRead(2) == LOW) {
    Serial.println("IDLY BLAA");
    int y = 10;
    for (int x = 0; x < y; x++) {
      delay(500);
      Serial.println("x:  ");         Serial.println(x);
    }
  }

}

void auto_run1() {
  if (morTime == 1 && String(timeClient.getFormattedTime()) > "06:00:00" && String(timeClient.getFormattedTime()) < "06:20:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  }
  else if (afterTime == 1 && String(timeClient.getFormattedTime()) > "12:00:00" && String(timeClient.getFormattedTime()) < "12:20:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  }
  else if (postNoon == 1 && String(timeClient.getFormattedTime()) > "14:00:00" && String(timeClient.getFormattedTime()) < "14:20:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  }
  else if (eveTime == 1 && String(timeClient.getFormattedTime()) > "12:59:00" && String(timeClient.getFormattedTime()) < "13:01:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  }
  else  {
    //(String(timeClient.getFormattedTime() == "06:20:00" || "12:20:00" || "14:20:00" || "13:48:00"))
    //waterNowrun();
    /*
      Blynk.virtualWrite(V10, 0);
      digitalWrite(14, LOW);
      Blynk.virtualWrite(V5, 0);
      Blynk.virtualWrite(V8, 0);
      Blynk.syncAll();
    */
  }
}

Don't do lcdI2C.clear(); on each loop. Just overwrite the existing contents. Then it does not flicker.

@PMF I just tried that, now the LCD is frozen

Frozen? As in: "Shows nothing at all"? I don't exactly know what kind of LCD library you use there, but it might be necessary to call the clear() once at startup.

@PMF Shows the information it should show, but does not update

You might need to do a lcdI2C.setCursor(0, 0); where the clear() was, to ensure you start at the top left with updating the lcd.

Now it works...  but there's another small problem- now if I physically disturb the LCD, it displays random characters.
Not a major issue, just want to know why.

I've seen LCDs behave unpredictably with bad cabling or a bad power source. So if moving the LCD causes contact problems, then this could be the cause. Make sure all cables are seated properly.

Alright, I did some digging around and found out it was due to high CPU frequency, case closed

one proposal. Give a good description about the problem you found. The solution you used. Answer your own question. It will be helpful for someone later.


text:
How to reset a variable just before entering a function?
I am facing a problem where the if condition in the function waterNowrun is able to execute once after the program starts as the variable v is 0 at the start, but upon starting it again the if does not execute as v is not <10.
After some debugging I had decided that v would have to be reset before entering the function, and so I set v to 0 in the loop, then what happened is that the if was always satisfied and did not go to the else.
Is it possible to do it? Maybe with interrupts or something else?
Hardware-ESP8266 based NodeMCU
In conclusion-
I want a reset a variable v once just before the function waterNowrun starts, how do I do it?
My code-
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include "DHT.h"
#include "LiquidCrystal_PCF8574.h"

#define BLYNK_PRINT Serial
#define DHT_PIN_DATA  12
// LCD definations
#define LCD_ADDRESS 0x27
#define LCD_ROWS 2
#define LCD_COLUMNS 16
#define SCROLL_DELAY 150
#define BACKLIGHT 25
#define DHTTYPE DHT22

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "ymri80lFL9_xZhf6WIRHtQ1qadfafdEWOt9zBy";
char ssid[] = "-Hotspot-82DB";
char pass[] = "b35288qqafdd";
int autoSch;
int waterNow;
int morTime;
int afterTime;
int postNoon;
int eveTime;
int schTime;
int minStep;
int interval;
int count;
int flag = 0;
int soilHum = A0;
int v;
unsigned long previousMillis = 0;

DHT dht(DHT_PIN_DATA, DHTTYPE);
LiquidCrystal_PCF8574 lcdI2C;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "in.pool.ntp.org", 19800, 600000);
// This function will be called every time Slider Widget
// in Blynk app writes values to the Virtual Pin 1

BLYNK_CONNECTED() {
  Blynk.syncAll();
}

BLYNK_WRITE(V0)
{
  autoSch = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V1)
{
  morTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V2)
{
  afterTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V6)
{
  postNoon = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V3)
{
  eveTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V10)
{
  waterNow = param.asInt(); // assigning incoming value from pin V1 to a variable
Serial.println("Boo BOO is BOO BOO billa");
}

BLYNK_WRITE(V4)
{
  schTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V7)
{
  minStep = param.asInt(); // assigning incoming value from pin V1 to a variable
}

void setup()
{
  dht.begin();
  lcdI2C.begin(LCD_COLUMNS, LCD_ROWS, LCD_ADDRESS, BACKLIGHT);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  pinMode(14, OUTPUT);
  digitalWrite(14, LOW);
  Blynk.virtualWrite(V5, 0);
  Blynk.virtualWrite(V8, 0);
  pinMode(0, INPUT_PULLUP);
  Serial.begin(9600);

  //WiFi.begin(ssid, password);
  Blynk.begin(auth, ssid, pass);
  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }
  timeClient.begin();
  Blynk.syncAll();
}

void loop()
{
  Blynk.run();
  time_run();
  lcd();
  butPress();

  timeClient.update();
  if (waterNow != 1) {
    Blynk.virtualWrite(V10, 0);
   // digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.virtualWrite(V8, minStep * 60);

    Blynk.syncAll();
  }
  if (waterNow == 1) {
    waterNowrun(v = 0);

  } else if (autoSch == 0) {
    auto_run1();
  } else if (autoSch == 1) {
    sch_run2();
  } else {
    Blynk.virtualWrite(V10, 0);
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.syncAll();
  }
  Blynk.syncAll();
  Serial.println(timeClient.getFormattedTime());
  Serial.println(analogRead(A0));
}
void butPress() {
  if (digitalRead(0) == LOW) {
    if (flag == 0) {

      digitalWrite(14, HIGH);
      delay(3000);
      digitalWrite(14, LOW);

      flag = 1;
    }
    else {
      digitalWrite(14, LOW);
      flag = 0;
    }
  }
}

void test() {
  if (v < 10) {
    digitalWrite(14, HIGH);
    v++;
    delay(500);

  } else {
    digitalWrite(14, LOW);

  }

}

void lcd() {
  //lcdI2C.clear();
  lcdI2C.setCursor(0, 0);
  timeClient.update();
  lcdI2C.print(timeClient.getFormattedTime());

  if (autoSch == 0) {
    lcdI2C.setCursor(9, 0);
    lcdI2C.print("Auto     ");
  } else {
    lcdI2C.print(" Sch   ");
  }

  if (digitalRead(14) == 1) {
    lcdI2C.selectLine(2);
    lcdI2C.print("Wtr Now           ");
  }
  else
  {

    if (int(timeClient.getHours()) < 6 && morTime == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 6a ");
    } else if (int(timeClient.getHours()) < 12 && afterTime == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 12n ");
    } else if (int(timeClient.getHours()) < 14 && postNoon == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at:14pn ");
    } else if (int(timeClient.getHours()) < 18 && eveTime == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 18e ");
    } else if (int(timeClient.getHours()) >= 18 && morTime == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 6a ");
    } else {
      lcdI2C.selectLine(2);
      lcdI2C.print("My name is billa");
    }

  }

}

void waterNowrun(int v) {
  /*
    Serial.println (currentMillis);
    Serial.println (previousMillis);
    Serial.println(interval);
  */

  if (v < 10) {

    Serial.println("Boo Boo");

    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    lcdI2C.selectLine(2);
    lcdI2C.print("Wtr Now :");
    /*
      lcdI2C.print((minStep * 60) - ((currentMillis - previousMillis) / 1000));
      Blynk.virtualWrite(V8, ((interval / 1000) - ((currentMillis - previousMillis) / 1000)));
    */
    Blynk.syncAll();
    delay(500);
    v++;
  } else {
    Blynk.virtualWrite(V10, 0);
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.virtualWrite(V8, 0);

    Blynk.syncAll();

  }
}

void sch_run2() {
  if (schTime == 1) {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  } else if (schTime == 0) {
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.syncAll();
  }

}

void time_run() {
  Blynk.virtualWrite(V11, int(timeClient.getHours()));
  Blynk.virtualWrite(V12, int(timeClient.getMinutes()));
  Blynk.virtualWrite(V13, float(dht.readTempC()));
  Blynk.virtualWrite(V14, float(dht.readHumidity()));

}

void auto_run1() {
  if (morTime == 1 && String(timeClient.getFormattedTime()) > "06:00:00" && String(timeClient.getFormattedTime()) < "06:20:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  }
  else if (afterTime == 1 && String(timeClient.getFormattedTime()) > "12:00:00" && String(timeClient.getFormattedTime()) < "12:20:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  }
  else if (postNoon == 1 && String(timeClient.getFormattedTime()) > "14:00:00" && String(timeClient.getFormattedTime()) < "14:20:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  }
  else if (eveTime == 1 && String(timeClient.getFormattedTime()) > "12:59:00" && String(timeClient.getFormattedTime()) < "13:01:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  }
  else  {
    //(String(timeClient.getFormattedTime() == "06:20:00" || "12:20:00" || "14:20:00" || "13:48:00"))
    //waterNowrun();
    /*
      Blynk.virtualWrite(V10, 0);
      digitalWrite(14, LOW);
      Blynk.virtualWrite(V5, 0);
      Blynk.virtualWrite(V8, 0);
      Blynk.syncAll();
    */
  }
}

The logic behind your explanation is not entirely clear to me, but the variable int v inside the waternowRun function is a local variable that is only valid inside this function and not the same as the "global" variable int v. This probably causes the confusion. If you want to retain the value of a local variable between function calls, you could declare it as a static variable but that might or might not be what you want. This is also a programming question and not an Arduino specific question.

And this is exacly why it's discouraged to use global variables... Anyway, test() function changes global variable v (great name if you wanted to encrypt the code). The waterNowrun(int v) changes local variable conveniently named v that shadows global v... take a pick what's messing it up

@StarCat Can you please explain how static variables work?

If's explained quite clearly here: https://www.tutorialspoint.com/what-is-the-lifetime-of-a-static-variable-in-a-cplusplus-function. If you declare a variable static inside of a function (for example static int counter;, it will keep its value when the function is called multiple times, as in the example from the link. Normally a local variable is re-allocated (reset) when leaving a function and re-entering it.

@StarCat I tried it does not work

The purpose of the waterNowrun function and 'v' seems to be to turn on some water and keep it running for 10 iterations, before turning it off?
I would split the waterNowrun into two functions:
void waterOn() {
    Serial.println("Boo Boo");
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    lcdI2C.selectLine(2);
    lcdI2C.print("Wtr Now :");
    /*
      lcdI2C.print((minStep * 60) - ((currentMillis - previousMillis) / 1000));
      Blynk.virtualWrite(V8, ((interval / 1000) - ((currentMillis -     previousMillis) / 1000)));
    */
    Blynk.syncAll();
    delay(500);
}

void waterOff() {
    Blynk.virtualWrite(V10, 0);
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.virtualWrite(V8, 0);
    Blynk.syncAll();
}

In the loop() I would do
...
if (waterNow != 1) {
    waterOff();
}
if (waterNow == 1) {
    if (v < 10) {
        waterOn();
        v++;
    }
    else {
        waterOff();
        v = 0;
    }
} else if (autoSch == 0) {
    auto_run1();
} else if (autoSch == 1) {
    sch_run2();
} else {
    waterOff();
}
...

But do yourself a favour and rename v to waterPeriod or something that is easier to remember.

Appreciate the help...  Just for clarification I'll try to explain what I've understood- So if waterNow is 1 and v<10 then waterOn until v> or = 10, go to the else statement and do WaterOff which also turns waterNow to 0 hence exiting the if statement and setting v=0, to reset the state of the variable.                              Is that what I am supposed to understand?

Hi, sorry for not getting back to you before. Yes, that's right. When you start out, waterNow is false (or 0) and v is 0. When waterOn is true (or 1), we get to the waterNow==1 branch. v is 0, so < 10, the water is turned on and v is incremented. For the next iterations, we do the same, until v reaches 10. Then we go to the else branch, turns off the water and resets V. Now waterNow and v are 0 like when we  started.

If going through waterOn again and again is a problem, you can try
if (v == 0) {
waterOn();
}
if (v++ == 10) {
waterOff();
v = 0;
}
EDIT: Seems like comments are formatted. Linebreaks after branckets and ;

It isn't clear what behavior you expect from v, especially since you have two of them - the global v at the head of your program, and the parameter v of the function waterNowrun(int v).
My understanding of what you want is that the function should maintain control of v. If so,

Get rid of the global v';
In loop(), don't pass anything to waterNowrun()
Inside waterNowrun() declare static int v = 0;. That initialization to zero will only happen once, before the program starts (not on every entry to the function, even though it kind of reads like that). From then on, only your waterNowrun() function can change v.

That may not be the only logic change you need to make - I don't understand what you're trying to do with v and can't critique that. But at least now v will be entirely controlled from within the function, and it will not change between invocations of the function.
Some background: A static variable declared within a function is like a global in that it has a fixed memory address for the entire program run; unlike a local (including a function parameter) that gets reallocated in memory each time the function is entered (and therefore must be initialized on every entry). But unlike a global, it is invisible - not known about - anywhere outside of that function.

Unfortunately this answer does not solve the problem as I am facing the same issue as before where the function works one time but not a second

Please clarify what it is you're trying to accomplish.

I'm trying to turn on watering for a particular number of iterations and then turn it off, the problem is that the iterations counter v remains = or > 10 hence not entering the function  a second time

Try to add a "v = 0;" line after the two other waterOff(); calls.

You need to reset the counter when you turn off the water and increase it while the water is on.