Color Sphere With Arduino

670

15

3

Published

Introduction: Color Sphere With Arduino

About: Always learning.....

Greetings technology and Arduino enthusiast. I wanted to share a project I have been working on using a Neopixel LED strip and a ADXL335 3-axis accelerometer. I would consider this project to be medium level and you will want to be familiar with some basics of coding with Arduino and C++. That being said I broke this Instructable down into parts where you could learn just the ADXL335 or just the Neopixel Strip individually. There is also a lot of room to expand on this project to make it way more advanced for experienced users. Once you start mixing and matching different Arduino projects and editing other peoples code, you see how much deeper your coding experience will be. Maybe you want to use the accelerometer for a different purpose, or you see another clever way to use the LED Strip. Please feel free to pick and choose where you would like to grow and learn.

Step 1: Parts and Equipment

Arduino Uno - $12.00 (reusable)

The brain behind this operation will be an Arduino Uno. There are many different models to choose from but most have the same basics. you will want to get yourself one and the appropriate USB cable to get started with for this project and future ones.

ADXL335 Accelerometer - $15.00 (reusable)

The first major component of this project is the 3-axis accelerometer. It is a small piece and it may require you to solder on the pins at first. There are also accelerometers with the pins already soldered in place so look around for what you would like. This can also be used for other projects as you build your collection of sensors and components.

Addressable RGB LED Strip - $7.00 (30 LED reusable)

LED Strips are very popular and can be found all over in different shapes and sizes. I previously bought a strip containing 144 LED's on one strip and I cut it down into lengths I need for each project. The cost changes depending on how long the strip is, how many LED's there are per meter of strip, and other features like Water proofing. I have 30 LED's crammed into this hamster ball which we will cover in the Neopixel section.

Batterey Pack (4 x AA)- $5.00 (reusable)

This will be covered later when we talk about powering the LED strip. It will depend on how many LED's you plan on powering. I wanted a finish product that could roll around and be portable. If you are only making a prototype to practice and learn, you could get away with out an actual battery pack. Your project would jest need to be connected to a different power source like a computer or power adapter.

Jumper Wires (3 minimum)- $6.00 (multipack, semi-reusable)

Jumper wires are basically reusable wires for Arduino and bredboards. It allows you to plug and unplug the wires simply as a opposed to permanently soldering them. The pack above contains male/male, male/female and female/female wires (males have and outty, girls have and inny). This is more than you need but they are good to have and do tend to break eventually. The LED strip needs 3 wires to get up and running. The ADXL335 needs 5 wires to get set up but in this example I soldered pin headers instead and then found a nice spot to plug it in directly on the Arduino.

Hamster Ball (5 inches minimum) - $5.00(optional)

The hamster ball is what will hold everything together. I wanted a clear round object and hamster ball seemed to fit the bill. The one shown in the link is just big enough to house the Arduino, battery pack, and the LED strip. I think i would even go bigger so I have more room to get my hands in there. If you are just testing out the LED strip and/or the ADXL335 then this may be optional for you.

overall the cost of this project is around $40-$50 if you are starting from ground zero. If you have used Arduino before many of the items should already be in your possession. Add in the idea that almost all of these components are reusable and great for other projects the cost goes way down compared to the value. There are also great Arduino kits that come with most of the basics bundled together.

Step 2: ADXL335 3-Axis Accelerometer

Adafruit link for ADXL335

Global Variables

Global variables are written above the void setup() section of our code. This is a common spot to declare variables for the rest of the code. This is also the spot to name the pins that will be connected to the ADXL335 Accelerometer. "const int" stands for constant integer and should appear blue in the code. Integers are whole numbers and constant means this whole number will not be changing. after "const int" I put the name of the variable. groundPin, powerPin, xPin... are names I created so I can keep track of what pin on the arduino is connected to which pin on the accelerometer. After that we want to set that variable equal= to the corresponding pin number. The attached image of an Arduino Uno shows all the different pin numbers. pin# 15-19 corresponds to analog pins A1-A5. "const int groundPin = A5; " would also be acceptable. This line of code all together means when ever I write groundPin, replace it with the number 19. I also declared three more variables as int variables. these are integer variables also but they are not constant, they can change throughout the code. These variables are going to be used to store the x, y, and z values as the ADXL moves around

const int groundPin = 19;          
const int powerPin = 18;              
const int xPin = 17;                  
const int yPin = 16;                  
const int zPin = 15;
int xVal = 0;
int yVal = 0;
int zVal = 0;

void setup()

