Arduino R3 - speeding up/breaking up Serial.available and Serial.read

Hello! I have a timing critical project, and so have most interrupts disabled most of the time, only enabling the main interrupt flag at times when I can spare it to read single bytes at a time over serial (using Timing Serial.available and Serial.read), and set a bool that one is available, before disabling once again.

with my initial test code, I thought I had something like 137 cycles at worst for this:

void setup() {
  Serial.begin(115200);

  noInterrupts();
  TIMSK0 = 0;
  TIMSK1 = 0;
  TIMSK2 = 0;
  EIMSK = 0;
  PCMSK0 = 0;
  PCMSK1 = 0;
  PCMSK2 = 0;
  ADCSRA &= ~bit(ADIE);
  ACSR &= ~bit(ACIE);

  TCCR1A = 0;
  TCCR1B = bit(CS10);//no divider

}

uint16_t cycles = 0;
uint16_t worstcycles = 0;

void loop() {
  TCNT1 = 0;
  interrupts();
  if(Serial.available()) {//137 cycles
  
  //if (UCSR0A & bit(RXC0)) {//this method a bit faster.. 111, but we're gonna miss available ones in buffer?
  //  TCNT1 = 0;
  //  interrupts();

    uint8_t readit = Serial.read();
    noInterrupts();
    cycles = TCNT1;
    if(cycles>worstcycles){
      worstcycles = cycles;
    }

    if(readit == '*'){
      printit();
    }
  }

}


void printit(){
  interrupts();
  Serial.print("worst number of cycles seen: ");
  Serial.println(worstcycles);//seeing 137/111 cycles at worst... can this be made better, or split up into smaller chunks?

  TCNT1 = 0;
  while(TCNT1 < 50000){
    worstcycles = 0;//something, while we waste time
  }

  noInterrupts();
}

However, in my project, I'm now measuring more like 360 cycles at worst, which is too long (137 would be fine). Is there any easy way to make this take less cycles? break the work up into multiple parts, or use a different method entirely to read the serial?

Cheers!

That won't work. You have a strange understanding of how the serial code works. Serial.available() does almost nothing, it returns the number of bytes in the input buffer. Activated interrupts means also that the timer interrupt for millis() and the like is activated so that may be executed too. Your method of measuring the time is completely senseless as you don't measure the actual time used (as you reset the counter in each loop() run).

Tell us what you're trying to achieve. What is sending the serial information? How often is it sent? Do you control when it is sent?

In general it is a bad idea to turn off interrupts if you want to receive data by the serial interface.

Hello! Yeah, I couldn't find any information at all about how many cycles i could expect any of the serial functions or interrupts to take, so i was pretty much just trying to lock it all down, and then count how many cycles were taken when i let it do it's thing, at worst, which i believe that code successfully does (hence starting the timer before and stopping it after). However, as you say, this is totally not the right way to go about it. I've since rewritten my project a great deal with this in mind, using interrupts to my advantage, and it seems to be working for me. I've still had to stop timer0 from interrupting though (data is basically constant 115200 bits per sec). But I don't use millis anyway. Hahah. Thanks!

Keep in mind that many libraries depend on the functionality of timer0 (delay, millis, etc.)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.