Sampling using ADC
An Analog to digital converter is a device that converts a continuous physical quantity (usually voltage) to a digital number that represents the quantity’s amplitude.
In this demo, we are sampling voltage across a potentiometer to establish its position. A potentiometer is a three-pin knob that provides a variable resistance between W-A and W-B pins (Fig.1). Amount of resistance between A and B is constant, but by turning the shaft of the potentiometer, we change the amount of resistance on either side of W.
Connecting A to 3 V, B to GND (or vice versa) and sampling voltage between W and GND we could measure wiper position: according to voltage divider, sampled voltage would be proportional to amount of resistance between W and pin connected to GND.
ADC in ChibiOS
STM32 has more than an ADC. As always, we had to enable ADC subsystem in halconf.h and proper driver in mcuconf.h.
Every ADC has more than a channel. We could sample from these channels choosing a custom sequence. In order to do that we had to configure some ADC register though ADCConversionGroup. Moreover, we could configure sampling frequency and mode. Our conversion group is:
We are sampling in a not circular way, from a single channel (ADC_CHANNEL_IN0). Sampling frequency is equal to three main clock cycle (ADC_SAMPLE_3), (For more information look for ADC registers on Reference Manual).
We have disabled the two callback of ADC. The first one occurs during sampling two times (in the middle and in the end of the conversion group); the second one occurs on ADC error.
In main we had to configure our pin. In ADC thread we start it, sampling a buffer of n items and making mean on data in order to remove noise.
Note that we can use the ADC in continuous mode using another API:adcStartConversion(). Always remember that we had to dimension samples buffer properly to avoid an overflow:
Dimming using PWM
The Pulse width Modulation is a technique used to encode a message into a pulsing signal and is hence a type of modulation. Although this modulation technique can be used to encode information for transmission, its main use is to control power supplies and electrical devices, especially used to drive inertial loads such as motors.
PWM in ChibiOS
Oversimplifying, PWM is a square wave characterized by a fixed period and a variable duty cycle. Best way to realize that is using a timer. Fixing timer frequency, (hence period), we could define PWM period and duty cycle as multiple of timer quantum. Note that timer frequency must be several orders of magnitude larger than PWM frequency in order to have a good duty cycle resolution.
At this point, should be clear that the field frequency of PWMConfig is referred to related timer and that there is a timer for every PWM. Since every timer as more than a channel we could generate more PWM with same period but different duty cycle.
PWM driver has callbacks: one is common to each channel and occurs every period, others are channel-depending and occur when PWM output switches, hence depends on duty cycle. This is the PWMConfig used fading green LED intensity:
Note that timer frequency is 1MHz and that initial PWM period is 1000 timer quantum i.e. 1ms. pwmpcb is the period callback and pwmc1cb is the channel 1 callback; moreover, first channel is active and output is high during a time frame proportional to duty cycle, other channels instead are disabled.
As every driver, PWM must be started before using it. PWM APIs allows starting channels choosing duty cycle, as well as change PWM period, disabled channel and stop driver. In order to fade LED we just start the driver before thread loop and continuously enable channel changing duty cycle (In our case we choose duty cycle proportional to last sampled value).
Green led is not directly connected to our timer output and we use callbacks to make a software PWM. When duty cycle is 0% or 100% one between pwmpcb and pwmc1cb callbacks could not occur: that explains checks on duty cycle edges.
Remember before using PWM to enable subsystem in halconf.h and assign timer in mcuconf.h.
The colour wheel
Driving a RGB LED we use three channel of the same PWM. Colour wheel avoid that more than two junction are tuned on together: this because turning on the third junction colour shift toward white losing saturation.
The circuit we made to drive the RGB led is this:
Project used in this tutorial
This code has been tested using ChibiOS/RT 3.0.x.