Introduction: Color Changing Night Light Using Ardruino 101

In this project you wil be making a night lamp using ardruino, Adafruit neo rgb Strips and a 3D printer.

Note that this intructable is purely for my school project. The code for this project is based from a other project. With that said i'm not a expert when it comes to Ardruino.

Step 1: Requirements

For this project wou wil need the following hardware and tools


1 - A ardruino101 (in US) or a Genuino101 (for outside the US).

2 - NeoPixel rgb led strips from adafruit (5 volt).

3 - A ardruino usb connector (type B to A connector).

4 - A software from Ardruino, Ardruino IDE In this tutorial we wil be using the 1.8.5 version. Software library requirements are: 101, Adafruit NeoPixel and Madgwick.

5 -And a object to house your hardware. In this case I will be using a 3D printer. The file for this 3D print is located in the descriptions called "Lamp Head". Note that this file format is not 3D print ready. Depending on your 3D printers you must first run the designated 3d print software on the 3D object beforehand. Sometimes the scale of the 3D print will reset. so make sure the diameter is set to 11 cm by 11 cm.

6 - Basic soldering kit.

Step 2: Understanding the Hardware and Software


Just to clarify Ardruino101 and genuino101 are exacly the same beside the names. Both have the same specs and use the same software.

Ardruino101 possess the basic specs like the ardruino UNO and more. The main feature of ardruino101 is the accelerometer and gyroscope wich we wil be using in our project. Also this type of ardruino have it's unique code library called CurrieIMU (Internal measurement Units) which is included in the library extension 101.

With that said lets talk about the software.

-Software and libraries

Ardruino IDE uses python as it's main source code. it's also the main code platvorm where most ardruino runs. There are plenty of tutorials online on how to use this software so I recomend you research those first if you are new to this programe.

With that said the libraries we be using are the following:

From the Sketch menu, > Include Library > Manage Libraries... In the text input box type in

- 101 At standart the ardruino 101 is not automaticly included onto the ardruino IDE. We need this library extension in order to code our ardruino type.

-Adafruit NeoPixel in order to code our Neo pixel strips.

-Madgwick In order to read the raw data and to calculate this data to raw, pitch and roll.

-Neo RGB strips

The type I wil be using is a 5 voltage or 5v type. With this 5v i dont need a extended power source to control my strips. Instead I wil be using my ardruino as the power source to control and light up the strips.

Here are some tips you need to know before you get started on this strips.

First you wil need a Neodigital RGB led strips from adafruit. This kind of strips is cotrolable using codes. Next you need to know is that there is a backside and a frontside on this strips. This back and frontside is important for the soldering. Make sure you solder the front side where the arrow key is pointing away from the tip.

Here is a guide on how to use them.

There are 3 solder point you need to keep in mind Ground connection(GND), Voltage connection(V) and Pin connection(DIN).

Step 3: Setting Up the Components

First you wil need to 3d print the component which you can find in the requirements. In this case I wil be using PLA. Make sure the diameter of the overal object is 11cm by 11cm. This wil ensure that the ardruino and the strips wil fit in the shpere. Note that each 3D printer uses difrent softwares to calculate it's printing process. With that said the file you use might be scaled difrently so keep that in mind.


Second after the print make sure the components is able to close. The 3D prints together make up a sphere. They should fit nicely. If the componten is to lose then ad some tape to the inner side so the cap is filled. And if it is to thick use sandpaper.

Third the skematichs for the ardruino and the strips are is fairly easy. You wil be using 3 wires to connect the strips to the ardruino. Note that the only places i solder is on the strips. not on the Ardruino itself.

GND goes to GND

DIN goes to a Pin (in our case pin6 on the ardruino)

5V goes to 5V

Make sure the amount of led strips you use is cap at 30. Anymore then that and it will fail to properly execute the code. You can simply cut of any uneeded strips displayd with a scissor sign.

Fourth Evrything should fit nicely in the sphere. You could like I did make an intersection between 1 of the 3d print in order to see trough and place a see trough plastic on the top.

Step 4: Coding

So by now you should have all the components needed in your library.

Here is the code you wil need in order to run the project. The result should look like the video link I send in this page.

The source of this code can be found here. This project also include the necercarly steps in order to better understand the code and algaritme behind the uses.

#include #include #include

#define PIN 6 // 11 pixels NeoPixel Strip #define PIN1 7 // 1 pixel NeoPixel Strip #define NUMPIXELS 30 // Numer of píxels #define SAMPLE_RATE 25 // Sampling rate for accelerometer and gyroscope

// Madgwick configuration Madgwick filter; unsigned long microsPerReading, microsPrevious; float accelScale, gyroScale;

// NeoPixel configuration Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); Adafruit_NeoPixel pixelsStatus = Adafruit_NeoPixel(1, 7, NEO_GRB + NEO_KHZ800);

// Color spaces RGBConverter rgbConverter; double h = 1; double s = 1; double v = 1; byte rgb[3];

