Notifications
Clear all

Trouble with millis() why is this not working

24 Posts
4 Users
2 Likes
1,077 Views
DanEvils
(@danevils)
Member
Joined: 2 years ago
Posts: 5
Topic starter  

Working on a DIY project to charge Multiple battery's Lawnmower, Motorcycle etc...  The problem I am Having is the Serial.print only refreshes after relays run through it's loop. board  UNO Rev3 looking it my code Serial.print should refresh "printDelay = 50; the relays are batteryDetectTime = 300; my concept: in a if Control Structure the UNO Rev3 will set relay HIGH a acs712 sensor will detect if battery is connected if "true" it will charge battery if "false" it will go to next relay and I want to print status to a screen (type unknown at this time) I can't have screen refreshing every four min if four battery's are connected

Can  someone point me in the right direction?
#define relay1 2
#define relay2 3
#define relay3 4
#define relay4 5

const int acs712 = A1;     // acs712 Hall effect voltage sensor
int acs712Value = 0;       // analogeRead(acs712) value from sensor
const int valueSet = 510;  // set value for if acs712Value goes above valueSet activatws if comand
                           // and acatvates relays an starts battery chargingg

//____________________________Delay times_____________
const unsigned long ACS712Time = 300;  // Alows time in millis() for acs712 sensor to check if battery has been conected
unsigned long previousTime;            // alowes time in delay() to slows down cycle time thru relays to prevent over heating
const unsigned long batteryDetectTime = 300;  // Alows time in millis() for acs712 sensor to check if battery has been conected
unsigned long previousTime1;                  // alowes time in delay() to slows down cycle time thru relays to prevent over heating
const unsigned long printDelay = 50;  // Alows time in millis() for acs712 sensor to check if battery has been conected
unsigned long previousTime2;          // alowes time in delay() to slows down cycle time thru relays to prevent over heating


const int chargeTime = 2000;  // 3540000;  // battery charging time 59 min
const int restTime = 2000;    // 60000;    // sixity seconds rest for battery charger so it detect battery properties

void setup() {
  Serial.begin(115200);
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(relay4, OUTPUT);
  //analogRead(acs712);/* Map an analog value to 8 bits (0 to 255) */
}


void loop() {
  unsigned long currentTime = millis();
  int acs712Value = analogRead(acs712);
  acs712Value = map(acs712Value, 0, 1023, 0, 255);
  if (currentTime - previousTime1 >= batteryDetectTime) {  // delay(batteryDetect); // alowes time to start acs712 sensor readings
    digitalWrite(relay1, HIGH);
    delay(chargeTime);
    digitalWrite(relay1, LOW);
    delay(restTime);
    digitalWrite(relay2, HIGH);
    delay(chargeTime);
    digitalWrite(relay2, LOW);
    delay(restTime);
    digitalWrite(relay3, HIGH);
    delay(chargeTime);
    digitalWrite(relay3, LOW);
    delay(restTime);
    digitalWrite(relay4, HIGH);
    delay(chargeTime);
    digitalWrite(relay4, LOW);
    delay(restTime);
     previousTime1 = currentTime;
  }
  if (currentTime - previousTime2 >= printDelay) {  // delay(batteryDetect); // alowes time to start acs712 sensor readings
    Serial.println();
    Serial.print("  Current Time   ");
    Serial.println(currentTime);
    Serial.print("  Prvious Time   ");
    Serial.println(previousTime);
    Serial.print("  acs712 Read   ");
    Serial.println(analogRead(acs712));
    Serial.print("  Value Set    ");
    Serial.println(valueSet);
    Serial.print("  ACS712 Analog value   ");
    Serial.println(acs712Value);
    Serial.print("  Sensor Reading   ");
    Serial.println(analogRead(acs712));
    previousTime2 = currentTime;
  }
}


   
Quote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6856
 

@danevils Where is currentTime updated, something like currentTime = millis(); at the bottom of the loop, or simply replace currentTime with millis();

EDIT: never mind, that isn't the problem

EDIT2: The previousTime and previousTime2 need to be set to millis()

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6856
 

Ignore all of that. I think maybe the delay is so short that the print's take longer. Maybe change the wait time and when updating prevTime's use millis() instead of the now old currentTime.

I didn't sleep last night so this could be nonsense.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2042
 

@danevils

So you want to check each battery for a voltage value and if the voltage value of that battery is less then a desired value you want to connect the charger to that battery for a given on time?

Do you have a circuit diagram of your setup?

