micros() resetting intermitantly (timer2 being used)

hello, i’m trying to sample a sensor at precisely 1ms intervals. In order to do this, I stole this code (http://popdevelop.com/2010/04/mastering-timer-interrupts-on-the-arduino/) and am running a motor at the same time on another arduino. I’m also trying to print a time stamp at the same time on both MCUs. Here’s the motor code:

////////motor motor motor motor motor motor!!!
#define PWM2 6
#define DIR2 7
#define sync 3

/* Timer2 reload value, globally available */  
unsigned int tcnt2;  
unsigned long initial;

unsigned int t;
unsigned long now;

int duty;
int t_;
unsigned int amp = 125;
unsigned int omega = 250;//in hz

void setup() {
  Serial.begin(115200);
  pinMode(sync,OUTPUT);
  pinMode(DIR2,OUTPUT);
  pinMode(PWM2,OUTPUT);
  /* First disable the timer overflow interrupt while we're configuring */  
  TIMSK2 &= ~(1<<TOIE2);  
//      
//  /* Configure timer2 in normal mode (pure counting, no PWM etc.) */  
  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));  
  TCCR2B &= ~(1<<WGM22);  
//      
//  /* Select clock source: internal I/O clock */  
  ASSR &= ~(1<<AS2);  
//      
//  /* Disable Compare Match A interrupt enable (only want overflow) */  
  TIMSK2 &= ~(1<<OCIE2A);  
//      
  /* Now configure the prescaler to CPU clock divided by 128 */  
  TCCR2B |= (1<<CS22)  | (1<<CS20); // Set bits  
  TCCR2B &= ~(1<<CS21);             // Clear bit  
//
  tcnt2 = 131;    
  /* Finally load end enable the timer once the sync pin goes high*/  
  while (analogRead(5)!=0){}
  digitalWrite(sync,1);
  initialize();
}  

void loop() {}   //everything within interrupt  

void initialize(){
  TCNT2 = tcnt2;  
  TIMSK2 |= (1<<TOIE2); 
  initial = micros();
}
//
ISR(TIMER2_OVF_vect) {  
  /* Reload the timer */  
  TCNT2 = tcnt2;

  duty = round(amp*sin((2*PI/omega)*t));
  
  if (duty>0){
    digitalWrite(DIR2,1); 
  }
  else{
    digitalWrite(DIR2,0); 
  }
  analogWrite(PWM2,abs(duty));
  t++;
  now = micros();
  Serial.print(initial,DEC);
  Serial.print("   ");
  Serial.print(now,DEC);
  Serial.print("   ");
  Serial.print(now-initial,DEC);
  Serial.print("   ");
  Serial.println(duty,DEC);
  initial=now;
}

In short, the code is waiting for a button press with the while(analogRead(5)!=0){} then sending a signal to get the other arduino synched up at the same time then running the motor with the sine curve. Everything seems to work ok but in checking with the timestamp, i’m getting something weird:

0   816044   816044   0
816044   816768   724   3
816768   816872   104   6
816872   816972   100   9
816972   817068   96   13
817068   817096   28   16
817096   817116   20   19
817116   817140   24   22
817140   816136   4294966292   25
816136   816428   292   28
816428   816608   180   31
816608   816788   180   34
816788   816968   180   37
816968   817144   176   40
817144   816296   4294966448   43
816296   816588   292   46
816588   816764   176   49
816764   816944   180   52
816944   817120   176   55
817120   816272   4294966448   57
816272   816564   292   60
816564   816744   180   63
816744   816920   176   66
816920   817100   180   68
817100   816260   4294966456   71
816260   816552   292   73
816420   816736   316   76
816736   816916   180   78
816916   817096   180   81
817096   816252   4294966452   83
816252   816548   296   86
816548   816728   180   88
816728   816912   184   90
816912   817092   180   92
817092   816252   4294966456   94
816252   816548   296   96
816548   816732   184   98...

as you can see it is going backward every so often overflowing the unsigned long being used to store the value. Can anyone please help?

as i understand it, my timer, utilizing timer2, should not upset the micros() function which uses timer0 according to this http://www.mythic-beasts.com/~markt/ATmega-timers.html

any help would be greatly appreciated.

thanks

Interrupt service routines are supposed to be fast. What that really means is FAST!

Serial.print() with all the crap you are printing is anything but fast. What is likely happening is that you are still printing stuff when the interrupt fires again.

  while (analogRead(5)!=0){}

