Timer problem

Hi.
I have tried several things, without being able to find the problem with this timer.
The first counter fine, but then starts the problem.
I ask for help because I've tried even without being able to solve the problem myself

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
const int analogPin = A0;
int val = 0;
int relay = 9;
int interval=3000;
int interval2=60000;
//int interval2=900000;
int interval3=1800000;
int interval4=2700000;
int interval5=3600000;
unsigned long previousMillis=0;

void setup() {
 
 Serial.begin(9600);
 pinMode(9,OUTPUT);
 pinMode(8,OUTPUT);
 pinMode(3,INPUT);
 pinMode(4,INPUT);
 pinMode(5,INPUT);
 pinMode(6,INPUT);
 pinMode(7,INPUT);
 

 }

void loop() {
 Serial.println(millis());
  //extern volatile unsigned long timer0_overflow_count;
  unsigned long currentMillis = millis();
   val = analogRead(analogPin);
   val = map (val, 0, 1023, 5000, 30000);
 if ((digitalRead(3) == HIGH) && ((currentMillis - previousMillis) >= (interval)){
 digitalWrite(relay, HIGH);
 delay(val*2);
 digitalWrite(relay, LOW);
 previousMillis = currentMillis;
 }

//{extern volatile unsigned long timer0_overflow_count;
// unsigned long currentMillis = millis();
//  val = analogRead(analogPin);
//  val = map (val, 0, 1023, 5000, 30000);}
 else if ((digitalRead(4) == HIGH) && ((unsigned long)currentMillis - previousMillis) >= (interval2)){
 digitalWrite(relay, HIGH);
 delay(val*2);
 digitalWrite(relay, LOW);
 
 previousMillis = currentMillis;
 
}

//{extern volatile unsigned long timer0_overflow_count;
//  unsigned long currentMillis = millis();
//  val = analogRead(analogPin);
//  val = map (val, 0, 1023, 5000, 30000);}
 else if ((digitalRead(5) == HIGH) + (unsigned long) (currentMillis - previousMillis) >= (interval3)){
 //digitalWrite(led,(state)?HIGH:LOW); 
 digitalWrite(relay, HIGH);
 delay(val*2);
 digitalWrite(relay, LOW);
 previousMillis = currentMillis;
}

//  extern volatile unsigned long timer0_overflow_count;
// unsigned long currentMillis4 = millis();
// val = analogRead(analogPin);
//  val = map (val, 0, 1023, 5000, 30000);
 else if (digitalRead(6) == HIGH && currentMillis - previousMillis >= interval4) {
 //digitalWrite(led,(state)?HIGH:LOW); 
 digitalWrite(relay, HIGH);
 delay(val*2);
 digitalWrite(relay, LOW);
 previousMillis = currentMillis;
}

//  extern volatile unsigned long timer0_overflow_count;
//  unsigned long currentMillis5 = millis();
// val = analogRead(analogPin);
//  val = map (val, 0, 1023, 5000, 30000);
 else if (digitalRead(7) == HIGH && currentMillis - previousMillis >= interval5) {
 digitalWrite(relay, HIGH);
 delay(val*2);
 digitalWrite(relay, LOW);
 previousMillis = currentMillis;
}

 else if (digitalRead(3) == LOW && digitalRead(4)== LOW && digitalRead(5)== LOW && digitalRead(6)== LOW && digitalRead(7)== LOW){
 digitalWrite(relay, LOW);
 previousMillis = currentMillis;}
//  if (digitalRead(3) == HIGH && digitalRead(4)== HIGH && digitalRead(5)== HIGH && digitalRead(6)== HIGH && digitalRead(7)== HIGH){
 //crossTime = millis();
}






//
// previousMillis = currentMillis;}
int interval3=1800000;
int interval4=2700000;
int interval5=3600000;

Not on most Arduinos.

Hi
Got correct the problem, now it counts on all inputs.

void loop() {
 Serial.println(millis() / 1000);
 val = analogRead(analogPin);
 val = map (val, 0, 1023, 5000, 30000);

 if (digitalRead(3) == HIGH && millis() - previousMillis > (3000)) {

   digitalWrite(relay, HIGH);
   delay(val * 2);
   digitalWrite(relay, LOW);
   previousMillis = millis();
 }

 if (digitalRead(4) == HIGH && millis() - previousMillis >= 900000) {

   digitalWrite(relay, HIGH);  
   delay(val * 2);
   digitalWrite(relay, LOW);
   previousMillis = millis();
 }
 if (digitalRead(5) == HIGH && millis() - previousMillis >= 1800000) {

   digitalWrite(relay, HIGH);  
   delay(val * 2);
   digitalWrite(relay, LOW);
   previousMillis = millis();
 }
 if (digitalRead(6) == HIGH && millis() - previousMillis >= 2700000) {

   digitalWrite(relay, HIGH);  
   delay(val * 2);
   digitalWrite(relay, LOW);
   previousMillis = millis();
 }
 if (digitalRead(7) == HIGH && millis() - previousMillis >= 3600000) {

   digitalWrite(relay, HIGH);
   delay(val * 2);
   digitalWrite(relay, LOW);
   previousMillis = millis();
 }
if (digitalRead(3) == LOW && digitalRead(4)== LOW && digitalRead(5)== LOW && digitalRead(6)== LOW && digitalRead(7)== LOW){
 digitalWrite(relay, LOW);
 }
}

And you end this topic without learn how to post correctly your code in the forum. Can you please read the forum rules?

  if (digitalRead(3) == HIGH && millis() - previousMillis > (3000)) {

    digitalWrite(relay, HIGH);
    delay(val * 2);
    digitalWrite(relay, LOW);
    previousMillis = millis();
  }

what do you think millis is doing when no button is high?
(maybe you should be resetting previousMillis when the buttons are all low)

also if you are using a number in the argument and the compare is a long then its better to add the capital L after the number so 3000L would be better

delay is confusing but then I have no idea what the program is designed to do.

Hmm okay :slight_smile:

I've tried resetting previousMillis when the buttons are all low, and it just will not count.

The program is designed to run a motor (shakers) to feet wood shavings in to a wood stove
A 3sec timer, to calibrate the relay high/low time with potentiometer (50kohm i now, had no other) from 10sec to 60sec
And timer 15,30,45,60 minutes interval between relay high

I've tried :confused:

if (digitalRead(3) == HIGH && millis() - previousMillis > 3000) {

    digitalWrite(relay, HIGH);
    delay(val * 2);
    digitalWrite(relay, LOW);
    
  }

  if (digitalRead(4) == HIGH && millis() - previousMillis >= 900000) {

    digitalWrite(relay, HIGH);  
    delay(val * 2);
    digitalWrite(relay, LOW);
    
  }
  if (digitalRead(5) == HIGH && millis() - previousMillis >= 1800000) {

    digitalWrite(relay, HIGH);  
    delay(val * 2);
    digitalWrite(relay, LOW);
    
  }
  if (digitalRead(6) == HIGH && millis() - previousMillis >= 2700000) {

    digitalWrite(relay, HIGH);  
    delay(val * 2);
    digitalWrite(relay, LOW);
   
  }
  if (digitalRead(7) == HIGH && millis() - previousMillis >= 3600000) {

    digitalWrite(relay, HIGH);
    delay(val * 2);
    digitalWrite(relay, LOW);
    previousMillis = millis();
  }
if (digitalRead(3) == LOW && digitalRead(4)== LOW && digitalRead(5)== LOW && digitalRead(6)== LOW && digitalRead(7)== LOW){
  digitalWrite(relay, LOW);
  }
}

