Home / Workshop
My electronics projects

The Workshop

Notes from the workbench: microcontroller sketches for Arduino, Netduino and chipKit boards, mostly worked through from the Arduino Cookbook (2nd ed.) by Michael Margolis and the Digilent examples, with a Bus Pirate and a scope close at hand. Code is included; click any project to expand it.

Arduino Mega 2560 · Deutsche Projekte

RGB LED Projekte

Das Erste! Written up in German. The starting point was the Adafruit RGB LED lesson. Blue is on pin 5, green on pin 6 and red on pin 7, with a common-cathode LED.

Arduino Mega wired to an RGB LED on a breadboard
The Mega and the breadboard
Breadboard wiring diagram for the RGB LED circuit
Wiring diagram
rgb_led_continuous · cycles through the colors
int rot_pin = 5;
int gruen_pin = 6;
int blau_pin = 7;

// common cathode

void setup()
{
   pinMode(rot_pin,OUTPUT);
   pinMode(gruen_pin,OUTPUT);
   pinMode(blau_pin,OUTPUT); 
}

void loop()
{
   //setColor(255,0,0);
   //delay(1000);
   for (int n=0; n<8; n++) {
     for (int x=0; x<8; x++) {
       for (int y=0; y<16; y++) {
         setColor(16*n,255-16*x,0);
         delay(1); 
       }
     }
   }
   setColor(0,0,10);
   delay(5000);   
}

void setColor(int rot, int gruen, int blau)
{
   analogWrite(rot_pin,rot);
   analogWrite(gruen_pin,gruen);
   analogWrite(blau_pin,blau);
}
rgb_led_ask · type R,G,B values in the serial monitor
int rot_pin = 7; int gruen_pin = 6; int blau_pin = 5;

// common cathode

   int rot; int gruen; int blau; 
   int field_index = 0;
   int colors[3];

void setup()
{
   pinMode(rot_pin,OUTPUT);
   pinMode(gruen_pin,OUTPUT);
   pinMode(blau_pin,OUTPUT); 
   Serial.begin(19200);
   Serial.println("(Wie viel Rot?), (Wie viel Grün?), (Wie viel Blau?)");
}

void loop()
{
    if (Serial.available()) {
      char num = Serial.read();
      if (isDigit(num)) { // is ascii between 0 and 9?
        if(field_index < 3) {
          colors[field_index] = (colors[field_index] * 10) + (num - '0');
        }
      }
      else if (num == ',') {
          field_index++; 
      }
      else {
          rot = colors[0];  gruen = colors[1];  blau = colors[2];
          Serial.print("Rot = ");  Serial.print(rot);
          Serial.print("    Gruen = ");   Serial.print(gruen);
          Serial.print("    Blau = ");   Serial.println(blau);
          setColor(rot,gruen,blau);
          field_index = 0;
          colors[0] = 0;  colors[1] = 0;  colors[2] = 0;
      }
    }
}

void setColor(int rot, int gruen, int blau)
{
   analogWrite(rot_pin,rot);
   analogWrite(gruen_pin,gruen);
   analogWrite(blau_pin,blau);
}
rgb_led_continuous sketch in the Arduino IDE
rgb_led_ask sketch in the Arduino IDE
Serial monitor asking for red, green and blue values
Serial monitor after entering color values
Arduino Uno

Debouncing & serial ports

Input/output and serial communications from Chapters 4 and 5 of the Arduino Cookbook, carried a bit further. Lots of fun.

Oscilloscope capture of a push-button switch bouncing
Scope capture of a push-button bouncing, Aug 2014

Switch debouncing, carried further

Based on Cookbook 5.2–5.4. The internal pull-up means no resistor is needed. It measures how long the button bounces and how long it's held, and reports both over serial. I had some trouble with stupidity in programming, then took the scope photo.

Debounce sketch
const int led_pin = 13;
const int input_pin = 2;    // switch input
const int debounce_delay = 10;
const int program_cycle_pin = 10
int bounce_count = 0;
int pb_on = 0;   // time from 1st pb press
int pb_bounce = 0;  //total bounce time
int pb_press = 0;
boolean pb_bounce_end = 0;

void setup() {
  pinMode(led_pin,OUTPUT);
  pinMode(input_pin,INPUT);
  digitalWrite(input_pin,HIGH);  // turns on internal pull-up R
  Serial.begin(19200);
  delay(100);
}

