Blockset described on this wiki is deprecated since 2012.

For Model Based Design (MBD), use the free MPLAB Device Blocks for Simulink, tool from Microchip.
Updated Rapid Control Prototyping (RCP) custom projects are published at:

PWM communication between two dsPIC

From - Simulink device driver Blockset for dsPIC / PIC24 / PIC32 Microcontrollers --[[User:LubinKerhuel|LubinKerhuel]] 12:40, 3 September 2009 (UTC)
Jump to navigation Jump to search


This example shows how one variable is transmitted from one microcontroller to another throw a PWM signal. A Sinus is generated in the microcontroller (A). Values are sent with a 1 kHz rate to the microcontroller (B) through a PWM signal. Microcontroller B reconstructs the received value sent the result to the PC with its UART peripheral. The Matlab rs232gui interface can then plot the received values.

(This example is not an Amplitude Modulation (AM) based on a low pass filtered PWM high frequency signal)

Characteristics of PWM transmissions

Scope picture of a PWM Signal generated by the microcontroller (A), here a large duty cycle code for a large value
Scope picture of a PWM Signal generated by the microcontroller (A), here a small duty cycle code a small value

Pulse Width Modulation (PWM) or Pulse Duration Modulation (PDM) signals are a two state signal (square or digital) with a fixed frequency and whose duty cycle can vary.

The simplicity of such coding is widely used in reduced model. Receiver transmits servo-motor position information through a PWM signal whose frequency is 50Hz (20ms period) and whose duty cycle takes values between 1ms and 2ms. 1.5ms being the servo motor central position.

PWM transmission is one of the easiest ways to have two microcontrollers exchanging variables. Peripheral to generate and read PWM are very common on most microcontrollers. On the dsPIC, two peripherals can generate PWM signals and three peripherals can read such signals:

Three peripheral can read PWM signals:

A PWM signal requires only one wire (two if we take into account the ground wire). However, the communication through one wire is one way only (not bi-directional).

As many wires as variable being sent are required.

Despite the two state values of the signal, this is an analog coding: the value of the variable is analog to the duty-cycle). Therefore, this analogue coding could add noise to the reconstructed value on the receiver side. This noise is due to:

  • Quantization of the duty cycle at the emitter side
  • Transition from one state to the other slow down due to wire capacity
  • Quantization at the receiver side

The quantization at the emitter or receiver side depends on both the period of the PWM signal and the speed of the microcontroller. How many ticks can the microcontroller count during this period? The respective provide these values through variables present in the workspace like PWMmax, OCxmax, ICxmax etc… These variables can be used as constant in the model.

There exist a trade of between the resolution and the bandwidth. The bandwidth of a PWM transmission is typically not very high. (Transmissions are done at 50Hz in reduced model, but can be increase to 500H)

We note however that information transmitted through a PWM signal is robust to electrical noise because it is based on a temporal coding.

Received value may be received with a delay.


PWM Circuit

The prototyping board comprises two microcontrollers dsPIC30f4012. Each dsPIC is clocked with a 10MHz quartz and each dsPIC has a led connected to a digital output port (RB0). The dsPIC at the bottom of the board (noted A) generate a PWM signal on the PWM1L pin (26). The dsPIC at the top of the board (noted B) measure PWM signal characteristics through its Input Capture pin (15). Thus the green wire connects the dsPIC A PWM1L pin (26) to the dsPIC B IC1 pin (15). Both dsPIC already share the ground signal through their alimentation.

An old ATX PC alimentation provides a 5V stabilized tension to the prototyping card.

Both dsPIC are connected through a custom made cable (based on a MAX205 chip) to the PC with their UART peripheral, respectively U1ATx (pin 12) and U1ARx (pin 11). A FTDI USB TTL Serial Cables could be used.

This serial connection has two functions. The first function is to allow easy flashing in situ of the two dsPIC which were pre-programmed with the tinybld bootloader. The second function is to monitor and plot algorithm results (here the received and reconstructed values by dsPIC B)


