I have a sensor connected to an Arduino that detects motion throughout the day and records the time that the motion was detected.
I would like to create something like a variable sized array (similar to what may be called a List in C# or an ArrayList in Java or a vector in C++) to keep track of the times throughout the day.
At the end of the day, I want an array of all the times where motion was detected throughout the day. I have no idea how many times motion will be detected. Could be 10 or could be 300. I want an object I can keep adding to.
I fully understand the reasons it might be a bad idea to use a variable sized datatype in an Arduino, so it is not necessary to explain to me the various reasons why it may not be a good idea to do this. Nevertheless I would still like to know how to do it.
Also, without a list/array capable of growing and shrinking, what would be the best way of accomplishing this, short of just making a giant array? What is the cleanest way of doing this without dynamic reallocation?
You seem to have all your own answers and strong opinions, s'ok!
The "how to do it" is fairly straight ahead.
But this is an Arduino. There is no reason not to plan on and account for as many records as you can make fit. You haven't said there's anything competing for memory, so just hand it all to an array. You can still run out of room.
I would think about data logging to a SD card, either one that is directly available to the Arduino or one of the cheap serial logging boards, I think it's Open Log, no need to spend more than $10 and you get practically infinite room.
Also you might want to implement a flurry detector, so you log the beginning and end of activity that is continuous by some definition so you don't get like 30000 records piling up while you are vacuuming or whatever.
Dynamically allocating an array (the only way to make an array of size determined at runtime in C) is a bad idea - while technically possible, you should absolutely not do it on an Arduino. The reason being - stability and predictability. At some point, you will run out of memory, and the sketch will crash. Due to the rudimentary memory management on such low resource microcontrollers, memory fragmentation can make this happen much sooner than you'd expect.
The better design paradigm is to set a maximum number of events to record, and statically allocate an array to fit them. That way, you can make sure you'll have enough memory, and handle the case of events that won't fit in the array gracefully, instead of your sketch crashing when a certain number of events is reached (a number which could change based on operating conditions).
When we program desktop computers, we usually don't need to think about how much memory we're using unless storing lots of data in memory (for example, in engineering simulations, or working with media) - but on an Arduino, you need to be very cognizant of how much memory you're using. An Uno/Nano/ProMini has 2048 BYTES of ram - a desktop computer has a couple of million times more memory.
soh215:
I would like to create something like a variable sized array (similar to what may be called a List in C# or an ArrayList in Java or a vector in C++) to keep track of the times throughout the day.
Also, without a list/array capable of growing and shrinking, what would be the best way of accomplishing this, short of just making a giant array? What is the cleanest way of doing this without dynamic reallocation?
A dynamically allocated linked list would do what you want and is a very standard, common, well-understood method of doing it.
Your data structure consists of a number of items. Each item holds the memory address (a pointer to) the next item. You have two global variables - on holding the memory location of the first item, another holding the memory location of the last item.
To add an entry to the list, you use new to allocate a new item, set the 'next' of that new item to null, set the 'next' of the current end of the list to the new item, and set the current end of the list to the new item. You also need code to handle the case where the list starts off empty (although there are ways to get around having to do that, using double indirection).
To scan down the list, you take a pointer to the first item and loop through the 'next' elements.
There is a great deal of info on "how to make a C++ linked list". There are libraries that implement it, but to learn how you might be better off rolling your own and understanding the code.