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 (http://www.efx-tek.com/files/charlieplex_leds.pdf)
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
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 ]-----------------------------------------------------
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.