The Gallatin Garden

Today, we are building a little electronic garden. Each of you will make your own “plant” out of an Arduino and some LEDs, planted in a special pot that has the ability to communicate wirelessly using infrared light (the same process used by most remote controls.)

Materials:

To begin, make sure you have everything you need:

Materials

Please be careful with your components – especially the plant pot and flower stems. Do not remove any of the tape holding them together. If you are curious about how they work, just ask!

The Arduino software:

Arduinos are micro-controllers specially designed for open-source hardware building, consisting of a reprogrammable computer chip with a bunch of extra components all wired up together on a board. They are programmed by a computer via a USB connection, but then, once the code is running, will work independently as long as they have sufficient power. There are lots of types and sizes of micro-controllers designed for general and specific use (ie, for wearables or robotics). Today we are using Arduino Unos – general use, medium-sized boards that don’t require soldering.

You will program the Arduino using the free Arduino software, Arduino IDE, available either as a web or desktop application. I recommend using the online Arduino Web Editor, which will require that you make an account on their website. If you would prefer not to do this, you can download the desktop version. This will require that you install drivers, if you are using a Windows based machine, and also that you manually install a library (more on this later.)

Once you have your chosen version of the IDE working, follow these instructions to get your Arduino UNO set up and upload and run your first program, or “sketch.”

Installing a Library

Skip this step if you are using the Arduino Web Editor.

In order to run today’s code, you are going to need to reference another block of code, called a library. (If you are unfamiliar with programming, think of it this way: our code is a research paper, and the library is a set of standard texts we are quoting and referencing.) The desktop IDE requires that you manually install the library. Go to Sketch>Include Library and then choose the top option of the dropdown menu, “Manage Libraries…”

Location of "Manage Libraries" menu option in Arduino IDE.

This will open up the library manager – a list of all available libraries. Search for “IRremote”, then choose the IRremote library. You will likely get a lot of search results, so make sure you choose the one that is authored by sherrif and has the description “send and receive infrared signals with multiple protocols.” It is the second option from the top in this image (note that I’ve already installed it so in this picture it says “installed” right next to the library in blue letters, yours will not say that yet):

The IRremote library in the library manager.

Click on the appropriate library then click the “Install” button. Now you are all set up!

If for some reason you cannot install this library, flag down one of the people running the workshop and they will help you install it from a .zip file.

Uploading the Gallatin Garden code

Now that your software is set up and communicating with your Arduino, we are going to take a moment to upload the code for today’s project. Click the “New Sketch” button to create a new sketch window (in the desktop IDE, go to File>New). Delete all of the code that appears in the new sketch window. This is important!

Replace it with this code instead. It is a lot of code, so make sure you cut and paste the whole thing:

