software PWM

Status
Not open for further replies.
the code in post#108 will fade in and out multiple leds. No they are not included in post#108. With some rearanging it will fade in and out multiple leds at different rates if desired
Only one at a time. While you fade one, the rest just sit there.
 
no I have 14 leds and they ALL DIM OR GO BRIGHT together
been hacking at popcorns code but have yet to get it to compile. The last code was way different than the first code.
I get the just of what is going on but want to actually see it work if it actually works as desired.
Code:
{
*****************************************************************************
*  Name    : UNTITLED.BAS                                                   *
*  Author  : [select VIEW...EDITOR OPTIONS]                                 *
*  Notice  : Copyright (c) 2022 [select VIEW...EDITOR OPTIONS]              *
*          : All Rights Reserved                                            *
*  Date    : 5/25/2022                                                      *
*  Version : 1.0                                                            *
*  Notes   :                                                                *
*          :                                                                *
*****************************************************************************
}


Device = 18F43K22
Clock = 8

// int osc and IO pin libraries
Include "intosc.bas"
#option DIGITALIO_INIT = true       // automatically call setalldigital
Include "setdigitalio.bas"

// hardware
Dim INDEX  As LongWord  //4294967295

Dim m As Byte
Dim w As Byte
Dim x As Byte
Dim y As Byte
Dim z As Byte

Dim Counter As LongWord
Dim LED1On As LongWord
Dim LED1Off As LongWord
Dim led1 As PORTA.0
Dim led2 As PORTB.0
Dim led3 As PORTC.0
Dim led4 As PORTD.0
Dim I As Byte
Dim led1offcount As Byte
Dim led1oncount As Byte
Dim led2oncount As Byte
Dim led2offcount As Byte
Dim led3oncount As Byte
Dim led3offcount As Byte
Dim led4offcount As Byte
Dim led4oncount As Byte

main:
// init hdw
               // LED port - all outputs 2 LEDs per port in parallel 330 ohm resistor
TRISA = 0      // SET ALL PORTS AS OUTPUTS
TRISB = 0
TRISC = 0
TRISD = 0
TRISE = 0
   PORTE=%000         //TURN OFF ALL PORTS
   PORTD=%00000000
   PORTC=%00000000
   PORTA=%00000000
   PORTB=%00000000   
//turn off the leds
led1offcount = 0
led1oncount = 0
led2offcount = 0
led2oncount = 0
led3oncount = 0
led3offcount = 0
led4oncount = 0
led4offcount = 0

I = 0
I = Counter
//set the variabls Led1on and Led1off to zero

LED1Off = 0
Counter = 0

While 1 = 1

   // some code will go here
   If led2oncount = I
    Then         //first pass led1 = 0
    led2 = ledon                    // led1 is on
    led2oncount = I +900
    led2offcount = I + 100
   End If
   If led2offcount = I
   Then
   led2 = ledoff
   EndIf
  
   If led3oncount = I
   Then
   led3 = led0n
   led3oncount = I  + 1900
   led3offcount = I + 25
   End If
   If led3offcount = I
   Then
   led3 = ledoff
   End If

  
  
   If led4oncount = I
       Then
       led4 = ledon
       led4offcount = I + 100
       led4offcount = I + 100000
   End If

    
    If led4offcount = I
    Then
    led4 = ledoff
    End If
    Inc (I)
    DelayUS(20)
Wend
 
here is the completed SUB for multiple leds to fade from dim to full brightness
Code:
Sub Fade()
    
 Bright_1 = 1              // bright_1 is ON  time variable
 Dimmer_1 = 5000           //dimmer_1 is OFF time variable
Repeat
  PORTA = %11001111
  PORTB = %00000111
  PORTC = %00010001
  PORTD = %10001110
 
  DelayUS(Bright_1) 
  PORTA = %00000000
  PORTB = %00000000
  PORTC = %00000000
  PORTD = %00000000
  // DIMMING
  DelayUS (Dimmer_1) 
  Bright_1 = (Bright_1 +1)   // increase ON time BY 1
  Dimmer_1 = (Dimmer_1 - 1)  //decrease OFF time BY 1
 
 Until
 Bright_1 >= 3000            //HIGH BRIGHT
 
 //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//reset values
  Bright_2 = 5000
  Dimmer_2 = 1
 //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 
Repeat
  PORTA = %11001111
  PORTB = %00000111
  PORTC = %00010001
  PORTD = %10001110
 
  DelayUS(Bright_1) 
  PORTA = %00000000
  PORTB = %00000000
  PORTC = %00000000
  PORTD = %00000000
  DelayUS(Dimmer_2)           // full dim          FIRST PASS IN LOOP
  Bright_2 = (Bright_2 - 1)
  Dimmer_2 = (Dimmer_2 + 1)
 
 Until
 Bright_2 = 1
  
