#include <avr/io.h>
#include <avr/interrupt.h>
#define LEDButtonPin PA3
#define PotEnablePin PA2
#define pot_DEL_pin PA0
#define pot_DUR_pin PA1
volatile int analogResult=200;
void setup() {
}
void loop() {
PORTA |= (1 << LEDButtonPin);
delay(analogResult);
PORTA &= ~(1 << LEDButtonPin);
delay(analogResult);
PORTA |= (1 << LEDButtonPin);
delay(analogResult);
PORTA &= ~(1 << LEDButtonPin);
delay(3000);
readPots();
}
void readPots() {
DDRA &= ~(1 << pot_DUR_pin);
DDRA |= ((1 << LEDButtonPin) | (1 << PotEnablePin));
PORTA |= (1 << PotEnablePin); // power up POTs
delay(100);
ADMUX |= (1 << MUX0); // ADC1 (PA1) channel is selected
DIDR0 |= (1 << ADC1D); // Digital input disable to save power
ADCSRA |= (1 << ADPS1) | (1 << ADPS0); // lowers ADC clock by 1/8 of CPU clock
ADCSRA |= (1 << ADEN); // Turn on ADC
delay(100);
ADCSRA |= (1 << ADSC); //start convertion
while (ADCSRA & (1 << ADSC) ); //wait for conversion
analogResult = (ADCH << 8) | ADCL; // read val
ADCSRA &= ~(1 << ADEN); // Turn off ADC
ADCSRA &= ~(1 << ADIF); // clear flag
PORTA &= ~(1 << PotEnablePin); // power down POTs
}
I turn the pots, the leds blink rate is always same from the start, if I turn off and on the system then the blink rate updates for once, that's the only way.What makes you think this is true. I can not find any information that prooves it .. neither can I see how it is tested.
I cared about it by pulling unused pins high with input pullupAs soon as you care about supply current you also have to care about floating pins.
LED is used in real circuit but the pots mission is not to set the blink rate but instead it's mission is to determine the value of a variable called "counter" which the Timer1 will countdown from.Are the LEDs only for testing or are they used in the real circuit?
I see some...
while (1) {
.. this really is a loop
.. put your loop code in here
}
If I manage to read one, I'll try the other. I actually did try, it only reads the first pot but second one can't be read.* you only use one ADC channel, the other is never read.
What makes you think this is true. I can not find any information that prooves it .. neither can I see how it is tested.The code I've written so far is below. It reads pot for once but doesn't update in the next loops. Can you help me answer: Why does ADC is able to do only a single conversion?
This contradicts itself: As soon as you care about supply current you also have to care about floating pins.I don't care about the tidyness of the code or floating pins. I am building a system which must run with no supply for a year that's why I must turn off ADC, at least I must try it in the test code.
I turn the pots, the leds blink rate is always same from the start, if I turn off and on the system then the blink rate updates for once, that's the only way.What makes you think this is true. I can not find any information that prooves it .. neither can I see how it is tested.
I cared about it by pulling unused pins high with input pullupAs soon as you care about supply current you also have to care about floating pins.
LED is used in real circuit but the pots mission is not to set the blink rate but instead it's mission is to determine the value of a variable called "counter" which the Timer1 will countdown from.Are the LEDs only for testing or are they used in the real circuit?
Forget the requirements, I want to read two potentiometers whenever I want for a single time literally that's the only goal, I don't care about LEDs, I can modify the code as I desire after I figure out how to comprehend ADC.I see some "requirements" in your text, but I miss them in your code. So I don´t know what is "important" for now and what is not important for me to check.
Wait a sec, It seems like it does the same thing with ADEN, do they both turn on/off the ADC?PRADC
Default value of REFS1 and REFS0 is 0 and this means VCC will be the reference, that's what I want.ADC REF: This is important for ADC function.
ADCSRA |= (1 << ADPS1) | (1 << ADPS0); // lowers ADC clock by 1/8 of CPU clockI miss the prescaler setup... we neither know what your microcontroller frequency is...
What? It is at around bottom lines.I miss ADCSR setup, or any mentioning that you want to use default values...
There are only ADTS bits in this register that are relevant and their default value is zero so I didn't need to make them zero again to enable Free Running Mode, but okay as you wanted sir.I miss ADCSRB setup, or any mentioning that you want to use default values...
I obeyed this. I've written a cleaner version of the code, I included the commands that equalizes registers to their default value for cleaner reading. This doesn't mean I've solved anything about the problem yet.This is good for us, so we see you did check and care about it.
#include <avr/io.h>
#include <avr/interrupt.h>
#define LEDButtonPin PA3
#define PotEnablePin PA2
#define pot_DEL_pin PA0
#define pot_DUR_pin PA1
volatile int analogResult1;
volatile int analogResult2;
void setup() {
DDRA &= ~((1 << pot_DUR_pin) | (1 << pot_DEL_pin));
DDRA |= ((1 << LEDButtonPin) | (1 << PotEnablePin));
DIDR0 |= (1 << ADC1D); // Digital input disable to save power
DIDR0 |= (1 << ADC0D); // Digital input disable to save power
ADCSRA |= (1 << ADPS1) | (1 << ADPS0); // lowers ADC clock by 1/8 of CPU clock
ADMUX &= ~((1<<REFS1) | (1<<REFS0)); // Chose VCC as ADC_ref
ADCSRB &= ~((1<<ADTS2) | (1<<ADTS1) | (1<<ADTS0)); // Choose Free running mode
}
void loop() {
PORTA |= (1 << LEDButtonPin);
delay(analogResult1);
PORTA &= ~(1 << LEDButtonPin);
delay(analogResult2);
PORTA |= (1 << LEDButtonPin);
delay(analogResult1);
PORTA &= ~(1 << LEDButtonPin);
delay(analogResult2);
PORTA |= (1 << LEDButtonPin);
delay(analogResult1);
PORTA &= ~(1 << LEDButtonPin);
delay(3000);
readPots();
}
void readPots() {
PORTA |= (1 << PotEnablePin); // power up POTs
delay(100);
ADMUX &= ~(1 << MUX0); // ADC0 (PA0) channel is selected
ADCSRA |= (1 << ADEN); // Turn on ADC
ADCSRA |= (1 << ADSC); //start convertion
while (ADCSRA & (1 << ADSC) ); //wait for conversion
analogResult1 = (ADCH << 8) | ADCL; // read val
ADMUX |= (1 << MUX0); // ADC1 (PA1) channel is selected
ADCSRA |= (1 << ADSC); //start convertion
while (ADCSRA & (1 << ADSC) ); //wait for conversion
analogResult2 = (ADCH << 8) | ADCL; // read val
//ADCSRA &= ~(1 << ADEN); // Turn off ADC
// PORTA &= ~(1 << PotEnablePin); // power down POTs
}
so maybe this solves the problem:ADCL must be read first, then ADCH, to ensure that the content of the
data registers belongs to the same conversion.
analogResult1 = ADCL; // read val
analogResult1 |=( uint16_t)(ADCH << 8) // read val
Oh, I didn't know the order of the reading matters. Well, I' cant check it right now but if I do a test I will inform this thread.Hi,
The code is much cleaner now.
Still I miss PORTB setup, you said you pulled HIGH all unused pins.
According ADCSR (without -A and without -B): Here I was confused by a typo in the datasheet page 150
Maybe the problem was caused by this: Pages 140, 154
so maybe this solves the problem:
same with result2..Code:analogResult1 = ADCL; // read val analogResult1 |=( uint16_t)(ADCH << 8) // read val
Don´t believe in magic. Even if it´s hard, but always try to find out why somehting does not work as expected.
Klaus
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?