Why do you have a digital switch attached to an analog pin?

i know the switch is stupid, right?! it's built into a screw terminal shield that i have from DFRobot (i got it from my school lol)

so you are saying its fast...do you think that is screwing up the timer or is it just not having enough time to print? I guess what i'm getting at is should i look into another way to log my data rather than a serial output? I didnt think this was the pinch point cause it seems to work some of the time. Also, can you suggest a way that might be faster? i was thinking of looking into a microSD shield or some such thing to log the data (namely the one from LadyAda). I just want to be sure that something like that is faster than the normal Serial.print command.

Thanks so much for the reply!

You're sitting at home, reading a book. The doorbell rings. You can go answer the door, and invite the person in, or you can talk to them in the doorway.

If you invite them in, you can deal with the doorbell if it rings again.

If you stand there in the doorway dealing with them, and someone else arrives and rings the doorbell, you are kind of stuck.

The serial printing you are doing in the ISR is like dealing with the person in the doorway.

Setting a flag, telling loop it needs to do something, is like inviting them in. You still have to deal with them, but not necessarily before the next person/interrupt arrives.

Its like a parable. Thanks for your patience, PaulS. I'm going to give that a shot later this afternoon. So i guess when an ISR triggers it basically pauses the code just long enough to run the ISR code, right? Just trying to get my head wrapped around this stuff and trying something new on my arduino always proves a daunting task.

I'll post my results later on. Again, thank you!

So i guess when an ISR triggers it basically pauses the code just long enough to run the ISR code, right?
Yes. The problem, as you can see, comes when the code does not finish before another interrupt occurs.

PaulS:
If you stand there in the doorway dealing with them, and someone else arrives and rings the doorbell, you are kind of stuck.

Especially if you don’t happen to notice them arriving while you are standing at the door. :stuck_out_tongue:

you guys are fantastic, thanks! i'm, going to try to populate a buffer array and just output it bit by bit within the loop(). hopefully that will work since i don't think the arduino has enough memory to store all the variables for long. Didn't get a chance to test it out yet though, but i'll be sure to post my results once i get it all coded up.

ok…sorry for testing this so late, but still having issues. I tried to implement what PaulS was talking about by printing everything from a buffer array (two actually) within void loop() rather than from within the isr routine. Here’s what i have (the isr printing was implemented after i had noticed that i had a problem):

#define PWM2 6
#define DIR2 7
#define sync 3

#define b_size 50
/* Timer2 reload value, globally available */  
unsigned int tcnt2;  
//timestamp variables
unsigned long initial;
unsigned int t;
unsigned long now;
unsigned long last = 0;
//buffer variables
unsigned long t_buffer_a[3][b_size], t_buffer_b[3][b_size];
unsigned int d_buffer_a[b_size], d_buffer_b[b_size];
bool loop_toggle=0;
bool isr_toggle=0;
unsigned int loop_i;
unsigned int isr_i;

int duty;
unsigned int amp = 125;
unsigned int omega = 250;//in hz

void setup() {
  Serial.begin(115200);
  pinMode(sync,OUTPUT);
  pinMode(DIR2,OUTPUT);
  pinMode(PWM2,OUTPUT);
  /* First disable the timer overflow interrupt while we're configuring */  
  TIMSK2 &= ~(1<<TOIE2);  
//      
//  /* Configure timer2 in normal mode (pure counting, no PWM etc.) */  
  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));  
  TCCR2B &= ~(1<<WGM22);  
//      
//  /* Select clock source: internal I/O clock */  
  ASSR &= ~(1<<AS2);  
//      
//  /* Disable Compare Match A interrupt enable (only want overflow) */  
  TIMSK2 &= ~(1<<OCIE2A);  
//      
  /* Now configure the prescaler to CPU clock divided by 128 */  
  TCCR2B |= (1<<CS22)  | (1<<CS20); // Set bits  
  TCCR2B &= ~(1<<CS21);             // Clear bit  
//
  tcnt2 = 131;    
  /* Finally load end enable the timer once the sync pin goes high*/  
//  while (analogRead(5)!=0){}
  digitalWrite(sync,1);
  initialize();
}  

