atmega328p reading analog inputs - Page 1
Forum section: electronics / general

author: altruan23
author_rank: Contributor
timestamp: November 21, 2021, 08:37:54 am
content: Hello. So I wanted to read voltages from 2 analog inputs and save them in a variable and print them out. On analog4 there is a voltage 3.3V, onanalog7 it is a 5V. So it schould basically print 684 and 1023 because im using an 10bit ADC. But somehow it only prints the 684. Do u see any mistakesin my Progamm?? datasheet:https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdfCode:#include "Arduino.h"// Global Variablesunsigned long int t_ref; // Reference time// whenever a variable is used by both, Interrupt and main programm we// need to tell the compiler about it ==> volatilevolatile unsigned long int millisekunden; // milli seconds timerunsigned long int last_msg; //char buffer;unsigned int c;int adc4, adc7;void setup() {// Timer 0 konfigurierenTCCR0A = (1 << WGM01); // CTC ModusTCCR0B |= (1 << CS01) | (1 << CS00); // Prescaler 64// ((16000000/64)/1000) = 25OCR0A = 250;// Compare Interrupt erlaubenTIMSK0 |= (1 << OCIE0A);// configure ADCADMUX |= (1 << REFS0) | (1 << MUX2); // Set Reference to AVCC and input to ADC4ADCSRA |= (1 << ADEN) | (1 << ADPS2);ADCSRA |= (1 << ADSC); //start conversionSerial.begin(9600);}void loop() {if (millisekunden - last_msg >= 1000) {while (ADCSRA & (1 << ADSC)) {adc4 = ADC;}ADMUX |= (1 << REFS0) | (1 << MUX2) | (1 << MUX1) | (1 << MUX0);ADCSRA |= (1 << ADSC);while ( ADCSRA & 1 << ADSC) {adc7 = ADC;}sprintf(buffer, "t=[%lu] PINB=[%2.2x] ADC4=[%d] ADC7=[%d] ", millisekunden, PINB, adc4, adc7);Serial.println(buffer);last_msg = millisekunden;}}// Timer-Interrupt-RoutineISR(TIMER0_COMPA_vect) {millisekunden++;}

author: Slh
author_rank: Regular Contributor
timestamp: November 21, 2021, 10:35:27 am
content: Given that it's a fairly simple task and you're using the Arduino libraries already, why don't you just use AnalogRead?Also, it looks like you should be changing the ADC settings twice in the loop but you're only doing it once (set one, read one, set two read two, repeat from set one rather than read one, set two, read two, repeat from read one).

author: altruan23
author_rank: Contributor
timestamp: November 21, 2021, 11:35:42 am
content: no im not allowed to use arduino functions i need to do it with while(adcsra..).i changed it by it isnt working. i dont quit understand what u mean with read one set one..Code:#include "Arduino.h"// Global Variablesunsigned long int t_ref; // Reference time// whenever a variable is used by both, Interrupt and main programm we// need to tell the compiler about it ==> volatilevolatile unsigned long int millisekunden; // milli seconds timerunsigned long int last_msg; //char buffer;unsigned int c;int adc4, adc7;void setup() {// Timer 0 konfigurierenTCCR0A = (1 << WGM01); // CTC ModusTCCR0B |= (1 << CS01) | (1 << CS00); // Prescaler 64// ((16000000/64)/1000) = 25OCR0A = 250;// Compare Interrupt erlaubenTIMSK0 |= (1 << OCIE0A);// configure ADC// Set Reference to AVCC and input to ADC4ADCSRA |= (1 << ADEN) | (1 << ADPS2);//start conversionSerial.begin(9600);}void loop() {if (millisekunden - last_msg >= 1000) {ADMUX |= (1 << REFS0) | (1 << MUX2);ADCSRA |= (1 << ADSC);while (ADCSRA & (1 << ADSC)) {adc4 = ADC;}ADMUX |= (1 << REFS0) | (1 << MUX2) | (1 << MUX1) | (1 << MUX0);ADCSRA |= (1 << ADSC);while ( ADCSRA & 1 << ADSC) {adc7 = ADC;}//int av = ADC; // 16 bit valuesprintf(buffer, "t=[%lu] PINB=[%2.2x] ADC4=[%d] ADC7=[%d] ", millisekunden, PINB, adc4, adc7);Serial.println(buffer);last_msg = millisekunden;}}// Timer-Interrupt-RoutineISR(TIMER0_COMPA_vect) {millisekunden++;}

author: Slh
author_rank: Regular Contributor
timestamp: November 21, 2021, 12:21:19 pm
content: I think your bit maths is wrong. You're using OR equals all the time. If you already have MUX1 and MUX2 set then OR equals MUX1 will not change it. You need to clear MUX2 instead &= or just set the entire register =

author: altruan23
author_rank: Contributor
timestamp: November 21, 2021, 12:41:47 pm
content: I tried it and it still isnt working. And i need to have the MUX2 set because the analoginput7 is 0111 --> MUX3 is 0, MUX2,Mux1 and MUX0 need to be set.

author: DrG
author_rank: Super Contributor
timestamp: November 21, 2021, 01:51:04 pm
content: This is a bit of a puzzle for me - how to help without doing it for you, so I am going to try this.....First, I get that you are spending hours on the problem and that you are frustrated.Please realize that in programming you can have more than one issue. So, the "I changed that and it didn't work", doesn't mean "that" wasn't broken.You have several problems with the code that you posted.Look at the code at the end of this threadhttps://www.avrfreaks.net/forum/sampling-multiple-adc-channelsRead the entire thread and try to understand the code and the data sheet.You can't just copy it for your homework because it does not strictly do what your assignment asks, but there is more than enough there to help you.Hope it helps (but not too much)

author: Simon
author_rank: Unknown
timestamp: November 21, 2021, 09:39:24 pm
content: why bother with the arduino for this? so that you can spit stuff out on serial? if you have figured the ADC out the serial port will be a doddle. Once you are out of that horrible thing you at least know what 90% of the code is rather than the 10% you actually wrote in arduino.

author: DrG
author_rank: Super Contributor
timestamp: November 21, 2021, 09:49:01 pm
content: You have to ask the OP, but I suspect that they are using Arduino because of its cheap availability but the course does not want to go with the rest of...it.

author: Simon
author_rank: Unknown
timestamp: November 21, 2021, 09:55:31 pm
content: You can program the chip on the board with what you like. Using the hardware makes sense as it's a self contained item with everything necessary. But you don't have to write arduino code on it.