Two analog sensors connected to ATmega16

Thread Starter

Beginner0001

Joined Sep 29, 2017
21
Hey,

I am trying to work with to analog sensors connected to ATmega16. The first one is LM35 temperature sensor connected to PA0, the second one is photoresistor, connected to PA1. Also I have connected two LEDs to PB0 and PB1. LED1 should be ON when the temperature goes high and LED2 turns ON when the lighting is low. Here is a code I tryed, but it's not working:

Code:
#include <avr/io.h>
#include <util/delay.h>

void InitADC()
{
    ADMUX=(1<<REFS0);                                     // Aref=AVcc;
    ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);    //Rrescalar div factor =128

}

uint16_t ReadADC(uint8_t ch)
{
    ch=ch&0b00000111;
    ADMUX&=0b11100000;
    ADMUX|=ch;

    ADCSRA|=(1<<ADSC);
    
     while(!(ADCSRA & (1<<ADIF)));
     ADCSRA|=(1<<ADIF);
    
    return(ADC);
}

void main()
{
    InitADC();
    DDRB=0Xff;
    uint16_t adc_result[2];

 while(1)
 {
     adc_result[0]=ReadADC(0);           // Read PA0
     adc_result[1]=ReadADC(1);           // Read PA1       
    
     if(adc_result[0]>60) //id it is more then 30 degrees
     { PORTB|=(1<<0);  } //LED1 ON
     else
     { PORTB &=~(1<<0);} //LED1 OFF
        
     if(adc_result[1]<50)  //light lower then 50
     { PORTB|=(1<<4);  } //LED2 ON
     else
     { PORTB &=~(1<<4);}  //LED2 OFF

 }
 }

I'm also uploading a schematis:

1651872768096.png

Can you help understand why the code is not working? Also you can share an example of similar code, or some instructions how can I do it..
 

MrChips

Joined Oct 2, 2009
30,821
Can you help understand why the code is not working? Also you can share an example of similar code, or some instructions how can I do it..
What do you mean by "the code is not working"?

This too common a problem with any microcontroller development project. It is very unlikely that anyone is going to spend the time to wade through your code to find that one bug in your code. Suppose there are 10 bugs. How would you find them all?

This is something you have to learn to do on your own.
If your project, hardware or software, worked perfectly the first time then (1) consider yourself lucky and (2) you would have missed a perfect opportunity to develop your analytical and problem solving skills.

Start simple. Don't attempt to develop and debug a complex program all at once.

First step
Write the simplest program to show that you can flash one LED at a certain rate.
Do this and show us your work. Then we will go to the step.
 

Thread Starter

Beginner0001

Joined Sep 29, 2017
21
What do you mean by "the code is not working"?
The code is working just for PA0, ie first sensor (and first LED), but nothing happens with the second sensor (LED is not turning ON)

Write the simplest program to show that you can flash one LED at a certain rate.
There is a code that is working for both sensors separately :

Code:
void ADC_Init()
{
    DDRA=0x0;           
    ADCSRA = 0x87;           
    ADMUX = 0x40;    //selecting PA0
}
int ADC_Read(char ch)
{
    ADMUX= (ADMUX & 0xF0) | (ch & 0x0F);
    ADCSRA |= (1 << ADSC);
    while (ADCSRA & (1 << ADSC));
    return ADC;

int main()
{     
       ADC_Init();
       DDRB=0xFF;
       uint8_t value;
        
    while(1)
    {
       value=ADC_Read(0);   //reading pin 0 
        
        if(value > 60)
        {PORTB|=(1<<0);}  //turning ON LED connected to PB0
        else
        {PORTB &=~(1<<0);} //turning LED off
    }
}
Of course, for the second sensor I would change some things:
ADMUX: 0x41; also
value=ADC_Read(1); and I would blink the second LED:
if(value < 50)
{PORTB|=(1<<1);}
else
{PORTB &=~(1<<1);}

The point is both sensors are working properly with this code, but I don't know how to make them work together. What can I change in my code? Your advice would be very helpful.
 

MrChips

Joined Oct 2, 2009
30,821
Ok. Let's review some parts of your code.

{PORTB|=(1<<0);} //turning ON LED connected to PB0

Why make your code so cryptic?
If you want to set PB0 to 1 why not make your code more readable?

PORTB |= BIT0;

assuming that we have defined BIT0 as 1;

Better yet, use structures so that you can write:
PORTB.bit0 = ON;
PORTB.bit0 = OFF;
 

Thread Starter

Beginner0001

Joined Sep 29, 2017
21
Ok. Let's review some parts of your code.

{PORTB|=(1<<0);} //turning ON LED connected to PB0

Why make your code so cryptic?
If you want to set PB0 to 1 why not make your code more readable?

PORTB |= BIT0;

assuming that we have defined BIT0 as 1;

Better yet, use structures so that you can write:
PORTB.bit0 = ON;
PORTB.bit0 = OFF;
I can do that, but will that solve my problem, or at least bring me closer to a solution?
 

MrChips

Joined Oct 2, 2009
30,821
I can do that, but will that solve my problem, or at least bring me closer to a solution?
Maybe it doesn’t but it makes your code more readable and more easily understood. This must always be an important objective if you want to be able to debug and maintain code effectively.
 

MrChips

Joined Oct 2, 2009
30,821
I would guess that your problem is in this function:
C:
uint16_t ReadADC(uint8_t ch)
{
    ch=ch&0b00000111;
    ADMUX&=0b11100000;
    ADMUX|=ch;

    ADCSRA|=(1<<ADSC);
    
     while(!(ADCSRA & (1<<ADIF)));
     ADCSRA|=(1<<ADIF);
    
    return(ADC);
}
I would suggest that you insert a delay after writing to the ADMUX.

I have not studied how you are testing for ADC conversion complete. You may want to reexamine this. You may try just waiting for some delay time before reading the ADC register rather than testing the flag (just for a temporary solution to finding the fault).
 
Top