#### Sonoma_Dog

Joined Jul 24, 2008
99
I am using a ATmega168 microcontroller, I wanted to control several I/O pins simultaneously. Can this be done?

Thnaks

#### nanovate

Joined May 7, 2007
666
It is a matter of simultaneously you want. You can read and write to a port very quickly. There are RTOSes available for the AVR but you have a limited amount of SRAM available.

#### CVMichael

Joined Aug 3, 2007
419
Before I answer to that question: Did you know that computers do not do 2 things at the same time ? (at least not until they came up with dual code CPUs)
Until then multithreading was simulated, it only looked like it's processing more than one thing at once, but actually it was not.

Lets say you have a function that is 1000 lines of code, and say you want 10 threads. You have to divide the 1000 lines of code into 10, so it's 100 lines. Then you run thread 1, first 100, thread 2 first 100, and so on, until you reach the last thread 9, first 100, then you continue with first thread, thread 1, lines 101 to 200, and so on.
That's what windows does in the background, runs pieces of code divided into small parts making you think it runs more than one at the same time.

#### hgmjr

Joined Jan 28, 2005
9,029
The coding method you need to look into is what is termed "Finite State Machine" coding.

hgmjr

#### hgmjr

Joined Jan 28, 2005
9,029
Very often the "switch" structure is used in c-language to code a FSM program.

Though not the best example of this type of coding, this is a link to an article on the topic.

hgmjr

#### Sonoma_Dog

Joined Jul 24, 2008
99
Thanks for all of your inputs. !! I understand that a microcontroller can not execute two instructions at a same time.

Here is what i am trying to do. I have sereval LEDs sets that is controled by the microcontroller (PWM).

Each LEDs set will controlled by one I/O pin and Here is how I generate the PWM signal. I set high to the pin and put a delay, then set low and put a delay. (I used thie method because not every I/O pin have the built in PWM function in the mega168)

I wrote this pseudo code, and all the function will keep looping. Do you think it will work? if it does, do you guys have any code example or website that can assist me setting this up? I have never used multithreading before.

LEDLOOP1 (Delay1)
{ Set pin 1 high
Delay1
Set pin 1 low
one sec - Delay1
}

LEDLOOP2 (Delay2)
{ Set pin 2 high
Delay2
Set pin 2 low
one sec - Delay2
}

LEDLOOP3 (Delay3)
{ Set pin 3 high
Delay3
Set pin 3 low
one sec - Delay3
}

MAIN LOOP (void)
{
SET variable Delay1, Delay2 and Delay3 to control the brightness
}

Thank you

#### hgmjr

Joined Jan 28, 2005
9,029
Are you programming with C-language? If not, what language are you using?

hgmjr

#### Sonoma_Dog

Joined Jul 24, 2008
99
I bought a Aruduino Diecimila, and I believe it's in C.

#### SIcam

Joined Aug 9, 2008
61
The pseudo code you wrote does not appear to do what you think.
(it will not compile as I tried so it has many problems.)

Your code is trying to vary the length of time the LED is ON and OFF at the high state and not vary brightness.

Try this example to vary brightness [the key is analogWrite(ledpin, i)]

Connect as follows:
9 ----- 1K R ------ +LED- -----Gnd

int ledPin = 9;

void setup(){}

void loop()
{
for (int i=0; i<=255; i++)
{
analogWrite(ledPin, i);
delay(100);
}
for (int i=255; i>=0; i--)
{
analogWrite(ledPin, i);
delay(100);
}
}

#### SIcam

Joined Aug 9, 2008
61
Different versions of the Arduino i/o board exist, but the basic versions have
• 14 digital i/o pins, of which 6 can be analog (PWM) output pins
• multiple serial ports (at the expense of digital i/o pins)
• 2 external interrupt pins
• power from USB or external power supply
• Extras: I2C communication interface
To use an output pins as analog (PWM) you will need to define it in the program as such:

Analog output pins can generate voltage levels between 0 - 5V, using a method called Pulse Width Modulation. PWM is basically a way of faking different voltages by very quickly alternating between 0V and 5V: the longer the 5V spikes take, the higher the output voltage appears.
This example makes a led connected to an analog output pin fade in and out, by changing the pin's voltage between 0 - 5V.

analogWrite(a, v); // set analog out pin a to value v

#### hgmjr

Joined Jan 28, 2005
9,029
Check out the example c program on page 44 of this link.

hgmjr

#### SIcam