A clear understanding of what it is supposed to do would make it easy to either fix your code or rewrite it.

 

 


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6856
 

@danevils I wonder if the two analogRead's plus all the other code is longer than the 50/1,000 of a second you have for your delay.

Also, updating the prevTimes should be the first instruction after the if.

I am sure it doesn't matter, but I usually write these kinds of statements as 

Now = millis();

if (Now > NextTime){

  NextTime = Now + delayTime;

  do the timer work

}

you can also replace all the Now's with millis()

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6856
 

@robotbuilder I suspect you like me are concerned with the basic assumptions of this project, but knowing that isn't going to help solve his immediate problem. Later we can discuss his overall design. Good chargers are much more complicated than just measuring voltage, but I have a hunch he wants to learn the hard way. Step 1 get lots of fire insurance. As a starter, I have attached a pic of a FLA charge curve. Each chemistry has it's own curve. My 120 Amp charger for my LiFePO4 battery bank has an app on my phone where I can specify a lot of the parameters, see pic.

Screenshot 2023 02 03 at 13.41.39
IMG 720182DC0626 1

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2507
 

Posted by: @danevils

Working on a DIY project to charge Multiple battery's Lawnmower, Motorcycle etc...  The problem I am Having is the Serial.print only refreshes after relays run through it's loop. board  UNO Rev3 looking it my code Serial.print should refresh "printDelay = 50; the relays are batteryDetectTime = 300; my concept: in a if Control Structure the UNO Rev3 will set relay HIGH a acs712 sensor will detect if battery is connected if "true" it will charge battery if "false" it will go to next relay and I want to print status to a screen (type unknown at this time) I can't have screen refreshing every four min if four battery's are connected

Can  someone point me in the right direction?

It's difficult to grasp what you're asking. As shown, the sketch never uses the ACS712 value and proceeds whether there's anything connected or not.

It then proceeds to check if the battery detect tie has elapsed and then starts a (currently 2 second) timed charge via the appropriate relay for each battery. This cycle requires 4 x (2000+2000) or 16 seconds to complete thereby guaranteeing that the printDelay time will have elapsed and have the results printed every time through the loop.

Furthermore, since you reset previousTime1 and previousTime2 to the time at the START OF THE CURRENT LOOP instead of the value of mills() when the section is completed, you're almost certain to repeat both sections loop after loop.

This will get you started thinking about where you're going wrong. I'd suggest for a start that you isolate the charging of the 4 batteries into a separate code section of the loop for each and use elapsed millis to manage the charging.

Maybe something like at the beginning declaring a boolean and an unsigned long time for each battery like

bool  charging1,charging2,charging3,charging4;
unsigned long charge1Started,charge2Started,charge3Started,charge4Started;

in setup() start everything off with no charging

  charging1 = false;
  charging2 = false;
  charging3 = false;
  charging4 = false;

and then in the loop when you determine that the battery at this relay requires charging 

  //
  //    If conditions are right, start charging battery at relay1
  //
  if ( true ) // <enter conditions which indicate that battery1 needs charging) 
    startCharging(relay1,charging1,charge1Started);

add the following lines to continue the charge cycle as required for each relay at the end of the loop 

  //
  //    Continue charge process if req'd
  //
  charge(relay1,charging1,charge1Started );
  charge(relay1,charging1,charge1Started );
  charge(relay1,charging1,charge1Started );
  charge(relay1,charging1,charge1Started );

and add the following subroutines to handle the details 

//
//    Start the charging process
//
void startCharging(int relayPin, bool &charging, unsigned long &startTime) {
  charging = true;              // Set charging indicator true
  digitalWrite(relayPin,HIGH);  // Close relay to start chagre
  startTime = millis();         // Note time that charge started
}
//
//    Continue charge process
//
void charge(int relayPin, bool &charging, unsigned long startTime) {
  if (charging) {               // Ignore if not charging
    if (millis()-startTime>chargeTime) {
     digitalWrite(relayPin,LOW);// Open relay and stop charging
    }
    if (millis()-startTime>(chargeTime+restTime)) {
     charging = false;          // Charge and rest cycle complete
    }
  }
}

 

 

 

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2507
 

Posted by: @will

add the following lines to continue the charge cycle as required for each relay at the end of the loop 

  //
  //    Continue charge process if req'd
  //
  charge(relay1,charging1,charge1Started );
  charge(relay1,charging1,charge1Started );
  charge(relay1,charging1,charge1Started );
  charge(relay1,charging1,charge1Started );

 

 