void loop() {
  if (loop_toggle==0 && isr_toggle==1){
    for(loop_i=0; loop_i<b_size-1; loop_i++){
      Serial.print(d_buffer_a[loop_i],DEC);//junk
      Serial.print("      ");
      Serial.print(t_buffer_a[1][loop_i],DEC);//junk
      Serial.print("      ");
      Serial.print(t_buffer_a[2][loop_i],DEC);//junk
      Serial.print("      ");
      Serial.println(t_buffer_a[3][loop_i],DEC);//junk
    }
    loop_toggle==1;
  }
  
  else if (loop_toggle==1 && isr_toggle==0){
    for(loop_i=0; loop_i<b_size-1;loop_i++){
      Serial.print(d_buffer_b[loop_i],DEC);//junk
      Serial.print("      ");
      Serial.print(t_buffer_b[1][loop_i],DEC);//junk
      Serial.print("      ");
      Serial.print(t_buffer_b[2][loop_i],DEC);//junk
      Serial.print("      ");
      Serial.println(t_buffer_b[3][loop_i],DEC);//junk
    }
  loop_toggle==0;
  }
}  

void initialize(){
  TCNT2 = tcnt2;  
  TIMSK2 |= (1<<TOIE2); 
  initial = micros();
}
//
ISR(TIMER2_OVF_vect) {  
  /* Reload the timer */  
  TCNT2 = tcnt2;
  duty = round(amp*sin((2*PI/omega)*t));
  //set direction pin
  if (duty>0){
    digitalWrite(DIR2,1); 
  }
  else{
    digitalWrite(DIR2,0); 
  }
  analogWrite(PWM2,abs(duty));
  now = micros();
  
  if (isr_i==b_size && isr_toggle==0) {
    isr_toggle=1;
    isr_i=0;
  }
  else if (isr_i==b_size && isr_toggle==1) {
    isr_toggle=0;
    isr_i=0;
  }
  
  //time and duty buffered storage
  if (isr_toggle==0){
    t_buffer_a[1][isr_i] = now;
    t_buffer_a[2][isr_i] = now-initial; 
    t_buffer_a[3][isr_i] = now-last;
    d_buffer_a[isr_i] = duty;
  }
  else if (isr_toggle==1){
    t_buffer_b[1][isr_i] = now;
    t_buffer_b[2][isr_i] = now-initial; 
    t_buffer_b[3][isr_i] = now-last;
    d_buffer_b[isr_i] = duty;
  }
  Serial.print(t,DEC);//junk
  Serial.print(" **** ");
  Serial.print(isr_toggle,DEC);//junk
  Serial.print(" **** ");
  Serial.print(isr_i,DEC);//junk
  Serial.print(" **** ");
  Serial.println(loop_toggle,DEC);//junk
  t++;
  isr_i++;
}

i’m filling one array then the other then switching back in the isr and if an array is full i’m printing it from within loop() i hope that is clear. The issue arises because it doesnt seem to be getting into loop(). Here’s my output from this (notice the stars indicate an output from the isr NOT loop):

