millis() always slows me [SOLVED]

Hi All,

Tying to get a ZC error detection correct here is my code and can't seem to find where the problem is. when i swtich off the zc source (Source being 12v) connected to H11AA1 with a 1K resistor in series and the output to PIN4 with 1K in series to arduino.

/* Spot Welder Microcontrollr version 4
  Using Servo to reaise and lower weld arm.
*/
#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
byte zCd = 2;  // Zero Crossing Detect
volatile boolean zeroCrossingFlag = false;
const byte rdy = 4;
unsigned long timeCheck = 1000;
int zCdState;
void setup()
{

  lcd.clear();
  lcd.begin(20, 4);
  lcd.setCursor(5, 0);
  lcd.print("Spot Welder");
  lcd.setCursor(3, 1);
  lcd.print("Microcontroller");
  lcd.setCursor(4, 3);
  lcd.print("Version 5.0");
  delay(2000);
  lcd.clear();
  lcd.setCursor(5, 2);
  lcd.print("Design");
  lcd.setCursor(1, 3);
  lcd.print("A.George Thomas");
  delay(3000);
  lcd.clear();
  Display();
  int LastServoPos;
  pinMode(rdy, OUTPUT);
  pinMode(zCd, INPUT_PULLUP);
  delay(500);
  Serial.begin(9600);
}
void Display()
{
  lcd.clear();
  lcd.setCursor(5, 0);
  lcd.print("Spot Welder");
  lcd.setCursor(3, 1);
  lcd.print("Microcontroller");
  lcd.setCursor(0, 3);
  lcd.print("Weld time: ");
  lcd.print("ms  ");
}

void loop()
{
  static unsigned long startTime = millis();
  Serial.print("Start Time: ");
  Serial.println(startTime);
  delay(100);
  unsigned long elapsed = millis() - startTime;
  Serial.print("Current Time: ");
  Serial.println(millis());
  Serial.print("Elapsed Time: ");
  Serial.println(elapsed);
  Serial.print("Time dif: ");
  Serial.println(millis() - elapsed);
  Serial.println(" ");
  if ((millis() - elapsed) <= timeCheck)
  {


    Serial.print("Current Time: ");
    Serial.println(millis());
    Serial.print("Elapsed Time: ");
    Serial.println(elapsed);
    if (zCdState == LOW)
    {
      digitalWrite (rdy, HIGH);
      Serial.println("READY");

    } else {
      digitalWrite(rdy, LOW);

      Serial.println("ZC error");
    }
    startTime = millis();

    Serial.print("New Time: ");
    Serial.println(startTime);
    Serial.println(" ");
    elapsed = 0;
  }
}

I can see where i need to correct but lack experience/knowledge to know it. Here is my serial data

Start Time: 5724
Current Time: 9753
Elapsed Time: 4029
Time dif: 5725

In a previous thread you declared the zero cross error detect problem solved
https://forum.arduino.cc/index.php?topic=422040.0

What are you trying to do here that is different? Please explain carefully and completely using words and not code, what you are trying to achieve.

The code posted above makes no sense, because you never check anywhere for zCdState.

What do you expect the serial output to be? All I see is that the current time and elapsed time increase by your 100ms delay plus the loop time.

anishkgt:
Tying to get a ZC error detection correct here is my code and can't seem to find where the problem is. when i swtich off the zc source (Source being 12v) connected to H11AA1 with a 1K resistor in series and the output to PIN4 with 1K in series to arduino.

I recognize all the individual words but I'm sorry that I have no idea what you are trying to convey.

Please re-write this so that someone who knows nothing at all about your project would understand it. And use proper punctuation.

Here is my serial data

Start Time: 5724
Current Time: 9753
Elapsed Time: 4029
Time dif: 5725

I'm guessing that this is not the data you would like to see but you have not told us what is wrong with it.

...R

Sorry about all confusion.

/* Spot Welder Microcontrollr version 4
  Using Servo to reaise and lower weld arm.
*/
#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
byte zCd = 2;  // Zero Crossing Detect
volatile boolean zeroCrossingFlag = false;
const byte rdy = 4;
unsigned long timeCheck = 5;
int zCdState;