void loop() {
  digitalWrite(program_cycle_pin,HIGH);
  int pb_val = digitalRead(input_pin);
  //Serial.print("beg loop ");
  //Serial.print(pb_val); Serial.print(" "); Serial.print(pb_on); Serial.print(" "); Serial.println(pb_press);
  if (pb_val == HIGH) {
    digitalWrite(led_pin,LOW);  // pb off
    bounce_count = 0;
    if (pb_press == 1) {
    pb_on++;
    pb_bounce++; 
    }
    if (pb_bounce_end  == 1) {
      //Serial.print("HI");
      pb_on = 0;
      pb_bounce_end = 0;
      pb_bounce = 0;
      pb_press = 0;
     delay(1000);  // need to figure better way to get let go bounce time 
    }
  }
  else {
    digitalWrite(led_pin,HIGH);  // pb pressed
    pb_press = 1;
    pb_on++;
    pb_bounce++;
    bounce_count++;
  }
  //Serial.print("end loop ");
  //Serial.print(pb_on); Serial.print(" "); Serial.println(bounce_count);
  if (bounce_count == 10) {
    Serial.print("Debounce Delay "); Serial.print(debounce_delay); Serial.println(" msec");
    Serial.print("PB Bounce for "); Serial.print(pb_bounce); Serial.println(" msec");
    Serial.print("PB ON for "); Serial.print(pb_on); Serial.println(" msec");
    Serial.print("\n");
    pb_bounce_end = 1;
  }
  if (pb_on == 1000) { 
    Serial.print("PB ON for "); Serial.print(pb_on); Serial.println("msec");
  }
  digitalWrite(program_cycle_pin,LOW);
  delay(1);
}

Serial port projects

1. Serial port monitor · changed to 19200 baud, one line per second
void setup() {
 Serial.begin(19200);
}

int number = 0;

void loop() {
  Serial.print("The number is ");
  Serial.println(number);
  delay(1000);
  number++;
}
2. ASCII table · formatting had to live in loop(), not setup()
void setup() {
  Serial.begin(19200);
  Serial.print("ASCII   Dec   Hex   Oct     Bin");
  Serial.println();
}

  int ascii_char = 33;

void loop() {
  //Serial.print("ASCII   Dec   Hex   Oct    Bin");
  //Serial.print("Character is : ");
  Serial.print("  ");
  Serial.write(ascii_char);
  //Serial.print("  Decimal is : ");
  Serial.print("      ");
  Serial.print(ascii_char,DEC);
  //Serial.print("  Hex is : ");
  Serial.print("    ");
  Serial.print(ascii_char,HEX);
  //Serial.print("  Octal is : ");
  Serial.print("    ");
  Serial.print(ascii_char,OCT);
  //Serial.print("  Binary is : ");
  Serial.print("   ");
  Serial.print(ascii_char,BIN);
  Serial.println();
  ascii_char++;
  delay(1000); 
}
3. Blink the LED from the PC · type 0–9, blink rate is number × 100 ms
int led = 13;
int blink_rate = 0;

void setup() {
  Serial.begin(19200);
  pinMode(led,OUTPUT);     
}

void loop() {
  if (Serial.available()) {
    char num = Serial.read();
    if (isDigit(num)) { // is ascii between 0 and 9?
        blink_rate = (num - '0') * 100;
    }
  }
  blink();
}

// blink routine
void blink() {
  digitalWrite(led,HIGH);
  delay(blink_rate);
  digitalWrite(led,LOW);
  delay(blink_rate);
}
4. Blink rate in milliseconds · PuTTY sends 0xD, not 0xA, so the sketch now expects CR
int led = 13;
int blink_rate = 0;
int num_value;

void setup() {
  Serial.begin(19200);
  pinMode(led,OUTPUT);     
}

void loop() {
  if (Serial.available()) {
    char num = Serial.read();
    Serial.print(num,HEX);
    Serial.print(" ");
    if (isDigit(num)) { // is ascii between 0 and 9?
      num_value = (num_value * 10) + (num - '0');
    }
    else if (num == 13) {  // newline?
      blink_rate = num_value;
      Serial.println(blink_rate);
      num_value = 0;
    }
  }
  blink();
}

// blink routine
void blink() {
  digitalWrite(led,HIGH);
  delay(blink_rate);
  digitalWrite(led,LOW);
  delay(blink_rate);
}
5. Send header + sensor values to the PC · Cookbook 4.4
int value1 = 10; // some hardcoded values to send
int value2 = 100;
int value3 = 1000;
void setup() {
  Serial.begin(19200);
}