//IR LED must be attached to pin 3//
//color transmit, 420365f6hex or 1107518966=red, b424ad80 or 3022302592=blue, 5be5ec99 or 1541794969=green
#include <IRremote.h>
//CUSTOMIZE YOUR FLOWER!!//
//Change the values below to change your flower colors and behaviors.
//For the red, blue, and green, find the RGB value of the color you want to use and input the numbers below.
int red = random(256); // red RGB value
int green = random(256);// green RGB value
int blue = random(256);// blue RGB value
int sensitive = true; //Set this to "true" if you want your flower to react a lot to its neighbors, to "false" if you want it to be more robust.
int talkative = true; // Set this to "true" if you want your flower to send information frequently, to "false" if you want it to listen longer.
//End customization.
int RECV_PIN = 11;//IR Receiver Pin
int transmitPin = 2;//transmission indicator pin, for testing
int receiveBluePin = 6;//blue receipt indicator pin
int receiveGreenPin = 5;//green receipt indicator pin
int receiveRedPin = 4;//red receipt indicator pin
int redPin = 12; //RGB lED pins
int greenPin = 10;
int bluePin = 9;
int redCount = 1; // deciding how long to broadcast over IR
int blueCount = 1;
int greenCount = 1;
int redValue = 255 - red;// we use common anode LEDs so the values need to be inverted
int blueValue = 255 - blue;
int greenValue = 255 - green;
int interval = 500;
int shiftAmount = 25; //This controls how much the colors shift. Low numbers = slow, high = fast.
IRsend irsend;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600);
pinMode(transmitPin, OUTPUT);
pinMode(receiveBluePin, OUTPUT);
pinMode(receiveGreenPin, OUTPUT);
pinMode(receiveRedPin, OUTPUT);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
if (talkative == true){
interval = 200;
}
if (sensitive == true){
shiftAmount = 50;
}
Serial.println("Enabling IRin");
irrecv.enableIRIn(); // Start the receiver
Serial.println("Enabled IRin");
}
void loop() {
colorCheck();\
transmitRed(redCount);
delay(interval);
transmitGreen(greenCount);
delay(interval);
transmitBlue(blueCount);
delay(interval);
if (irrecv.decode(&results)) {
Serial.println(results.value);
switch (results.value) {
case 1107518966:
redShift();
setColor();
break;
case 1541794969:
greenShift();
setColor();
break;
case 3022302592:
blueShift();
setColor();
break;
default:
Serial.println("Unreadable Code");
if (sensitive == true){
redValue = redValue - 1;
blueValue = blueValue - 1;
greenValue = greenValue - 1;
setColor();
}
}
irrecv.enableIRIn();
reportData();
}
}
void setColor(){ //push the RGB value to the LED
analogWrite(redPin, constrain(redValue, 0, 255));
analogWrite(greenPin, constrain(greenValue, 0, 255));
analogWrite(bluePin, constrain(blueValue, 0, 255));
}
void reportData(){//print to serial for debugging
Serial.print("red = ");
Serial.print(redValue);
Serial.print(" count = ");
Serial.print(redCount);
Serial.print(" blue = ");
Serial.print(blueValue);
Serial.print(" count = ");
Serial.print(blueCount);
Serial.print(" green = ");
Serial.print(greenValue);
Serial.print(" count = ");
Serial.print(greenCount);
Serial.print("\n");
}
void transmitRed(int redTime){//changes transmit to red for a period of time, then back to receive
digitalWrite(transmitPin, HIGH);//lights up transmit pin for debugging
for (int j = 0; j <redTime; j++){
for (int i = 0; i < 3; i++) {
irsend.sendNEC(0x420365f6, 32);
delay(40);
}
delay(100);
}
digitalWrite(transmitPin, LOW);//turns off debugging pin
irrecv.enableIRIn();
}
void transmitBlue(int blueTime){//changes transmit to blue for a period of time, then back to receive
digitalWrite(transmitPin, HIGH);
for (int j = 0; j <blueTime; j++){
for (int i = 0; i < 3; i++) {
irsend.sendNEC(0xb424ad80, 32);
delay(40);
}
delay(100);
}
digitalWrite(transmitPin, LOW);
irrecv.enableIRIn();
}
void transmitGreen(int greenTime){//changes transmit to green for a period of time, then back to receive
digitalWrite(transmitPin, HIGH);
for (int j = 0; j <greenTime; j++){
for (int i = 0; i < 3; i++) {
irsend.sendNEC(0x5be5ec99, 32);
delay(40);
}
delay(100);
}
digitalWrite(transmitPin, LOW);
irrecv.enableIRIn();
}
void redShift(){ //makes receipt LED red, shifts main RGB LED towards red
digitalWrite(receiveRedPin, LOW);
digitalWrite(receiveBluePin, HIGH);
digitalWrite(receiveGreenPin, HIGH);
redCount = redCount + 1;
if (redValue >= 0){
redValue = redValue - shiftAmount;
}
if (blueValue < 255){
blueValue = blueValue + shiftAmount;
}
if (greenValue < 255){
greenValue = greenValue + shiftAmount;
}
}
void blueShift(){//makes receipt LED blue, shifts main RGB LED towards blue
digitalWrite(receiveBluePin, LOW);
digitalWrite(receiveRedPin, HIGH);
digitalWrite(receiveGreenPin, HIGH);
blueCount = blueCount + 1;
if (blueValue >= 0){
blueValue = blueValue - shiftAmount;
}
if (redValue < 255){
redValue = redValue + shiftAmount;
}
if (greenValue < 255){
greenValue = greenValue + shiftAmount;
}
}
void greenShift(){//makes receipt LED green, shifts main RBG LED towards green
digitalWrite(receiveGreenPin, LOW);
digitalWrite(receiveRedPin, HIGH);
digitalWrite(receiveBluePin, HIGH);
greenCount = greenCount + 1;
if (greenValue >= 0){
greenValue = greenValue - shiftAmount;
}
if (blueValue < 255){
blueValue = blueValue + shiftAmount;
}
if (redValue < 255){
redValue = redValue + shiftAmount;
}
}
void turnOff(){//turns off main RGB LED
redValue = 255;
blueValue = 255;
greenValue = 255;
setColor();
delay(150);
}
void makeRed(){//makes main RGB pure red
redValue = 0;
blueValue = 255;
greenValue = 255;
setColor();
delay(150);
}
void makeBlue(){//makes main RGB LED pure blue
redValue = 255;
blueValue = 0;
greenValue = 255;
setColor();
delay(150);
}
void makeGreen(){//makes main RGB LED pure green
redValue = 255;
blueValue = 255;
greenValue = 0;
setColor();
delay(150);
}
void makeWhite(){//main main RGB LED white
redValue = 100;
blueValue = 100;
greenValue = 100;
setColor();
delay(150);
}
void colorCheck(){
if (redCount >= 10){
for (int k = 0; k < 5; k++){
turnOff();
makeRed();
}
runRainbow();
runRainbow();
redCount = 0;
}
else if (greenCount >= 10){
for (int k = 0; k < 5; k++){
turnOff();
makeGreen();
}
runRainbow();
runRainbow();
greenCount = 0;
}
else if (blueCount >= 10){
for (int k = 0; k < 5; k++){
turnOff();
makeBlue();
}
runRainbow();
runRainbow();
blueCount = 0;
}
}
void runRainbow() {
unsigned int rgbColour[3];
rgbColour[0] = 255; // Start off with red.
rgbColour[1] = 0;
rgbColour[2] = 0;
for (int decColour = 0; decColour < 3; decColour += 1) { // Choose the colours to increment and decrement.
int incColour = decColour == 2 ? 0 : decColour + 1;
for(int i = 0; i < 255; i += 1) { // cross-fade the two colours.
rgbColour[decColour] -= 1;
rgbColour[incColour] += 1;
setColourRgb(rgbColour[0], rgbColour[1], rgbColour[2]);
delay(10);
}
}
}
void setColourRgb(unsigned int red, unsigned int green, unsigned int blue) {//modification to make runRainbow work with common anode
analogWrite(redPin, 255 - red);
analogWrite(greenPin, 255 - green);
analogWrite(bluePin, 255 - blue);
}

