November 22, 2024, 02:58:57 AM

News:

Be sure to checkout our Vixen interfaces in the Library forum -- if you want PC automation at near zero cost, EFX-TEK and Vixen is a great combination of tools.


Control Up To 30 LEDs from 6 I/O Pins [Advanced]

Started by JonnyMac, August 16, 2007, 02:55:22 PM

Previous topic - Next topic

JonnyMac

Yes, it's true: you can control up to 30 LEDs with just six I/O pins.  This is possible through a bit of programming trickery called "Charlieplexing."  Charlieplexing is a method of enabling just two pins while disconnecting the others (by making them inputs) so that a single LED will light.  Therein lies the limitation of Charlieplexing: only one LED is lit at any given time.  With really fast processors like the SX we can switch things so fast that it can appear we have many on, the speed of the Prop-1 limits us in that regard.

Still, the the techique is useful.  What if we wanted to make a Cylon-type eye display with 10 LEDs, have a trigger, and external speed control.  Without Charlieplexing we would have to use a Prop-2 for the number of pins; with Charlieplexing we can do it on the Prop-1.

Charlieplexing Schematic

And here's the code that takes advantage of Charlieplexed LED connections:

' =========================================================================
'
'   File...... Cylon10.BS1
'   Purpose... 10 LED Cyclon-type display via Charlieplexing
'   Author.... Jon Williams, EFX-TEK
'   E-mail.... jwilliams@efx-tek.com
'   Started...
'   Updated...
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------


' -----[ Revision History ]------------------------------------------------


' -----[ I/O Definitions ]-------------------------------------------------

SYMBOL  Speed           = 7                     ' no ULN, remove SETUP
SYMBOL  Trigger         = PIN6                  ' SETUP = DN

SYMBOL  Leds            = PINS
SYMBOL  LedCtrl         = DIRS


' -----[ Constants ]-------------------------------------------------------

SYMBOL  Pressed         = 1
SYMBOL  NotPressed      = 0


' -----[ Variables ]-------------------------------------------------------

SYMBOL  theLed          = B2                    ' which LED is on
SYMBOL  pntr            = B3                    ' EEPROM pointer
SYMBOL  delay           = W5                    ' on-time for LED


' -----[ Initialization ]--------------------------------------------------

Reset:
  Leds = %00000000                              ' clear LEDs
  LedCtrl = %00000000                           ' disable outputs


' -----[ Program Code ]----------------------------------------------------

Main:
  IF Trigger = NotPressed THEN Main             ' wait for trigger

  FOR theLed = 1 TO 9
    GOSUB Set_Led
    GOSUB Speed_Delay
    IF Trigger = NotPressed THEN Reset
  NEXT

  FOR theLed = 10 TO 2 STEP -1
    GOSUB Set_Led
    GOSUB Speed_Delay
    IF Trigger = NotPressed THEN Reset
  NEXT

  GOTO Main


' -----[ Subroutines ]-----------------------------------------------------

' Pass LED to light (1 to 30) in "theLed"

Set_Led:
  IF theLed > 30 THEN Set_Led_Exit              ' bad LED #
    LedCtrl = %00000000                         ' disable LEDs
    pntr = theLed - 1 * 2                       ' point into table
    READ pntr, Leds                             ' get LED pins
    pntr = pntr + 1
    READ pntr, LedCtrl                          ' get control pins

Set_Led_Exit:
  RETURN

' -------------------------------------------------------------------------

' Use Prop-Pot to control speed

Speed_Delay:
  POT Speed, 110, delay
  delay = delay * 4                             ' scale to ~1 sec max
  PAUSE delay
  RETURN


' -----[ EEPROM Data ]-----------------------------------------------------

Charlieplexed_Leds:

