What I want to do: attach six buttons to a single input. Each button triggers a different action.
How I want to do it: Use an AD conversion and add a resistor with different values to each button so that you can distinguish between the different input signals
I use these values: 1k, 4.7k, 18k, 22k, 55k, 300k
Vcc is stable 3.3v but I also tried it on 5v. I use Vcc as reference value for the ADC.
The problem I have: no matter what I do I always read the same value on the ADC. Connected to GND it reads 0 and on Vcc it reads a value that’s always the same regardless what resistor I actually use.
I tried a lot of things I’ve found on the internet but nothing really worked for me. I’m clearly doing something wrong
This is the method I call in setup()
to initialize the converter on ADC2(pb4)
void initADC()
{
// 8-bit resolution
// set ADLAR to 1 to enable the Left-shift result (only bits ADC9..ADC2 are available)
// then, only reading ADCH is sufficient for 8-bit results (256 values)
ADMUX =
(1 << ADLAR) | // left shift result
(0 << REFS1) | // Sets ref. voltage to VCC, bit 1
(0 << REFS0) | // Sets ref. voltage to VCC, bit 0
(0 << MUX3) | // use ADC2 for input (PB4), MUX bit 3
(0 << MUX2) | // use ADC2 for input (PB4), MUX bit 2
(1 << MUX1) | // use ADC2 for input (PB4), MUX bit 1
(0 << MUX0); // use ADC2 for input (PB4), MUX bit 0
ADCSRA =
(1 << ADEN) | // Enable ADC
(1 << ADPS2) | // set prescaler to 64, bit 2
(1 << ADPS1) | // set prescaler to 64, bit 1
(0 << ADPS0); // set prescaler to 64, bit 0
}
The code is taken from here https://www.marcelpost.com/wiki/index.php/ATtiny85_ADC
The page seems to be down at the moment so here is an archived version of it https://web.archive.org/web/20230128091128/https://www.marcelpost.com/wiki/index.php/ATtiny85_ADC
In the loop()
method I do basically this: Read ADC and then blink an LED n times, based on the read value.
ADCSRA |= (1 << ADSC); // start ADC measurement
while (ADCSRA & (1 << ADSC) ); // wait till conversion complete
uint8_t adcValue = ADCH;
if (adcValue >= 0 && adcValue < 32) {
blink(1);
} else if (adcValue >= 32 && adcValue < 126) {
blink(2);
} else if (adcValue >= 126 && adcValue < 193) {
blink(3);
} else if (adcValue >= 193 && adcValue < 227) {
blink(4);
} else if (adcValue >= 227 && adcValue < 245) {
blink(5);
} else if (adcValue >= 245 && adcValue <= 255) {
blink(6);
}
delay(60000);
My breadboard has the resistors going from Vcc to an empty row and I connect a jumperwire from PB4 to one of these resistors and do an external reset of the microcontroller to test my setup. They share GND/Vcc
What am I doing wrong? What can I do to debug this?
Thanks
analogRead()
or is there another reason why you are directly reading ADC registers ? The ADC is 10bit so can read analog values up to 1023. Does your application allow for pressing two or more buttons simultaneously? If you have a multimeter you could check the voltage between the analog pin and ground when a button is pressed.