Mea culpa.

I got carried away and forgot to change this section, each line should relate to items 1 to 4 not just 1 repeated 4 times, so each line will be different as in ... for N=1,2,3 and 4

charge( relayN,chargingN,chargeNStarted );

 

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2042
 

@zander 

 

@robotbuilder I suspect you like me are concerned with the basic assumptions of this project, but knowing that isn't going to help solve his immediate problem.

 

No point solving a problem if the code doesn't do what is required in the first place.

I just can't get enthusiasm trying to figure out what might be going on when I don't have the complete picture.

While looking at the code many questions arose and from past experience I can see many posts to come with guess what is going on,  here is another clue.  Of course smarter members might just see it all and problem solved.

So I have to use my imagination. Maybe this is what the circuit looks like?

To enlarge image, right click image and choose Open link in new window.

circuit

I would then think about the algorithm and would write it in pseudo code.

 

LOOP
FOR N = 1 to 4
   TURN ON RELAY N
   IF SENSOR > 0 THEN  // BATTERY CONNECTED
      IF SENSOR > MAX THEN  // BATTERY NOT FULLY CHARGED TOO MUCH CURRENT FLOW
         LEAVE RELAY ON FOR x SECONDS
      END IF
   END IF
   TURN OFF RELAY N
NEXT N
END LOOP

 


   
DanEvils reacted
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6856
 

@robotbuilder He has issues with the code that @will did a good job of documenting, so that was step 1. As far as circuitry, the code tells me he is so far from reality when it comes to charging that I think we may be speaking a foreign language. A good 3 or 4-stage charger needs circuitry to produce specific voltages at certain times depending on the chemistry, as well it must also have the ability to produce certain currents at the right time. If these are car sized batteries, the full charging cycle is many hours long, if Lithium it is shorter but still hours. This means his mention of 50msecs and 300msecs is so far from reality I wonder if I am misinterpreting what is happening. Then there is the safety aspects, make a mistake with these devices and fire and explosion are common.

I am including a FLA charge curve to put things into perspective. Notice the X axis is hours and it goes up to 12. For his lawnmower and motorcycle batteries, that would likely be reduced to somewhere between 4 and 6 but simply impossible to have constant on for a few seconds then off type of behaviour, it could damage the battery.

Screenshot 2023 02 03 at 13.41.39

 

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2042
 

@zander 

 

He has issues with the code that @will did a good job of documenting,

 

Yes I could see the issues. Ok. I will back off and let you and @will fix it 🙂

 

 

 


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6856
 

@robotbuilder I think fix is the wrong word, I suspect design and build is more likely UNLESS this entire project is not what he makes it sound like, namely a multi-battery charger. over 99% of the hardware and software is missing.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
DanEvils
(@danevils)
Member
Joined: 2 years ago
Posts: 5
Topic starter  

@robotbuilder Thank you for your help

your image shows exactly what's going on.

 to answer you questions:

The battery's are lead acid from a riding mower, motor cycle and a couple of the kids toys.

the battery charger is a 12volt 1amp with a battery maintainer cycle and overcharge protection.

the ideal is to keep battery charge over the winter months to prevent discharging, freezing and damage.

now using the UNO Rev3 to cycle the relays is no different than going out to the garage and moving the battery cables from one battery to the next every hour  example code " chargeTime = 2000;  // 3540000; = 59 minutes witch can be adjusted to improve performance.

the acs712 sensor hasn't been written in yet because I'm in the process of rewrite the to solve  problems, but acs7i2 will have it own 'if control structure" one to read if battery is present to charge or skip and two to read  amperage, voltage Etc.. later in the build

I just cant figure out why Serial.print  only refresh after the relay's run through one cycle.  I haven't had a chance to review other comment yet.

Thank you

Dan Evilsizor

 


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2042
 

@danevils 

 

I just cant figure out why Serial.print  only refresh after the relay's run through one cycle.

 

The relays have to run through their cycle before the Serial print section is executed because everything stops during a delay() except of course the time  if that is what you mean?

I noticed that the variable previousTime is printed but I don't see it being used?

 

 


   
ReplyQuote
DanEvils
(@danevils)
Member
Joined: 2 years ago
Posts: 5
Topic starter  

I would like to thank every one who responded to my question. it's going to take a minute or two to go through your response's.

I'm currently rewriting the sketch trying to solve one problem at a time.

robotBuilder  has a diagram of my project 


   
ReplyQuote
Page 1 / 2