Tuesday, March 22, 2016

Building a simple circuit probe


The Goals

Sometimes you need to check one circuit and test some of its nodes. Usually a tester in voltage mode is a good solution, but it has a pair of problems. First, it measures about zero both when the node is driven at zero volts and when the node is floating (not driven at all). Second, it gives the information on the tester display, so you need to take the view from the circuit to the tester to check the voltage.

The proposed circuit somewhat qualifies as a logic probe. It should give no indication when the node is not being driven and it should give a different indication when the node is driven at high or a low voltage.

A lot of logic probes are not self powered. They rely on the circuit supply to operate. In my case I would like the probe to be usable also a as a continuity tester. If we set ground in one point of the circuit and we probe another point, the continuity can be detected between both points because a low level will be driven even if the circuit is not powered at all.

The Circuit

The following figure shows the schematic of the circuit.

Probe Schematic

The circuit is powered with a 3V CR2032 battery. When the probe is not connected to anything, the probe voltage, as set with R1 and R2 will be 1.5V. As both Operational Amplifiers (MCP6002) have very low bias current (1pA), no voltage drops on R3 and 1.5V is also seen on the non inverting input of U2 and on the inverting input of U1.

Resistors R4, R5 and R6 define a voltage divider that sets 1V on the inverting input of U2 and 2V on the non inverting input of U1. With 1.5V on the probe, both operationals saturate at high level (3V) so both LEDs are OFF.

If we set the probe tip to a voltage below 1V (The trip point of U2), U2 will saturate at low level and the Blue LED will turn ON. In a similar way, if the probe tip voltage is set above 2V (The trip point of U1), U1 will saturate at low level and the White LED will turn ON. I know white is a strange color for high level. A red color will be better buy I had no red LEDs similar to the blue one at hand.

Operational Amplifiers are not the best suited components for this project. As they are used as comparators, a dual comparator could be better in this case. The choice of the MCP6002 dual opamp was only because I had them available.


Circuit operation

In the end, the circuit puts a 1.5V voltage on the probe tip, provided by the two 100k resistors, so it behaves like a 1.5V source with a 50k series resistance. If the probe voltage is kept between 1V and 2V, no LED is lit. If the probe voltage is below 1V, the blue LED turns ON. And if the probe voltage is above 2V, the white LED will turn ON.

When you probe a node in the circuit, you can sense its voltage using a high impedance voltmeter. That will give you the open circuit voltage (Voc). This voltage can be driven with different strengths. The drive strength is related to the equivalent resistance at the node. For a linear non reactive circuit it will be the equivalent Thevenin resistance. In the end, the equivalent circuit will be something like that:

Simplified equivalent circuit



Here we have the 1.5V and 50k resistance provided by the probe and the Voc and Rth associated with the probed node. As we know, the LEDs will lit when the probe voltage Vp is above 2V or below 1V. The following graph shows the LED status as function of Voc and Rth.

LED status as function on Voc and Rth
For low Thevenin equivalent resistances (below 1k) only the Voc voltage determines if each LED is lit of not. For higher node resistances the threshold Voc voltage shifts due to the resistor interaction in the circuit.
We can see that at 100k Thevenin resistance we need 0V to lit the Blue led. For higher resistances we will need a negative voltage to lit the LED. Same for the white led: at 100k or more Thevenin resistance you need more than 3V to turn ON the LED. So, the circuit, not only senses the node voltage but also its drive strength.

From the curve we can see that, when used as continuity tester, it can detect continuity (or lack of isolation) for resistances up to 100k. To lower the resistance detection threshold, the  R1 and R2 resistors could be changed for lower values.


Effects of the probe on the circuit under test

Measuring any magnitude always modifies the device under test (DUT). Sometimes this error is negligible. For instance, using a good quality voltmeter to measure the voltage between two nodes usually introduces a 10 megaohm resistance between the measured nodes.

Measuring the drive strength always affects the DUT. In our case we are applying a 1.5V voltage with a drive strength of 50k. If the node has a Thevenin resistance similar or higher than 50k, we are actively modifying the node voltage and potentially inducing a modification in the behaviour of the DUT.



Give it some protection

