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.

Project Help and Ideas » IF ELSE STATEMENT TEMPSENSOR HELP

January 17, 2011
by missle3944
missle3944's Avatar

Hi Ive recently completed the tempsensor project and the blinking LED project and now I want to combine them both. I want to use the if else statement to turn on a LED when the temperature reaches over a certain point. This is my code but it receives numerous errors. I just thought I'd take a stab at it but it looks like it is a tuffy.

    // 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 <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.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
  // for external reference (5v), single ended input ADC0
  ADMUX = 0;

  // set analog to digital converter
  // to be enabled, with a clock prescale of 1/128
  // so that the ADC clock runs at 115.2kHz.
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);

  // fire a conversion just to get the ADC warmed up
  ADCSRA |= (1<<ADSC);
}

uint16_t adc_read() {
  // read from ADC, waiting for conversion to finish
  // (assumes someone else asked for a conversion.)
  // wait for it to be cleared
  while(ADCSRA & (1<<ADSC)) {
    // do nothing... just hold your breath.
  }
  // bit is cleared, so we have a result.

  // read from the ADCL/ADCH registers, and combine the result
  // Note: ADCL must be read first (datasheet pp. 259)
  uint16_t result = ADCL;
  uint16_t temp = ADCH;
  result = result + (temp<<8);

  // set ADSC bit to get the *next* conversion started
  ADCSRA |= (1<<ADSC);

  return result;
}

double sampleToFahrenheit(uint16_t sample) {
  // conversion ratio in DEGREES/STEP:
  // (5000 mV / 1024 steps) * (1 degree / 10mV)
  //    ^^^^^^^^^^^      ^^^^^^^^^^
  //     from ADC         from LM34
  return sample * (5000.0 / 1024.0 / 10.0);  
}

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();

  // 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 temperature data
  uint16_t last_sample = 0;
  double this_temp;
  double temp_avg;
  uint8_t i;

  while(1) {

    if ( sample %.2f < 80) {

        DDRC |= (1<<PC3);
    // turn on YELLOw LED
        PORTC |= (1<<PC3);

    //delay for 500 milliseconds to let the light stay on
        delay_ms(1000);

    // turn off LED
        PORTC &= ~(1<<PC3);

    //delay for 500 milliseconds to let the light stay off
        delay_ms(600);
    }
    else{

        DDRC |= (1<<PC4);
    // turn on RED LED
        PORTC |= (1<<PC4);

    //delay for 500 milliseconds to let the light stay on
        delay_ms(1000);

    // turn off LED
        PORTC &= ~(1<<PC4);

    //delay for 500 milliseconds to let the light stay off
        delay_ms(1200);
    }

    // take 100 samples and average them!
    temp_avg = 0.0;
    for(i=0; i<100; i++) {
      last_sample = adc_read();
      this_temp = sampleToFahrenheit(last_sample);

      // add this contribution to the average
      temp_avg = temp_avg + this_temp/100.0;
    }

    // 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("The Temp is %.2f"), temp_avg);
    lcd_write_data(0xdf);
    lcd_write_string(PSTR("F      "));

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

  return 0;
}
January 17, 2011
by Ralphxyz
Ralphxyz's Avatar

Move your code down below line 127 an use this_temp instead of sample.

That is my best guess without trying it.

Ralph

January 17, 2011
by missle3944
missle3944's Avatar

Thanks Ralph, for your suggestion, I got it to work because I put in the this_temp for sample temp. Now I am trying to display a message on the LCD. I am also trying to use the if else statement along with if and else but it wont work.

// 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 <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.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
  // for external reference (5v), single ended input ADC0
  ADMUX = 0;

  // set analog to digital converter
  // to be enabled, with a clock prescale of 1/128
  // so that the ADC clock runs at 115.2kHz.
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);

  // fire a conversion just to get the ADC warmed up
  ADCSRA |= (1<<ADSC);
}

