Published on

[Offside] - A matter of data type and millis

Authors
When I think about data type in my codes

When I think about data type in my codes - TawalMc with Excalidraw

So we have int, long, char,... as words? no, as data types

Okeuh. And after? Simple we use data types to declare our variables. Something like this (c++):

int position = 10;
float average = 15.3;

And each data type can hold a (a maximum) amount of data (🤪). Each of them has a number of bytes that can be used for storage depending on the target architecture. And when we are in embedded, we have to take care of it. We're not working on computers with GigaBytes as storage, so the bigger our data the more bytes we consume and therefore more space. Also, there are side effects when we don't use the right data types and one of them is data type overflow.

Overflow? Like a water overflowing from a container

You know when water overflows a container, it simply sinks, but the container is just filled to it. No more. This is, let's say, the same thing that happens if your data is bigger than your data types: they get cut-off. So you are trying to store a value of 123456 in int on Arduino, not good.

Recently I worked on project and faced this issue and only my computer knows how much time I take to figure it out.

My Problem: store/get millis value

You know that with Arduino, millis() return the number of milliseconds since the execution of our program... And the best type to store the value returned by millis() is unsigned long. Why? Because, millis() can return a value like 120'000 which is equal to 2 (minutes). So imagine you try to store this value in unsigned int... - [☠️ Sacrilege - 💀 Offense]

Why again? Look at this table that I get from sparkfun website.

Typesrange of valuesbytes
bool1 (true/false)1
byte0 to 2551
char-128 to 1271
int-32'768 to 32'7672
unsigned int0 to 65'5352
long-2'147'483'648 to 2'147'483'6474
unsigned long0 to 4'294'967'2954
float-3.4028235E38 to -3.4028235E384

tips: to calculate the max value that a data type can hold

signed types:
              min = - (2^(bits))/2
              max =   (2^(bits))/2 - 1
so int  ->    min = - (2^(16))/2     = - 32768
              max =   (2^(16))/2 - 1 = 32767

unsigned types:
                    min = 0
                    max = 2^(16) - 1
so unsigned int ->  max = 2^(16) -1  = 65'535

so max(unsigned long) > max(unsigned int) and what I have done it is something like

#define MAX_TIME 120000; // 2 minutes I mean
unsigned int duration_between_req = 0;

void setup() {
  // do stuff
  duration_between_req = millis();
}

void loop() {
  // do stuff

  if (millis() - duration_between_req >= MAX_TIME) {
    // execute an action

    duration_between_req = millis();
  }
}

Guess what happens

This piece of code executes correctly only once. Why does it do that ? Simple:

1- After 02 minutes the expression (millis() - duration_between_req >= MAX_TIME) is true so my code first executes the action and then puts in duration_between_req the value returned by millis() let's say 121'000 so (2minutes+1seconde).

2- But unsigned int cannot hold too much and it cut-off. Welcome to bug hunting!! So after just some seconds , the expression (millis() - duration_between_req >= MAX_TIME) is always true because duration_between_req don't hold all value returned by millis but just truncate it to be less than its maximal value 65'535. And each second (less than 01 second) the program executes the if statement body...

Yes, it's so much fun

I spent at least 30 minutes to understand my code (a code that I write myself) and Arduino IDE doesn't help me either...

And it is not the end, take care of byte yeah the word named byte because if by any kind of rain you store in Arduino EEPROM a data of type int and you try to retrieve it as a long and vice versa, what will happen? What are you hoping for? What magic will happen? Ask your code...

I share some tips that I used in my daily tasks and I hope you've some others tips that you want to share with us. I'm open to advises, and my social accounts (below) are there for this purposes...

So can you smell what TawalMc is cooking?