read analog pin from interrupt ?

has anyone ever tried to read an analog pin from an interrupt i havent wrote any code yet but I was wondering if any one had any tips i don't like using attachInterrupt it uses more code space than just defining one your self I have read it is a little tricky to read analog pins from an interrupt has anyone tried this I'm trying for speed here ?

I can't tell what you are asking - how can you use an interrupt but not attachinterrupt? I've not done analogRead() inside an interrupt, but digitalRead() works just fine. Why not just try it?

ps, please use a bit more punctuation.

I don’t understand the problem with attachInterrupt; can you please elaborate.

I have not had a need for my own interrupt handlers but here you go.

#define btnPin 2


volatile bool fNewValue = false;
volatile int value;

void setup()
{
  Serial.begin(115200);
  pinMode(btnPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(btnPin), btnHandler, FALLING);
}

void loop()
{
  if (fNewValue == true)
  {
    fNewValue = false;
    Serial.println(value);
  }
}

void btnHandler()
{
  value = analogRead(A1);
  fNewValue = true;
}

The beauty of the Arduino is that you can try things easily yourself :wink:

Trying for speed? Not much you can do about the speed of analogRead() which is about 100µs. It takes somewhere around 2uS to enter an interrupt. Some MCU cycles can be saved by avoiding attachinterrupt and programming the registers directly, but is it worth it time-wise?

ome MCU cycles can be saved by avoiding attachinterrupt and programming the registers directly, but is it worth it time-wise?

GRR What registers? There are none involved in setting up an ISR!

No, do not use analogRead in an ISR -it takes to long

For any one using interrupts look up "avr/interrupt"

If you want to grab a quick ADC reading when an interrupt occurs then you need of use the ADC in free running mode. See datasheet.

Mark

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3f,20,4); 

int num=0;


int main(void)
{
   lcd.init();                 
   lcd.init();
   lcd.backlight();
   lcd.setCursor(0,0);
   lcd.print("HELLO!");
    DDRB = 0b00000001;//pin B0 is an output 
    
    PORTD |= (1 << PORTD3);    // turn On the Pull-up
    // PD3 is now an input with pull-up enabled
   
    EICRA = (1<<ISC11)|(0 << ISC10);    // set INT1 to trigger on falling edge 
    EIMSK = (1 << INT1);     // Turns on INT1
    
    sei(); // turn on interrupts
//*************************WHILE_LOOP**************************************************
    while(1)
   {
    //do nothing   
   }
//*************************************************************************************
}//END-OF-MAIN



//*************ISR************
ISR (INT1_vect)
{
//enpty for now
}
//*****END-OF-ISR**************

ok here is the kind of interrupt I like using for less program space and I want to send results to an I2C-LCD via ATmega328p on a bread board its a long story of what my goal is but this is what im trying to do is read A0 quickly and send results to LCD simple IDEA just not simple to do from what Ive read

If you're willing to sacrifice resolution, could get up to 77ksps with 1MHz ADC clock.

I'd set the ADC to free running.

Just set a flag in the ISR.

Check the flag in your while loop.

If the flag is set then read the adc byte/bytes and display them. reseting the flag of course

But look in the datasheet for details.

Mark

well the ADC doesn’t have to be extremely fast 100 times a second is fast enough and how would I set a flag
to make it read ADC (A1 or A0 ) from interrupt then send results to LCD

Well, your loop speed should be much faster than 100 iterations per second, so you should be able to do this without using interrupts at all.

Just

int flag =0;

----

ISR etc{
flag =1

}

then in your

forever loop
if (flag==1){

    flag=0;
    read the adc by what ever means you like

}

Mark

Thanks holmes4 and yea your rite my code is not very long so it would be fast enough and thanks dloyd

if you want to do things at about 100 HZ and don't care about actually going more than 10ms every now and then... you can use this construct:

if (!( millis() % 10L)) { // do the every-10-ms things here }

wg0z: if you want to do things at about 100 HZ and don't care about actually going more than 10ms every now and then... you can use this construct:

if (!( millis() % 10L)) { // do the every-10-ms things here }

Or you could do it properly.

holmes4: Just

int flag =0;

ISR etc{ flag =1

}

then in your

forever loop if (flag==1){

   flag=0;    read the adc by what ever means you like

}




Mark

Not quite - number of issues there:

Try this:

// variables used in ISR and your main code _must_ be declared volatile - otherwise the compiler
// is perfectly justified in optimizing them into a broken state
volatile bool flag = false ; // use one byte variable type - you get atomic reads and writes that way.

----

ISR etc{
flag = true; 

}

then in your

forever loop
if (flag){
    flag = false;
    read the adc by what ever means you like

}