I figured it must be doable from the Sparkulator, so I set off tonight to try and make it possible to change the PWM frequency to whatever you want. Default in the Spark Core is 500Hz and I tested this up to 64000Hz on all 8 PWM outputs. It works flawlessly and I’m sure it can go higher. You’ll notice in the comments I also have fixed the PWM glitch by keying off of the fact that if the pin_mode is set to AF_OUTPUT_PUSHPULL it is already setup as a PWM. If this mode is only used for PWM, we’re good… if not, some other state variable will have to be used. When the PWM is already set up, we just update the duty cycle on successive calls to analowWrite2(). PWM also achieves true 100% because there is no glitch now.
Because it’s so easy to change the frequency, maybe we can gain access to this in an easier way? Spark.pwmFreq(1000);
+1 for Spark.pwmFreq(1000); // or something like it - at least up to 96kHz for possible SoftAudio - once the lag caused by the cloud processes does not interfere with the user process anymore.
One possible problem with changing the timer frequency might arise, if that very same timer is used for any other standard function (i. e. delay() or so).
As I recall this was to consider when messing with the timers on Arduino.
But I have not got down that far into all of the Core FW source, so it might be easier if our highly honoured Sparkies ( @zach, @zachary, …) could answer this from the top of their heads.
Based on what I saw in the code, yes there are 4 different timers that are all set up the same way. You COULD set them up differently. Are we starting to see the power of the Spark Core vs. Arduino? I hope so!
The ARM on the Spark core does not have any DACs, just two ADCs. You need to go to the “high-density” STM32F103’s the get 2 DACs. The three parts in the datasheet with DACs are 256k to 512k Flash and 48k to 64k RAM, but also come in a physically larger package.
That would work, assuming we don’t re-initialize the PWM every time we call that function. It just needs to be a little bit smart about the fact that it already set it up, and if it has… then if it needs to change the LEVEL (duty cycle) it just updates the corresponding register, but if it needs to change the FREQUENCY then I’m pretty sure it will have to re-init.
And you can easily initialize the FREQUENCY value to 500 in case someone doesn’t specify all 3 arguments.
I’ll work on this when I can get some time, unless Satish beats me to it. That guy is a machine!
@kennethlimcp, the image only shows half the cycle. As @bko pointed out, the period is off for a 1KHz output and looks more like a 1MHz output. Can you show the settings you used for the timer and channel?
As for the noise, I am not surprised especially if it’s sitting on a breadboard and you have a jumper connected to the board and then your probe. Also, if your probe is not tuned, it affects the “edges”.
As @peekay123 says, step one on any oscilloscope is to calibrate your probes to the channels you’ll be using them on. Hook the scope probe tip and ground to the reference waveform output (usually some test hook/clips that stick out of the scope down near the BNC connectors). Adjust the vertical and horizontal controls to view one complete rising and falling edge or a whole cycle if you wish. Using a non-metallic screwdriver, adjust the probe set screw until the waveform has no over or undershoot on the rising/falling edges.
It will never be “square” really, since all wires have inductance, capacitance, resistance and all outputs have a finite amount of current that is sourced. These components along with the frequency of the output waveform affect the slope of the rising and falling edges. Typically if everything is fixed, the slope will decrease inverse-proportionally to the output frequency.
It also helps to have a high frequency (aka expensive) scope probe. Most probes that come with cheap scopes are rated for 25 - 50MHz. You need a >300MHz probe to really be able to even see some of the high frequency ringing and noise present in most analog and digital signals, otherwise it’s just attenuated by the probe and never shows up at the scope.
I don’t know about 10MHz, but I have tested the Core’s PWM up to 64kHz. I don’t remember how square it was though