Author Topic: atmega328p reading analog inputs  (Read 2335 times)

0 Members and 1 Guest are viewing this topic.

Offline altruan23Topic starter

  • Contributor
  • Posts: 17
  • Country: si
atmega328p reading analog inputs
« on: November 21, 2021, 08:37:54 am »
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, on
analog7 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 mistakes
in my Progamm?? datasheet: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf
Code: [Select]
#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[64];
unsigned int c;
int adc4, adc7;
void setup() {

  // Timer 0 konfigurieren
  TCCR0A = (1 << WGM01); // CTC Modus
  TCCR0B |= (1 << CS01) | (1 << CS00); // Prescaler 64
  // ((16000000/64)/1000) = 25
  OCR0A = 250;
  // Compare Interrupt erlauben
  TIMSK0 |= (1 << OCIE0A);

  // configure ADC

  ADMUX |= (1 << REFS0) | (1 << MUX2); // Set Reference to AVCC and input to ADC4
  ADCSRA |= (1 << ADEN) | (1 << ADPS2);


  ADCSRA |= (1 << ADSC); //start conversion




  Serial.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-Routine
ISR(TIMER0_COMPA_vect) {
  millisekunden++;
}
 

Offline Slh

  • Regular Contributor
  • *
  • Posts: 121
  • Country: gb
Re: atmega328p reading analog inputs
« Reply #1 on: November 21, 2021, 10:35:27 am »
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).
 

Offline altruan23Topic starter

  • Contributor
  • Posts: 17
  • Country: si
Re: atmega328p reading analog inputs
« Reply #2 on: November 21, 2021, 11:35:42 am »
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: [Select]
#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[64];
unsigned int c;
int adc4, adc7;
void setup() {

  // Timer 0 konfigurieren
  TCCR0A = (1 << WGM01); // CTC Modus
  TCCR0B |= (1 << CS01) | (1 << CS00); // Prescaler 64
  // ((16000000/64)/1000) = 25
  OCR0A = 250;
  // Compare Interrupt erlauben
  TIMSK0 |= (1 << OCIE0A);

  // configure ADC

  // Set Reference to AVCC and input to ADC4
  ADCSRA |= (1 << ADEN) | (1 << ADPS2);


  //start conversion




  Serial.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 value
    sprintf(buffer, "t=[%lu] PINB=[%2.2x] ADC4=[%d] ADC7=[%d] ", millisekunden, PINB, adc4, adc7);
    Serial.println(buffer);
    last_msg = millisekunden;




  }

}

// Timer-Interrupt-Routine
ISR(TIMER0_COMPA_vect) {
  millisekunden++;
}
 

Offline Slh

  • Regular Contributor
  • *
  • Posts: 121
  • Country: gb
Re: atmega328p reading analog inputs
« Reply #3 on: November 21, 2021, 12:21:19 pm »
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 =
 

Offline altruan23Topic starter

  • Contributor
  • Posts: 17
  • Country: si
Re: atmega328p reading analog inputs
« Reply #4 on: November 21, 2021, 12:41:47 pm »
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.
 

Offline DrG

  • Super Contributor
  • ***
  • !
  • Posts: 1199
  • Country: us
Re: atmega328p reading analog inputs
« Reply #5 on: November 21, 2021, 01:51:04 pm »
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 thread https://www.avrfreaks.net/forum/sampling-multiple-adc-channels Read 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 :) )
- Invest in science - it pays big dividends. -
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: atmega328p reading analog inputs
« Reply #6 on: November 21, 2021, 09:39:24 pm »
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.
 

Offline DrG

  • Super Contributor
  • ***
  • !
  • Posts: 1199
  • Country: us
Re: atmega328p reading analog inputs
« Reply #7 on: November 21, 2021, 09:49:01 pm »
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.
- Invest in science - it pays big dividends. -
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: atmega328p reading analog inputs
« Reply #8 on: November 21, 2021, 09:55:31 pm »
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.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf