Animated Bike Light

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:

parts

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.

mounting

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;
    }
  }
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s