Skip to content

Instantly share code, notes, and snippets.

@mangrovemike
Last active December 11, 2015 10:59
Show Gist options
  • Select an option

  • Save mangrovemike/4590724 to your computer and use it in GitHub Desktop.

Select an option

Save mangrovemike/4590724 to your computer and use it in GitHub Desktop.
Arduino code to read MQTT data (on wind speed) and display different colours on a RGB LED. It uses a very basic RGB 'blink-em' arduino config. Thanks to Toby Jaffey and Nick O'Leary for mqtt libraries and tutorials and to Andy Piper and Andy Stafford-Clark for MQTT inspiration. Michael Barwell Jan 2013 @mangrovemike
/*
Beaufort Scale LED Display
This is a Beaufort Scale LED display using MQTT Server to determine wind speed. It is written to use
the Wind Speed data collected from my weather station but can be adapted to any other MQTT
service (even COSM data).
It uses a very basic RGB 'blink-em' arduino config.
Thanks to Toby Jaffey and Nick O'Leary for mqtt libraries and tutorials and to Andy Piper and
Andy Stafford-Clark for MQTT inspiration.
Michael Barwell Jan 2013 @mangrovemike
PS I've intentionally left in plenty of Console comments. Remove as required.
*/
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
// LED leads connected to PWM pins
const int RED_LED_PIN = 3;
const int GREEN_LED_PIN = 5;
const int BLUE_LED_PIN = 6;
char message_buff[100];
// Define base colours
int red[] = {255,0,0};
int lime[] = { 0,255,0};
int blue[] = { 0,0,255};
int yellow[] = { 255,255,0};
int orange[] = { 255,128,0};
int cyan[] = { 0,255,255};
int magenta[] = { 255,0,255};
int purple[] = { 128,0,128};
int green[] = { 0,128,0};
int gray[] = { 128,128,128};
int pink[] = { 255,0,0};
int none[] = { 0,0,0};
#define ARRAYSIZE 13
int bAllColours[][3] = {
{red[0],red[1],red[2]},
{lime[0],lime[1],lime[2]},
{pink[0],pink[1],pink[2]},
{blue[0],blue[1],blue[2]},
{yellow[0],yellow[1],yellow[2]},
{orange[0],orange[1],orange[2]},
{cyan[0],cyan[1],cyan[2]},
{magenta[0],magenta[1],magenta[2]},
{purple[0],purple[1],purple[2]},
{green[0],green[1],green[2]},
{gray[0],gray[1],gray[2]},
{none[0],none[1],none[2]},
{pink[0],pink[1],pink[2]} };
// If anyone knows a better way to do this let me know - I tried a number of other ways to
// create an array of arrays but with little success
// Define our Beaufort Scale Colours
int b0[] = { 255,255,255}; // Calm < 1 km/h
int b1[] = { 204,255,255}; // Light Air 1.1 - 5.5 km/h
int b2[] = { 153,255,204}; // Light Breeze 5.6 - 11 km/h
int b3[] = { 153,255,153}; // Gentle Breeze 12 - 19 km/h
int b4[] = { 153,255,102}; // Moderate Breeze 20 - 28 km/h
int b5[] = { 153,255,0}; // Fresh Breeze 29 - 38 km/h
int b6[] = { 204,255,0}; // Strong Breeze39 - 49
int b7[] = { 255,255,0}; // High wind, moderate gale,near gale 50 - 61
int b8[] = { 255,204,0}; // Gale, fresh Gale 62 - 74
int b9[] = { 255,153,0}; // Strong Grail 75 - 88
int b10[] = { 255,102,0}; // Storm, Whole Gale 89 - 102
int b11[] = { 255,51,0}; // Violent Storm 103-117
int b12[] = { 255,0,0}; // Hurricane > 118 km/h
// Define the array of arrays
int bScaleColours[][3] = {
{ b0[0], b0[1], b0[2] } ,
{ b1[0], b1[1], b1[2] } ,
{ b2[0], b2[1], b2[2] } ,
{ b3[0], b3[1], b3[2] } ,
{ b4[0], b4[1], b4[2] },
{ b5[0], b5[1], b5[2] },
{ b6[0], b6[1], b6[2] } ,
{ b7[0], b7[1], b7[2] },
{ b8[0], b8[1], b8[2] },
{ b9[0], b9[1], b9[2] } ,
{ b10[0], b10[1], b10[2] },
{ b11[0], b11[1], b11[2] },
{ b12[0], b12[1], b12[2] }
};
// Setup the Ethernet Shield MAC Address, ip and MQTT Server address
byte mac[] = { 0x90, 0xA6, 0xDA, 0x12, 0x21, 0x81 }; // Your Arduino Ethernet Shield MAC address
byte server[] = { 192, 168, 1, 102 }; // Your MQTT Server
byte ip[] = { 192, 168, 1, 207 }; //
// Function to set the RGB LED
void setColour (int sColours[]) {
Serial.print("SetColour - R:" );
Serial.print(sColours[0]);
Serial.print(" G:" );
Serial.print(sColours[1]);
Serial.print(" B:" );
Serial.println(sColours[2]);
analogWrite(RED_LED_PIN, sColours[0]);
analogWrite(GREEN_LED_PIN, sColours[1]);
analogWrite(BLUE_LED_PIN, sColours[2]);
}
void callback(char* topic, byte* payload, unsigned int length) {
// handle message arrived
// print the results to the serial monitor:
Serial.print("Topic = " );
Serial.print(topic);
Serial.print("\t Length = ");
Serial.println("Length: " + String(length,DEC));
int i = 0;
for(i=0; i<length; i++) {
message_buff[i] = payload[i];
}
message_buff[i] = '\0';
String msgString = String(message_buff);
Serial.println("Payload: " + msgString);
// See if it's what we are after
if (topic = "weather/merewether/channel/wind_speed") {
// Calculate the beaufort scale (roughly)
int x = msgString.toInt();
int bScale=round(pow(x/3.01,0.66667));
Serial.print("Beaufort Scale is = ");
Serial.println(bScale);
setColour(bScaleColours[bScale]);
}
}
PubSubClient client(server, 1883, callback);
void setup()
{
// initialize serial communications at 9600 bps:
Serial.begin(9600);
Serial.print("Starting ..." );
Serial.print("Colour Array Size is = ");
Serial.println(ARRAYSIZE);
// Some startup Blinking
setColour(none);
delay(1000);
setColour(red);
delay(1000);
setColour(blue);
delay(1000);
setColour(lime);
delay(1000);
// Lets flick through the Beaufort Scale colours as well
int i = 0;
for (i = 0; i < ARRAYSIZE; i +=1) {
Serial.println(i);
setColour(bScaleColours[i]);
delay(100);
}
setColour(lime);
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// DHCP failed, so use a fixed IP address:
Ethernet.begin(mac, ip);
}
if (client.connect("arduinoClient")) {
client.publish("arduino/beaufortreporter/state","1");
// Now subscribe to the wine speed feed. Technically for the Beaufort Scale I think you should use
// 10 minute gust values rather than raw speed but for me it doesn't change quick enough :-)
client.subscribe("weather/merewether/channel/wind_speed");
}
}
void loop()
{
client.loop();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment