ElectricRCAircraftGuy / eRCaGuy_TimerCounter

An Arduino micros()-like function (encapsulated in a library) with 0.5us precision (since the built-in Arduino micros() function has only 4us precision)
http://www.electricrcaircraftguy.com/2014/02/Timer2Counter-more-precise-Arduino-micros-function.html
31 stars 13 forks source link

Doesn't work on Leonardo (reported by Nils) #10

Closed ElectricRCAircraftGuy closed 3 years ago

ElectricRCAircraftGuy commented 3 years ago

From Nils via email to me:

Hi. would like to try your eminent timer lib for arduino.. But it doesent compile... Any ideas? Using Leonardo.

ElectricRCAircraftGuy commented 3 years ago

Hi Nils, the problem is that the registers I'm using, such as TIMSK2 (from memory) and others are specific to the ATmega328 microcontroller. The Leonardo uses a different microcontroller--the ATmega32u4. So, unfortunately the library doesn't currently support the Leonardo, and I don't have incentive right now to take the time to make it work with the Leonardo.

It will work on the Uno, Mini, and Nano, however.

Thanks!

Gabriel Staples

ElectricRCAircraftGuy commented 3 years ago

If you want to try, it should be a pretty simple change (for a knowledgeable or dedicated person). You'll need to compare the register names in the datasheets for both chips and update them in the code, for the Leonardo.

ElectricRCAircraftGuy commented 3 years ago

From Nils:

Thank u very much Gabriels for a very fast reply on this.

Cant say i am knowledgeble, however always dedicated. So in some way in a year or so maybe i succed :) Completly new to the topic arduinos and registrers contra interrupts., but learning in older days.

What i want to do is basically timestamp a minimum of 4 external interruppts consisting of MEMS-Mics going high/Rising when sound triggers/passes the mic.

Do u know where i get the best/easyest info on this topic? Seems like there are a lot of problems whith interrupts/Delay/priority etc that i need to grasp also.

Applying som primary test-code that actually works as thanx below with q i try to solve......

int mic1 = 2; // Mic 1 on pin 2-Leonardo
int mic2 = 3; // Mic 2 on pin 3-Leonardo

volatile unsigned long tid1 = 0; //Var used in both interrupts an loop as Volatile to store time. tid=time in swedish .
volatile unsigned long tid2 = 0;// Does var type affect serial print?
volatile unsigned long tid11 = 0;
volatile unsigned long tid22 = 0;
volatile unsigned long tid33 = 0;

volatile int  stop1 = 0; // Flag for trig 1
volatile int stop2 = 0; // Flag for trig 2
volatile unsigned long diff = 0; // var to put micros-oldmicros in and save it for calc.
char dir = ('x'); // Var for debugging and telling in serial print wether the right or left mic is triggered first.

void setup() {
  pinMode(mic1, INPUT);
  pinMode(mic2, INPUT);
  Serial.begin(115200); // Does serial reading affect micros timer? do they use same registrerd allocated memory?
  attachInterrupt(digitalPinToInterrupt(mic1), trig1, RISING); // Switching these on/off using Interrupts() and nointerrupt() affect timer... why?
  attachInterrupt(digitalPinToInterrupt(mic2), trig2, RISING);// Rising/Falling/change/ all give errors but rising works best so far. (Due to amplitudes and freq.?)
}

void loop() {
  // If both mics are triggered start loop, otherwise do nothing in loop....

  if (( stop1 == 1 && stop2 == 1 )) {
    stop1 = 3;
    stop2 = 3;
    // tid33 = (tid22 - tid11);
    // Serial.print (tid33);

    //If right mic gets timestamped before left mic, then print it out in serial as debugger and vice versa.

    if (tid1 > tid2) {
      diff = (tid1 - tid2);
      dir = ('H');

    }
    if (tid1 < tid2)  {
      diff = (tid2 - tid1);
      dir = ('V');

    }

    Serial.println();
    Serial.print(diff);
    Serial.print(" / ");
    Serial.print(dir);

    // This sound-echo-debounce-delay messes with timer. If put elsewere it affects timer registred value, why?

    delay(500);

    //Put Flag back on so that triggers work again. Theese are have to be zero to trig s to take new time. using micros()
    stop1 = 0;
    stop2 = 0;
  }
}

void trig1() {
  // If stop 1 and 2 is not zero dont take time. Controlled in loop.
  if (stop1 == 0);
  tid1 = micros();
  //tid11 = timer2.get_count();
  stop1 = 1;
}

void trig2() {
  // If stop 1 and 2 is not zero dont take time. Controlled in loop.

  if (stop2 == 0);
  tid2 = micros();
  //tid22 = timer2.get_count();
  stop2 = 1;
}

//Game on!
//Best wishes Nils.
ElectricRCAircraftGuy commented 3 years ago

For advanced Arduino understanding, I recommend reading:

  1. The "Advanced" links, by Nick Gammon, at the bottom of my article here: https://www.electricrcaircraftguy.com/2014/01/the-power-of-arduino.html.
  2. The microcontroller datasheet for your Arduino. ex: ATmega328 datasheet for Uno, Nano, Mini, or ATmega32U4 datasheet for Leonardo, Pro Micro, etc.

Learning and help resources:

Regarding your more-specific questions, please post to one or more of these:

  1. Stack Overflow (https://stackoverflow.com/)
  2. the Arduino Stack Exchange (https://arduino.stackexchange.com/)
  3. the Arduino forum (https://forum.arduino.cc/)
  4. Code Review stack exchange (https://codereview.stackexchange.com/)

...and then come back here and post a link to where you posted it there, and I'll see if I can help you there too.

ElectricRCAircraftGuy commented 3 years ago

FYI: your code above has race conditions and all volatile variables will be corrupted. You have to provide atomic access guards to prevent this when accessing the volatile variables outside of your interrupt service routines (ISRs).

I present 4 ways to safely access a variable atomically, here: https://stackoverflow.com/questions/36381932/c-decrementing-an-element-of-a-single-byte-volatile-array-is-not-atomic-why/39693278#39693278.

See the latter part of my question there too for demonstration of using one of those techniques properly to prevent data corruption.

ElectricRCAircraftGuy commented 3 years ago

If this helps you out. Please consider sponsoring me on Github. You'd be my first sponsor, which would be awesome: https://github.com/sponsors/ElectricRCAircraftGuy.