Goodbye PIC, Hello dsPIC!

If I had a penny everytime I see “hello world!” I’d be one penny richer once more. I have been contemplating since the start of summer to create a new blog. But alas, as always, ended up procrastinating until now. It has been a few months since DIT’s ROBOSUMO tournament took place (in which yours truly’s team, participated in and won 2nd place or first loser, whichever you prefer. More of that here) and I have been itching for some time now to delve back into the world of microcontrollers. I originally planned to prepare for one of my upcoming modules; which is robotics, before the semester even started. This is the reason I bought my own materials i.e. PICkit2(which I shall be using all the time for the meantime), a dsPIC microcontroller, an H bridge to control DC motors, different types of sensor i.e. colour sensors and piezoelectric sensors, and many others. But enough about my boring ramblings, onto the show! PS: I shall try to refrain from unnecessary puns or jokes but odd ones might slip and so, I apologize in advance.

First task : DC motor control using Pulse Width Modulation

Materials used:

  • PICkit2 programmer
  • dsPIC30f4011
  • Breadboard and wires
  • Power Supply
  • 2 x DC motors
  • Soldering iron
  • LEDs
  • Various resistors
  • Microswitch
  • Trimmers used as potentiometers

I decided to go and give the dsPIC a test run since this is the chip I shall be using next year. To be honest I still don’t fully understand the difference between a normal PIC and a dsPIC but I have a rough idea, just looking at the pinouts on the datasheets it is clear that the dsPIC has more analogue inputs and way more PWM outputs than the last chip I used for C.A.K.E.¬†which was the PIC16f4620. This will be for my advantage on this task as I will be needing two PWM outputs and three(for now) analogue inputs. Below is a block diagram of the task(click image to enlarge):

So in short : I’m making a sort of independent dimmer switches for two motors. I also forgot to add on the block diagram that I will be putting a microswitch to change the directions the motors are going(I intended for this to be a toggle switch but only a microswitch was available at the time but it does the job with a little software tweaking). So I twist the left pot: the left motor powers up accordingly, I twist the right pot: the right motor powers up, and I press the microswitch: the direction changes.

Pulse Width Modulation

I can’t go on without talking about PWM or Pulse Width modulation. This is a method to control power supplied to a point. By controlling the duty cycle one controls the amount of voltage coming out of a pin of a microcontroller. An analogy I told one of my friends once whilst trying to attempt to explain PWM was: imagine there was a conveyor belt of food and at the end is a fat man that consumes everything in sight, now the conveyor belt is designed to drop 10 cupcakes per second at the mouth of the fat man. Now let’s say that we want to make the fat man a bit thinner by putting him on a diet, that we’ll only give him half of his usual cupcakes i.e. 50% duty cycle, a way of doing this would be to turn off the conveyor belt every 5 seconds for the duration of 5 seconds. by doing this we limit the cupcakes to 50 per 10 seconds instead of the usual 100, the fat man still gets his cupcakes; only not as much so in theory he’d be less fat. This is exactly the same with PWM on the PIC only that instead of having a period of 10 seconds(5 on and 5 off) it will have a much smaller cycle time i.e. it will be doing this a lot lot faster.


I haven’t used Inkscape in a good while so apologies if the image is a bit cluttered. As it can be seen on the schematic: the connections of the dsPIC are similar to the connections on a normal PIC, the main differences being the jumper wires connections the AVdd,AVss,Vdd, and Vss pins together, and of course the location of the TX and RX pins. Two trimmers connected up as potentiometers will be used to give a varied voltage signal to the analogue inputs of the dsPIC and this signal will determine the duty cycle that the dsPIC will give the motors. The microswitch is just connected to AN2 for the purpose of changing the directions, I will go into a bit more detail about this later on the program part of the post. The H bridge is connected to a different power supply as to prevent power fluctuations that might reset the pic or a worse case scenario: you draining too much power from the USB port of your computer via the PIC and as a safety feature; windows usually disables the USB port and you end up wasting time trying to enable it again, although there are ways to disable this safety feature, but I’m not here to talk about that. Anyways the H bridge is connected up as such, this is the same H bridge model as the one used on our ROBOSUMO project last year so I am very familiar with it. LEDs are connected both ways as to know which direction the motors are going, I used two sets: two red for backwards, and two green ones for forward(EDIT: The LEDs are actually connected in parallel with pin 2 and 7, and pin 10 and 15 and not across the motors although this might work as well).

The code

