Announcement

Collapse
No announcement yet.

Baracuda + Micro

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • ivconic
    replied
    Except for one thing; backlight at standard 16x2: pin 15 is + and pin 16 is -.
    But that probably differs at different manufacturers and different series i suppose?

    Leave a comment:


  • ivconic
    replied
    So far as i understood from blur schematic:


    PHP Code:
    // ******************** LCD 16x2 connections ********************
    // * Atmega pin  5(PD3)= Arduino (D3) ----- LCD pin 14 (d7)     *
    // * Atmega pin  6(PD4)= Arduino (D4) ----- LCD pin 13 (d6)     *
    // * Atmega pin 11(PD5)= Arduino (D5) ----- LCD pin 12 (d5)     *
    // * Atmega pin 12(PD6)= Arduino (D6) ----- LCD pin 11 (d4)     *
    // * Atmega pin 13(PD7)= Arduino (D7) ----- LCD pin  6 (Enable) *
    // * Atmega pin 14(PB0)= Arduino (D8) ----- LCD pin  4 (RS)     *
    // *                              GND ----- LCD pin  5 (R/W)    *
    // * Atmega pin 15(PB1)= Arduino (D9) ----- LCD pin  3 (VEE)    *
    // * LCD 16x2 Pin 15 = Led + 220 ohms ----- +5V                 *
    // * LCD 16x2 Pin 16 = Led -          ----- GND                 *
    // **************************************************************
    // Atmega pin 16 (PB2)= Arduino (D10)- button                   *
    // Atmega pin 17 (PB3)= Arduino (D11)- button                   *
    // Atmega pin 18 (PB4)= Arduino (D12)- button                   *
    // Atmega pin 19 (PB5)= Arduino (D13)- button                   *
    // Buttons common + 100k - GND                                  *
    //***************************************************************
    // TX Pulse --- Atmega pin 23 (ADC0)/(PC0)= Arduino (A0)        *
    // Pulse 1  --- Atmega pin 24 (ADC1)/(PC1)= Arduino (A1)        *
    // Pulse 2  --- Atmega pin 25 (ADC2)/(PC2)= Arduino (A2)        *
    //*************************************************************** 
    

    Leave a comment:


  • Michaelo
    replied
    If anyone want to improve the menu code please go right ahead...

    The current code works well but is difficult to explain in a few lines but here goes...

    First we select the main menu by pressing the rightmost key...
    This displays "[T] [F] [S] [D]" on the top line...

    Now select 'T' (Transmit Pulse Duration), or 'F' (Duty Cycle /Frequency), or 'S' (Sample Pulse Width) or 'D' (Sample Pulse Delay)...

    The display will show the appropriate value on the top line...

    Use the two centre keys to Decrease (left) or Increase (right) the value... (whatever changes you make are automatically updated)...

    Press the Menu Key to go back to the Main Menu...

    The left key (inside the adjust options) has no associated job but I may use it to reset that item to its default value)...
    Currently altered values are not saved... default values are loaded on start up...

    I may try a version with the rotary switch... it might simplify things... but in the mean time this code works fine...
    Mike

    Leave a comment:


  • Michaelo
    replied
    @Koala thanks for the input... Just trying to determine if my coils is up to the job...

    The Blue 16x2 LCD arrived yesterday... code changed appropriately...

    The main options are:
    1 Change transmit pulse duration (Min/Max Limits = 50uS - 150uS) Default = 100uS...
    2 Change the duty cycle (640Hz) 1562uS (Min/Max = 1000uS - 2000uS) Default = 1562uS (640Hz)...
    3 Change Sample Pulse Width (Min/Max = 20uS - 70uS) Default = 45uS...
    4 Change Sample Pulse Delay (Min/Max = 10uS - 30uS) Default = 20uS...

    LCD Displays: [T] [F] [S] [D] (The four buttons)
    T = Set: TX Pulse Duration
    F = Set: Frequency/Cycle
    S = Set: Sample Pulse Width
    D = Set: Sample Pulse Delay

    Would need a second/submenu to change the Second Sample Pulse Width/Delay which might be an option...
    The only other display item is the battery voltage and battery low indication...

    I'll post the code but I warn you it isn't pretty...
    PHP Code:
    #include <TimerOne.h>
    #include <LiquidCrystal.h>
    #include <avr/pgmspace.h>
    
    /*
     * This is the code for the Bara Micro @ Geotec www.geotech1.com
     * http://www.geotech1.com/forums/showthread.php?23112-Baracuda-Micro
     * Michael O'Toole 2016
     * 
     * #define CYCLE_TIME 1562 // 0.0015625 Seconds @ 640 PPS // 1562
     */
    
    /* defaults 
    #define TX_PULSE         100 //(100uS)    100uS
    #define PULSE_1_DELAY     20 //( 20uS)    Delay before Sample Pulse 1
    #define PULSE_1           45 //( 45uS)    Sample 1 Pulse Duration
    #define PULSE_2_DELAY    150 //(150uS)    Delay between Sample Pulse 1 and Pulse 2
    #define PULSE_2           45 //( 45uS)    Sample 2 Pulse Duration 45uS
    */
    
    /*
     Total Pulses Time        310
     -----------------------------
     Cycle Time              1562
     Pulse Times             -310
     Delay till next cycle   1252
    
     Actual cycle time is 1/1562 = 640Hz
    */
    
    #define BCT 360
    #define BAT_LOW 0.90
    #define BUTTON_PRESS 0
    #define ROW1 10
    #define ROW2 11
    #define ROW3 12
    #define ROW4 13
    #define LCD_CHARS 16
    #define LCD_LINES 2
    #define INCREASE 13
    #define DECREASE 11 
    #define DEBUG 0
    //#define CONTRAST_PIN 9
    
    volatile int CYCLE_TIME    =1562;
    volatile int FREQUENCY     = 640;
    volatile int TX_PULSE      = 100;
    volatile int PULSE_1_DELAY =  20;
    volatile int PULSE_1       =  45;
    volatile int PULSE_2_DELAY = 150;
    volatile int PULSE_2       =  45;
    
    volatile unsigned long timer = 0;
    
    int CYCLE_TIME_MIN = 1000;
    int CYCLE_TIME_MAX = 2000;
    int TX_PULSE_MIN = 50;
    int TX_PULSE_MAX = 150;
    int PULSE_1_MIN = 20;
    int PULSE_1_MAX = 70;
    int PULSE_1_DELAY_MIN = 10;
    int PULSE_1_DELAY_MAX = 30;
    int PULSE_2_MIN = 20;
    int PULSE_2_MAX = 70;
    int PULSE_2_DELAY_MIN = 50;
    int PULSE_2_DELAY_MAX = 250;
    int adjust = 0;
    int bcount = 0;
    int contrast = 10;
    int in_menu = 0;
    int last_key = 0;
    
    bool in_main_menu = false;
    
    char menuSP1[] = "S Pulse 1 ";
    char menuSD1[] = "S Delay 1 ";
    char menuSP2[] = "S Pulse 2 ";
    char menuSD2[] = "S Delay 2 ";
    char menuTP[]  = "TX Pluse  ";
    char menuTD[]  = "Cycle     ";
    
    
    /*
     * characters to make a nice pulse
     */
    byte B[8] = {
      0b00000,
      0b00000,
      0b00000,  
      0b00000,  
      0b00000,  
      0b00000,
      0b00000,
      0b11111
    };
    byte T[8] = {
      0b11111,
      0b00000,
      0b00000,  
      0b00000,  
      0b00000,  
      0b00000,
      0b00000,
      0b00000
    };
    byte L[8] = {
      0b11111,
      0b10000,
      0b10000,  
      0b10000,  
      0b10000,  
      0b10000,
      0b10000,
      0b10000
    };
    byte R[8] = {
      0b11111,
      0b00001,
      0b00001,  
      0b00001,  
      0b00001,  
      0b00001,
      0b00001,
      0b00001
    };
    byte HL[8] = {
      0b00011,
      0b00010,
      0b00010,  
      0b00010,  
      0b00010,  
      0b00010,
      0b00010,
      0b11110
    };
    byte HR[8] = {
      0b11000,
      0b01000,
      0b01000,  
      0b01000,  
      0b01000,  
      0b01000,
      0b01000,
      0b01111
    };
    
    LiquidCrystal lcd(8,7,6,5,4,3); //LiquidCrystal(rs, enable, d4, d5, d6, d7)     
    
    void setup()
    {
      pinMode (A0, OUTPUT);
      pinMode (A1, OUTPUT);  
      pinMode (A2, OUTPUT);
      
      pinMode (ROW1, INPUT_PULLUP);
      pinMode (ROW2, INPUT_PULLUP);
      pinMode (ROW3, INPUT_PULLUP);
      pinMode (ROW4, INPUT_PULLUP);
      
      digitalWrite (A0, LOW);
      digitalWrite (A1, LOW);
      digitalWrite (A2, LOW);
    
      lcd.createChar(1, B);
      lcd.createChar(2, L);  
      lcd.createChar(3, T);  
      lcd.createChar(4, R);
      lcd.createChar(5, HL);
      lcd.createChar(6, HR);
      
      lcd.begin(16, 2);
      lcd.setCursor(0, 0);
      delay(500);
      lcdstart();
      Serial.begin(9600);
    
      Timer1.initialize(CYCLE_TIME);
      Timer1.attachInterrupt(do_isr);
    }
    
    void loop()
    {
      if(bcount++ > BCT && !in_menu) check_battery();
      
      delay(5);
      
      int key_input = getkeypress();
    
      if(key_input)
      {
        if(in_menu)
        {
          process_in_menu_key(key_input);
        }
        else do_menu(key_input);  
      }
    }
    
    void do_isr()
    {
      PINC = 0x01;
      for(int i = 0; i < TX_PULSE; i++)
      {
        __asm__("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
        __asm__("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
        __asm__("nop\n\tnop\n\t");
      }
      PINC = 0x01;
      
      for(int i = 0; i < PULSE_1_DELAY; i++)
      {
        __asm__("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
        __asm__("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
        __asm__("nop\n\tnop\n\t");
      }
      
      PINC = 0x02;
      for(int i = 0; i < PULSE_1; i++)
      {
        __asm__("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
        __asm__("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
        __asm__("nop\n\tnop\n\t");
      }  
      PINC = 0x02;
      
      for(int i = 0; i < PULSE_2_DELAY; i++)
      {
        __asm__("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
        __asm__("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
        __asm__("nop\n\tnop\n\t");
      }
      
      PINC = 0x04;
      for(int i = 0; i < PULSE_2; i++)
      {
        __asm__("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
        __asm__("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
        __asm__("nop\n\tnop\n\t");
      }  
      PINC = 0x04;   
    }
    
    void lcdstart()
    {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Bara Micro Tool.");
      lcd.setCursor(0, 1);
      lcd.print("  Version 1.0   ");
      lcd.setCursor(0, 0);  
      delay(1500);
    }
    
    void check_battery() // quick battery code
    {
      double bat = 0.00;
      int tmp = 0;
      
      for(int i = 0; i < 5; i++)
      {
        tmp += analogRead(A5);
        delayMicroseconds(5);
      }
      tmp = tmp / 5;
      bat = tmp / 1023.0;
        
      if(bat < BAT_LOW)
      {
        lcd.setCursor(0, 1);
        lcd.print("                ");
        lcd.setCursor(0, 1);    
        lcd.print("Battery Low:");
        lcd.print(bat);
        lcd.print("V");    
      }
      else
      {
        lcd.setCursor(0, 1);
        lcd.print("                ");
        lcd.setCursor(0, 1);    
        lcd.print("Battery:   ");
        lcd.print(bat*5);
        lcd.print("V"); 
      }
      bcount = 0;
    }
    
    int getkeypress()
    {
      int keydata = PINB;
      keydata = ((keydata << 2)>> 4);   // Loose the bits we don't want, we just need PB2 to PB5 //
      delay(5);
    
      if(keydata == ((PINB<<2)>>4) && keydata < 15)
      {
        last_key = keydata;
    
        while(keydata == ((PINB<<2)>>4));
       
        if(!in_main_menu)
        {
          in_main_menu = true;
          main_menu();
          return(1);
        }
        
        if(in_menu && keydata == 14)
        {
          in_menu = 0;
          in_main_menu = true;
          main_menu();      
          return(1);
        }
        return(last_key);
      }
      return(0);
    }
    
    void printpulse(int w = 1)
    {
      int fix = 0;
      int cur = 0;
      int odd = w % 10;
      
      if(w == 8)
        odd = 1;
      w = w / 8;
     
      lcd.setCursor(0, 1);
      for (int i = 0; i< 16; i++)
      {
        lcd.print(char(1));
      }
    
      if(!odd) fix = 1;
      lcd.setCursor((7 + fix) - (w/2), 1);
      if(!odd)
      {
        lcd.print(char(2));
      }
      else
      {
        lcd.print(char(5));
      }
      if(odd) fix = 0; else fix = 2;
      for(int i = 0; i < w - fix; i++)
      {
        lcd.print(char(3));
      }
    
      if(!odd)
      {
        lcd.print(char(4));
      }
      else
      {
        lcd.print(char(6));
      }
    }
    
    void do_menu(int input)
    {
      lcd.setCursor(0, 0);
      
      switch(input)
      {
        case 7: // tx pulse
                lcd.clear();
                lcd.print(menuTP); 
                rightadjust(TX_PULSE);
                printpulse(TX_PULSE);
                in_menu = input;
                report(input);
        break;
        
        case 11: // freq
                lcd.clear();
                lcd.print(menuTD);
                rightadjust(CYCLE_TIME);
                printpulse((CYCLE_TIME/100));
                in_menu = input;
                report(input);
        break;
        
        case 13: //sample pulse
                lcd.clear();
                lcd.print(menuSP1);
                rightadjust(PULSE_1);
                printpulse(PULSE_1);
                in_menu = input;
                report(input);
        break;
        
        case 14: // sample pulse delay
                lcd.clear();
                lcd.print(menuSD1);
                rightadjust(PULSE_1_DELAY);            
                printpulse(PULSE_1_DELAY);
                in_menu = input;
                report(input);
        break;
        
        default:
        break;
      }
    }
    
    void process_in_menu_key(int key)
    {
      if(in_menu ==  7) // tx pulse
      {
        if(key == INCREASE) TX_PULSE += 5;
        if(key == DECREASE) TX_PULSE -= 5;
        if(TX_PULSE < TX_PULSE_MIN) TX_PULSE = TX_PULSE_MIN;
        if(TX_PULSE > TX_PULSE_MAX) TX_PULSE = TX_PULSE_MAX;
        rightadjust(TX_PULSE);
        return;
      }
      if(in_menu == 11) // frequency
      {
        if(key == INCREASE)
        {
          CYCLE_TIME += 50;  
          if(CYCLE_TIME > CYCLE_TIME_MAX)
          CYCLE_TIME = CYCLE_TIME_MAX;
        }
        else if(key == DECREASE)
        {
          CYCLE_TIME -= 50;
          if(CYCLE_TIME < CYCLE_TIME_MIN)
          CYCLE_TIME = CYCLE_TIME_MIN;
        }
        rightadjust(CYCLE_TIME);
        return;
      }
      if(in_menu == 13) // sample pulse 1
      {
        if(key == INCREASE) PULSE_1 += 5;  
        else if(key == DECREASE) PULSE_1 -= 5;
        if(PULSE_1 < PULSE_1_MIN) PULSE_1 = PULSE_1_MIN;
        if(PULSE_1 > PULSE_1_MAX) PULSE_1 = PULSE_1_MAX;
        rightadjust(PULSE_1);
        return;
      }
      if(in_menu == 14) // sample pulse delay 1
      {
        if(key == INCREASE) PULSE_1_DELAY += 5;
        else if(key == DECREASE) PULSE_1_DELAY -= 5;
        if(PULSE_1_DELAY < PULSE_1_DELAY_MIN) PULSE_1_DELAY = PULSE_1_DELAY_MIN;
        if(PULSE_1_DELAY > PULSE_1_DELAY_MAX) PULSE_1_DELAY = PULSE_1_DELAY_MAX;
        rightadjust(PULSE_1_DELAY);
        return;
      }
      key = 0;
      beep();
    }
    
    void save()
    {
      ;// later
    }
    
    void main_menu()
    {
      char menumenu1[] = "[T] [F] [S] [D] ";
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(menumenu1);
    }
    
    void beep()
    {
      ;//later
    }
    
    void report(int var)
    {
      if(!DEBUG) return;
      lcd.setCursor(0, 0);
      lcd.print("                ");
      lcd.setCursor(0, 0);  
      lcd.print("Menu=[");
      lcd.print(in_menu);
      lcd.print("] Key=[");
      lcd.print(var);
      lcd.print("]");
    }
    
    /*
     * Align right and print value
     */
    void rightadjust(int data)
    {
      lcd.setCursor(10, 0);
      lcd.print("      ");
      lcd.setCursor(10, 0);
    
      if(data < 10)
      {
        lcd.setCursor(13, 0);
      }  
      else if(data < 100)
      {
        lcd.setCursor(12, 0);    
      }
      else if(data < 1000)
      {
        lcd.setCursor(11, 0);    
      }
      lcd.print(String(data));
      lcd.print("us");
    } 
    

    Leave a comment:


  • Koala
    replied
    Originally posted by Michaelo View Post
    Just an update as it's pretty quiet lately...
    Currently building the Rev 3 Baracuda on to new empty Bara PCB, this will free up the old board so I can add the Micro...

    The new displays have not arrived yet (slow boat from China) but should be here soon...
    If anyone has a really good coil and details of how they made it, please post back...
    Also, what distances should I be aiming for in relation to depth and coins to test for...
    Mike
    Coil is about 8.5" and 29 turns of .71mm copper enamelled wire.

    Just over 12" on a one pound coin. Not optimised for that coin so I would expect another inch or so would be possible at the sacrifice of other targets

    Leave a comment:


  • Michaelo
    replied
    Just an update as it's pretty quiet lately...
    Currently building the Rev 3 Baracuda on to new empty Bara PCB, this will free up the old board so I can add the Micro...

    The new displays have not arrived yet (slow boat from China) but should be here soon...
    If anyone has a really good coil and details of how they made it, please post back...
    Also, what distances should I be aiming for in relation to depth and coins to test for...
    Mike

    Leave a comment:


  • ODM
    replied
    Originally posted by moodz View Post
    50 ns for example is extremely coarse in this context.
    Yep, that's 50ns granularity with a 20MHz clock for timing. When things are repeatable to a cycle (at cost of extra cycles to sync program counter to hardware timer), actual jitter in AVR timing boils down to the oscillator itself. More finely grained timing would need a faster clock, but AVR's spec'd to 20MHz. If someone really wants to use a bare-bones AVR for faster timing than that, there's ones that run their timer PWM pins up to 64MHz. Caveat is that the high speed PWM comes from an internal PLL clock multiplier that may or may not have decent jitter spec.

    Going beyond the originally implied AVR hardware is an option, of course. Still, building a relatively precise and repeatable timer to the order of a couple nanoseconds is not exactly an easy task either in digital or in analog.

    Leave a comment:


  • Teleno
    replied
    Originally posted by moodz View Post
    ... I will add this comment also ... 1 ns resolution is provided natively in some processors now ( eg picxx ) ... however this circuit is a beauty without using particularly fast clocks ( and YES Virginia it uses ISR to do the main work ).

    Its also a great circuit to use in PIs ... ( not for this application .. something else ... however the idea does not belong to me so I cant say what it is at the moment )

    [ATTACH]36079[/ATTACH]

    http://electronicdesign.com/test-amp...icrocontroller
    Q3 and Q4 should be a current mirror but in the configuration shown they're not.

    Leave a comment:


  • moodz
    replied
    ... I will add this comment also ... 1 ns resolution is provided natively in some processors now ( eg picxx ) ... however this circuit is a beauty without using particularly fast clocks ( and YES Virginia it uses ISR to do the main work ).

    Its also a great circuit to use in PIs ... ( not for this application .. something else ... however the idea does not belong to me so I cant say what it is at the moment )

    Click image for larger version

Name:	figure_01.gif
Views:	1
Size:	17.2 KB
ID:	345659

    Nanosecond interval timers are a critical component in products as diverse as time-domain reflectometers (TDRs), collision-avoidance systems, radar altimeters, and nuclear instrumentat...

    Leave a comment:


  • moodz
    replied
    I could be cheeky and say that using 500ns timing steps just means you are not working on cutting edge PI's ... however consider the attached pic .. it shows a flyback pulse with 400 volt peak and 1 usec total duty ... active damping brings this pulse to around a few microvolts within 40 nanoseconds of the falling edge. In fact one of the sample pulses on this pi is only 40 ns in total length .... so 500 ns is completely too big.

    Click image for larger version

Name:	wtf.jpg
Views:	1
Size:	1,015.3 KB
ID:	345658
    Originally posted by scrungy_doolittle View Post
    500 ns is slow for hi spec pi work, I'm not sure I would agree. So run your counter at 24 mhz, and then you have 40 ns which is better. The approach I was going to use on the GG project, was to not sample that way.
    The chosen processor has a 10 mega sample 12 bit ADC, start sampling the moment the pulse is started, and let the ADC along with a DMA put the data into memory. Hardware counters are good, but we were looking at a 1 usec sample time. Not sure that 20 ns is necessary.

    Leave a comment:


  • scrungy_doolittle
    replied
    Originally posted by moodz View Post
    ....teleno might be referring to an isr that calls a very tight machine code polling loop that has precise non rentrant timing. Despite manufacturers specifications isr latencies are not guaranteed or fixed. Hardware comparators and counters work best IMHO.

    500 ns timing is practically useless for high spec pi work. 20 ns or better is required.
    500 ns is slow for hi spec pi work, I'm not sure I would agree. So run your counter at 24 mhz, and then you have 40 ns which is better. The approach I was going to use on the GG project, was to not sample that way.
    The chosen processor has a 10 mega sample 12 bit ADC, start sampling the moment the pulse is started, and let the ADC along with a DMA put the data into memory. Hardware counters are good, but we were looking at a 1 usec sample time. Not sure that 20 ns is necessary.

    Leave a comment:


  • moodz
    replied
    I would nake the comment that if your timing is not at the very least accurate to 20 ns then your not at the cutting edge edge of pi design ....with fast coils having a response of better than 1 mhz and switches moving hundreds of volts in under 100 ns and you are trying to pull out micro volt changes 50 ns for example is extremely coarse in this context. You are practically forced to use tight non interrupting machine code or hardware solutions.isr are useful for house keeping outside the crtical timeslots.

    Leave a comment:


  • ODM
    replied
    I think I see where we misunderstood each other. For the fastest reaction time to something or very rapid bit banging, straight coding and polling has its merit.

    For fixed output where timing relative to output instead of response to external stimulus is needed, there is time to take a handful of extra cycles to sync execution to a timer.

    For example we can have a timer interrupt that runs a certain instruction from 15-18 cycles from interrupt source, or take a fixed 30 cycles from interrupt source, with the synchronizing. The pulse train in our output pins doesn't care about how many cycles it takes to enter interrupts, if there are enough cycles to spare. At 20 MHz one cycle is 50ns, so 5us is 100 cycles. Few PI detectors take continuous timing tighter than that.

    For very rapid, 1-5us timing we are better off spending time in deterministic loops compared to interrupts. When running delays far longer than the synced interrupt takes, then it is better to use that interrupt. We rarely run into need for that or use a faster mcu though

    If we want, of course, we can stop in the interrupt to do a string of delay loop timing. Its just rare to have continuous need for it.

    Leave a comment:


  • Teleno
    replied
    Originally posted by ODM View Post
    Easiest way for AVR cycle precise timing is using timer HW pins.
    Still you must react when the timer sets the I flag.

    Maybe together with a mux for an elegant solution.

    Originally posted by ODM View Post
    Precision to a single cycle for code execution and interrupts can be guaranteed, though interrupt latency is dependent on the presently executed instruction in AVR core.
    Am I the only one to see a contradition in that claim?

    Originally posted by ODM View Post
    The interrupt has a fixed overhead around a dozen or two cycles (interrupt vector, jump to isr, status save to stack) plus a smaller delay for present instruction.
    That ecludes interrupts for a lot of real-time applications.

    Originally posted by ODM View Post
    Polling has incertainty for the duration of the polling loop as well.
    wait: sbis TOV1, TIR1 // skip next instruction if TOV1 bit set in TIFR1
    rjmp wait
    ...useful code...

    sbis: 1 cycle
    rjmp: 2 cycles

    Worst case reaction time is 3 clock cycles. Now beat that with an interrupt.

    If reaction time is not critical, please use interrupts, but don't pretend they're always the optimum approach.

    Leave a comment:


  • ODM
    replied
    Easiest way for AVR cycle precise timing is using timer HW pins. Maybe together with a mux for an elegant solution.

    Precision to a single cycle for code execution and interrupts can be guaranteed, though interrupt latency is dependent on the presently executed instruction in AVR core. The interrupt has a fixed overhead around a dozen or two cycles (interrupt vector, jump to isr, status save to stack) plus a smaller delay for present instruction.

    Polling has incertainty for the duration of the polling loop as well. Getting cycle precise delays takes reading a timer value and delaying appropriately, but after that we have clock jitter as the remaining source of incertainty. For examples, check out video/OSD generator projects.

    Leave a comment:

Working...
X