Click the checkmark button to verify the code- this is just checking that you pasted it correctly. If the code does not verify try cutting and pasting again. Once it works, click the “upload” button – the right-pointing arrow button above your code – to push it to your Arduino, and wait for it to say “finished uploading.”

The Flower Stems

Now that your Arduino is ready, we are going to assemble the stems for your flowering plant. Grab all of your materials, including your Arduino (unplug it from your computer for now). This is the circuit you will eventually build (if you are unfamiliar with breadboard diagrams, don’t worry, there are step by step instructions below):

breadboard diagram of circuit

Before we hook the Arduino up to the pot, we are going to wire up the LED flower centers and stems, which will be plugged into the mini breadboard. A breadboard is an easy way to connect circuits together – if you have never seen or used one, it is important to understand how it works so you can wire everything right. Take a moment to look at your breadboard- it has two large circular bolt holes (we will not use these), a long trench down the center that splits it lengthwise, and small square sided holes arranged in 17 columns, ten to a column. The long trench splits the whole board in half, meaning that these square wholes are actually connected in columns of five each- anything you plug into one of the holes in that five-hole group will be connected to anything plugged in the other four holes.

To begin, take three of your resistors and three male to male jumper cables and wire up the breadboard like this. The color of the wires does not matter, just make sure they are plugged in correctly.

breadboard step one
breadboard photo

Remember that each column of five square hole is connected- so here, you are using the resistor to connect the top five to the bottom five in each column, and then putting a wire in each of the three long columns.

Do the same on the other side with your three remaining resistors and three more cables. This is a mirror image of the first three.

breadboard step two
photo of breadboard step two

Now you are going to attach the breadboard to the Arduino using a rubber band. You can in theory do this later, but it would require unhooking a bunch of wires, so it’s easier to do it now. Put the breadboard on top of the Arduino and then rubber band it around the middle:

breadboard on arduino

Connect the six jumper cables to the Arduino ports. It is very important that you do this correctly, if you do not, your flower will not light up. Double check that each wire goes to the correctly numbered port. 

With the breadboard oriented as in the photo, from left to right your wires are plugged into 12, ~10, ~9, ~6, ~5, 4.

breadboard step three
photo

Now take your remaining three jumper cables. You are going to use the breadboard to complete the power circuit so these LED stems will light up. A little explanation: the LEDs we are using are common-anode RGB LEDs. Basically, that means there are actually three lights inside each of the lights- a red LED, a blue LED and a green LED. Together they combine to make thousands of colors. So far you have connected the red, blue, and green LEDs to the Arduino so the Arduino can control the colors, and now you are going to connect the final leg, what is called the anode or the positive leg, to the power port on the Arduino. 

Use those three cables like this, connecting where the LED will go to a common column, and then connecting that column to the 3.3V port on the Arduino (this puts out 3.3 volts of power):

breadboard step four
photo of step four

Now we are going to double-check that you connected everything correctly. Go ahead and plug two of your LED “stems” in. The longer stem with the diffused LED goes on the left side (plugged to ports 12, 10, and 9) and the shorter stem with the clear LED goes on the right (ports 6,5, and 4).

breadboard step five
photo of step five

Plug your Arduino back into your computer and let it power on. The LEDs should light up and they should be white. If they do not, try plugging them in in the other direction (rotate the plug 180 degrees). If they do not work in either direction, or they turn a color other than white, double check that all of your wires are correct. If none of that works, flag down someone to help you.

stems lit up

Wiring the Infrared Transmitter and Receiver

Most of this wiring has already been done – if you look into your plant pot, you will see the infrared receiver and the infrared LED (light-emitting diode) wired and ready to go. There is also a resistor already wired in- it is covered with electrical tape (green in the photo below, yours may be black). Once again, be careful with these components- they are securely wired, but not soldered together. You should have five wires coming out of your pot – a red or orange wire, a black or purple/magenta wire, a blue or green wire, a white or yellow wire, and a gray or brown wire. Take a moment to identify all five and verify they are there.

Plant pot wired with infrared receiver and transmitter.

The first three (red/orange, black/purple/magenta, and blue/green) are connected to the receiver- the black and silver component on one side of the pot. The other two (white/yellow and gray/brown) are attached to the IR LED- which is a clear LED on the other side of the pot. Your wires may be two different colors (like in the photo above, one of the wires is both orange and black). When trying to determine which wire is which, only the color on the unplugged end matters – so in the photo above, we consider the black/orange wire to be the orange wire, because the orange is the unplugged end.

Unplug the stems and the USB cord from your Arduino/breadboard unit. Lay the plant pot on its side to give you easy access to the wires, and plug the receiver in first. The red/orange wire goes to the 5v line – this is the power cord. The black/purple/magenta wire goes to the GND port next to the 5v port – this is the ground cord. The blue/green wire goes to pin ~11 – this is the data cord.

breadboard step sixphoto of step sixHome stretch! Now plug the last two wires in – the white/yellow cord goes to pin ~3, this is the data/power cord, and the grey/brown cord goes to the GND port- this is the ground cord.

Breadboard diagram of step sevenphoto of step sevenTime to test again! This time, you are going to need some help from another student to check if your transmitter and receiver are working. Find a partner who is also at this stage and set up next to each other. Plug your Arduinos into your computers and open up the IDE software again.

You are going to check the Serial Monitor, a window that reports data coming from the Arduino, to see if your plant is transmitting and receiving correctly. If you are using the web editor, click on “Monitor” in the left side menu. If you are using the desktop IDE, navigate to Tools>Serial Monitor. This will open up a window – make sure it is set to 9600 baud (the setting should be above or below the window.) You should immediately see two lines pop up- Enabling IRin, then Enabled IRin: (don’t be concerned if you get some stuttering, like in the first photo where it says EnabEnabling):

View of Serial Monitor
Serial port on Arduino Web Editor
View of Serial Monitor
Serial Monitor in Desktop IDE

You and your partner should now arrange your potted plants so the IR receiver of one is near the IR LED of the other, like so:

friends