flimmer1979:
Hmm okay :slight_smile:

I've tried resetting previousMillis when the buttons are all low, and it just will not count.

The program is designed to run a motor (shakers) to feet wood shavings in to a wood stove
A 3sec timer, to calibrate the relay high/low time with potentiometer (50kohm i now, had no other) from 10sec to 60sec
And timer 15,30,45,60 minutes interval between relay high

ok I understand that the pot is being used to control the time the relay is on for the chip feeder. The digital inputs are set by switchs or are you using a button?

judging by your code you have a 2x16 lcd and at least 3 buttons.

wouldn't it be better to have the lcd do all the interface and let the arduino do the settings

screen 1, feeder on/off (change between modes while in edit)
time to next feed (????) (display only)

screen 2 time between feeds 15 to 60 minutes (adjustable)

screen 3 feed run time 3 to 60 seconds (adjustable)

screen 4 feed test (press up button while in edit mode to activate)

3 buttons ( edit, up, down )

there is nothing wrong with what you are doing but its a lot less hardware and wiring to use the lcd as a interface

yes 1 lcd and rotate switch 5 output.
The lcd is used only to tjek millis and val, will not be used when it works, because when it run, it is not necessary to see the timer.

Yes I know it's better to used the lcd, as a menu.
I have only starte learned to program, by read projects on arduino and other websites , change/add code so it fit my projects with try and error.