0 **** 0 **** 0 **** 0
1 **** 0 **** 1 **** 0
2 **** 0 **** 2 **** 0
3 **** 0 **** 3 **** 0
4 **** 0 **** 4 **** 0
5 **** 0 **** 5 **** 0
6 **** 0 **** 6 **** 0
7 **** 0 **** 7 **** 0
8 **** 0 **** 8 **** 0
9 **** 0 **** 9 **** 0
10 **** 0 **** 10 **** 0
11 **** 0 **** 11 **** 0
12 **** 0 **** 12 **** 0
13 **** 0 **** 13 **** 0
14 **** 0 **** 14 **** 0
15 **** 0 **** 15 **** 0
16 **** 0 **** 16 **** 0
17 **** 0 **** 17 **** 0
18 **** 0 **** 18 **** 0
19 **** 0 **** 19 **** 0
20 **** 0 **** 20 **** 0
21 **** 0 **** 21 **** 0
22 **** 0 **** 22 **** 0
23 **** 0 **** 23 **** 0
24 **** 0 **** 24 **** 0
25 **** 0 **** 25 **** 0
26 **** 0 **** 26 **** 0
27 **** 0 **** 27 **** 0
28 **** 0 **** 28 **** 0
29 **** 0 **** 29 **** 0
30 **** 0 **** 30 **** 0
31 **** 0 **** 31 **** 0
32 **** 0 **** 32 **** 0
33 **** 0 **** 33 **** 0
34 **** 0 **** 34 **** 0
35 **** 0 **** 35 **** 0
36 **** 0 **** 36 **** 0
37 **** 0 **** 37 **** 0
38 **** 0 **** 38 **** 0
39 **** 0 **** 39 **** 0
40 **** 0 **** 40 **** 0
41 **** 0 **** 41 **** 0
42 **** 0 **** 42 **** 0
43 **** 0 **** 43 **** 0
44 **** 0 **** 44 **** 0
45 **** 0 **** 45 **** 0
46 **** 0 **** 46 **** 0
47 **** 0 **** 47 **** 0
48 **** 0 **** 48 **** 0
49 **** 0 **** 49 **** 0
50 **** 1 **** 0 **** 0
51 **** 1 **** 1 **** 0
52 **** 1 **** 2 **** 0
53 **** 1 **** 3 **** 0
54 **** 1 **** 4 **** 0
55 **** 1 **** 5 **** 0
56 **** 1 **** 6 **** 0
57 **** 1 **** 7 **** 0
58 **** 1 **** 8 **** 0
59 **** 1 **** 9 **** 0
60 **** 1 **** 10 **** 0
61 **** 1 **** 11 **** 0
62 **** 1 **** 12 **** 0
63 **** 1 **** 13 **** 0
64 **** 1 **** 14 **** 0
65 **** 1 **** 15 **** 0
66 **** 1 **** 16 **** 0
67 **** 1 **** 17 **** 0
68 **** 1 **** 18 **** 0
69 **** 1 **** 19 **** 0
70 **** 1 **** 20 **** 0
71 **** 1 **** 21 **** 0
72 **** 1 **** 22 **** 0
73 **** 1 **** 23 **** 0
74 **** 1 **** 24 **** 0
75 **** 1 **** 25 **** 0
76 **** 1 **** 26 **** 0
77 **** 1 **** 27 **** 0
78 **** 1 **** 28 **** 0
79 **** 1 **** 29 **** 0
80 **** 1 **** 30 **** 0
81 **** 1 **** 31 **** 0
82 **** 1 **** 32 **** 0
83 **** 1 **** 33 **** 0
84 **** 1 **** 34 **** 0...

as you can see i’m not printing ANYTHING from the loop routine. Is it running too fast to be able to loop anything? you can see that i’m using micros() so its running at one ms per isr trigger and populating four vectors as it loops (i in d_buffer for the duty cycle and 3 in t_buffer for the time stamps)

again, thanks for all your help before and sorry for getting back to you later than i had hoped!

sorry the code got a little convoluted! I wanted to make sure that loop() was ONLY printing if the array was fully populated and that the isr was counting to the end of the array then resetting and switching to the other array. If there is a better way to do this, i’d love to know. Thanks!

Don't print from the ISR. Period.

Then evaluate what is happening. Printing all that stuff will take a significant amount of time. Then when you finally leave the ISR, the timer will fire again and you will be back in it.

before i wasnt printing from isr and the code wasnt getting into loop(). When i was doing it that way i got no output at all. I dont know how to force it into the loop so i cant debug it. When the flags are set as the are (showing in the isr output) it should print stuff from within loop(). Is there something you can suggest on how to do this? I'd love not printing within isr, but if i dont, nothing shows in serial monitor.

Show the code, that doesn't print from the ISR, that doesn't (appear to) print from loop. What is the timer period BTW? Save me working it out from all those bit patterns.

In this code:

void loop() {
  if (loop_toggle==0 && isr_toggle==1){
    for(loop_i=0; loop_i<b_size-1; loop_i++){
      Serial.print(d_buffer_a[loop_i],DEC);//junk
      Serial.print("      ");
      Serial.print(t_buffer_a[1][loop_i],DEC);//junk
      Serial.print("      ");
      Serial.print(t_buffer_a[2][loop_i],DEC);//junk
      Serial.print("      ");
      Serial.println(t_buffer_a[3][loop_i],DEC);//junk
    }
    loop_toggle==1;
  }

What do you think this is doing:

    loop_toggle==1;

?

I dont know how to force it into the loop so i cant debug it.

It always goes into loop. You don't force it there. Your problem is the way loop is written.

:fearful: ok, i apologize. The period is 1ms but i just commented out all the serial prints that are in the isr to show the nonworking code and it seems to work or at least output something which is more than it was doing before. I think that once i had the excess code in the isr it was just too much for it to even get to loop. Sorry about that like i said i only added that cause it didnt seem to be working but as it seems to be working now, i'm gonna check out what i have going now. Sorry about that!

oh yeah, i didnt see that. thanks!

You still need to fix:

    loop_toggle==1;

...

    loop_toggle==0;

ok, i fixed all the things you mentioned along with changing the array storing the duty cycle so that it is signed rather than unsigned (sine curve) and its giving me what seems to be random numbers on every other output or so. I’ll post my code, but i’m going to look at it a little. I hate to barrage you all with questions too much…

////////motor motor motor motor motor motor!!!
#define PWM2 6
#define DIR2 7
#define sync 3

#define b_size 50
/* Timer2 reload value, globally available */  
unsigned int tcnt2;  
//timestamp variables
unsigned long initial;
unsigned int t;
unsigned long now;
unsigned long last = 0;
//buffer variables
unsigned long t_buffer_a[3][b_size], t_buffer_b[3][b_size];
int d_buffer_a[b_size], d_buffer_b[b_size];
bool loop_toggle=0;
bool isr_toggle=0;
unsigned int loop_i;
unsigned int isr_i;

int duty;
unsigned int amp = 125;
unsigned int omega = 250;//in hz

void setup() {
  Serial.begin(115200);
  pinMode(sync,OUTPUT);
  pinMode(DIR2,OUTPUT);
  pinMode(PWM2,OUTPUT);
  /* First disable the timer overflow interrupt while we're configuring */  
  TIMSK2 &= ~(1<<TOIE2);  
//      
//  /* Configure timer2 in normal mode (pure counting, no PWM etc.) */  
  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));  
  TCCR2B &= ~(1<<WGM22);  
//      
//  /* Select clock source: internal I/O clock */  
  ASSR &= ~(1<<AS2);  
//      
//  /* Disable Compare Match A interrupt enable (only want overflow) */  
  TIMSK2 &= ~(1<<OCIE2A);  
//      
  /* Now configure the prescaler to CPU clock divided by 128 */  
  TCCR2B |= (1<<CS22)  | (1<<CS20); // Set bits  
  TCCR2B &= ~(1<<CS21);             // Clear bit  
//
  tcnt2 = 131;    
  /* Finally load end enable the timer once the sync pin goes high*/  
//  while (analogRead(5)!=0){}
  digitalWrite(sync,1);
  initialize();
}  

void loop() {
  if (loop_toggle==0 && isr_toggle==1){
    for(loop_i=0; loop_i<b_size; loop_i++){
      Serial.print(loop_i,DEC);//junk
      Serial.print("      ");
      Serial.print(d_buffer_a[loop_i],DEC);//junk
      Serial.print("      ");
      Serial.print(t_buffer_a[1][loop_i],DEC);//junk
      Serial.print("      ");
      Serial.print(t_buffer_a[2][loop_i],DEC);//junk
      Serial.print("      ");
      Serial.println(t_buffer_a[3][loop_i],DEC);//junk
    }
    loop_toggle=1;
  }
  
  else if (loop_toggle==1 && isr_toggle==0){
    for(loop_i=0; loop_i<b_size;loop_i++){
      Serial.print(loop_i,DEC);//junk
      Serial.print("      ");
      Serial.print(d_buffer_b[loop_i],DEC);//junk
      Serial.print("      ");
      Serial.print(t_buffer_b[1][loop_i],DEC);//junk
      Serial.print("      ");
      Serial.print(t_buffer_b[2][loop_i],DEC);//junk
      Serial.print("      ");
      Serial.println(t_buffer_b[3][loop_i],DEC);//junk
    }
  loop_toggle=0;
  }
}  

void initialize(){
  TCNT2 = tcnt2;  
  TIMSK2 |= (1<<TOIE2); 
  initial = micros();
}
//
ISR(TIMER2_OVF_vect) {  
  /* Reload the timer */  
  TCNT2 = tcnt2;
  duty = round(amp*sin((2*PI/omega)*t));
  //set direction pin
  if (duty>0){
    digitalWrite(DIR2,1); 
  }
  else{
    digitalWrite(DIR2,0); 
  }
  analogWrite(PWM2,abs(duty));
  now = micros();
  
  if (isr_i==b_size && isr_toggle==0) {
    isr_toggle=1;
    isr_i=0;
  }
  else if (isr_i==b_size && isr_toggle==1) {
    isr_toggle=0;
    isr_i=0;
  }
  
  //time and duty buffered storage
  if (isr_toggle==0){
    t_buffer_a[1][isr_i] = now;
    t_buffer_a[2][isr_i] = now-initial; 
    t_buffer_a[3][isr_i] = now-last;
    d_buffer_a[isr_i] = duty;
  }
  else if (isr_toggle==1){
    t_buffer_b[1][isr_i] = now;
    t_buffer_b[2][isr_i] = now-initial; 
    t_buffer_b[3][isr_i] = now-last;
    d_buffer_b[isr_i] = duty;
  }
  t++;
  isr_i++;
}