As explained before, resistor R3 should not have any current in normal operation. IC inputs,  like the ones on the MCP6002 device, don't like to be driven above Vcc (3V in our case) or below GND. Trying to go outside of this limits will trigger the internal protections on the device. The R3 resistor guarantees that it will not cause a high input current.
The circuit has been used to probe a low impedance 20V node and it operated correclty, detecting a higher than 2V level, without any harm done to the probe. This would not be the case if R3 wasn't present.

Frequency limits

If the tip voltage changes with time alternating between voltages over 2V and below 1V, both LEDs will lit during some time. At low frequencies the blinking is apparent. At higher frequencies, over the Flicker fusion frequency, both LEDs seem to be lit at the same time. The circuit, however, due to some technical limits like the use of opamps instead of comparators has a maximum frequency of operation at about 50kHz. A square signal over this frequency doesn't lit any LED.

This is no problem as the main purpose of the probe was to test static nodes but it should be taken into account for dynamic nodes. It is usual for logic probes to have an special detection mode for pulsed signals with frequencies up to several MHz. This is not the case in this circuit.


Building the probe

The probe has been fabricated in a prototyping perfboard.

Built Probe
From left to right you have the probe tip, the three R1, R2 and R3 resistors, both LEDs and their R7 and R8 resistors, the MCP6002 dual opamp and the three R4, R5 and R6 resistors.
Ending the board we have the ground connection and the three pin power connector.
The LEDs are close to the tip so that we don't need to move the eyes from the circuit to check if they are lit.

The back side of the probe board is shown in the following figure. All the wiring has been done using thin, isolated, solid wire.

Probe, solder side

The three pin power connector uses the center pin for Vdd (+3V) and the other two pins for ground. A CR2032 socket is connected to a three pin female socket to provide the supply to the circuit.
As the connector is symmetric, it can be connected with the battery facing the top of the bottom of the board. As the supply is detachable from the probe, we don't need a power switch.

Power Supply
The ground connection is provided by an aligator clip connected to a short stranded wire.

Ground connection

The final probe with the supply and ground terminal is shown in the following figure.

Probe with battery and ground connection

In order to check for continuity or to check diferential voltages, a second ground probe has been built using a thin piece of coper board and some heat-shrink tubing. As you can see, touching both probe tips makes the system behave as a continuity tester.


Main probe and ground probe













Tuesday, November 10, 2015

Atollic returns to no code limit

In the year 2011 I was in the search for free programming solutions for the STM32 Discovery boards when I found the Atollic True Studio Lite. It was a very interesting product. Based on Eclipse, it provided all the necessary tools to develop on ARM MCUs. It had some functionality limitations in the free version but It was very good for learning and teaching MCU programming.

That ended at the start of 2012 when Atollic decided to set at 32KB code limit in True Studio Lite. When programming a STM32F4 Discovery board that features 1MB of flash, a code limit of 32KB is a joke. Moreover, it made impossible to integrate an RTOS and some middleware in the code. As I was using ChibiOS at this time, this limitation was very important to me. I complained to Atollic, but, in the end, I found that I was out of the user group that Atollic was targetting. So, I moved on, leaved Atollic alone, and developed my own Eclipse based environment and used it for learning and teaching. That was dificult because the debug was quite difficult to setup at that time and ChibiOS didn't had come with ChibiStudio yet.

Now, at the end of 2015, almost four years after Atollic introduced the code limit in True Studio Lite, Atollic has decided to remove it. That is good news because ST provides examples for True Studio for its evaluation boards so it eases a lot the developement. Perhaps it is time to check again what Atollic has to offer but now there are quite more free options to develop in ARM MCUs that there were at the start of 2012. And now I have my own toolchain.

But for anyone willing to program the cheap evaluation boards that ST and others like Freescale provide,  Atollic True Studio Lite is a free solution that should be taken into account now that the code limit is removed.

Friday, May 29, 2015

LED lights deadbug style

This will be a brief article about building some LED lights to illuminate small things. The objective is to create some lights that can be oriented as needed to iluminate small objets to work on.

Schematic of the circuit





The basic circuit is a constant current driver using a NPN transistor. The 6k8 resistor, the 1N4148 diode and the adjustable resistor set the base voltage at the transistor between about 0.6V and 1.2V. That sets the votage at Re between 0 and 0.6V. The current at the transistor collecto will be between 0 and 0.6V/Re.
For instance, selecting a 15Ohm resistor we can get currents on the LED up to 27mA.

