Watch My Pins !

Hi all,

For those who do not know me, I'm author of a serial communication library for arduino, known as SerPro, RPC-like, fast, small and useful when you don't want your data to be lost or corrupt.

This library (actually a set of C++ templates) was developed for my arduino oscope, but can be used on any project, and used as-is in both arduino and PC, provided you have a C++ compiler.

Some people have been asking me to write better examples on how to use it, so I decided to give it a quick shot at a very simple one yet powerful. The sketch (if you remove the not yet used PWM code) is 90 lines long.

I dedided to call it "Watch My Pins":

This is a GTK+ client for it. From this client you can control arduino pins in a very simple way (a more complex way is on the forge) and also watch your arduino digital inputs.

The top squares depict the logical level on each pin. Green means '1', white means '0'.

The other squares show the pin mode. Can be Output1 (black up arrow on white background), Output0 (white up arrow on black background), Input (black down arrow) and Input with pullup (black arrow with a plus sign). Clicking on the pin mode square with your right mouse button allows you to change the mode and output (1/0).

Next version will allow pins to be mapped to specific functions, like PWM.

But again, this is only a demo of SerPro.

You can find SerPro latest code here:

And source code for "Watch My Pins" here:





Code (simple version, for the impatient). Released under LGPLv2/v3.

SerPro code not included. Stripped down code.


#include <inttypes.h>
#define PACK __attribute__((packed))

struct arduinoPinData
      uint8_t DDR;
      uint8_t PORT;
      uint8_t PIN;

struct arduinoPins
      arduinoPinData d[3];

/* Commands and replies */

#define REQUEST_VERSION         1
#define REPLY_VERSION           1

#define REQUEST_PIN_DATA        2
#define REPLY_PIN_DATA          2

#define SET_PIN_DATA            3


#include "SerProArduino.h"
#include "protocol.h"

#define BAUD_RATE 115200

static const uint8_t version_major = 1;
static const uint8_t version_minor = 0;

SERPRO_ARDUINO_BEGIN(); /* Instantiate first part of serpro */

void loop()
      unsigned bIn;
      if (Serial.available()>0) {
            bIn =;
            SerPro::processData(bIn & 0xff);

void setup()

      SerPro::send(REPLY_VERSION, version_major, version_minor);

      int i;
      struct arduinoPins data;

      data.d[0].PORT = PORTB;
      data.d[0].PIN = PINB;
      data.d[0].DDR = DDRB;

      data.d[1].PORT = PORTC;
      data.d[1].PIN = PINC;
      data.d[1].DDR = DDRC;

      data.d[2].PORT = PORTD;
      data.d[2].PIN = PIND;
      data.d[2].DDR = DDRD;

      SerPro::send(REPLY_PIN_DATA, &data);

DECLARE_FUNCTION(SET_PIN_DATA)(const struct arduinoPins *data) {

      DDRB  = data->d[0].DDR;
      PORTB = data->d[0].PORT;

      DDRC  = data->d[1].DDR;
      PORTC = data->d[1].PORT;
      DDRD  = data->d[2].DDR;
      PORTD = data->d[2].PORT;

SERPRO_ARDUINO_END(); /* Instantiate remaining of serpro */