We created a zen waterfalls that:
- Had water flowing over the rocks
- Had an MP3 music player
- Had a rotating light show
Part of the fun on this project was that we could play with different rotating light patterns that could be used in either normal lighting or in a dark room.
For this project we tried it with a Raspberry Pi, littleBits and Arduino. We found that the Arduino offered the best overall solution.
The parts that we used were:
- Arduino UNO with prototyping shield
- Arduino Serial MP3 module ($7)
- Arduino motor shield ($18)
- IR receiver chips ($6 for 10)
- strip of neopixel lights ($25)
- small water pump ($5)
- some plastic tubing
- speakers
- a TV remote
- a large container and some rocks
We placed the rocks into the large container and then we mounted the water pump in one of the back corners. It will take a bit of trial and error to ensure that you keep the water flowing down the rocks and not shooting out everywhere. We put a rock on the very top to secure the plastic tube and to block the water spray so that the water flows “quietly” down the lower rocks.
The motor shield was stacked on top of the UNO and the protyping shield was used for mounting the IR receiver and serial MP3 player.
The first important step is to read your IR codes. Each manufacturers TV remote will give different IR codes. Below is some simple code that will show the IR code for each button press. We used this code and then we recorded the button codes that we wanted to use.
/* IR TEST PROGRAM PINOUTS: lEFT = DATA PIN MIDDLE = gnd RIGHT = 3.3 volts */ #include int RECV_PIN = 11; //11; IRrecv irrecv(RECV_PIN); decode_results results; void setup() { Serial.begin(9600); irrecv.enableIRIn(); // Start the receiver Serial.println("Setup Complete"); } void loop() { if (irrecv.decode(&results)) { Serial.println(results.value, HEX); irrecv.resume(); // Receive the next value delay(500); } }
Once we got our IR button codes we were able to pull everything together. For our project we wanted the following buttons:
- Pump ON
- Pump OFF
- Lights ON
- Lights OFF
- Play music
- Stop music
- Volume UP
- Volume DOWN
Below is our final code:
//Arduino PWM Speed Control // Neopixel setup #include #define PIN 8 Adafruit_NeoPixel strip = Adafruit_NeoPixel(100, PIN, NEO_GRB + NEO_KHZ800); bool leds_on = false; int thecolor = 0; int thepixel = 0; // IR setup #include int RECV_PIN = 11; //11; IRrecv irrecv(RECV_PIN); decode_results results; // Pump setup char thekey; int E1 = 5; // motor speed pin int M1 = 4; // motor enable pin // Music Setup #include static int8_t Send_buf[8] = {0} ; #define CMD_VOLUME_UP 0X04 #define CMD_VOLUME_DOWN 0X05 #define CMD_SEL_DEV 0X09 #define DEV_TF 0X02 #define CMD_PLAY 0X0D #define CMD_PLAY_NEXT 0X01 #define CMD_PAUSE 0X0E #define CMD_FOLDER_CYCLE 0X17 #define ARDUINO_RX 5//should connect to TX of the Serial MP3 Player module #define ARDUINO_TX 6//connect to RX of the module SoftwareSerial mySerial(ARDUINO_RX, ARDUINO_TX); //----------------------------------------------------- void setup() { Serial.begin(9600); irrecv.enableIRIn(); // Start the IR receiver // Enable the Neopixel strip strip.begin(); strip.setBrightness(20); // Setup the pump pinMode(M1, OUTPUT); digitalWrite(M1, HIGH); analogWrite(E1, 0); //Set pump speed to zero (off) // Setup the music mySerial.begin(9600); delay(500);//Wait chip initialization is complete sendCommand(CMD_SEL_DEV, DEV_TF);//select the TF card delay(200);//wait for 200ms sendCommand(CMD_FOLDER_CYCLE, 0X0001); } //----------------------------------------------------- void loop() { if (irrecv.decode(&results)) { switch (results.value) { case 0xDAEA83EC: //Stop Pump 'Red Button' Serial.println("Stop Pump"); analogWrite(E1, 0); break; case 0x2BAFCEEC: //Start Pump 'Green Button' Serial.println("Run Pump"); analogWrite(E1, 255); break; case 0xB5210DA6: //LEDs ON 'Yellow Button' Serial.println("Turn LEDs ON"); leds_on = true; break; case 0x71A1FE88: //LEDs ON 'Yellow Button' Serial.println("Turn LEDs OFF"); leds_on = false; color_off(); break; case 0x68733A46: //Volume Up sendCommand(CMD_VOLUME_UP, 0); Serial.println("Turning Volume Up"); break; case 0x83B19366: //Volume Down sendCommand(CMD_VOLUME_DOWN, 0); Serial.println("Turning Volume Down"); break; case 0x6A618E02: //Play //sendCommand(CMD_PLAY_NEXT, 0); sendCommand(CMD_PLAY,0); Serial.println("Play Music"); break; case 0xED45D744: //Play Next sendCommand(CMD_PLAY_NEXT, 0); Serial.println("Play Next SongMusic"); break; case 0xC863D6C8: //Stop sendCommand(CMD_PAUSE, 0); Serial.println("Pause Music"); delay(1000); // delay so that you don't jump ahead 2+ songs break; default: Serial.println(results.value, HEX); } irrecv.resume(); // Receive the next value } // Do colors if (leds_on) { color_on(); } } //---------------------------------------------------- void color_on() { thecolor = thecolor + 5; if (thecolor > 255) { thecolor = 0;} for (int i=0; i strip.numPixels()) {thepixel = 0;} strip.setPixelColor(thepixel, 238, 201, 0); strip.setPixelColor((thepixel+1), 205, 173, 0); strip.setPixelColor((thepixel+2), 238, 201, 0); strip.show(); delay (100); } //---------------------------------------------------- void color_off() { for (int i=0; i > 8);//datah Send_buf[6] = (int8_t)(dat); //datal Send_buf[7] = 0xef; //ending byte for(uint8_t i=0; i<8; i++)// { mySerial.write(Send_buf[i]) ; } }