Menu

Setting up a timer along with a PWM output

Winch
2022-05-12
2022-05-20
1 2 3 > >> (Page 1 of 3)
  • Winch

    Winch - 2022-05-12

    I'm struggling with a piece of written software and I just don't understand the problem?
    Timer 1 I have set up to examples from GC and seems to work fine.
    But when I merge this with a PWM output, the program no longer runs as it should.
    Does this have to do with the fact that a PWM output also uses a timer and that this does not go together? The question then is automatically how should you use a timer intended for slowing down processes together with a PWM output?

    I've created a virtual timer (Timer_1) that I let run when a timer1overflow occurs.
    Then he increments by 1 and so on. I have this done every 10mS.
    And that works fine as long as I don't activate the PWM.

    Can anyone help?

    ; ----- Configuration
        #chip mega32u4,16
        #option explicit
    
    ;----- Determine where the Switch is connected to the microcontroller
      #define HkeyC PortD.4   'High key Cold
      #define LkeyC PortD.5   'Low key Cold
      #define HkeyW PortD.7   'High key Warm
      #define LkeyW PortD.6   'Low key Warm
    
    ;----- Determine where the RGB LED is connected to the microcontroller
      #define LED_Blue PortE.2    'Blue led connection
      #define LED_Red PortE.6   'Red led connection
    
    ;----- Determine where the Buzzer is connected to the microcontroller
      #define Soundout PortB.7
    
      #define Motion PortB.4    'When the PIR sensor is detected, input is pulled low
    
    ;----- Determine where the Switch is connected to the microcontroller
      #define Control PortD.1
      #define PS_ShutDown PortB.0
    
    ;----- Determine how the PWM is connected
      #define AVRTC0    'Specifies AVR TC0 associated with channel 1, and 2
      #define AVRCHAN2  'Specifies AVR HPWM channel 2 to the associated output pin OC0B (Axial Fan)
    
      #define AVRTC1    'Specifies AVR TC1 associated with channel 3, 4 and 5 
      #define AVRCHAN3  'Specifies AVR HPWM channel 3 to the associated output pin OC1A (Warm output)
      #define AVRCHAN4  'Specifies AVR HPWM channel 4 to the associated output pin OC1B (Cold output)
    
    ; ----- Define Hardware settings PWM output
      dir PortB.5 out   'PWM output for the Warm light (port OC1A)
      dir PortB.6 out   'PWM output for the Cold light (port OC1B)
      dir PortD.0 out   'Set the PWM channel for the Axial Fan (port OC0B)
    
    ; ----- Define Hardware settings RGB LED
      dir PortE.2 out   'Blue Led
      dir PortE.6 out   'Red Led
    
    ; ----- Define Hardware settings Efapel Switch
      dir PortD.4 in    'High key Cold
      dir PortD.5 in    'Low key Cold
      dir PortD.6 in    'Low key Warm
      dir PortD.7 in    'High key Warm
    
    ; ----- Define Hardware settings Switch
      dir PortD.1 in     'Control switch
      dir PortB.0 out    'ShutDown system
    
    ; ----- Define Hardware settings Buzzer
      dir PortB.7 out
    
    ;----- Define Hardware settings for the PIR, CO2 sensor
      dir PortB.4 in    'Input motion PIR sensor
    
    ;----- Variables
      Dim Motion_On, Bright_C, Bright_W, Freq, as Byte
      Dim Timer_1, as Word
    
      Led_blue = 1
      Led_Red = 1
      PS_ShutDown = 1
      Freq = 100
    
    ;----- Sound when starting up
        Start_up 
        Timer
    
    ;----- Main body of program commences here.
    Main:
    
        If Motion = 0 then
            Timer_1 = 0
            Led_Red = 1     ;when high the LED is off
        End If
    
        If Timer_1 = 100 then
            Scene_C10W30
            Led_Red = 0     ;when low the LED is on
        end if
    
    goto main
    end
    
    sub Scene_C10W30
      Bright_C = 10
      Bright_W = 78
      HPWM 4, Freq, Bright_C
      HPWM 3, Freq, Bright_W
    end sub
    
    Sub Timer
        On Interrupt Timer1Overflow Call Counter_1
        Inittimer1 osc, PS_1_64
        Starttimer 1
        Settimer 1, 63036   ;preload timer
    End sub
    
    Sub Counter_1
        Settimer 1, 63036
        Timer_1 = Timer_1 + 1
    End sub
    
    sub Start_up
        Tone 440, 100               
    End sub    
    
     
  • Anobium

    Anobium - 2022-05-12

    You need @kent_twt4

    :-)

     
  • Winch

    Winch - 2022-05-12

    What do you mean?

     
  • kent_twt4

    kent_twt4 - 2022-05-12

    Hello, I wrote the HPWM for the AVR

    There is a conflict with trying to using TC1 as both a counter and PWM as suspected,. In the PWM mode it clears the counter when it reaches the top value for PWM, and when it is 0, it disables the Timer altogether.

    You have three PWM's on TC1 why not put your fan on Chan5 (OC1C)? Then use TMR0 for the counter, or TMR2 if the prescale does not work out.

     
  • Winch

    Winch - 2022-05-13

    Hello Kent!
    Does this mean that you will never have all the PWM outputs at your disposal? At least in combination with the use of a timer.
    The practical problem now is that I have made a PCB where these outputs are already captured.
    But if I understand correctly, shouldn't I use a different timer?
    Maybe just Timer 5?

     
  • Winch

    Winch - 2022-05-13

    In the meantime I am trying to set up a Timer with timer4 from this microcontroller.
    Timer5 does not exist by the way.
    But here too I face quite a few challenges? My question is actually can I use this timer4?

     
  • Winch

    Winch - 2022-05-13

    In the datasheet I see that it is basically a 10 bit timer but can be used as an 8 bit.
    Do I have to use a special setting for this?

     
  • Winch

    Winch - 2022-05-13

    Hi Kent,
    Tried everything today to find a solution with the Timer4 but failed!
    So in the end I modified the PCB to the suggestion you made earlier. But here too I continue to experience problems with the Timer0 module. For example, now I have given HPWM 5 a fixed value. (see software) When this PWM value is entered, the Timer0 module will give a completely different output. Presumably this has to do with another prescaler value but I can't find it. I also read the following in the datasheet which makes me think differently?

    (Timer/Counter0, 1, and 3 share the same prescaler module, but the Timer/Counters can have different prescaler settings.)

    The entered value of my "If Timer_1 =" counter gives exactly a 1 second pulse! But at the moment of activating the HPWM 5 module I lost this.

    I feel like I no longer have anything to hold on to and I don't really know what or where to look at? I would like some input please.
    Thanks.

    ; ----- Configuration
        #chip mega32u4,16
        #option explicit
    
    ;----- Determine where the Switch is connected to the microcontroller
      #define HkeyC PortD.4   'High key Cold
      #define LkeyC PortD.5   'Low key Cold
      #define HkeyW PortD.7   'High key Warm
      #define LkeyW PortD.6   'Low key Warm
    
    ;----- Determine where the RGB LED is connected to the microcontroller
      #define LED_Blue PortE.2    'Blue led connection
      #define LED_Red PortE.6   'Red led connection
    
    ;----- Determine where the Buzzer is connected to the microcontroller
      #define Soundout PortD.0
    
      #define Motion PortB.4    'When the PIR sensor is detected, input is pulled low
    
    ;----- Determine where the Switch is connected to the microcontroller
      #define Control PortD.1
      #define PS_ShutDown PortB.0
    
    ; ----- Define software settings PWM output
      #define AVRTC1    'Specifies AVR TC1 associated with channel 3, 4 and 5 
      #define AVRCHAN3  'Specifies AVR HPWM channel 3 to the associated output pin OC1A (Warm output)
      #define AVRCHAN4  'Specifies AVR HPWM channel 4 to the associated output pin OC1B (Cold output)
      #define AVRCHAN5  'Specifies AVR HPWM channel 5 to the associated output pin OC1C (Axial Fan)
    
    ; ----- Define Hardware settings PWM output
      dir PortB.5 out   'PWM output for the Warm light OC1A (port OC1A)
      dir PortB.6 out   'PWM output for the Cold light OC1B (port OC1B)
      dir PortB.7 out   'Set the PWM channel for the Axial Fan (port OC1C)
    
    ; ----- Define Hardware settings RGB LED
      dir PortE.2 out   'Blue Led
      dir PortE.6 out   'Red Led
    
    ; ----- Define Hardware settings Efapel Switch
      dir PortD.4 in    'High key Cold
      dir PortD.5 in    'Low key Cold
      dir PortD.6 in    'Low key Warm
      dir PortD.7 in    'High key Warm
    
    ; ----- Define Hardware settings Switch
      dir PortD.1 in     'Control switch
      dir PortB.0 out     'ShutDown system
    
    ; ----- Define Hardware settings Buzzer
      dir PortD.0 out
    
    ;----- Define Hardware settings for the PIR, CO2 sensor
      dir PortB.4 in    'Input motion PIR sensor
    
    ;----- Variables
      Dim Timer_1, as word
    
      Led_blue = 1
      Led_Red = 1
      PS_ShutDown = 1
      Timer_1 = 0
    
    ;----- The sound when starting up the Apollo
      Start_up 
      Timer 
    
    ; ----- Main body of program commences here.
    Main:
    
      HPWM 5, 100, 80
    
      If Timer_1 = 976 then
        Led_Red = 0
      End if
    
      If Timer_1 = 1952 then
        Led_red = 1
        Timer_1 = 0
      End if
    
      goto main
    end
    
    sub Start_up
      Tone 440, 100             
    End sub     
    
    Sub Counter_1
        Timer_1 = Timer_1 + 1
    End sub
    
    Sub Timer
      Inittimer0 osc, PS_64
      Starttimer 0
      On Interrupt Timer0Overflow Call Counter_1
    End sub
    
     
  • kent_twt4

    kent_twt4 - 2022-05-13

    Oh, Dear, did not know a PCB was involved from my suggestions!

    Looks like we are on differents sides of the pond so to speak, thus the slow response.

    I see you are using the mega32U4, missed that on the first look. HPWM was not developed for that chip, did not have one for testing at the time. I based my suggestions on the mega328 on an UNO board, not the same at all.

    I can help by simulating on the UNO board based on the type of timers involved if need be,

    First few suggestions would be to test HPWM, then Timer3 interrupt separately before combining:

    A) Test HPWM5 over full range in a loop, as seen in help. Get that working first. May have to manually set up registers if the library does not work.

    Basically for the HPWM 5,freq,PWMfan:

    Dim PWMfan,freq as byte
    Main:
    freq = 63
    
    Do
    
      For PWMfan = 0 to 255
        HPWM 5,freq,PWMfan
        wait 5 ms
      Next
    
      For PWMfan = 255 to 0 step -1
        HPWM 5,freq,PWMfan
        wait 5 ms
      Next
    
    Loop
    
    1. On interrupt should be in the setup prior to main, not in the sub.
    2. Try using Timer3/TC3 with your values for Timer1, Should work as it is the same 16 bit timer. Using a timer in counter and pwm mode at the same time is incompatible.

    P.S. if you actually are going to use an RGB led then constants for HPWM are going to be messed up. I have always gone the route of testing setup before PCB.

    EDIT 1: deleted comment on start_up and Timer, as they do indeed initialize correctly!

     

    Last edit: kent_twt4 2022-05-13
  • Winch

    Winch - 2022-05-13

    Hi Kent,
    In the meantime, after a lot of experimenting, I have found that this program below works.
    But as crazy as it sounds I'm glad to hear that GC doesn't support this chip because I really thought I was going crazy.
    Of course I hope that this chip will be included in the library!

    And indeed as you can see using timer3 it seems to work so far. The 1 sec time that I have now programmed is correct (measured with the oscilloscope) and the three HPWM outputs remain stable! (HPWM 3, 4 and 5) So that gives confidence.

    But if I can help by adding this chip to the library, I'd be happy to contribute!

    ; ----- Configuration
        #chip mega32u4,16
        #option explicit
    
    ;----- Determine where the Switch is connected to the microcontroller
      #define HkeyC PortD.4   'High key Cold
      #define LkeyC PortD.5   'Low key Cold
      #define HkeyW PortD.7   'High key Warm
      #define LkeyW PortD.6   'Low key Warm
    
    ;----- Determine where the RGB LED is connected to the microcontroller
      #define LED_Blue PortE.2    'Blue led connection
      #define LED_Red PortE.6   'Red led connection
    
    ;----- Determine where the Buzzer is connected to the microcontroller
      #define Soundout PortD.0
    
      #define Motion PortB.4    'When the PIR sensor is detected, input is pulled low
    
    ;----- Determine where the Switch is connected to the microcontroller
      #define Control PortD.1
      #define PS_ShutDown PortB.0
    
    ; ----- Define software settings PWM output
      #define AVRTC1    'Specifies AVR TC1 associated with channel 3, 4 and 5 
      #define AVRCHAN3  'Specifies AVR HPWM channel 3 to the associated output pin OC1A (Warm output)
      #define AVRCHAN4  'Specifies AVR HPWM channel 4 to the associated output pin OC1B (Cold output)
      #define AVRCHAN5  'Specifies AVR HPWM channel 5 to the associated output pin OC1C (Axial Fan)
    
    ; ----- Define Hardware settings PWM output
      dir PortB.5 out   'PWM output for the Warm light OC1A (port OC1A)
      dir PortB.6 out   'PWM output for the Cold light OC1B (port OC1B)
      dir PortB.7 out   'Set the PWM channel for the Axial Fan (port OC1C)
    
    ; ----- Define Hardware settings RGB LED
      dir PortE.2 out   'Blue Led
      dir PortE.6 out   'Red Led
    
    ; ----- Define Hardware settings Efapel Switch
      dir PortD.4 in    'High key Cold
      dir PortD.5 in    'Low key Cold
      dir PortD.6 in    'Low key Warm
      dir PortD.7 in    'High key Warm
    
    ; ----- Define Hardware settings Switch
      dir PortD.1 in     'Control switch
      dir PortB.0 out     'ShutDown system
    
    ; ----- Define Hardware settings Buzzer
      dir PortD.0 out
    
    ;----- Define Hardware settings for the PIR, CO2 sensor
      dir PortB.4 in    'Input motion PIR sensor
    
    ;----- Variables
      Dim Bright_C, Bright_W, as Byte
      Dim Timer_1, as word
    
      Led_blue = 1
      Led_Red = 1
      PS_ShutDown = 1
      Timer_1 = 0
      Bright_W = 0
      Bright_C = 64
    
    ;----- The sound when starting up the Apollo
      Start_up 
      Timer 
    
    ; ----- Main body of program commences here.
    Main:
    
      HPWM 3, 100, Bright_W
      HPWM 4, 100, Bright_C
      HPWM 5, 100, 128
    
      If Timer_1 = 244 then
        Led_Red = 0
      End if
    
      If Timer_1 = 488 then
        Led_red = 1
        Timer_1 = 0
      End if
    
      goto main
    end
    
    sub Start_up
      Tone 440, 100             
    End sub     
    
    Sub Counter_1
        Timer_1 = Timer_1 + 1
    End sub
    
    Sub Timer
      Inittimer3 osc, PS_1
      Starttimer 3
      On Interrupt Timer3Overflow Call Counter_1
    End sub
    
     
  • kent_twt4

    kent_twt4 - 2022-05-13

    Well, glad you got it working, that is certainly the most important part.

    I didn't say that the 32u4 was unsupported, just did not have one to test. I would say that Timer4, the 10 bit timer, may not be supported because I don't recollect dealing with a 10 bit timer, just not sure off the top of my head. You could try TC4 chan11, 12 and see if that works, there is no chan13 with the 10 bit timer.

    But, TC0 chan2, TC1 chan3, 4, 5, and TC3 chan8,9,10 should work. Feel free to check them out with the test program from above with led/DVM/scope if you are inclined.

    Thanks.
    Kent

     
  • kent_twt4

    kent_twt4 - 2022-05-13

    In theory, you could still use TC0/TC4 for the interrupt by using a counter flag on rollovers (if need be) and adjusting the register count for your 1 sec. Then, for sure you would at least have 6 or 7 PWM's available as is.

     

    Last edit: kent_twt4 2022-05-13
  • Winch

    Winch - 2022-05-13

    I thought so too at first, but this doesn't work well with the HPWM output. I think there is something wrong with the prescaler settings? But maybe you have an example for me so I can test it? I am still very unsure about my own quality of programming.

     
  • kent_twt4

    kent_twt4 - 2022-05-13

    I don't have the answer right now, perhaps later my time. Should be quick fix for TC0 at least. You are doing good. You can check out the examples, and see if there is something there that is relevant.

     
  • Winch

    Winch - 2022-05-13

    I'll continue with it tomorrow.

     
  • kent_twt4

    kent_twt4 - 2022-05-14

    I see the frustration here on making the HPWM and the timeroverflow interrupt to work nicely together. Seems to be a delicate dance between the length of the Osc, timeroverflows and the HPWM freq.

    I finally got the timer0Overflow to sort of work. It required reducing the HPWM freq to 2(khz), checking the CKDIV8 fuse, using PS_256, and making the #chip mega328, 2 for my UNO board. My counter value in the overflow sub was 10500. Change the freq and everything goes to heck.

    Will try TC4. Another idea that might work is to make a scheduler/state machine, but hey :-)?

     
  • Winch

    Winch - 2022-05-14

    Good morning Kent,
    I'm just trying to understand what you're writing? It might take me a little longer to figure out what you're talking about. But I don't understand the frequency adjustment of the HPWM?
    Do you mean I have to change it in the fuse settings?

     
  • Winch

    Winch - 2022-05-14

    Remember I'm not a thoroughbred programmer, I want to be but I'm still in a lurning curve! ;-)
    And what do you mean by "scheduler/state machine"???

     
  • kent_twt4

    kent_twt4 - 2022-05-14

    Oh, you wouldn't call me a "programmer", I have to slog through it.

    Skip the state machine for now. I it is basically setting up a timer for say 100ms interrupts and a small counter of such 100ms interrupts, then say at 100ms (1) check PIR sensor, 200 ms (2) check button and so forth till you reset the number and start again. I hope that explains it.

    Here is a stripped down version for the UNO board. Port number(s) change of course.

    ; ----- Configuration
        #chip mega328,2
        #option explicit
    
    ; ----- Define software settings PWM output
      #define AVRTC1    'Specifies AVR TC1 associated with channel 3, 4 and 5
      #define AVRCHAN3 
    ; ----- Define Hardware settings PWM output
      dir PortB.1 out   'PWM output for the Warm light OC1A (port OC1A)
        ; ----- Main body of program commences here.
    #define RedLED PortD.2
    dir PortD.2 Out
    Set RedLED Off
    
    Dim freq as byte
    Dim Counter as Word
    InitTimer0 OSC, PS_256
    StartTimer 0  'not req'd for Timer0
    Counter = 0
    
    On Interrupt Timer0Overflow Call BlinkLED
    
    Main:
      freq = 2
      HPWM 3,freq,64
      wait 500 ms
    goto Main
    
    Sub BlinkLED
    
      Counter ++
      If Counter = 5000 Then
        RedLED = Not RedLED
        Counter = 0
       End If
    
    End Sub
    

    Oops, counter was 5000.

     
  • Winch

    Winch - 2022-05-14

    Ok now I see you mean the Fuse CKDIV8! (I always use microchip studio to change the fuses)
    But indeed that is not the case. So this is not divided 8 times by the clock.

    I see that you can adjust this in the software by just using freq = 2?
    So no need to change this in the fuse setting?

     
  • Winch

    Winch - 2022-05-14

    I'm going to test the above!

     
  • kent_twt4

    kent_twt4 - 2022-05-14

    No, you still need to set the programming fuse, and the osc as 2. GCB has to use 2Mhz (i.e. 16/8=2) in define for wait, PWM and other things. I'm going to try and get some sleep!

     
  • Winch

    Winch - 2022-05-14

    Then I don't understand why Freq = 2 is set like that?
    Isn't that the freq of the pwm, that is much too low? Normally it is set to 64.

    Good night from here!

     
  • kent_twt4

    kent_twt4 - 2022-05-14

    Still not asleep. I wouldn't think that 2khz PWM is too low at all, unless you get a buzzing noise from the motor, or need a very granular duty cycle? That's seems to be the problem tho, try 2 khz then try 64khz and see what I mean.

    EDIT: If you intend to use the USB, then I am not sure what the knock on effect of the 64Mhz, PLL clock would be. I forgot about that. definitely going to bed now.

     

    Last edit: kent_twt4 2022-05-14
  • Winch

    Winch - 2022-05-14

    I have my best result at 64Khz, If I set this to 2 then my clock is wrong again.
    At the setting of 64 my blinking LED runs exactly at 1Hz measured with the scope.
    So is this problem the difference between a mega328 and the mega32u4?

    Below is my current program!

    ;----- Variables
      Dim Motion_On, Bright_C, Bright_W, Freq, as Byte
      Dim Counter, as Word
    
      Led_blue = 1
      Led_Red = 1
      PS_ShutDown = 1
      Freq = 64
    
    ;----- Sound when starting up
        Start_up    ;Play a tone on product startup 
    
    ;----- Define settings for the Timer3 clock
      Inittimer0 osc, PS_256
      Starttimer 0
      Counter = 0
      On Interrupt Timer0Overflow Call Timer_1
    
    ;----- Main body of program commences here.
    Main:
    
      Bright_W = 255
      HPWM 3, Freq, Bright_W
      ;Wait 500 ms
    
    goto main
    end
    
    ;Sub Timer
    ;End sub
    
    Sub Timer_1
        Counter ++
        If Counter = 10500 then
            LED_Red = not LED_Red
            Counter = 0
        End if
    End sub
    
    sub Start_up
        Tone 440, 100               
    End sub    
    
     
1 2 3 > >> (Page 1 of 3)

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.