So i have a long way to go :confused:

ok a few pointers may help especially if the timer is resetting when it shouldn't be able to.

The inputs on the arduino are sensitive to floating voltage so you really need to change the switch wiring and the look at the INPUT_PULLUP example under learning

this means the input pin now reads as a high and you connect the pin to negative to make the arduino sense the input you also change the digitalRead to ==LOW (internally the arduino adds a 10k resistor between the pin and 5v+ when you press the button which connects the pin to ground it drops the voltage to 0 which is a low)

see if you can read and understand this code.

this is not finished code just a different approach that also does away with the delay

this uses INPUT_PULLUP which means the switch will have to be rewired for testing.

// tells the program to ignore what follows it like text. I have // some other parts like the library's for testing.

//include <Wire.h>
//#include <LiquidCrystal_I2C.h>
//LiquidCrystal_I2C lcd(0x27, 16, 2);


int relay = 9;
unsigned long preset = 0;
unsigned long previousMillis = 0;
unsigned long previousMillis2 = 0;
byte feeder = 0;

void setup() {

  Serial.begin(9600);
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);


}


void loop() {

  int val = analogRead(A0);
  val = map(val, 0, 1023, 3000, 6000);

  unsigned long currentMillis = millis();//this stops roll over
  //it happens about every 45 days so you will see lots of code
  //that skips this but its best to add it

  if (digitalRead(3) == LOW) {
    preset = 0;//off
  }
  else if (digitalRead(4) == LOW) {
    preset = (15 * 1000L); //15 mins if times by 60000
  }
  else if (digitalRead(5) == LOW) {
    preset = (30 * 1000L); //30 mins if times by 60000
  }
  else if (digitalRead(6) == LOW) {
    preset = (45 * 1000L); //45 mins if times by 60000
  }
  else if (digitalRead(7) == LOW) {
    preset = (60 * 1000L); //60 mins if times by 60000
  }
  //all of the above preset = 60*1000L must include the L or it gets weird
  //if you dont belive me remove L from 45min time and 45*1000
  //becomes something like 4 million

  Serial.println(preset);//for testing

  if ((preset == 0) || (feeder == 1)) {
    previousMillis = currentMillis;//dont time while it doing its thing or off
  }//this was added so i could shorten the timers for testing which caused one to
  //reset before the other had finnished
  //in real life this might not be required but it does no harm to be here


  //if preset != 0 means its not off then time
  // != means not equal e.g anything other than 0
  //once time is done reset timer
  if (preset != 0 && currentMillis - previousMillis > preset) {
    previousMillis = currentMillis;//reset for next time cycle

    feeder = 1;//tell feeder its time to run
    previousMillis2 = currentMillis;//set feeder time so it starts at 0 time

  }


  if (feeder == 1) {//feeder requested to on
    //timer is backwards so if its not done then its relay high
    //once timer is done relay low and reset feeder to off

    if (currentMillis - previousMillis2 > val) {
      Serial.println("done............................");//hard to see at speed
      feeder = 0;//turn feeder request off
      digitalWrite(relay, LOW);
    } else {
      digitalWrite(relay, HIGH);
      Serial.println("running");//added for testing

    }
  }
}