using PWM to dim LED NEON STRIP

MrDEB

Well-Known Member
couldn't locate this thread but here is the issue
I breadboarded this circuit and it seems to work driving just an LED but I am driving a 12v led neon strip.
The circuit flashes the strip slowly to fast as per pot adjustment.
The 555 circuit works as planned with one LED (it is supposed to change the duty cycle
Thinking the two different supply voltages has something but what to do? Any suggestions?
NOTE THE 7555 IS POWERED BY THE pic
the MOSFET is logic level
 

Attachments

  • dimming circuit brd.png
    89.4 KB · Views: 490
thinking about going back to the schematic in post#45 using the 555 timers as the PWM suggested by tumbleweed is good but I need to have DELAYMS() to simulate drinking straw and glass being filled.
several corrections to schematic in post#45 eliminate the 9v regulator
here is basically what I am trying to do but all the DELAYMS() will mess up the PWM section. I tried adding a second timer but no can do. I tried post 14 and it works as planned but need the drinking simulation
Code:
Device = 18F2221
Clock = 32

Include "intosc.bas"
// do NOT include setdigitalio
// to use PORTB for the ADC all pins must be in analog mode due to the way
// these old pics map ADC inputs

Include "adc.bas"

// ADC pot inputs
// used to set the PWM duty cycle for PWM1-PWM3
// connect pot upper lug = VDD, lower lug = GND, wiper = port IO
Dim
    POT1 As PORTB.0,    // RB0/AN12
    POT2 As PORTB.1,    // RB1/AN10
    POT3 As PORTB.2     // RB2/AN8

// ADC channels
Const
    CH_POT1 = 12,       // AN12
    CH_POT2 = 10,       // AN10
    CH_POT3 = 8         // AN8
 
// PWM outputs
Dim
    PWM1 As PORTA.5,
    PWM2 As PORTA.6,
    PWM3 As PORTA.7

// pwm duty cycles (from ADC) 0=min, 255=max
Dim
    pwm1_duty As Byte,
    pwm2_duty As Byte,
    pwm3_duty As Byte

Dim pwm_period As Byte

// pwm timer TMR2
Dim
    TMR2IF As PIR1.bits(1),
    TMR2IE As PIE1.bits(1),
    TMR2ON As T2CON.bits(2)
    
    
dim straw_0 as portc.0,
    straw_1 as portc.1,
    straw_2 as portc.2,
    straw_3 as portc.3,
    straw_4 as portc.4,
    straw_5 as portc.5
    
dim Drink_0 as porta.0,
    Drink_1 as porta.1,
    Drink_2 as porta.2,
    Drink_3 as porta.3,
    Drink_4 as porta.4,
    Drink_5 as porta.5
 
// set IO pin directions and initial settings
Sub InitIO()
    // set inputs
    Input(POT1)
    Input(POT2)
    Input(POT3)
 
    // set outputs (low to start)
    Low(PWM1)
    Low(PWM2)
    Low(PWM3)
End Sub

// pwm TMR2 interrupt
Interrupt tmr2_isr()
    TMR2IF = 0   
    pwm_period = pwm_period + 1
    If (pwm_period >= pwm1_duty) Then
        PWM1 = 0
    Else
        PWM1 = 1
    EndIf
    If (pwm_period >= pwm2_duty) Then
        PWM2 = 1
    Else
        PWM2 = 0
    EndIf
    If (pwm_period >= pwm3_duty) Then
        PWM3 = 1
    Else
        PWM3 = 0
    EndIf
End Interrupt


main:
InitIO()

// ADC setup
ADCON1 = $00        // all pins set to analog mode, VREF = VDD/GND
ADCON2 = ADC.FRC    // ADC clock = Frc
ADC.ADFM = 0        // left justify (we only use the 8 MSB's)
ADC.SetAcqTime(100) // 100us delay

pwm_period = 0
pwm1_duty = 0
pwm2_duty = 0
pwm3_duty = 0

// setup pwm timer TMR2
// 25KHz = 40us/bit -> 40us x 256 = 10240us period, ~10ms period (100Hz)
T2CON = %00000001   // T2OUTPS<3:0>=%000 (1:1), TMR2ON=0, T2CKPS<1:0>=%01 (1:4)
PR2 = 176
TMR2 = 0
TMR2IF = 0
TMR2IE = 1
TMR2ON = 1

Enable(tmr2_isr)

While (true)   //DELAYMS is a no no
    pwm1_duty = ADC.Read(CH_POT1) >> 8
    pwm2_duty = ADC.Read(CH_POT2) >> 8
    pwm3_duty = ADC.Read(CH_POT3) >> 8
    drink_0 = 1
    delayms(1000)    //simulate glass bing filled
    drink_1 = 1
    delayms(1000)
    drink_2 = 1
    delayms(1000)
    drink_3 = 1
    delayms(1000)
    drink_4 = 1
    delayms(1000)
    drink_5 = 1
    straw_0 = 1         //simulate liquid going up straw
    delayms(500)
     straw_0 = 1         //simulate liquid going up straw
    delayms(500)
     straw_1 = 1         //simulate liquid going up straw
    delayms(500)
     straw_2 = 1         //simulate liquid going up straw
    delayms(500)
     straw_3 = 1         //simulate liquid going up straw
    delayms(500)
    straw_4 = 1         //simulate liquid going up straw
    delayms(500)
    straw_5 = 1         //simulate liquid going up straw
    delayms(500)
    
    
    
End While
 
It was just groundhog day. How many times will what happens with delay statements need to be explained?


It was just groundhog day. How many times will what happens with delay statements need to be explained?


It was just groundhog day. How many times will what happens with delay statements need to be explained?


It was just groundhog day. How many times will what happens with delay statements need to be explained?


was just groundhog day. How many times will what happens with delay statements need to be explained?
 
Sounds like a good idea to change direction again.
 
I don't know why I do this...

here is basically what I am trying to do but all the DELAYMS() will mess up the PWM section.
No it won't. The only thing the delayms() calls will do is make it difficult to adjust the PWM since it delays reading the pots. The outputs will still pwm just fine.

Did you ever make the 'straw_x' and 'drink_x' pins outputs? (answer: no, I didn't).
Also, you have 'Drink_5 as porta.5', which is the same pin as PWM1 so 'Drink_5' is going to be pwm'd.
 
Here's what #142 might look like if it was written to work, keeping in mind I have no idea what you want to do...
(This doesn't fix the 'Drink_5' and PWM1 conflict though. That one's on you)

Code:
Device = 18F2221
Clock = 32

Include "intosc.bas"
// do NOT include setdigitalio
// to use PORTB for the ADC all pins must be in analog mode due to the way
// these old pics map ADC inputs

Include "adc.bas"

// ADC pot inputs
// used to set the PWM duty cycle for PWM1-PWM3
// connect pot upper lug = VDD, lower lug = GND, wiper = port IO
Dim
    POT1 As PORTB.0,    // RB0/AN12
    POT2 As PORTB.1,    // RB1/AN10
    POT3 As PORTB.2     // RB2/AN8

// ADC channels
Const
    CH_POT1 = 12,       // AN12
    CH_POT2 = 10,       // AN10
    CH_POT3 = 8         // AN8
 
// PWM outputs
Dim
    PWM1 As PORTA.5,
    PWM2 As PORTA.6,
    PWM3 As PORTA.7

// pwm duty cycles (from ADC) 0=min, 255=max
Dim
    pwm1_duty As Byte,
    pwm2_duty As Byte,
    pwm3_duty As Byte

Dim pwm_period As Byte

// pwm timer TMR2
Dim
    TMR2IF As PIR1.bits(1),
    TMR2IE As PIE1.bits(1),
    TMR2ON As T2CON.bits(2)
    
dim straw_0 as portc.0,
    straw_1 as portc.1,
    straw_2 as portc.2,
    straw_3 as portc.3,
    straw_4 as portc.4,
    straw_5 as portc.5
    
dim Drink_0 as porta.0,
    Drink_1 as porta.1,
    Drink_2 as porta.2,
    Drink_3 as porta.3,
    Drink_4 as porta.4,
    Drink_5 as porta.5

dim drink_no as byte,
    straw_no as byte
    
// set IO pin directions and initial settings
Sub InitIO()
    // set inputs
    Input(POT1)
    Input(POT2)
    Input(POT3)
 
    // set outputs (low to start)
    Low(PWM1)
    Low(PWM2)
    Low(PWM3)

    // set Drink_0-Drink_5 outputs low
    LATA = 0
    TRISA = TRISA and %11000000
    
    // set Straw_0-Straw_5 outputs low
    LATC = 0
    TRISC = TRISC and %11000000
End Sub

// pwm TMR2 interrupt
Interrupt tmr2_isr()
    TMR2IF = 0   
    pwm_period = pwm_period + 1
    If (pwm_period >= pwm1_duty) Then
        PWM1 = 0
    Else
        PWM1 = 1
    EndIf
    If (pwm_period >= pwm2_duty) Then
        PWM2 = 1
    Else
        PWM2 = 0
    EndIf
    If (pwm_period >= pwm3_duty) Then
        PWM3 = 1
    Else
        PWM3 = 0
    EndIf
End Interrupt


main:
InitIO()

// ADC setup
ADCON1 = $00        // all pins set to analog mode, VREF = VDD/GND
ADCON2 = ADC.FRC    // ADC clock = Frc
ADC.ADFM = 0        // left justify (we only use the 8 MSB's)
ADC.SetAcqTime(100) // 100us delay

pwm_period = 0
pwm1_duty = 0
pwm2_duty = 0
pwm3_duty = 0

// setup pwm timer TMR2
// 25KHz = 40us/bit -> 40us x 256 = 10240us period, ~10ms period (100Hz)
T2CON = %00000001   // T2OUTPS<3:0>=%000 (1:1), TMR2ON=0, T2CKPS<1:0>=%01 (1:4)
PR2 = 176
TMR2 = 0
TMR2IF = 0
TMR2IE = 1
TMR2ON = 1

Enable(tmr2_isr)

drink_no = 0
straw_no = 0

While (true)
    pwm1_duty = ADC.Read(CH_POT1) >> 8
    pwm2_duty = ADC.Read(CH_POT2) >> 8
    pwm3_duty = ADC.Read(CH_POT3) >> 8

    // simulate glass being filled
    select(drink_no)
        case 0: drink_0 = 1
        case 1: drink_1 = 1
        case 2: drink_2 = 1
        case 3: drink_3 = 1
        case 4: drink_4 = 1
        case 5: drink_5 = 1
    end select
    if (drink_no < 5) then
        drink_no = drink_no + 1
        delayms(1000)
    endif
    
    // simulate liquid going up straw
    if (drink_no = 5) then
        select(straw_no)
            case 0: straw_0 = 1
            case 1: straw_1 = 1
            case 2: straw_2 = 1
            case 3: straw_3 = 1
            case 4: straw_4 = 1
            case 5: straw_5 = 1
        end select
        if (straw_no < 5) then
            straw_no = straw_no + 1
            delayms(500)
        endif
    endif
End While
 
If popcorn looked, I stated delays are a no-no right next to the while true statement BUT in tumbleweeds suggestion it has a delayms??
will make corrections and run it today thanks
 
Here's what I think you might be after...
it has the animation, and it allows you to use the pots to control the Drink and Straw outputs which are pwm'd.
POT1 controls 'Drink' outputs, POT2 controls the (unused) PWM7 and PWM8 outputs, and POT2 controls 'Straw' outputs

Because of the delayms() calls it may take a second or two to react to adjusting the pots, but that won't stop the pwm.

Code:
// Swordfish BASIC sixteen channel software PWM using TMR2 and 3 pot ADC inputs
// schematic https://www.electro-tech-online.com/threads/using-pwm-to-dim-led-neon-strip.165067 post #112
// v3 - programmable outputs with Drink and Straw animation
device = 18F2221
clock = 32

include "intosc.bas"
// do NOT include setdigitalio
// to use PORTB for the ADC all pins must be in analog mode due to the way
// these old pics map ADC inputs

include "adc.bas"

// ADC pot inputs
// used to set the PWM duty cycle for PWM1-PWM8 and LED1-LED8
// connect pot upper lug = VDD, lower lug = GND, wiper = port IO
dim
    POT1 as PORTB.0,    // RB0/AN12
    POT2 as PORTB.1,    // RB1/AN10
    POT3 as PORTB.2     // RB2/AN8

// ADC channels
const
    CH_POT1 = 12,       // AN12
    CH_POT2 = 10,       // AN10
    CH_POT3 = 8         // AN8
 
// PWM outputs  (controlled by POT1 and POT2)
dim
    PWM1 as PORTA.0,    // controlled by POT1
    PWM2 as PORTA.1,
    PWM3 as PORTA.2,
    PWM4 as PORTA.3,
    PWM5 as PORTA.4,
    PWM6 as PORTA.5,
    PWM7 as PORTA.6,    // controlled by POT2
    PWM8 as PORTA.7     // controlled by POT2

// LED PWM outputs (all controlled by POT3)
dim
    LED1 as PORTC.0,
    LED2 as PORTC.1,
    LED3 as PORTC.2,
    LED4 as PORTC.3,
    LED5 as PORTC.4,
    LED6 as PORTC.5,
    LED7 as PORTC.6,
    LED8 as PORTC.7

// this structure holds the on-off state of the pwm and led outputs
// to turn an output on, set it to 1 (ie 'vPORTS.vPWM2 = 1')
// to turn an output off, set it to 0 (ie 'vPORTS.vPWM2 = 0')
// dimming for all outputs is still controlled by the pots
structure vPORT_t
    vPWM as byte
    vLED as byte

    vPWM1 as vPWM.bits(0)       // PWM1-PWM8 settings
    vPWM2 as vPWM.bits(1)
    vPWM3 as vPWM.bits(2)
    vPWM4 as vPWM.bits(3)
    vPWM5 as vPWM.bits(4)
    vPWM6 as vPWM.bits(5)
    vPWM7 as vPWM.bits(6)
    vPWM8 as vPWM.bits(7)
   
    vLED1 as vLED.bits(0)       // LED1-LED8 settings
    vLED2 as vLED.bits(1)
    vLED3 as vLED.bits(2)
    vLED4 as vLED.bits(3)
    vLED5 as vLED.bits(4)
    vLED6 as vLED.bits(5)
    vLED7 as vLED.bits(6)
    vLED8 as vLED.bits(7)
end structure
dim vPORTS as vPORT_t

// Drink and Straw alias names for PWMx and LEDx states
dim
    drink_0 as vPORTS.vPWM1,    // PORTA.0-PORTA.5
    drink_1 as vPORTS.vPWM2,
    drink_2 as vPORTS.vPWM3,
    drink_3 as vPORTS.vPWM4,
    drink_4 as vPORTS.vPWM5,
    drink_5 as vPORTS.vPWM6
dim
    straw_0 as vPORTS.vLED1,    // PORTC.0-PORTC.5
    straw_1 as vPORTS.vLED2,
    straw_2 as vPORTS.vLED3,
    straw_3 as vPORTS.vLED4,
    straw_4 as vPORTS.vLED5,
    straw_5 as vPORTS.vLED6

dim drink_no as byte,
    straw_no as byte

// pwm duty cycles (from ADC) 0=min, 255=max
dim
    pwm1_duty as byte,
    pwm2_duty as byte,
    pwm3_duty as byte

dim pwm_period as byte

// pwm timer TMR2
dim
    TMR2IF as PIR1.bits(1),
    TMR2IE as PIE1.bits(1),
    TMR2ON as T2CON.bits(2)
 
// macro to toggle an individual bit
macro toggle_bit(x)
    if (x = 1) then
        x = 0
    else
        x = 1
    endif               
end macro

// set IO pin directions and initial settings
sub InitIO()
    // set inputs
    input(POT1)
    input(POT2)
    input(POT3)
 
    // set outputs (low to start)
    low(PWM1)
    low(PWM2)
    low(PWM3)
    low(PWM4)
    low(PWM5)
    low(PWM6)
    low(PWM7)
    low(PWM8)

    low(LED1)
    low(LED2)
    low(LED3)
    low(LED4)
    low(LED5)
    low(LED6)
    low(LED7)
    low(LED8)

    // set all the variable states to low (off)
    clear(vPORTS)
end sub

// pwm TMR2 interrupt
interrupt tmr2_isr()
    TMR2IF = 0  
    pwm_period = pwm_period + 1
    // outputs controlled by POT1
    if (pwm_period >= pwm1_duty) then   // set outputs off
        PWM1 = 0
        PWM2 = 0
        PWM3 = 0
        PWM4 = 0
        PWM5 = 0
        PWM6 = 0
    else                                // set outputs to current variable setting
        PWM1 = vPORTS.vPWM1
        PWM2 = vPORTS.vPWM2
        PWM3 = vPORTS.vPWM3
        PWM4 = vPORTS.vPWM4
        PWM5 = vPORTS.vPWM5
        PWM6 = vPORTS.vPWM6
    endif
    // outputs controlled by POT2
    if (pwm_period >= pwm2_duty) then   // set outputs off
        PWM7 = 0
        PWM8 = 0
    else                                // set outputs to current variable setting
        PWM7 = vPORTS.vPWM7
        PWM8 = vPORTS.vPWM8
    endif
    // outputs controlled by POT3
    if (pwm_period >= pwm3_duty) then   // set outputs off
        LED1 = 0
        LED2 = 0
        LED3 = 0
        LED4 = 0
        LED5 = 0
        LED6 = 0
        LED7 = 0
        LED8 = 0
    else                                // set outputs to current variable setting
        LED1 = vPORTS.vLED1
        LED2 = vPORTS.vLED2
        LED3 = vPORTS.vLED3
        LED4 = vPORTS.vLED4
        LED5 = vPORTS.vLED5
        LED6 = vPORTS.vLED6
        LED7 = vPORTS.vLED7
        LED8 = vPORTS.vLED8
    endif
end interrupt

main:
InitIO()

// ADC setup
ADCON1 = $00        // all pins set to analog mode, VREF = VDD/GND
ADCON2 = ADC.FRC    // ADC clock = Frc
ADC.ADFM = 0        // left justify (we only use the 8 MSB's)
ADC.SetAcqTime(100) // 100us delay

pwm_period = 0
pwm1_duty = 0
pwm2_duty = 0
pwm3_duty = 0

// setup pwm timer TMR2
// 25KHz = 40us/bit -> 40us x 256 = 10240us period, ~10ms period (100Hz)
T2CON = %00000001   // T2OUTPS<3:0>=%000 (1:1), TMR2ON=0, T2CKPS<1:0>=%01 (1:4)
PR2 = 176
TMR2 = 0
TMR2IF = 0
TMR2IE = 1
TMR2ON = 1

// start pwm dimming
enable(tmr2_isr)

drink_no = 0
straw_no = 0

while (true)
    // read pots and set pwm duty cycle
    pwm1_duty = ADC.Read(CH_POT1) >> 8
    pwm2_duty = ADC.Read(CH_POT2) >> 8
    pwm3_duty = ADC.Read(CH_POT3) >> 8
   
    // simulate glass being filled
    select(drink_no)
        case 0: drink_0 = 1
        case 1: drink_1 = 1
        case 2: drink_2 = 1
        case 3: drink_3 = 1
        case 4: drink_4 = 1
        case 5: drink_5 = 1
    end select
    if (drink_no < 5) then
        drink_no = drink_no + 1
        delayms(1000)
    endif
   
    // simulate liquid going up straw and emptying the glass
    if (drink_no = 5) then
        select(straw_no)
            case 0: straw_0 = 1
                    drink_5 = 0
            case 1: straw_1 = 1
                    drink_4 = 0
            case 2: straw_2 = 1
                    drink_3 = 0
            case 3: straw_3 = 1
                    drink_2 = 0
            case 4: straw_4 = 1
                    drink_1 = 0
            case 5: straw_5 = 1
                    drink_0 = 0
            case 6: straw_0 = 0            // now empty the straw
            case 7: straw_1 = 0
            case 8: straw_2 = 0
            case 9: straw_3 = 0
            case 10:straw_4 = 0
            case 11:straw_5 = 0
        end select
        if (straw_no < 12) then
            straw_no = straw_no + 1
            delayms(500)
        else    // start over
            drink_no = 0
            straw_no = 0
            delayms(500)
        endif
    endif
end while
 
I stated delays are a no-no right next to the while true statement BUT in tumbleweeds suggestion it has a delayms??
You can have delayms() calls, but you need to understand how they effect things.
In your post #142, every time around the 'while' loop there is about 9 seconds of delay.
That makes for a really long lag time between adjusting the pots and the out pwm changing.

Plus, the 'Drink' and 'straw' outputs are not part of the pwm code done in the isr, so they aren't controlled by it at all.
It never worked cause you never made the IO pins outputs.
 
using this schematic with 3 MOSFETs in parallel. need to keep the MOSFETs from getting too warm. I really should redesign the board and use the PCboard as the heat sink. Trying to keep the current per MOSFET below 2 amps and the lettering has the most draw (I need to remeasure all the circuits)
hopefully this should work?
 

Attachments

  • margarita sign.jpg
    366 KB · Views: 159
using this schematic with 3 MOSFETs in parallel. need to keep the MOSFETs from getting too warm.
If this is what you're talking about (hard to keep track of the differences in the dozens of schematics you post).....



... the answer is bad idea. TI's Application Brief Tips for Successfully Paralleling Power MOSFETs explains:

The current in each FET is proportional to the inverse of its on resistance, RDS(on). Naturally, the device with the lowest RDS(on) will carry more current. As it heats up, its RDS(on) increases, shifting some of the current to the other FETs. The junction temperatures of paralleled FETs with good thermal coupling will be roughly the same. Current sharing still depends on the relative on-resistance of each FET and will be within the RDS(on) tolerances specified in the MOSFET data sheet.

During dynamic operation, the FET with the lowest threshold voltage, VGS(th), turns on first and turns off last. This FET takes more of the switching losses and sees higher stresses during switching transitions. To some extent, the thermal sharing effect balances out the switching and conduction losses, and the FETs will operate at roughly the same temperature.

Best Practices When Paralleling Power MOSFETs

Here are helpful tips when using FETs in parallel:
• Each FET needs its own gate resistor with a value from a few ohms up to tens of ohms. This helps with current sharing and prevents gate oscillations.
FETs need good thermal coupling to ensure current and thermal balancing between devices. They can be mounted on a common heat sink or copper plane to maintain equal temperatures.
• The placement and layout of each FET should be identical and symmetrical, within reason, to equalize parasitic inductance in the critical gate-to-source and drain-to-source loops.
 
I guess MrDEB doesn't like my answer, since he didn't even acknowledge it. *shrug*
I don't know why there is even a discussion about heat of that mosfet, heat sinking it, or even paralleling it. These are beasts and, with an R(on) of only 22milliOhms, will generate only 88mWatts of heat plus switching losses (I doubt will be over a half-watt (which is my advice for using a heat sink).

My advice would be to set it up with a single mosfet on each string of LEDs and feel if they get warm (I doubt it). If (IF!) they do get warm, not many big concerns because these beasts can handle a max junction temp of 175°C. Good luck, MrDEB. No need to help the OP over-over-engineer it.
 
I don't know why there is even a discussion about heat of that mosfet, heat sinking it, or even paralleling it


ZipZapOuch – The QUESTION was asked and answered with an authoritative reference – will MOSFETs work in parallel.

I don't know if MrDEB thinks the MOSFETs are getting too hot or if they may actually be too hot. I don't know how much if any heat sink area they have on the board (although I do believe I mentioned it with illustrations). I don't know what current is being drawn – I believe there are specs for some LED neon in the 8 pages of this thread or in any of the 3 or 4 equally lengthy threads, but that may or may not be accurate in any case. The question ASKED was answered.

I don't read many of your replies in this forum, but in the few I do read, you're ALWAYS argumentative. Whatever gets you off I guess.
 
Or, you could have just clicked, "like".
 
In response to post #154 I just got back on my computer today, Monday February 4 2024
Hopefully, my PCboard enclosure gets here today, then I can test all the strips as well as the current draw and heat of each MOSFET.
I will post the measurement data after I get the board mounted etc.
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…