Go Down

Topic: [Solved!] Trying to understand my own working code (Read 161 times) previous topic - next topic

brunopeniche

Sep 20, 2019, 12:10 am Last Edit: Sep 20, 2019, 11:11 pm by brunopeniche
Hey :)

It's been quite a time since I last wrote to the forum. Now that I am finishing my thesis and I am revising my codes and trying again to understand them, I cant actually understandy one about the millis function ahah. To make things worse, I no longer have access to an Arduino, so I can't make experiments with the code, the code is the following:

Code: [Select]
// Solenoid part: 

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  11;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

unsigned long startMillis;
unsigned long currentMillis;
 
// Function part:

float timer;
float volume;
float flow;

void setup() {
 
 Serial.begin(9600);

 Serial.print("Enter volume value: ");
 

 pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  startMillis = millis();  //initial start time

}

void loop() {

   currentMillis = millis();
   buttonState = digitalRead(buttonPin);
 
  if (buttonState == LOW)
  {
    startMillis = currentMillis;
    // turn LED on:
    digitalWrite(ledPin, HIGH);
 }
 
  if (Serial.available()) {
   
    volume = readSerial();

    Serial.print("Enter flow value: ");
    while (!Serial.available());
    flow = readSerial();

    findSide(volume, flow);

    Serial.println();
    Serial.print("Enter volume value: ");
  }

 if (currentMillis - startMillis >= timer)  //test whether the period has elapsed
  {
    // turn LED off:
    digitalWrite(ledPin, LOW);
   
  }
 
    }

  float readSerial()
  {
    float i = Serial.parseFloat();

    Serial.println(i, 4); // The comma and the 4 just represents the number of decimal houses displayed on the serial monitor, it could be changed to whatever we want
    Serial.parseFloat();
    return i;
  }

  void findSide(float x, float y)
  {
    //calculation

    timer = (x / y) * 10000;

    //print out the result
    Serial.print("TIME = ");
    Serial.println(timer);

  }


I wrote that code a few months ago and I wanted to control solenoids (I did experiments first on LEDs) with an equation where I would put the flow rate and the volume and with an simple equation, I would get a time and when I pressed a button, the LED or solenoid would get lighted/open for the time calculated on the equation. The code worked. I just dont understand if this line of code
Code: [Select]
startMillis = millis();  //initial start time is really necessary in the beginning? It doesnt make sense to me.

Thanks guys!!

DangerToMyself

From the reference on millis(): Returns the number of milliseconds passed since the Arduino board began running the current program. This number will overflow (go back to zero), after approximately 50 days.

Basically, your loop is getting the current time
Code: [Select]
currentMillis = millis();

Then it checks if its time to do whatEver
 
Code: [Select]
if (currentMillis - startMillis >= timer)
Which is .... Right Now (currentMillis) - last time Whatever was done (startMillis) >= your interval time (timer)

If it's not, it loops back and gets the current time again and again until its time to do whatEver.

whatEver gets done and startMillis is set to the current time so the code knows the last time whatEver was done.

Clear as mud?

So, yes. It's needed.

brunopeniche

Thank you very much for your answer!

So let me see if I understood it. From the moment I start my Arduino, I got a time that is always counting. When I press the button, the current time equals to the time since the arduino started to work, lets say, 1456 miliseconds. So the current time is 1456 seconds but the time in arduino keeps passing (start millis), so when that subtraction gets equal to the value calculated from the equation, the LED turns off. Oh but if its that way, I have a negative value and doesnt make sense...

Its the other way around?

TheMemberFormerlyKnownAsAWOL

Quote
Oh but if its that way, I have a negative value and doesnt make sense...
millis() returns an unsigned value

Slumpert

Oh but if its that way, I have a negative value and doesnt make sense...
unsigned long startMillis;
unsigned long currentMillis;
The definition of "unsigned" means the variables never go negative.

jremington

#5
Sep 20, 2019, 09:58 pm Last Edit: Sep 20, 2019, 09:59 pm by jremington
Quote
To make things worse, I no longer have access to an Arduino, so I can't make experiments with the code
It is easy to remedy that situation! An Arduino Pro Mini clone costs about $1 on eBay, and they always seem to work.

CrossRoads

And you can always write & compile code without having an Arduino connected.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

brunopeniche

millis() returns an unsigned value
unsigned long startMillis;
unsigned long currentMillis;
The definition of "unsigned" means the variables never go negative.
So my first thought is correct?

Oh yes thank you for remembering that about the unsigned long thing!! But according to my thought, the currentmillis would be the value of miliseconds that the arduino was on when I pressed the button, and the startmillis the value that passed since I pressed the button, even if they are still positive, if the value of the right of the subtraction is bigger than the left one, the final result will be negative ( (+) - (+++) ), or am I wrong? Thats why I askeed if it was the other way around with the startmillis being the value of milisenconds that was the arduino on when I pressed the button and the currentmillis the value of miliseconds that passed since I pressed the button.

 
It is easy to remedy that situation! An Arduino Pro Mini clone costs about $1 on eBay, and they always seem to work.
Thank you!

And you can always write & compile code without having an Arduino connected.
Oh yes! I know a online software, tinkercad. I also used it for 3D printing


I really have to say thank you once again guys!! I will write and make to this forum one of the biggest thank yous in my thesis!!

cattledog

#8
Sep 20, 2019, 10:45 pm Last Edit: Sep 20, 2019, 10:47 pm by cattledog
Quote
startmillis being the value of milisenconds that was the arduino on when I pressed the button
Correct. startmillis takes the value of millis() when you press the button. millis() continues to advance, and startmillis stays at the set value.

Nick Gammon has a good and short tutorial on millis() and subtraction of unsigned long numbers and why you don't have to worry about millis() rollover.

https://www.gammon.com.au/millis

DangerToMyself

with the startmillis being the value of milisenconds that was the arduino on when I pressed the button and the currentmillis the value of miliseconds that passed since I pressed the button.
Nope. currentMillis equals millis(). Which returns the number of millis since the board was last started/reset (and resets to 0 at around 54 days, if memory serves). The result of currentMillis minus startMillis is the value of milliseconds that passed since the button was pressed.


brunopeniche

Correct. startmillis takes the value of millis() when you press the button. millis() continues to advance, and startmillis stays at the set value.

Nick Gammon has a good and short tutorial on millis() and subtraction of unsigned long numbers and why you don't have to worry about millis() rollover.

Nope. currentMillis equals millis(). Which returns the number of millis since the board was last started/reset (and resets to 0 at around 54 days, if memory serves). The result of currentMillis minus startMillis is the value of milliseconds that passed since the button was pressed.


Thanks guys!!!! Completely understood :D

Go Up