To power the circuit we will use a 2x6 100 mill spaced connector (J1). This connector works in a pseudocoaxial way with ground at the outer pins and +5V at the center. Having two rows enables us to chain several independent LED drive circuits.

The LED is also connected to the circuit using a 3 pin pseudocoaxial connector (J2) with +5V on the outer pin and the drive current on the center.

The circuit is mounted on a scrap piece of two sided copper PCB. The connections are done directly on the copper using deadbug style.

Deadbug circuit



We want the LEDs to be able to be positioned in the position we want. To do that a SMD LED is mounted on a rigid wire soldered to the current pin at  the center of a 3 pin male connector. A second thin wire provides the +5V supply on one of the outer connector pins.

LED connected to a rigid wire
In order to have two independent LED lights I have build two twin circuits.



Twin LED drivers

Next figure shows the detail of the supply J1 connector.


Supply connector
This connector enables us to chain both boards

Chain power to the twin drivers

Now we can put the LEDs on the driver boards

Twin lights
We can also use different LED colors, although this is less usefull.

Green and White lights

That's all for now. This was only a little project to iluminate small spaces. In fact, with the size of the SMD LEDs, we can practically illuminate anything regardless of the space we have to route the lights.

Saturday, January 17, 2015

Fast ADC on Arduino Leonardo

Last December I wrote about generating fast PWM on the Arduino Leonardo board.
This time I will follow my ideas of going beyond stock vanilla Arduino talking about the ADC.


The problem

You can use the Arduino analogRead function to read an analog value on one of the analog enabled pins. On the Arduino Leonardo there are 12 analog inputs. The typical A0 to A5 six standard Arduino inputs and the additional six lines A6 to A11 that correspond to D4, D6, D8, D9, D10 and D12. 
The ADCs contained in the Atmega MCUs used in Arduino boards are 10 bit converters. To do one conversion the analogRead function takes 100us. It is supposed that the MCU needs that much time to give a 10 bit precision conversion. But 100us, for some applications, can be too much time. It limits, in fact, the maximum analog sample frequency to 10kHz and this doesn't take into account the time needed to process the read data.

You can do better. You can do faster. But, as is normal in life, there must be some trade offs. So, if you want to do faster conversions you need to know what are you trading for them.


The ATmega 32u4 ADC

I suspect that other ATmega based Arduinos include a similar ADC, but I don't know for sure. The ADC uses an internal clock that is obtained from the system clock (16MHz on Arduino Leonardo) which is divided by factor between 2 and 128 using an special register setting. 

On the Arduino Leonardo, the divider is set to the maximum 128 value so, at 16MHz master clock frequency we get a 125kHz ADC clock frequency.
To obtain the time needed to do a conversion from the ADC clock frequency we can refer to one table in the ATmega 42u4 datasheet.

Number of cycles to do a conversion
There are three kinds of conversion: First Conversion, Normal Conversions and Auto Triggered Conversion. The ones that apply to analogRead are the two first ones, but the first only applies to the first conversion so we can use the central column (Normal Conversion) as the typical case.

The ADC needs to do two things to provide a conversion: Sample and Hold and SAR Conversion. In the table we find that those needs 1.5 and 13 cycles for a total of 14.4 cycles. As the ADC frequency is 125kHz, the total ADC time is 14.5/125kHz  =  116 us. That's where the about 100us analogRead time comes from.

The MCU datasheet states that we need an ADC frequency between 50kHz and 200kHz to get the maximum 10 bit resolution. With a 200kHz frequency we could shorten the total ADC time to 72,5us. Unfortunately the clock divider option next to 128 is 64 so, we cannot select 200kHz. We can only select 125kHz, 250kHz... Any option beyond 125kHz, using a 16MHz master clock, goes beyond the Atmel recommendations for the MCU.

Separating the two things the ADC does we get 12us Sample and Hold time and 104us SAR Conversion time. If we increase the ADC frequency we could shorten those times but. We know that we won't get maximum resolution but, ¿What are exactly the side effecs?


Sample and Hold

To understand the Sample and Hold we can use one of the figures in the ATmega 32u4 datasheet:

The Sample and Hold (S&H) circuit is composed on a switch, a resistor and a capacitor. At the start of the conversion the switch is closed during the sample time (1.5 ADC clock cycles). After that, the switch is open and the ADC SAR circuit does the real conversion. The S&H circuit is important because the signal should not change during the SAR conversion. That is guaranteed by the fact that the switch is open during the conversion.

One fundamental point about S&H circuits is that the capacitor need to be charged to the input voltage, during the sample time, before the conversion starts. As this is an RC circuit, in theory, the capacitor voltage will never reach the input one. In practice we only need to get as close to the input voltage as is needed for the converter resolution. For a 10 bit ADC, in order to get a negligible error we need to get to 1/2^11 of the ADC reference value that is normally 5V for Arduino boards.

The RC charging, assuming the worst case of capacitor at zero will be modelled by:


In the worst case, the input voltage will be 5V and to meet the required 10 bit precision the input value capacitor value should get to 1/2^11 of the input value.

That will get:


At 125kHz ADC clock operation we know that the sample time is 12us, so the time constant should be 1,57us or less. As the capacitance is 14pF, the total resistance should be below 112 kOhm. As the ADC internal resistance can go up to 100k, that limits the external resistance to about 12kOhm. That is consistent with the fact that the MCU datasheet recommends external resistances to the ADC of 10 kOhm or  less.

The above formula is quite important. When using the ADC. At a 16MHz master frequency the sample time cannot be bigger than 12us so you should not use a total external resistance to the ADC greater than 12 kOhm. Using a greater resistance could limit the ADC resolution lowering the effective number of bits you get from the ADC.

If, for instance, you only need 8 bits because you are discarding the 4 lower bits resulting from the conversion, you only need to have a 5,4 us time constant (sampling time divided by ln(9) ) so, with the same 14pF ADC capacitance you will only need a total resistance below 386k Ohm. Considering the maximum 100k internal ADC resistance you only need to guarantee a maximum of 286k Ohm external resistance.


SAR Conversion

The ATmega 32u4 MCU uses a Succesive Approximation Register (SAR) to do the conversion. This is the most usual kind of converter that can be found on MCUs. These converters get one bit at a time at each clock cycle. So, in order to get a 10bit value, we need 10 clock cycles. From the table found on the datasheet we know that the actual conversion takes 13 cycles. The extra 3 cycles are probably for synchronization tasks.

Increasing the clock frequency during the conversion operation will affect the ADC resolution but the effect is not easy to model although it can be measured. Fortunately someone has done this measurements.


On the Open Music Labs website you can find this two articles:



They are a quite interesting read and they explain more details on the Sample and Hold operation. The links apply to the ATmega 328p but I don't think that the ATmega 32u4 ADC should be much different.

The result is that increasing the ADC frequency reduces the equivalent number of bits (ENOB) of the conversion. Observe that at the minimum stock 125 kHz frequency the ENOB is not 10 bits but something above 9. Also, at 250 and 500 kHz the ENOB is also over 9 but decaying. At 1MHz the ENOB is over 8. For frequencies greater than that the ENOB falls below 8 bits.

Finally we can find the trade offs of using a bigger ADC frequency:
  • The resolution (number of bits) could be limited by the S&H
  • The resolution (number of bits) will be limited during the conversion
The number of bits of an ADC is an integer number, but the Equivalent Number of Bits (ENOB) is not. At 125kHz, if the S&H is not the limiting factor, you will get about 9,5 bits worth of data. That is, the ratio between the maximum value you can convert and the conversion noise will be limited to a 2^9,5 ratio. If you don't need more than 9 bits of real resolution, you can increase the ADC clock frequency up to 500kHz but you must verify that the S&H is also capable to keep with that speed for your ADC external resistance values. For 8 bit operation you could go to 1MHz. That is eight times the original conversion speed.


Example Program

In order to change the ADC speed clock you need to change the ADC Control and Status Register A (ADCSRA).

The 3 lower bits of this register determine the divider used to obtain the ADC clock from the MCU master frequency.


For 111 we get a 128 prescaler that corresponds to the 125 kHz stock Arduino frequency.
For 110 we get a 64 divider that gets a 250kHz clock. For 101 we get 500kHz and for 100 we get 1MHz.

