Shop OBEX P1 Docs P2 Docs Learn Events
1 Core 2 Activities — Parallax Forums

1 Core 2 Activities

HumanoidoHumanoido Posts: 5,770
edited 2010-08-24 13:35 in Propeller 1
One tiny spin program in 1 cog multi-tasks 2 simple and separate activities - blinking 2 LEDs. Blinking rate can be slow: half second on/off for one LED, 1 second on/off for the other. What is the smallest code example to do this?

Thanks in advance,
Humanoido
«13

Comments

  • Heater.Heater. Posts: 21,230
    edited 2010-08-20 14:47
    In bog standard Spin the two activities are never going to be totally separate and independent. If one hangs up in a loop or sits on a waitxx then it halts the other also.

    But if the tasks are "cooperative" they can get along just fine.

    My approach is:
    1) Have one method per task.
    2) Each method is called every repeatedly at some suitable iteration rate by a main loop.
    3) Each task method maintains a "state variable" so that it does not forget what it was doing between calls.
    4) A case statement can be used to direct activity within the task depending on the state variable.
    4) Tasks may not hang up on repeat loops or waitxx.

    This may seem very crude, but I have worked on Rolls-Royce jet engine management systems that were basically organized like this.

    Below is a simple example for your flashing LEDs case. Only two states per task ON or OFF.
    'Example of two tasks in Spin.
    '
    CON
      _clkmode        = xtal1 + pll16x
      _xinfreq        = 6_553_600
    
      OFF = 0
      ON = 1
    
    VAR
      'Task state variables
      byte state0
      byte state1
    
      'Millisecond counter
      long ms
    
    PUB start
      'Outputs, P0 for task0, P1 for task1
      OUTA := %00
      DIRA := %11
    
      'Repeatedly run each tasks method every 1ms
      repeat
        task0
        task1
        waitcnt(clkfreq / 1000 + cnt) '1ms delay
        ms++
    
    'N.B. Tasks may not hang up for long periods in repeat loops
    '     Rather they would peform one iteration of a loop on each call
    '     remembering the task state and iteration count ready for the next call.
    
    'Task 0 flashes LED 0 every second
    PRI task0
      case state0
        OFF:
          if (ms // 500) == 0
            DIRA := %01
            state0 := ON
        ON:
          if (ms // 500) == 0
            DIRA := %00
            state0 := OFF
        OTHER:
          'WTF?
    
    'Task 1 flashes LED 1 twice every second
    PRI task1
      case state1
        OFF:
          if (ms // 250) == 0
            DIRA := %10
            state1 := ON
        ON:
          if (ms // 250) == 0
            DIRA := %00
            state1 := OFF
        OTHER:
          'WTF?
    
  • John R.John R. Posts: 1,376
    edited 2010-08-20 14:58
    I'm not where I can work on this, but I'm thinking you might be able to user counters for this. Two counters per cog, one for each LED.

    Basically set each counter to control the output of one of the pins at the desired frequencies.
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-20 16:30
    Heater: Thank you very much. I'm interested in this code, but the LEDs are not lit after running it. Are there any changes needed to make this run? Thanks.

    Humanoido

    Edit: I think I see it now, it must be a faster crystal you're using.
    Added this to CON but still not blinking:
    _clkmode = xtal1 + pll16x ' Feedback and PLL multiplier
    _xinfreq = 5_000_000 ' External oscillator = 5 MHz
  • kuronekokuroneko Posts: 3,623
    edited 2010-08-20 17:25
    Humanoido wrote: »
    ... but the LEDs are not lit after running it. Are there any changes needed to make this run?

    The LEDs are controlled through dira which means for the demoboard outa has to be initialised to %11 (it may well work on his h/w). The other thing is that both tasks interfere with each others LED pins.

    Change the dira setup to:
    ' task0
    OFF: dira |= %01
    ON:  dira ^= %01
    
    ' task1
    OFF: dira |= %10
    ON:  dira ^= %10
    

    This then works for me on the demoboard (adjusted for 16/17).
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-20 17:55
    Kuroneko, it's running now. Perfect!
    Thank you very much for your assistance!

    Humanoido
  • kuronekokuroneko Posts: 3,623
    edited 2010-08-20 18:01
    Humanoido wrote: »
    Can you attach the file? The code is giving an error. Thanks.
    Sorry for the confusion, the code I listed was more along the lines of find this anchor, apply this change.
  • tonyp12tonyp12 Posts: 1,951
    edited 2010-08-20 20:22
    You could use the counters to blink the LEDs.
    But I think you are looking for co-operative tasking in general.

    The right way would be to use a greatest common denominator time cycle.
    So create a state machine that is initiated 100 times a second.

    A=A+1
    B=B+1
    IF A>50 LED0 turned on
    IF A>100 LED0 turned OFF, A=0
    IF B>100 LED1 turned on
    IF B>200 LED1 turned OFF, B=0
  • Heater.Heater. Posts: 21,230
    edited 2010-08-20 22:17
    Oops, sorry, I never actually ran that, no LEDs on my boards just now. You could of course just change those DIRAs in the tasks to OUTAs as originally had in mind. I was not thinking about the LED's as much as the threads.

    Now, if the code in the tasks gets a bit complicated and the they are very different I would be inclined to put the task methods and their associated variables into their own separate Spin files as different objects. The top level "scheduler" loop would then be in a top level object by itself.

    Of course if you do that you only need to write one LED task object in this case, create two instances of it with OBJ and pass the LED flash period in as a parameter.

    One "deep" thing about this technique is that if you make the rule that there can be no loops (repeat etc) in the task methods and no waitxxx then it becomes possible for some code analysis program to find all the possible pathways through each task. Including any subroutine calls. For each pathway it could know which instructions are executed and how long they take to execute. This analysis can then tell you exactly how much of the "scheduler" time tick period each task takes in the worst case. That is to say, every time you change and recompile the code the analysis can tell you if you are running out of time. For those Rolls-Royce engine projects we had just such analysis built into the compiler.
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-21 02:20
    Kuroneko wrote: Sorry for the confusion, the code I listed was more along the lines of find this anchor, apply this change.

    Kuroneko, no confusion, it was your comments which sorted things out, thank you. Also good that you ran the program on a Demo Board too.
    Humanoido
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-21 02:22
    Tony P wrote: You could use the counters to blink the LEDs. But I think you are looking for co-operative tasking in general. The right way would be to use a greatest common denominator time cycle. So create a state machine that is initiated 100 times a second.

    A=A+1
    B=B+1
    IF A>50 LED1 turned on
    IF A>100 LED1 turned OFF, A=0
    IF B>100 LED1 turned on
    IF B>200 LED1 turned OFF, B=0

    Tony P : Definitely looks like there's a place for both counters and a greatest common denominator time cycle from within the code! It's also a clean straightforward way of embedding state machines within code using a looping technique. It can also serve to create sub-processors. Thank you for pointing this out.Humanoido
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-21 02:28
    John R. wrote: »
    I'm not where I can work on this, but I'm thinking you might be able to user counters for this. Two counters per cog, one for each LED. Basically set each counter to control the output of one of the pins at the desired frequencies.
    John R., excellent idea - perhaps seeing some minimal code to illustrate this technique would help and be most appreciated. Thank you.

    Humanoido
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-21 02:46
    Heater. wrote: »
    Oops, sorry, I never actually ran that, no LEDs on my boards just now. You could of course just change those DIRAs in the tasks to OUTAs as originally had in mind. I was not thinking about the LED's as much as the threads.
    Heater, that was the first thought that came to mind, i.e. maybe change those DIRAs to OUTAs. :)
    Heater. wrote: »
    Now, if the code in the tasks gets a bit complicated and .. they are very different, I would be inclined to put the task methods and their associated variables into their own separate Spin files as different objects. The top level "scheduler" loop would then be in a top level object by itself. Of course if you do that you only need to write one LED task object in this case, create two instances of it with OBJ and pass the LED flash period in as a parameter.
    Good idea - it would make writing and keeping track of more tasks easier.
    Heater. wrote: »
    One "deep" thing about this technique is that if you make the rule that there can be no loops (repeat etc) in the task methods and no waitxxx then it becomes possible for some code analysis program to find all the possible pathways through each task. Including any subroutine calls. For each pathway it could know which instructions are executed and how long they take to execute. This analysis can then tell you exactly how much of the "scheduler" time tick period each task takes in the worst case. That is to say, every time you change and recompile the code the analysis can tell you if you are running out of time. For those Rolls-Royce engine projects we had just such analysis built into the compiler.
    Heater, this is another brilliant and logical idea - we must say - that Rolls-Royce jet engine project is having a positive effect on this forum thread.

    Heater, as a next step to expand the program, what is involved in putting 8 LEDs in the program, instead of only 2? (I have LEDs on p0 through p7).. hint ..hint.. :)

    Humanoido
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-21 03:30
    Here's what I have so far for 4 LEDs. Problem: the first 2 LEDs stay on.
    ' ' Example of four tasks in Spin.
    ' controls 4 LEDs
    '
    CON
    '  _clkmode        = xtal1 + pll16x   ' Feedback and PLL multiplier
    '  _xinfreq        = 5_000_000        ' External oscillator = 5 MHz
       _clkmode = xtal1+pll16x            ' Overclocked 6.25MHz crystal for 100MHz
       _xinfreq = 6_250_000               ' External oscillator = 6.25 MHz
      OFF = 0
      ON = 1
    VAR             'Task state variables 
      byte state0
      byte state1
      long ms      'Millisecond counter 
    PUB start      'Outputs, P0 for task0, P1 for task1
      DIRA := %1111
      repeat       'Repeatedly run each tasks method every 1ms  
        task0
        task1
        task2
        task3
        waitcnt(clkfreq / 1000 + cnt) '1ms delay    
        ms++
    'N.B. Tasks may not hang up for long periods in repeat loops
    '     Rather they would peform one iteration of a loop on each call
    '     remembering the task state and iteration count ready for the next call.
    PRI task0         'Task 0 flashes LED 0 every second 
      case state0
        OFF:
          if (ms // 500) == 0
            outa |= %01      
            state0 := ON
        ON:
          if (ms // 500) == 0
            outa ^= %01 
            state0 := OFF
        OTHER:
    PRI task1        'Task 1 flashes LED 1 twice every second  
      case state1
        OFF:
          if (ms // 250) == 0
            outa |= %10
            state1 := ON
        ON:
          if (ms // 250) == 0
            outa ^= %10
            state1 := OFF
        OTHER:
    PRI task2         'Task 2 flashes LED 2 every second 
      case state0
        OFF:
          if (ms // 500) == 0
            outa |= %100      
            state0 := ON
        ON:
          if (ms // 500) == 0
            outa ^= %100 
            state0 := OFF
        OTHER:
    PRI task3         'Task 3 flashes LED 3 twice every second 
      case state1
        OFF:
          if (ms // 250) == 0
            outa |= %1000
            state1 := ON
        ON:
          if (ms // 250) == 0
            outa ^= %1000
            state1 := OFF
        OTHER:
    
  • Heater.Heater. Posts: 21,230
    edited 2010-08-21 03:40
    Humanoido, your tasks2 and task3 are using state0 and state1.

    Here is an 8 LED cooperative task scheduler example with only one actual LED flasher method with parameters to select which LED and period it should use. The flasher method is now in its own spin file as separate object. That save the confusuion over which vars belong to which task.

    I have not run this. May wan to change the 1ms time tick to 10ms if Spin can't keep up.
    'Example of eight cooperative tasks in Spin.
    '
    CON
      _clkmode        = xtal1 + pll16x
      _xinfreq        = 5_000_000
    
    OBJ
      'Create 8 instances of the LED flasher task object
      task_led_0 : "task_led_flasher"
      task_led_1 : "task_led_flasher"
      task_led_2 : "task_led_flasher"
      task_led_3 : "task_led_flasher"
      task_led_4 : "task_led_flasher"
      task_led_5 : "task_led_flasher"
      task_led_6 : "task_led_flasher"
      task_led_7 : "task_led_flasher"
    
    PUB start
      'Initialize 8 LED flasher tasks with different LED pins
      'and flash periods.
      task_led_0.init(%00000000, 100)
      task_led_1.init(%00000010, 110)
      task_led_2.init(%00000100, 120)
      task_led_3.init(%00001000, 130)
      task_led_4.init(%00010000, 140)
      task_led_5.init(%00100000, 150)
      task_led_6.init(%01000000, 160)
      task_led_7.init(%10000000, 170)
    
      'Repeatedly run each tasks run method every 1ms
      repeat
        task_led_0.run
        task_led_1.run
        task_led_2.run
        task_led_3.run
        task_led_4.run
        task_led_5.run
        task_led_6.run
        task_led_7.run
        waitcnt(clkfreq / 1000 + cnt) '1ms delay
    
    'LED flasher cooperative task.
    
    CON
      'Possible task states.
      STATE_OFF = 0
      STATE_ON = 1
    
    VAR
      LONG state         'State of the task
      LONG ms            'Count milliseconds here
      LONG led           'Pin to use for a LED
      LONG period        'Flash period
    
    'Call this first to initialise the task.
    PUB init(_led, _period)
      led := _led
      period := _period
      OUTA := 0
      DIRA := led
    
    'Call this every millisecond to "kick" the task along
    'N.B. Tasks may not hang up for long periods in repeat loops
    '     Rather they would peform one iteration of a loop on each call
    '     remembering the task state and iteration count ready for the next call.
    PUB run
      ms++
      case state
        STATE_OFF:
          if (ms // period) == 0
            OUTA := led
            state := STATE_ON
        STATE_ON:
          if (ms // period) == 0
            OUTA := 0
            state := STATE_OFF
        OTHER:
          'WTF?
    
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-21 04:04
    Heater. wrote: »
    Humanoido, your tasks2 and task3 are using state0 and state1.
    Changes like this? It gives an error this time.
    ' Example of four tasks in Spin.
    ' controls 4 LEDs
    '
    CON
    '  _clkmode        = xtal1 + pll16x   ' Feedback and PLL multiplier
    '  _xinfreq        = 5_000_000        ' External oscillator = 5 MHz
       _clkmode = xtal1+pll16x            ' Overclocked 6.25MHz crystal for 100MHz
       _xinfreq = 6_250_000               ' External oscillator = 6.25 MHz
      OFF = 0
      ON = 1
    VAR             'Task state variables 
      byte state0
      byte state1
      long ms      'Millisecond counter 
    PUB start      'Outputs, P0 for task0, P1 for task1
      DIRA := %1111
      repeat       'Repeatedly run each tasks method every 1ms  
        task0
        task1
        task2
        task3
        waitcnt(clkfreq / 1000 + cnt) '1ms delay    
        ms++
    'N.B. Tasks may not hang up for long periods in repeat loops
    '     Rather they would peform one iteration of a loop on each call
    '     remembering the task state and iteration count ready for the next call.
    PRI task0         'Task 0 flashes LED 0 every second 
      case state0
        OFF:
          if (ms // 500) == 0
            outa |= %01      
            state0 := ON
        ON:
          if (ms // 500) == 0
            outa ^= %01 
            state0 := OFF
        OTHER:
    PRI task1        'Task 1 flashes LED 1 twice every second  
      case state1
        OFF:
          if (ms // 250) == 0
            outa |= %10
            state1 := ON
        ON:
          if (ms // 250) == 0
            outa ^= %10
            state1 := OFF
        OTHER:
    PRI task2         'Task 2 flashes LED 2 every second 
      case state2
        OFF:
          if (ms // 500) == 0
            outa |= %100      
            state2 := ON
        ON:
          if (ms // 500) == 0
            outa ^= %100 
            state2 := OFF
        OTHER:
    PRI task3         'Task 3 flashes LED 3 twice every second 
      case state3
        OFF:
          if (ms // 250) == 0
            outa |= %1000
            state3 := ON
        ON:
          if (ms // 250) == 0
            outa ^= %1000
            state3 := OFF
        OTHER:
    
  • Heater.Heater. Posts: 21,230
    edited 2010-08-21 04:15
    If you re going to use a variable you should remember to define it first or the compiler will remind you:)
      byte state2
      byte state3
    
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-21 05:20
    Heater, thanks for catching that. So now 4 is working, and I added 2 more so 6 is working perfect. I will try another 2 now. How many lights do you think the code can handle?

    Heater said "Here is an 8 LED cooperative task scheduler example with only one actual LED flasher method with parameters to select which LED and period it should use. The flasher method is now in its own spin file as separate object. That save the confusuion over which vars belong to which task. I have not run this. May wan to change the 1ms time tick to 10ms if Spin can't keep up."

    I must say this code is remarkable! However, I ran it "as is" and nothing lights up. Next I will try the 10ms and let you know the results.

    Humanoido
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-21 05:44
    Heater, added 2 more leds for a total of 8 leds and the program is still running perfect. I can try another 8. What do you think?

    humanoido
  • Heater.Heater. Posts: 21,230
    edited 2010-08-21 05:56
    Ooops, As we are running all this code in one COG I think the DIRA and OUTA are wrong.

    Each task instance should be sure to only disturb it's own pins direction and state.
    So remove the OUTA from the init method and change the DIRA to:
      'Set set our LED pin as output
      DIRA |= led
    

    Change the OUTAs in the run method like so:
    OUTA |= led                'Put LED on
    
    OUTA &= !led               'Put LED off
    

    Do I have to solder some LEDs to my TriBlade Prop #3 ?
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-21 06:15
    Heater. wrote: »
    Ooops, As we are running all this code in one COG I think the DIRA and OUTA are wrong.

    Each task instance should be sure to only disturb it's own pins direction and state.
    So remove the OUTA from the init method and change the DIRA to:
      'Set set our LED pin as output
      DIRA |= led
    
    Change the OUTAs in the run method like so:
    OUTA |= led                'Put LED on
    
    OUTA &= !led               'Put LED off
    
    Do I have to solder some LEDs to my TriBlade Prop #3 ?
    Hi Heater, it works much better, all the LEDs are working except the first one on p0. Yes, it would be convenient if you had a TriBlade platform with LEDs.
  • Heater.Heater. Posts: 21,230
    edited 2010-08-21 06:26
    Ooops again.

    The init call for LED 0 does not have bit zero set in the LED parameter, should be:
      task_led_0.init(%00000001, 100)
    

    "I can try another 8. What do you think?"

    Now that you have that working it's easily extendable to 16 LEDs:)
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-21 06:57
    Heater. wrote: »
    Ooops again. The init call for LED 0 does not have bit zero set in the LED parameter, should be:
      task_led_0.init(%00000001, 100)
    
    Humanoido said "I can try another 8. What do you think?"

    Now that you have that working it's easily extendable to 16 LEDs:)
    Heater, the LED parameter fixed it - now this program is working perfect too! I should say it is absolutely "spot on." :)

    I already have the original program working on 10 LEDs now. It goes from P7 on the header to P16 using the LEDs soldered on the demo board. It's a very nice arrangement. I'll continue adding LEDs until I get to 16. After that, I can harvest 4 more ports from the TV circuit for a total of 20 LEDs.

    Heater, nice work, so if you were to speculate about how many (maximum) LED threads can run, with either program, what do you think? 128?
  • Heater.Heater. Posts: 21,230
    edited 2010-08-21 07:26
    Maximum number of LED tasks?

    No idea. Of course you run out of memory at some point. Or you run out of time, perhaps 1ms is to fine grained.

    Actually thinking about time, that 1ms timer tick will drift off depending on the execution time of all the thread run calls. so if one of our tasks was responsible for counting seconds, minutes, hours etc as a real time clock it would soon be wrong.

    If we want more accurate timer ticks we should really do something like:
    PUB start
      'Initialsie 8 LED flasher tasks with different LED pins
      'and flash periods.
      task_led_0.init(%00000001, 100)
      task_led_1.init(%00000010, 110)
      task_led_2.init(%00000100, 120)
      task_led_3.init(%00001000, 130)
      task_led_4.init(%00010000, 140)
      task_led_5.init(%00100000, 150)
      task_led_6.init(%01000000, 160)
      task_led_7.init(%10000000, 170)
    
      OneMS := clkfreq / 1000                'Calculate cycles per 1 millisecond
      TimeBase := cnt                        'Get current count
    
      'Repeatedly run each tasks run method every 1ms
      repeat
        waitcnt(TimeBase += OneMS)           'Wait to start of next millisecond
        task_led_0.run
        task_led_1.run
        task_led_2.run
        task_led_3.run
        task_led_4.run
        task_led_5.run
        task_led_6.run
        task_led_7.run
    

    As shown in the propeller manual p74.

    With that in place everything goes well until the total execution time of all the task calls exceeds 1ms then the waitcnt will hang up until CNT rolls over, 20 seconds or so.
  • John R.John R. Posts: 1,376
    edited 2010-08-21 07:50
    John R. wrote: »
    I'm not where I can work on this, but I'm thinking you might be able to user counters for this. Two counters per cog, one for each LED.

    Basically set each counter to control the output of one of the pins at the desired frequencies.
    Humanoido wrote: »
    John R., excellent idea - perhaps seeing some minimal code to illustrate this technique would help and be most appreciated. Thank you.

    Humanoido

    But you've outgrown this method already. There are only two counters per cog, and you're way past two LEDs. The counters could provide a resettable counting value, but as you're progressing, they really don't offer anything over using the cnt register.

    John R.
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-21 07:59
    John R. wrote: »
    But you've outgrown this method already. There are only two counters per cog, and you're way past two LEDs. The counters could provide a resettable counting value, but as you're progressing, they really don't offer anything over using the cnt register. John R.
    Hi John, very good point. Thinking about the two counters per Cog does impose a limitation. But what if we used a counter inside one of the many single Cog threads, and called that a sub-thread.. it would gain at least two processes per Cog more than the existing threads. That could gain 2 x 8 = 16 more processes, which just might be an edge in the app. What do you think?

    Humanoido
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-21 08:31
    Heater. wrote: »
    Maximum number of LED tasks? No idea. Of course you run out of memory at some point. Or you run out of time, perhaps 1ms is to fine grained.
    Heater, did you consider running out of LEDs first? I can build the threads up to 20 on the Demo Board. The Proto Board will gain a few more pins but still under 30.

    EDIT:I just remembered a way to double and triple the LEDs using the same number of ports. It's a technique used on BASIC Stamps. So an average of 25 displays can become 50 or 75. That gives some upward mobility..
    Heater. wrote: »
    Actually thinking about time, that 1ms timer tick will drift off depending on the execution time of all the thread run calls. so if one of our tasks was responsible for counting seconds, minutes, hours etc as a real time clock it would soon be wrong. If we want more accurate timer ticks we should really do something like...
    Consider it done. The new code with a more accurate timebase is up and running! :)
    Heater. wrote: »
    With that in place everything goes well until the total execution time of all the task calls exceeds 1ms then the waitcnt will hang up until CNT rolls over, 20 seconds or so.
    I knew that would happen at some point. It needs a warning light, a red LED that lights steady to indicate an imminent rollover in the next cycle.

    Humanoido
  • Heater.Heater. Posts: 21,230
    edited 2010-08-21 08:51
    Humanoido: "...did you consider running out of LEDs first?"

    No, when we run out of RAM on the Prop we just virtualize it and continue. Same with LEDs:)
  • jazzedjazzed Posts: 11,803
    edited 2010-08-21 09:27
    Heater. wrote: »
    No, when we run out of RAM on the we just virtualize it and continue. Same with LEDs:)
    TV or VGA gives lots of LEDs with very few pins.
  • pjvpjv Posts: 1,903
    edited 2010-08-21 09:31
    Humanoido;

    I'm confused...... based on your posts under "more cogs from one prop" and "cloning leds" , are you trying to see how many LED's you can light up with independent (deterministic?) timings, or are you trying to see how many independent threads can be supported under SPIN, and just using the LED's as indicators of that?

    Cheers,

    Peter (pjv)
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-08-21 09:37
    Heater. wrote: »
    Humanoido: "...did you consider running out of LEDs first?"

    No, when we run out of RAM on the we just virtualize it and continue. Same with LEDs:)
    Heater, exactly! How about banks of the total number of LEDs (maybe only 16 real LEDs), and just switch banks showing the results on the same number of LEDs? That would avoid putting TV in and taking up a cog for pixel virtual representation, up to a certain number..beyond a certain number, total virtualization, like RAM.

    Humanoido
Sign In or Register to comment.