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.

Microcontroller Programming » Running 2 program in same time... subroutine

November 08, 2011
by Molek
Molek's Avatar

Hi!!! and sorry for my english.

I toke the tempsensor program and replace it to a pot for flashing diode with the led_blink program... the trouble that i have is when the ADC value is at 500 (or higher or less...)= 500 ms for the timer the value is not changed automatically in the line: delay_ms(valeur+1); (I put last_sample as valeur). the question is; can i run two while in same time in the MCU or do something other. the only experience i have in programming is on the allen bradley software like rs logix 500 & 5000 and it is call subroutine to run 2 function program in the same time.


November 09, 2011
by Rick_S
Rick_S's Avatar

If you post your full code, It would be easier to help.

I don't understand you question fully. Are you having a problem with your code working or are you trying to blink two LED's at different rates using two pots as the analog input?

Welcome Sign


November 09, 2011
by Molek
Molek's Avatar

No my trouble is not that. when the program is reading the line it make that high to down and when the line

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

is working, i can't change the value valeur. hummm.... when the led is on and the pot is at maximum (2k in my case) the value valeur is at 1024 that create a delay of 1024 ms (aproximatively 2 seconde of delay with the sequnce on-off led) i don't want this time delay if i change the value of the pot i want that the led blink at different speed automatically not 2 seconde later.


// tempsensor.c // for NerdKits with ATmega168 //

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 // 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 1000/(sample *2);

int main() {

uint16_t counter;


uint16_t valeur;


// LED as output DDRC |= (1<<PC5); // 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<10; i++) { last_sample = adc_read(); this_temp = sampleToFahrenheit(last_sample);

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

counter = last_sample;

valeur = counter ;

// write message to LCD
lcd_write_string(PSTR("ADC: "));
lcd_write_string(PSTR(" of 1024   "));
fprintf_P(&lcd_stream, PSTR("Frequence: %.2f"), temp_avg);
lcd_write_string(PSTR("Hz "));

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

//delay for 500 milliseconds to let the light stay on

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

//delay for 500 milliseconds to let the light stay off


return 0; }

November 09, 2011
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Molek,

Two things, when posting code it really helps if you put 4 spaces in fron of every line, that way the markdown renderer recognizes it as a code block. Check out the Supported Markup section under the rules of the forum.

Second, the ATmega168 is a much more low level environment than you are used to working with, so there is no "subrutine" abstraction like you are refering to. Instead you have to think about the program flow of your code and when different parts need to run. Depending on how you architect your system you could just have two functions that do two separate things and call one then the other one from your main loop. More often though, we have a main loop that takes care of things like updating the LCD or sending data to the computer, and one or more interrupts setup that run whenever something interesting happens. Check out our interrupts tutorial for more about interupts.

Hope that clears things up a little, and gets you thinking in the right direction.


November 09, 2011
by Molek
Molek's Avatar

Very well, Thanks!!!

Post a Reply

Please log in to post a reply.

Did you know that you can make a spooky Halloween Jack-O-Lantern with a microcontroller? Learn more...