void loop() {
  Serial.print('H'); // unique header to identify start of message
  Serial.print(",");
  Serial.print(value1,DEC);
  Serial.print(",");
  Serial.print(value2,DEC);
  Serial.print(",");
  Serial.print(value3,DEC);
  Serial.print(","); // note that a comma is sent after the last field
  Serial.println(); // send a cr/lf
  delay(100); 
  value1++;
  value2++;
  value3++;
}
6. Processing: read the serial port · 19200 baud, pick the right COM port index
// Processing Sketch to read comma delimited serial 
// expects format: H,1,2,3,
import processing.serial.*;
Serial myPort; // Create object from Serial class
char HEADER = 'H'; // character to identify the start of a message
short LF = 10; // ASCII linefeed
// WARNING!
// If necessary change the definition below to the correct port
short portIndex = 1; // select the com port, 0 is the first port
void setup() {
  size(200, 200);
  println(Serial.list());
  println(" Connecting to -> " + Serial.list()[portIndex]);
  myPort = new Serial(this,Serial.list()[portIndex], 19200);
}
void draw() {
}
void serialEvent(Serial p)
{
  String message = myPort.readStringUntil(LF); // read serial data
  if(message != null)
  {
    print(message);
    String [] data = message.split(","); // Split the comma-separated message
    if(data[0].charAt(0) == HEADER && data.length > 3) // check validity
    {
      for( int i = 1; i < data.length-1; i++) // skip the header & end if line 
      {
        println("Value " + i + " = " + data[i]); // Print the field values
      }
      println();
    }
  }
}
7. Processing: display the Arduino's analog inputs
import processing.serial.*;

Serial myPort; 
String message = null;
int font_size = 12;

int max_num_labels = 12;

int rect_margin = 40;
int window_width = 600;
int window_height = rect_margin + (max_num_labels + 1) * (font_size * 2);
int rect_width = window_width - (rect_margin * 2);
int rect_height = window_height -rect_margin;
int min_value = 0;
int max_value = 255;
int origin = rect_margin;
float scale = float(rect_width) / (max_value - min_value);
String [] sensor_labels = {"s1","s2","s3","s4","s5","s6","s7","s8","s9","s10","s11","s12"};
int label_count = max_num_labels;


short LF = 10; // ASCII linefeed


void setup() {
  size(window_width, window_height);
   short port_index = 1; // select the com port, 0 is the first port
  String port_name = Serial.list()[port_index];
  println(Serial.list());
  println(" Connecting to -> " + port_name);
  myPort = new Serial(this,port_name, 19200);
}


void drawGrid() {
  fill(0);
  text(min_value,xPos(min_value),rect_margin - font_size);
  line(xPos(min_value),rect_margin + font_size,xPos(min_value),rect_height + font_size);
  
  
  text(max_value,xPos(max_value),rect_margin - font_size);
  line(xPos(max_value),rect_margin,xPos(max_value),rect_height + font_size);
  
  for (int i=0;i<label_count;i++) {
    text(sensor_labels[i],font_size,yPos(i));
    text(sensor_labels[i],xPos(max_value) + font_size,yPos(i));
  }
}
int yPos(int index) {
  return rect_margin + font_size + (index * font_size * 2);
}
int xPos(int value) {
  return origin + int(scale * value);
}

void drawBar(int yIndex,int value) {
  rect(origin,yPos(yIndex) - font_size,value*scale,font_size); 
}

