Noobish question here, but how/what do you store event information in the Arduino code?
I'm using a piezo setup as a 'bonk' sensor. I want to 'record' bonk information. Like pressing a button beings 'recording', then pressing the button again 'plays back' the information.
Not really asking for code here, but more the how of how it's done, so I know what to look up.
Will the write/erase thing be a factor if it's going to be used a lot? I don't think I need the information to stay with the unit when it turns off, although that make for some interesting 'memory' functions of the code, where it changes over time (keeping what's been played, and using that to inform what's recorded next etc..)
Kriista, you just need to cycle a variable through a couple different states. The variable can be stored in RAM, defined like byte playrec = 0;
If you detect a button press, set your variable playrec to '1'. '1' equals "record". You also need to set a variable now that says you have something recorded in memory, say boolean recording = true. If the recording function hits a memory limitation (memory full), or the user presses the "stop" button, the recording function would end and the playrec variable would be set back to '0' to keep the recording function from looping.
If you detect another play/record button press, check to see if the recording variable equals true, and if so set playrec to '2'. '2' equals "play". If the play back function reaches the end of the recording, it would stop playback and set the playrec variable back to '0' to keep the play back function from looping.
You could also set up a function to detect if the play/record button was held down, and if that happened it would set the recording variable to false. Now the next time the play/rec button is pressed, it would set playrec to 1 and do the recording function.
@kriista:
I misunderstood what you wrote. Sorry about that. The EEPROM is not a very good choice (unless you really do want the recorded bonk preserved through a power cycle).
The end goal will be a virtual AI type accompaniment by recording what I'm playing/bonking, then based on the information received, generate a series of bonks back.
I kind of understand the state/button logic, it's more then part of it that 'records' a timeline, and events place in that timeline. Much less without knowing how many events there will be ahead of time.
I just used "bonk" here to mean a tap on a piezo (read it referred to as a 'bonk' elsewhere, so I thought that was the term for it).
The end result will be using Solenoids for playback, so I suppose a bonk is not out of the question. Although unlikely for what I'm trying to do with it.
The first step would be to define precisely what information you want to store. For example, do you need to just record that a 'bonk' took place, or do you need to record the intensity and/or duration of the 'bonk', which in technical terms would be an 'impulse'.
If you want to play back the sequence, then you'll need to record the time at which the bonk began. It would be easy to record the millisecond at which the bonk was first detected, but gets a little more complicated if you want more precise timing than that.
Finally, Arduinos are memory-constrained. The internal memory is going to limit how long a sequence you can record (the amount of information that you record for each bonk will affect this as well). It's also possible to add external memory to an Arduino, but that makes the hardware and software a bit more complicated.
Having said all that, here's an overview of one way to implement it:
While recording
wait for a bonk to occur
when a bonk occurs, store the time (and possibly other info) in memory
While playing back
fetch the next bonk from memory
wait until the elapsed time matches the time stored for the bonk
make a bonk
That doesn't sound too complicated. So it would all be millis based then?
As far as information to store, it's going to be fed back via a Solenoid, so intensity/duration don't matter. Only the timing of the initial 'bonk'.
As far as the memory limitations. Is that something that has to be built into the code, to prevent it from 'running out'?
As far as storing/reading the events. How are the events defined/allocated (sorry if I'm using the wrong terms here). Like in the example you gave, when a bonk occurs, store that time in memory. There could be hundreds of these events. Do they get named? Do I have to define how many I would possibly want?
When it's playing back, what is the 'memory' that it's reading from? I can only picture it (mentally) with each of those events being a variable, but I can't picture that working for an indeterminate amount of events.
That doesn't sound too complicated. So it would all be millis based then?
As far as information to store, it's going to be fed back via a Solenoid, so intensity/duration don't matter. Only the timing of the initial 'bonk'.
As far as the memory limitations. Is that something that has to be built into the code, to prevent it from 'running out'?
As far as storing/reading the events. How are the events defined/allocated (sorry if I'm using the wrong terms here). Like in the example you gave, when a bonk occurs, store that time in memory. There could be hundreds of these events. Do they get named? Do I have to define how many I would possibly want?
When it's playing back, what is the 'memory' that it's reading from? I can only picture it (mentally) with each of those events being a variable, but I can't picture that working for an indeterminate amount of events.
One way to implement something like this is to start simple and work towards the final solution. For example, I would use a push button to simulate a piezo sensor, and an LED to simulate a solenoid. Your first program would record button pushes and play them back by flashing an LED.
As to memory, start with an array:
#define MAX_EVENTS 100
int events_recorded = 0;
unsigned long events[MAX_EVENTS];
You have to be careful not to make MAX_EVENTS too large, because each long will take up four bytes.
When you start recording, save the start time:
unsigned long start_time;
unsigned long now;
start_time = millis();
When an event occurs (button is pushed):
now = millis();
events[events_recorded] = now - start_time; // store elapsed time
start_time = now;
events_recorded = events_recorded + 1;
You will also want to check to make sure that you don't store more than MAX_EVENTS in the array.
To play it back:
for (int i = 0; i < events_recorded; ++i)
{
delay(events[i]); // wait appropriate interval
// flash LED here
}
Once you've got that working, you can get your piezo sensor and solenoid working. You can also work on finding a better way to store events that uses less memory. For example, if the time between events will always be less than 65 seconds, you could use an 'unsigned int' array, which will take up half the space of an 'unsigned long' array.
Thanks for the code clips. At the moment I've been using a simplified setup (piezo code/electronics working fine, but using an LED in place of the solenoid).
The gap between the events would never be over a minute, so I'll try using the unsigned int variable instead.
In a finished application (not that I'm anywhere near that), but would I just compile the basic sketch (no array(?)), and subtract that from the total arduino memory, and make my MAX_EVENTS just under that?