- Published on
[Offside] - A matter of data type and millis
- Authors
- Name
- Tawaliou ALAO
- @Tawal_Mc
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.
Types | range of values | bytes |
---|---|---|
bool | 1 (true/false) | 1 |
byte | 0 to 255 | 1 |
char | -128 to 127 | 1 |
int | -32'768 to 32'767 | 2 |
unsigned int | 0 to 65'535 | 2 |
long | -2'147'483'648 to 2'147'483'647 | 4 |
unsigned long | 0 to 4'294'967'295 | 4 |
float | -3.4028235E38 to -3.4028235E38 | 4 |
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?