Can micro-controller multi-threading?

Discussion in 'Embedded Systems and Microcontrollers' started by Sonoma_Dog, Sep 15, 2008.

  1. Sonoma_Dog

    Thread Starter Active Member

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

    Thnaks
     
  2. nanovate

    Distinguished Member

    May 7, 2007
    665
    1
    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.
     
  3. CVMichael

    Senior Member

    Aug 3, 2007
    416
    17
    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.

    So to answer to your question: Does the ATmega168 have dual core (or more) ? if your answer is NO, then you can only simulate multithreading.

    How to simulate multithreading ?
    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.
     
  4. hgmjr

    Moderator

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

    hgmjr
     
  5. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    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
     
  6. Sonoma_Dog

    Thread Starter Active Member

    Jul 24, 2008
    99
    0
    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
     
  7. hgmjr

    Moderator

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

    hgmjr
     
  8. Sonoma_Dog

    Thread Starter Active Member

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

    Active Member

    Aug 9, 2008
    61
    0
    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

    Copy, paste, compile then download after connecting.



    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);
    }
    }
     
  10. SIcam

    Active Member

    Aug 9, 2008
    61
    0
    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
    • 6 analog input 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
     
  11. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    Here is a link to an ATMEL application note that illustrates the FSM programming technique.

    hgmjr
     
  12. hgmjr

    Moderator

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

    hgmjr
     
  13. SIcam

    Active Member

    Aug 9, 2008
    61
    0
    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);

    }
     
  14. Sonoma_Dog

    Thread Starter Active Member

    Jul 24, 2008
    99
    0


    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
     
  15. Sonoma_Dog

    Thread Starter Active Member

    Jul 24, 2008
    99
    0
    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!
     
  16. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    Code ( (Unknown Language)):
    1. /**************************
    2.  
    3.     FINITE STATE MACHINE DEMO
    4.  
    5. **************************/
    6. #include <avr/io.h>
    7. #include <avr/interrupt.h>
    8. unsigned char tick1;
    9. unsigned char tick2;
    10. unsigned char LED1_state;
    11. unsigned char LED2_state;
    12.  
    13. void INIT_DIO(void)
    14. {
    15.  // In this function, set up the IO pins to be used as
    16.  //    your LED enable lines...
    17. }
    18.  
    19. void INIT_TIMER0(void)
    20. {
    21.   // In this function, set up TIMER0 prescale to interrupt
    22.  // once every 100 milliseconds and enable it for
    23.  //   interrupt operation...
    24.  
    25. }
    26.  
    27. ISR(TIMER0_OVF_vect) // This interrupt happens 10 times per second...
    28. {
    29.  tick1++;
    30.  tick2++;
    31. }
    32.  
    33. void Service_LED1(void)
    34. {
    35.  switch(LED1_state)
    36.  {
    37.   case 0:  // IDLE or DO-NOTHING state
    38.    tick1 = 0;
    39.    break;
    40.   case 1:
    41.    if (tick1 >= 10)  
    42.    {
    43.     // Turn on LED1...
    44.     tick1 = 0;
    45.     LED1_state = 2;
    46.    }
    47.    break;
    48.   case 2:
    49.    if (tick1 >= 10)
    50.    {
    51.     // Turn off LED1
    52.  
    53.     tick1 = 0;
    54.     LED1_state = 1;
    55.    }
    56.    break;
    57.   default:
    58.    break;
    59.  }
    60. }
    61.  
    62. void Service_LED2(void)
    63. {
    64.  // Repeat the instruction from LED2 using tick2 and LED2_state...
    65. }
    66.  
    67. int main(void)
    68. {
    69.  
    70.  INIT_DIO();
    71.  INIT_TIMER0();
    72.  LED1_state = 1; // Set state to first active state...
    73.  LED2_state = 1; // Set state to first active state...
    74.  sei();   // Enable Global Interrupts...
    75.  while(1)   //  Effectively a forever loop...
    76.  {
    77.   Service_LED1();
    78.   Service_LED2();
    79.  }
    80.  
    81.  return(0); // This line should never be executed....
    82. }
    83.  
    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: Sep 16, 2008
  17. Sonoma_Dog

    Thread Starter Active Member

    Jul 24, 2008
    99
    0
    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.
     
  18. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    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
     
  19. Sonoma_Dog

    Thread Starter Active Member

    Jul 24, 2008
    99
    0
    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.
     
Loading...