We're going to take a walk through the code, load it onto our Feather Huzzah, and interact with it using the Adafruit IO Dashboard we made earlier. 

The code assumes the NeoPixel strip is connected to the Feather Huzzah's digital pin 2 and the NeoPixel jewel is connected to digital pin 16. Both of these pins can be changed by modifying the STRIP_PIN and JEWEL_PIN variables at the beginning of the code.

The code initializes the NeoPixel strip, NeoPixel jewel and the Si7021 sensor objects. It also sets up feeds for the outdoor lights, indoor lights, humidity, and temperature.

// initalize neopixel strip
Adafruit_NeoPixel strip = Adafruit_NeoPixel(STRIP_PIXEL_COUNT, STRIP_PIN, PIXEL_TYPE);
// initalize neopixel jewel
Adafruit_NeoPixel jewel = Adafruit_NeoPixel(JEWEL_PIXEL_COUNT, JEWEL_PIN, PIXEL_TYPE);

// initalize the sensor object
Adafruit_Si7021 sensor = Adafruit_Si7021();

// set up the Adafruit IO feeds
AdafruitIO_Feed *indoorLights = io.feed("indoor-lights");
AdafruitIO_Feed *outdoorLights = io.feed("outdoor-lights");
AdafruitIO_Feed *humidity = io.feed("humidity");
AdafruitIO_Feed *temperature = io.feed("temperature");

The next chunk of code within setup() connects to Adafruit IO, registers two messages handlers to subscribe to the indoorLights and outdoorLights feeds. We also initialize the Si7021 sensor, NeoPixel strip, and NeoPixel jewel. Then, we set all NeoPixels in the house to `off`. 

void setup() {

  // start the serial connection
  Serial.begin(115200);

  // wait for serial monitor to open
  while(! Serial);

  // connect to io.adafruit.com
  Serial.print("Connecting to Adafruit IO");
  io.connect();

  // subscribe to lighting feeds and register message handlers
  indoorLights->onMessage(indoorLightHandler);
  outdoorLights->onMessage(outdoorLightHandler);


  // wait for a connection
  while(io.status() < AIO_CONNECTED) {
    Serial.print(".");
    delay(500);
  }

  // we are connected
  Serial.println();
  Serial.println(io.statusText());

  // initalize the Si7021 sensor
  if (!sensor.begin()) {
    Serial.println("Did not find Si7021 sensor!");
    while (true);
  }
  Serial.println("Si7021 sensor set up!");
  
  // initalize the neopixel strip and jewel.
  strip.begin();
  jewel.begin();

  // set all neopixels on the strip and jewel to `off`.
  strip.show();
  jewel.show();
}

The next chunk of code is the main loop(). First, we call io.run(), which keeps the client connected to Adafruit IO. Then, we query the Si7021 for temperature and humidity values and print them to the Serial Monitor.

The code sends the feeds to Adafruit IO by saving the individual feeds to the data obtained. Finally, it delays the loop by TEMP_DELAY seconds to avoid flooding Adafruit IO with requests - you only get so many requests within a certain time period.

void loop() {
  io.run();

  temperatureData = sensor.readTemperature() * 1.8 + 32;
  humidityData = sensor.readHumidity();
  
  Serial.print("-> Sending Temperature to Adafruit IO: ");
  Serial.println(temperatureData);
  Serial.print("-> Sending Humidity to Adafruit IO: ");
  Serial.println(humidityData);

  // send the state of the feed to adafruit io
  temperature->save(temperatureData);
  humidity->save(humidityData);
  
  // delay the loop to avoid flooding Adafruit IO
  delay(1000*TEMP_DELAY);
}

The code uses have two separate message handlers: one for the outdoor lights and one for the indoor house light. Both of these functions operate in a similar fashion - whenever a message from either the humidity or temperature feed is received from Adafruit IO, the function is called. The function prints out the data value from the Adafruit IO feed as a hexadecimal value and converts it to a RGB value which the NeoPixel light can display.

Then, it sets the color of each individual pixel in the strip from zero to the _PIXEL_COUNT declared at the top of the file. Finally, it calls strip.show() to set the NeoPixel strip to the new color.

void indoorLightHandler(AdafruitIO_Data *data) {
  Serial.print("-> indoor light HEX: ");
  Serial.println(data->value());

  long color = data->toNeoPixel();

  // set the color of each NeoPixel in the jewel
  for(int i=0; i<JEWEL_PIXEL_COUNT; ++i) {
    jewel.setPixelColor(i, color);
  }
  // 'set' the neopixel jewel to the new color
  jewel.show();
}

Compile the code (Sketch->Verify/Compile) and upload (Sketch->Upload) it to your Feather Huzzah. Open the Serial Monitor (Tools->Serial Monitor) and you should see the following output:

Adafruit IO connected.
Si7021 sensor set up!
-> Sending Temperature to Adafruit IO: 75
-> Sending Humidity to Adafruit IO: 41

Navigate to your IO House's Dashboard. The temperature and humidity gauges should display the values from the Arduino Serial Monitor.

Next, we'll test out the inside and outdoor lights from the dashboard. Click (or tap if you're on mobile) the color picker and select a color to set the lights to. You should see either the outdoor or inside lights change depending on which color picker was selected.

This guide was first published on Aug 27, 2018. It was last updated on Mar 25, 2024.

This page (Arduino Code) was last updated on Mar 08, 2024.

Text editor powered by tinymce.