The following example program just does 4 conversions in a row. The first at the stock 125kHz, the second at 250kHz, the third at 500kHz and the last one at 1MHz.



The program also toggles the Arduino pin 3 before and after each call to analogRead so that the total time associated to this function can be measured.

Output at pin 3
From the mesurement we can see how the analogRead function time halves on each call as the ADCSRA register is changed to obtain greater ADC frequencies.

Fortunately the analogRead function itself doesn't modify the ADCSRA register. If that was the case we could not hack the ADC speed without creating a new analogRead function.

Monday, December 22, 2014

Fast PWM on Arduino Leonardo

Today I will talk about PWM generation.
The Arduino boards provide pseudo analog outputs using the analogWrite( ) function. This function is not available on all pins, only the ones marked with the ~ symbol. The Analog Write function doesn't provide a real analog output but a PWM signal instead.

Arduino Leonardo Board
A PWM (Pulse Width Modulation) signal is a pulsed binary signal. As it is binary it can only have two output states "HIGH" and "LOW". The analog information is not on the signal levels but on the width of the generated pulses.We define Pulse Width as the width of the HIGH pulses and Duty Cycle, represented with a lower case delta letter, as the fraction of the Pulse Width to the total period T of the signal. The frequency of the PWM signal is defined as the inverse of the period.
PWM Signal

The mean value of the PWM signal depends on the Duty Cycle and the voltage values associated to the HIGH and LOW levels:
If the LOW level is zero, the the mean value of the PWM signal is:

That way, the mean value of the signal is proportional to the Duty Cycle.



Arduino analogWrite( ) function maps a 0 to 255 input value to a 0% to 100% Duty Cycle. As the HIGH level is about 5V and the LOW level is near to zero, the mean value of the signal generated using  analogWrite(pin,x) is:
 
If the device connected to the pin has lower bandwidth than the frequency of the PWM signal, it will work as low pass to the signal an only will see the mean value. Arduino Leonardo PWM pins use frequencies of  488Hz or 976Hz. When you use analogWrite on a LED, as LEDS have usually higher than 1kHz bandwidth, the LED will turn full ON and OFF as indicated on the PWM signal. Our eye, however, has a bandwidth (fusion frequency) up to about 100 Hz depending on the ambient ligh levels. As the LED pulses at a higher frequency than the eye bandwidth, we only see the mean value and seems that the LED lights at intermediate levels between ON and OFF.
The same applies if we use a PWM signal to drive a motor. Normal DC motors, due to their inertia, have bandwidths near or below the Arduino PWM frequency, so the motor works as if a constant variable voltage where applied. In fact, PWM operation at low frequency can make the motor work better at low speeds.

All in all, the 500Hz to 1kHz PWM frequency in stock Arduino is adequate to drive motors. If we want, however, to generate an audio signal, the analogWrite function does not work.The hearing bandwidth in humans is arround 20kHz, much higher than the Arduino PWM frequency. Typical speakers are usually designed inside the human hearing bandwith so applying a PWM signal to them will produce an audible tone at the PWM frequency.

One of the utilities to generate a high frequency PWM signal is going beyond the speaker and hearing bandwidths so that we can use an PWM signal to generate an audio signal.


Stock PWM on Arduino Leonardo

First we start explaining how the PWM is implementated on the Arduino Leonardo board. In most Arduino boards the PWM signals are generated using timers. Timer peripheras provide hardware PWM generation so that the CPU don't need to use any of it's execution resources to generate the signals. Each timer has a limited number of PWM signals than can be generated by hardware. 

The Arduino Leonardo, as the Micro and Esplora use the ATmega42u4 MCU. It includes four timers: Timer 0, Timer 1, Timer 3 and Timer 4. Timers 1 and 3 are equal, but the rest of timers are quite different. Other Arduino Boards make use of other timers provided by the MCUs they use.

The following table shows the timers usage to generate PWM on the Arduino Leonardo board. You can see it and more information on my Arduino Leonardo spreadsheet.

