Hello everyone,
I'm writing some Arduino code to control a motor to spin at a given frequency every 2 seconds. I'm storing the frequencies in an array (note) and the times it needs to spin for in another array (NoteTimes). It works as expected for the first 3 values in the arrays in the code below but when it reaches the last element, the interrupt takes longer than 2 seconds to move on to the next step (which is stopping the rotation). Any idea how I can solve this?
#include <TimerOne.h>
#include <SPI.h>
#include <SparkFun_MiniGen.h>
int i=0;
volatile float NoteTimes[] = {2,2,2,2};
volatile float note[] ={880, 440, 880, 440};
volatile int noteStatus[]={1,1,1,1};
void playnote(float freq){
}
void setup(void)
{
Timer1.initialize(100000); //1 second
Timer1.attachInterrupt(updateDSS);
Serial.begin(9600);
}
void updateDSS(void)
{
do{
if(noteStatus[i]==1){
playnote(note[i]);
i++;
}
else{
playnote(0);
i++;
}
}while(NoteTimes[i]==0);
Timer1.setPeriod(NoteTimes[i]*1E6);
if(i>((sizeof(NoteTimes)/sizeof(float)))-1){ //if there is nothing else in the array
noInterrupts();
playnote(0);
}
}
void loop(void)
{
}
It seems to me that you have a lot of code in the interrupt. You should minimize this as much as possible
especially the while loop is "killing" the responsiveness of an interrupt.
and please use code tags - see thread how to post code
Thank you for your reply.
My issue is that yes, the while loop is "killing" the responsiveness but the interrupt only causes problems for the last value. The first 3 have no issues and do exactly what I wish them to do.
If you add a fifth note, does the problem still occurs at the 3th note?
Or does it move to the fourth?
No matter how many notes I add, the problems occurs for the last note in the array.
That is an important clue...
in your code you have NoteTimes which is an array but used as an int ?
I think you must use NoteTimes[ i] at some places...
The code you posted in your first message makes no sense. I think there's quite a bit missing. For example:
}while(NoteTimes==0);
NoteTimes is the address of an array and can therefore never be zero.
and
Timer1.setPeriod(NoteTimes*1E6);
the address of an array multiplied by one million isn't going to produce a sensible answer.
I suspect that it should be NoteTimes[i]
Pete
Hi, thanks for spotting that. It might have been an issue with the copying as the original code has those as NoteTimes*. It just did not copy the "i" parts. I have changed that in the code in the first post. The problem still persists though. Also, Timer1.setPeriod takes the time in microseconds as parameter so that explains the large number as it is just a conversion to seconds.*
The posted code cannot work properly, "i" is never reset to 0 and this would cause invalid memory to be accessed. Also it should be obvious that the last element would take longer time since it has more code to execute (what follows the "do..while" loop).
It works as expected
The playnote() function does nothing and you don't light up a LED or otherwise do anything which would give an external indication that anything is "working".
So, you're going to have to explain what "works as expected" means.
Pete