The void setup() section of a sketch is used for activating the general INPUT/OUTPUT pins (GPIO) and for parts of our code that we need to set up once before going into our void loop(). The void setup() only runs one time when the arduino is first turned on. Looking back to my void setup() it may seem odd that I am using pin 18 and 19 as my ground and power pins. If you look into the void setup() you can see I am going to activate 18 and 19 as OUTPUTS and digitalWrite 18 to HIGH and 19 to LOW. HIGH and LOW correspond to 5Volts and 0Volts. The purpose of this is to make 18 my powerpin and 19 my groundpin. I know there are many other %v and GND pins on the Arduino but can you see how neatly the ADXL335 fits now. This saves me extra jumper wires and gets rid of the need for a bread board. Finally I activated the Serial monitor using Serial.begin(9600); this will let us see the values that the accelerometer is reading for x, y, and z later on.

void setup() {
pinMode(groundPin,OUTPUT);
pinMode(powerPin,OUTPUT);

digitalWrite(groundPin,LOW);
digitalWrite(powerPin,HIGH);

Serial.begin(9600);
}

void loop()

The final section of our code is the void loop(). This section runs from top to bottom and then repeats continually as long as the Arduino has power. In this section we will constantly read the 3 axiss'ss of the accelerometer and print it to the Serial monitor for us to see. The first line of code shows us analog reading the xPin (pin 17 or A3) and saving that value in the variable xVal. analogRead is used to check the voltages coming into an analog pin. It will return a value between 0 and 1023 which corresponds to voltages of 0 - 5 volts. This is more detailed and gives us a range of values as opposed to digitalRead which only reads 0 OR 1023 which is 0 OR 5volts. digitalRead is more useful for something like a button which is either on or off. For this ADXL we dont want to know how much we are tilted towards x, y or z so we want to analogRead. In order to work with these numbers we should print these newly saved values to the serial monitor. Serial.print(xVal) will write on my serial monitor what ever xVal is equal to that time through the loop. Serial.Println means write on the serial monitor and then skip a line. My first suggestion would be only Serial.print one of the variables at a time so you can see clearly. You can also experiment with where to put the "ln" to see how that changes the look of the serial monitor. Idealy you want to see each value in its own scrolling column with labels and nice spaces.

void loop(){
xVal = analogRead(xPin);
yVal = analogRead(yPin);
zVal = analogRead(zPin);

Serial.print(xVal);
Serial.print(yVal);
Serial.println(zVal);
}

That is a completed sketch for the ADXL335 accelerometer. You now have a tilt sensor that can give you values for how much you are titled in each direction. This can be the fin comes when you start thinking of all the cool things you can do in response to this tilt. With this major section of my project completed and bug free I can now look to combine this with the RGB Strip.

Step 3: Neopixel Adressable RGB LED Strip

The next step in this project is to get our RGB strip up and running. This involves practicing and learning about the neopixel strip and neopixel library. Projects with multiple components should usually be tested individually first. Get a good understanding of each part of a project before combining them and you will save a lot of trouble later. This Adafruit Uber Guide was a great place to start for me. All the material is in one location so you wont need to bounce around the internet trying to match different codes. The strand Test example built into the neopixel library shows several types of patterns with interesting coding behind them. Trying to decode how each effect is made was an enjoyable way to get more experience with coding for me. The video shows a Strip of RGB LED cycling through several paterns

Solder Wires to Strip

Depending on which strip of LEDs you buy, you may need to solder wires to the end. A brand new strand usually comes with wires attached but this particular spool has been used before. You can cut the strip along the copper connections shown above. I put dabs of solder on those copper tabs and then soldered male jumper wires to them. You can see in the picture above that the ground (GND), power (5V), and digital (D0) conections now have usable wires attached to them. I am not the worlds greatest soldererer....yet. I do find it a fun part of most projects, little action in the middle of a long story. get it down how ever you can just make sure none of the three connections get soldered to each other. Stick with that rule and you will be find for the most part.

How Many Neopixels?

Each individual Neopixel on the strip draws its own energy. Most of the bugs related to RGB strips have been related to the amount of current supplied to the strip. while one Neopixel or a few can be run fairly easily, sometimes I have close to 150 running at one time. If there is not enough current to run each neopixel and the arduino microcontroller, you will be to see some funky effects. Some times the arduino will shut itself off because there isn't enough power. Other times the colors will change towards the end of the strip as it runs out of power. you will actually notice some colors take way more energy than other colors. This is part of the fun of tinkering with something new. The same Adafruit Uber Guide from earlier breaks down in detail how much power you will need. I have about 30 LEDs on my strip now and it almost always works. I would do somewhere between 10 and 20 LEDs to be safe.

