Raspberry Pi – RGB LED conversion

I was looking at the cost of an Arduino and Ethernet shield and thinking that they are quite expensive compared with a Raspberry Pi.  So time to update my Arduino RGB LEDs project to run on a RPi.

As noted all over the web the Raspberry Pi only has one PWM channel on the GPIO.  But there is a cool software PWM workaround called Pi-Blaster that does the business and opens up 8 channels of PWM, over kill for the 3 channels I need.

Initial trial with two PSUs:

RPi RGB Led controller trial with 2 PSUs

RPi RGB Led controller trial with 2 PSUs

Modify the driver board with a bigger 7805!:

Driver board regulator mod

Driver board regulator mod

Powering the RPi from the new PSU (I know I could have injected 5V back in through the GPIO header, but I have run out of 0.1″ sockets!):

Power to RPi

Power to RPi

The finished project:

RPi RGB Led controller

RPi RGB Led controller

The MQTT Python code:

#!/usr/bin/python
#
# rgb_mqtt_listener.py
# listen on MQTT queue for RGB light values
#

import os
import mosquitto

#define what happens after connection
def on_connect(rc):
        print "Connected"

def on_message(msg):
        print "OK " + msg.payload;
        hex_red = int(msg.payload[:2], 16);
        hex_green = int(msg.payload[2:4], 16);
        hex_blue = int(msg.payload[4:6], 16);
        print ("R:%d, G:%d, B:%d" % (hex_red, hex_green, hex_blue) );
        val_r = ( hex_red / 255.0 );
        val_g = ( hex_green / 255.0 );
        val_b = ( hex_blue / 255.0 );
        print ("R:%0.2f, G:%0.2f, B:%0.2f" % (val_r, val_g, val_b) );
        pwm_r = "echo 23=%0.2f > /dev/pi-blaster" % val_r;
        os.system(pwm_r);
        pwm_g = "echo 24=%0.2f > /dev/pi-blaster" % val_g;
        os.system(pwm_g);
        pwm_b = "echo 25=%0.2f > /dev/pi-blaster" % val_b;
        os.system(pwm_b);

#create a broker
mqttc = mosquitto.Mosquitto("python_sub")

#define the callbacks
mqttc.on_message = on_message
mqttc.on_connect = on_connect

#connect
mqttc.connect("mqtt.server.ip.address", 1883, 60, True)

#subscribe to topic test
mqttc.subscribe("rgblight", 2)

#keep connected to broker
while mqttc.loop() == 0:
        pass

The code listens on my Mosquito server for traffic on the “rgblight” topic.

Changing the colour of the strip is simple:

mosquitto_pub -h <mqtt server> -t "rgblight" -m "ff0000"   # Red
mosquitto_pub -h <mqtt server> -t "rgblight" -m "00ff00"   # Green

The Raspberry Pi is much quicker at processing the MQTT requests which I guess is to be expected, 16MHz vs 800MHz!

Arduino RGB LEDs and MQTT

Yesterday I took my RGB LED strip project and upgraded it to use MQTT instead of the simple terminal server I was using before. I couldn’t get it working using my WiFly shield, the system would work fine for five minutes or so and then crash. I did a little digging around, thinking it may be a memory issue, put came up blank.  So ditch the WiFly shield and dig out an Ethernet shield…

Arduino Ethernet RGB Lights

Arduino Ethernet RGB Lights

Then installed the Nick O’Leary’s Arduino MQTT library, and got coding:

/*
 * Ethernet RGB LEDS with MQTT 
 * (c) Mark McKillen
 *
 */

#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>

#define MQTT_SERVER "<Mosquitto Server IP>"

byte MAC_ADDRESS[] = { 0x91, 0xA3, 0xAA, 0x00, 0x01, 0x03 };
char message_buff[30];

int redPin   = 3;   // Red LED,   connected to digital pin 9
int greenPin = 5;   // Green LED, connected to digital pin 10
int bluePin  = 6;   // Blue LED,  connected to digital pin 11

EthernetClient ethClient;  // Ethernet object
PubSubClient client( MQTT_SERVER, 1883, callback, ethClient); // MQTT object

