Hi David,

The reason for choosing for a step increment of 2 is to limit the number of 
steps. If I had chosen to use a step increment of 1 then the timer has to run 
256 times faster than the chosen period time in order to be able to have 256 
steps in one period.. So in case of 80 Hz frequency timer has to run at around 
20 kHz or an interrupt time of 50 us. That would not leave much time left for 
the main program so that's why I used a step increment of 2 and to reducing the 
timer frequency around 10 kHz. Of course you can decide to go for 20 kHz so 
that you can use the 8 bit value  of the ADC. I assume your PIC runs at a 
higher frequency than 4 MHz.

Below another example using four LEDs, using timer 2. STEP_BRIGHT is called 
UP_BRIGHT here but you get the idea.

procedure pwm_cycle is pragma interrupt
   if PIR1_TMR2IF & PIE1_TMR2IE then
      PIR1_TMR2IF = FALSE

      ; First check the if we need to start a new period.
      if (pwm_period == 0) then
         ; New period. Switch leds on and start a new duty cycle.
         pwm_period = PWM_PERIOD_TIME
         led_1_timer = duty_cycle_1
         led_2_timer = duty_cycle_2
         led_3_timer = duty_cycle_3
         led_4_timer = duty_cycle_4
         led_1 = LED_ON
         led_2 = LED_ON
         led_3 = LED_ON
         led_4 = LED_ON
       else
          pwm_period = pwm_period - 1
       end if


       ; If the timer of the LED is 0 then the duty cycle time has passed.
       if led_1_timer >= UP_BRIGHT then
          led_1_timer = led_1_timer - UP_BRIGHT
       else
          led_1 = LED_OFF
       end if

       if led_2_timer >= UP_BRIGHT then
          led_2_timer = led_2_timer - UP_BRIGHT
       else
          led_2 = LED_OFF
       end if

       if led_3_timer >= UP_BRIGHT then
          led_3_timer = led_3_timer - UP_BRIGHT
       else
          led_3 = LED_OFF
       end if

       if led_4_timer >= UP_BRIGHT then
          led_4_timer = led_4_timer - UP_BRIGHT
       else
          led_4 = LED_OFF
       end if

   end if
end procedure


Kind regards,

Rob

________________________________
Van: jallib@googlegroups.com <jallib@googlegroups.com> namens 
pinhe...@gmail.com <pinhead...@gmail.com>
Verzonden: woensdag 21 juni 2023 11:33
Aan: jallib <jallib@googlegroups.com>
Onderwerp: Re: [jallib] Software PWM

@Kiste (Got it ;-)   )
Clever way to do it !   I guess it took some time to figure that out, and get 
it running properly, specially if you further had to manage the LED 
multiplexing.
Hats off !
I guess the PIC is running at a fairly high speed to be able to achieve all 
that process ?
BTW: My nickname "Pinhead" is usually a term referring to a pinball freak 
(which I am).   Furthermore, I like horror movies, and Pinhead is the name of 
one of those bad guys we love to hate (in the Hellraiser franchise).   That's 
why ;-)

@Rob
The resolution is not critical for dimming LED's in the way I intend: 127 
steps, as in your solution, are enough.   But why limit it with STEP_BRIGHT = 2 
?
If, for example, I would like to use the ADC value of a LDR to set the 
duty_cycle, I'd simply use the 8 MSB's of the ADC value, and that would give me 
8 bits resolution...
What was the requirement in your application to limit the resolution to 128 
steps ?
Also, is the PWM frequency critical ?  Otherwise, maybe you could get rid of 
the "pwm_period = PWM_PERIOD_TIME" line, isn't it ?

All in all, those two answers are food for thoughts, and I will certainly take 
your good advices.   Thanks for that !

Le mercredi 21 juin 2023 à 07:59:57 UTC+2, Rob CJ a écrit :
Hi David, Oliver,

What should be the resolution of the PWM? I sometimes made it in software using 
one timer and controlling several LEDS. In the example below I control one LED 
using 128 steps (step increment of 2 (STEP_BRIGHT)) but can be extended with 
more LEDs. Would that be sufficient for your application?

This was running on a 12F675 running at 4 MHz. The refresh rate was about 80 Hz 
to prevent flicker.  Below this program you find some calculations. Normally I 
used Timer 2 because of the automatic reload but this PIC did not have that.

