With Pure Data

From Pinguino
Revision as of 19:27, 3 September 2013 by Skc (talk | contribs) (Message Format Description: Formatting)
Jump to: navigation, search
  • Current support only for Pinguino PIC32 OTG, but you can add support for your board easily. <br\>
  • Link to the Firmware and Patches.[1] <br\><br\>

This post is about a communication method to control a Pinguino board in real time with software such as Pure Data or Max/MSP (Although in this case I worked with Pure Data) It is very much like the Firmata protocol for Arduino. Messages are sent to Pinguino using CDC USB from and to Pure Data, the format of the messages is processed by the PIC to change its configuration on the fly, and the same format is interpreted by PD to monitor the state of such configuration and states in the board. Download the PD patches and Pinguino Firmware from the link above. <br\>

The project here uses this communication protocol and firmware to enable two way messages between Pinguino and Pure Data. It allows control of the Microcontroller from Pure Data in real time, set the Digital pins to High and Low levels, as well as read them when Inputs, use the (PWM) Analogue Outputs, and read the Analogue Inputs from the ADC module included in the PIC.<br\>

The same as Firmata, this firmware is based on the MIDI message format. It is implemented as a source code that can be added to the Pinguino IDE libraries. So that the programs there can include a couple of functions that perform the communication when loaded into the Pinguino board. <br\>

Once the Firmware is in the PIC, you can send serial messages to it via USB CDC, using a COM port on the computer side. In Pure Data this is easily done by implementing the COMPORT object, which opens a port at a custom baud rate. In here I had to use a CDC RS-232 EMULATION DEMO from here[2]. <br\>

Here, all you need to do in your code on Pinguino’s IDE is tu include the source file, then in setup include the function PureData.init(), which configures your PIC to the adequate Ports and Pins’ states, as well as the ADC module. Then, in the looping part of the code you need to call function PureData.communicate(char inputData[3], char Dgtl[22], long int Anlg[8]). I have included the size of the arrays that this funcion expects. PureData.communicate will return the size of InputData, filling it with the message coming from the CDC USB (from Pure Data for example). Dgtl and Anlg will be filled with the values of all the current Digital Pins and the values of 8 channels on the ADC module. It is 8 channels, corresponding to the PIC32 OTG board. <br\>

Version: 1.1

Roberto Becerra--<http://iobridger.wordpress.com/>
July 2013

#include <puredata.c>                    //Source file with functions of the interface

// variables will change:

unsigned char inputData[3], Dgtl[22];     //Buffers to read/send data through CDC
unsigned long int Anlg[8];               //16 bit values

int inputL;                              //variable to store the length of the input Data
void setup() {

    PureData.init();                     /* Initialize the communication. It sets the ADC module and Ports as Inputs
                                        * or outputs. LED1 (D13) is configured as output and UserButton (D2)as input

void loop(){   
    inputL = PureData.communicate(inputData, Dgtl, Anlg);  // Call function that deals with any request sent from outside via CDC,
                                                // only if it is a new instruction.     

The messages can be sent through CDC USB with Pure Data, as done in the patches that are included in the compressed file linked at the top of the page. The simplified steps of how this patches work with Pinguino by sending messages over the COM Port (CDC) are in this[3] tutorial. Description of the format of such messages in the next section.<br\>

Message Format Description

You can use the format of the messages in order to add support to other boards, as well as to do modifications to the Pure Data or Pinguino functioning. This format could also be use as a start of a formal Firmata for Pinguino.

The communication protocol is based on the MIDI message format. In it, 3 data bytes are defined to be sent over the COM Port. For more information on the MIDI protocol refer to: http://www.cs.cf.ac.uk/Dave/Multimedia/node158.html.

Messages to the Micro-controller (PINGUINO PIC32 OTG in this case) are formatted as follows:

  • First byte sent (Byte 0) = Status (instruction) message
  • Second byte (Byte 1) = Data byte 1
  • Third byte (Byte 2) = Data byte 2

Message Byte 0 (Hex) Byte 1 (Hex) Byte 2 (Hex)
  • * – This values actually start from F4, as used in the Firmata protocol.


The "x" in the values refers to the number of the Port (channel) we want to address. i.e. if a 90 byte is passed, the channel 0 will be addressed, which in this case. corresponds to the Port B, since the PIC here does not have a Port A.<br\>

In the same fashion, a 91 corresponds to Port C an so on, depending on available ports in this PIC. A lis of ports is provided ahead in this document.<br\>

The Byte 1 determines the number of Pin of the particular Port, while Byte 2 gives the value of the state of this Pin. Here is an example:<br\><br\>

  • 0x920801 - This message, in hexadecimal, will set Pin 8 inPort D to HIGH, which corresponds to D6 in the Pinguino PIC32 OTG board.<br\><br\>

Again, it is to consider that all of these values are specific and mapped to the Ports and Pins available and implemented in the Pinguino PIC32 OTG platform.<br\><br\>


The same logic as in the SET_DIGITAL_VALUE, except that in this case there are only 3 available analogue outputs in this Pinguino board (D0-D2), which means that the second half of Byte 0 will represent this number of output.

Bytes 1 and 2 are used to carry the 10 bit analogue value supported by the PWM in the PIC. Byte 2 carries the less significant byte, whereas Byte 1 does the opposite. Example:

  • 0xE100FF - This message will set D1 (RD3) to 200
  • 0xE203E8 - This message will set D2 (RD4) to 1000


As with the Digital Values, the second half of Byte 0 gives the number of the channel we are addressing. Here the values start from F4, following the already established protocol of similar platforms (Firmata). 1 is an input, while 0 is an Output.<br\><br\>

  • 0xF40201 - Sets Port B, Pin 2 to Input.<br\><br\>

More about this, in this page [4], where you can find the complete list of instructions used for this protocol.