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.

Support Forum » What am I doing wrong? (Tempsensor)

December 27, 2011
by Drwish
Drwish's Avatar

So far so good, until the tempsensor project that is =P. When I flash my MCU with my code, it does not show anything on the LCD when put back to normal mode and power cycled. When I flash the example tempsensor code, everything is fine and dandy. (I'm amazed at how accurate the sensor is!) So, here's an opporutnity to try the prestigious NerdKits support. I hope you can help me out!

My code:

// tempsensor.c
// for NerdKits with ATmega168
// mrobbins@mit.edu

#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() {
//Set Analog to Digital Converter to input ADC0
    ADMUX = 0;

//Enable the ADC and set clock cycle to 1/128 of system clock
    ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);

//Do one conversation just to get ADC warmed up.
//Needs to warm up because first conversion
//takes 25 ADC clock cycles, next takes 13
    ADCSRA |= (1<<ADSC);

}

uint16_t adc_read() {
    while(ADCSRA & (1<<ADEN)){
    //do nothing while you wait for the conversion to be over.
    }
//conversion is over, read ADCL first then ADCH
    uint16_t result = ADCL;
    uint16_t temp = ADCH;
    //because ADCH is the higher bits, shift by 8
    temp = temp<<8;
    //combine ADCL and ADCH
    result = result + temp;

    //get ready for next conversion
    ADCSRA |= (1<<ADSC);

    //return the converted result
    return result;
}
double sampleToFahrenheit(uint16_t sample) {

    return sample * (5000.0 / 1024.0 / 10.0);

}
//  double sampleToCelcius(unint16_t sample){
//  return sampletoFahrenheight(sample) - 32.0 * (5.0/9.0);
//}

int main() {
    //start the LCD
    lcd_init();
    //set it up as a stream
    FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
    lcd_home();

    //start the ADC
    adc_init();

    //start up the serial port
    uart_init();
    FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
    stdin = stdout = &uart_stream;

    //holder variables for data
    uint16_t last_sample;
    double avg_ftemp;
    double avg_ctemp;
    double this_temp;
    uint8_t i;
  while(1) {   
    //take 100 samples, averge them.
    // start with a 0 average.
    avg_ftemp = 0.0;
    avg_ctemp = 0.0;
    for(i=0; i<100; i++) {
        last_sample = adc_read();
        avg_ftemp += sampleToFahrenheit(last_sample);
        //avg_ctemp += sampleToCelcius(last_sample);
    }
    avg_ftemp = avg_ftemp / 100;
    avg_ctemp = avg_ctemp / 100;

    // write message to LCD
    lcd_home();
    lcd_write_string(PSTR("ADC: "));
    lcd_write_int16(last_sample);
    lcd_write_string(PSTR(" of 1024   "));
    lcd_line_two();
    fprintf_P(&lcd_stream, PSTR("Temperature: %.2f"), avg_ftemp);
    lcd_write_data(0xdf);
    lcd_write_string(PSTR("F      "));

    // write message to serial portf
    printf_P(PSTR("%.2f degrees F\r\n"), avg_ftemp);

  }

  return 0;
}
December 27, 2011
by Drwish
Drwish's Avatar

Also just an FYI, my intent was to also add Celsius, but my function was giving me errors about expecting "a '<' before samples" so I decided to see if my code would run Fahrenheit first, but it didn't, and here I am.

December 27, 2011
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Drwish,

Do you get absolutely nothing on your LCD when you load your program? I don't really see anything in your code that would cause that. The error you were getting when you had your Celsius conversion function was happening because you misspelled uint16_t on line 60 above.

Humberto

December 27, 2011
by Drwish
Drwish's Avatar

Yep nothing at all. Here are some pictures describing my progress:

MCU flashed with example code

MCU put into programming mode

Flashing my code, completed successfully (notice the directory)

rebooting in normal mode. Nothing.

Reboot in programming mode, still nothing, but WinAVR is still successful in programming it.