; Interrupt routine for timer 0, handling the PWM signal in software.
; This routine is called every 107 us (measured) and takes between 18-28 us.
procedure timer_0_interrupt() is pragma interrupt

   if INTCON_T0IF then

      ; First preset the time for the next interrupt.
      TMR0 = TIMER_0_RELOAD
      INTCON_T0IF = FALSE

      ; Check the if we need to start a new period.
      if (pwm_period == 0) then
         ; New period. Switch LEDs on and start a new duty cycle.
         pwm_period = PWM_PERIOD_TIME
         pwm_timer = duty_cycle
         ; Only turn LED on if it has a duty cycle to prevent flashing.
         if (pwm_timer > 0) then
            LED = LED_ON
         end if
      else
         pwm_period = pwm_period - 1
      end if

      ; If the timer of the LED is at the mininum brightness then time has 
passed.
      if (pwm_timer >= BRIGHT_MIN) then
         pwm_timer = pwm_timer - STEP_BRIGHT
      else
         LED = LED_OFF
      end if


   end if

end procedure

Some constants I used.

; Specify the values for the minimum and maximum brightness of the LEDs and
; the value to increase or decrease it. The minimum value is not zero since
; we want to know if the device is on or off so there always has to be a
; minium brightness when the device is switched on.
const byte BRIGHT_MIN  = 10  ; Must be >= STEP_BRIGHT.
const byte BRIGHT_MAX  = 254 ; Must be even and <= 254
const byte STEP_BRIGHT = 2   ; This gives 254 / 2 = 127 steps.

; Timer reload value. The clock is 4 MHz so the timer clock is 1 MHz. Let's
; use 80 Hz as PWM frequency for the LEDs. This means that the timer has to
; run at 80 * 125 steps = 10.000 Hz or a period time of 100 us. With a prescale
; of 2 (minimum) the we need a timer value of 1.000.000 / 2 / 10.000 = 50.
; Since we use the timer overflow the reload value becomes 256 - 50 = 206.
; The measured value is 9.333 Hz, most like due to processing time.
const byte TIMER_0_RELOAD = 206.

; See timer init, 10.000 Hz / 125 gives 80 Hz. Measured is 74 Hz.
const byte PWM_PERIOD_TIME = 125

Kind regards,

Rob

________________________________
Van: 'Oliver Seitz' via jallib <jal...@googlegroups.com>
Verzonden: woensdag 21 juni 2023 07:38
Aan: jal...@googlegroups.com <jal...@googlegroups.com>
Onderwerp: Re: [jallib] Software PWM

Salut pinhead,

If I had to extend an existing controller with PWMs, I'd use e.g. PIC16F18313. 
It has 8 pins, I2C and 4 independent PWMs at a cost of less than 1,50€. I 
cannot tell however if the MCLR pin can be used for I2C. A safe choice would be 
12F1572 which is even cheaper and has 4x 16bit PWM. You can use serial_software 
for communication, as the PWMs run happily on their own.

Yes, the way you're describing you could dim LEDs, but each time something else 
is happening, like new I2C-input is processed, all your LEDs would slightly 
flicker.

When I did bitbang-dim 120 multiplexed LEDs, i did it binarily: If bit 7 is 
set, light up the LED for 128µs. Then, if bit 6 is set, light up the LED for 
another 64µs and so on. The brightness sums up in the eye of the beholder. I've 
programmed a timer to generate an interrupt in succession after 128, then 64, 
then 32... µs. However, 4,2 and 1 µs I did without leaving the ISR. I did not 
use any "if" for that, I had an 8x8bit matrix with the dimming values, which I 
rotated by 90°, so I had a byte full of "bit7" of each channel, a "bit6" of 
each channel and so on. So, the ISR had nothing to do but move the "bit7"-byte 
to the output port right before the 128µs interrupt delay, the "bit6"-byte 
before the 64µs delay... That way I could dim 8 LEDs (all on e.g. PORTA) for 
the price of one.

Oliver is my real name, but Kiste (=Carton(fr) =Doos(nl) =Box(en)) is my very 
common nickname, even in real life.

Greets,
Kiste

Am Dienstag, 20. Juni 2023 um 22:10:07 MESZ hat pinhe...@gmail.com 
<pinhe...@gmail.com> Folgendes geschrieben:


Hello Oliver,