void draw() {
  while (myPort.available () > 0) {
    try {
      message = myPort.readStringUntil(LF);  //read until find LF
      if (message != null) {
        print(message);
        String [] data = message.split(",");
        if (data[0].equals("Labels")) {  //Label header?
          label_count = min(data.length - 1,max_num_labels);
          arrayCopy(data,1,sensor_labels,0,label_count);
        }
        else if (data[0].equals("Data")) {  //Data header?
          background(#00ffff);
          drawGrid();
          fill(#ff00aa);
          println(data.length);
          for (int i=1;i<=label_count && i < data.length - 1;i++) {
            drawBar(i - 1,Integer.parseInt(data[i])); 
          }
        }
      }
    }
    catch (Exception e) {
      e.printStackTrace();  //display error
    }
  }
}
8. Arduino stimulus for the analog display
void setup() {
  Serial.begin(19200);
  delay(1000);
  Serial.println("Labels,L0,L1,L2,L3,L4,L5");
}

void loop() {
  Serial.print("Data,");
  for(int i=0;i<6;i++) { 
    Serial.print(analogRead(i));
    Serial.print(",");  
  }
  Serial.print('\n');
  delay(100);
}
9. Processing: move the PC mouse from the Arduino · Cookbook 4.10, updated for newer Processing
// use esc to stop sketch

import java.awt.AWTException;
import java.awt.Robot;
import processing.serial.*;

Serial myPort;  //creates object from Serial class
arduMouse myMouse;  //creates arduino controlled mouse

public static final short LF = 10;
public static final short port_index = 1;  //com port, 0 is first

int posX, posY, btn;  //data from message fields

void setup() {
  size(200, 200);
  println(Serial.list());
  println(" Connecting to -> " + Serial.list()[port_index]);
  myPort = new Serial(this,Serial.list()[port_index], 19200);
  myMouse = new arduMouse();
  btn = 0;  //mouse off for now
}

void draw() {
  if (btn != 0)
    myMouse.move(posX,posY); 
}

void serialEvent(Serial p) {
  String message = myPort.readStringUntil(LF); // read serial data
  if(message != null) {
    print(message);
    String [] data = message.split(","); // Split the comma-separated message
    if(data[0].equals("Data")) {// check validity
      if (data.length > 3) {
        try {
          posX = Integer.parseInt(data[1]);
          posY = Integer.parseInt(data[2]);
          btn  = Integer.parseInt(data[3]);
        }
        catch (Throwable t) {
          println(".");  //parse error
          print(message);
        }
      }
    }
  }
}

class arduMouse {
  Robot myRobot;  //create Robot class object
  
  static final short rate = 1;  //multiplier for movement rate
  int centerX, centerY;
  arduMouse() {
    try {
      myRobot = new Robot();
    }
    catch (AWTException e) {
      e.printStackTrace();
    }

    //screen = java.awt.Toolkit.getDefaultToolkit().size();
    //size(displayWidth,displayHeight); //creates big box
    centerX = (int)width/2;  //displayWidth not needed as variable?
    centerY = (int)height/2;
    print("width = " + width + " height = " + height);
  }
  void move(int offsetX,int offsetY) {
      myRobot.mouseMove(rate * offsetX,rate * offsetY);  //didn't like center as origin, probably should change
  //  myRobot.mouseMove(centerX + (rate * offsetX),centerY - (rate * offsetY));
    //println(offsetX + " " + offsetY);
  }
}
10. Arduino stimulus: sweep x 1–1920, y 1–1080
  int value1 = 1; // some hardcoded values to send
  int value2 = 1;
  int value3 = 1;
  void setup() {
  Serial.begin(19200);
}

void loop() {
  Serial.print("Data"); // unique header to identify start of message
  Serial.print(",");
  Serial.print(value1,DEC);
  Serial.print(",");
  Serial.print(value2,DEC);
  Serial.print(",");
  Serial.print(value3,DEC);
  Serial.print(","); // note that a comma is sent after the last field
  Serial.println(); // send a cr/lf
  delay(100); 
  value1 = value1 + 10;
  if (value1 > 1920) {
    value1 = 1;
  }
  value2 = value2 + 10;
  if (value2 > 1080) {
    value2 = 1;
  }
  //value3++;
}
Netduino Plus · C# / .NET Micro Framework

Netduino projects

The same beginner exercises, this time in C#.

GPIO

Blinky Onboard

Blink the onboard LED. Hello, World!

Code
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;


namespace NetduinoPlusApplication1
{
    public class Program
    {
        public static void Main()
        {
            OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
            while (true)
            {
                led.Write(true);
                Thread.Sleep(250);
                led.Write(false);
                Thread.Sleep(250);
            }
        }

    }
}
GPIO

Blinky Pins

Blink both the onboard and an external LED, alternating.

Code
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;

namespace NetduinoPlusApplication1
{
    public class Program
    {
        public static void Main()
        {
            OutputPort blu_led = new OutputPort(Pins.GPIO_PIN_D0, false);
            OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);

            while (true)
            {
                led.Write(true);
                blu_led.Write(false);
                Thread.Sleep(250);
 
                led.Write(false);
                blu_led.Write(true);
                Thread.Sleep(250);
            }
        }

    }
}
Input

Blinky Button

Use the onboard button to switch the blinking pattern of two LEDs.

Code
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;

namespace NetduinoPlusApplication1
{
    public class Program
    {
        public static void Main()
        {
            OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
            OutputPort blu_led = new OutputPort(Pins.GPIO_PIN_D0, false);
            InputPort button = new InputPort(Pins.ONBOARD_SW1, false, Port.ResistorMode.Disabled);
            bool buttonState = false;

            while (true)
            {
                buttonState = button.Read();
                Debug.Print(buttonState.ToString());

                led.Write(buttonState);
                blu_led.Write(!buttonState);
                Thread.Sleep(500);

                led.Write(!buttonState);
                blu_led.Write(buttonState);
                Thread.Sleep(250);
            }
        }

    }
}
Analog

Blinky Potentiometer

Use a pot to control the LED blinking frequency.

Code
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;

namespace NetduinoPlusApplication1
{
    public class Program
    {
        public static void Main()
        {
            OutputPort blu_led = new OutputPort(Pins.GPIO_PIN_D0, false);
            //AnalogInput pot = new Microsoft.SPOT.Hardware.AnalogInput(SecretLabs.NETMF.Hardware.NetduinoPlus.AnalogChannels.ANALOG_PIN_A0);
            AnalogInput pot = new AnalogInput(AnalogChannels.ANALOG_PIN_A0);
            int pot_value = 0;

            while (true)
            {
                pot_value = (int) (pot.Read() * 255);
                Debug.Print(pot_value.ToString());
                Debug.Print(pot.Read().ToString());

                blu_led.Write(false);
                Thread.Sleep(pot_value);

                blu_led.Write(true);
                Thread.Sleep(pot_value);
            }
        }

    }
}
PWM

LED Dimmer

A pot sets the duty cycle of a PWM port to dim the LED.

Code
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;

namespace NetduinoPlusApplication1
{
    public class Program
    {
        public static void Main()
        {
            PWM blue_led = new PWM(PWMChannels.PWM_PIN_D5, 100, 50, false);
            AnalogInput pot = new AnalogInput(AnalogChannels.ANALOG_PIN_A0);
            double pot_value = 0;

            while (true)
            {
                pot_value = pot.Read();
                Debug.Print(pot_value.ToString());
                Debug.Print(pot.Read().ToString());

                blue_led.DutyCycle = pot_value;
                //blue_led.DutyCycle = .9;
            }
        }

    }
}
PWM

RGB LED

Random-ish RGB color patterns. Change the sleep time to make it less annoying; next time, a larger resistor!

Code
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;

namespace NetduinoPlusApplication1
{
    public class Program
    {
        public static void Main()
        {
            PWM red_led = new PWM(PWMChannels.PWM_PIN_D9, 100, 50, false);
            PWM green_led = new PWM(PWMChannels.PWM_PIN_D10, 100, 50, false);
            PWM blue_led = new PWM(PWMChannels.PWM_PIN_D6, 100, 50, false);

            double red_duty_cycle = 5;
            double green_duty_cycle = 11;
            double blue_duty_cycle = 19;

            int color_count = 1;

            while (true)
            {
                ++color_count;

                red_duty_cycle += color_count;
                if (red_duty_cycle > 50) { red_duty_cycle = 5; }
                red_led.DutyCycle += blue_duty_cycle / 100;

                green_duty_cycle += color_count;
                if (green_duty_cycle > 50) { green_duty_cycle = 1; }
                green_led.DutyCycle = green_duty_cycle / 100;

                blue_duty_cycle += color_count;
                if (blue_duty_cycle > 50) { blue_duty_cycle = 2; }
                blue_led.DutyCycle = blue_duty_cycle / 100;

                Debug.Print("color_count = " + color_count.ToString());
                Debug.Print("red = " + red_duty_cycle.ToString());
                Debug.Print("green = " + green_duty_cycle.ToString());
                Debug.Print("blue = " + blue_duty_cycle.ToString());
                Debug.Print(" ");

                if (color_count > 20) { color_count = 1; }

                Thread.Sleep(3000);
            }
        }

    }
}
chipKit Max32 + Basic I/O Shield

chipKit projects

Adapted from Digilent's examples. When the libraries fought back, I wrote the I2C calls inline and watched the bus with a Bus Pirate.

GPIO

Basic I/O LEDs

Pin numbers for all eight shield LEDs, blinking in alternation.

Code
/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
 
  This example code is in the public domain.
 */
int ld1 = 77;
int ld2 = 76;
int ld3 = 75;
int ld4 = 74;
int ld5 = 73;
int ld6 = 72;
int ld7 = 71;
int ld8 = 70;
void setup() {                
  // initialize the digital pin as an output.
  // Pin PIN_LED1 has an LED connected on most Arduino and compatible boards:
  pinMode(PIN_LED1, OUTPUT);     
  pinMode(ld1, OUTPUT);     
  pinMode(ld2, OUTPUT);     
  pinMode(ld3, OUTPUT);     
  pinMode(ld4, OUTPUT);     
  pinMode(ld5, OUTPUT);     
  pinMode(ld6, OUTPUT);     
  pinMode(ld7, OUTPUT);     
  pinMode(ld8, OUTPUT);     
}

void loop() {
  digitalWrite(PIN_LED1, HIGH);   // set the LED on

  digitalWrite(ld1, LOW);    // set the LED off
  digitalWrite(ld3, LOW);    // set the LED off
  digitalWrite(ld5, LOW);    // set the LED off
  digitalWrite(ld7, LOW);    // set the LED off

  digitalWrite(ld2, HIGH);   // set the LED on
  digitalWrite(ld4, HIGH);   // set the LED on
  digitalWrite(ld6, HIGH);   // set the LED on
  digitalWrite(ld8, HIGH);   // set the LED on

  delay(1000);              // wait for a second

  digitalWrite(PIN_LED1, LOW);    // set the LED off

  digitalWrite(ld1, HIGH);   // set the LED on
  digitalWrite(ld3, HIGH);   // set the LED on
  digitalWrite(ld5, HIGH);   // set the LED on
  digitalWrite(ld7, HIGH);   // set the LED on

  digitalWrite(ld2, LOW);    // set the LED off
  digitalWrite(ld4, LOW);    // set the LED off
  digitalWrite(ld6, LOW);    // set the LED off
  digitalWrite(ld8, LOW);    // set the LED off

  delay(1000);              // wait for a second
}
OLED

Basic I/O OLED

A basic message on the shield's OLED, plus the LEDs.

Code
#include <IOShieldOled.h>

int ld1 = 77;
int ld2 = 76;
int ld3 = 75;
int ld4 = 74;
int ld5 = 73;
int ld6 = 72;
int ld7 = 71;
int ld8 = 70;

void setup()
{
  IOShieldOled.begin();

  pinMode(PIN_LED1, OUTPUT);     
  pinMode(ld1, OUTPUT);     
  pinMode(ld2, OUTPUT);     
  pinMode(ld3, OUTPUT);     
  pinMode(ld4, OUTPUT);     
  pinMode(ld5, OUTPUT);     
  pinMode(ld6, OUTPUT);     
  pinMode(ld7, OUTPUT);     
  pinMode(ld8, OUTPUT);     
}

void loop()
{
  int irow;
  int ib;

  //Clear the virtual buffer
  IOShieldOled.clearBuffer();
  
  //Chosing Fill pattern 0
  IOShieldOled.setFillPattern(IOShieldOled.getStdPattern(0));
  //Turn automatic updating off
  IOShieldOled.setCharUpdate(0);
  
  //Draw a rectangle over wrting then slide the rectagle
  //down slowly displaying all writing
  for (irow = 0; irow < IOShieldOled.rowMax; irow++)
  {
    IOShieldOled.clearBuffer();
    IOShieldOled.setCursor(0, 0);
    IOShieldOled.putString("Tom's chipKIT");
    IOShieldOled.setCursor(0, 1);
    IOShieldOled.putString("Basic I/O Shield");
    IOShieldOled.setCursor(0, 2);
    IOShieldOled.putString("by Digilent");
    
    IOShieldOled.moveTo(0, irow);
    IOShieldOled.drawFillRect(127,31);
    IOShieldOled.moveTo(0, irow);
    IOShieldOled.drawLine(127,irow);
    IOShieldOled.updateDisplay();
    delay(100);
  }
  
  delay(1000);
  
  // Blink the display a bit.
  IOShieldOled.displayOff();
  delay(500);
  IOShieldOled.displayOn();
  delay(500);
  
  IOShieldOled.displayOff();
  delay(100);
  IOShieldOled.displayOn();
  delay(100);

  //IOShieldOled.displayOff();
  //delay(500);
  //IOShieldOled.displayOn();
  //delay(500);

  delay(2000);
  
  // Now erase the characters from the display
  for (irow = IOShieldOled.rowMax-1; irow >= 0; irow--) {
    IOShieldOled.setDrawColor(1);
    IOShieldOled.setDrawMode(IOShieldOled.modeSet);
    IOShieldOled.moveTo(0,irow);
    IOShieldOled.drawLine(127,irow);
    IOShieldOled.updateDisplay();
    delay(25);
    IOShieldOled.setDrawMode(IOShieldOled.modeXor);
    IOShieldOled.moveTo(0, irow);
    IOShieldOled.drawLine(127, irow);
    IOShieldOled.updateDisplay();
  }
  
  delay(1000);  

  // Draw a rectangle in center of screen
  // Display the 8 different patterns availible
  //IOShieldOled.setDrawMode(IOShieldOled.modeSet);

  //for(ib = 1; ib < 8; ib++)
  //{
    //IOShieldOled.clearBuffer();
    
    //IOShieldOled.setFillPattern(IOShieldOled.getStdPattern(ib));
    //IOShieldOled.moveTo(55, 1);
    //IOShieldOled.drawFillRect(75, 27);
    //IOShieldOled.drawRect(75, 27);
    //IOShieldOled.updateDisplay();
    
    //delay(1000);
  //}
  digitalWrite(ld1, LOW);    // set the LED off
  digitalWrite(ld3, LOW);    // set the LED off
  digitalWrite(ld5, LOW);    // set the LED off
  digitalWrite(ld7, LOW);    // set the LED off

  digitalWrite(ld2, HIGH);   // set the LED on
  digitalWrite(ld4, HIGH);   // set the LED on
  digitalWrite(ld6, HIGH);   // set the LED on
  digitalWrite(ld8, HIGH);   // set the LED on

  delay(1000);              // wait for a second

  digitalWrite(ld1, HIGH);   // set the LED on
  digitalWrite(ld3, HIGH);   // set the LED on
  digitalWrite(ld5, HIGH);   // set the LED on
  digitalWrite(ld7, HIGH);   // set the LED on

  digitalWrite(ld2, LOW);    // set the LED off
  digitalWrite(ld4, LOW);    // set the LED off
  digitalWrite(ld6, LOW);    // set the LED off
  digitalWrite(ld8, LOW);    // set the LED off

  delay(1000);              // wait for a second
}
I2C

Temperature sensor

Had a bit of trouble: the I2C bus just hung. The culprit was probably a missing Wire.begin(), found with the Bus Pirate.

Code
//#include <IOShieldTemp.h>
#include <Wire.h>

#define ALERT_PIN 2
#define IOShieldTempAddr  0x48

int ld4 = 74;

void setup()
{
  Serial.begin(115200);
  Serial.println("Serial Port 115200");

  pinMode(ALERT_PIN, INPUT); 
  
  pinMode(ld4, OUTPUT);     

  byte error, address;
  Wire.begin();

  uint8_t temp[2] = {0};
  temp[0] = 0x01;
  temp[1] = 0xC4;
  Wire.beginTransmission(IOShieldTempAddr); // actual address, but need shift up and add r/w
  Wire.send(temp, 2);
  error = Wire.endTransmission();
  digitalWrite(ld4, HIGH);   // set the LED on
  delay(2000);
  Serial.print("error = ");
  Serial.println(error);
  if (error == 0){
      digitalWrite(ld4, LOW);   // set the LED on
  }
  
  //Set the range to bring the alert pin high if it's above 78F (25.5C), alert will stay
  //high until the temp drops below 75.2F (24C).
  //IOShieldTemp.setTempLimit(IOShieldTemp.convFtoC(78)); // 78.0F ~ 25.5C
  //IOShieldTemp.setTempHyst(24); // 75.2F ~ 24.0C
}

void loop() 
{
  float tempF, tempC;


  //Get Temperature in Celsius.
  //tempC = IOShieldTemp.getTemp();
  float  tempResult;
  int16_t  wResult = 0;
  uint8_t temp[2] = {0};
  int index = 0;
  
  Wire.beginTransmission(IOShieldTempAddr);
  Wire.send(temp, 1);
  Wire.endTransmission();

  Wire.requestFrom(IOShieldTempAddr, 2);
  while(Wire.available())
  {
    temp[index++] = Wire.receive();
  }
  
  // Convert the result
  wResult = temp[1] | (temp[0] << 8);
  tempResult = wResult/256.0;
    
  // Convert the result to Fahrenheit.
  //tempF = IOShieldTemp.convCtoF(tempC);

  //
  tempC = tempResult;
  Serial.print(tempResult);
  Serial.print(" C, ");
  tempF = tempC*9.0/5.0+32.0;
  Serial.print(tempF);
  Serial.print(" F");
  Serial.println();

  delay(5000);  
}
I2C

EEPROM read/write

More library problems, so I made my own functions from theirs. Not sure they're correct, but it works.

Code
//#include <IOShieldEEPROM.h>
#include <Wire.h>

#define IOShieldEEPROMAddr  0x50

int ld4 = 74;

void setup() {

  char buf[26];
  char single;
  int i;

  pinMode(ld4, OUTPUT);     

  Serial.begin(9600);
  Serial.println("Serial Port 9600");

  Wire.begin();

  //Write the alphabet to the EEPROM
  //The data length is assumed in this example because the data
  //is a string. If you write an array numbers to EEPROM then the
  //length of the array must be provided.
  //IOShieldEEPROM.writeString(0,"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  //char new_string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  //uint8_t data = new_string.toInt();
  writeString(0,"ABCDEFGHIJKLMNOPQRSTUVWXYZ",strlen("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
  digitalWrite(ld4, HIGH);   // set the LED on
  delay(2000);

  //Read alphabet back and print to monitor
  //IOShieldEEPROM.readString(0, buf, 26);
  readString(0, buf, 26);
  Serial.print(buf);
  Serial.println();
  
  //Write a single character
  write(20,'@');
  
  //Read all characters back
  readString(0, buf, 26);
  Serial.print(buf);
  Serial.println();
  
  //Read back last letter
  single = read(20);
  Serial.print(single);
}

void loop() {
  Serial.println("hello");
  delay(5000);
}

uint8_t read(uint16_t address) {
  char temp;
  readString(address, &temp, 1);
  return temp;
}

void write(uint16_t address, char data) {
  writeString(address, &data, 1);
}

void readString(uint16_t address, char *sz, int size) {
  uint8_t temp[2] = {0,0};
  int index = 0;
  temp[0] = (address >> 8);
  temp[1] = (address & 0xFF);
  
  Wire.beginTransmission(IOShieldEEPROMAddr);
  Wire.send(temp, 2);
  Wire.endTransmission();
  
  Wire.requestFrom(IOShieldEEPROMAddr, size);
  while(Wire.available()) {
  sz[index++] = Wire.receive();
  }
  //twi_writeTo(IOShieldEEPROMAddr, temp, 2, 1);
  //twi_readFrom(IOShieldEEPROMAddr, sz, size);
}

void writeString(uint16_t address, char *data, int size) {
  int i;
  uint8_t temp[67] = {0,0,0};
  temp[0] = (address >> 8);
  temp[1] = (address & 0xFF);

  if(size > 64) {
    size = 64;
  }

  for(i=0; i<size; i++) {
    temp[i+2] = *data;
    data++;
  }

  Wire.beginTransmission(IOShieldEEPROMAddr);
  Wire.send(temp, (size + 2));
  Wire.endTransmission();
  
  //twi_writeTo(IOShieldEEPROMAddr, temp, size+2, 1);
  delay(10);
}
I2C

I2C bus scanner

Marches through all 127 addresses. Used to test the Max32 bus when I thought it was broken.

Code
// i2c_scanner
 //
 // This program (or code that looks like it)
 // can be found in many places.
 // For example on the Arduino.cc forum.
 // The original author is not know.
 //
 // This sketch tests the standard 7-bit addresses
 // from 0 to 127. Devices with higher bit address
 // might not be seen properly.
 //
 // Adapted to be as simple as possible by Arduino.cc user Krodal
 //
 // June 2012
 // Using Arduino 1.0.1
 //
 
#include <Wire.h>
 
void setup()
 {
   Wire.begin();
 
  Serial.begin(115200);
   Serial.println("\nI2C Scanner");
 }
 
void loop()
 {
   byte error, address;
   int nDevices;
 
  Serial.println("Scanning...");
 
  nDevices = 0;
   for(address = 8; address <= 127; address++ )
  {
     // The i2c_scanner uses the return value of
     // the Write.endTransmisstion to see if
     // a device did acknowledge to the address.
     Wire.beginTransmission(address);
     error = Wire.endTransmission();
 
    if (error == 0)
     {
       Serial.print("I2C device found at address 0x");
       if (address<16)
        Serial.print("0");
       Serial.print(address,HEX);
       Serial.println(" !");
 
      nDevices++;
     }
     else if (error==4)
    {
       Serial.print("Unknow error at address 0x");
       if (address<16)
        Serial.print("0");
       Serial.println(address,HEX);
     }
   }
   if (nDevices == 0)
     Serial.println("No I2C devices found\n");
   else
     Serial.println("done\n");
 
  delay(8000);           // wait 8 seconds for next scan
 }

On the bench: a Rainbowduino LED matrix, a Raspberry Pi and an 8051. Write-ups to come, someday.