PWM Timers in Arduino Leonardo
Arduino uses the timers for other functionalities. For instance, Timer 0 is also used to record the pass of time as is needed for the functions millis( ), micros( ), delay( ) and delayMicroseconds( ). You don't wanna mess with Timer 0 operation as it will disturb all timing functions. 
Some Arduino libraries make also use of timers. The Servo library uses Timer 1 on the Leonardo while the MsTimer2 library uses Timer 4. You should know that using any library that needs a timer will affect any PWM pin associated to that timer.

There are several two basic ways to create a PWM signal using a timer.

Single Slope PWM

The timers are typically based on a Counter. The counter uses a clock input and, at each active clock edge, the counter changes state. One typical mode of operation for a timer involves increasing the counter at clock each clock edge until it reaches a maximum value. Once this value is reached, the counter returns to zero and the process repeats.That gives a sawtooth waveform on the counter values as is depicted in the figure below. One full cycle of the sawtooth will need Count Max + 1 clock cycles.

Single slope PWM

Timer peripherals usually include several capture/compare registers. In order to create a PWM signal, a compare register is linked to a hardware output of the MCU in a way that makes this output high if the counter is below or equal to the compare register value. That will give, for each compare register, a PWM signal whose duty cycle depends on the compare value. 
All PWM signals generated by the same timer, will have the same frequency as the start of the generated pulses will allways be at the falling edge of the sawtooth signal.
If we have several PWM signals regenerated with different compare registers at the same timer, all of them will have the rising edge at the same times.

The Arduino analogWrite( ) functions operate the ATmega 32u4 Timer 0 at single slope. The 250kHz clock used is obtained dividing by 64 the 16MHz system clock. The final PWM frequency will the be 976Hz.
Timer 0 has two compare channels A and B associated to two compare registers OCR0A and OCR0B. The two channels are linked to two hardware outputs OC0A and OC0B that are used as Arduino pins numbers 11 and 3.

Dual Slope PWM

Another way to generate a PWM signal configures the counter to increase at each clock edge, and when it reaches the maximum value, start decreasing one number each clock cycle until it reaches zero and the patter repeats again. That will give a triangle waveform instead of the sawtooth one.

Dual Slope PWM
We can also configure a capture register so that a generated output signal is high when the counter is below this register. This will generate a PWM signal as in the single slope case. The difference is that, if we have several compare registers, the PWM signal generated with each one will be synchronized at the center of the generated pulses.
This is handy in some kinds of motor control but the details are beyond this article.
In any case, the PWM frequency will be the same for all compare channels and will also be half of the value we would obtain if we used a Single Slope counter.


The Arduino analogWrite( ) functions operate the ATmega 32u4 MCU Timers 1, 3 and 4 in Dual Slope mode. A possible reason why Timer 0 is not operated also in Dual Slope can probably be due to the fact that Timer 0 is used to record the pass of time and, this use, is difficult to be implemented on a dual slope timer. Working on dual slope, all PWM pins associated to those pins use half the Timer 0 frequency working at 488Hz.
Timer 1 includes three compare channels A, B and C associated to compare registers OCR1A, OCR1B, OCR1C linked to hardware outputs OC1A, OC1B and OC1C. The Arduino software only uses the channels A and B that are related to Arduino pins 9 and 10. Channel C output OC1C is associated to the same 11 Arduino Pin driven by Timer 0. For whatever reason Arduino designers preferred to drive pin 11 using Timer 0 at single slope than use Timer 1 at dual slope.
Timer 3 only includes one hardware output OC1A at Arduino pin 5, associated to the compare register OCR3A.
Timer 4 is a special timer, but respect to PWM, it operates as Timers 1 and 3 in dual slope mode. It includes three hardware outputs OC4A, OC4B and OC4D associated to registers OCR4A, OCR4B and OCR4D. Only channels A and D are used in stock Arduino for pins 13 and 6. Channel B is associated to the same pin driven by OC1B so Timer 1, instead of Timer 4, is used for this pin.
All of that gives the table of the 7 PWM enabled Arduino Pins.


Fast PWM on Timer 1

If the maximum 976 Hz that stock Arduino analogWrite is not enough, we need to develop our own PWM functionality. Timer 1 is a good candidate as it has three available compare channels and don't mess with Arduino delay functions. You should take care if you use the Servo library because it also uses Timer 1.