The programming environment that I’m going to be using is the MPLABX which is the new version of MPLAB, a C16 compiler is also needed to be able to program this particular MCU. I would like to acknowledge Mr. Ted Burke( as the template I used to write this code are snippets of full codes found on his website(above), the part in particular that would have taken me days if not weeks to write myself would be the “configure pins” part of the program. The ADC part is familiar as I used it last year but of course I learned that off him, too! So go pay his blog a visit. I just edited some of the “setup” he has to suit my own needs.

// This program shows how PWM can be used to control two DC motors
// using a dsPIC and a motor driver chip.
// Two potentiometers control two motors independently
// Microswitch changes directions
// Setup template written by Ted Burke(
// Program written by Gian Lorenzo
// Last edited 31/08/2012

#include <libpic30.h>
#include <p30f4011.h>
#include <stdio.h>
#include <xc.h>

// Configuration settings
_FOSC(CSW_FSCM_OFF & FRC_PLL16);  // Fosc=16x7.5MHz, Fcy=30MHz
_FWDT(WDT_OFF);                   // Watchdog timer off
_FBORPOR(MCLR_DIS);               // Disable reset pin

// Function prototypes
void setup();
unsigned int read_analog_channel(int n);

int main()
    int voltage,voltage2,direction,flag;
    double tmin = 0.0005;
    double tmax = 0.02;

    // Set up which pins are which and activate UART tool
    direction = 1;
        voltage = read_analog_channel(0);
        PDC1 = 937509.375 * (tmin + (voltage / 1023.0) * (tmax - tmin));
        voltage2 = read_analog_channel(1);
        PDC2 = 937509.375 * (tmin + (voltage2 / 1023.0) * (tmax - tmin));
        if(direction == 1)
            if(read_analog_channel(2) < 500)
                flag = 1;
            if(flag == 1 && read_analog_channel(2) >500)
                direction = 1-direction;
                flag = 0;
        if(direction == 0)
            if(read_analog_channel(2) < 500)
                flag = 1;
            if(flag == 1 && read_analog_channel(2) >500)
                direction = 1-direction;
                flag = 0;
    return 0;

void setup()
    // Setup UART
    U1BRG = 48;            // 38400 baud @ 30 MIPS
    U1MODEbits.UARTEN = 1; // Enable UART

    // Configure D ports as a digital outputs
    LATD = 0;
    TRISD = 0b11110000;

    // Configure analog inputs
    TRISB = 0x01FF;      /* Port B all inputs */
    ADPCFG = 0xFF00;     /* PORTB 0-7 are analog inputs */
    ADCON1 = 0;          /* Manually clear SAMP to end sampling, start conversion*/
    ADCON2 = 0;          /* Voltage reference from AVDD and AVSS */
    ADCON3 = 0x0005;     /* Manual Sample, ADCS=5 -> Tad = 3*Tcy = 0.1us */
    ADCON1bits.ADON = 1; /* Turn ADC ON */

    // Configure PWM
    // PWM period = Tcy * prescale * PTPER = 0.33ns * 64 * 9470 = 20ms
    PWMCON1 = 0x00FF; // Enable all PWM pairs in complementary mode
    PTCON = 0;
    _PTCKPS = 3;      // prescale=1:64 (0=1:1, 1=1:4, 2=1:16, 3=1:64)
    PTPER = 9470;     // 20ms PWM period (15-bit period value)
    PDC1 = 0;         // 0% duty cycle on channel 1 (max is 65536)
    PDC2 = 0;         // 0% duty cycle on channel 2 (max is 65536)
    PDC3 = 0;         // 0% duty cycle on channel 3 (max is 65536)
    PTMR = 0;         // Clear 15-bit PWM timer counter
    _PTEN = 1;        // Enable PWM time base

// Analogue input reading
unsigned int read_analog_channel(int channel)
    ADCHS = channel;          // Select the requested channel
    ADCON1bits.SAMP = 1;      // start sampling
    __delay32(30);            // 1us delay @ 30 MIPS
    ADCON1bits.SAMP = 0;      // start Converting
    while (!ADCON1bits.DONE); // Should take 12 * Tad = 1.2us
    return ADCBUF0;

As I said earlier I had to make a few tweaks to make the microswitch into a toggle one thus the code is a bit longer, even so this is still a real basic task. In the end I got it to work, but talk is cheap so:

If I was any good at fabrication I’d try to make this into a sort of toy crane like contraption, the motors would of course control the horizontal and vertical movements of the arm. Or whenever I figure out how to send commands via UART I can make a toy remote control car, whichever comes first! For the next task I plan on using a sharp rangefinder(another surplus from the ROBOSUMO project, the DC motors and the microswitches are also surplus parts of C.A.K.E.), some colour sensors, and maybe even the piezo electric sensor. Here’s to hoping inspiration for a task breezes towards my direction soon.