Hello.
I want to read 2 analog inputs and print them out every second, but i dont know how to do that. Can anyone help me?
the datasheet can be found here:
https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf#include "Arduino.h"
// Global Variables
unsigned 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 ==> volatile
volatile unsigned long int millisekunden; // milli seconds timer
unsigned long int last_msg; //
char buffer[256];
unsigned int c;
unsigned int adc2;
unsigned int adc5;
void setup() {
// Timer 0
TCCR0A = (1 << WGM01); // CTC Mode
TCCR0B |= (1 << CS01) | (1 << CS00); // Prescaler 64
OCR0A = 250;
// Compare Interrupt
TIMSK0 |= (1 << OCIE0A);
// ADC
ADCSRA |= (1 << ADEN) | (1 << ADPS2) | (1 << ADIE);
ADMUX |= (1 << REFS0) | (1 << MUX1); // avcc and ADC2
ADCSRA |= 1 << ADSC; // start cconversion
Serial.begin(9600);
}
void loop() {
if (millisekunden - last_msg >= 1000) {
sprintf(buffer, "\nt=[%lu] adc2=%d, adc5=%d",
millisekunden, adc2, adc5);
Serial.println(buffer);
last_msg = millisekunden;
}
}
// Timer-Interrupt-Routine
ISR(TIMER0_COMPA_vect) {
millisekunden++;
}
ISR(ADC_vect) {
adc2 = ADC;
ADCSRA |= 1 << ADSC;
}
Im not allowed to use arduino functions... im just using the platform but our teacher doesnt allow us to use that.
You don't need to use use any interrupts or timers (unless the teachers says you must use interrupts).
Setup
- Configure the ADC reference to what you want to use, probably AVCC pin.
Loop
- Set the ADC channel to the correct channel for the first ADC input you want to read
- Start an ADC conversion by writing 1 to the correct bit of the ADC control registers
- Wait in a loop for the ADC conversion complete bit to become set
- Read the ADC data register value and print it or whatever
- Set the ADC channel to the correct channel for the second ADC input you want to read
- Start an ADC conversion by writing 1 to the correct bit of the ADC control registers
- Wait in a loop for the ADC conversion complete bit to become set
- Read the ADC data register value and print it or whatever
i only know this way to read 1 value. how can i read another one and print them both out?
So i tried to solve it with an array but it doesnt want to work. it saves just 1 value in both array places.
#include "Arduino.h"
// Global Variables
unsigned 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 ==> volatile
volatile unsigned long int millisekunden; // milli seconds timer
unsigned long int last_msg; //
char buffer[256];
unsigned int c;
unsigned int adc2;
unsigned int adc5;
unsigned int anVal[2];
volatile unsigned int adc_curr_ch = 0;
void setup() {
// Timer 0
TCCR0A |= (1 << WGM01); // CTC Mode
TCCR0B |= (1 << CS01) | (1 << CS00); // Prescaler 64
OCR0A = 250;
// Compare Interrupt
TIMSK0 |= (1 << OCIE0A);
// ADC
ADCSRA |= (1 << ADEN) | (1 << ADPS2) | (1 << ADIE);
ADMUX |= (1 << REFS0); // avcc
ADCSRA |= 1 << ADSC; // start cconversion
Serial.begin(9600);
}
void loop() {
if (millisekunden - last_msg >= 1000) {
sprintf(buffer, "\nt=[%lu] ADC0=%d ADC1=%d ",
millisekunden, anVal[0], anVal[1]);
last_msg = millisekunden;
Serial.println(buffer);
}
}
// Timer-Interrupt-Routine
ISR(TIMER0_COMPA_vect) {
millisekunden++;
}
ISR(ADC_vect) {
anVal[adc_curr_ch] = ADC;
// save to adc2
if (adc_curr_ch == 0) {
ADMUX |= (1 << MUX1);
adc_curr_ch = 1;
}
// save to adc5
else if (adc_curr_ch == 1) {
ADMUX |= (1 << MUX2) | (1 << MUX0);
ADMUX &= ~(1 << MUX1);
adc_curr_ch = 0;
}
ADCSRA |= 1 << ADSC;
}
Your anVal array needs to be made volatile.
Also, check your MUX settings are correct. Looks like you are starting on ADC2 but then switching between ADC5 and ADC7 because MUX2 and MUX0 are never cleared. So it's switching between 101 and 111
still isnt working. can u just pls check my code and repair it? i really dont have time i waster already 4hourse today and im writing the exam in 2 days.
[code]ISR(ADC_vect) {
anVal[adc_curr_ch] = ADC;
// save to adc2
if (adc_curr_ch == 0) {
ADMUX |= (1 << MUX1);
ADMUX &= ~(1 << MUX2) | ( 1 << MUX0);
adc_curr_ch = 1;
}
// save to adc5
else if (adc_curr_ch == 1) {
ADMUX |= (1 << MUX2) | (1 << MUX0);
ADMUX &= ~(1 << MUX1);
adc_curr_ch = 0;
}
ADCSRA |= 1 << ADSC;
}
[/code]
I'm happy to point out errors, but I'm not writing your homework for you.
You're missing a ~ for the (1 << MUX0) when you clear ADMUX.
i fixed it but still isnt working.
#include "Arduino.h"
// Global Variables
unsigned 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 ==> volatile
volatile unsigned long int millisekunden; // milli seconds timer
unsigned long int last_msg; //
char buffer[256];
unsigned int c;
unsigned int adc2;
unsigned int adc5;
volatile unsigned int anVal[2];
volatile unsigned int adc_curr_ch = 0;
void setup() {
// Timer 0
TCCR0A |= (1 << WGM01); // CTC Mode
TCCR0B |= (1 << CS01) | (1 << CS00); // Prescaler 64
OCR0A = 250;
// Compare Interrupt
TIMSK0 |= (1 << OCIE0A);
// ADC
ADCSRA |= (1 << ADEN) | (1 << ADPS2) | (1 << ADIE);
ADMUX |= (1 << REFS0); // avcc
ADCSRA |= 1 << ADSC; // start cconversion
Serial.begin(9600);
}
void loop() {
if (millisekunden - last_msg >= 1000) {
sprintf(buffer, "\nt=[%lu] ADC0=%d ADC1=%d ",
millisekunden, anVal[0], anVal[1]);
last_msg = millisekunden;
Serial.println(buffer);
}
}
// Timer-Interrupt-Routine
ISR(TIMER0_COMPA_vect) {
millisekunden++;
}
ISR(ADC_vect) {
anVal[adc_curr_ch] = ADC;
// save to adc2
if (adc_curr_ch == 0) {
ADMUX |= (1 << MUX1);
ADMUX &= ~(1 << MUX2);
ADMUX &= ~( 1 << MUX0);
adc_curr_ch = 1;
}
// save to adc5
else if (adc_curr_ch == 1) {
ADMUX |= (1 << MUX2) | (1 << MUX0);
ADMUX &= ~(1 << MUX1);
adc_curr_ch = 0;
}
ADCSRA |= 1 << ADSC;
}
hmm, did you enable the global interrupt with sei() ?
unfortunately. thats not the problem