Timer 1 is based arround a 16 bit counter. That means that it can count from 0 up to 65535 before overflowing. The timer has several modes of operations that include 12 PWM modes. The fastest PWM mode available is single slope 8 bits counting between 0 and 255. As single slope is faster that dual slope, it is also called Fast PWM mode.
You can also have 9 bits and 10 bits PWM modes with 511 and 1023 terminal counts that can operate on single and dual slope modes. Three bit modes 8, 9 and 10 for single and dual slope PWM gives a total of 6 PWM modes. The other 6 additional PWM modes use programmable terminal counts that can be any 16 bit value and is not restricted to 255, 511 or 1023.

The timer gets its clock from the global MCU prescaler that provides five frequencies from the system clock. The divide ratios are 1, 8, 64, 256 and 1024. That gives, using the 16MHz Arduino Leonardo system clock, the fiveclock and single slope frequencies shown below for standard 8, 9 and 19 bit modes:

Prescaler and PWM options
Using dual slope the maximum frequency will be half. We see that the maximum available PWM frequency on Timer 1 is 62.5kHz. That's enough to generate some sort of audio signal as it is beyond the audible range of frequencies.

In order to configure the timer we must program the Timer 1 registers TCCR1A and TCCR1B.


Bits 0, 1 and 2 of TCCR1B (CS10, CS11 and CS12) configure the clock options acording to the following table.


Bit 1 of TCCR1A (WGM11) and bits 3 and 4 of TCCR1B configure the waveform for the timer acording to the table:


Modes  1, 2, 3, 5, 6 and 7 correspond to the 6 standard PWM modes.

Once the timer is configured on one PWM mode, each of the three compare channels A, B and C can be enabled to generate a PWM signal. To do that, the COM1x0 an COM1x1 bits on register TCCR1A associated to a particular x channel (A, B, C) need to be configured according to the table:


The PWM value for each channel should be programmed in each channel compare register OCR1A, OCR1B and OCR1C.

All the above tables habe been taken from the ATmega32u4 datasheet.

Configuring the TCCR1A bits is not enough to generate the PWM signal at the output pins. We also need to configure them in output mode. From the ATmega32u4 we can see that the timer 1 outputs OC1A, OC1B and OC1C  are associated to port lines PB5, PB6 and PB7 (Arduino Pins 9, 10 and 11). We need to set those pins in output mode using the Port B Data Direction Register DDRB.


Fast PWM on Timer 4

Using Timers 0, 1 or 3  we can have up to 62,5kHz PWM signals, but the maximum possible PWM frequency is only available on Timer 4.
Timer 4 is a 10 bit timer that can operate at very fast speed due to its clock source options.
The ATmega32u4 MCU includes an USB peripheral. This peripheral needs a 48MHz clock frequency that goes beyond the maximum 16MHz system clock. In order to generate the USB frequency the MCU incorporates an internal PLL. In the Arduino Leonardo the PLL takes as input the 16MHz system clock and multiplies it by 6 to generate a 96MHz output frequency.
You don't want to mess with the PLL configuration on the Arduino Leonarda as it will break the USB communications. The only need you need to know about the PLL is that its output can source the Timer 4 peripheral.

The PLL register PLLFRQ includes among other things, two bits PLLTM0 and PLLTM1 that determine the input clock to Timer 4.


There are four options, don't use the PLL to source the timer (it will be sourced by system clock) or to use the PLL output divided by 1, 1.5 or 2. That will give 96MHz, 64MHz or 48MHz clock frequencies.


At the time of this writting the above table was missing from the official ATmega32u4 current datasheet. I needed to find an older datasheet to obtain the full PLL configuration register contents.

Timer 4 has an additional divider configured with bits CS40 to CS43 of the TCCR4B configuration register.

The available options are:


 That way, using the PLL and Timer 4 dividers you can have input frequencies betwen 96MHz and 5859Hz.

In a similar way than Timer 1, Timer 4 must select a waveform operation mode using bits WGM40 and WGM41 of the TCCR4D register.

The available options are:


Mode 00 is Single Slope while mode 01 is Dual Slope.

Observe that the PWM signal has a maximum count value defined in OCR4C register. As compare channel C register is used for the terminal count, there is no independent channel C PWM output.

PWM6 is an special PWM operation mode that uses all three available channels A, B and D to drive a motor. The details, that are beyond the scope of this document, can be found on the MCU datasheet.

