# How to make a circuit which can give divided voltage to ADC and can send a trigger pulse to INT0 when I press a button?

I connected 4 buttons to the ADC module of AVR-ATMega328p with different resistor values,

To know which button is pressed this is the ISR() function I implemented,

ISR(ADC_vect)
{
// Assign the data to bInput variable

if((bInput < 900) && (bInput > 800))
{
// B1 is pressed
// V in to ADC is 4.1v
}
if((bInput < 700) && (bInput > 600))
{
// B2 is pressed
// V in to ADC is 3.1v
}
if((bInput < 500) && (bInput > 400))
{
// B3 is pressed
// V in to ADC is 2.0v
}
if((bInput < 300) && (bInput > 200))
{
// B4 is pressed
// V in to ADC is 1.1v
}
}

##### Output values I get(Tested using a Multi-meter) -
1. If button B1 pressed: Vdrop across R = 4.1 V , Vin to ADC module = 4.1 V , ADC registor = 853
2. If button B2 pressed: Vdrop across R = 3.1 V , Vin to ADC module = 3.1 V , ADC registor = 639
3. If button B3 pressed: Vdrop across R = 2.0 V , Vin to ADC module = 2.0 V , ADC registor = 426
4. If button B4 pressed: Vdrop across R = 1.1 V , Vin to ADC module = 1.1 V , ADC registor = 227

But the processor is always busy to do the ADC conversion every time, So I decided to add a trigger-INT0 for the ADC conversion to happen,

#define F_CPU 16000000UL

#include <avr/io.h>

void __init__button();

int bInput = 0;

int main()
{
__init__button();

while(1)
{
//loop
}
return 0;
}

void __init__button()
{
// Make ADC pins as input
DDRC=0x0;
SREG |= (1<<7);

// Set the prescalar to 128 -> 125 kHz

// Select the voltage referance - AREF pin

// Select the input channel - ADC3

// Enable the INT0
EIMSK |= (1<<INT0);
EICRA |= (1<<ISC00);
EICRA |= (1<<ISC01);
PORTD |= (1<<PORTD2);

// This will start the conversion if trigger INT0 is pressed

}

{
// Assign the data to bInput variable

if((bInput < 900) && (bInput > 800))
{
// B1 is pressed
}
if((bInput < 700) && (bInput > 600))
{
// B2 is pressed
}
if((bInput < 500) && (bInput > 400))
{
// B3 is pressed
}
if((bInput < 300) && (bInput > 200))
{
// B4 is pressed
}
}

ISR(INT0_vect)
{
// nop;
}


And this is the corresponding circuit,

##### Output values I get Now (Tested using a Multi-meter) -
1. When no button is pressed: Vdrop across R = 1.0 V , Vin to ADC module = 1.0 V , Current in the circuit 0.09mA so I think R internal of INT0 is - 44k.
2. If button B1 pressed: Vdrop across R = 4 V , Vin to ADC module = 4 V , ADC registor = 872
3. If button B2 pressed: Vdrop across R = 3 V , Vin to ADC module = 3 V , ADC registor = 695
4. If button B3 pressed: Vdrop across R = 2.32 V , Vin to ADC module = 2.32 V , ADC registor = 520
5. If button B4 pressed: Vdrop across R = 1.698 V , Vin to ADC module = 1.698 V and this is not triggering the INT0 interrupt.

But the problem is - connecting the wire to INT0 pin from same pin connected to the ADC module(highlighted wire) mess things up - I think the internal resistance of pin INT0 causes the problem because R1,R2,R3,R4 and R internal of INT0 pin is connected in parallel. And not only that to trigger the INT0 interrupt I think we need at least 2.5vDC, so when we press the button B4 the voltage drop across the R is - 1.1V and this will not trigger the INT0 interrupt.

#### What I want:

I want the ADC to start a conversion only when I press a button- B1,B2,B3 OR B4.

#### Problem to solve:

So, I need a circuit that can trigger the INT0 interrupt and doesn't mess with button circuit I made...

• So you basically want an interrupt every time the ADC input rises above, say, 0.5 V? The ATMega328P has an internal voltage comparator that could be used for this purpose, or you could add an external chip. Commented Apr 22, 2023 at 14:32
• ADC on this chip may involve a timing algorithm and so would likely not play well with an interrupt. I suggest you just get a discrete expansion if you can't spare the pins. These will essentially spread your values over time on the same pin.
– Abel
Commented Apr 22, 2023 at 15:38