Re: Sampling frequency and interfacing with matlab

I am currently doing a very similar task.
One way would be to copy the data from the serial monitor into notepad then read the text file into Matlab.
I am trying to use a timer interrupt to sample a digital sensor which is proving to be more work than I anticipated.
Here is my code I am using. I am experiencing problems with it freezing up the arduino IDE as soon as I open the serial monitor. So it doesn’t work, but this is the way I would go about sampling data. That is, taking in data at a known frequency which in this case is 8kHz.

//storage variables
volatile boolean toggle1 = 0;

void setup(){
  
  //set pins
  Serial.begin(115200);
  pinMode(13, INPUT);

cli();//stop interrupts

//set timer2 interrupt at 8kHz
  TCCR2A = 0;// set entire TCCR2A register to 0
  TCCR2B = 0;// same for TCCR2B
  TCNT2  = 0;//initialize counter value to 0
  // set compare match register for 8khz increments
  OCR2A = 249;// = (16*10^6) / (8000*8) - 1 (must be <256)
  // turn on CTC mode
  TCCR2A |= (1 << WGM21);
  // Set CS21 bit for 8 prescaler
  TCCR2B |= (1 << CS21);   
  // enable timer compare interrupt
  TIMSK2 |= (1 << OCIE2A);


sei();//allow interrupts
  
ISR(TIMER2_COMPA_vect){//reads digital pin
    
    toggle1 = digitalRead(0);
    
}


void loop(){
  //do other things here
  Serial.write(toggle1);
}

printing only the changes to matlab and let matlab add the timestamp gives far less communication overhead.

volatile boolean toggle1 = 0;
volatile boolean previous = 1;

...

void loop()
{
  if (toggle1 != previous)
  {
    previous = toggle1;
    Serial.write(toggle1);
  }
}

give it a try

Hello,
I am trying to sample a digital signal at a minimum of 8kHz and be able to communicate it to the computer. Does anyone have any code or suggestions for this? I am currently trying to use this code below but it locks up every time I run it. Any help would be appreciated.

//storage variables
volatile boolean state = 0;

void setup(){
  
  //set pins as outputs
  pinMode(13, INPUT);
 Serial.begin(115200);

cli();//stop interrupts

//set timer2 interrupt at 8kHz
  TCCR2A = 0;// set entire TCCR2A register to 0
  TCCR2B = 0;// same for TCCR2B
  TCNT2  = 0;//initialize counter value to 0
  // set compare match register for 8khz increments
  OCR2A = 249;// = (16*10^6) / (8000*8) - 1 (must be <256)
  // turn on CTC mode
  TCCR2A |= (1 << WGM21);
  // Set CS21 bit for 8 prescaler
  TCCR2B |= (1 << CS21);   
  // enable timer compare interrupt
  TIMSK2 |= (1 << OCIE2A);


sei();//allow interrupts

}//end setup


  
ISR(TIMER2_COMPA_vect){//timer1 interrupt 8kHz reads pin 13.    
    state = digitalRead(0);
    //Serial.write(state);
}


void loop(){
  //do other things here
  Serial.write(state);
}

Whenever I run Serial communication with the computer the Arduino IDE freezes up.

Serial.write(state) sends binary values to the IDE, not the ascii characters '0' or '1'. Is this what you wanted?
The binary values may be locking up the IDE.

It seems to lock up even if I change the code to:
volatile int = state;
Serial.print(state);
I will keep trying different things. THanks!

The interrupt routine samples the state of pin 0 at 8kHz.
The loop() function just writes (or prints) the value of state repeatedly without being synchronized with the interrupt. To do that you need to set a flag in the interrupt routine and then the loop function checks that flag before it prints the state.

Pete

Duplicate topics merged.DO NOT CROSS-POST, IT WASTES TIME

Okay, I got a similar version of the code to work at 2kHz. Also moving the Serial.print to the loop seemed to fix the issue!
I will post my updated code incase anyone wants to use a basic 2kHz timer interrupt code.

//storage variables
volatile int state = 0; //input variable

void setup(){
  
  //set pins as outputs
  pinMode(5, INPUT);
  
  Serial.begin(115200);

cli();//stop interrupts

//set timer0 interrupt at 2kHz
  TCCR0A = 0;// set entire TCCR2A register to 0
  TCCR0B = 0;// same for TCCR2B
  TCNT0  = 0;//initialize counter value to 0
  // set compare match register for 2khz increments
  OCR0A = 124;// = (16*10^6) / (2000*64) - 1 (must be <256)
  // turn on CTC mode
  TCCR0A |= (1 << WGM01);
  // Set CS01 and CS00 bits for 64 prescaler
  TCCR0B |= (1 << CS01) | (1 << CS00);   
  // enable timer compare interrupt
  TIMSK0 |= (1 << OCIE0A);

sei();//allow interrupts

}//end setup

ISR(TIMER0_COMPA_vect){//timer0 interrupt 2kHz toggles pin 8
//generates pulse wave of frequency 2kHz/2 = 1kHz (takes two cycles for full wave- toggle high then toggle low)
    state = digitalRead(5);
    Serial.println(toggle1); //reads input and outputs it to serial at 2kHz.
}

void loop(){
}

One more quick question about the serial monitor, I have the arduino outputting data to the serial monitor at 8kHz now yet when I have the serial monitor at 115200 bps it still can’t seem to keep up. Are there any tricks to get a higher bps serial reading?

Generally, it is bad practice to print in an interrupt routine. Interrupts should be short and fast.

Okay, so what is another method of sampling and recording data at over 2kHz? I am simultaneously using a Raspberry Pi and seeing if the RP is capable(easier) at doing what I need.