void setup()
{
  attachInterrupt(0, setFlag, FALLING);
  lcd.clear();
  lcd.begin(20, 4);
  lcd.setCursor(5, 0);
  lcd.print("Spot Welder");
  lcd.setCursor(3, 1);
  lcd.print("Microcontroller");
  lcd.setCursor(4, 3);
  lcd.print("Version 5.0");
  delay(2000);
  lcd.clear();
  lcd.setCursor(5, 2);
  lcd.print("Design");
  lcd.setCursor(1, 3);
  lcd.print("A.George Thomas");
  delay(3000);
  lcd.clear();
  Display();
  int LastServoPos;
  pinMode(rdy, OUTPUT);
  pinMode(zCd, INPUT_PULLUP);
  delay(500);
  Serial.begin(9600);
}

void setFlag()
{
  zeroCrossingFlag = true; //interrupt sets flag true
}

void Display()
{
  lcd.clear();
  lcd.setCursor(5, 0);
  lcd.print("Spot Welder");
  lcd.setCursor(3, 1);
  lcd.print("Microcontroller");
  lcd.setCursor(0, 3);
  lcd.print("Weld time: ");
  lcd.print("ms  ");
}

void loop()
{
  while (!zeroCrossingFlag)
  {
    digitalWrite(rdy, LOW);
    lcd.setCursor(0, 2);
    Serial.print("ZC Error");
    lcd.print("ZC sense Error");
  }
  digitalWrite(rdy, HIGH);
  lcd.setCursor(0, 2);
  lcd.print("              ");
  zeroCrossingFlag = false;
}

The above code is working and does detect the ZC with an LED. No problem there. Now i've bought an 4x20 LCD with YwROBOT LCM1602 on its back.

The led blinks when it detects HIGH and LOW so basically blinking very fast. When using the LCD to update one like it just flickers when it should be showing no characters on line 0,2. here the led remains on. But no problem when the ac source for zc is switched off. The LCD displays the message.

Hope am clear now.

Well, the end of loop() ALWAYS sets zeroCrossingFlag to false, so the beginning of loop() will always try to show the text. (Except in the rare case of finding a zero crossing during that nanosecond between ending and starting the loop.)

It takes a certain amount of time to write that stuff out to the LCD. So you start seeing those characters on the LCD.

Then the loop ALWAYS erases those characters, if zeroCrossingFlag has become true while you were writing out the message. So they flicker. A lot.

well that is true ! The could be some way to just display it on an LCD like with a condition that was when things got a little messier and here i am at the forum.

@anishkgt
Ithink the timeout approach from the previous thread Zero Cross Error detect [SOLVED] - Project Guidance - Arduino Forum is valid and can be adapted to print the error message to the lcd.

boolean zeroCrossingFlag = false;
unsigned long timeout = 1000;
const byte rdy = 4;//indicator led


void setup() {
  Serial.begin(115200);
  // lcd set up
  
  pinMode(rdy, OUTPUT);

  pinMode(2, INPUT_PULLUP);//zero cross interrupt pin
  attachInterrupt(0, setFlag, FALLING);//zero cross detect
}

void loop() {

  unsigned long startTime = millis();
  while (!zeroCrossingFlag && (millis() - startTime < timeout))
  {
    //hang in while loop until either zeroCrossFlag or timeout occurs
    //both conditions need to be met to stay in while loop
  }

  if (zeroCrossingFlag)//exit while loop due to flag set
  {
    Serial.println("exit while loop with zero cross detected");
    //write lcd zero cross OK messsage
    zeroCrossingFlag = false;
    digitalWrite(rdy,HIGH);//led on when triggered
  }
  else  //exit while loop due to time out error
  {
    Serial.println("zero cross time out error");
    //write lcd error message
    digitalWrite(rdy, LOW);
    //while (1); // halt sketch on timeout?
  }

 
}


void setFlag() 
{
  zeroCrossingFlag = true;//interrupt sets flag true
 
}

The if condition seems to be true always and does not skip to the else block. Hence all the time the

"exit while loop with zero cross detected"

is what is displayed.

The if condition seems to be true always and does not skip to the else block.

Not in my testing. When I run the sketch and apply a 50Hz pulse signal to pin2 the led is on, and one second after I remove the signal the led goes off.

The zeroCrossFlag is set false after that if conditional is entered. It can only be set true again by the zero cross interrupt.

Thanks just tested again and i realized i was setting the flag to true again at the end. corrected that and all works like you said.