its running at 1ms or at least the isr was (should still be since the registers haven’t been changed) here’s the output:

0      -15232      252      252      252
1      0      1308      1044      1308
2      -14236      2312      2048      2312
3      0      3308      3044      3308
4      -13236      4304      4040      4304
5      0      5308      5044      5308
6      -12232      6304      6040      6304
7      0      7300      7036      7300
8      -11232      8300      8036      8300
9      0      9300      9036      9300
10      -10236      10304      10040      10304
11      0      11304      11040      11304
12      -9236      12300      12036      112304
13      37      113308      113044      113308
14      34      114312      114048      114312
15      31      115312      115048      115312
16      28      116308      116044      116308
17      25      117308      117044      117308
18      22      118308      118044      118308
19      19      119312      119048      119312
20      16      120312      120048      120312
21      2      121312      121048      121312
22      30236      122316      122052      122316
23      2      123320      123056      123320
24      31236      124316      124052      124316
25      2      125308      125044      125308
26      32236      126312      126048      126312
27      2      127316      127052      127316
28      -32304      128312      128048      128312
29      2      129308      129044      129308
30      -31296      130312      130048      130312
31      2      131308      131044      131308
32      -30296      132304      132040      232308
33      -52      233308      233044      233308
34      -49      234308      234044      234308
35      -46      235312      235048      235312
36      -43      236308      236044      236308
37      -40      237308      237044      237308
38      -37      238308      238044      238308
39      4      239312      239048      239312
40      8164      240312      240048      240312
41      4      241308      241044      241308
42      9164      242308      242044      242308
43      4      243308      243044      243308
44      10164      244312      244048      244312
45      4      245316      245052      245316
46      11164      246316      246052      246316
47      4      247316      247052      247316
48      12168      248320      248056      248320
49      4      249316      249052      249316
0      13164      250312      250048      7864439
1      4      251312      251048      7929977
2      14168      252316      352052      352316
3      66      353312      353048      353312
4      63      354316      354052      354316
5      60      355316      355052      355316
6      57      356312      356048      356312
7      5      357312      357048      357312
8      -13904      358312      358048      358312
9      5      359312      359048      359312
10      -12900      360316      360052      360316
11      5      361312      361048      361312
12      -11904      362312      362048      362312
13      5      363312      363048      363312
14      -10908      364316      364052      364316
15      5      365316      365052      4286971781
16      -9908      366312      366048      4286906244
17      5      367312      367048      4286840707
18      -8908      368312      368048      4286840707
19      5      369316      369052      4286840707
20      -7904      370320      370056      4286840707
21      5      371316      371052      471316
22      -81      472316      472052      472316
23      -78      473316      473052      473316
24      -76      474320      474056      474320
25      7      475316      475052      475316
26      29560      476316      476052      476316
27      7      477316      477052      477316
28      30564      478312      478048      478312
29      7      479316      479052      479316
30      31564      480312      480048      480312
31      7      481312      481048      481312
32      32560      482312      482048      482312
33      7      483312      483048      483312
34      -31976      484312      484048      484312
35      7      485316      485052      485316
36      -30976      486312      486048      486312
37      7      487312      487048      487312
38      -29972      488312      488048      488312
39      7      489316      489052      7471220
40      -28968      490316      490052      7340145
41      7      491312      591052      591316
42      92      592320      592056      592320
43      9      593320      593056      593320
44      7492      594316      594052      594316
45      9      595320      595056      595320
46      8492      596320      596056      596320
47      9      597316      597052      597316
48      9492      598316      598052      598316...

first thing i noticed was that the second variable, the duty cycle should be a sine curve. When i was outputting it within the isr no problems, but now it seems that only every other variable is valid. Is it possible that i’m outputting both arrays one after the other? Also, the timestamps dont seem quite right. I’m not sure if the problem is in how i’m storing them or outputting them. Still looking into it…

thanks again all!