Important Code

Above the void setup() there needs to be a few lines of code to properly use the strip and libraries. you will need to include the adafruit_neopixel library and enter some parameters using the lines of code below. If the library is installed correctly it should turn orange. Make sure the PIN number matches up with the pin you connect the strip to the arduino with. This example uses pin D6. The first parameter is the number of leds on your particualr strip. When you 30 infront of the PIN that means I have 30 individual RGB LED to control. Adjust this number to match your strip.

#include <Adafruit_NeoPixel.h>
#define PIN 6 Adafruit_NeoPixel strip = Adafruit_NeoPixel(30, PIN, NEO_GRB + NEO_KHZ2800);

In the void setup() you need only two lines of code. These lines turn on the strip and then set all the LEDs off untill we change that in the void loop(). As you can see in the strand test example, there are seemingly countless possibilities and combinations of collors and effects you can use for the NeoPixel strip. I choose to take the color wipe function from that example code and use it for the color sphere. At the bottom of the code there is now a new function used to change the color of all the LEDs. If you write colorWipe in your loop it will then call the colorWipe function written bellow. you need to enter some info so it knows how to do this. After writing colorWipe(strip.Color( you need to enter the color you want and how long to wait between changing the color of the next pixel. The first three numbers set the color we want. The order is (red,green,blue) and the numbers can be between 0 and 255. 255 would be make brightness and 0 would be basically off. The fourth number after that is the delay. The loop below allows the strip to change each LED to red with a 50 millisecond delay between then turn them all to green and finally turning them all to blue.

void setup(){ 
     strip.begin(); 
     strip.show(); 
}

void loop(){
 colorWipe(strip.Color(255,0,0),50);
 colorWipe(strip.Color(0,255,0),50);
 colorWipe(strip.Color(0,0,255),50);
} void colorWipe(unit32_t c, uint8_t wait{ for (uint16_t i = 0; i < strip.numPixels(); i++){ strip.setPixelColor(i,c); strip.show(); delay(wait); } }

Step 4: Mashing the Codes Together

This is the time to bring it all together. Be careful when trying to mix coded together, do more than simply cut and paste one after another. The general rule should be everything above the void setup() should go together, everything in the void setup() should be together and then everything in the void loop should be but in a logical order. The only real addition in this code is the if statements that control which color to make the ball as it is moved. There are endless ways to change the color and I plan to continuing to search for more innovative ways. This example makes the ball red when The xVal is bigger than both the yVal and zVal. It turns green when yVal is the most and blue when zVal. The human way to read the first if statement ..... If xVal is greater than yVal and zVal, Then change the strip to red. If ("this is true") {then do everything in between here } This is the final code for the complete project but please feel free to get more creative with it. There is also added code so we can see the x y and z values. That is done using the Serial.print(); function. The way its written will show all three values with a tab between them so there is three nice columns

#include <Adafruit_NeoPixel.h>
#define PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(30, PIN, NEO_GRB + NEOKHZ800);

const int groundPin = 19;
const int powerPin = 18;
const int xPin = A3;
const int yPin = A2;
const int zpin = A1;

int xVal = 0;
int yVal = 0;
int zVal = 0;

void setup (){
Serial.begin(9600);
strip.begin();
strip.show();
pinMode(grounPin,OUTPUT);
pinMode(powerPin, OUTPUT);
digitalWrite(groundPin,LOW);
digitalWrite(powerPin,HIGH);
}

void loop(){
xVal = analogRead(xPin);
yVal = analogRead(yPin);
zVal = analogRead(zPin);

Serial.print(xVal);
Serial.print("\t");
Serial.print(yVal);
Serial.print("\t");
Serial.println(zVal);


if (xVal > yVal && xVal > zVal){
	colorWipe(strip.color(255,0,0),50);
}

if (yVal > xVal && yVal> zVal){
	colorWipe(strip.Color(0,255,0),50);
}

if (zVal > xVal && zVal > yVal){
	colorWipe(strip.Color(0,0,255),50);
}


void colorWipe(uint32_t c, uint8_t wait){
	for(uint16_t i = 0; i < strip.numPixels(); i++){
		strip.setPixelColor(i,c);
		strip.show();
		delay(wait);
	}
}

Share

    Recommendations

    • Oil Contest

      Oil Contest
    • Water Contest

      Water Contest
    • Creative Misuse Contest

      Creative Misuse Contest

    3 Discussions

    best instructable ever written

    Great Job. You must be one hell of a teacher...