Another millis() doubt

Need some guidance with Millis() or is there better way to accomplish what i intent to

startTime = millis();
    elapsedTime = millis() - startTime;
    if (elapsedTime >= TimeCheck)
    elapsedTime = 0;
    digitalWrite(rdy, LOW);
    lcd.setCursor(5, 0);
    lcd.print("ZC ERROR ! !");
    lcd.setCursor(3, 1);
    lcd.print("CHECK IC H11AA1 ");
    lcd.setCursor(0, 3);
    lcd.print("SYSTEM HALT     ");
    Serial.println("ZC ERROR");
  } else {
    digitalWrite(rdy, HIGH);
    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(WeldStep());
    lcd.print("ms  ");

Tried several ways to switch on an led when zero cross is detected and off when not detected.

Now all works well but the else statements gets activated several times. How can i get rid of this ?

That won't compile. You have an else without a previous if error.

startTime = millis();
    elapsedTime = millis() - startTime;
    if (elapsedTime >= TimeCheck)

Since you just set startTime equal to millis and then immediately subtract it from millis, what do you think are the chances that the result of that subtraction will even be larger than 0 or maybe a 1?

Post complete code if you want help with this.

/* 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;

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);
attachInterrupt(0, setFlag, FALLING);//zero cross attach
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 setFlag()
{
zeroCrossingFlag = true; //interrupt sets flag true
}

void loop()
{
unsigned long timeCheck = 1000;
unsigned long startTime = 0;
unsigned long elapsedTime = 0;
int zCdState = digitalRead(zCd);
startTime = millis();
if (zCdState == HIGH && millis() - startTime >= timeCheck)
{
digitalWrite(rdy, LOW);
Serial.println(“ZC ERROR”);
delay(3000);
} else {
digitalWrite(rdy, HIGH);
Serial.println(“Ready”);
}
elapsedTime = 0;
}

Let's try again :wink:

  startTime = millis();
  if (millis() - startTime >= timeCheck)

Assume millis() returns 10 on the first call; one microsecond (or so later) you call millis() again. What will millis() return at the second call? More than likely 10, very very maybe 11.

So will millis() - startTime ever be greater than timeCheck?

You need to make startTime static so the time is remembered between successive calls to loop();

void loop()
{
  unsigned long timeCheck = 1000;
  static unsigned long startTime = 0;
  if (millis() - startTime >= timeCheck)
  {
    startTime = millis();
    digitalWrite(rdy, LOW);
    Serial.println("ZC ERROR");
  }
  else
  {
    digitalWrite(rdy, HIGH);
    Serial.println("Ready");
  }
}

Thanks i get what you mean but it stills says ready when i swtich off the zc source. Source being 12v connected to H11AA1 with a 1K resistor in series and the output to PIN2 with 1K in series

my code after some error check

// Spot Welder Microcontroller version 4.
#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;

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);
  attachInterrupt(0, setFlag, FALLING);//zero cross attach
  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 setFlag()
{
  zeroCrossingFlag = true; //interrupt sets flag true
}

void loop()
{
  unsigned long timeCheck = 1000;
  static unsigned long startTime = 0;
  unsigned long elapsedTime = 0;
  int zCdState = digitalRead(zCd);
  startTime = millis();
  if (zCdState == HIGH && (millis() - startTime) >= timeCheck)
  {
    elapsedTime = (millis() - startTime);
    digitalWrite(rdy, LOW);
    Serial.println("ZC ERROR");
  } else {
    digitalWrite(rdy, HIGH);
    Serial.println("Ready");
  }
  Serial.println(elapsedTime);
  elapsedTime = 0;
}

No, you still did not get it :wink: You still set startTime before you do your timing check. Why ?? The only time that you want to update startTime is if the time has lapsed (see my loop() example above.

You have also added a second condition to the if statement. If zCdState is LOW at the moment that you reach the 'if', you will always get the 'Ready' message regardless of what the timing is.

Sorry missed you loop example. I’ve added the one line and am getting closer, now the lCD does not update when the ZC is stopped or started.