XD i fixed it. I was writing to a piece of the array that didnt exist and reading one as well. If you look, the t_buffer arrays are 3 tall and i was accessing t_buffer[3] which is beyond the array. Also, i wasnt reinitializing the “last” variable so that i could calculate the difference between “last” and “now”. Thank you so much PaulS and Nick Gammon. Your help was indispensable. Here’s the final code and output:

#define PWM2    6
#define DIR2    7
#define sync    3
#define b_size  50
#define amp     125 //in PWM
#define omega   250 //in hz

/* Timer2 reload value, globally available */  
unsigned int tcnt2;  
//timestamp variables
unsigned long initial;
unsigned int t;
unsigned long now;
unsigned long last = 0;
//buffer variables
unsigned long t_buffer_a[3][b_size], t_buffer_b[3][b_size];
int d_buffer_a[b_size], d_buffer_b[b_size];
bool loop_toggle=0;
bool isr_toggle=0;
unsigned int loop_i;
unsigned int isr_i;

int duty;

void setup() {
  Serial.begin(115200);
  pinMode(sync,OUTPUT);
  pinMode(DIR2,OUTPUT);
  pinMode(PWM2,OUTPUT);
  /* First disable the timer overflow interrupt while we're configuring */  
  TIMSK2 &= ~(1<<TOIE2);  
//      
//  /* Configure timer2 in normal mode (pure counting, no PWM etc.) */  
  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));  
  TCCR2B &= ~(1<<WGM22);  
//      
//  /* Select clock source: internal I/O clock */  
  ASSR &= ~(1<<AS2);  
//      
//  /* Disable Compare Match A interrupt enable (only want overflow) */  
  TIMSK2 &= ~(1<<OCIE2A);  
//      
  /* Now configure the prescaler to CPU clock divided by 128 */  
  TCCR2B |= (1<<CS22)  | (1<<CS20); // Set bits  
  TCCR2B &= ~(1<<CS21);             // Clear bit  
//
  tcnt2 = 131;    
  /* Finally load end enable the timer once the sync pin goes high*/  
//  while (analogRead(5)!=0){}
  digitalWrite(sync,1);
  initialize();
}  

void loop() {
  if (loop_toggle==0 && isr_toggle==1){
    for(loop_i=0; loop_i<b_size; loop_i++){
      Serial.print(d_buffer_a[loop_i],DEC);//junk
      Serial.print("      ");
      Serial.print(t_buffer_a[0][loop_i],DEC);//junk
      Serial.print("      ");
      Serial.print(t_buffer_a[1][loop_i],DEC);//junk
      Serial.print("      ");
      Serial.println(t_buffer_a[2][loop_i],DEC);//junk
    }
    loop_toggle=1;
  }
  
  else if (loop_toggle==1 && isr_toggle==0){
    for(loop_i=0; loop_i<b_size;loop_i++){
      Serial.print(d_buffer_b[loop_i],DEC);//junk
      Serial.print("      ");
      Serial.print(t_buffer_b[0][loop_i],DEC);//junk
      Serial.print("      ");
      Serial.print(t_buffer_b[1][loop_i],DEC);//junk
      Serial.print("      ");
      Serial.println(t_buffer_b[2][loop_i],DEC);//junk
    }
  loop_toggle=0;
  }
}  

void initialize(){
  TCNT2 = tcnt2;  
  TIMSK2 |= (1<<TOIE2); 
  initial = micros();
}
//
ISR(TIMER2_OVF_vect) {  
  /* Reload the timer */  
  TCNT2 = tcnt2;
  now = micros();
  duty = round(amp*sin((2*PI/omega)*t));
  //set direction pin
  if (duty>0){
    digitalWrite(DIR2,1); 
  }
  else{
    digitalWrite(DIR2,0); 
  }
  analogWrite(PWM2,abs(duty));
  
  if (isr_i==b_size && isr_toggle==0) {
    isr_toggle=1;
    isr_i=0;
  }
  else if (isr_i==b_size && isr_toggle==1) {
    isr_toggle=0;
    isr_i=0;
  }
  
  //time and duty buffered storage
  if (isr_toggle==0){
    t_buffer_a[0][isr_i] = now;
    t_buffer_a[1][isr_i] = now-initial; 
    t_buffer_a[2][isr_i] = now-last;
    d_buffer_a[isr_i] = duty;
  }
  else if (isr_toggle==1){
    t_buffer_b[0][isr_i] = now;
    t_buffer_b[1][isr_i] = now-initial; 
    t_buffer_b[2][isr_i] = now-last;
    d_buffer_b[isr_i] = duty;
  }
  
  t++;
  isr_i++;
  last=now;
}