Each dsPIC is connected to the PC through an UART or serial connection. Using a bootloader over this serial connection is a very convenient way to reprogram the dsPIC. It is safe because no change is required on the prototyping cards (either adding programming cable, or moving the dsPIC to a programmer). However, classical programmer could be used as well as the bootloader.

Two useful bootloader are freely available for dsPIC. The older one is tinybld which works only on 30f chip. It uses very little memory (about 100 bytes). The second bootloader is ds30 Loader and is free also. It is more recent and can work with more chips (16f, 18f, 24f, dsPIC). In this example, the dsPIC are equipped with the tinybld bootloader.

The dsPIC firmware of the bootloader is configured on the UART1 peripheral of the dsPIC 30f4012 using the Alt Rx/Tx pins with a baud rates of 115200. It will works with a 10Mhz quartz and set up an 8X multiplier factor (PLL8). The dsPIC speed is 20MIPS : (10Mhz / 4(cycles/step) * 8 (PLL)). The binary .hex file of the firmware bootloader with this configuration is in the file package proposed. This firmware must be programmed once using a classical programmer (ICD2, real-ICE …). Then the dsPIC could be programmed through the UART.

Simulink models

Two simulink models generate the code for the dsPIC (A) and the dsPIC (B).

Common parts

Master block

Both models targets a dsPIC 30f4012 configured with a 10 MHz quartz with X8 PLL multiplier to obtain 20MIPS. The Master block set up this configuration in both of them.

The fixed Time step for both models is 1ms (thus 1 kHz system).

Both model blink their LED attached on PIN B0 at 2Hz.

Bootloader RESET

Bootloader Reset subsystem. The subsystem read one value received on the UART. If it receive the value 55, another subsystem is enabled. This subsystem will block the step until a character 66 is received on the UART, causing a reset of the chip (see subsystems).