Changed some text for sake of demonstration and here we are again at square one with the example file flashed again:

=(

December 27, 2011
by Rick_S
Rick_S's Avatar

Do you have a screen shot of the actual compile? Try deleting the .hex, and .o file in the tempsensor_edu folder, also, delete the .o files in the libnerdkit folder. Then re-compile your program and show a screenshot of the process. I'm thinking something is going wrong or getting confused in the compile stage.

Rick

December 27, 2011
by Drwish
Drwish's Avatar

Deleted the object and hex files in tempsensor_edu, tempsensor, and libnerdkit and still the same result.

December 27, 2011
by Drwish
Drwish's Avatar

Oh wait, slight change. Now after flashing my program, I still have a blank screen. When I put it back into programming mode however, I get the 2 black lines on the LCD. I then put it back into normal mode and the LCD returned to a blank state. When I put in programming mode again, I get the black lines. I repeated this about 2 more times, with the same results. Step in the right direction I suppose.

December 27, 2011
by Drwish
Drwish's Avatar

Another update:

I copied and pasted the sample code into my program, replacing completley what I had, saved, compiled, flashed to my MCU and it ran like normal.This mean that it has to be a problem in my code...

December 27, 2011
by Rick_S
Rick_S's Avatar

Maybe try printing something to the display after the first lcd_home() command like..

lcd_write_string(PSTR("I'm Here..."));
delay_ms(500);

Try inserting those after line 69 in the above file. See if it displays that.

December 27, 2011
by Drwish
Drwish's Avatar

Hmm...

December 28, 2011
by Rick_S
Rick_S's Avatar

Well, that means your program is working but hanging somewhere for some reason. My next step would generally be to start sprinkling that statement elsewhere to find the point at which it goes bad.

This is at least progress. BigGrin_Green

Rick

December 28, 2011
by Rick_S
Rick_S's Avatar

Nevermind... I think I may have found your problem.

Line 37 - Your adc_read function

uint16_t adc_read() {
  while(ADCSRA & (1<<ADEN)){
    //do nothing while you wait for the conversion to be over.
    } 
  //conversion is over, read ADCL first then ADCH
  uint16_t result = ADCL;
  uint16_t temp = ADCH;
  //because ADCH is the higher bits, shift by 8
  temp = temp<<8;
  //combine ADCL and ADCH
  result = result + temp;
  //get ready for next conversion
  ADCSRA |= (1<<ADSC);
  //return the converted result
  return result;
}

In your while statement you coded:

while(ADCSRA & (1<<ADEN))

And that should be

while(ADCSRA & (1<<ADSC))

You are checking a wrong register and as such your code is hanging there on the 1st attempt at reading the ADC.

ADSC is the Analog to Digital Start Conversion bit. When this bit is set, a conversion is started and it is automatically cleared by hardware when the conversion is complete. ADEN is the enable of the ADC and doesn't change from hardware. Since ADEN was set to 1 in the initialization, your code hangs because it never zero's out.

Rick

December 28, 2011
by Drwish
Drwish's Avatar

Yep that seemed to do the trick! What's amazing is that wasn't the first time I made that mistake. I guess somewhere in mind, Enable and Start Conversation are too similar. Thanks Rick, Humberto. =)

December 28, 2011
by hevans
(NerdKits Staff)

hevans's Avatar

Great catch Rick! I've been scratching my head about this one for a whole day!

Humberto

December 28, 2011
by Rick_S
Rick_S's Avatar

Thanks BigGrin_Green I knew after I saw it display the I'm Here message I had told him to add, that it had to be something simple. I'm just glad to have come home from work to see it working for him.

Rick

December 28, 2011
by Rick_S
Rick_S's Avatar

Drwish, did support live up to your expectations?? Wink

December 28, 2011
by Drwish
Drwish's Avatar

It sure did!

Post a Reply

Please log in to post a reply.

Did you know that multiple MOSFETs can be used in parallel to switch bigger currents on and off? Learn more...