poida
 Guru
 Joined: 02/02/2017 Location: AustraliaPosts: 1432 |
Posted: 11:04pm 24 Jan 2021 |
|
|
|
Angelo:
it's good to see you having a play with this code. I was wrong with my guess you were a student! sorry. (I also do linux IT system admin.)
PPWM is the time, in clocks for a 20KHz PWM, and so it is put into ICR1. 200 of these 20KHz pulses is 1/100 second, so we can make one half of the 50 Hz sine wave using the 200 PWM duty width values. The Nano (and a lot of other microcontrollers) use tiny crystals for the clock, and they can be quite stable but not so accurate.
The nano I tested your code on gives 49.900 Hz with PPWM = 800 Using 798 it is now 50.027 Hz
Feel free to change this to obtain a closer output to 50Hz. Note that this was done without any signal on D2, potentially altering the output via the phase lock loop
OCR1A = PPWM / 2 + c;
In your version of the firmware, we need to use one pin only for PWM output. Sine wave is bipolar. It ranges between positive and negative values. I can't output a negative voltage via a pin. So I offset the sine wave 1/2 it's amplitude to permit it to vary between 0 and 5V so it needs to be offset by 2.5V PWM duty width ranges from 0 to PPWM (in clocks) To make 2.5V use a duty width of 800/2 or 400 clocks. So I always output a duty width of 400 plus or minus the sine wave modulation which will vary +/- 400 clocks or a little smaller for safely avoiding under or over flow.
why do you use 200 + 1 values?
Just in case I make a mistake in code and go "out by one" in my counting or addressing. This does not happen with the code now since it's so mature and so we can remove this to save 2 bytes of RAM. Always use NPWM = 200
The phase lock code is an unprofessional solution to synchronising a signal with an input. But it works. The end result of the code is to add or subtract one extra PWM output for the nominal 50 Hz output frequency, to make the output track the input pulse on D2. This is the smallest change I can make to the output but it contributes to a lot of phase noise.
I do fractional math to carry 10 bits of precision in the PLL error term. The performance of this PLL is not bad, it always locks when given an input within about 50Hz +/- 1Hz. It can maintain lock +/- 2 Hz when I test it. |