uint16_t adc_read() {
  // read from ADC, waiting for conversion to finish
  // (assumes someone else asked for a conversion.)
  // wait for it to be cleared
  while(ADCSRA & (1<<ADSC)) {
    // do nothing... just hold your breath.
  }
  // bit is cleared, so we have a result.

  // read from the ADCL/ADCH registers, and combine the result
  // Note: ADCL must be read first (datasheet pp. 259)
  uint16_t result = ADCL;
  uint16_t temp = ADCH;
  result = result + (temp<<8);

  // set ADSC bit to get the *next* conversion started
  ADCSRA |= (1<<ADSC);

  return result;
}

double sampleToFahrenheit(uint16_t sample) {
  // conversion ratio in DEGREES/STEP:
  // (5000 mV / 1024 steps) * (1 degree / 10mV)
  //    ^^^^^^^^^^^      ^^^^^^^^^^
  //     from ADC         from LM34
  return sample * (5000.0 / 1024.0 / 10.0);  
}

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();

  // 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 temperature data
  uint16_t last_sample = 0;
  double this_temp;
  double temp_avg;
  uint8_t i;

  while(1) {

    // take 100 samples and average them!
    temp_avg = 0.0;
    for(i=0; i<100; i++) {
      last_sample = adc_read();
      this_temp = sampleToFahrenheit(last_sample);

      // add this contribution to the average
      temp_avg = temp_avg + this_temp/100.0;
    }

    if (this_temp > 80) {

        DDRC |= (1<<PC3);
    // turn on RED LED
        PORTC |= (1<<PC3);

    //delay for 500 milliseconds to let the light stay on
        delay_ms(500);

    // turn off LED
        PORTC &= ~(1<<PC3);

    //delay for 500 milliseconds to let the light stay off
        delay_ms(200);
    }

    if else (this_temp > 75) {

        DDRC |= (1<<PC5);
    // turn on GREEN LED
        PORTC |= (1<<PC5);

    //delay for 500 milliseconds to let the light stay on
        delay_ms(1000);

    // turn off LED
        PORTC &= ~(1<<PC5);

    //delay for 500 milliseconds to let the light stay off
        delay_ms(1800);
    }

    else{

        DDRC |= (1<<PC4);
    // turn on RED LED
        PORTC |= (1<<PC4);

    //delay for 500 milliseconds to let the light stay on
        delay_ms(1000);

    // turn off LED
        PORTC &= ~(1<<PC4);

    //delay for 500 milliseconds to let the light stay off
        delay_ms(1200);
    }

    // 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("The Temp is %.2f"), temp_avg);
    lcd_write_data(0xdf);
    lcd_write_string(PSTR("F      "));

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

  return 0;
}
January 18, 2011
by Ralphxyz
Ralphxyz's Avatar

line 120 "if else (this_temp > 75) {"

What you need is "else if" or just else!

if else The general format for these are,

     if( condition 1 )
        statement1;
     else if( condition 2 )
        statement2;
     else if( condition 3 )
        statement3;
     else
        statement4;

The else clause allows action to be taken where the condition evaluates as false (zero).

This is from http://gd.tuwien.ac.at/languages/c/programming-bbrown/c_025.htm

Ralph

January 18, 2011
by Jalex
Jalex's Avatar

Hi I see the line numbers in your code. Is there a way to make the program add in the line numbers? I have had to count down from the top to find errors shown in MakeFile.

January 18, 2011
by glidestone
glidestone's Avatar

Lower Left hand corning of the Progamer's Notepad shows the line # your cursor is on.

January 19, 2011
by SpaceGhost
SpaceGhost's Avatar

Jalex, when using Programmer's Notepad click on the "View" menu, then click on "Line Numbers" ("checking" it). This will show all the line numbers for the program while you are working on it.

Dave

Post a Reply

Please log in to post a reply.

Did you know that you can control 120 LEDs with just 17 microcontroller pins? Learn more...