Phillips Hue control from Arduino Nano IoT

This week I was able to get my Arduino Nano 33 IoT board to connect to the IP of the HUE hub on the ITP floor. In the video uploaded below you can see the code being sent from my computer to the IP.

The code is uploaded to GitHub and posted in the bottom of this, but you have to include a file called arduino_secrets.h file (add a new tab, call it “arduino_secrets.h”) and add the following defines, and change to your own values:

#define SECRET_SSID “ssid” // your own 2.4G home network name
#define SECRET_PASS “password” // your wifi password
char hueHubIP[] = “000.000.000.000”; // IP address of your hue bridge
String hueUserName = “averylongstringofnumbersandletters”; // the user name you got from your hue bridge

https://github.com/louiselessel/Lightandinteractivity/tree/master/Hue

The code is based on the examples from Tom Igoe here:

https://github.com/tigoe/hue-control

I changed the code so it is possible to write more commands to one string, by creating a packageRequest method, before sending the string to the hub with sendRequest from Tom’s code. I also edited this, so it only adds the necessary put request and the “{ }” around the json. You still need to specify the light there.

My code is split into a packageRequest and a sendRequest function. Tom’s code did all operations in the sendRequest, and therefore couldn’t include both a change in hue and brightness simultaneously.
This is the Arduino Nano 33 IoT sending the commands.

In order to make this code, I first tried to just send multiple sendRequests at a time with a 4 seconds delay – It is very important not to flood the network or you might get banned by the provider, because it looks like an attack. It does work, but I didn’t like this method because I will probably want to adjust more than one parameter at the same time, and it is always better to send fewer commands on a network regardless. So that’s why I wrote the code above to collect all the commends into one string before making the PUT request.

Tom already has examples that use the json library to package it similarly, but that code was not as easy to understand. So maybe my classmates will find my code example useful.


To debug my connection – and find out which light is which (Right-click and use the inspect -> console) – I used this p5 client-example also written by Tom Igoe. You have to input your IP and username and the code will allow you to control your own Hue bulbs from the p5 sketch.

Inspected items after sending requests, and watching live cam changes.

I helped Tom set up all the bulbs on the ITP floor following his description here https://github.com/tigoe/hue-control, so they are ready for this type of control, so I have been using this tool for debugging quite a lot.

If you wanna try on your own Hue hub at home, follow that last link^.

Next step will be doing the same, but to a dmx setup. I have always loved network programming, so I am happy that the course is verging more in that direction due to Covid.

Then I will build a small controller that’ll work for either one I think.

I am also super exited to finally get my Arduino Nano to connect to wifi. I have always been using Arduino Uno’s or Teensy. And I want to use a wifi enabled board for my thesis, so this is exiting.


Code for the Hue control

/* Based on
   HueBlink example for ArduinoHttpClient library

   Uses ArduinoHttpClient library to control Philips Hue
   For more on Hue developer API see http://developer.meethue.com
   For more on the ArduinoHttpClient, install the library from the
   Library Manager.

  To control a light, the Hue expects a HTTP PUT request to:

  http://hue.hub.address/api/hueUserName/lights/lightNumber/state

  The body of the PUT request looks like this:
  {"on": true} or {"on":false}

  This example  shows how to concatenate Strings to assemble the
  PUT request and the body of the request.

  note: WiFi SSID and password are stored in arduino_secrets.h file.
  If it is not present, add a new tab, call it "arduino_secrets.h"
  and add the following defines, and change to your own values:

  #define SECRET_SSID "ssid"
  #define SECRET_PASS "password"
  char hueHubIP[] = "000.000.000.000";  // IP address of your hue bridge
  String hueUserName = "averylongstringofnumbersandletters"; // the user name you got from your hue bridge

   modified 6 Jan 2018
   by Tom Igoe (tigoe)
   https://github.com/tigoe/hue-control/tree/master/ArduinoExamples

   modified 6 April 2020
   by Louise Lessél
   Note: This code allows you to package all the hue bulb commands into one json string
   before sending it.
*/

#include <SPI.h>
//#include <WiFi101.h>
#include <WiFiNINA.h>
#include <ArduinoHttpClient.h>
#include "arduino_secrets.h"

// ------ WIFI

int status = WL_IDLE_STATUS;      // the Wifi radio's status

// make a wifi instance and a HttpClient instance:
WiFiClient wifi;
HttpClient httpClient = HttpClient(wifi, hueHubIP);
// change the values of these two in the arduino_serets.h file:
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;

// ------ GLOBAL VARIABLES
// variables for including multiple commands to hue in the json http request
int multipleItems = 0;
String phueCmd = "";


void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial); // wait for serial port to connect.

  // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);
  }

  // you're connected now, so print out the data:
  Serial.print("You're connected to the network IP = ");
  IPAddress ip = WiFi.localIP();
  Serial.println(ip);
}


void loop() {

  // package to 2 part json
  int hueColor = random(0, 65535); // give random color
  packageRequest("hue", String(hueColor));
  packageRequest("on", "true");   // turn light on

  // send request to hue
  sendRequest(10, phueCmd);
  delay(4000);

  // package only one command and send request to hue
  packageRequest("on", "false");   // turn light off
  sendRequest(10, phueCmd);
  delay(4000);
}


void packageRequest(String cmd, String value) {
  // if this is the first call
  if (multipleItems < 1) {
    // make a string for the JSON command:
    phueCmd = "\"" + cmd;
    phueCmd += "\":";
    phueCmd += value;
  } else {
    // if this is the second call or more
    phueCmd += ",";
    phueCmd += "\"" + cmd;
    phueCmd += "\":";
    phueCmd += value;
  }

  // see what you assembled to send:
  Serial.print("packaged: ");
  Serial.println(phueCmd);

  // increment so we know packageRequest has been called before (this controls using the comma in json string)
  multipleItems++;
}


void sendRequest(int light, String packagedRequest) {
  // make a String for the HTTP request path:
  String request = "/api/" + hueUserName;
  request += "/lights/";
  request += light;
  request += "/state/";

  String contentType = "application/json";

  // make a string for the JSON command:
  String hueCmd = "{" + packagedRequest;
  hueCmd += "}";

  // see what you assembled to send:
  //Serial.print("PUT request to server: ");
  //Serial.println(request);
  Serial.print("JSON command to server: ");


  // make the PUT request to the hub:
  httpClient.put(request, contentType, hueCmd);

  // read the status code and body of the response
  int statusCode = httpClient.responseStatusCode();
  String response = httpClient.responseBody();

  Serial.println(hueCmd);
  Serial.print("Status code from server: ");
  Serial.println(statusCode);
  Serial.print("Server response: ");
  Serial.println(response);
  Serial.println();

  // reset variables
  multipleItems = 0;
}