initial commit

This commit is contained in:
2026-09-25 10:48:51 +10:00
commit b90beea8ae
1020 changed files with 131665 additions and 0 deletions
@@ -0,0 +1,55 @@
/***************************************************
This is a library for our I2C LED Backpacks
Designed specifically to work with the Adafruit LED Matrix backpacks
----> http://www.adafruit.com/products/872
----> http://www.adafruit.com/products/871
----> http://www.adafruit.com/products/870
These displays use I2C to communicate, 2 pins are required to
interface. There are multiple selectable I2C addresses. For backpacks
with 2 Address Select pins: 0x70, 0x71, 0x72 or 0x73. For backpacks
with 3 Address Select pins: 0x70 thru 0x77
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
#ifndef _BV
#define _BV(bit) (1<<(bit))
#endif
Adafruit_LEDBackpack matrix = Adafruit_LEDBackpack();
uint8_t counter = 0;
void setup() {
Serial.begin(9600);
Serial.println("HT16K33 test");
matrix.begin(0x70); // pass in the address
}
void loop() {
// paint one LED per row. The HT16K33 internal memory looks like
// a 8x16 bit matrix (8 rows, 16 columns)
for (uint8_t i=0; i<8; i++) {
// draw a diagonal row of pixels
matrix.displaybuffer[i] = _BV((counter+i) % 16) | _BV((counter+i+8) % 16) ;
}
// write the changes we just made to the display
matrix.writeDisplay();
delay(100);
counter++;
if (counter >= 16) counter = 0;
}
@@ -0,0 +1,65 @@
/***************************************************
This is a library for our I2C LED Backpacks
Designed specifically to work with the Adafruit LED 24 Bargraph Backpack
----> http://www.adafruit.com/products/721
These displays use I2C to communicate, 2 pins are required to
interface. There are multiple selectable I2C addresses. For backpacks
with 2 Address Select pins: 0x70, 0x71, 0x72 or 0x73. For backpacks
with 3 Address Select pins: 0x70 thru 0x77
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
Adafruit_24bargraph bar = Adafruit_24bargraph();
void setup() {
Serial.begin(9600);
Serial.println("HT16K33 Bi-Color Bargraph test");
bar.begin(0x70); // pass in the address
for (uint8_t b=0; b<24; b++ ){
if ((b % 3) == 0) bar.setBar(b, LED_RED);
if ((b % 3) == 1) bar.setBar(b, LED_YELLOW);
if ((b % 3) == 2) bar.setBar(b, LED_GREEN);
}
bar.writeDisplay();
delay(2000);
}
void loop() {
for (uint8_t b=0; b<24; b++) {
bar.setBar(b, LED_RED);
bar.writeDisplay();
delay(50);
bar.setBar(b, LED_OFF);
bar.writeDisplay();
}
for (uint8_t b=0; b<24; b++) {
bar.setBar(b, LED_GREEN);
bar.writeDisplay();
delay(50);
bar.setBar(b, LED_OFF);
bar.writeDisplay();
}
for (uint8_t b=0; b<24; b++) {
bar.setBar(23-b, LED_YELLOW);
bar.writeDisplay();
delay(50);
bar.setBar(23-b, LED_OFF);
bar.writeDisplay();
}
}
@@ -0,0 +1,122 @@
/***************************************************
This is a library for our I2C LED Backpacks
Designed specifically to work with the Adafruit LED Matrix backpacks
----> http://www.adafruit.com/products/872
----> http://www.adafruit.com/products/871
----> http://www.adafruit.com/products/870
These displays use I2C to communicate, 2 pins are required to
interface. There are multiple selectable I2C addresses. For backpacks
with 2 Address Select pins: 0x70, 0x71, 0x72 or 0x73. For backpacks
with 3 Address Select pins: 0x70 thru 0x77
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix();
void setup() {
Serial.begin(9600);
Serial.println("8x8 LED Matrix Test");
matrix.begin(0x70); // pass in the address
}
static const uint8_t PROGMEM
smile_bmp[] =
{ B00111100,
B01000010,
B10100101,
B10000001,
B10100101,
B10011001,
B01000010,
B00111100 },
neutral_bmp[] =
{ B00111100,
B01000010,
B10100101,
B10000001,
B10111101,
B10000001,
B01000010,
B00111100 },
frown_bmp[] =
{ B00111100,
B01000010,
B10100101,
B10000001,
B10011001,
B10100101,
B01000010,
B00111100 };
void loop() {
matrix.clear();
matrix.drawBitmap(0, 0, smile_bmp, 8, 8, LED_GREEN);
matrix.writeDisplay();
delay(500);
matrix.clear();
matrix.drawBitmap(0, 0, neutral_bmp, 8, 8, LED_YELLOW);
matrix.writeDisplay();
delay(500);
matrix.clear();
matrix.drawBitmap(0, 0, frown_bmp, 8, 8, LED_RED);
matrix.writeDisplay();
delay(500);
matrix.clear(); // clear display
matrix.drawPixel(0, 0, LED_GREEN);
matrix.writeDisplay(); // write the changes we just made to the display
delay(500);
matrix.clear();
matrix.drawLine(0,0, 7,7, LED_YELLOW);
matrix.writeDisplay(); // write the changes we just made to the display
delay(500);
matrix.clear();
matrix.drawRect(0,0, 8,8, LED_RED);
matrix.fillRect(2,2, 4,4, LED_GREEN);
matrix.writeDisplay(); // write the changes we just made to the display
delay(500);
matrix.clear();
matrix.drawCircle(3,3, 3, LED_YELLOW);
matrix.writeDisplay(); // write the changes we just made to the display
delay(500);
matrix.setTextWrap(false); // we dont want text to wrap so it scrolls nicely
matrix.setTextSize(1);
matrix.setTextColor(LED_GREEN);
for (int8_t x=7; x>=-36; x--) {
matrix.clear();
matrix.setCursor(x,0);
matrix.print("Hello");
matrix.writeDisplay();
delay(100);
}
matrix.setRotation(3);
matrix.setTextColor(LED_RED);
for (int8_t x=7; x>=-36; x--) {
matrix.clear();
matrix.setCursor(x,0);
matrix.print("World");
matrix.writeDisplay();
delay(100);
}
matrix.setRotation(0);
}
@@ -0,0 +1,178 @@
// Clock example using a seven segment display & DS1307 real-time clock.
//
// Must have the Adafruit RTClib library installed too! See:
// https://github.com/adafruit/RTClib
//
// Designed specifically to work with the Adafruit LED 7-Segment backpacks
// and DS1307 real-time clock breakout:
// ----> http://www.adafruit.com/products/881
// ----> http://www.adafruit.com/products/880
// ----> http://www.adafruit.com/products/879
// ----> http://www.adafruit.com/products/878
// ----> https://www.adafruit.com/products/264
//
// Adafruit invests time and resources providing this open source code,
// please support Adafruit and open-source hardware by purchasing
// products from Adafruit!
//
// Written by Tony DiCola for Adafruit Industries.
// Released under a MIT license: https://opensource.org/licenses/MIT
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <RTClib.h>
#include "Adafruit_LEDBackpack.h"
// Set to false to display time in 12 hour format, or true to use 24 hour:
#define TIME_24_HOUR false
// I2C address of the display. Stick with the default address of 0x70
// unless you've changed the address jumpers on the back of the display.
#define DISPLAY_ADDRESS 0x70
// Create display and DS1307 objects. These are global variables that
// can be accessed from both the setup and loop function below.
Adafruit_7segment clockDisplay = Adafruit_7segment();
RTC_DS1307 rtc = RTC_DS1307();
// Keep track of the hours, minutes, seconds displayed by the clock.
// Start off at 0:00:00 as a signal that the time should be read from
// the DS1307 to initialize it.
int hours = 0;
int minutes = 0;
int seconds = 0;
// Remember if the colon was drawn on the display so it can be blinked
// on and off every second.
bool blinkColon = false;
void setup() {
// Setup function runs once at startup to initialize the display
// and DS1307 clock.
// Setup Serial port to print debug output.
Serial.begin(115200);
Serial.println("Clock starting!");
// Setup the display.
clockDisplay.begin(DISPLAY_ADDRESS);
// Setup the DS1307 real-time clock.
rtc.begin();
// Set the DS1307 clock if it hasn't been set before.
bool setClockTime = !rtc.isrunning();
// Alternatively you can force the clock to be set again by
// uncommenting this line:
//setClockTime = true;
if (setClockTime) {
Serial.println("Setting DS1307 time!");
// This line sets the DS1307 time to the exact date and time the
// sketch was compiled:
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// Alternatively you can set the RTC with an explicit date & time,
// for example to set January 21, 2014 at 3am you would uncomment:
//rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
}
void loop() {
// Loop function runs over and over again to implement the clock logic.
// Check if it's the top of the hour and get a new time reading
// from the DS1307. This helps keep the clock accurate by fixing
// any drift.
if (minutes == 0) {
// Get the time from the DS1307.
DateTime now = rtc.now();
// Print out the time for debug purposes:
Serial.print("Read date & time from DS1307: ");
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
// Now set the hours and minutes.
hours = now.hour();
minutes = now.minute();
}
// Show the time on the display by turning it into a numeric
// value, like 3:30 turns into 330, by multiplying the hour by
// 100 and then adding the minutes.
int displayValue = hours*100 + minutes;
// Do 24 hour to 12 hour format conversion when required.
if (!TIME_24_HOUR) {
// Handle when hours are past 12 by subtracting 12 hours (1200 value).
if (hours > 12) {
displayValue -= 1200;
}
// Handle hour 0 (midnight) being shown as 12.
else if (hours == 0) {
displayValue += 1200;
}
}
// Now print the time value to the display.
clockDisplay.print(displayValue, DEC);
// Add zero padding when in 24 hour mode and it's midnight.
// In this case the print function above won't have leading 0's
// which can look confusing. Go in and explicitly add these zeros.
if (TIME_24_HOUR && hours == 0) {
// Pad hour 0.
clockDisplay.writeDigitNum(1, 0);
// Also pad when the 10's minute is 0 and should be padded.
if (minutes < 10) {
clockDisplay.writeDigitNum(3, 0);
}
}
// Blink the colon by flipping its value every loop iteration
// (which happens every second).
blinkColon = !blinkColon;
clockDisplay.drawColon(blinkColon);
// Now push out to the display the new values that were set above.
clockDisplay.writeDisplay();
// Pause for a second for time to elapse. This value is in milliseconds
// so 1000 milliseconds = 1 second.
delay(1000);
// Now increase the seconds by one.
seconds += 1;
// If the seconds go above 59 then the minutes should increase and
// the seconds should wrap back to 0.
if (seconds > 59) {
seconds = 0;
minutes += 1;
// Again if the minutes go above 59 then the hour should increase and
// the minutes should wrap back to 0.
if (minutes > 59) {
minutes = 0;
hours += 1;
// Note that when the minutes are 0 (i.e. it's the top of a new hour)
// then the start of the loop will read the actual time from the DS1307
// again. Just to be safe though we'll also increment the hour and wrap
// back to 0 if it goes above 23 (i.e. past midnight).
if (hours > 23) {
hours = 0;
}
}
}
// Loop code is finished, it will jump back to the start of the loop
// function again!
}
@@ -0,0 +1,159 @@
// Clock example using a seven segment display & GPS for time.
//
// Must have the Adafruit GPS library installed too! See:
// https://github.com/adafruit/Adafruit-GPS-Library
//
// Designed specifically to work with the Adafruit LED 7-Segment backpacks
// and ultimate GPS breakout/shield:
// ----> http://www.adafruit.com/products/881
// ----> http://www.adafruit.com/products/880
// ----> http://www.adafruit.com/products/879
// ----> http://www.adafruit.com/products/878
// ----> http://www.adafruit.com/products/746
//
// Adafruit invests time and resources providing this open source code,
// please support Adafruit and open-source hardware by purchasing
// products from Adafruit!
//
// Written by Tony DiCola for Adafruit Industries.
// Released under a MIT license: https://opensource.org/licenses/MIT
#include <SoftwareSerial.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_GPS.h>
#include "Adafruit_LEDBackpack.h"
// Set to false to display time in 12 hour format, or true to use 24 hour:
#define TIME_24_HOUR false
// Offset the hours from UTC (universal time) to your local time by changing
// this value. The GPS time will be in UTC so lookup the offset for your
// local time from a site like:
// https://en.wikipedia.org/wiki/List_of_UTC_time_offsets
// This value, -7, will set the time to UTC-7 or Pacific Standard Time during
// daylight savings time.
#define HOUR_OFFSET -7
// I2C address of the display. Stick with the default address of 0x70
// unless you've changed the address jumpers on the back of the display.
#define DISPLAY_ADDRESS 0x70
// Create display and GPS objects. These are global variables that
// can be accessed from both the setup and loop function below.
Adafruit_7segment clockDisplay = Adafruit_7segment();
SoftwareSerial gpsSerial(8, 7); // GPS breakout/shield will use a
// software serial connection with
// TX = pin 8 and RX = pin 7.
Adafruit_GPS gps(&gpsSerial);
void setup() {
// Setup function runs once at startup to initialize the display and GPS.
// Setup Serial port to print debug output.
Serial.begin(115200);
Serial.println("Clock starting!");
// Setup the display.
clockDisplay.begin(DISPLAY_ADDRESS);
// Setup the GPS using a 9600 baud connection (the default for most
// GPS modules).
gps.begin(9600);
// Configure GPS to onlu output minimum data (location, time, fix).
gps.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
// Use a 1 hz, once a second, update rate.
gps.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
// Enable the interrupt to parse GPS data.
enableGPSInterrupt();
}
void loop() {
// Loop function runs over and over again to implement the clock logic.
// Check if GPS has new data and parse it.
if (gps.newNMEAreceived()) {
gps.parse(gps.lastNMEA());
}
// Grab the current hours, minutes, seconds from the GPS.
// This will only be set once the GPS has a fix! Make sure to add
// a coin cell battery so the GPS will save the time between power-up/down.
int hours = gps.hour + HOUR_OFFSET; // Add hour offset to convert from UTC
// to local time.
// Handle when UTC + offset wraps around to a negative or > 23 value.
if (hours < 0) {
hours = 24+hours;
}
if (hours > 23) {
hours = 24-hours;
}
int minutes = gps.minute;
int seconds = gps.seconds;
// Show the time on the display by turning it into a numeric
// value, like 3:30 turns into 330, by multiplying the hour by
// 100 and then adding the minutes.
int displayValue = hours*100 + minutes;
// Do 24 hour to 12 hour format conversion when required.
if (!TIME_24_HOUR) {
// Handle when hours are past 12 by subtracting 12 hours (1200 value).
if (hours > 12) {
displayValue -= 1200;
}
// Handle hour 0 (midnight) being shown as 12.
else if (hours == 0) {
displayValue += 1200;
}
}
// Now print the time value to the display.
clockDisplay.print(displayValue, DEC);
// Add zero padding when in 24 hour mode and it's midnight.
// In this case the print function above won't have leading 0's
// which can look confusing. Go in and explicitly add these zeros.
if (TIME_24_HOUR && hours == 0) {
// Pad hour 0.
clockDisplay.writeDigitNum(1, 0);
// Also pad when the 10's minute is 0 and should be padded.
if (minutes < 10) {
clockDisplay.writeDigitNum(2, 0);
}
}
// Blink the colon by turning it on every even second and off
// every odd second. The modulus operator is very handy here to
// check if a value is even (modulus 2 equals 0) or odd (modulus 2
// equals 1).
clockDisplay.drawColon(seconds % 2 == 0);
// Now push out to the display the new values that were set above.
clockDisplay.writeDisplay();
// Loop code is finished, it will jump back to the start of the loop
// function again! Don't add any delays because the parsing needs to
// happen all the time!
}
SIGNAL(TIMER0_COMPA_vect) {
// Use a timer interrupt once a millisecond to check for new GPS data.
// This piggybacks on Arduino's internal clock timer for the millis()
// function.
gps.read();
}
void enableGPSInterrupt() {
// Function to enable the timer interrupt that will parse GPS data.
// Timer0 is already used for millis() - we'll just interrupt somewhere
// in the middle and call the "Compare A" function above
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
}
@@ -0,0 +1,5 @@
# Arduino-Custom-Character
This repository holds arduino and processing code for printing Custom Characters on Adafruit HT16k33 8x8 Bicolor Led Matrix from software.
Full explaination of this project is available on [Instructables](https://www.instructables.com/id/Custom-Character-Generator-Adafruit-HT16k33-Matrix/).
@@ -0,0 +1,86 @@
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix();
String data="";
uint8_t emoji[]={0,0,0,0,0,0,0,0};
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
matrix.begin(0x70); // pass in the address
print_emoji(emoji,"green");
}
void loop() {
if (Serial.available()>0)
{
data=Serial.readStringUntil('\n');
Serial.println(data);
}
if (data!="")
{
emoji[0]=(val(data.substring(1,9)));
//Serial.println(val(data.substring(1,9)));
emoji[1]=(val(data.substring(11,19)));
//Serial.println(val(data.substring(11,19)));
emoji[2]=(val(data.substring(21,29)));
//Serial.println(val(data.substring(21,29)));
emoji[3]=(val(data.substring(31,39)));
//Serial.println(val(data.substring(31,39)));
emoji[4]=(val(data.substring(41,49)));
//Serial.println(val(data.substring(41,49)));
emoji[5]=(val(data.substring(51,59)));
//Serial.println(val(data.substring(51,59)));
emoji[6]=(val(data.substring(61,69)));
//Serial.println(val(data.substring(61,69)));
emoji[7]=(val(data.substring(71,79)));
//Serial.println(val(data.substring(71,79)));
data="";
print_emoji(emoji,"green");
}
}
int val(String str)
{
int v=0;
for (int i=0;i<8;i++)
{
if (str[i]=='1')
{
v=v+power(2,(7-i));
}
}
return v;
}
int power(int base,int exponent)
{
int c=1;
for (int i=0;i<exponent;i++)
{
c=c*base;
}
return c;
}
void print_emoji( uint8_t emoji[],String color)
{
matrix.clear();
if (color=="red")
{
matrix.drawBitmap(0, 0,emoji, 8, 8, LED_RED);
}
else
{
matrix.drawBitmap(0, 0,emoji, 8, 8, LED_GREEN);
}
matrix.writeDisplay();
delay(500);
}
@@ -0,0 +1,352 @@
///////////////////////////////////////////////////////////////LIBRARIES/////////////////////////////////////////////////////////////////
import processing.serial.*;
import java.io.*;
PFont f;
//////////////////////////////////////////////////////////////DECLARATION//////////////////////////////////////////////////////////////////
String subtext;
Serial myPort;
PFont font;
Button button;
Button button1,button2,button3,button4,button5,button6,button7,button8,button9,button10,button11,button12,button13,button14,button15,button16,button17,button18,button19,button20,button21,button22,button23,button24,button25,button26,button27,button28,button29,button30,button31,button32,button33,button34,button35,button36,button37,button38,button39,button40,button41,button42,button43,button44,button45,button46,button47,button48,button49,button50,button51,button52,button53,button54,button55,button56,button57,button58,button59,button60,button61,button62,button63,button64;
int val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13,val14,val15,val16,val17,val18,val19,val20,val21,val22,val23,val24,val25,val26,val27,val28,val29,val30,val31,val32,val33,val34,val35,val36,val37,val38,val39,val40,val41,val42,val43,val44,val45,val46,val47,val48,val49,val50,val51,val52,val53,val54,val55,val56,val57,val58,val59,val60,val61,val62,val63,val64;
////////////////////////////////////////////////////////////////////SETUP FUNCTION///////////////////////////////////////////////////////
void setup(){
size(270,305);
f = createFont("Arial",12,true);
button = new Button(110,230,40,25,"PRINT",10,255);
init();
myPort = new Serial(this, "COM5", 9600);
myPort.bufferUntil('\n');
}
/////////////////////////////////////////////////////////////////////DRAW FUNCTION/////////////////////////////////////////////////////////
void draw(){
background(100,149,237);
textFont(f,12);
fill(255);
text("CUSTOM CHARACTER GENERATOR",25,40);
button.Draw();
initdraw();
}
////////////////////////////////////////////////////////////////CLASS DEFINITION////////////////////////////////////////////////////////
class Button
{
private int x, y, width, height;
private PFont font;
private String label;
private int fontSize;
private int fillcolor;
private int delay = 0, framesPassed = 0;
public Button(int x, int y, int width, int height, String label, int fontSize,int filcolor)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.font = createFont("Arial", 16, true);
this.fontSize = fontSize;
this.label = label;
this.fillcolor=filcolor;
}
public void Draw()
{
fill(fillcolor);
stroke(0);
rect(x, y, width, height);
textFont(font, fontSize);
fill(0);
noStroke();
text(label, x + 5, y + (height - fontSize) / 2 + (height / 2));
if(framesPassed < delay)
{
framesPassed++;
}
}
public void colorswap()
{
if (this.getbuttoncolor()==255)
{
stroke(255);
fill(0);
noStroke();
}
else
{
stroke(0);
fill(255);
noStroke();
}
}
public int getbuttoncolor()
{
return this.fillcolor;
}
public void SetFrameDelay(int delay)
{
this.delay = delay;
}
public boolean IsPressed()
{
if(!mousePressed)
{
return false;
}
if(mouseX >= x && mouseX <= x + width)
{
if(mouseY >= y && mouseY <= y + (height))
{
if(framesPassed == delay)
{
framesPassed = 0;
return true;
}
}
}
return false;
}
}
//////////////////////////////////////////////////////////////////INITIALIZATION AND BUTTON PROCEDURES//////////////////////////////////////////////////////
void init()
{
button1=new Button(50,50,20,20," ",5,255);
button2=new Button(70,50,20,20," ",5,255);
button3=new Button(90,50,20,20," ",5,255);
button4=new Button(110,50,20,20," ",5,255);
button5=new Button(130,50,20,20," ",5,255);
button6=new Button(150,50,20,20," ",5,255);
button7=new Button(170,50,20,20," ",5,255);
button8=new Button(190,50,20,20," ",5,255);
button9=new Button(50,70,20,20," ",5,255);
button10=new Button(70,70,20,20," ",5,255);
button11=new Button(90,70,20,20," ",5,255);
button12=new Button(110,70,20,20," ",5,255);
button13=new Button(130,70,20,20," ",5,255);
button14=new Button(150,70,20,20," ",5,255);
button15=new Button(170,70,20,20," ",5,255);
button16=new Button(190,70,20,20," ",5,255);
button17=new Button(50,90,20,20," ",5,255);
button18=new Button(70,90,20,20," ",5,255);
button19=new Button(90,90,20,20," ",5,255);
button20=new Button(110,90,20,20," ",5,255);
button21=new Button(130,90,20,20," ",5,255);
button22=new Button(150,90,20,20," ",5,255);
button23=new Button(170,90,20,20," ",5,255);
button24=new Button(190,90,20,20," ",5,255);
button25=new Button(50,110,20,20," ",5,255);
button26=new Button(70,110,20,20," ",5,255);
button27=new Button(90,110,20,20," ",5,255);
button28=new Button(110,110,20,20," ",5,255);
button29=new Button(130,110,20,20," ",5,255);
button30=new Button(150,110,20,20," ",5,255);
button31=new Button(170,110,20,20," ",5,255);
button32=new Button(190,110,20,20," ",5,255);
button33=new Button(50,130,20,20," ",5,255);
button34=new Button(70,130,20,20," ",5,255);
button35=new Button(90,130,20,20," ",5,255);
button36=new Button(110,130,20,20," ",5,255);
button37=new Button(130,130,20,20," ",5,255);
button38=new Button(150,130,20,20," ",5,255);
button39=new Button(170,130,20,20," ",5,255);
button40=new Button(190,130,20,20," ",5,255);
button41=new Button(50,150,20,20," ",5,255);
button42=new Button(70,150,20,20," ",5,255);
button43=new Button(90,150,20,20," ",5,255);
button44=new Button(110,150,20,20," ",5,255);
button45=new Button(130,150,20,20," ",5,255);
button46=new Button(150,150,20,20," ",5,255);
button47=new Button(170,150,20,20," ",5,255);
button48=new Button(190,150,20,20," ",5,255);
button49=new Button(50,170,20,20," ",5,255);
button50=new Button(70,170,20,20," ",5,255);
button51=new Button(90,170,20,20," ",5,255);
button52=new Button(110,170,20,20," ",5,255);
button53=new Button(130,170,20,20," ",5,255);
button54=new Button(150,170,20,20," ",5,255);
button55=new Button(170,170,20,20," ",5,255);
button56=new Button(190,170,20,20," ",5,255);
button57=new Button(50,190,20,20," ",5,255);
button58=new Button(70,190,20,20," ",5,255);
button59=new Button(90,190,20,20," ",5,255);
button60=new Button(110,190,20,20," ",5,255);
button61=new Button(130,190,20,20," ",5,255);
button62=new Button(150,190,20,20," ",5,255);
button63=new Button(170,190,20,20," ",5,255);
button64=new Button(190,190,20,20," ",5,255);
}
void initdraw()
{
button1.Draw();
button2.Draw();
button3.Draw();
button4.Draw();
button5.Draw();
button6.Draw();
button7.Draw();
button8.Draw();
button9.Draw();
button10.Draw();
button11.Draw();
button12.Draw();
button13.Draw();
button14.Draw();
button15.Draw();
button16.Draw();
button17.Draw();
button18.Draw();
button19.Draw();
button20.Draw();
button21.Draw();
button22.Draw();
button23.Draw();
button24.Draw();
button25.Draw();
button26.Draw();
button27.Draw();
button28.Draw();
button29.Draw();
button30.Draw();
button31.Draw();
button32.Draw();
button33.Draw();
button34.Draw();
button35.Draw();
button36.Draw();
button37.Draw();
button38.Draw();
button39.Draw();
button40.Draw();
button41.Draw();
button42.Draw();
button43.Draw();
button44.Draw();
button45.Draw();
button46.Draw();
button47.Draw();
button48.Draw();
button49.Draw();
button50.Draw();
button51.Draw();
button52.Draw();
button53.Draw();
button54.Draw();
button55.Draw();
button56.Draw();
button57.Draw();
button58.Draw();
button59.Draw();
button60.Draw();
button61.Draw();
button62.Draw();
button63.Draw();
button64.Draw();
}
void mousePressed()
{
if (button.IsPressed())
{
subtext=make();
//print(subtext);
myPort.write(subtext);
}
if(button1.IsPressed()){if(button1.getbuttoncolor()==255){button1.fillcolor=0;val1=1;}else{button1.fillcolor=255;val1=0;}}
if(button2.IsPressed()){if(button2.getbuttoncolor()==255){button2.fillcolor=0;val2=1;}else{button2.fillcolor=255;val2=0;}}
if(button3.IsPressed()){if(button3.getbuttoncolor()==255){button3.fillcolor=0;val3=1;}else{button3.fillcolor=255;val3=0;}}
if(button4.IsPressed()){if(button4.getbuttoncolor()==255){button4.fillcolor=0;val4=1;}else{button4.fillcolor=255;val4=0;}}
if(button5.IsPressed()){if(button5.getbuttoncolor()==255){button5.fillcolor=0;val5=1;}else{button5.fillcolor=255;val5=0;}}
if(button6.IsPressed()){if(button6.getbuttoncolor()==255){button6.fillcolor=0;val6=1;}else{button6.fillcolor=255;val6=0;}}
if(button7.IsPressed()){if(button7.getbuttoncolor()==255){button7.fillcolor=0;val7=1;}else{button7.fillcolor=255;val7=0;}}
if(button8.IsPressed()){if(button8.getbuttoncolor()==255){button8.fillcolor=0;val8=1;}else{button8.fillcolor=255;val8=0;}}
if(button9.IsPressed()){if(button9.getbuttoncolor()==255){button9.fillcolor=0;val9=1;}else{button9.fillcolor=255;val9=0;}}
if(button10.IsPressed()){if(button10.getbuttoncolor()==255){button10.fillcolor=0;val10=1;}else{button10.fillcolor=255;val10=0;}}
if(button11.IsPressed()){if(button11.getbuttoncolor()==255){button11.fillcolor=0;val11=1;}else{button11.fillcolor=255;val11=0;}}
if(button12.IsPressed()){if(button12.getbuttoncolor()==255){button12.fillcolor=0;val12=1;}else{button12.fillcolor=255;val12=0;}}
if(button13.IsPressed()){if(button13.getbuttoncolor()==255){button13.fillcolor=0;val13=1;}else{button13.fillcolor=255;val13=0;}}
if(button14.IsPressed()){if(button14.getbuttoncolor()==255){button14.fillcolor=0;val14=1;}else{button14.fillcolor=255;val14=0;}}
if(button15.IsPressed()){if(button15.getbuttoncolor()==255){button15.fillcolor=0;val15=1;}else{button15.fillcolor=255;val15=0;}}
if(button16.IsPressed()){if(button16.getbuttoncolor()==255){button16.fillcolor=0;val16=1;}else{button16.fillcolor=255;val16=0;}}
if(button17.IsPressed()){if(button17.getbuttoncolor()==255){button17.fillcolor=0;val17=1;}else{button17.fillcolor=255;val17=0;}}
if(button18.IsPressed()){if(button18.getbuttoncolor()==255){button18.fillcolor=0;val18=1;}else{button18.fillcolor=255;val18=0;}}
if(button19.IsPressed()){if(button19.getbuttoncolor()==255){button19.fillcolor=0;val19=1;}else{button19.fillcolor=255;val19=0;}}
if(button20.IsPressed()){if(button20.getbuttoncolor()==255){button20.fillcolor=0;val20=1;}else{button20.fillcolor=255;val20=0;}}
if(button21.IsPressed()){if(button21.getbuttoncolor()==255){button21.fillcolor=0;val21=1;}else{button21.fillcolor=255;val21=0;}}
if(button22.IsPressed()){if(button22.getbuttoncolor()==255){button22.fillcolor=0;val22=1;}else{button22.fillcolor=255;val22=0;}}
if(button23.IsPressed()){if(button23.getbuttoncolor()==255){button23.fillcolor=0;val23=1;}else{button23.fillcolor=255;val23=0;}}
if(button24.IsPressed()){if(button24.getbuttoncolor()==255){button24.fillcolor=0;val24=1;}else{button24.fillcolor=255;val24=0;}}
if(button25.IsPressed()){if(button25.getbuttoncolor()==255){button25.fillcolor=0;val25=1;}else{button25.fillcolor=255;val25=0;}}
if(button26.IsPressed()){if(button26.getbuttoncolor()==255){button26.fillcolor=0;val26=1;}else{button26.fillcolor=255;val26=0;}}
if(button27.IsPressed()){if(button27.getbuttoncolor()==255){button27.fillcolor=0;val27=1;}else{button27.fillcolor=255;val27=0;}}
if(button28.IsPressed()){if(button28.getbuttoncolor()==255){button28.fillcolor=0;val28=1;}else{button28.fillcolor=255;val28=0;}}
if(button29.IsPressed()){if(button29.getbuttoncolor()==255){button29.fillcolor=0;val29=1;}else{button29.fillcolor=255;val29=0;}}
if(button30.IsPressed()){if(button30.getbuttoncolor()==255){button30.fillcolor=0;val30=1;}else{button30.fillcolor=255;val30=0;}}
if(button31.IsPressed()){if(button31.getbuttoncolor()==255){button31.fillcolor=0;val31=1;}else{button31.fillcolor=255;val31=0;}}
if(button32.IsPressed()){if(button32.getbuttoncolor()==255){button32.fillcolor=0;val32=1;}else{button32.fillcolor=255;val32=0;}}
if(button33.IsPressed()){if(button33.getbuttoncolor()==255){button33.fillcolor=0;val33=1;}else{button33.fillcolor=255;val33=0;}}
if(button34.IsPressed()){if(button34.getbuttoncolor()==255){button34.fillcolor=0;val34=1;}else{button34.fillcolor=255;val34=0;}}
if(button35.IsPressed()){if(button35.getbuttoncolor()==255){button35.fillcolor=0;val35=1;}else{button35.fillcolor=255;val35=0;}}
if(button36.IsPressed()){if(button36.getbuttoncolor()==255){button36.fillcolor=0;val36=1;}else{button36.fillcolor=255;val36=0;}}
if(button37.IsPressed()){if(button37.getbuttoncolor()==255){button37.fillcolor=0;val37=1;}else{button37.fillcolor=255;val37=0;}}
if(button38.IsPressed()){if(button38.getbuttoncolor()==255){button38.fillcolor=0;val38=1;}else{button38.fillcolor=255;val38=0;}}
if(button39.IsPressed()){if(button39.getbuttoncolor()==255){button39.fillcolor=0;val39=1;}else{button39.fillcolor=255;val39=0;}}
if(button40.IsPressed()){if(button40.getbuttoncolor()==255){button40.fillcolor=0;val40=1;}else{button40.fillcolor=255;val40=0;}}
if(button41.IsPressed()){if(button41.getbuttoncolor()==255){button41.fillcolor=0;val41=1;}else{button41.fillcolor=255;val41=0;}}
if(button42.IsPressed()){if(button42.getbuttoncolor()==255){button42.fillcolor=0;val42=1;}else{button42.fillcolor=255;val42=0;}}
if(button43.IsPressed()){if(button43.getbuttoncolor()==255){button43.fillcolor=0;val43=1;}else{button43.fillcolor=255;val43=0;}}
if(button44.IsPressed()){if(button44.getbuttoncolor()==255){button44.fillcolor=0;val44=1;}else{button44.fillcolor=255;val44=0;}}
if(button45.IsPressed()){if(button45.getbuttoncolor()==255){button45.fillcolor=0;val45=1;}else{button45.fillcolor=255;val45=0;}}
if(button46.IsPressed()){if(button46.getbuttoncolor()==255){button46.fillcolor=0;val46=1;}else{button46.fillcolor=255;val46=0;}}
if(button47.IsPressed()){if(button47.getbuttoncolor()==255){button47.fillcolor=0;val47=1;}else{button47.fillcolor=255;val47=0;}}
if(button48.IsPressed()){if(button48.getbuttoncolor()==255){button48.fillcolor=0;val48=1;}else{button48.fillcolor=255;val48=0;}}
if(button49.IsPressed()){if(button49.getbuttoncolor()==255){button49.fillcolor=0;val49=1;}else{button49.fillcolor=255;val49=0;}}
if(button50.IsPressed()){if(button50.getbuttoncolor()==255){button50.fillcolor=0;val50=1;}else{button50.fillcolor=255;val50=0;}}
if(button51.IsPressed()){if(button51.getbuttoncolor()==255){button51.fillcolor=0;val51=1;}else{button51.fillcolor=255;val51=0;}}
if(button52.IsPressed()){if(button52.getbuttoncolor()==255){button52.fillcolor=0;val52=1;}else{button52.fillcolor=255;val52=0;}}
if(button53.IsPressed()){if(button53.getbuttoncolor()==255){button53.fillcolor=0;val53=1;}else{button53.fillcolor=255;val53=0;}}
if(button54.IsPressed()){if(button54.getbuttoncolor()==255){button54.fillcolor=0;val54=1;}else{button54.fillcolor=255;val54=0;}}
if(button55.IsPressed()){if(button55.getbuttoncolor()==255){button55.fillcolor=0;val55=1;}else{button55.fillcolor=255;val55=0;}}
if(button56.IsPressed()){if(button56.getbuttoncolor()==255){button56.fillcolor=0;val56=1;}else{button56.fillcolor=255;val56=0;}}
if(button57.IsPressed()){if(button57.getbuttoncolor()==255){button57.fillcolor=0;val57=1;}else{button57.fillcolor=255;val57=0;}}
if(button58.IsPressed()){if(button58.getbuttoncolor()==255){button58.fillcolor=0;val58=1;}else{button58.fillcolor=255;val58=0;}}
if(button59.IsPressed()){if(button59.getbuttoncolor()==255){button59.fillcolor=0;val59=1;}else{button59.fillcolor=255;val59=0;}}
if(button60.IsPressed()){if(button60.getbuttoncolor()==255){button60.fillcolor=0;val60=1;}else{button60.fillcolor=255;val60=0;}}
if(button61.IsPressed()){if(button61.getbuttoncolor()==255){button61.fillcolor=0;val61=1;}else{button61.fillcolor=255;val61=0;}}
if(button62.IsPressed()){if(button62.getbuttoncolor()==255){button62.fillcolor=0;val62=1;}else{button62.fillcolor=255;val62=0;}}
if(button63.IsPressed()){if(button63.getbuttoncolor()==255){button63.fillcolor=0;val63=1;}else{button63.fillcolor=255;val63=0;}}
if(button64.IsPressed()){if(button64.getbuttoncolor()==255){button64.fillcolor=0;val64=1;}else{button64.fillcolor=255;val64=0;}}
}
String make()
{
String s="";
s=s+"B"+str(val1)+str(val2)+str(val3)+str(val4)+str(val5)+str(val6)+str(val7)+str(val8)+",";
s=s+"B"+str(val9)+str(val10)+str(val11)+str(val12)+str(val13)+str(val14)+str(val15)+str(val16)+",";
s=s+"B"+str(val17)+str(val18)+str(val19)+str(val20)+str(val21)+str(val22)+str(val23)+str(val24)+",";
s=s+"B"+str(val25)+str(val26)+str(val27)+str(val28)+str(val29)+str(val30)+str(val31)+str(val32)+",";
s=s+"B"+str(val33)+str(val34)+str(val35)+str(val36)+str(val37)+str(val38)+str(val39)+str(val40)+",";
s=s+"B"+str(val41)+str(val42)+str(val43)+str(val44)+str(val45)+str(val46)+str(val47)+str(val48)+",";
s=s+"B"+str(val49)+str(val50)+str(val51)+str(val52)+str(val53)+str(val54)+str(val55)+str(val56)+",";
s=s+"B"+str(val57)+str(val58)+str(val59)+str(val60)+str(val61)+str(val62)+str(val63)+str(val64)+",";
return s;
}
@@ -0,0 +1,133 @@
/***************************************************
This is a library for our I2C LED Backpacks
Designed specifically to work with the Adafruit 16x8 LED Matrix backpacks
----> http://www.adafruit.com/products/2035
----> http://www.adafruit.com/products/2036
----> http://www.adafruit.com/products/2037
----> http://www.adafruit.com/products/2038
----> http://www.adafruit.com/products/2039
----> http://www.adafruit.com/products/2040
----> http://www.adafruit.com/products/2041
----> http://www.adafruit.com/products/2042
----> http://www.adafruit.com/products/2043
----> http://www.adafruit.com/products/2044
----> http://www.adafruit.com/products/2052
These displays use I2C to communicate, 2 pins are required to
interface. There are multiple selectable I2C addresses. For backpacks
with 2 Address Select pins: 0x70, 0x71, 0x72 or 0x73. For backpacks
with 3 Address Select pins: 0x70 thru 0x77
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
Adafruit_8x16matrix matrix = Adafruit_8x16matrix();
void setup() {
Serial.begin(9600);
Serial.println("16x8 LED Matrix Test");
matrix.begin(0x70); // pass in the address
}
static const uint8_t PROGMEM
smile_bmp[] =
{ B00111100,
B01000010,
B10100101,
B10000001,
B10100101,
B10011001,
B01000010,
B00111100 },
neutral_bmp[] =
{ B00111100,
B01000010,
B10100101,
B10000001,
B10111101,
B10000001,
B01000010,
B00111100 },
frown_bmp[] =
{ B00111100,
B01000010,
B10100101,
B10000001,
B10011001,
B10100101,
B01000010,
B00111100 };
void loop() {
matrix.clear();
matrix.drawBitmap(0, 0, smile_bmp, 8, 8, LED_ON);
matrix.writeDisplay();
delay(500);
matrix.clear();
matrix.drawBitmap(0, 8, neutral_bmp, 8, 8, LED_ON);
matrix.writeDisplay();
delay(500);
matrix.clear();
matrix.drawBitmap(0, 0, frown_bmp, 8, 8, LED_ON);
matrix.writeDisplay();
delay(500);
matrix.clear(); // clear display
matrix.drawPixel(0, 0, LED_ON);
matrix.writeDisplay(); // write the changes we just made to the display
delay(500);
matrix.clear();
matrix.drawLine(0,0, 7,15, LED_ON);
matrix.writeDisplay(); // write the changes we just made to the display
delay(500);
matrix.clear();
matrix.drawRect(0,0, 8,16, LED_ON);
matrix.fillRect(2,2, 4,12, LED_ON);
matrix.writeDisplay(); // write the changes we just made to the display
delay(500);
matrix.clear();
matrix.drawCircle(3,8, 3, LED_ON);
matrix.writeDisplay(); // write the changes we just made to the display
delay(500);
matrix.setTextSize(2);
matrix.setTextWrap(false); // we dont want text to wrap so it scrolls nicely
matrix.setTextColor(LED_ON);
for (int8_t x=0; x>=-64; x--) {
matrix.clear();
matrix.setCursor(x,0);
matrix.print("Hello");
matrix.writeDisplay();
delay(100);
}
matrix.setTextSize(1);
matrix.setTextWrap(false); // we dont want text to wrap so it scrolls nicely
matrix.setTextColor(LED_ON);
matrix.setRotation(1);
for (int8_t x=7; x>=-36; x--) {
matrix.clear();
matrix.setCursor(x,0);
matrix.print("World");
matrix.writeDisplay();
delay(100);
}
matrix.setRotation(0);
}
@@ -0,0 +1,120 @@
/***************************************************
This is a library for our I2C LED Backpacks
Designed specifically to work with the Adafruit LED Matrix backpacks
----> http://www.adafruit.com/products/872
----> http://www.adafruit.com/products/871
----> http://www.adafruit.com/products/870
These displays use I2C to communicate, 2 pins are required to
interface. There are multiple selectable I2C addresses. For backpacks
with 2 Address Select pins: 0x70, 0x71, 0x72 or 0x73. For backpacks
with 3 Address Select pins: 0x70 thru 0x77
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
Adafruit_8x8matrix matrix = Adafruit_8x8matrix();
void setup() {
Serial.begin(9600);
Serial.println("8x8 LED Matrix Test");
matrix.begin(0x70); // pass in the address
}
static const uint8_t PROGMEM
smile_bmp[] =
{ B00111100,
B01000010,
B10100101,
B10000001,
B10100101,
B10011001,
B01000010,
B00111100 },
neutral_bmp[] =
{ B00111100,
B01000010,
B10100101,
B10000001,
B10111101,
B10000001,
B01000010,
B00111100 },
frown_bmp[] =
{ B00111100,
B01000010,
B10100101,
B10000001,
B10011001,
B10100101,
B01000010,
B00111100 };
void loop() {
matrix.clear();
matrix.drawBitmap(0, 0, smile_bmp, 8, 8, LED_ON);
matrix.writeDisplay();
delay(500);
matrix.clear();
matrix.drawBitmap(0, 0, neutral_bmp, 8, 8, LED_ON);
matrix.writeDisplay();
delay(500);
matrix.clear();
matrix.drawBitmap(0, 0, frown_bmp, 8, 8, LED_ON);
matrix.writeDisplay();
delay(500);
matrix.clear(); // clear display
matrix.drawPixel(0, 0, LED_ON);
matrix.writeDisplay(); // write the changes we just made to the display
delay(500);
matrix.clear();
matrix.drawLine(0,0, 7,7, LED_ON);
matrix.writeDisplay(); // write the changes we just made to the display
delay(500);
matrix.clear();
matrix.drawRect(0,0, 8,8, LED_ON);
matrix.fillRect(2,2, 4,4, LED_ON);
matrix.writeDisplay(); // write the changes we just made to the display
delay(500);
matrix.clear();
matrix.drawCircle(3,3, 3, LED_ON);
matrix.writeDisplay(); // write the changes we just made to the display
delay(500);
matrix.setTextSize(1);
matrix.setTextWrap(false); // we dont want text to wrap so it scrolls nicely
matrix.setTextColor(LED_ON);
for (int8_t x=0; x>=-36; x--) {
matrix.clear();
matrix.setCursor(x,0);
matrix.print("Hello");
matrix.writeDisplay();
delay(100);
}
matrix.setRotation(3);
for (int8_t x=7; x>=-36; x--) {
matrix.clear();
matrix.setCursor(x,0);
matrix.print("World");
matrix.writeDisplay();
delay(100);
}
matrix.setRotation(0);
}
@@ -0,0 +1,123 @@
/***************************************************
This is a library for our I2C LED Backpacks & FeatherWings
Designed specifically to work with the Adafruit 16x8 LED Matrix FeatherWing
These displays use I2C to communicate, 2 pins are required to
interface. There are multiple selectable I2C addresses. For backpacks
with 2 Address Select pins: 0x70, 0x71, 0x72 or 0x73. For backpacks
with 3 Address Select pins: 0x70 thru 0x77
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
Adafruit_8x16minimatrix matrix = Adafruit_8x16minimatrix();
void setup() {
//while (!Serial);
Serial.begin(9600);
Serial.println("16x8 LED Mini Matrix Test");
matrix.begin(0x70); // pass in the address
}
static const uint8_t PROGMEM
smile_bmp[] =
{ B00111100,
B01000010,
B10100101,
B10000001,
B10100101,
B10011001,
B01000010,
B00111100 },
neutral_bmp[] =
{ B00111100,
B01000010,
B10100101,
B10000001,
B10111101,
B10000001,
B01000010,
B00111100 },
frown_bmp[] =
{ B00111100,
B01000010,
B10100101,
B10000001,
B10011001,
B10100101,
B01000010,
B00111100 };
void loop() {
matrix.clear();
matrix.drawBitmap(0, 0, smile_bmp, 8, 8, LED_ON);
matrix.writeDisplay();
delay(500);
matrix.clear();
matrix.drawBitmap(0, 8, neutral_bmp, 8, 8, LED_ON);
matrix.writeDisplay();
delay(500);
matrix.clear();
matrix.drawBitmap(0, 0, frown_bmp, 8, 8, LED_ON);
matrix.writeDisplay();
delay(500);
matrix.drawPixel(0, 0, LED_ON);
matrix.writeDisplay(); // write the changes we just made to the display
delay(500);
matrix.clear();
matrix.drawLine(0,0, 7,15, LED_ON);
matrix.writeDisplay(); // write the changes we just made to the display
delay(500);
matrix.clear();
matrix.drawRect(0,0, 8,16, LED_ON);
matrix.fillRect(2,2, 4,12, LED_ON);
matrix.writeDisplay(); // write the changes we just made to the display
delay(500);
matrix.clear();
matrix.drawCircle(3,8, 3, LED_ON);
matrix.writeDisplay(); // write the changes we just made to the display
delay(500);
matrix.setTextSize(2);
matrix.setTextWrap(false); // we dont want text to wrap so it scrolls nicely
matrix.setTextColor(LED_ON);
for (int8_t x=0; x>=-64; x--) {
matrix.clear();
matrix.setCursor(x,0);
matrix.print("Hello");
matrix.writeDisplay();
delay(100);
}
matrix.setTextSize(1);
matrix.setTextWrap(false); // we dont want text to wrap so it scrolls nicely
matrix.setTextColor(LED_ON);
matrix.setRotation(1);
for (int8_t x=7; x>=-36; x--) {
matrix.clear();
matrix.setCursor(x,0);
matrix.print("World");
matrix.writeDisplay();
delay(100);
}
matrix.setRotation(0);
}
@@ -0,0 +1,60 @@
// This example shows how to use the alphanumeric segment names in an animation.
//
// Author: Jonny Bergdahl (github@bergdahl.org)
//
#include <Arduino.h>
#include <Adafruit_LEDBackpack.h>
Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4();
/*
Segment names for 14-segment alphanumeric displays.
See https://learn.adafruit.com/14-segment-alpha-numeric-led-featherwing/usage
-------A-------
|\ | /|
| \ J / |
| H | K |
F \ | / B
| \|/ |
|--G1--|--G2--|
| /|\ |
E / | \ C
| L | N |
| / M \ |
|/ | \|
-------D------- DP
*/
uint16_t animation[] { 0, ALPHANUM_SEG_A | ALPHANUM_SEG_D,
1, ALPHANUM_SEG_H | ALPHANUM_SEG_L,
1, ALPHANUM_SEG_N | ALPHANUM_SEG_K,
2, ALPHANUM_SEG_L | ALPHANUM_SEG_H,
2, ALPHANUM_SEG_K | ALPHANUM_SEG_N,
3, ALPHANUM_SEG_A | ALPHANUM_SEG_D,
3, ALPHANUM_SEG_B | ALPHANUM_SEG_C,
3, ALPHANUM_SEG_C | ALPHANUM_SEG_B,
3, ALPHANUM_SEG_D | ALPHANUM_SEG_A,
2, ALPHANUM_SEG_N | ALPHANUM_SEG_K,
2, ALPHANUM_SEG_H | ALPHANUM_SEG_L,
1, ALPHANUM_SEG_K | ALPHANUM_SEG_N,
1, ALPHANUM_SEG_L | ALPHANUM_SEG_H,
0, ALPHANUM_SEG_D | ALPHANUM_SEG_A,
0, ALPHANUM_SEG_E | ALPHANUM_SEG_F,
0, ALPHANUM_SEG_F | ALPHANUM_SEG_E };
void setup() {
Serial.begin(9600);
alpha4.begin(0x70); // pass in the address
}
void loop() {
// For each step of the animation, write the value to the given digit
for (int j = 0; j < sizeof(animation)/2; j = j + 2)
{
alpha4.clear();
alpha4.writeDigitRaw(animation[j], animation[j+1]);
alpha4.writeDisplay();
delay(200);
}
}
@@ -0,0 +1,73 @@
// Demo the quad alphanumeric display LED backpack kit
// scrolls through every character, then scrolls Serial
// input onto the display
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4();
void setup() {
Serial.begin(9600);
alpha4.begin(0x70); // pass in the address
alpha4.writeDigitRaw(3, 0x0);
alpha4.writeDigitRaw(0, 0xFFFF);
alpha4.writeDisplay();
delay(200);
alpha4.writeDigitRaw(0, 0x0);
alpha4.writeDigitRaw(1, 0xFFFF);
alpha4.writeDisplay();
delay(200);
alpha4.writeDigitRaw(1, 0x0);
alpha4.writeDigitRaw(2, 0xFFFF);
alpha4.writeDisplay();
delay(200);
alpha4.writeDigitRaw(2, 0x0);
alpha4.writeDigitRaw(3, 0xFFFF);
alpha4.writeDisplay();
delay(200);
alpha4.clear();
alpha4.writeDisplay();
// display every character,
for (uint8_t i='!'; i<='z'; i++) {
alpha4.writeDigitAscii(0, i);
alpha4.writeDigitAscii(1, i+1);
alpha4.writeDigitAscii(2, i+2);
alpha4.writeDigitAscii(3, i+3);
alpha4.writeDisplay();
delay(300);
}
Serial.println("Start typing to display!");
}
char displaybuffer[4] = {' ', ' ', ' ', ' '};
void loop() {
while (! Serial.available()) return;
char c = Serial.read();
if (! isprint(c)) return; // only printable!
// scroll down display
displaybuffer[0] = displaybuffer[1];
displaybuffer[1] = displaybuffer[2];
displaybuffer[2] = displaybuffer[3];
displaybuffer[3] = c;
// set every digit to the buffer
alpha4.writeDigitAscii(0, displaybuffer[0]);
alpha4.writeDigitAscii(1, displaybuffer[1]);
alpha4.writeDigitAscii(2, displaybuffer[2]);
alpha4.writeDigitAscii(3, displaybuffer[3]);
// write it out!
alpha4.writeDisplay();
delay(200);
}
@@ -0,0 +1,72 @@
// Demo the quad alphanumeric display LED backpack kit
// Displays a short message and then scrolls through every character
// For use with Gemma or Trinket (Attiny85)
#include <avr/power.h>
#include <Wire.h>
// Connect + pins to 3-5V
// Connect GND to ground
// Connect Data to #0
// Connect Clock to #2
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
char *message = "Hello world! ";
Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4();
void setup() {
// This is the auto-speed doubler line, keep it in, it will
// automatically double the speed when 16Mhz is selected!
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
alpha4.begin(0x70); // pass in the address
alpha4.writeDigitRaw(3, 0x0);
alpha4.writeDigitRaw(0, 0xFFFF);
alpha4.writeDisplay();
delay(200);
alpha4.writeDigitRaw(0, 0x0);
alpha4.writeDigitRaw(1, 0xFFFF);
alpha4.writeDisplay();
delay(200);
alpha4.writeDigitRaw(1, 0x0);
alpha4.writeDigitRaw(2, 0xFFFF);
alpha4.writeDisplay();
delay(200);
alpha4.writeDigitRaw(2, 0x0);
alpha4.writeDigitRaw(3, 0xFFFF);
alpha4.writeDisplay();
delay(200);
alpha4.clear();
alpha4.writeDisplay();
// send a message!
for (uint8_t i=0; i<strlen(message)-4; i++) {
alpha4.writeDigitAscii(0, message[i]);
alpha4.writeDigitAscii(1, message[i+1]);
alpha4.writeDigitAscii(2, message[i+2]);
alpha4.writeDigitAscii(3, message[i+3]);
alpha4.writeDisplay();
delay(200);
}
}
void loop() {
// display every character,
for (uint8_t i='!'; i<='z'; i++) {
alpha4.writeDigitAscii(0, i);
alpha4.writeDigitAscii(1, i+1);
alpha4.writeDigitAscii(2, i+2);
alpha4.writeDigitAscii(3, i+3);
alpha4.writeDisplay();
delay(300);
}
}
@@ -0,0 +1,251 @@
// 'roboface' example sketch for Adafruit I2C 8x8 LED backpacks:
//
// www.adafruit.com/products/870 www.adafruit.com/products/1049
// www.adafruit.com/products/871 www.adafruit.com/products/1050
// www.adafruit.com/products/872 www.adafruit.com/products/1051
// www.adafruit.com/products/959 www.adafruit.com/products/1052
//
// Requires Adafruit_LEDBackpack and Adafruit_GFX libraries.
// For a simpler introduction, see the 'matrix8x8' example.
//
// This sketch demonstrates a couple of useful techniques:
// 1) Addressing multiple matrices (using the 'A0' and 'A1' solder
// pads on the back to select unique I2C addresses for each).
// 2) Displaying the same data on multiple matrices by sharing the
// same I2C address.
//
// This example uses 5 matrices at 4 addresses (two share an address)
// to animate a face:
//
// 0 0
//
// 1 2 3
//
// The 'eyes' both display the same image (always looking the same
// direction -- can't go cross-eyed) and thus share the same address
// (0x70). The three matrices forming the mouth have unique addresses
// (0x71, 0x72 and 0x73).
//
// The face animation as written is here semi-random; this neither
// generates nor responds to actual sound, it's simply a visual effect
// Consider this a stepping off point for your own project. Maybe you
// could 'puppet' the face using joysticks, or synchronize the lips to
// audio from a Wave Shield (see wavface example). Currently there are
// only six images for the mouth. This is often sufficient for simple
// animation, as explained here:
// http://www.idleworm.com/how/anm/03t/talk1.shtml
//
// Adafruit invests time and resources providing this open source code,
// please support Adafruit and open-source hardware by purchasing
// products from Adafruit!
//
// Written by P. Burgess for Adafruit Industries.
// BSD license, all text above must be included in any redistribution.
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
// Because the two eye matrices share the same address, only four
// matrix objects are needed for the five displays:
#define MATRIX_EYES 0
#define MATRIX_MOUTH_LEFT 1
#define MATRIX_MOUTH_MIDDLE 2
#define MATRIX_MOUTH_RIGHT 3
Adafruit_8x8matrix matrix[4] = { // Array of Adafruit_8x8matrix objects
Adafruit_8x8matrix(), Adafruit_8x8matrix(),
Adafruit_8x8matrix(), Adafruit_8x8matrix() };
// Rather than assigning matrix addresses sequentially in a loop, each
// has a spot in this array. This makes it easier if you inadvertently
// install one or more matrices in the wrong physical position --
// re-order the addresses in this table and you can still refer to
// matrices by index above, no other code or wiring needs to change.
static const uint8_t matrixAddr[] = { 0x70, 0x71, 0x72, 0x73 };
static const uint8_t PROGMEM // Bitmaps are stored in program memory
blinkImg[][8] = { // Eye animation frames
{ B00111100, // Fully open eye
B01111110,
B11111111,
B11111111,
B11111111,
B11111111,
B01111110,
B00111100 },
{ B00000000,
B01111110,
B11111111,
B11111111,
B11111111,
B11111111,
B01111110,
B00111100 },
{ B00000000,
B00000000,
B00111100,
B11111111,
B11111111,
B11111111,
B00111100,
B00000000 },
{ B00000000,
B00000000,
B00000000,
B00111100,
B11111111,
B01111110,
B00011000,
B00000000 },
{ B00000000, // Fully closed eye
B00000000,
B00000000,
B00000000,
B10000001,
B01111110,
B00000000,
B00000000 } },
mouthImg[][24] = { // Mouth animation frames
{ B00000000, B00000000, B00000000, // Mouth position A
B00000000, B00000000, B00000000,
B01111111, B11111111, B11111110,
B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000 },
{ B00000000, B00000000, B00000000, // Mouth position B
B00000000, B00000000, B00000000,
B00111111, B11111111, B11111100,
B00000111, B00000000, B11100000,
B00000000, B11111111, B00000000,
B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000 },
{ B00000000, B00000000, B00000000, // Mouth position C
B00000000, B00000000, B00000000,
B00111111, B11111111, B11111100,
B00001000, B00000000, B00010000,
B00000110, B00000000, B01100000,
B00000001, B11000011, B10000000,
B00000000, B00111100, B00000000,
B00000000, B00000000, B00000000 },
{ B00000000, B00000000, B00000000, // Mouth position D
B00000000, B00000000, B00000000,
B00111111, B11111111, B11111100,
B00100000, B00000000, B00000100,
B00010000, B00000000, B00001000,
B00001100, B00000000, B00110000,
B00000011, B10000001, B11000000,
B00000000, B01111110, B00000000 },
{ B00000000, B00000000, B00000000, // Mouth position E
B00000000, B00111100, B00000000,
B00011111, B11000011, B11111000,
B00000011, B10000001, B11000000,
B00000000, B01111110, B00000000,
B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000 },
{ B00000000, B00111100, B00000000, // Mouth position F
B00000000, B11000011, B00000000,
B00001111, B00000000, B11110000,
B00000001, B00000000, B10000000,
B00000000, B11000011, B00000000,
B00000000, B00111100, B00000000,
B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000 } };
uint8_t
blinkIndex[] = { 1, 2, 3, 4, 3, 2, 1 }, // Blink bitmap sequence
blinkCountdown = 100, // Countdown to next blink (in frames)
gazeCountdown = 75, // Countdown to next eye movement
gazeFrames = 50, // Duration of eye movement (smaller = faster)
mouthPos = 0, // Current image number for mouth
mouthCountdown = 10; // Countdown to next mouth change
int8_t
eyeX = 3, eyeY = 3, // Current eye position
newX = 3, newY = 3, // Next eye position
dX = 0, dY = 0; // Distance from prior to new position
void setup() {
// Seed random number generator from an unused analog input:
randomSeed(analogRead(A0));
// Initialize each matrix object:
for(uint8_t i=0; i<4; i++) {
matrix[i].begin(matrixAddr[i]);
// If using 'small' (1.2") displays vs. 'mini' (0.8"), enable this:
// matrix[i].setRotation(3);
}
}
void loop() {
// Draw eyeball in current state of blinkyness (no pupil). Note that
// only one eye needs to be drawn. Because the two eye matrices share
// the same address, the same data will be received by both.
matrix[MATRIX_EYES].clear();
// When counting down to the next blink, show the eye in the fully-
// open state. On the last few counts (during the blink), look up
// the corresponding bitmap index.
matrix[MATRIX_EYES].drawBitmap(0, 0,
blinkImg[
(blinkCountdown < sizeof(blinkIndex)) ? // Currently blinking?
blinkIndex[blinkCountdown] : // Yes, look up bitmap #
0 // No, show bitmap 0
], 8, 8, LED_ON);
// Decrement blink counter. At end, set random time for next blink.
if(--blinkCountdown == 0) blinkCountdown = random(5, 180);
// Add a pupil (2x2 black square) atop the blinky eyeball bitmap.
// Periodically, the pupil moves to a new position...
if(--gazeCountdown <= gazeFrames) {
// Eyes are in motion - draw pupil at interim position
matrix[MATRIX_EYES].fillRect(
newX - (dX * gazeCountdown / gazeFrames),
newY - (dY * gazeCountdown / gazeFrames),
2, 2, LED_OFF);
if(gazeCountdown == 0) { // Last frame?
eyeX = newX; eyeY = newY; // Yes. What's new is old, then...
do { // Pick random positions until one is within the eye circle
newX = random(7); newY = random(7);
dX = newX - 3; dY = newY - 3;
} while((dX * dX + dY * dY) >= 10); // Thank you Pythagoras
dX = newX - eyeX; // Horizontal distance to move
dY = newY - eyeY; // Vertical distance to move
gazeFrames = random(3, 15); // Duration of eye movement
gazeCountdown = random(gazeFrames, 120); // Count to end of next movement
}
} else {
// Not in motion yet -- draw pupil at current static position
matrix[MATRIX_EYES].fillRect(eyeX, eyeY, 2, 2, LED_OFF);
}
// Draw mouth, switch to new random image periodically
drawMouth(mouthImg[mouthPos]);
if(--mouthCountdown == 0) {
mouthPos = random(6); // Random image
// If the 'neutral' position was chosen, there's a 1-in-5 chance we'll
// select a longer hold time. This gives the appearance of periodic
// pauses in speech (e.g. between sentences, etc.).
mouthCountdown = ((mouthPos == 0) && (random(5) == 0)) ?
random(10, 40) : // Longer random duration
random(2, 8); // Shorter random duration
}
// Refresh all of the matrices in one quick pass
for(uint8_t i=0; i<4; i++) matrix[i].writeDisplay();
delay(20); // ~50 FPS
}
// Draw mouth image across three adjacent displays
void drawMouth(const uint8_t *img) {
for(uint8_t i=0; i<3; i++) {
matrix[MATRIX_MOUTH_LEFT + i].clear();
matrix[MATRIX_MOUTH_LEFT + i].drawBitmap(i * -8, 0, img, 24, 8, LED_ON);
}
}
@@ -0,0 +1,86 @@
/***************************************************
This is a library for our I2C LED Backpacks
Designed specifically to work with the Adafruit LED 7-Segment backpacks
----> http://www.adafruit.com/products/881
----> http://www.adafruit.com/products/880
----> http://www.adafruit.com/products/879
----> http://www.adafruit.com/products/878
These displays use I2C to communicate, 2 pins are required to
interface. There are multiple selectable I2C addresses. For backpacks
with 2 Address Select pins: 0x70, 0x71, 0x72 or 0x73. For backpacks
with 3 Address Select pins: 0x70 thru 0x77
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
#include <Wire.h> // Enable this line if using Arduino Uno, Mega, etc.
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
Adafruit_7segment matrix = Adafruit_7segment();
void setup() {
#ifndef __AVR_ATtiny85__
Serial.begin(9600);
Serial.println("7 Segment Backpack Test");
#endif
matrix.begin(0x70);
}
void loop() {
// try to print a number thats too long
matrix.print(10000, DEC);
matrix.writeDisplay();
delay(500);
// print a hex number
matrix.print(0xBEEF, HEX);
matrix.writeDisplay();
delay(500);
// print a floating point
matrix.print(12.34);
matrix.writeDisplay();
delay(500);
// print a string message
matrix.print("7SEG");
matrix.writeDisplay();
delay(10000);
// print with print/println
for (uint16_t counter = 0; counter < 9999; counter++) {
matrix.println(counter);
matrix.writeDisplay();
delay(10);
}
// method #2 - draw each digit
uint16_t blinkcounter = 0;
boolean drawDots = false;
for (uint16_t counter = 0; counter < 9999; counter ++) {
matrix.writeDigitNum(0, (counter / 1000), drawDots);
matrix.writeDigitNum(1, (counter / 100) % 10, drawDots);
matrix.drawColon(drawDots);
matrix.writeDigitNum(3, (counter / 10) % 10, drawDots);
matrix.writeDigitNum(4, counter % 10, drawDots);
blinkcounter+=50;
if (blinkcounter < 500) {
drawDots = false;
} else if (blinkcounter < 1000) {
drawDots = true;
} else {
blinkcounter = 0;
}
matrix.writeDisplay();
delay(10);
}
}
@@ -0,0 +1,336 @@
// 'wavface' example sketch for Adafruit I2C 8x8 LED backpacks
// and Wave Shield:
//
// www.adafruit.com/products/870 www.adafruit.com/products/1049
// www.adafruit.com/products/871 www.adafruit.com/products/1050
// www.adafruit.com/products/872 www.adafruit.com/products/1051
// www.adafruit.com/products/959 www.adafruit.com/products/1052
// www.adafruit.com/products/94
//
// Requires Adafruit_LEDBackpack, Adafruit_GFX libraries and WaveHC
// libraries.
//
// This sketch shows animation roughly synchronized to prerecorded
// speech. It's fairly complex and may be overwhelming to novice
// programmers, who may want to start with the 'matrix8x8' example
// and then 'roboface' before working through this code. Also, much
// of the comments relating to the face animation have been stripped
// here for brevity...refer to the 'roboface' sketch if you have any
// questions how that part works.
//
// Additional hardware required: sounds are triggered using three
// normally-open momentary buttons connected to Digital pins 6, 7, 8
// and GND. (e.g. www.adafruit.com/products/1009 )
//
// Adafruit invests time and resources providing this open source code,
// please support Adafruit and open-source hardware by purchasing
// products from Adafruit!
//
// Written by P. Burgess for Adafruit Industries, parts adapted from
// 'PiSpeakHC' sketch included with WaveHC library.
// BSD license, all text above must be included in any redistribution.
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <WaveHC.h>
#include <WaveUtil.h>
#include "Adafruit_LEDBackpack.h"
// These WAV files should be in the root level of the SD card:
static const char PROGMEM
wav0[] = "beware_i.wav",
wav1[] = "ihunger.wav",
wav2[] = "run_cowd.wav";
static const char * const wavname[] PROGMEM = { wav0, wav1, wav2 };
// PROGMEM makes frequent appearances throughout this code, reason being that
// the SD card library requires gobs of precious RAM (leaving very little to
// our own sketch). PROGMEM lets us put fixed data into program flash memory,
// which is considerably more spacious. String tables are paritcularly nasty.
// See www.arduino.cc/en/Reference/PROGMEM for more info.
SdReader card; // This object holds the information for the card
FatVolume vol; // This holds the information for the partition on the card
FatReader root; // This holds the information for the volumes root directory
FatReader file; // This object represent the WAV file for a phrase
WaveHC wave; // A single wave object -- only one sound is played at a time
// Because the two eye matrices share the same address, only four
// matrix objects are needed for the five displays:
#define MATRIX_EYES 0
#define MATRIX_MOUTH_LEFT 1
#define MATRIX_MOUTH_MIDDLE 2
#define MATRIX_MOUTH_RIGHT 3
Adafruit_8x8matrix matrix[4] = { // Array of Adafruit_8x8matrix objects
Adafruit_8x8matrix(), Adafruit_8x8matrix(),
Adafruit_8x8matrix(), Adafruit_8x8matrix() };
// Rather than assigning matrix addresses sequentially in a loop, each
// has a spot in this array. This makes it easier if you inadvertently
// install one or more matrices in the wrong physical position --
// re-order the addresses in this table and you can still refer to
// matrices by index above, no other code or wiring needs to change.
static const uint8_t PROGMEM matrixAddr[] = { 0x70, 0x71, 0x72, 0x73 };
static const uint8_t PROGMEM // Bitmaps are stored in program memory
blinkImg[][8] = { // Eye animation frames
{ B00111100, // Fully open eye
B01111110,
B11111111,
B11111111,
B11111111,
B11111111,
B01111110,
B00111100 },
{ B00000000,
B01111110,
B11111111,
B11111111,
B11111111,
B11111111,
B01111110,
B00111100 },
{ B00000000,
B00000000,
B00111100,
B11111111,
B11111111,
B11111111,
B00111100,
B00000000 },
{ B00000000,
B00000000,
B00000000,
B00111100,
B11111111,
B01111110,
B00011000,
B00000000 },
{ B00000000, // Fully closed eye
B00000000,
B00000000,
B00000000,
B10000001,
B01111110,
B00000000,
B00000000 } },
mouthImg[][24] = { // Mouth animation frames
{ B00000000, B00000000, B00000000, // Mouth position A
B00000000, B00000000, B00000000,
B01111111, B11111111, B11111110,
B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000 },
{ B00000000, B00000000, B00000000, // Mouth position B
B00000000, B00000000, B00000000,
B00111111, B11111111, B11111100,
B00000111, B00000000, B11100000,
B00000000, B11111111, B00000000,
B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000 },
{ B00000000, B00000000, B00000000, // Mouth position C
B00000000, B00000000, B00000000,
B00111111, B11111111, B11111100,
B00001000, B00000000, B00010000,
B00000110, B00000000, B01100000,
B00000001, B11000011, B10000000,
B00000000, B00111100, B00000000,
B00000000, B00000000, B00000000 },
{ B00000000, B00000000, B00000000, // Mouth position D
B00000000, B00000000, B00000000,
B00111111, B11111111, B11111100,
B00100000, B00000000, B00000100,
B00010000, B00000000, B00001000,
B00001100, B00000000, B00110000,
B00000011, B10000001, B11000000,
B00000000, B01111110, B00000000 },
{ B00000000, B00000000, B00000000, // Mouth position E
B00000000, B00111100, B00000000,
B00011111, B11000011, B11111000,
B00000011, B10000001, B11000000,
B00000000, B01111110, B00000000,
B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000 },
{ B00000000, B00111100, B00000000, // Mouth position F
B00000000, B11000011, B00000000,
B00001111, B00000000, B11110000,
B00000001, B00000000, B10000000,
B00000000, B11000011, B00000000,
B00000000, B00111100, B00000000,
B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000 } };
// Animation sequences corresponding to each WAV. First number in
// each pair is a mouth bitmap index. Second number is the hold
// time (in frames). 255 marks end of list.
// There is no 'magic' here, the software is NOT deriving mouth
// position from the sound...the tables were determined by hand,
// just as animators do it. Further explanation here:
// http://www.idleworm.com/how/anm/03t/talk1.shtml
static const uint8_t PROGMEM
seq1[] = { 0, 2, 2, 5, 5, 3, 3, 7, // "Beware, I live!"
4, 5, 3, 4, 2, 5, 4, 3,
3, 4, 1, 5, 3, 5, 255 },
seq2[] = { 0, 1, 3, 5, 1, 5, 4, 2, // "I hunger!"
3, 2, 1, 2, 4, 4, 1, 3,
4, 2, 255 },
seq3[] = { 0, 1, 1, 2, 3, 6, 2, 5, // "Run, coward!"
0, 1, 4, 4, 5, 2, 1, 5,
3, 6, 1, 4, 255 };
static const uint8_t * const anim[] = { seq1, seq2, seq3 };
const uint8_t
blinkIndex[] PROGMEM = { 1, 2, 3, 4, 3, 2, 1 }; // Blink bitmap sequence
uint8_t
blinkCountdown = 100, // Countdown to next blink (in frames)
gazeCountdown = 75, // Countdown to next eye movement
gazeFrames = 50, // Duration of eye movement (smaller = faster)
mouthPos = 0, // Current image number for mouth
mouthCountdown = 10, // Countdown to next mouth change
newPos = 255, // New mouth position for current frame
*seq, // Animation sequence currently being played back
idx, // Current array index within animation sequence
prevBtn = 99, // Button # pressed on last loop() iteration
btnCount = 0; // Number of iterations same button has been held
int8_t
eyeX = 3, eyeY = 3, // Current eye position
newX = 3, newY = 3, // Next eye position
dX = 0, dY = 0; // Distance from prior to new position
void setup() {
Serial.begin(9600);
Serial.println(F("WAV face"));
if(!card.init()) Serial.println(F("Card init. failed!"));
if(!vol.init(card)) Serial.println(F("No partition!"));
if(!root.openRoot(vol)) Serial.println(F("Couldn't open dir"));
Serial.println(F("Files found:"));
root.ls();
// Seed random number generator from an unused analog input:
randomSeed(analogRead(A0));
// Initialize each matrix object:
for(uint8_t i=0; i<4; i++) {
matrix[i].begin(pgm_read_byte(&matrixAddr[i]));
// If using 'small' (1.2") displays vs. 'mini' (0.8"), enable this:
// matrix[i].setRotation(3);
}
// Enable pull-up resistors on three button inputs.
// Other end of each button then connects to GND.
for(uint8_t i=6; i<=8; i++) {
pinMode(i, INPUT);
digitalWrite(i, HIGH); // Enable pullup
}
}
void loop() {
uint8_t i;
// Draw eyeball in current state of blinkyness (no pupil).
matrix[MATRIX_EYES].clear();
matrix[MATRIX_EYES].drawBitmap(0, 0,
blinkImg[
(blinkCountdown < sizeof(blinkIndex)) ? // Currently blinking?
pgm_read_byte(&blinkIndex[blinkCountdown]) : // Yes, look up bitmap #
0 // No, show bitmap 0
], 8, 8, LED_ON);
// Decrement blink counter. At end, set random time for next blink.
if(--blinkCountdown == 0) blinkCountdown = random(5, 180);
if(--gazeCountdown <= gazeFrames) {
// Eyes are in motion - draw pupil at interim position
matrix[MATRIX_EYES].fillRect(
newX - (dX * gazeCountdown / gazeFrames),
newY - (dY * gazeCountdown / gazeFrames),
2, 2, LED_OFF);
if(gazeCountdown == 0) { // Last frame?
eyeX = newX; eyeY = newY; // Yes. What's new is old, then...
do { // Pick random positions until one is within the eye circle
newX = random(7); newY = random(7);
dX = newX - 3; dY = newY - 3;
} while((dX * dX + dY * dY) >= 10); // Thank you Pythagoras
dX = newX - eyeX; // Horizontal distance to move
dY = newY - eyeY; // Vertical distance to move
gazeFrames = random(3, 15); // Duration of eye movement
gazeCountdown = random(gazeFrames, 120); // Count to end of next movement
}
} else {
// Not in motion yet -- draw pupil at current static position
matrix[MATRIX_EYES].fillRect(eyeX, eyeY, 2, 2, LED_OFF);
}
// Scan buttons 6, 7, 8 looking for first button pressed...
for(i=0; (i<3) && (digitalRead(i+6) == HIGH); i++);
if(i < 3) { // Anything pressed? Yes!
if(i == prevBtn) { // Same as last time we checked? Good!
if(++btnCount == 3) { // 3 passes to 'debounce' button input
playfile((char *)pgm_read_word(&wavname[i])); // Start WAV
// Look up animation sequence # corresponding to this WAV...
seq = (uint8_t *)pgm_read_word(&anim[i]);
idx = 0; // Begin at first byte of data
newPos = pgm_read_byte(&seq[idx++]); // Initial mouth pos
mouthCountdown = pgm_read_byte(&seq[idx++]); // Hold time for pos
}
} else btnCount = 0; // Different button than before - start count over
prevBtn = i;
} else prevBtn = 99; // No buttons pressed
if(newPos != 255) { // Is the mouth in motion?
if(--mouthCountdown == 0) { // Count down frames to next position
newPos = pgm_read_byte(&seq[idx++]); // New mouth position
if(newPos == 255) { // End of list?
mouthPos = 0; // Yes, set mouth to neutral position
} else {
mouthPos = newPos; // Set mouth to new position
mouthCountdown = pgm_read_byte(&seq[idx++]); // Read hold time
}
}
} else mouthPos = 0; // Mouth not in motion -- set to neutral position
drawMouth(mouthImg[mouthPos]);
// Refresh all matrices in one quick pass
for(uint8_t i=0; i<4; i++) matrix[i].writeDisplay();
delay(20);
}
// Draw mouth image across three adjacent displays
void drawMouth(const uint8_t *img) {
for(uint8_t i=0; i<3; i++) {
matrix[MATRIX_MOUTH_LEFT + i].clear();
matrix[MATRIX_MOUTH_LEFT + i].drawBitmap(i * -8, 0, img, 24, 8, LED_ON);
}
}
// Open and start playing a WAV file
void playfile(const char *name) {
char filename[13]; // 8.3+NUL
if(wave.isplaying) wave.stop(); // Stop any currently-playing WAV
strcpy_P(filename, name); // Copy name out of PROGMEM into RAM
if(!file.open(root, filename)) {
Serial.print(F("Couldn't open file "));
Serial.println(filename);
return;
}
if(!wave.create(file)) {
Serial.println(F("Not a valid WAV"));
return;
}
wave.play();
}