After configuring the clock input, each channel x = A, B and D of Timer 4, can be configured with its own bits COM4x0, COM4x1 and PWM4x at registers TCCR4A and TCCR4C.
As we have explained channel C, used as terminal count, has no output unit so it cannot be used to generate PWM.

To operate one x channel in PWM mode you need to set to "1" the  corresponding PWM4x bit. After that, the COM4x0 and COM4x1 determine the mode of PWM operation. In the case of channel A in fast PWM mode we can choose:


Normal PWM operation corresponds to mode 10. Mode 11 will give a complementary output whereas mode 01 gives two complementary PWM outputs at different pins. The complementary signals can have some deadband between them so that one signal, and its complement are never active at the same time.
Similar tables can be found for channels B and D.

Fast PWM Test Code

I have put together all the above methods to generate PWM in a FastPWM Arduino sketch.



The sketch includes the needed code to operate 5 pins associated to Timers 1 and 4 in fast PWM modes.

Timer 1 Code

The code associated to timer 1 includes 4 functions and several defines. It can uses all three Timer 1 compare channels to generate PWM signals at Arduino pins 9, 10 and 11.

The pwm91011configure function must be called previously to the call of any other function associated to this timer. It configures the timer to operate in single slope fast PWM mode and sets the prescaler to the mode indicated on the function argument.
The five possible modes are  PWM62k,  PWM8k, PWM1k, PWM244 and PWM61 and are associated to the four available frequencies in single slope 8 bit PWM modes.

Functions pwmSet9, pwmSet10 and pwmSet11 configure the Timer 1 channels associated to pins 9, 10 and 11 to work in PWM mode and set the given PWM value (0 to 255).

After one of the three above functions is called, the PWM value can be fast changed using a direct access to the corresponding compare register. To ease the access, three definitions PWM9, PWM10 and PWM11 are associated to compare registers OCR1A, OCR1B and OCR1C.


Timer 4 Code
The code associated to timer 1 includes 3 functions and several defines also. It uses two of the three available compare channels A and D associted to Arduino pins 13 and 6. It doesn't use channel B because its Arduino pin 10 conflicts with the Timer 1 channel B previously used.
The pwm613configure function is similar to the one defined for Timer 1. It sets the PLL and PWM modes to properly configure Timer 4 in high speed mode from the 48MHz PLL tap and sets the terminal count in OCR4C to 8 bits (255). 
The input argument sets one of seven available prescaler frequencies for a 48MHz timer 4 clock input: PWM187k (187500 Hz), PWM94k  (93750 Hz), PWM47k  (46875 Hz), PWM23k  (23437 Hz), PWM12k  (11719 Hz), PWM6k   (5859 Hz) and  PWM3k  (2930 Hz). If you remenber the Timer4 options there where 15 clock prescaler options. The lower frequency ones are not implemented in the defines as they provide no advantage over stock analogWrite functionality.

Functions pwmSet13 and pwmSet6 configure the Timer 4 channels associated to pins 13, 6 to work in PWM mode and set the given PWM value (0 to 255).
In a similar way than timer 1, after one of the two above functions is called, the PWM value can be fast changed using a direct access to the corresponding compare register. Two definitions PWM13, and PWM6 are associated to compare registers OCR4A and OCR4D. An aditional PWM6_13_MAX definition has been added to access the OCR4C register that sets the PWM terminal count that is, by default, set to 255 (8 bits).


Setup and Loop Code

To check all the above functions Timer 1 is configured in setup to generate 62,5kHz PWM signals.  Timer 4 is configured for 187kHz. 4 signals are generated. At pins 11 and 13 11% and 75% fixed PWM values are set.  For pins 6 and 9, a variable 0% to 100% PWM value is programmed inside the loop function.

Generated Waveforms

The following figure shows the generated waveforms captured with the Logic Analizer of the Analog Discovery scope.


Timer 1 signals at pins 9 and 11 have the same risign edge as they are in single ramp PWM mode. The same applies to signals at pins 6 and 13 that depend on Timer 4. Signals at different timers are at different frequency so the rising edges don't usually coincide for both timer signals.

That's all for now. Timers are very usefull peripherals. PWM is only one of the timer applications. In the future I plan to talk also about generation of periodic events.