void setup() {
  Serial.begin(9600);
  Serial.println("Net begin");

  if (Ethernet.begin(MAC_ADDRESS) == 0)       // Get connected!
  {
      Serial.println("Failed to configure Ethernet using DHCP");
      return;
  }

  Serial.print("IP: ");                       // A little debug.. show IP address
  Serial.println(Ethernet.localIP());

  if (client.connect("arduinoClient")) {      // connect to MQTT server
    client.subscribe("rgblight");             // subscribe to topic "rgblight"
    Serial.println("Connected to MQTT");      // let us know this has happened
  }
}

void loop()
{
  client.loop();                              // loop for ever waiting for MQTT event
}

// handles message arrived on subscribed topic
void callback(char* topic, byte* payload, unsigned int length) {
  int i = 0;

  // create character buffer with ending null terminator (string)
  for(i=0; i<length; i++) {
    message_buff[i] = payload[i];
  }
  message_buff[i] = '\0';

  long colorVal = strtol( message_buff, NULL, 16);

  analogWrite(redPin, (colorVal&0xff0000)>>16 );
  analogWrite(greenPin, (colorVal&0x00ff00)>>8 );
  analogWrite(bluePin, (colorVal&0x0000ff)>>0 );
}

Really simple, that is the cool thing about MQTT, it’s so easy and powerful.

To light the lights all I need to do is:

mosquitto_pub -h <mqtt server> -t rgblight -m "ff0000"  # All red
mosquitto_pub -h <mqtt server> -t rgblight -m "00ff00"  # All green
mosquitto_pub -h <mqtt server> -t rgblight -m "0000ff"  # All blue

The lights respond quickly, much faster than my last version. Success!

Getting started with the ATTiny85 and the AVR USB ISP MkII

It doesn’t take long to want to move from Arduino to more embedded uses for the Atmel MCU’s.  I got an ATTiny85 the other day and a AVR USB ISP MkII as well. Time to see if I can get the leds blinking?!

First off I had to get the Arduino IDE ready for ATTiny’s..

Installing ATtiny support in Arduino

  • Download: ATtiny (from this GitHub repository)
  • Locate your Arduino sketchbook folder ( ~/sktechbook/)
  • Create a new sub-folder called “hardware” (if it doesn’t exist already!) in the sketchbook folder.
  • Copy the attiny folder from inside the .zip to the hardware folder.
  • Restart the Arduino development environment.
  • You should see ATtiny entries in the Tools > Board menu.

Now time to wire up the ISP.. Remembering that Rst (pin 1 on the Tiny85) has to be held high via a 4K7 resister, and the ATTiny85 needs to get power from somewhere.  The ISP won’t power the circuit. No KiCAD today, just pen cad!

Pin-outs for the ISP and ATTiny85

Pin-outs for the ISP and ATTiny85

I has a RGB LED lying around so I hooked it up to the ATTiny.  Red to PWM0 (pin 5) and green to PWW1 (pin 6).

AVR USB ISP MkII connected to a ATTiny85

AVR USB ISP MkII connected to a ATTiny85

Easy and quick.. there is something very cool about a two colour pulsing LED, or is it just me?

Arduino – WiFi controlled RGB Leds

Following on from yesterdays post, I’ve decided that the remote control is not the way to go… I think these RGB LEDs need to be controlled from Internet.  Had a dig around in my parts bin and found a WiFly Shield, wrote a simple Telnet server for it that parses the colour data from the input and updates the PWMs.

Arduino WiFly Shield and RGB LED controller

Arduino WiFly Shield and RGB LED controller

Then wrote a PHP application that uses a colour wheel (jQuery based, called Farbtastic) to get a set colour and transmit the colour code over our network to the Arduino.

Basic RGB LED control page

Basic RGB LED control page

It uses a very simple socket connection to get the data over to the Arduino.. Here is the set colour handler:

<?php

$colour = $_REQUEST["c"];

$fp = fsockopen("10.0.0.67", 23, $errno, $errstr, 30);
$rply = '';
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {
    $out = $colour."\r\n";
    fwrite($fp, $out);
    while (!feof($fp)) {
        $rply .= fgets($fp, 16);
    }
    fclose($fp);
}

if ( substr( $rply, 0, 2) == 'OK' ) {
    header("location:./?d=y&c=".urlencode($colour) );
    exit();
    }

header("location:./?d=n&c=".urlencode($colour) );
?>

Work nice, now I can set the light colour over the web… cool!