Joined Aug 9, 2008
61
If you want to run 3 LEDs and have them each vary their intensity randomly then you can download the following program. (Note: Each LED gets assigned a different random number-intensity level. Had I put the randomNumber generator only at the beginning then all the LED's would be at the same intensity of the random generator. Also note that the delay is at the end so they will appear seemless in switching. If the delay is after each then they will appear as if each is being changed independently instead of simultaneously.)

int ledPin9 = 9;
int ledPin10 = 10;
int ledPin11 = 11;
long randNumber;
void setup(){}
void loop()
{
randNumber = random(255);
analogWrite(ledPin9, randNumber);
randNumber = random(255);
analogWrite(ledPin10, randNumber);
randNumber = random(255);
analogWrite(ledPin11, randNumber);
delay(100);

}

#### Sonoma_Dog

Joined Jul 24, 2008
99
The pseudo code you wrote does not appear to do what you think.
(it will not compile as I tried so it has many problems.)

Your code is trying to vary the length of time the LED is ON and OFF at the high state and not vary brightness.

Try this example to vary brightness [the key is analogWrite(ledpin, i)]

Connect as follows:
9 ----- 1K R ------ +LED- -----Gnd

int ledPin = 9;

void setup(){}

void loop()
{
for (int i=0; i<=255; i++)
{
analogWrite(ledPin, i);
delay(100);
}
for (int i=255; i>=0; i--)
{
analogWrite(ledPin, i);
delay(100);
}
}

Yea that will work, but for only one I/0 Pin at a time, right? and it utilize the analog I/O pin, i have notice that the ATMega168 doesn't have any analog I/O pin, and i really wanted to able to control all I/O port at the same time, not just the analog I/O pin.

What i wanted to do is to just use Aruduino program the ATmega168 and after that, I will pull out the chip and use it without the Aruduino board.

I thought controlling the length of on and off time will control the brightness of the LED. As long as i toggle the pin fast enough, our eyes are not going to notice it blinks, instead we are going notice the different in brightness, right?

Thanks

#### Sonoma_Dog

Joined Jul 24, 2008
99
If you want to run 3 LEDs and have them each vary their intensity randomly then you can download the following program. (Note: Each LED gets assigned a different random number-intensity level. Had I put the randomNumber generator only at the beginning then all the LED's would be at the same intensity of the random generator. Also note that the delay is at the end so they will appear seemless in switching. If the delay is after each then they will appear as if each is being changed independently instead of simultaneously.)

int ledPin9 = 9;
int ledPin10 = 10;
int ledPin11 = 11;
long randNumber;
void setup(){}
void loop()
{
randNumber = random(255);
analogWrite(ledPin9, randNumber);
randNumber = random(255);
analogWrite(ledPin10, randNumber);
randNumber = random(255);
analogWrite(ledPin11, randNumber);
delay(100);

}
Yeah i understand It will make things SOO much easier if i use analogWrite. but I need to use all of the of the I/O pins.

Thanks!

#### hgmjr

Joined Jan 28, 2005
9,029
Rich (BB code):
/**************************

FINITE STATE MACHINE DEMO

**************************/
#include <avr/io.h>
#include <avr/interrupt.h>
unsigned char tick1;
unsigned char tick2;
unsigned char LED1_state;
unsigned char LED2_state;

void INIT_DIO(void)
{
// In this function, set up the IO pins to be used as
}

void INIT_TIMER0(void)
{
// In this function, set up TIMER0 prescale to interrupt
// once every 100 milliseconds and enable it for
//   interrupt operation...

}

ISR(TIMER0_OVF_vect) // This interrupt happens 10 times per second...
{
tick1++;
tick2++;
}

void Service_LED1(void)
{
switch(LED1_state)
{
case 0:  // IDLE or DO-NOTHING state
tick1 = 0;
break;
case 1:
if (tick1 >= 10)
{
// Turn on LED1...
tick1 = 0;
LED1_state = 2;
}
break;
case 2:
if (tick1 >= 10)
{
// Turn off LED1

tick1 = 0;
LED1_state = 1;
}
break;
default:
break;
}
}

void Service_LED2(void)
{
// Repeat the instruction from LED2 using tick2 and LED2_state...
}

int main(void)
{

INIT_DIO();
INIT_TIMER0();
LED1_state = 1; // Set state to first active state...
LED2_state = 1; // Set state to first active state...
sei();   // Enable Global Interrupts...
while(1)   //  Effectively a forever loop...
{
Service_LED1();
Service_LED2();
}

return(0); // This line should never be executed....
}
This program is not 100 percent ready for prime time but it conveys the general idea of how to implement a state machine.

This approach allows for concurrent and independent control of two LEDs.

Simply rinse and repeat to add more LEDs or for that matter to interleave additional taskes like checking the state of a switch.

hgmjr

Last edited:

#### Sonoma_Dog

Joined Jul 24, 2008
99
Thank you so much , i think i have an idea how to do it now.

You probably just saved me a week of research .
Now i just cant wait until I get my microcontroller, stupid USPS takes forever.

#### hgmjr

Joined Jan 28, 2005
9,029
On review I picked up on a glaring error in the initialized values of LED1_state and LED2_state.

Once you have your first stab at your code, post your code and those members with AVR programming experience will be happy to comment and suggest ways to improve your program.

You know that you can start coding without waiting for your hardware. AVRSTUDIO4 and WINAVR can be downloaded free right now and you can begin familiarizing yourself with the tools. Also the program simulation capability of AVRSTUDIO4 and WINAVR are quite good.

hgmjr

#### Sonoma_Dog

Joined Jul 24, 2008
99
On review I picked up on a glaring error in the initialized values of LED1_state and LED2_state.

Once you have your first stab at your code, post your code and those members with AVR programming experience will be happy to comment and suggest ways to improve your program.

You know that you can start coding without waiting for your hardware. AVRSTUDIO4 and WINAVR can be downloaded free right now and you can begin familiarizing yourself with the tools. Also the program simulation capability of AVRSTUDIO4 and WINAVR are quite good.

hgmjr
Thanks! I will post my program once i am done with it.

I will be using the arduino program to edit my code. since i dont know any other ways to upload my code to the microcontroller.