For this project we wanted to create a portable animated light that we could mount below our bike seat or attach it to a knapsack. The parts that we used were:
- Arduino Squarewear (or any small arduino module)
- Adafruit 8×8 LED Matrix
- Soft phone case
We happened to have a Squarewear module from some past work. This is a nice module for wearable projects because it has a built-in rechargeable battery and easy to solder connections. However other small Arduino modules could also be used.
The case that we used we got from a local dollar store (for $1) and it had a hard back and neoprene front pocket. The four wires that we soldered to the LED Matrix were fairly stiff so we bent them over the lip of the neoprene pocket. The Squarewear module was slipped in behind for easy access to its power switch.
The Adafruit 8×8 matrix has four connections: SDA, SCL, VCC and GND. In the arduino code you will need to include the libraries:
- Adafruit_GFX.h
- Adafruit_LEDBackpack.h
There are a lot of options on what you could display. Our first example used a set of squares that changed sizes.
Our second example used some “old school” animated alien images.
In our final project we used the button on the Squarewear to trigger four different modes:
- Alien mode
- Square mode (best for biking)
- Scroll the temperature
- Show some text
Have fun.
//****************************************************/ #include <Wire.h> #include "Adafruit_LEDBackpack.h" #include "Adafruit_GFX.h" #include <PciManager.h> #include <PciListenerImp.h> #define ulong unsigned long #define uchar unsigned char #define pinButton 4 #define temp_sensor A1 PciListenerImp listener(pinButton, onPinButtonChange); uchar buttonPressed = 10; //4 = onboard button //----------------------------------------------------------- void onPinButtonChange(byte changeKind) { static ulong t = 0; if (changeKind == 1 && millis() > t + 250) { t = millis(); buttonPressed = 1; } } Adafruit_8x8matrix matrix = Adafruit_8x8matrix(); //----------------------------------------------------------- void setup() { pinMode(pinButton, INPUT); digitalWrite(pinButton, HIGH); PciManager.registerListener(pinButton, &listener); matrix.begin(0x70); // pass in the address } //----------------------------------------------------------- void loop() { // Make 3 modes, 1) Temperature, 2) Bike, 3) Pictures buttonPressed = 0; loop_pic(); buttonPressed = 0; loop_temp(); buttonPressed = 0; loop_bike(); buttonPressed = 0; loop_text(); } //---------------------------------------- void loop_temp() { // Loop thru showing the temperature until the button is pressed float temp; matrix.setTextWrap(false); matrix.setTextSize(0.5); matrix.setRotation(3); while(!buttonPressed) { // convert to celcius temp = (float)analogRead(temp_sensor); temp = (temp * 3.3 / 1024 - 0.5) / 0.01; for (int8_t x=0; x>=-20; x--) { matrix.clear(); matrix.setCursor(x,0); matrix.print(int(temp) ); matrix.print("c"); matrix.writeDisplay(); delay(300); if(buttonPressed) break; } } } //------------------------------------------------------------- void loop_bike() { // Loop with a visible biking safe pattern until button pushed while(!buttonPressed) { matrix.clear(); matrix.fillRect(3,3, 2,2, LED_ON); matrix.writeDisplay(); // write the changes we just made to the display if(buttonPressed) break; delay(250); matrix.clear(); matrix.fillRect(2,2, 4,4, LED_ON); matrix.writeDisplay(); // write the changes we just made to the display if(buttonPressed) break; delay(250); matrix.clear(); matrix.fillRect(1,1, 6,6, LED_ON); matrix.writeDisplay(); // write the changes we just made to the display if(buttonPressed) break; delay(250); matrix.clear(); matrix.fillRect(0,0, 8,8, LED_ON); matrix.writeDisplay(); // write the changes we just made to the display if(buttonPressed) break; delay(250); } } // ------------------------------------------------------------ const uint8_t PROGMEM alien[21][8] = { { B00011000, // This is the first frame for alien #1 B00111100, // If you squint you can kind of see the B01111110, // image in the 0's and 1's. B11011011, B11111111, B00100100, B01011010, B10100101 }, { B00011000, // This is the second frame for alien #1 B00111100, B01111110, B11011011, B11111111, B00100100, B01011010, B01000010 }, { B00011000, B00111100, B01111110, B11011011, B11111111, B00100100, B01011010, B10100101 }, { B00011000, B00111100, B01111110, B11011011, B11111111, B00100100, B01011010, B01000010 }, { B00000000, // First frame for alien #2 B00111100, B01111110, B11011011, B11011011, B01111110, B00100100, B11000011 }, { B00111100, // Second frame for alien #2 B01111110, B11011011, B11011011, B01111110, B00100100, B00100100, B00100100 }, { B00000000, B00111100, B01111110, B11011011, B11011011, B01111110, B00100100, B11000011 }, { B00111100, B01111110, B11011011, B11011011, B01111110, B00100100, B00100100, B00100100 }, { B00100100, // First frame for alien #3 B00100100, B01111110, B11011011, B11111111, B11111111, B10100101, B00100100}, { B00100100, // Second frame for alien #3 B10100101, B11111111, B11011011, B11111111, B01111110, B00100100, B01000010 }, { B00100100, B00100100, B01111110, B11011011, B11111111, B11111111, B10100101, B00100100 }, { B00100100, B10100101, B11111111, B11011011, B11111111, B01111110, B00100100, B01000010 }, { B00111100, // First frame for alien #4 B01111110, B00110011, B01111110, B00111100, B00000000, B00001000, B00000000 }, { B00111100, // Second frame for alien #4 B01111110, B10011001, B01111110, B00111100, B00000000, B00001000, B00001000 }, { B00111100, // Third frame for alien #4 (NOT a repeat of frame 1) B01111110, B11001100, B01111110, B00111100, B00000000, B00000000, B00001000 }, { B00111100, // Fourth frame for alien #4 (NOT a repeat of frame 2) B01111110, B01100110, B01111110, B00111100, B00000000, B00000000, B00000000}, { B00111100, B01111110, B00110011, B01111110, B00111100, B00000000, B00001000, B00000000 }, { B00111100, B01111110, B10011001, B01111110, B00111100, B00000000, B00001000, B00001000 }, { B00111100, B01111110, B11001100, B01111110, B00111100, B00000000, B00000000, B00001000 }, { B00111100, B01111110, B01100110, B01111110, B00111100, B00000000, B00000000, B00000000 }, }; //------------------------------------------------------------- static const uint8_t PROGMEM smile_bmp[] = { B00111100, B01000010, B10100101, B10000001, B10100101, B10011001, B01000010, B00111100 }, wink_bmp[] = { B00111100, B01000010, B10100001, B10000001, B10100101, B10011001, B01000010, B00111100 }, lsmile_bmp[] = { B00111100, B01000010, B10100101, B10000001, B10100001, B10011001, B01000010, B00111100 }, rsmile_bmp[] = { B00111100, B01000010, B10100101, B10000001, B10000101, B10011001, B01000010, B00111100 }; //---------------------------------------- void loop_pic() { while(!buttonPressed) { matrix.clear(); matrix.drawBitmap(0, 0, smile_bmp, 8, 8, LED_ON); matrix.writeDisplay(); delay(1500); if(buttonPressed) break; matrix.clear(); matrix.drawBitmap(0, 0, wink_bmp, 8, 8, LED_ON); matrix.writeDisplay(); delay(500); if(buttonPressed) break; matrix.clear(); matrix.drawBitmap(0, 0, smile_bmp, 8, 8, LED_ON); matrix.writeDisplay(); delay(1500); if(buttonPressed) break; matrix.clear(); matrix.drawBitmap(0, 0, lsmile_bmp, 8, 8, LED_ON); matrix.writeDisplay(); delay(1000); matrix.clear(); matrix.drawBitmap(0, 0, rsmile_bmp, 8, 8, LED_ON); matrix.writeDisplay(); delay(1000); if(buttonPressed) break; matrix.clear(); matrix.drawBitmap(0, 0, smile_bmp, 8, 8, LED_ON); matrix.writeDisplay(); delay(1500); matrix.setRotation(3); for (int i=0; i< 21; i++) { matrix.clear(); matrix.drawBitmap(0, 0, alien[i], 8, 8, LED_ON); matrix.writeDisplay(); delay(250); if(buttonPressed) break; } } } //---------------------------------------- void loop_text() { // Loop thru showing the temperature until the button is pressed matrix.setTextWrap(false); matrix.setTextSize(1); matrix.setRotation(3); char thetext[] = "Hello"; while(!buttonPressed) { for (int8_t x=0; x>=-40; x--) { matrix.clear(); matrix.setCursor(x,0); matrix.print(thetext); matrix.writeDisplay(); delay(300); if(buttonPressed) break; } } }