Both models use UART to exchange data with the PC. The block [[Block/UART_Configuration|UART configuration] set-up the dsPIC UART1 peripheral on Alt Tx/Rx pins with a bauds rate of 115200. dsPIC A does not send result to the PC, but use however the UART for the bootloader. The subsystem Bootloader RESET (tinybld) read the received data on the UART. If the value 55 is received, the subsystem will wait forever (and thus stop the real time computation of the model steps), until the value 66 is received on the UART. The dsPIC is then reset. Thus, from the PC tinybld bootloader application (tinybldWin.exe), the values 55 and 66 are sent first to reset the dsPIC (theses reset code are set up in the Option tab, in Codes to sent first).

Value 55 will stop the dsPIC (and will prevent the dsPIC from using its UART anymore). Then value 66 reset the dsPIC which will enter into its embedded bootloader code. Then the PC bootloader and the dsPIC bootloader application should see each other.

Model A: Emission

Simulink model A: PWM_a_30f4012

The model A creates an internal sine wave signal of type int16 with amplitude 5000 and frequency 4 Hz. The sine wave generated values are transmitted to microcontroller (B) (corresponding to model B) through a 1ms period PWM signal. The sine wave full scale (+-5000) modulates the PWM duty cycle within the range [5 - 95]%.

Sine wave generation

Different techniques for sine wave generation exist. Their results differs in precision, complexity (time resources), and memory used. The comparison of these techniques is beyond the scope of this example. However, 4 different sine wave generation techniques are discussed here without getting into the many details.

Matlab 2010b is used here. 3 methods tested belong to the Simulink standard library. 1 method belongs to the Signal Processing Blockset.

The 4 presented sine generations are simulated in the simulink model Sinus_Generation_Simulation.mdl configured with a fixed time step of 1ms. Precision of theses 4 sine wave generator are compared using this simulation. Then, the sine wave comprised within the model PWM_a_30f4012.mdl were successively replace with each sine wave generator. The model ROM consumption is given by the compiler. A block Calculus Time Step connected to a block Tx_Labview_Matlab provide a precise numerical value of the time resources taken by the model step (these values were averaged on several seconds).

Measuring Time Step
Model:Sinus_Generation_Simulation. Comparison of different method for sinus generation including Cordic and lookup table.
  • The classical sine wave source block in Simulink/Sources is the most precise. However, the computational time of this block is important (21% of the 1ms time step). It uses a moderate ROM size (7%).
  • The classical trigonometric block in Simulink/Math Operation proposes a Cordic algorithm (New option from Matlab 2010b version) to compute sine and cosine. The precision of a Cordic algorithm depends on the iteration number. With a 12 iteration number, the computational time is low (2.6% of the 1ms time step) and uses only 3% of the ROM which makes it the smallest ROM usage. Despite the 12 iteration, the error is the largest (0.4% when reported to the sine wave amplitude of 5000).
  • The sine wave source block in Signal Processing Blockset/Signal Processing Sources proposed several methods for sine wave generation. I chosen a lookup table optimized for speed. The computational time is the smallest obtained with only 1.5% of the 1ms time step. But the required ROM for this model growth up to 28%. The max relative error reached is 0.02%. This block with this configuration is thus the fastest and the largest (in ROM) of the tested blocks. This block requires the Signal Processing Blockset!
  • The sine wave from a lookup table in Simulink/Lookup Tables is a quite good compromise. Configured with a lookup table of size 33 (which will code for 1/4 of the sine), the model time step is executed in 2% of 1ms, and the block model takes 4% of the available ROM. The relative max error is 0.05%. This wave generator will used in the model because its overall performances are very good and it is available in the standard simulink library.

PWM Generation

The 4Hz sine wave generated in microcontroller A has to be converted into a PWM signal so as to be transmitted to the microcontroller B. The PWM motor block is used.

The PWM motor block is set with a fixed period of 1ms (period of the PWM output signal). The period does not appear as a block input (however, this option is possible).

The PWM motor block creates the variable PWM in the workspace. It value correspond to a 1ms time for the block. In this example, the PWM value is 40000 which provide a precision better than 15 bits.

The PWM signal should always be measurable by the receiving microcontroller (B). Thus, PWM duty cycle near value 0 or 40000 must be avoided as their PWM resulting signal is a constant.

Capacities of the physical line used by the PWM signal may low pass filter the signal. Consequently, to avoid constant like signal, the PWM duty cycle is modulated within the range [5 95]% of its period.

Thus, the +-5000 amplitude sinus values are translated within 5% and 95% of the PWM value. The resulting translated value will code directly the duty cycle. Thus, the PWM signal duty cycle is modulated within the range 5% and 95% and the PWM signal is never constant.

Model B: Reception

Simulink model B: PWM_b_30f4012

The model B read the PWM signal duty cycle and reconstructs the original variable sent. Then, the microcontroller B sent the variable through the Tx Output Multiplexed for Matlab on the UART peripheral. The reconstructed sine wave can then be traced using the blockset internal rs232gui tool.

The block Input Capture read the duty cycle of the PWM signal. The block creates the IC1max in the Matlab workspace. The IC1max value represents the value of time set in the Max/Channels of the block. Here, the max/Channels is set to 1ms, thus the IC1max value correspond to 1ms. IC1max = 19999 therefore the coding resolution of a duty cycle varying in the interval 0-1ms is about 14 bits which is quite precise.

The duty cycle read (block output IC1_up) is firstly converted into a signed value, then the centered about the value IC1max/2 and a gain is applied to retrieve the value sent, taking into account that 90% of a PWM cycle represent the full scale of the original sinus in the microcontroller A.

In this example, the PWM is created with a high resolution (15 bits) and read with a high resolution also (14 bits). Consequently, we obtain a pretty good transmission with no quantization errors. The PWM period is equal to the model time step. Thus the delay at the receiver side may vary between 0 time steps in certain condition to 4 time step (4 ms) in the worst case. Using a smaller PWM period (for example a period corresponding to a half time step) may limit the max delay to 1 time step while it will also reduce the resolution of the overall transmission.

Matlab plot of the data sent by microcontroller B through UART. The rs232gui interface is used to plot incoing data in realtime