Hello
As part of a project I am trying to use a proportional solenoid requiring around 20KHz PWM.
Given the Arduino Mega PWM frequency is around 500Hz I though bit manipulation will be the way to go:
Here is the code i wrote :
void setup()
{
/// we will try to use timer4
TCCR4A = 1 << COM4A1 | 0 << COM4A0 | 1 << WGM41 | 0 << WGM40; // SET COM4A1 TO 1 COM4A0 TO 0 :Clear OCnA on compare match, set OCnA at BOTTOM (non-inverting mode)
// WGM41 is set to 1 so we will work with TOP of ICR4 mode 14
TCCR4B = 1 << WGM43 | 1 << WGM42; //settin those for fast PWM mode 14 - reqires 1 1 1 0
// 20 kHz at 16Mhz
ICR4 = 799; // Sets TOP value for Timer4 - 16milion ticks in a sec * with period of 50 microsec =800 ticks
// 50% duty cycle
OCR4A = 400; // Sets duty cycle for Channel A (OC4A pin)
TCNT4 = 0; // Initialize the counter
// Start Timer4 at 16MHz (no prescaling)
TCCR4B = 1 << WGM43 | 1 << WGM42 | 0 << CS42 | 0 << CS41 | 1 << CS40;
pinMode(6, OUTPUT);
}
void loop()
{
}
I have no prior experience doing something like this so feel free to explain if I did anything wrong.
The way i see it is we set TCCR4A register to clear OC4A on compare match so we are HIGH until OCR4A values is ticked then we are LOW and continue to count till ICR4 values is reached.
Then the counter is initialized using TCNT4 =0 and then we start the count when we initialize the clock by setting 0 << CS42 | 0 << CS41 | 1 << CS40.
At the end I set the relevant pin to output so I will be able to get an output in the relevant pin.
Have i done anything wrong? I currently have no scope to validate this.
I did not find which functions uses timer4 so i used him - is there a problem by doing so?
Mega pin mapping :
as per a email exange I had with someone from the manufacturer : "generating a PWM signal with a current control. If you use a PWM, please set the frequency ideally around 20 kHz but at minimum 3kHz."
i agree, in my understating only when i set 0 << CS42 | 0 << CS41 | 1 << CS40; the actual counting starts, that is why i did not incorporate that section in the first instance of TCCR4B.
i believe though that i can only use something like:
oh ok, so i can only write it once at the end
like this?
TCCR4A = 1 << COM4A1 | 0 << COM4A0 | 1 << WGM41 | 0 << WGM40; // SET COM4A1 TO 1 COM4A0 TO 0 :Clear OCnA on compare match, set OCnA at BOTTOM (non-inverting mode)
// WGM41 is set to 1 so we will work with TOP of ICR4 mode 14
// 20 kHz at 16Mhz
ICR4 = 799; // Sets TOP value for Timer4 - 16milion ticks in a sec * with period of 50 microsec =800 ticks
// 50% duty cycle
OCR4A = 799; // Sets duty cycle for Channel A (OC4A pin)
TCNT4 = 0; // Initialize the counter
// Start Timer4 at 16MHz (no prescaling)
TCCR4B = 1 << WGM43 | 1 << WGM42 | 0 << CS42 | 0 << CS41 | 1 << CS40;
pinMode(6, OUTPUT);