In this pair, the plant on the left is transmitting and the one on the right is receiving. Check your computer- the receiving plant should now have info scrolling in the Serial monitor:

web editor
Serial data in the web editor.
serial data
Serial data in the desktop IDE.

Now, switch your plants around so the one that was transmitting is receiving and vice versa. The other plant should send data to the serial monitor. Don’t worry about what the data is – just check that something is coming through. If nothing is happening, you can try resetting the Arduinos by plugging and unplugging them. Then, double check your wires. If nothing works, flag down someone to help you.

Potting the Plants

Now it’s time to assemble everything inside the pot. While the USB is still plugged in to the computer, plug your LED stems back in to the breadboard, making sure you put the long stem (with the diffused or cloudy LED) on the left side and the shorter (clear LED) on the right. They should light up again. If they do not, flip them over like you did before.

photo with stems

You may, at this point, decide you want to add more stems to your flower by plugging them in the same column as the stems already in place. I’d recommend no more than four total flowers. You can add the stems to either side, but I’d recommend adding them to the side where the long stem currently is, like so:

extra stems

Unplug your Arduino from the computer. Taking care not to unplug anything else, slide the whole Arduino + breadboard + stem assembly into the pot USB-port-side first. Try to angle the USB port so it is facing the hole in your pot. It will sit at an angle:

arduino in pot

Carefully plug the USB port back in just to check that everything lights up still. This may take a little bit of maneuvering.

plugged in

Now, carefully slide the brown or black cover over the stems. You may need to bend them to get them positioned nicely. Push the cover down so it hides the wiring.

covered up

Congratulations! Your plant is potted. Now it is time to customize your flower.

Customizing your Plant.

There are two parts to this- building the flowers themselves, and customizing the code. For the flowers, go up and grab supplies- construction paper, scissors, glue, flower centers, pipe cleaners, and go to town. The flower centers are already custom cut to fit over the LEDs, so once you have your flowers build you can just slide them into place:

flowers!

The final bit- time to customize your code. This step is OPTIONAL, but if you want to play around with the code a bit, it is fun to do. The first thing is you can change the starting color of the long stems of your flower. To do this, find the section of your code that looks like this:

int red = random(256); // red RGB value
int green = random(256);// green RGB value
int blue = random(256);// blue RGB value
int sensitive = true; //Set this to "true" if you want your flower to react a lot to its neighbors, to "false" if you want it to be more robust.
int talkative = true; // Set this to "true" if you want your flower to send information frequently, to "false" if you want it to listen longer.

Right now, the color of your flower is random at the start – that is what random(256) means. The program picks a random number between 0 and 255. Change the values of red, blue, and green from random(256) to any number between 0 and 255. If you want help choosing a color, use an RGB color picker. I picked lime green, color value #99ff33. The RGB value is (153, 255, 51) – that means the red value is 153, the green is 255 and the blue is 51. Set your numbers accordingly:

int red = 153; // red RGB value
int green = 255;// green RGB value
int blue = 51;// blue RGB value
int sensitive = true; //Set this to "true" if you want your flower to react a lot to its neighbors, to "false" if you want it to be more robust.
int talkative = true; // Set this to "true" if you want your flower to send information frequently, to "false" if you want it to listen longer.

Take care not to delete any of the code except “random(256)” – specifically, do not erase the semicolon.

Once you have your color chosen, you can also decide if you want your flower to be sensitive or not, or if you want it to be talkative or not. These values are automatically set to true. If you want to change one, erase the word “true” and replace it with “false.” So, if I wanted my lime green plant to be more robust, that is, not senstive, I would do the following:

int red = 153; // red RGB value
int green = 255;// green RGB value
int blue = 51;// blue RGB value
int sensitive = false; //Set this to "true" if you want your flower to react a lot to its neighbors, to "false" if you want it to be more robust.
int talkative = true; // Set this to "true" if you want your flower to send information frequently, to "false" if you want it to listen longer.

And that’s it! Click the checkmark to make sure your code is working, then upload it to your Arduino. Check that the color is what you want- remember that only the long stem LED (and any extras you plugged in to that port) will change color- the other LED will still be white.

And your flower is done and ready to join the garden! Unplug it from your computer and bring it, both the pot and the USB, to the garden table.

Thanks for joining us!