and output:

0      124      124      124
3      1124      884      1000
6      2124      1884      1000
9      3124      2884      1000
13      4124      3884      1000
16      5128      4888      1004
19      6132      5892      1004
22      7132      6892      1000
25      8132      7892      1000
28      9132      8892      1000
31      10132      9892      1000
34      11132      10892      1000
37      12132      11892      1000
40      13132      12892      1000
43      14132      13892      1000
46      15132      14892      1000
49      16132      15892      1000
52      17132      116908      1000
22      118148      117908      1000
19      119148      118908      1000
16      120148      119908      1000
13      121148      120908      1000
9      122148      121908      1000
6      123148      122908      1000
3      124148      123908      1000
0      125148      124908      1000
-3      126148      125908      1000
-6      127148      126908      1000
-9      128148      127908      1000
-13      129148      128908      1000
-16      130148      129908      1000
-19      131148      130908      1000
-22      132148      131908      1000
-25      133148      132908      1000
-28      134152      133912      1004
-31      135156      134916      1004
-34      136156      135916      1000
-37      137156      136916      1000
-40      138156      137916      1000
-43      139156      138916      1000
-46      140156      139916      1000
-49      141156      140916      1000
-52      142156      141916      1000
-55      143156      142916      1000
-57      144156      143916      1000
-60      145156      144916      1000
-63      246172      245932      1000
-9      247172      246932      1000
-6      248172      247932      1000
-3      249172      248932      1000
0      250172      249932      1000
3      251172      250932      1000
6      252172      251932      1000
9      253172      252932      1000
13      254172      253932      1000
16      255172      254932      1000
19      256172      255932      1000
22      257172      256932      1000
25      258172      257932      1000
28      259172      258932      1000
31      260172      259932      1000
34      261172      260932      1000
37      262172      261932      1000
40      263176      262936      1004
43      264180      363956      1000
31      365196      364956      1000
28      366196      365956      1000
25      367196      366956      1000
22      368196      367956      1000
19      369196      368956      1000
16      370196      369956      1000
13      371196      370956      1000
9      372196      371956      1000
6      373196      372956      1000
3      374196      373956      1000
0      375196      374956      1000
-3      376196      375956      1000
-6      377196      376956      1000
-9      378196      377956      1000
-13      379196      378956      1000
-16      380196      379956      1000
-19      381196      380956      1000
-22      382196      381956      1000
-25      383196      382956      1000
-28      384196      383956      1000
-31      385196      384956      1000
-34      386196      385956      1000
-37      387196      386956      1000
-40      388196      387956      1000
-43      389196      388956      1000
-46      390196      389956      1000
-49      391196      390956      1000
-52      392200      391960      1000
-22      493220      492980      1000
-19      494220      493980      1000
-16      495220      494980      1000
-13      496220      495980      1000
-9      497220      496980      1000
-6      498220      497980      1000
-3      499220      498980      1000
0      500220      499980      1000
3      501220      500980      1000
6      502220      501980      1000
9      503220      502980      1000
13      504220      503980      1000
16      505220      504980      1000
19      506220      505980      1000
22      507220      506980      1000
25      508220      507980      1000
28      509220      508980      1000
31      510220      509980      1000
34      511220      510980      1000
37      512220      511980      1000
40      513220      512980      1000
43      514220      614004      1000
31      615244      615004      1000
28      616244      616004      1000
25      617244      617004      1000
22      618244      618004      1000
19      619244      619004      1000
16      620244      620004      1000

one final thing is that the duty cycle (first column of output) doesn't create a good sinusoid. If you look at the output it seems to run nicely to a maximum of 52 (also strange cause amplitude should be 125) then drops off drastically. If the duty cycle is outputted within the isr (i know this is a no-no but for debugging i wanted to make sure it was calculating correctly) it gives me the sinusoid i'm looking for. Furthermore, if i increase the size of the buffer matrices, nothing outputs at all and if i decrease their size, the values that are printed are different. Is it that the loop is running too slow? If this is the case what can i do about it other than slow down the isr. I'm looking into purchasing an SD card writer from adafruit so perhaps that can alleviate some of the issues if it is indeed faster than Serial.print(_).

sorry to keep this going, but i feel like its better than starting another thread. Thanks again.