//reset valuesxxxxxxxxxxxxxx 
  Bright_2 = 1
  Dimmer_2 = 5000
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
End Sub
 
Hmmm. Looks like I forgot to click POST after I wrote this, and it looks like MrDEB is going to hang on to his way of doing things (which he is certainly entitled to do), so I'll just hide this away.

Let me explain this one last, final time.

The code I posted wasn't designed to be copied and pasted into your project. The purpose was for you to READ and UNDERSTAND the process so you could make it work to do what you want. Post #116 explains the steps in detail. If you won't go through the steps, please save us all a lot of grief and go back to what you were doing.

The counter is going to run from zero to some maximum value and then repeat. 0. 1. 2. 3. 4. 5. 6.. ... (max value) and back to zero. This goes on endlessly.

Let's say you want to flash an LED. You tell it when to turn on and when to turn off:

If Counter = 0 then turn the LED on.

If Counter = 100 then turn the LED off.

That turns the LED on one brief moment in the long loop. The make it flash, we need to slide the on and off points along the loop.

If Counter = 0 then turn the LED on and set the on point for the next cycle, which would be 200.

If Counter = 100 then turn the LED off and set the next off point, which would be 300.

Kick the can further ahead with each cycle. Read my code to understand how this works. It's not difficult. Once you understand this simple part, dimming a d fading will be easy.

If you can't figure this out, please delete everything related to my code and forgetaboutit.
 
here is the completed SUB for multiple leds to fade from dim to full brightness

Great. If you're happy with the way that looks then you could make the Fade() subroutine a little more versatile and save yourself a lot of typing as you make different patterns.

Code:
// bright is initial ON  time
// dimmer is initial OFF time
// stop is end value (loop until bright = stop)
// A, B, C, and D are port values
Sub Fade(bright as word, dimmer as word, stop as word, A as byte, B as byte, C as byte, D as byte)
    dim dir as boolean
  
    // figure out direction and account for 'repeat-until' end
    if (bright < dimmer) then
        dir = true                // increase ON time
        stop = stop + 1
    else
        dir = false                // increase OFF time
        stop = stop - 1
    endif
  
    repeat
        PORTA = A            // ON time
        PORTB = B
        PORTC = C
        PORTD = D
        delayus(bright)
      
        PORTA = 0            // OFF time
        PORTB = 0
        PORTC = 0
        PORTD = 0
        delayus(dimmer)
  
        if (dir) then
            bright = bright + 1        // increase ON time
            dimmer = dimmer - 1        // decrease OFF time
        else
            bright = bright - 1        // decrease ON time
            dimmer = dimmer + 1        // increase OFF time
        endif
    until (bright = stop)
end sub

main:
while (true)
    // fade brightness up
    Fade(1, 5000, 3000, %11001111, %00000111, %00010001, %10001110)

    // fade brightness down
    Fade(5000, 1, 1, %11001111, %00000111, %00010001, %10001110)
end while
 
Last edited:
got back to this program and finally read Tumbleweeds post # 148
That looks more versatile and cleaner code thanks
I am contemplating redesigning the method to drive all the leds.
considered using a transistor per port DDTA143TUA-7-F (post#9) but I recall a discussion about port expander?
some how drive all 70 leds without releasing the magic smoke.. 2 leds per port pin
 
What problem are you trying to solve by adding driver transistors? If you turn on ALL of LEDs simultaneously, you'll still be within the chip current limits. With parallel LEDs, calculate the current using Vf and R for one LED. That will be the total current through the resistor, but that current will be shared across the two parallel LEDs.

You are using 330 ohm resistors, and Vf depends on the color of the LEDs.

For Vf = 3.0, current for the group is 6mA. Current for each LED will be half of that, or 3mA.

For Vf = 3.7, current for the group is 4mA, so current is 2mA per LED.

Say you have 18 groups with Vf = 3.0 and 17 groups with Vf = 3.7 (this is worst case – if I have is backwards, current is even less):

Total current = 18 × 6 + 17 × 4 = 108 + 68 = 176mA if all LEDs are on. Close to the maximum recommended, but not over it.


As for using a driver chip, with the right chip selection, you can drive 70 LEDs INDIVIDUALLY (no need to pair them) and control the brightness on each LED separately – send a command to set the brightness and it's hands off. But this brings the complexity of controlling the chip using I2C or SPI where a whole lot of attention to detail is required to make the chip do anything.
 
at present, I have each port driving 2 blue or white leds in parallel.
using 1- 320 ohm resistor per pair
I come up with 6.14ma per pair round it off at 6.5ma
6.5ma x 35 = 227ma

the problem I had started with the footprint of the resistor array. have since found 25 resistor arrays at 560 ohms. The footprint for the arrays is discontinued I find out)
using EASYEDA I swapped out the 330 and need to redesign the board using a smaller footprint. Just thinking that the design is flawed using one resistor driving two blue or white LEDs in parallel is not the greatest thing to do.
 
