23 martie 2024

Simplyfying the code by using a tic-tac machine

Playing with Arduino and it's C++ I often use timed tasks.

Basically, in Arduino you can do things at specific interval either by adding delay() at some strategic points or using wellknown non-blocking code:

const unsigned long interval = 1000; // Interval for LED blink (in milliseconds)
unsigned long previousMillis = 0;    // Variable to store time since last LED update

int ledPin = 13; // Pin for the LED

void setup() {
                    pinMode(ledPin, OUTPUT); // Initialize LED pin as an output
  }

void loop() {

                  unsigned long currentMillis = millis(); // Get the current time

  // Check if it's time to update the LED
  if (currentMillis - previousMillis >= interval) {
                    previousMillis = currentMillis; // Save the last time LED was updated
                    digitalWrite(ledPin, !digitalRead(ledPin)); // Toggle the LED state
          }

      // Other non-blocking tasks can be added here
}
 
What if, the code need more than one timer?
Well, we  can use multiple timers like that!
While this is the simple and easy way, in a big code we start loosing track of what does what and if the code is big, each byte counts! Let's not forget that  each unsigned long type variable cost us 4 bytes of precious memory; each byte consists of 8 bits, and an unsigned long on Arduino is a 32-bit data type, so it occupies 4 bytes (32 bits / 8 bits per byte = 4 bytes).
I have a program in which I have to test multiple timers with multiple distinct intervals and the memory cost was huge.
So, I stayed and think and found a very elegant solution.
While I may reinvented the wheel, I think it is nice to share it with you!
It is all about making a single time measuring function and asign boolean variables to keep track of various things.
  unsigned long previousMillis_ONESECOND = 0; // Variable to store the last time the ONESECOND was flipped
  const unsigned long interval_ONESECOND = 1000; // Interval at which to flip the ONESECOND (in milliseconds)
    bool ONESECOND = false;

void loop(){
    updateONESECOND(); }

void updateONESECOND(){
          unsigned long currentMillis = millis(); // Get the current time
 
          // Check if it's time to flip ONESECOND
          if (currentMillis - previousMillis_ONESECOND >= interval_ONESECOND) {
            // Save the last time ONESECOND was flipped
            previousMillis_ONESECOND = currentMillis;

           // Flip ONESECOND
            ONESECOND = !ONESECOND;
      }
}
then, I have other functions that check various conditions AND bool.
For example, a function that blink a special character on a LCD: 
 
bool ProcessSTART = false;
 
void fLCD(){  // alternate symbol at a rate of one second while StartLog is activated
            if (ONESECOND && ProcessSTART){
                     printFN_Char();
                            }
                else {
                     printFP_Char();
                }
}

the other bool ProcessSART is flipped in other part of the program.
In other functions you can count the number of seconds using this tic-tac function and get other intervals derived from it, using less bytes in a simple arithmetic function.
It's like using an external time generator for all the functions in the code.

Niciun comentariu:

Most viewed posts in last 30 days