Indeed, PIC18F27J13 could be a candidate.  I overlooked this one too quickly (I 
already ranted about the parametric search tool on the µchip site :-{   )
I'll check for the other characteristics.
No internal OPAMP and internal VREF are a bit annoying, but if it's the only 
missing parts, it's ok.

Anyway, what about a PIC that would be programmed as a I²C generator with 
several independant channels, and I²C slave.

He would have nothing else to do than generating the signals.
Consider one channel:
- A register contains the value of its duty cycle (from 0 to 255)
- In the main loop, a 8-bit counter is incremented.
  - At each increment, its value is compared to the duty cycle register, and if 
needed, the corresponding output is toggled.

You could generate as many PWM signals as there are IOs available.
The I²C-slave interface would be handled by the MSSP module with interrupts 
(yes, this could cause glitches in the PWM signals if the time needed to 
process the I²C processes is greater than the time it takes to increment the 
PWM counter by one, but if it is only to dim some LED's, I think I could live 
with it)
The frequency could be adjusted by changing the oscillator frequency and/or 
adding delays in the main loop when the main counter is incremented

Just for the sake of it, I think I will give it a try.....

Hoping I am not overlooking a major impediment

Thanks for your suggestion, Oliver (or Kiste ?)


Le mardi 20 juin 2023 à 20:43:01 UTC+2, Oliver Seitz a écrit :
Hi!

A software PWM library isn't easy. Without a timer, it blocks everything. With 
a timer, it's complicated and would only add a few channels. I've done software 
PWM for 120 LEDs independently with a 28 pin controller, but it couldn't do 
much more than that at 64MHz.

Have you had a look at, say, PIC18F27J13? It has 3+7 independent ccp modules 
(with 3 TMR2-type timers).

Greets,
Kiste

Am Dienstag, 20. Juni 2023 um 19:49:33 MESZ hat pinhe...@gmail.com 
<pinhe...@gmail.com> Folgendes geschrieben:


Hi,

I'm falling short of PWM outputs for a project.
I need 6 independant outputs, and the only way to get them is to use a 64-pin 
18fxxxx, which is a bit overkill for me, or use a second PIC, bond to the first 
(I²C or SPI) which is also overkill but could be acceptable in the absence of 
another "clean" solution.

It will only be used for dimming LED's, and I don't need particular features 
like dead-band, half or full bridges, precise or stable frequency.....

To my surprise, I didn't find a software PWM library in Jallib 1.8.....
Or do I miss something ?

Have a nice day







--
You received this message because you are subscribed to the Google Groups 
"jallib" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to jallib+un...@googlegroups.com.

To view this discussion on the web visit 
https://groups.google.com/d/msgid/jallib/923bd215-4855-49d9-b7e1-17e02482c219n%40googlegroups.com<https://groups.google.com/d/msgid/jallib/923bd215-4855-49d9-b7e1-17e02482c219n%40googlegroups.com?utm_medium=email&utm_source=footer>.

--
You received this message because you are subscribed to the Google Groups 
"jallib" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to jallib+un...@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/jallib/9aad71fb-a1f2-47f3-8cc4-82a1110327c2n%40googlegroups.com<https://groups.google.com/d/msgid/jallib/9aad71fb-a1f2-47f3-8cc4-82a1110327c2n%40googlegroups.com?utm_medium=email&utm_source=footer>
.

--
You received this message because you are subscribed to the Google Groups 
"jallib" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to jallib+un...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jallib/1639372286.1548147.1687325901648%40mail.yahoo.com<https://groups.google.com/d/msgid/jallib/1639372286.1548147.1687325901648%40mail.yahoo.com?utm_medium=email&utm_source=footer>.

--
You received this message because you are subscribed to the Google Groups 
"jallib" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to 
jallib+unsubscr...@googlegroups.com<mailto:jallib+unsubscr...@googlegroups.com>.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jallib/87f34955-bd10-4bca-980b-8cce7b5dac0an%40googlegroups.com<https://groups.google.com/d/msgid/jallib/87f34955-bd10-4bca-980b-8cce7b5dac0an%40googlegroups.com?utm_medium=email&utm_source=footer>.

-- 
You received this message because you are subscribed to the Google Groups 
"jallib" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to jallib+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jallib/GVXP195MB1637B7D84672E7A24C12D980E65DA%40GVXP195MB1637.EURP195.PROD.OUTLOOK.COM.

Reply via email to