// Status Motion Lamp // State 0 -> Select Hue - Pitch // State 1 -> Select Saturation - Roll // State 2 -> Select Value - Yaw // State 3 -> Fix color volatile int statusLamp = 0;

void setup() { Serial.begin(9600);

// start the IMU and filter CurieIMU.begin(); CurieIMU.setGyroRate(SAMPLE_RATE); CurieIMU.setAccelerometerRate(SAMPLE_RATE); filter.begin(SAMPLE_RATE);

// Set the accelerometer range to 2G CurieIMU.setAccelerometerRange(2); // Set the gyroscope range to 250 degrees/second CurieIMU.setGyroRange(250);

CurieIMU.autoCalibrateAccelerometerOffset(X_AXIS, 0); CurieIMU.autoCalibrateAccelerometerOffset(Y_AXIS, 0); CurieIMU.autoCalibrateAccelerometerOffset(Z_AXIS, 1); CurieIMU.autoCalibrateGyroOffset();

CurieIMU.attachInterrupt(eventCallback); CurieIMU.setDetectionThreshold(CURIE_IMU_TAP, 950); CurieIMU.interrupts(CURIE_IMU_TAP);

// initialize variables to pace updates to correct rate microsPerReading = 1000000 / SAMPLE_RATE; microsPrevious = micros();

// Init NeoPixel 11 pixels.begin();;

// Init NeoPixel 1 pixelsStatus.begin();;

// Show status in px setStatusPixel(statusLamp); }

void loop() { int aix, aiy, aiz; //accelerometer int gix, giy, giz; float ax, ay, az; float gx, gy, gz; float roll, pitch, yaw; static unsigned long microsNow;

// check if it's time to read data and update the filter microsNow = micros(); if (microsNow - microsPrevious >= microsPerReading) {

// read raw data from CurieIMU CurieIMU.readMotionSensor(aix, aiy, aiz, gix, giy, giz);

// convert from raw data to gravity and degrees/second units ax = convertRawAcceleration(aix); ay = convertRawAcceleration(aiy); az = convertRawAcceleration(aiz); gx = convertRawGyro(gix); gy = convertRawGyro(giy); gz = convertRawGyro(giz);

// update the filter, which computes orientation filter.updateIMU(gx, gy, gz, ax, ay, az);

// print the heading, pitch and roll roll = filter.getRoll(); pitch = filter.getPitch(); yaw = filter.getYaw();

// increment previous time, so we keep proper pace microsPrevious = microsPrevious + microsPerReading;

// Only if change Hue, Saturation or Value if (statusLamp < 3) { // pitch only -90º to 90º = 180º // State 0 -> select Hue if (pitch >= -90 && pitch <= 90 && statusLamp == 0) { // Transform angle pitch = pitch + 90; // Obtains color cordinates from angles h = pitch / 180.0; }

// Angles restrictions // roll only -90º to 90º = 180º // State 1 -> select Saturation if (roll >= -90 && roll <= 90 && statusLamp == 1) { // Transform angle roll = roll + 90; // Obtains color cordinates from angles s = roll / 180.0; }

// State 2 -> select Value if (statusLamp == 2) { // yaw 0º to 360º v = yaw / 360.0; }

// Convert to rgb rgbConverter.hsvToRgb(h, s, v, rgb); /* Serial.print("Color: "); Serial.print(h); Serial.print(" - "); Serial.print(s); Serial.print(" - "); Serial.print(v); Serial.println(" ");

Serial.print("Orientation: "); Serial.print(yaw); Serial.print(" "); Serial.print(pitch); Serial.print(" "); Serial.println(roll); */

// Change color of the pixels for (int px = 0; px < NUMPIXELS; px++) { pixels.setPixelColor(px, pixels.Color(rgb[0], rgb[1], rgb[2]));; } }

// Show status in px setStatusPixel(statusLamp); } }

float convertRawAcceleration(int aRaw) { // since we are using 2G range // -2g maps to a raw value of -32768 // +2g maps to a raw value of 32767

float a = (aRaw * 2.0) / 32768.0; return a; }

float convertRawGyro(int gRaw) { // since we are using 250 degrees/seconds range // -250 maps to a raw value of -32768 // +250 maps to a raw value of 32767

float g = (gRaw * 250.0) / 32768.0; return g; }

static void eventCallback() { // Detect tap in all axis if (CurieIMU.getInterruptStatus(CURIE_IMU_TAP)) { Serial.print("Tap detected statusLamp: "); Serial.println(statusLamp);

// Change state statusLamp++;

// Init state if (statusLamp > 3) { statusLamp = 0; } } }

void setStatusPixel(int statusPx) { switch (statusPx) { case 0: pixelsStatus.setPixelColor(0, pixelsStatus.Color(150, 0, 0));; break; case 1: pixelsStatus.setPixelColor(0, pixelsStatus.Color(0, 150, 0));; break; case 2: pixelsStatus.setPixelColor(0, pixelsStatus.Color(0, 0, 150));; break; case 3: pixelsStatus.setPixelColor(0, pixelsStatus.Color(0, 0, 0));; break;

} }