NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Basic Electronics » Problem with code (2 inputs)

February 23, 2012
by Langermanagement
Langermanagement's Avatar

Here is the code :

#define F_CPU 14745600

#include <stdio.h>
#include <math.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>

#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/uart.h"

// PIN DEFINITIONS:
//
// PC0 -- temperature sensor analog input

void adc_init(int inputpin) {

ADMUX = inputpin;

ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);  // makes ADCSRA retain the bits 100000111

ADCSRA |= (1<<ADSC); //(Adds 1 with certain amount of zeros to current ADCSRA value)

}

uint16_t adc_read() {

while (ADCSRA & (1<<ADSC)){ //(this will always be true)
}

uint16_t f8bit = ADCL; // (Stores first 8 bits)
uint16_t l2bit = ADCH; // (Stores last 2 bits)

uint16_t value = f8bit + (l2bit<<8); //(puts the bits side by side (10bit value))

ADCSRA |= (1<<ADSC); // resets the values

return value;

}

int main() {

 // start up the LCD
  lcd_init();
 // FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
  lcd_home();

  // start up the Analog to Digital Converter
  adc_init(0);
  uint16_t input1 = adc.read();
  adc_init(1);
  uint16_t input2 = adc.read();

  // start up the serial port
  uart_init();
  FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW); // These two lines are implemented variables
  stdin = stdout = &uart_stream;

    // write message to LCD
    lcd_home();
    lcd_write_string(PSTR("ADC: "));
    lcd_write_int16(input1);
    lcd_write_string(PSTR(" of 1024   "));

    lcd_line_two();
    lcd_write_string(PSTR("ADC: "));
    lcd_write_int16(input2);
    lcd_write_string(PSTR(" of 1024   "));

    // write message to serial port
    //printf_P(PSTR("%.2f degrees F\r\n"), temp_avg); // WHAT DOES THIS DO?

  return 0;
}

The message that I get from command prompt when I try to download this code is:

  • adc is undeclared
February 23, 2012
by Rick_S
Rick_S's Avatar

In lines 54 and 56 the adc.read should be adc_read. Don't know why they are like that...

Rick

February 23, 2012
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Langermanagement,

You seem to be using adc.read(), I think you meant adc_read().

Humberto

February 23, 2012
by Langermanagement
Langermanagement's Avatar

Thanks Rick,

I'm using to programming in java, and am completely new to this stuff.

February 23, 2012
by Langermanagement
Langermanagement's Avatar

Ok, it compiled as planned

Unfortunately it prints two of the same inputs even though input 1 should have a value of 0 . Both show a value of about 380 to 420.

February 23, 2012
by Langermanagement
Langermanagement's Avatar

I got it to compile, Unfortunately both inputs seem to have the same value, despite the fact that nothing is hooked up into the input 1 on my breadboard. What in the code could be causing this?

Thanks for all your help

Lucas

February 23, 2012
by Langermanagement
Langermanagement's Avatar

sorry for double post, was viewing from an old window

February 23, 2012
by Rick_S
Rick_S's Avatar

You need someting connected to it otherwise it will pick up stray interference and give erroneous readings. A simple test would be to connect it to GND and see if it reads zero, then disconnect GND and connect it to 5V. It should read 1023 or something close. If it does, then it is working.

Rick

February 23, 2012
by Langermanagement
Langermanagement's Avatar

Rick,

I did the exact test which you suggested and it gave me the 0 and 1023 values I expected.

How can I get separate values for the two inputs?

February 23, 2012
by Rick_S
Rick_S's Avatar

One thing I noticed, you don't need to re-initialize the ADC everytime you change channels to read. All you have to do is set ADMUX to the channel you want to read.

Other than that, I'm not too sure what you meant by "it gave me the 0 and 1023 values I expected" and then you asked how to get separate values. Did it work as expected or not??

Here is a sample of how I did it a while ago.

Rick

February 23, 2012
by Langermanagement
Langermanagement's Avatar

I changed the code.

I am still getting the same input for both pins for some reason.

The input value always seems to be that of pin0

February 24, 2012
by Rick_S
Rick_S's Avatar

OK, a couple of changes to your code above. I don't know what you have changed already, but there were some issues as written.

uint16_t adc_read() {

  // This actually starts a conversion does not reset values.

ADCSRA |= (1<<ADSC); // resets the values

  // This while statement is NOT always true, it is only true 
  // when a conversion has been completed.  
  while (ADCSRA & (1<<ADSC)){ //(this will always be true)
   }

  uint16_t f8bit = ADCL; // (Stores first 8 bits)

  uint16_t l2bit = ADCH; // (Stores last 2 bits)

  uint16_t value = f8bit + (l2bit<<8); //(puts the bits side by side (10bit value))

  return value;

}

int main() {

  // start up the LCD

  lcd_init();

  // FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);

  lcd_home();

  // start up the Analog to Digital Converter

  adc_init(0);

  uint16_t input1 = 0;

  uint16_t input2 = 0;

  // start up the serial port

  uart_init();

  FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW); // These two lines are implemented variables

  stdin = stdout = &uart_stream;

  while(1){

    ADMUX=0;
    input1=adc_read();
    ADMUX=1;
    input2=adc_read();

    // write message to LCD

    lcd_home();

    lcd_write_string(PSTR("ADC: "));

    lcd_write_int16(input1);

    lcd_write_string(PSTR(" of 1024   "));

    lcd_line_two();

    lcd_write_string(PSTR("ADC: "));

    lcd_write_int16(input2);

    lcd_write_string(PSTR(" of 1024   "));

    }

  // write message to serial port

  //printf_P(PSTR("%.2f degrees F\r\n"), temp_avg); // WHAT DOES THIS DO?

  return 0;
}

Try these changes. I rearranged the flow in adc_read so that you get the value of your current reading. I also changed your main so you aren't re-declaring your variables and re-initializing everything. Plus, you had no loop in main to repeat.

Warning

I hand typed this and did not actually compile the code to beware of typo's Tongue in Cheek

Rick

Post a Reply

Please log in to post a reply.

Did you know that a piezoelectric buzzer can be used to play music with your microcontroller? Learn more...