I misread/mis-remembered one of your previous posts, and thought that one of your LEDs had a nominal Vf of 3v, the other 3.7v. So sorry.

Let's calculate the current at the worst case, which is the Vf of 2.8v. That results in a current of 6⅔ mA per pair = 233mA total if they are all on. It will actually be even higher, since Vf is based on 20mA drive current (usually) and decreases with lower drive current.

Just don't turn over three-quarters of them on at the same time. No problem then. I'd suggest you get this version working first before starting on a re-design.
 
The easiest way to figure this out is to turn them all on and measure the supply current.
Too many things change to make it a simple calculation unless you're shooting for worst-case numbers (port output voltage, LED Vf voltage, etc).

You're not sending this off into space or anything.
 
I'm not trying to be pedantic, just show that if you're pushing the limits, you need to check for the extreme case.

But at any rate, just don't turn on everything at the same time and it will be ok. And don't redesign until this version works. The paired LEDs spread out across the board limit the effects that can be done, like an LED chaser around the perimeter.
 
It is probably gonna be close, but in this case maybe not that far off that it matters.
In the end what's going to kill it is how much heat it generates/operates at, so if it runs cool enough you're good to go.

I agree... I'd definitely check it out before redesigning it yet again.
 
am redesigning the board so it is smaller. Added 2 additional leds as I had/ have one port not being used..
I am going to write some code to turn on all the white, measure current then measure with all the blue on.
the past two days been trying to recover my hacked email account.
Back to code in post #148 I think I made a wrong turn. It won't compile.
Code:
{
*****************************************************************************
*  Name    : UNTITLED.BAS                                                   *
*  Author  : [select VIEW...EDITOR OPTIONS]                                 *
*  Notice  : Copyright (c) 2022 [select VIEW...EDITOR OPTIONS]              *
*          : All Rights Reserved                                            *
*  Date    : 5/31/2022                                                      *
*  Version : 1.0                                                            *
*  Notes   :                                                                *
*          :                                                                *
*****************************************************************************
}
Device = 18F43K22
Clock = 8

// int osc and IO pin libraries
Include "intosc.bas"
#option DIGITALIO_INIT = true       // automatically call setalldigital
Include "setdigitalio.bas"

// hardware
Dim INDEX  As LongWord  //4294967295
Dim Counter As Word
Dim Counter_up As Word
Dim Counter_down As Word
Dim m As Byte
Dim w As Byte
Dim x As Byte
Dim y As Byte
Dim z As Byte
Dim Bright_1 As LongWord        // a wider range of settings FOR A SMOOTHER TRANSITION
Dim Dimmer_1 As LongWord
Dim Bright_2 As LongWord        // a wider range of settings
Dim Dimmer_2 As LongWord
Dim bright As Word
Dim dimmer As Word
Dim stop As Word
Dim  A As Byte
Dim B As Byte
Dim C As Byte
Dim D As Byte
Dim dir As Boolean




Sub Fade1()
 
    // figure out direction and account for 'repeat-until' end
    If (bright < dimmer) Then
        dir = true                // increase ON time
        stop = stop + 1
    Else
        dir = false                // increase OFF time
        stop = stop - 1
    EndIf
 
    Repeat
        PORTA = A            // ON time
        PORTB = B
        PORTC = C
        PORTD = D
        DelayUS(bright)
      
        PORTA = 0            // OFF time
        PORTB = 0
        PORTC = 0
        PORTD = 0
        DelayUS(dimmer)
 
        If (dir) Then
            bright = bright + 1        // increase ON time
            dimmer = dimmer - 1        // decrease OFF time
        Else
            bright = bright - 1        // decrease ON time
            dimmer = dimmer + 1        // increase OFF time
        EndIf
    Until (bright = stop)
End Sub

main:
// init hdw
               // LED port - all outputs 2 LEDs per port in parallel 330 ohm resistor
TRISA = 0
TRISB = 0
TRISC = 0
TRISD = 0
TRISE = 0
   PORTE=%000
   PORTD=%00000000
   PORTC=%00000000
   PORTA=%00000000
   PORTB=%00000000   
// bright is initial ON  time
// dimmer is initial OFF time
// stop is end value (loop until bright = stop)
// A, B, C, and D are port values

'main:
While (true)
    // fade brightness up
    Fade1(1, 5000, 3000, %11001111, %00000111, %00010001, %10001110)

    // fade brightness down
    Fade2(5000, 1, 1, %11001111, %00000111, %00010001, %10001110)
End While
 
There are so many mistakes... put the code back the way it was in post 148.

Get rid of all your variable declarations. The sub doesn’t need them.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…