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;-----DeterminewheretheSwitchisconnectedtothemicrocontroller#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;-----DeterminewheretheRGBLEDisconnectedtothemicrocontroller#define LED_Blue PortE.2 'Blue led connection#define LED_Red PortE.6 'Red led connection;-----DeterminewheretheBuzzerisconnectedtothemicrocontroller#define Soundout PortB.7#define Motion PortB.4 'When the PIR sensor is detected, input is pulled low;-----DeterminewheretheSwitchisconnectedtothemicrocontroller#define Control PortD.1#define PS_ShutDown PortB.0;-----DeterminehowthePWMisconnected#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);-----DefineHardwaresettingsPWMoutputdirPortB.5out'PWM output for the Warm light (port OC1A)dirPortB.6out'PWM output for the Cold light (port OC1B)dirPortD.0out'Set the PWM channel for the Axial Fan (port OC0B);-----DefineHardwaresettingsRGBLEDdirPortE.2out'Blue LeddirPortE.6out'Red Led;-----DefineHardwaresettingsEfapelSwitchdirPortD.4in'High key ColddirPortD.5in'Low key ColddirPortD.6in'Low key WarmdirPortD.7in'High key Warm;-----DefineHardwaresettingsSwitchdirPortD.1in'Control switchdirPortB.0out'ShutDown system;-----DefineHardwaresettingsBuzzerdirPortB.7out;-----DefineHardwaresettingsforthePIR,CO2sensordirPortB.4in'Input motion PIR sensor;-----VariablesDimMotion_On,Bright_C,Bright_W,Freq,asByteDimTimer_1,asWordLed_blue=1Led_Red=1PS_ShutDown=1Freq=100;-----SoundwhenstartingupStart_upTimer;-----Mainbodyofprogramcommenceshere.Main:IfMotion=0thenTimer_1=0Led_Red=1;whenhightheLEDisoffEndIfIfTimer_1=100thenScene_C10W30Led_Red=0;whenlowtheLEDisonendifgotomainendsubScene_C10W30Bright_C=10Bright_W=78HPWM4,Freq,Bright_CHPWM3,Freq,Bright_WendsubSubTimerOnInterruptTimer1OverflowCallCounter_1Inittimer1osc,PS_1_64Starttimer1Settimer1,63036;preloadtimerEndsubSubCounter_1Settimer1,63036Timer_1=Timer_1+1EndsubsubStart_upTone440,100Endsub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
#chipmega32u4,16
#optionexplicit;----- Determine where the Switch is connected to the microcontroller
#defineHkeyCPortD.4'High key Cold
#defineLkeyCPortD.5'Low key Cold
#defineHkeyWPortD.7'High key Warm
#defineLkeyWPortD.6'Low key Warm;----- Determine where the RGB LED is connected to the microcontroller
#defineLED_BluePortE.2'Blue led connection
#defineLED_RedPortE.6'Red led connection;----- Determine where the Buzzer is connected to the microcontroller
#defineSoundoutPortD.0
#defineMotionPortB.4'When the PIR sensor is detected, input is pulled low;----- Determine where the Switch is connected to the microcontroller
#defineControlPortD.1
#definePS_ShutDownPortB.0; ----- Define software settings PWM output
#defineAVRTC1'Specifies AVR TC1 associated with channel 3, 4 and 5
#defineAVRCHAN3'Specifies AVR HPWM channel 3 to the associated output pin OC1A (Warm output)
#defineAVRCHAN4'Specifies AVR HPWM channel 4 to the associated output pin OC1B (Cold output)
#defineAVRCHAN5'Specifies AVR HPWM channel 5 to the associated output pin OC1C (Axial Fan); ----- Define Hardware settings PWM outputdirPortB.5out'PWM output for the Warm light OC1A (port OC1A)dirPortB.6out'PWM output for the Cold light OC1B (port OC1B)dirPortB.7out'Set the PWM channel for the Axial Fan (port OC1C); ----- Define Hardware settings RGB LEDdirPortE.2out'Blue LeddirPortE.6out'Red Led; ----- Define Hardware settings Efapel SwitchdirPortD.4in'High key ColddirPortD.5in'Low key ColddirPortD.6in'Low key WarmdirPortD.7in'High key Warm; ----- Define Hardware settings SwitchdirPortD.1in'Control switchdirPortB.0out'ShutDown system; ----- Define Hardware settings BuzzerdirPortD.0out;----- Define Hardware settings for the PIR, CO2 sensordirPortB.4in'Input motion PIR sensor;----- VariablesDimTimer_1, aswordLed_blue=1Led_Red=1PS_ShutDown=1Timer_1=0;----- The sound when starting up the ApolloStart_upTimer; ----- Main body of program commences here.Main:
HPWM5, 100, 80IfTimer_1=976thenLed_Red=0EndifIfTimer_1=1952thenLed_red=1Timer_1=0EndifgotomainendsubStart_upTone440, 100EndsubSubCounter_1Timer_1=Timer_1+1EndsubSubTimerInittimer0osc, PS_64Starttimer0OnInterruptTimer0OverflowCallCounter_1Endsub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
On interrupt should be in the setup prior to main, not in the sub.
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
#chipmega32u4,16
#optionexplicit;----- Determine where the Switch is connected to the microcontroller
#defineHkeyCPortD.4'High key Cold
#defineLkeyCPortD.5'Low key Cold
#defineHkeyWPortD.7'High key Warm
#defineLkeyWPortD.6'Low key Warm;----- Determine where the RGB LED is connected to the microcontroller
#defineLED_BluePortE.2'Blue led connection
#defineLED_RedPortE.6'Red led connection;----- Determine where the Buzzer is connected to the microcontroller
#defineSoundoutPortD.0
#defineMotionPortB.4'When the PIR sensor is detected, input is pulled low;----- Determine where the Switch is connected to the microcontroller
#defineControlPortD.1
#definePS_ShutDownPortB.0; ----- Define software settings PWM output
#defineAVRTC1'Specifies AVR TC1 associated with channel 3, 4 and 5
#defineAVRCHAN3'Specifies AVR HPWM channel 3 to the associated output pin OC1A (Warm output)
#defineAVRCHAN4'Specifies AVR HPWM channel 4 to the associated output pin OC1B (Cold output)
#defineAVRCHAN5'Specifies AVR HPWM channel 5 to the associated output pin OC1C (Axial Fan); ----- Define Hardware settings PWM outputdirPortB.5out'PWM output for the Warm light OC1A (port OC1A)dirPortB.6out'PWM output for the Cold light OC1B (port OC1B)dirPortB.7out'Set the PWM channel for the Axial Fan (port OC1C); ----- Define Hardware settings RGB LEDdirPortE.2out'Blue LeddirPortE.6out'Red Led; ----- Define Hardware settings Efapel SwitchdirPortD.4in'High key ColddirPortD.5in'Low key ColddirPortD.6in'Low key WarmdirPortD.7in'High key Warm; ----- Define Hardware settings SwitchdirPortD.1in'Control switchdirPortB.0out'ShutDown system; ----- Define Hardware settings BuzzerdirPortD.0out;----- Define Hardware settings for the PIR, CO2 sensordirPortB.4in'Input motion PIR sensor;----- VariablesDimBright_C, Bright_W, asByteDimTimer_1, aswordLed_blue=1Led_Red=1PS_ShutDown=1Timer_1=0Bright_W=0Bright_C=64;----- The sound when starting up the ApolloStart_upTimer; ----- Main body of program commences here.Main:
HPWM3, 100, Bright_WHPWM4, 100, Bright_CHPWM5, 100, 128IfTimer_1=244thenLed_Red=0EndifIfTimer_1=488thenLed_red=1Timer_1=0EndifgotomainendsubStart_upTone440, 100EndsubSubCounter_1Timer_1=Timer_1+1EndsubSubTimerInittimer3osc, PS_1Starttimer3OnInterruptTimer3OverflowCallCounter_1Endsub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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 :-)?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
#chipmega328,2
#optionexplicit; ----- Define software settings PWM output
#defineAVRTC1'Specifies AVR TC1 associated with channel 3, 4 and 5
#defineAVRCHAN3; ----- Define Hardware settings PWM outputdirPortB.1out'PWM output for the Warm light OC1A (port OC1A); ----- Main body of program commences here.
#defineRedLEDPortD.2dirPortD.2OutSetRedLEDOffDimfreqasbyteDimCounterasWordInitTimer0OSC, PS_256StartTimer0'not req'dforTimer0Counter=0OnInterruptTimer0OverflowCallBlinkLEDMain:
freq=2HPWM3,freq,64wait500msgotoMainSubBlinkLEDCounter++IfCounter=5000ThenRedLED=NotRedLEDCounter=0EndIfEndSub
Oops, counter was 5000.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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?
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?
You need @kent_twt4
:-)
What do you mean?
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.
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?
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?
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?
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.
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:
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
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!
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
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
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.
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.
I'll continue with it tomorrow.
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 :-)?
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?
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"???
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.
Oops, counter was 5000.
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?
I'm going to test the above!
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!
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!
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
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!