'            PINS       DIRS
'
  EEPROM (%00000001, %00000011)                 ' LED 1
  EEPROM (%00000010, %00000011)                 ' LED 2
  EEPROM (%00000001, %00000101)                 ' LED 3
  EEPROM (%00000100, %00000101)                 ' LED 4
  EEPROM (%00000001, %00001001)                 ' LED 5
  EEPROM (%00001000, %00001001)                 ' LED 6
  EEPROM (%00000001, %00010001)                 ' LED 7
  EEPROM (%00010000, %00010001)                 ' LED 8
  EEPROM (%00000001, %00100001)                 ' LED 9
  EEPROM (%00100000, %00100001)                 ' LED 10
  EEPROM (%00000010, %00000110)                 ' LED 11
  EEPROM (%00000100, %00000110)                 ' LED 12
  EEPROM (%00000010, %00001010)                 ' LED 13
  EEPROM (%00001000, %00001010)                 ' LED 14
  EEPROM (%00000010, %00010010)                 ' LED 15
  EEPROM (%00010000, %00010010)                 ' LED 16
  EEPROM (%00000010, %00100010)                 ' LED 17
  EEPROM (%00100000, %00100010)                 ' LED 18
  EEPROM (%00000100, %00001100)                 ' LED 19
  EEPROM (%00001000, %00001100)                 ' LED 20
  EEPROM (%00000100, %00010100)                 ' LED 21
  EEPROM (%00010000, %00010100)                 ' LED 22
  EEPROM (%00000100, %00100100)                 ' LED 23
  EEPROM (%00100000, %00100100)                 ' LED 24
  EEPROM (%00001000, %00011000)                 ' LED 25
  EEPROM (%00010000, %00011000)                 ' LED 26
  EEPROM (%00001000, %00101000)                 ' LED 27
  EEPROM (%00100000, %00101000)                 ' LED 28
  EEPROM (%00010000, %00110000)                 ' LED 29
  EEPROM (%00100000, %00110000)                 ' LED 30

Jon McPhalen
EFX-TEK Hollywood Office

gadget-evilusions

I have a program I pieced together for the prop-1 and dc-16 to control 9 sets of leds, looking to a pot for which section of program to run depending on the position. Would I be able to just use a prop-1, and use a section of the charlieplexing schematic to be be able to just use the prop-1 for what I am trying to accomplish. I was going to switch to a prop-2 because instead of just the on/off of the dc-16 i wanted to be able to pwm the leds.

' =========================================================================
'
'   File...... Evilusions_led_motorcycle.BS1
'   Purpose...
'   Author.... Brian Warner
'   E-mail.... gadget@evilusions.com
'   Started...
'   Updated... 8-1-07
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------
'
'



' -----[ Revision History ]------------------------------------------------


' -----[ I/O Definitions ]-------------------------------------------------

SYMBOL  Dial            = 6
SYMBOL  Sio             = 7
' -----[ Constants ]-------------------------------------------------------

SYMBOL  Baud            = OT2400
SYMBOL  Addr            = %00

' -----[ Variables ]-------------------------------------------------------

SYMBOL  cmd             = B2


' -----[ Initialization ]--------------------------------------------------

Reset:
  DIRS = %001111111


' -----[ Program Code ]----------------------------------------------------

Main:
  POT Dial, 104, cmd
  cmd = cmd / 37
  BRANCH cmd, (Task0, Task1, Task2, Task3, Task4, Task5, Task6)
  GOTO Main

Task0:
  SEROUT Sio, Baud, ("!DC16", Addr, "S", %01001001, %00000000)
  PAUSE 100
  GOTO Main

Task1:
  SEROUT Sio, Baud, ("!DC16", Addr, "S", %10010010, %00000000)
  PAUSE 100
  GOTO Main

Task2:
  SEROUT Sio, Baud, ("!DC16", Addr, "S", %00100100, %00000001)
  PAUSE 100
  GOTO Main

Task3:
  SEROUT Sio, Baud, ("!DC16", Addr, "S", %01001001, %00000000)
  PAUSE 50
  SEROUT Sio, Baud, ("!DC16", Addr, "X")
  PAUSE 50
  GOTO Main

Task4:
  SEROUT Sio, Baud, ("!DC16", Addr, "S", %10010010, %00000000)
  PAUSE 50
  SEROUT Sio, Baud, ("!DC16", Addr, "X")
  PAUSE 50
  GOTO Main

Task5:
  SEROUT Sio, Baud, ("!DC16", Addr, "S", %00100100, %00000001)
  PAUSE 50
  SEROUT Sio, Baud, ("!DC16", Addr, "X")
  PAUSE 50
  GOTO Main

Task6:
  SEROUT Sio, Baud, ("!DC16", Addr, "S", %10100001, %00000000)
  PAUSE 250
  SEROUT Sio, Baud, ("!DC16", Addr, "S", %00001010, %00000001)
  PAUSE 250
  SEROUT Sio, Baud, ("!DC16", Addr, "S", %01010100, %00000000)
  PAUSE 250
  GOTO Main




' -----[ Subroutines ]-----------------------------------------------------


' -----[ EEPROM Data ]-----------------------------------------------------
Brian
Evilusions LLC
www.evilusions.com for all your pneumatic components

JonnyMac

You would have to use the Prop-SX to Charlie-plex AND PWM LEDs at the same time, and that code would be fairly tricky.  For proper operation you'd have to keep track of which LEDs are on and at what level.  While it can be done, this is not a simple exercise and would probably take a good code write a few days to sort out.
Jon McPhalen
EFX-TEK Hollywood Office