1 Commits
Author SHA1 Message Date
Google Code Exporter b069f9a130 Migrating wiki contents from Google Code 2015-05-28 07:29:25 -04:00
106 changed files with 1 additions and 5705 deletions
-672
View File
@@ -1,672 +0,0 @@
/*
Charliplexing.cpp - Using timer2 with 1ms resolution
Alex Wenger <a.wenger@gmx.de> http://arduinobuch.wordpress.com/
Matt Mets <mahto@cibomahto.com> http://cibomahto.com/
Timer init code from MsTimer2 - Javier Valencia <javiervalencia80@gmail.com>
Misc functions from Benjamin Sonnatg <benjamin@sonntag.fr>
History:
2009-12-30 - V0.0 wrote the first version at 26C3/Berlin
2010-01-01 - V0.1 adding misc utility functions
(Clear, Vertical, Horizontal) comment are Doxygen complaints now
2010-05-27 - V0.2 add double-buffer mode
2010-08-18 - V0.9 Merge brightness and grayscale
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include <inttypes.h>
#include <math.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "Charliplexing.h"
/* ----------------------------------------------------------------- */
/// Determines whether the display is in single or double buffer mode
uint8_t displayMode = SINGLE_BUFFER;
/** Table for the LED multiplexing cycles
* Each frame is made of 24 bytes (for the 12 display cycles)
* There are SHADES-1 frames per buffer in grayscale mode (one for each
* brightness) and twice that many to support double-buffered grayscale.
*/
struct videoPage {
uint16_t pixels[12*(SHADES-1)];
};
/// Display buffers; only account two if DOUBLE_BUFFER is configured
#ifdef DOUBLE_BUFFER
volatile boolean videoFlipPage = false;
videoPage leds[2], *displayBuffer, *workBuffer;
#else
videoPage leds;
#define displayBuffer (&leds)
#define workBuffer (&leds)
#endif
/// Pointer inside the buffer that is currently being displayed
uint16_t* displayPointer;
// Timer counts to display each page for, plus off time
typedef struct timerInfo {
uint8_t counts[SHADES];
uint8_t prescaler[SHADES];
};
/// Timing buffers (see SetBrightness())
volatile boolean videoFlipTimer = false;
timerInfo timer[2], *frontTimer, *backTimer;
// Number of ticks of the prescaled timer per cycle per frame, based on the
// CPU clock speed and the desired frame rate.
#define TICKS (F_CPU + 6 * (FRAMERATE << SLOWSCALERSHIFT)) / (12 * (FRAMERATE << SLOWSCALERSHIFT))
// Cutoff below which we need to use a lower prescaler. This is designed
// so that TICKS is always <128, to avoid arithmetic overflow calculating
// individual "page" times.
// TODO: Technically the 128 cutoff depends on SHADES, FASTSCALERSHIFT,
// and the gamma curve.
#define CUTOFF(scaler) ((128 * 12 - 6) * FRAMERATE * scaler)
const uint8_t
#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) || defined (__AVR_ATmega8__)
# if F_CPU < CUTOFF(8)
fastPrescaler = _BV(CS20), // 1
slowPrescaler = _BV(CS21); // 8
# define SLOWSCALERSHIFT 3
# define FASTSCALERSHIFT 3
# elif F_CPU < CUTOFF(32)
fastPrescaler = _BV(CS21), // 8
slowPrescaler = _BV(CS21) | _BV(CS20); // 32
# define SLOWSCALERSHIFT 5
# define FASTSCALERSHIFT 2
# elif F_CPU < CUTOFF(64)
fastPrescaler = _BV(CS21), // 8
slowPrescaler = _BV(CS22); // 64
# define SLOWSCALERSHIFT 6
# define FASTSCALERSHIFT 3
# elif F_CPU < CUTOFF(128)
fastPrescaler = _BV(CS21) | _BV(CS20), // 32
slowPrescaler = _BV(CS22) | _BV(CS20); // 128
# define SLOWSCALERSHIFT 7
# define FASTSCALERSHIFT 2
# elif F_CPU < CUTOFF(256)
fastPrescaler = _BV(CS21) | _BV(CS20), // 32
slowPrescaler = _BV(CS22) | _BV(CS21); // 256
# define SLOWSCALERSHIFT 8
# define FASTSCALERSHIFT 3
# elif F_CPU < CUTOFF(1024)
fastPrescaler = _BV(CS22) | _BV(CS20), // 128
slowPrescaler = _BV(CS22) | _BV(CS21) | _BV(CS20); // 1024
# define SLOWSCALERSHIFT 10
# define FASTSCALERSHIFT 3
# else
# error frame rate is too low
# endif
#elif defined (__AVR_ATmega128__)
# if F_CPU < CUTOFF(8)
fastPrescaler = _BV(CS20), // 1
slowPrescaler = _BV(CS21); // 8
# define SLOWSCALERSHIFT 3
# define FASTSCALERSHIFT 3
# elif F_CPU < CUTOFF(64)
fastPrescaler = _BV(CS21), // 8
slowPrescaler = _BV(CS21) | _BV(CS20); // 64
# define SLOWSCALERSHIFT 6
# define FASTSCALERSHIFT 3
# elif F_CPU < CUTOFF(256)
fastPrescaler = _BV(CS21) | _BV(CS20), // 64
slowPrescaler = _BV(CS22); // 256
# define SLOWSCALERSHIFT 8
# define FASTSCALERSHIFT 2
# elif F_CPU < CUTOFF(1024)
fastPrescaler = _BV(CS22), // 256
slowPrescaler = _BV(CS22) | _BV(CS20); // 1024
# define SLOWSCALERSHIFT 10
# define FASTSCALERSHIFT 2
# else
# error frame rate is too low
# endif
#elif defined (__AVR_ATmega32U4__)
# if F_CPU < CUTOFF(8)
fastPrescaler = _BV(WGM12) | _BV(CS10), // 1
slowPrescaler = _BV(WGM12) | _BV(CS11); // 8
# define SLOWSCALERSHIFT 3
# define FASTSCALERSHIFT 3
# elif F_CPU < CUTOFF(64)
fastPrescaler = _BV(WGM12) | _BV(CS11), // 8
slowPrescaler = _BV(WGM12) | _BV(CS11) | _BV(CS10); // 64
# define SLOWSCALERSHIFT 6
# define FASTSCALERSHIFT 3
# elif F_CPU < CUTOFF(256)
fastPrescaler = _BV(WGM12) | _BV(CS11) | _BV(CS10), // 64
slowPrescaler = _BV(WGM12) | _BV(CS12); // 256
# define SLOWSCALERSHIFT 8
# define FASTSCALERSHIFT 2
# elif F_CPU < CUTOFF(1024)
fastPrescaler = _BV(WGM12) | _BV(CS12), // 256
slowPrescaler = _BV(WGM12) | _BV(CS12) | _BV(CS10); // 1024
# define SLOWSCALERSHIFT 10
# define FASTSCALERSHIFT 2
# else
# error frame rate is too low
# endif
#else
# error no support for this chip
#endif
static bool initialized = false;
/// Uncomment to set analog pin 5 high during interrupts, so that an
/// oscilloscope can be used to measure the processor time taken by it
#undef MEASURE_ISR_TIME
#ifdef MEASURE_ISR_TIME
const uint8_t statusPIN = 19;
#endif
/* ----------------------------------------------------------------- */
/** Table for LED Position in leds[] ram table
*/
typedef struct LEDPosition {
uint8_t high;
uint8_t cycle;
};
#if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__)
#define P(pin) ((pin < 5) ? (pin + 1) : (pin == 5) ? (2) : (pin))
#elif defined (__AVR_ATmega32U4__)
#define P(pin) ((pin == 2) ? (1) : (pin == 3) ? (0) : (pin == 5) ? (2) : (pin == 6) ? (7) : (pin == 7) ? (5) : (pin == 12) ? (6) : (pin == 13) ? (3) : (pin))
#else
#define P(pin) (pin)
#endif
#if !defined (__AVR_ATmega32U4__)
#define L(high, low) { P(high), (P(low) - 2) }
#else
// Since the offset of 2 doesn't have to do anything with the ports anymore and just adds complexity we omit it.
#define L(high, low) { P(high), P(low) }
#endif
const LEDPosition PROGMEM ledMap[126] = {
L(13, 5), L(13, 6), L(13, 7), L(13, 8), L(13, 9), L(13,10), L(13,11), L(13,12),
L(13, 4), L( 4,13), L(13, 3), L( 3,13), L(13, 2), L( 2,13),
L(12, 5), L(12, 6), L(12, 7), L(12, 8), L(12, 9), L(12,10), L(12,11), L(12,13),
L(12, 4), L( 4,12), L(12, 3), L( 3,12), L(12, 2), L( 2,12),
L(11, 5), L(11, 6), L(11, 7), L(11, 8), L(11, 9), L(11,10), L(11,12), L(11,13),
L(11, 4), L( 4,11), L(11, 3), L( 3,11), L(11, 2), L( 2,11),
L(10, 5), L(10, 6), L(10, 7), L(10, 8), L(10, 9), L(10,11), L(10,12), L(10,13),
L(10, 4), L( 4,10), L(10, 3), L( 3,10), L(10, 2), L( 2,10),
L( 9, 5), L( 9, 6), L( 9, 7), L( 9, 8), L( 9,10), L( 9,11), L( 9,12), L( 9,13),
L( 9, 4), L( 4, 9), L( 9, 3), L( 3, 9), L( 9, 2), L( 2, 9),
L( 8, 5), L( 8, 6), L( 8, 7), L( 8, 9), L( 8,10), L( 8,11), L( 8,12), L( 8,13),
L( 8, 4), L( 4, 8), L( 8, 3), L( 3, 8), L( 8, 2), L( 2, 8),
L( 7, 5), L( 7, 6), L( 7, 8), L( 7, 9), L( 7,10), L( 7,11), L( 7,12), L( 7,13),
L( 7, 4), L( 4, 7), L( 7, 3), L( 3, 7), L( 7, 2), L( 2, 7),
L( 6, 5), L( 6, 7), L( 6, 8), L( 6, 9), L( 6,10), L( 6,11), L( 6,12), L( 6,13),
L( 6, 4), L( 4, 6), L( 6, 3), L( 3, 6), L( 6, 2), L( 2, 6),
L( 5, 6), L( 5, 7), L( 5, 8), L( 5, 9), L( 5,10), L( 5,11), L( 5,12), L( 5,13),
L( 5, 4), L( 4, 5), L( 5, 3), L( 3, 5), L( 5, 2), L( 2, 5),
};
#undef P(pin)
#undef L(high, low)
/*
Converting the pin numbers to indices usable with Leonardo.
pin number -> Leonardo port number -> logical index
---------------------------------------------------
02 -> D1 -> 01
03 -> D0 -> 00
04 -> D4 -> 04
05 -> C6 -> 02
06 -> D7 -> 07
07 -> E6 -> 05
08 -> B4 -> 08
09 -> B5 -> 09
10 -> B6 -> 10
11 -> B7 -> 11
12 -> D6 -> 06
13 -> C7 -> 03
This yields the horrible macro
#define P(pin) ((pin == 2) ? (1) : (pin == 3) ? (0) : (pin == 5) ? (2) : (pin == 6) ? (7) : (pin == 7) ? (5) : (pin == 12) ? (6) : (pin == 13) ? (3) : (pin))
TODO If anyone has a better idea how to handle this, feel free to change it.
TODO Another possibility would be to just add another ledMap without the remap macros.
The order in which the LEDs light up is now pretty random, but shouldn't be visible with a high update rate.
The used ports are
B7, B6, B5, B4, --, --, --, --
C7, C6, --, --, --, --, --, --
D7, D6, --, D4, --, --, D1, D0
--, E6, --, --, --, --, --, --
Luckily, these can merge together into the following contiguous order, stored in the 16bit pixels variable.
--, --, --, --, B7, B6, B5, B4
D7, D6, E6, D4, C7, C6, D1, D0
Now the ISR can work in the same way, it just has to extract the ports like this
PORTB = (pixels >> 4) & 0xF0);
PORTC = (pixels << 4) & 0xC0);
PORTD = (pixels << 0) & 0xD3);
PORTE = (pixels << 1) & 0x40);
*/
/* ----------------------------------------------------------------- */
/** Constructor : Initialize the interrupt code.
* should be called in setup();
*/
void LedSign::Init(uint8_t mode)
{
#ifdef MEASURE_ISR_TIME
pinMode(statusPIN, OUTPUT);
digitalWrite(statusPIN, LOW);
#endif
#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__)
TIMSK2 &= ~(_BV(TOIE2) | _BV(OCIE2A));
TCCR2A &= ~(_BV(WGM21) | _BV(WGM20));
TCCR2B &= ~_BV(WGM22);
ASSR &= ~_BV(AS2);
#elif defined (__AVR_ATmega8__)
TIMSK &= ~(_BV(TOIE2) | _BV(OCIE2));
TCCR2 &= ~(_BV(WGM21) | _BV(WGM20));
ASSR &= ~_BV(AS2);
#elif defined (__AVR_ATmega128__)
TIMSK &= ~(_BV(TOIE2) | _BV(OCIE2));
TCCR2 &= ~(_BV(WGM21) | _BV(WGM20));
#elif defined (__AVR_ATmega32U4__)
// The only 8bit timer on the Leonardo is used by default, so we use the 16bit Timer1
// in CTC mode with a compare value of 256 to achieve the same behaviour.
TIMSK1 &= ~(_BV(TOIE1) | _BV(OCIE1A));
TCCR1A &= ~(_BV(WGM10) | _BV(WGM11));
OCR1A = 256;
#endif
// Record whether we are in single or double buffer mode
displayMode = mode;
#ifdef DOUBLE_BUFFER
videoFlipPage = false;
// If we are in single buffered mode, point the work buffer
// at the same physical buffer as the display buffer. Otherwise,
// point it at the second physical buffer.
if (displayMode & DOUBLE_BUFFER)
workBuffer = &leds[1];
else
workBuffer = &leds[0];
displayBuffer = &leds[0];
#endif
// Point the display buffer to the first physical buffer
displayPointer = displayBuffer->pixels;
// Set up the timer buffering
videoFlipTimer = false;
backTimer = &timer[1];
frontTimer = &timer[0];
LedSign::SetBrightness(127);
// Then start the display
#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__)
TIMSK2 |= _BV(TOIE2);
TCCR2B = fastPrescaler;
#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega128__)
TIMSK |= _BV(TOIE2);
TCCR2 = fastPrescaler;
#elif defined (__AVR_ATmega32U4__)
// Enable output compare match interrupt
TIMSK1 |= _BV(OCIE1A);
TCCR1B = fastPrescaler;
#endif
// interrupt ASAP
#if !defined (__AVR_ATmega32U4__)
TCNT2 = 255;
#else
TCNT1 = 255;
#endif
initialized = true;
}
#ifdef DOUBLE_BUFFER
/* ----------------------------------------------------------------- */
/** Signal that the front and back buffers should be flipped
* @param blocking if true : wait for flip before returning, if false :
* return immediately.
*/
void LedSign::Flip(bool blocking)
{
// Just set the flip flag, the buffer will flip between redraws
videoFlipPage = true;
// If we are blocking, sit here until the page flips.
if (blocking)
while (videoFlipPage)
;
}
#endif
/* ----------------------------------------------------------------- */
/** Clear the screen completely
* @param set if 1 : make all led ON, if not set or 0 : make all led OFF
*/
void LedSign::Clear(uint8_t c) {
for (uint8_t x=0; x<DISPLAY_COLS; x++)
for (uint8_t y=0; y<DISPLAY_ROWS; y++)
Set(x, y, c);
}
/* ----------------------------------------------------------------- */
/** Clear an horizontal line completely
* @param y is the y coordinate of the line to clear/light [0-8]
* @param set if 1 : make all led ON, if not set or 0 : make all led OFF
*/
void LedSign::Horizontal(uint8_t y, uint8_t c) {
for (uint8_t x=0; x<DISPLAY_COLS; x++)
Set(x, y, c);
}
/* ----------------------------------------------------------------- */
/** Clear a vertical line completely
* @param x is the x coordinate of the line to clear/light [0-13]
* @param set if 1 : make all led ON, if not set or 0 : make all led OFF
*/
void LedSign::Vertical(uint8_t x, uint8_t c) {
for (uint8_t y=0; y<DISPLAY_ROWS; y++)
Set(x, y, c);
}
/* ----------------------------------------------------------------- */
/** Set : switch on and off the leds. All the position #for char in frameString:
* calculations are done here, so we don't need to do in the
* interrupt code
*/
void LedSign::Set(uint8_t x, uint8_t y, uint8_t c)
{
#ifdef GRAYSCALE
// If we aren't in grayscale mode, just map any pin brightness to max
if (c > 0 && !(displayMode & GRAYSCALE))
c = SHADES-1;
#else
if (c)
c = SHADES-1;
#endif
const LEDPosition *map = &ledMap[x+y*DISPLAY_COLS];
uint16_t mask = 1 << pgm_read_byte_near(&map->high);
uint8_t cycle = pgm_read_byte_near(&map->cycle);
uint16_t *p = &workBuffer->pixels[cycle*(SHADES-1)];
uint8_t i;
for (i = 0; i < c; i++)
*p++ |= mask; // ON;
for (; i < SHADES-1; i++)
*p++ &= ~mask; // OFF;
}
uint8_t LedSign::DisplayMode(){
return displayMode;
}
/* Set the overall brightness of the screen
* @param brightness LED brightness, from 0 (off) to 127 (full on)
*/
void LedSign::SetBrightness(uint8_t brightness)
{
// An exponential fit seems to approximate a (perceived) linear scale
const unsigned long brightnessPercent = ((unsigned int)brightness * (unsigned int)brightness + 8) >> 4; /*7b*2-4b = 10b*/
/* ---- This needs review! Please review. -- thilo */
// set up page counts
// TODO: make SHADES a function parameter. This would require some refactoring.
uint8_t i;
const int ticks = TICKS;
const unsigned long m = (ticks << FASTSCALERSHIFT) * brightnessPercent; /*10b*/
#define C(x) ((m * (unsigned long)(x * 1024) + (1<<19)) >> 20) /*10b+10b-20b=0b*/
#if SHADES == 2
const int counts[SHADES] = {
0.0f,
C(1.0f),
};
#elif SHADES == 8
const int counts[SHADES] = {
0.0f,
C(0.030117819624378613658712f),
C(0.104876339357015456218728f),
C(0.217591430058779512857041f),
C(0.365200625214741116475101f),
C(0.545719579451565749226202f),
C(0.757697368024318811680598f),
C(1.0f),
};
#else
// NOTE: Changing "scale" invalidates any tables above!
const float scale = 1.8f;
int counts[SHADES];
counts[0] = 0.0f;
for (i=1; i<SHADES; i++)
counts[i] = C(pow(i / (float)(SHADES - 1), scale));
#endif
// Wait until the previous brightness request goes through
while (videoFlipTimer)
;
// Compute on time for each of the pages
// Use the fast timer; slow timer is only useful for < 3 shades.
for (i = 0; i < SHADES - 1; i++) {
int interval = counts[i + 1] - counts[i];
backTimer->counts[i] = 256 - (interval ? interval : 1);
backTimer->prescaler[i] = fastPrescaler;
}
// Compute off time
int interval = ticks - (counts[i] >> FASTSCALERSHIFT);
backTimer->counts[i] = 256 - (interval ? interval : 1);
backTimer->prescaler[i] = slowPrescaler;
if (!initialized)
*frontTimer = *backTimer;
/* ---- End of "This needs review! Please review." -- thilo */
// Have the ISR update the timer registers next run
videoFlipTimer = true;
}
/* ----------------------------------------------------------------- */
/** The Interrupt code goes here !
*/
#if !defined (__AVR_ATmega32U4__)
ISR(TIMER2_OVF_vect) {
#else
ISR(TIMER1_COMPA_vect) {
#endif
#ifdef MEASURE_ISR_TIME
digitalWrite(statusPIN, HIGH);
#endif
// For each cycle, we have potential SHADES pages to display.
// Once every page has been displayed, then we move on to the next
// cycle.
// 24 Cycles of Matrix
static uint8_t cycle = 0;
// SHADES pages to display
static uint8_t page = 0;
#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__)
TCCR2B = frontTimer->prescaler[page];
#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega128__)
TCCR2 = frontTimer->prescaler[page];
#elif defined (__AVR_ATmega32U4__)
TCCR1B = frontTimer->prescaler[page];
#endif
#if !defined (__AVR_ATmega32U4__)
TCNT2 = frontTimer->counts[page];
#else
TCNT1 = frontTimer->counts[page];
#endif
#if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__)
static uint16_t sink = 0;
PINE = (sink << 1) & 0x38;
PING = (sink << 0) & 0x20;
PINH = (sink >> 3) & 0x78;
PINB = (sink >> 6) & 0xf0;
//delayMicroseconds(1);
DDRE &= ~0x38;
DDRG &= ~0x20;
DDRH &= ~0x78;
DDRB &= ~0xf0;
sink = 1 << (cycle+2);
uint16_t pins = sink;
if (page < SHADES - 1)
pins |= *displayPointer++;
PINE = (PORTE ^ (pins << 1)) & 0x38;
PING = (PORTG ^ (pins << 0)) & 0x20;
PINH = (PORTH ^ (pins >> 3)) & 0x78;
PINB = (PORTB ^ (pins >> 6)) & 0xf0;
//delayMicroseconds(1);
DDRE |= (pins << 1) & 0x38;
DDRG |= (pins << 0) & 0x20;
DDRH |= (pins >> 3) & 0x78;
DDRB |= (pins >> 6) & 0xf0;
PINE = (sink << 1) & 0x38;
PING = (sink << 0) & 0x20;
PINH = (sink >> 3) & 0x78;
PINB = (sink >> 6) & 0xf0;
#elif defined (__AVR_ATmega32U4__)
static uint16_t sink = 0;
PINB = (sink >> 4) & 0xF0;
PINC = (sink << 4) & 0xC0;
PIND = (sink << 0) & 0xD3;
PINE = (sink << 1) & 0x40;
//delayMicroseconds(1);
DDRB &= ~0xF0;
DDRC &= ~0xC0;
DDRD &= ~0xD3;
DDRE &= ~0x40;
sink = 1 << (cycle);
uint16_t pins = sink;
if (page < SHADES - 1)
pins |= *displayPointer++;
PINB = (PORTB ^ (pins >> 4)) & 0xF0;
PINC = (PORTC ^ (pins << 4)) & 0xC0;
PIND = (PORTD ^ (pins << 0)) & 0xD3;
PINE = (PORTE ^ (pins << 1)) & 0x40;
//delayMicroseconds(1);
DDRB |= (pins >> 4) & 0xF0;
DDRC |= (pins << 4) & 0xC0;
DDRD |= (pins << 0) & 0xD3;
DDRE |= (pins << 1) & 0x40;
PINB = (sink >> 4) & 0xF0;
PINC = (sink << 4) & 0xC0;
PIND = (sink << 0) & 0xD3;
PINE = (sink << 1) & 0x40;
#else
static uint16_t sink = 0;
// Set sink pin to Vcc/source, turning off current.
PIND = sink;
PINB = (sink >> 8);
//delayMicroseconds(1);
// Set pins to input mode; Vcc/source become pullups.
DDRD = 0;
DDRB = 0;
sink = 1 << (cycle+2);
uint16_t pins = sink;
if (page < SHADES - 1)
pins |= *displayPointer++;
// Enable pullups on new output pins.
PORTD = pins;
PORTB = (pins >> 8);
//delayMicroseconds(1);
// Set pins to output mode; pullups become Vcc/source.
DDRD = pins;
DDRB = (pins >> 8);
// Set sink pin to GND/sink, turning on current.
PIND = sink;
PINB = (sink >> 8);
#endif
page++;
if (page >= SHADES) {
page = 0;
cycle++;
if (cycle >= 12) {
cycle = 0;
#ifdef DOUBLE_BUFFER
// If the page should be flipped, do it here.
if (videoFlipPage)
{
videoFlipPage = false;
videoPage* temp = displayBuffer;
displayBuffer = workBuffer;
workBuffer = temp;
}
#endif
if (videoFlipTimer) {
videoFlipTimer = false;
timerInfo* temp = frontTimer;
frontTimer = backTimer;
backTimer = temp;
}
displayPointer = displayBuffer->pixels;
}
}
#ifdef MEASURE_ISR_TIME
digitalWrite(statusPIN, LOW);
#endif
}
-42
View File
@@ -1,42 +0,0 @@
/*
Charliplexing.h - Library for controlling the charliplexed led board
from JimmiePRodgers.com
Created by Alex Wenger, December 30, 2009.
Modified by Matt Mets, May 28, 2010.
Released into the public domain.
*/
#ifndef Charliplexing_h
#define Charliplexing_h
#include <inttypes.h>
#define SINGLE_BUFFER 0
#define DOUBLE_BUFFER 1 // comment out to save memory
#define GRAYSCALE 2 // comment out to save memory
#define FRAMERATE 80UL // Desired number of frames per second
#define DISPLAY_COLS 14 // Number of columns in the display
#define DISPLAY_ROWS 9 // Number of rows in the display
#ifdef GRAYSCALE
#define SHADES 8 // Number of distinct shades to display, including black, i.e. OFF
#else
#define SHADES 2
#endif
namespace LedSign
{
extern void Init(uint8_t mode = SINGLE_BUFFER);
extern void Set(uint8_t x, uint8_t y, uint8_t c = 1);
extern void SetBrightness(uint8_t brightness);
#ifdef DOUBLE_BUFFER
extern void Flip(bool blocking = false);
#endif
extern void Clear(uint8_t c = 0);
extern void Horizontal(uint8_t y, uint8_t c = 0);
extern void Vertical(uint8_t x, uint8_t c = 0);
extern uint8_t DisplayMode();
};
#endif
-126
View File
@@ -1,126 +0,0 @@
/*
Figure drawing library
Copyright 2009/2010 Benjamin Sonntag <benjamin@sonntag.fr> http://benjamin.sonntag.fr/
History:
2010-01-01 - V0.0 Initial code at Berlin after 26C3
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include "Figure.h"
#include "Charliplexing.h"
#include <Arduino.h>
#include <inttypes.h>
#include <avr/pgmspace.h>
#define C(c,r) ((c << 4) | r)
PROGMEM const uint8_t figuresData[][14] = {
{ C(0,0), C(1,0), C(2,0), C(0,1), C(2,1), C(0,2), C(2,2), C(0,3), C(2,3), C(0,4), C(1,4), C(2,4), 255, 255 },
{ C(1,0), C(0,1), C(1,1), C(1,2), C(1,3), C(0,4), C(1,4), C(2,4), 255, 255, 255, 255, 255, 255 },
{ C(0,0), C(1,0), C(2,0), C(2,1), C(1,2), C(0,3), C(0,4), C(1,4), C(2,4), 255, 255, 255, 255, 255 },
{ C(0,0), C(1,0), C(2,0), C(2,1), C(0,2), C(1,2), C(2,3), C(0,4), C(1,4), C(2,4), 255, 255, 255, 255 },
{ C(0,0), C(2,0), C(0,1), C(2,1), C(0,2), C(1,2), C(2,2), C(2,3), C(2,4), 255, 255, 255, 255, 255 },
{ C(0,0), C(1,0), C(2,0), C(0,1), C(0,2), C(1,2), C(2,2), C(2,3), C(0,4), C(1,4), C(2,4), 255, 255, 255 },
{ C(0,0), C(1,0), C(2,0), C(0,1), C(0,2), C(1,2), C(2,2), C(0,3), C(2,3), C(0,4), C(1,4), C(2,4), 255, 255 },
{ C(0,0), C(1,0), C(2,0), C(2,1), C(2,2), C(1,3), C(1,4), 255, 255, 255, 255, 255, 255, 255 },
{ C(0,0), C(1,0), C(2,0), C(0,1), C(2,1), C(0,2), C(1,2), C(2,2), C(0,3), C(2,3), C(0,4), C(1,4), C(2,4), 255 },
{ C(0,0), C(1,0), C(2,0), C(0,1), C(2,1), C(0,2), C(1,2), C(2,2), C(2,3), C(0,4), C(1,4), 255, 255, 255 }
};
/* ----------------------------------------------------------------- */
/** Draws a figure (0-9). You should call it with set=1,
* wait a little them call it again with set=0
* @param figure is the figure [0-9]
* @param x,y coordinates,
* @param set is 1 or 0 to draw or clear it
*/
void Figure::Draw(uint8_t figure, int x, int y, uint8_t c) {
const uint8_t* character = figuresData[figure];
for (;;) {
uint8_t data = pgm_read_byte_near(character++);
if (data == 255)
break;
uint8_t charCol = data >> 4, charRow = data & 15;
if (
charCol+x<DISPLAY_COLS &&
charCol+x>=0 &&
charRow+y<DISPLAY_ROWS &&
charRow+y>=0
) {
LedSign::Set(charCol+x, charRow+y, c);
}
}
}
/* ----------------------------------------------------------------- */
/** Draw a figure in the other direction (rotated 90°)
* You should call it with set=1,
* wait a little them call it again with set=0
* @param figure is the figure [0-9]
* @param x,y coordinates,
* @param set is 1 or 0 to draw or clear it
*/
void Figure::Draw90(uint8_t figure, int x, int y, uint8_t c) {
const uint8_t* character = figuresData[figure];
for (;;) {
uint8_t data = pgm_read_byte_near(character++);
if (data == 255)
break;
uint8_t charCol = data >> 4, charRow = data & 15;
if (
(5-charRow)+x<DISPLAY_COLS &&
(5-charRow)+x>=0 &&
charCol+y<DISPLAY_ROWS &&
charCol+y>=0
) {
LedSign::Set((5-charRow)+x, charCol+y, c);
}
}
}
/* ----------------------------------------------------------------- */
/** Scroll a number from right to left
* remove unused figures (0 at the left)
* valid for up to 7 figures.
* @param value is the value to draw and scroll
* @param x is the coordinate where we put the top of the figure [0-13]
*/
void Figure::Scroll90(unsigned long value,uint8_t x) {
int8_t i,j,k;
uint8_t figures[10];
j = 0;
do {
figures[j++] = value%10;
value/=10;
} while (value);
for (i=9+4*j; i>=0; i--) {
for (k=j; k>0; k--)
Figure::Draw90(figures[k-1], x, i-4*k, SHADES-1);
delay(100);
for (k=j; k>0; k--)
Figure::Draw90(figures[k-1], x, i-4*k, 0);
}
}
-38
View File
@@ -1,38 +0,0 @@
/*
Figure drawing library
Copyright 2009/2010 Benjamin Sonntag <benjamin@sonntag.fr> http://benjamin.sonntag.fr/
History:
2010-01-01 - V0.0 Initial code at Berlin after 26C3
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#ifndef Figures_h
#define Figures_h
#include <inttypes.h>
namespace Figure
{
extern void Draw(uint8_t figure, int x, int y, uint8_t c=1);
extern void Draw90(uint8_t figure, int x, int y, uint8_t c=1);
extern void Scroll90(unsigned long value, uint8_t x=3);
}
#endif
-206
View File
@@ -1,206 +0,0 @@
#include <avr/pgmspace.h>
/*
Font drawing library
Copyright 2009/2010 Benjamin Sonntag <benjamin@sonntag.fr> http://benjamin.sonntag.fr/
History:
2010-01-01 - V0.0 Initial code at Berlin after 26C3
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include "Font.h"
#include "Charliplexing.h"
#include <inttypes.h>
#define L(x) letter_##x
#define C(x) PROGMEM const uint8_t L(x)[]
#define P(c,r) ((c << 4) | r)
#define END 255
C(33) = { P(1,1), P(1,2), P(1,3), P(1,4), P(1,5), P(1,7), END };
C(39) = { P(1,3), P(2,1), P(2,2), END };
C(44) = { P(1,7), P(2,5), P(2,6), END };
C(48) = { P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(1,1), P(1,7), P(2,1), P(2,7), P(3,1), P(3,7), P(4,2), P(4,3), P(4,4), P(4,5), P(4,6), END };
C(49) = { P(1,2), P(1,7), P(2,1), P(2,2), P(2,3), P(2,4), P(2,5), P(2,6), P(2,7), P(3,7), END };
C(50) = { P(0,2), P(0,5), P(0,6), P(0,7), P(1,1), P(1,4), P(1,7), P(2,1), P(2,4), P(2,7), P(3,1), P(3,4), P(3,7), P(4,2), P(4,3), P(4,7), END };
C(51) = { P(0,2), P(0,6), P(1,1), P(1,4), P(1,7), P(2,1), P(2,4), P(2,7), P(3,1), P(3,4), P(3,7), P(4,2), P(4,3), P(4,5), P(4,6), END };
C(52) = { P(0,4), P(0,5), P(1,3), P(1,5), P(2,2), P(2,5), P(3,1), P(3,2), P(3,3), P(3,4), P(3,5), P(3,6), P(3,7), P(4,5), END };
C(53) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,7), P(1,1), P(1,4), P(1,7), P(2,1), P(2,4), P(2,7), P(3,1), P(3,4), P(3,7), P(4,1), P(4,5), P(4,6), END };
C(54) = { P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(1,1), P(1,4), P(1,7), P(2,1), P(2,4), P(2,7), P(3,1), P(3,4), P(3,7), P(4,2), P(4,5), P(4,6), END };
C(55) = { P(0,1), P(1,1), P(2,1), P(2,5), P(2,6), P(2,7), P(3,1), P(3,3), P(3,4), P(4,1), P(4,2), END };
C(56) = { P(0,2), P(0,3), P(0,5), P(0,6), P(1,1), P(1,4), P(1,7), P(2,1), P(2,4), P(2,7), P(3,1), P(3,4), P(3,7), P(4,2), P(4,3), P(4,5), P(4,6), END };
C(57) = { P(0,2), P(0,3), P(0,7), P(1,1), P(1,4), P(1,7), P(2,1), P(2,4), P(2,7), P(3,1), P(3,4), P(3,7), P(4,2), P(4,3), P(4,4), P(4,5), P(4,6), END };
C(65) = { P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(0,7), P(1,1), P(1,4), P(2,1), P(2,4), P(3,2), P(3,3), P(3,4), P(3,5), P(3,6), P(3,7), END };
C(66) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(0,7), P(1,1), P(1,4), P(1,7), P(2,1), P(2,4), P(2,7), P(3,2), P(3,3), P(3,5), P(3,6), END };
C(67) = { P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(1,1), P(1,7), P(2,1), P(2,7), P(3,2), P(3,6), END };
C(68) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(0,7), P(1,1), P(1,7), P(2,1), P(2,7), P(3,2), P(3,3), P(3,4), P(3,5), P(3,6), END };
C(69) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(0,7), P(1,1), P(1,4), P(1,7), P(2,1), P(2,4), P(2,7), P(3,1), P(3,7), END };
C(70) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(0,7), P(1,1), P(1,4), P(2,1), P(2,4), P(3,1), END };
C(71) = { P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(1,1), P(1,7), P(2,1), P(2,5), P(2,7), P(3,2), P(3,5), P(3,6), P(3,7), END };
C(72) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(0,7), P(1,4), P(2,4), P(3,1), P(3,2), P(3,3), P(3,4), P(3,5), P(3,6), P(3,7), END };
C(73) = { P(0,1), P(0,7), P(1,1), P(1,2), P(1,3), P(1,4), P(1,5), P(1,6), P(1,7), P(2,1), P(2,7), END };
C(74) = { P(0,7), P(1,1), P(1,7), P(2,1), P(2,2), P(2,3), P(2,4), P(2,5), P(2,6), P(3,1), END };
C(75) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(0,7), P(1,4), P(2,3), P(2,5), P(3,1), P(3,2), P(3,6), P(3,7), END };
C(76) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(0,7), P(1,7), P(2,7), P(3,7), END };
C(77) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(0,7), P(1,2), P(2,3), P(3,2), P(4,1), P(4,2), P(4,3), P(4,4), P(4,5), P(4,6), P(4,7), END };
C(78) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(0,7), P(1,3), P(2,4), P(3,1), P(3,2), P(3,3), P(3,4), P(3,5), P(3,6), P(3,7), END };
C(79) = { P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(1,1), P(1,7), P(2,1), P(2,7), P(3,2), P(3,3), P(3,4), P(3,5), P(3,6), END };
C(80) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(0,7), P(1,1), P(1,4), P(2,1), P(2,4), P(3,2), P(3,3), END };
C(81) = { P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(1,1), P(1,7), P(2,1), P(2,6), P(3,2), P(3,3), P(3,4), P(3,5), P(3,7), END };
C(82) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(0,7), P(1,1), P(1,4), P(2,1), P(2,4), P(2,5), P(3,2), P(3,3), P(3,6), P(3,7), END };
C(83) = { P(0,2), P(0,3), P(0,6), P(1,1), P(1,4), P(1,7), P(2,1), P(2,4), P(2,7), P(3,2), P(3,5), P(3,6), END };
C(84) = { P(0,1), P(1,1), P(1,2), P(1,3), P(1,4), P(1,5), P(1,6), P(1,7), P(2,1), END };
C(85) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(1,7), P(2,7), P(3,1), P(3,2), P(3,3), P(3,4), P(3,5), P(3,6), END };
C(86) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,5), P(1,6), P(2,7), P(3,6), P(4,1), P(4,2), P(4,3), P(4,4), P(4,5), END };
C(87) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(1,7), P(2,4), P(2,5), P(2,6), P(3,7), P(4,1), P(4,2), P(4,3), P(4,4), P(4,5), P(4,6), END };
C(88) = { P(0,1), P(0,2), P(0,6), P(0,7), P(1,3), P(1,5), P(2,4), P(3,3), P(3,5), P(4,1), P(4,2), P(4,6), P(4,7), END };
C(89) = { P(0,1), P(0,2), P(1,3), P(2,4), P(2,5), P(2,6), P(2,7), P(3,3), P(4,1), P(4,2), END };
C(90) = { P(0,1), P(0,6), P(0,7), P(1,1), P(1,5), P(1,7), P(2,1), P(2,4), P(2,7), P(3,1), P(3,3), P(3,7), P(4,1), P(4,2), P(4,7), END };
#ifdef LOWERCASE
C(97) = { P(0,5), P(0,6), P(1,4), P(1,7), P(2,4), P(2,7), P(3,4), P(3,5), P(3,6), P(3,7), END };
C(98) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(0,7), P(1,4), P(1,7), P(2,4), P(2,7), P(3,5), P(3,6), END };
C(99) = { P(0,5), P(0,6), P(1,4), P(1,7), P(2,4), P(2,7), END };
C(100) = { P(0,5), P(0,6), P(1,4), P(1,7), P(2,4), P(2,7), P(3,1), P(3,2), P(3,3), P(3,4), P(3,5), P(3,6), P(3,7), END };
C(101) = { P(0,4), P(0,5), P(0,6), P(1,3), P(1,5), P(1,7), P(2,3), P(2,5), P(2,7), P(3,4), P(3,5), P(3,7), END };
C(102) = { P(0,4), P(1,1), P(1,2), P(1,3), P(1,4), P(1,5), P(1,6), P(1,7), P(2,1), P(2,4), P(3,1), END };
C(103) = { P(0,4), P(0,5), P(0,8), P(1,3), P(1,6), P(1,8), P(2,3), P(2,6), P(2,8), P(3,3), P(3,4), P(3,5), P(3,6), P(3,7), END };
C(104) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(0,7), P(1,4), P(2,4), P(3,5), P(3,6), P(3,7), END };
C(105) = { P(0,2), P(0,4), P(0,5), P(0,6), P(0,7), END };
C(106) = { P(0,8), P(1,2), P(1,4), P(1,5), P(1,6), P(1,7), P(1,8), END };
C(107) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(0,7), P(1,5), P(2,4), P(2,6), P(3,7), END };
C(108) = { P(0,1), P(0,2), P(0,3), P(0,4), P(0,5), P(0,6), P(0,7), END };
C(109) = { P(0,4), P(0,5), P(0,6), P(0,7), P(1,4), P(2,5), P(2,6), P(2,7), P(3,4), P(4,5), P(4,6), P(4,7), END };
C(110) = { P(0,4), P(0,5), P(0,6), P(0,7), P(1,4), P(2,4), P(3,5), P(3,6), P(3,7), END };
C(111) = { P(0,5), P(0,6), P(1,4), P(1,7), P(2,4), P(2,7), P(3,5), P(3,6), END };
C(112) = { P(0,4), P(0,5), P(0,6), P(0,7), P(0,8), P(1,4), P(1,7), P(2,4), P(2,7), P(3,5), P(3,6), END };
C(113) = { P(0,5), P(0,6), P(1,4), P(1,7), P(2,4), P(2,7), P(3,4), P(3,5), P(3,6), P(3,7), P(3,8), END };
C(114) = { P(0,4), P(0,5), P(0,6), P(0,7), P(1,4), P(2,4), END };
C(115) = { P(0,4), P(0,7), P(1,3), P(1,5), P(1,7), P(2,3), P(2,5), P(2,7), P(3,3), P(3,6), END };
C(116) = { P(0,4), P(1,3), P(1,4), P(1,5), P(1,6), P(1,7), P(2,4), P(2,7), P(3,7), END };
C(117) = { P(0,4), P(0,5), P(0,6), P(1,7), P(2,7), P(3,4), P(3,5), P(3,6), P(3,7), END };
C(118) = { P(0,4), P(0,5), P(0,6), P(1,7), P(2,4), P(2,5), P(2,6), END };
C(119) = { P(0,4), P(0,5), P(0,6), P(1,7), P(2,4), P(2,5), P(2,6), P(3,7), P(4,4), P(4,5), P(4,6), P(4,7), END };
C(120) = { P(0,4), P(0,7), P(1,5), P(1,6), P(2,4), P(2,7), END };
C(121) = { P(0,4), P(0,5), P(0,6), P(1,7), P(2,7), P(3,4), P(3,5), P(3,6), P(3,7), P(3,8), END };
C(122) = { P(0,4), P(0,7), P(1,4), P(1,6), P(1,7), P(2,4), P(2,5), P(2,7), P(3,4), P(3,7), END };
#endif
const unsigned char fontMin=33;
#ifdef LOWERCASE
const unsigned char fontMax=122;
#else
const unsigned char fontMax=90;
#endif
PROGMEM const uint8_t* const font[fontMax-fontMin+1] = {
L(33) /*!*/, 0, 0, 0, 0, 0,
L(39) /*'*/, 0, 0, 0, 0,
L(44) /*,*/, 0, 0, 0,
L(48) /*0*/, L(49) /*1*/, L(50) /*2*/, L(51) /*3*/, L(52) /*4*/,
L(53) /*5*/, L(54) /*6*/, L(55) /*7*/, L(56) /*8*/, L(57) /*9*/,
0, 0, 0, 0, 0, 0, 0,
L(65) /*A*/, L(66) /*B*/, L(67) /*C*/, L(68) /*D*/, L(69) /*E*/,
L(70) /*F*/, L(71) /*G*/, L(72) /*H*/, L(73) /*I*/, L(74) /*J*/,
L(75) /*K*/, L(76) /*L*/, L(77) /*M*/, L(78) /*N*/, L(79) /*O*/,
L(80) /*P*/, L(81) /*Q*/, L(82) /*R*/, L(83) /*S*/, L(84) /*T*/,
L(85) /*U*/, L(86) /*V*/, L(87) /*W*/, L(88) /*X*/, L(89) /*Y*/,
L(90) /*Z*/,
#ifdef LOWERCASE
0, 0, 0, 0, 0, 0,
L(97) /*a*/, L(98) /*b*/, L(99) /*c*/, L(100) /*d*/, L(101) /*e*/,
L(102) /*f*/, L(103) /*g*/, L(104) /*h*/, L(105) /*i*/, L(106) /*j*/,
L(107) /*k*/, L(108) /*l*/, L(109) /*m*/, L(110) /*n*/, L(111) /*o*/,
L(112) /*p*/, L(113) /*q*/, L(114) /*r*/, L(115) /*s*/, L(116) /*t*/,
L(117) /*u*/, L(118) /*v*/, L(119) /*w*/, L(120) /*x*/, L(121) /*y*/,
L(122) /*z*/,
#endif
};
/* ----------------------------------------------------------------- */
/** Draws a figure (0-9). You should call it with c=1,
* wait a little them call it again with c=0
* @param figure is the figure [0-9]
* @param x,y coordinates,
* @param c is 1 or 0 to draw or clear it
*/
uint8_t Font::Draw(unsigned char letter, int x, int y, uint8_t c) {
uint8_t maxx=0, data;
const uint8_t* character;
if (letter==' ') return 3+2;
if (letter<fontMin || letter>fontMax) {
return 0;
}
character = (const uint8_t *)pgm_read_word_near(&font[letter-fontMin]);
data = pgm_read_byte_near(character++);
while (data != END) {
uint8_t charCol = data >> 4, charRow = data & 15;
if (charCol>maxx) maxx=charCol;
if (
charCol + x <DISPLAY_COLS &&
charCol + x >=0 &&
charRow + y <DISPLAY_ROWS &&
charRow + y >=0
) {
LedSign::Set(charCol + x, charRow+y, c);
}
data = pgm_read_byte_near(character++);
}
return maxx+2;
}
/* ----------------------------------------------------------------- */
/** Draw a figure in the other direction (rotated 90°)
* @param figure is the figure [0-9]
* @param x,y coordinates,
* @param c is 1 or 0 to draw or clear it
*/
uint8_t Font::Draw90(unsigned char letter, int x, int y, uint8_t c) {
uint8_t maxx=0, data;
const uint8_t* character;
if (letter==' ') return 3+2;
if (letter<fontMin || letter>fontMax) {
return 0;
}
character = (const uint8_t *)pgm_read_word_near(&font[letter-fontMin]);
data = pgm_read_byte_near(character++);
while (data != END) {
uint8_t charCol = data >> 4, charRow = data & 15;
if (charCol>maxx) maxx=charCol;
if (
7 - charRow + x <DISPLAY_COLS &&
7 - charRow + x >=0 &&
charCol + y <DISPLAY_ROWS &&
charCol + y >=0
) {
LedSign::Set(7 - charRow + x, charCol + y, c);
}
data = pgm_read_byte_near(character++);
}
return maxx+2;
}
-38
View File
@@ -1,38 +0,0 @@
/*
Font drawing library
Copyright 2009/2010 Benjamin Sonntag <benjamin@sonntag.fr> http://benjamin.sonntag.fr/
History:
2010-01-01 - V0.0 Initial code at Berlin after 26C3
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#ifndef Font_h
#define Font_h
#include <inttypes.h>
#undef LOWERCASE
namespace Font
{
extern uint8_t Draw(unsigned char letter, int x, int y, uint8_t c=1);
extern uint8_t Draw90(unsigned char letter, int x, int y, uint8_t c=1);
}
#endif
-193
View File
@@ -1,193 +0,0 @@
/*simple lol shield text lib toprovide full ascii charset. written by Michael Schwarzer
* TODO: make gplv3 pls!
*
*
* if you dont like the font type write your own and share!!!
* just leave those codes blank ( 0x00 0x00 0x00 0x00 0x00) that arent used!
*
*/
#include <avr/pgmspace.h>
#include "Myfont.h"
#include "Charliplexing.h"
#include "Arduino.h"
#include <inttypes.h>
const byte la[][5] PROGMEM = {
/*all ascii codes:*/
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x0 => Blank */
{0x33,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x1 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x2 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x3 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x4 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x5 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x6 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x7 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x8 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x9 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0xA => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0xB => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0xC => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0xD => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0xE => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0xF => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x10 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x11 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x12 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x13 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x14 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x15 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x16 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x17 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x18 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x19 => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x1A => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x1B => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x1C => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x1D => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x1E => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x1F => Blank */
{0x00,0x00,0x00,0x00,0x00}, /* ASCII-Code 0x20 => Space */
{0x00,0x00,0x4F,0x00,0x00}, /* ASCII-Code 0x21 => ! */
{0x00,0x07,0x00,0x07,0x00}, /* ASCII-Code 0x22 => " */
{0x14,0x7F,0x14,0x7F,0x14}, /* ASCII-Code 0x23 => # */
{0x24,0x2A,0x7F,0x2A,0x12}, /* ASCII-Code 0x24 => $ */
{0x23,0x13,0x08,0x64,0x62}, /* ASCII-Code 0x25 => % */
{0x36,0x49,0x55,0x52,0x50}, /* ASCII-Code 0x26 => & */
{0x00,0x05,0x03,0x00,0x00}, /* ASCII-Code 0x27 => ´ */
{0x00,0x1C,0x22,0x81,0x00}, /* ASCII-Code 0x28 => { */
{0x00,0x81,0x22,0x1C,0x00}, /* ASCII-Code 0x29 => } */
{0x14,0x08,0x3E,0x08,0x14}, /* ASCII-Code 0x2A => * */
{0x08,0x08,0x3E,0x08,0x08}, /* ASCII-Code 0x2B => + */
{0x00,0x50,0x30,0x00,0x00}, /* ASCII-Code 0x2C => , */
{0x08,0x08,0x08,0x08,0x08}, /* ASCII-Code 0x2D => - */
{0x00,0x60,0x60,0x00,0x00}, /* ASCII-Code 0x2E => . */
{0x20,0x10,0x08,0x04,0x02}, /* ASCII-Code 0x2F => / */
{0x3E,0x51,0x49,0x45,0x3E}, /* ASCII-Code 0x30 => 0 */
{0x00,0x42,0x7F,0x40,0x00}, /* ASCII-Code 0x31 => 1 */
{0x42,0x61,0x51,0x49,0x46}, /* ASCII-Code 0x32 => 2 */
{0x21,0x41,0x45,0x4B,0x31}, /* ASCII-Code 0x33 => 3 */
{0x18,0x14,0x12,0x7F,0x10}, /* ASCII-Code 0x34 => 4 */
{0x27,0x45,0x45,0x45,0x39}, /* ASCII-Code 0x35 => 5 */
{0x3C,0x4A,0x49,0x49,0x30}, /* ASCII-Code 0x36 => 6 */
{0x01,0x71,0x09,0x05,0x03}, /* ASCII-Code 0x37 => 7 */
{0x36,0x49,0x49,0x49,0x36}, /* ASCII-Code 0x38 => 8 */
{0x06,0x49,0x49,0x29,0x1E}, /* ASCII-Code 0x39 => 9 */
{0x00,0x36,0x36,0x00,0x00}, /* ASCII-Code 0x3A => : */
{0x00,0x56,0x36,0x00,0x00}, /* ASCII-Code 0x3B => ; */
{0x08,0x14,0x22,0x41,0x00}, /* ASCII-Code 0x3C => < */
{0x14,0x14,0x14,0x14,0x14}, /* ASCII-Code 0x3D => = */
{0x41,0x22,0x14,0x08,0x00}, /* ASCII-Code 0x3E => > */
{0x02,0x01,0x51,0x09,0x06}, /* ASCII-Code 0x3F => ? */
{0x32,0x49,0x79,0x41,0x3E}, /* ASCII-Code 0x40 => @ */
{0x7E,0x11,0x11,0x11,0x7E}, /* ASCII-Code 0x41 => A */
{0x7F,0x49,0x49,0x49,0x36}, /* ASCII-Code 0x42 => B */
{0x3E,0x41,0x41,0x41,0x22}, /* ASCII-Code 0x43 => C */
{0x7F,0x41,0x41,0x22,0x1C}, /* ASCII-Code 0x44 => D */
{0x7F,0x49,0x49,0x49,0x41}, /* ASCII-Code 0x45 => E */
{0x7F,0x09,0x09,0x09,0x01}, /* ASCII-Code 0x46 => F */
{0x3E,0x41,0x49,0x49,0x7A}, /* ASCII-Code 0x47 => G */
{0x7F,0x08,0x08,0x08,0x7F}, /* ASCII-Code 0x48 => H */
{0x00,0x41,0x7F,0x41,0x00}, /* ASCII-Code 0x49 => I */
{0x20,0x40,0x41,0x3F,0x01}, /* ASCII-Code 0x4A => J */
{0x7F,0x08,0x14,0x22,0x41}, /* ASCII-Code 0x4B => K */
{0x7F,0x40,0x40,0x40,0x40}, /* ASCII-Code 0x4C => L */
{0x7F,0x02,0x0C,0x02,0x7F}, /* ASCII-Code 0x4D => M */
{0x7F,0x04,0x08,0x10,0x7F}, /* ASCII-Code 0x4E => N */
{0x3E,0x41,0x41,0x41,0x3E}, /* ASCII-Code 0x4F => O */
{0x7F,0x09,0x09,0x09,0x06}, /* ASCII-Code 0x50 => P */
{0x3E,0x41,0x51,0x21,0x5E}, /* ASCII-Code 0x51 => Q */
{0x7F,0x09,0x19,0x29,0x46}, /* ASCII-Code 0x52 => R */
{0x46,0x49,0x49,0x49,0x31}, /* ASCII-Code 0x53 => S */
{0x01,0x01,0x7F,0x01,0x01}, /* ASCII-Code 0x54 => T */
{0x3F,0x40,0x40,0x40,0x3F}, /* ASCII-Code 0x55 => U */
{0x1F,0x20,0x40,0x20,0x1F}, /* ASCII-Code 0x56 => V */
{0x3F,0x40,0x38,0x40,0x3F}, /* ASCII-Code 0x57 => W */
{0x63,0x14,0x08,0x14,0x63}, /* ASCII-Code 0x58 => X */
{0x07,0x08,0x70,0x08,0x07}, /* ASCII-Code 0x59 => Y */
{0x61,0x51,0x49,0x45,0x43}, /* ASCII-Code 0x5A => Z */
{0x00,0x7F,0x41,0x41,0x00}, /* ASCII-Code 0x5B => [ */
{0x15,0x16,0x7C,0x16,0x15}, /* ASCII-Code 0x5C => \ */
{0x00,0x41,0x41,0x7F,0x00}, /* ASCII-Code 0x5D => ] */
{0x04,0x02,0x01,0x02,0x04}, /* ASCII-Code 0x5E => ^ */
{0x40,0x40,0x40,0x40,0x40}, /* ASCII-Code 0x5F => _ */
{0x00,0x01,0x02,0x04,0x00}, /* ASCII-Code 0x60 => ` */
{0x20,0x54,0x54,0x54,0x78}, /* ASCII-Code 0x61 => a */
{0x7F,0x48,0x44,0x44,0x38}, /* ASCII-Code 0x62 => b */
{0x38,0x44,0x44,0x44,0x20}, /* ASCII-Code 0x63 => c */
{0x38,0x44,0x44,0x48,0x7F}, /* ASCII-Code 0x64 => d */
{0x38,0x54,0x54,0x54,0x18}, /* ASCII-Code 0x65 => e */
{0x08,0x7E,0x09,0x01,0x02}, /* ASCII-Code 0x66 => f */
{0x0C,0x52,0x52,0x52,0x3E}, /* ASCII-Code 0x67 => g */
{0x7F,0x08,0x04,0x04,0x78}, /* ASCII-Code 0x68 => h */
{0x00,0x44,0x7D,0x40,0x00}, /* ASCII-Code 0x69 => i */
{0x20,0x40,0x44,0x3D,0x00}, /* ASCII-Code 0x6A => j */
{0x7F,0x10,0x28,0x44,0x00}, /* ASCII-Code 0x6B => k */
{0x00,0x41,0x7F,0x40,0x00}, /* ASCII-Code 0x6C => l */
{0x7C,0x04,0x18,0x04,0x78}, /* ASCII-Code 0x6D => m */
{0x7C,0x08,0x04,0x04,0x78}, /* ASCII-Code 0x6E => n */
{0x38,0x44,0x44,0x44,0x38}, /* ASCII-Code 0x6F => o */
{0x7C,0x14,0x14,0x14,0x08}, /* ASCII-Code 0x70 => p */
{0x08,0x14,0x14,0x18,0x7C}, /* ASCII-Code 0x71 => q */
{0x7C,0x08,0x04,0x04,0x08}, /* ASCII-Code 0x72 => r */
{0x48,0x54,0x54,0x54,0x20}, /* ASCII-Code 0x73 => s */
{0x04,0x3F,0x44,0x40,0x20}, /* ASCII-Code 0x74 => t */
{0x3C,0x40,0x40,0x20,0x7C}, /* ASCII-Code 0x75 => u */
{0x1C,0x20,0x40,0x20,0x1C}, /* ASCII-Code 0x76 => v */
{0x3C,0x40,0x30,0x40,0x3C}, /* ASCII-Code 0x77 => w */
{0x44,0x28,0x10,0x28,0x44}, /* ASCII-Code 0x78 => x */
{0x0C,0x50,0x50,0x50,0x3C}, /* ASCII-Code 0x79 => y */
{0x44,0x64,0x54,0x4C,0x44}, /* ASCII-Code 0x7A => z */
{0x00,0x08,0x36,0x41,0x00}, /* ASCII-Code 0x7B => { */
{0x00,0x00,0x7F,0x00,0x00}, /* ASCII-Code 0x7C => | */
{0x00,0x41,0x36,0x08,0x00}, /* ASCII-Code 0x7D => } */
{0x08,0x08,0x2A,0x1C,0x08}, /* ASCII-Code 0x7E => -> */
{0x08,0x1C,0x2A,0x08,0x08}}; /* ASCII-Code 0x7F => <- */
void Myfont::Draw(int xval, unsigned char chr) /*draws an ascii char to the screen using the given x value */
{
uint8_t mode = LedSign::DisplayMode();
uint8_t vr=0;
vr=chr;
for(uint8_t i=0; i<5; i++)
{
uint8_t mask = 0x01; /*bitmask used to select the different bits from the values in the table*/
for(uint8_t j=0; j<7; j++)
{
uint8_t tmps=pgm_read_byte( &la[vr][i] )&mask; /*read a value from the table and do a & with the mask*/
if(tmps==mask) /*if there was a 1 set tmps to 1 else set it to 0*/
{
if (mode == GRAYSCALE) tmps=7;
else tmps=1;
}
else
{
tmps=0;
}
if(xval+i<14 && (xval+i) >(-1)){ /*only write x vals that are existing on the screen*/
LedSign::Set(xval+i, j+1, tmps); /*write it*/
}
mask <<= 1; /*take the next bit of the val from the table*/
}
}
}
void Myfont::Banner(int len, unsigned char* text){ /* text banner creator. use with example code!!*/
int xoff=14;/* setmx offset to the right end of the screen*/
for(int i=0; i<len*5 +52; i++){ /*scrolling loop*/
for(int j=0; j<len; j++){ /*loop over all of the chars in the text*/
Myfont::Draw(xoff + j*6, text[j]); /* call the draw font function*/
}
xoff--; /* decrement x offset*/
delay(70); /*scrolling speed increments if delay goes down*/
LedSign::Clear(); /*empty the screen */
}
}
-13
View File
@@ -1,13 +0,0 @@
#ifndef Myfont_h
#define Myfont_h
#include <inttypes.h>
namespace Myfont
{
extern void Draw(int xval, unsigned char chr);
extern void Banner(int len, unsigned char* text);
}
#endif
Binary file not shown.
Binary file not shown.
-5
View File
@@ -1,5 +0,0 @@
This PCB is released under the Creative Commons Attribution-Share Alike 3.0 United States License.
You may manufacture PCBs for both your own personal use, and for commertial use. You will have to provide a link to the original kit on any documentation or website.
You may also modify the PCB files, but you must then release them as well. Credit can be attributed through a link to the product website: http://jimmieprodgers.com/apc/
+1
View File
@@ -0,0 +1 @@
The LoL shield is an open Arduino shield, with Lots of LEDs on it, hence the name. This is the project page where people can post programs for it. This is also where the official library and PCB files will reside.
-16
View File
@@ -1,16 +0,0 @@
These are arduino-duemilanove + LolShield source code & libraries.
you may put them into your Arduino Sketchbook folder.
warning :
- lib is a library folder, all other projects may use it. it's currently using symlink to include the libraries in the projects ...
- font is not a project : it's a code generator : it generate the cpp arrays representing the font characters present in the same folder. Please see fonttest/Font.cpp for more information
all other folders are projects that should compile using Arduino and gcc-avr compiling chain.
All those program are distributed under GPL v2+ or LGPL v2+ license
(C) 2009-2010 Jimmie P Rodgers, Benjamin Sonntag, Alex Wanger, Aurélien Couderc, Matt Mets, & maybe others,
And thanks goes flying to Berlin to the Chaos Computer Club team for the unbelievable congress they organized ;)
@@ -1,58 +0,0 @@
/*
Super-simple LoL Shield "breathe" fading test
Written by Thilo Fromm <kontakt@thilo-fromm.de>.
Writen for the LoL Shield, designed by Jimmie Rodgers:
http://jimmieprodgers.com/kits/lolshield/
This is free software; you can redistribute it and/or
modify it under the terms of the GNU Version 3 General Public
License as published by the Free Software Foundation;
or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "Charliplexing.h"
const unsigned int inhale_time_ms = 500;
const unsigned int hold_breath_ms = 600;
const unsigned int exhale_time_ms = 800;
const unsigned int pause_breath_ms = 2000;
void setup() // run once, when the sketch starts
{
LedSign::Init(DOUBLE_BUFFER | GRAYSCALE);
}
void loop() // run over and over again
{
// inhale
for (int8_t i=0; i <= SHADES-1; i++) {
uint8_t sleep = inhale_time_ms / SHADES
+ ( SHADES / 2 - i ) * ( inhale_time_ms / (SHADES * 6) );
LedSign::Clear(i);
LedSign::Flip(true);
delay( sleep );
}
delay( hold_breath_ms );
// exhale
for (int8_t i=SHADES-1; i >= 0; i--) {
uint8_t sleep = exhale_time_ms / SHADES
+ ( SHADES / 2 - i ) * ( inhale_time_ms / (SHADES * 6) );
LedSign::Clear(i);
LedSign::Flip(true);
delay( sleep );
}
// pause
delay( pause_breath_ms );
}
@@ -1,82 +0,0 @@
/*
Example for Charliplexing library
Alex Wenger <a.wenger@gmx.de> http://arduinobuch.wordpress.com/
History:
30/Dez/09 - V0.0 wrote the first version at 26C3/Berlin
*/
#include "Charliplexing.h"
struct point {
uint8_t xp; // Point Position in X direction (multplied by 16)
uint8_t x_speed; // Speed
uint8_t flag;
} points[9];
void setup() // run once, when the sketch starts
{
LedSign::Init();
for(uint8_t i = 0; i < 9; i++)
{
points[i].xp = 0;
points[i].x_speed = random(1, 16);
points[i].flag = 1;
}
}
uint8_t heart_p[] = {
4,5,
3,4,
2,4,
5,4,
6,4,
7,5,
1,5,
7,6,
1,6,
6,7,
2,7,
5,8,
3,8,
4,9,
};
void heart()
{
for(uint8_t y = 0; y < 9; y++)
for(uint8_t x = 3; x < 11; x++)
{
LedSign::Set(x,y,0);
}
for(uint8_t i = 0; i < 14; i++)
{
LedSign::Set(heart_p[i*2+1],heart_p[i*2],1);
}
}
uint8_t heart_flag;
void loop() // run over and over again
{
for(uint8_t i = 0; i < 9; i++)
{
points[i].xp += points[i].x_speed;
if (points[i].xp >= 14*16)
{
points[i].x_speed = random(1, 16);
points[i].xp = 0;
points[i].flag ^= 1;
}
LedSign::Set(points[i].xp/16,i,points[i].flag);
}
heart_flag++;
if (heart_flag < 20) {
heart();
}
delay(40);
}
@@ -1,387 +0,0 @@
#include "Charliplexing.h"
#include "Myfont.h"
#include "Arduino.h"
#include <EEPROM.h>
int toggleState;
int EEPROMaddress = 0;
int charLength = 30;
unsigned char text[]="Would you like to play a game?";
byte brightness = 7;
//Game of Life stuff
#define DELAY 150 //Sets the time each generation is shown
#define RESEEDRATE 5000 //Sets the rate the world is re-seeded
#define SIZEX 14 //Sets the X axis size
#define SIZEY 9 //Sets the Y axis size
byte world[SIZEX][SIZEY][2]; //Creates a double buffer world
long density = 50; //Sets density % during seeding
int geck = 0; //Counter for re-seeding
void setup(){
toggleState = EEPROM.read(EEPROMaddress);
upToggleState();
LedSign::Init(GRAYSCALE);
for (int i = toggleState+1; i > 0; i--){
LedSign::Set(i-1, 0, brightness);
}
delay(1000);
LedSign::Clear(0);
}
void loop(){
/*
0 Plasma
1 Game of Life
2 "Would you like to play a game?"
3 Double Helix
*/
switch(toggleState){
case 0:
plasma();
break;
case 1:
life();
break;
case 2:
Myfont::Banner(charLength,text);
break;
case 3:
DNA();
break;
default:
EEPROM.write(EEPROMaddress, 0);
}
}
//Ups or resets the state counter
void upToggleState(){
toggleState++;
if (toggleState > 3) toggleState = 0;
EEPROM.write(EEPROMaddress, toggleState);
}
void plasma(){
/*
Plasma
written by Zach Archer http://zacharcher.com/
NOTES:
- Requires the LoLshield library to run. Get the library here: http://code.google.com/p/lolshield/downloads/
- How to install the library: http://www.arduino.cc/en/Hacking/Libraries
This sketch moves two points along Lissajious curves. See: http://en.wikipedia.org/wiki/Lissajous_curve
The distances between each LED and each point are multiplied,
then this value is shaped using a sine function, and this sets the brightness of each LED.
*/
// Convenient 2D point structure
struct Point {
float x;
float y;
};
float phase = 0.0;
float phaseIncrement = 0.08; // Controls the speed of the moving points. Higher == faster. I like 0.08 .
float colorStretch = 0.11; // Higher numbers will produce tighter color bands. I like 0.11 .
// This function is called every frame.
while(true) {
phase += phaseIncrement;
// The two points move along Lissajious curves, see: http://en.wikipedia.org/wiki/Lissajous_curve
// We want values that fit the LED grid: x values between 0..13, y values between 0..8 .
// The sin() function returns values in the range of -1.0..1.0, so scale these to our desired ranges.
// The phase value is multiplied by various constants; I chose these semi-randomly, to produce a nice motion.
Point p1 = {
(sin(phase*1.000)+1.0) * 7.5, (sin(phase*1.310)+1.0) * 4.0 };
Point p2 = {
(sin(phase*1.770)+1.0) * 7.5, (sin(phase*2.865)+1.0) * 4.0 };
byte row, col;
// For each row...
for( row=0; row<9; row++ ) {
float row_f = float(row); // Optimization: Keep a floating point value of the row number, instead of recasting it repeatedly.
// For each column...
for( col=0; col<14; col++ ) {
float col_f = float(col); // Optimization.
// Calculate the distance between this LED, and p1.
Point dist1 = {
col_f - p1.x, row_f - p1.y }; // The vector from p1 to this LED.
float distance = sqrt( dist1.x*dist1.x + dist1.y*dist1.y );
// Calculate the distance between this LED, and p2.
Point dist2 = {
col_f - p2.x, row_f - p2.y }; // The vector from p2 to this LED.
// Multiply this with the other distance, this will create weird plasma values :)
distance *= sqrt( dist2.x*dist2.x + dist2.y*dist2.y );
//distance += sqrt( dist2.x*dist2.x + dist2.y*dist2.y ); // Variation: weird linear color bands. Might need to increase colorStretch
// Warp the distance with a sin() function. As the distance value increases, the LEDs will get light,dark,light,dark,etc...
// You can use a cos() for slightly different shading, or experiment with other functions. Go crazy!
float color_f = (sin( distance * colorStretch ) + 1.0) * 0.5; // range: 0.0...1.0
// Square the color_f value to weight it towards 0. The image will be darker and have higher contrast.
color_f *= color_f;
//color_f *= color_f*color_f*color_f; // Uncomment this line to make it even darker :)
// Scale the color up to 0..7 . Max brightness is 7.
LedSign::Set( col, row, byte( round(color_f * 7.0) ) );
}
}
// There's so much math happening, it's already a bit slow ;) No need for extra delays!
//delay( 20 );
}
}
void DNA(){
/*
DoubleHelix
written by Zach Archer http://zacharcher.com/
NOTES:
- Requires the LoLshield library to run. Get the library here: http://code.google.com/p/lolshield/downloads/
- How to install the library: http://www.arduino.cc/en/Hacking/Libraries
This sketch draws two sine waves with different brightness values.
The phase of the "darker" sine wave will drift a bit.
On every other column, LEDs between the sines will be subtly lit (hopefully resembling DNA nucleobases).
*/
// You can tweak these values to create a custom DNA molecule :)
float stretch = 0.44; // The width of each sine wave. Smaller values create wider sine waves. I like 0.44 .
float phaseIncrement = 0.1; // How fast the sines move. I like 0.1 .
// The phase of the "darker" sine wave will drift (relative to the "lighter" sine wave).
// This makes the DoubleHelix more organic/hypnotic .
float driftIncrement = 0.019; // The speed it drifts back and forth. Larger == faster. I like 0.019 .
float driftForce = 0.4; // The visual amount of drift. I like 0.4 .
// On every other column, light the LEDs between the sine waves, resembling the nucleotides of a DNA molecule.
// This looks good if we switch between lighting odd columns, then even columns -- the molecule appears to be moving.
float barPhaseIncrement = 0.09; // Bar movement speed. Plz use values between 0..1 . I like 0.09 .
// Brightness values. Range is 0..7
byte lightSineBrightness = 7;
byte darkSineBrightness = 3;
byte barBrightness = 1;
// (End tweak section)
// These values change every frame:
float phase = 0.0; // This is how "far" we've travelled along the DNA.
float driftPhase = 0.0;
float barPhase = 0.0;
// This function is called every frame.
while(true) {
phase += phaseIncrement; // Move the sine waves forward.
// The "darker" sine wave drifts (relative to the "lighter" sine wave).
driftPhase += driftIncrement;
// Increment the position of the bars.
barPhase += barPhaseIncrement;
if( barPhase > 1.0 ) barPhase -= 1.0; // Wrap this value between 0..1 .
// We'll hilite either the even columns, or odd columns, depending on the value of barPhase.
boolean drawEvenBars = (barPhase < 0.5);
byte row, col;
// For each column of LEDs...
for( col=0; col<14; col++ ) {
// This is the "raw" value for the lighter sine wave. Range: -1.0...1.0
float lightSineThisColumn = sin( phase + float(col)*stretch );
// Scale the "raw" value and round it off, so the range is 0..8 . This is the LED we're going to light in this column.
int lightSine = int( round( lightSineThisColumn*4.0 ) ) + 4;
// driftPhase controls the phase drift of the "darker" sine.
// The drift amount is derived from this sin() function, so it will drift back and forth.
// Orbit around 2.1, which is about 1/3 phase offset from the lighter sine wave (2*PI/3). Looks pretty good.
float drift = 2.1 + (driftForce * sin( driftPhase ));
// This is the LED we're going to light for the "dark" sine wave.
// This is similar to computing the lightSine value, but it's compacted into one line :P
int darkSine = int( round( sin(phase+drift+float(col)*stretch)*4.0 ) ) + 4;
// For each LED within the column...
for( row=0; row<9; row++ ) {
// Does this LED belong to our light sine wave?
if( row==lightSine ) {
LedSign::Set( col, row, lightSineBrightness ); // The third argument is the brightness. Max bright == 7.
// Does this LED belong to our dark sine wave?
}
else if( row==darkSine ) {
LedSign::Set( col, row, darkSineBrightness ); // The third argument is the brightness.
}
else {
// This LED doesn't belong to either sine wave. So we'll turn it off, unless it belongs to a vertical bar.
int color = 0; // 0 == unlit
// Alternate even/odd columns:
// If col is an odd number, (col & 0x1) evaluates to true. (Example: 13 == B1101, rightmost bit is 1, so it's odd!)
// The ^ operator is binary XOR. So this statement evaluates true if _one_ condition is met, but _not_ both.
if( (col & 0x1) ^ (drawEvenBars) ) {
// If lightSine is above this LED, and darkSine is below, then this LED belongs to a vertical bar.
if( lightSine < darkSine ) {
if( lightSine<row && row<darkSine ) {
color = barBrightness;
}
// If darkSine is above, and lightSine is below, this LED belongs to a vertical bar.
}
else if( darkSine < lightSine ) {
if( darkSine<row && row<lightSine ) {
color = barBrightness;
}
}
}
LedSign::Set( col, row, color );
}
}
}
// Wait between frames to slow down the animation.
delay( 20 );
}
}
void life(){
/*
Conway's "Life"
Writen for the LoL Shield, designed by Jimmie Rodgers:
http://jimmieprodgers.com/kits/lolshield/
This needs the Charliplexing library, which you can get at the
LoL Shield project page: http://code.google.com/p/lolshield/
Created by Jimmie Rodgers on 12/30/2009.
Adapted from: http://www.arduino.cc/playground/Main/DirectDriveLEDMatrix
History:
December 30, 2009 - V1.0 first version written at 26C3/Berlin
This is free software; you can redistribute it and/or
modify it under the terms of the GNU Version 3 General Public
License as published by the Free Software Foundation;
or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
//#include <Charliplexing.h> //Imports the library, which needs to be
//Initialized in setup.
randomSeed(analogRead(5));
//Builds the world with an initial seed.
for (int i = 0; i < SIZEX; i++) {
for (int j = 0; j < SIZEY; j++) {
if (random(100) < density) {
world[i][j][0] = 1;
}
else {
world[i][j][0] = 0;
}
world[i][j][1] = 0;
}
}
while(true) {
// Birth and death cycle
for (int x = 0; x < SIZEX; x++) {
for (int y = 0; y < SIZEY; y++) {
// Default is for cell to stay the same
world[x][y][1] = world[x][y][0];
int count = neighbours(x, y);
geck++;
if (count == 3 && world[x][y][0] == 0) {
// A new cell is born
world[x][y][1] = 1;
LedSign::Set(x,y,brightness);
}
else if ((count < 2 || count > 3) && world[x][y][0] == 1) {
// Cell dies
world[x][y][1] = 0;
LedSign::Set(x,y,0);
}
}
}
//Counts and then checks for re-seeding
//Otherwise the display will die out at some point
geck++;
if (geck > RESEEDRATE){
seedWorld();
geck = 0;
}
// Copy next generation into place
for (int x = 0; x < SIZEX; x++) {
for (int y = 0; y < SIZEY; y++) {
world[x][y][0] = world[x][y][1];
}
}
delay(DELAY);
}
//Re-seeds based off of RESEEDRATE
//Runs the rule checks, including screen wrap
}
void seedWorld(){
randomSeed(analogRead(5));
for (int i = 0; i < SIZEX; i++) {
for (int j = 0; j < SIZEY; j++) {
if (random(100) < density) {
world[i][j][1] = 1;
}
}
}
}
int neighbours(int x, int y) {
return world[(x + 1) % SIZEX][y][0] +
world[x][(y + 1) % SIZEY][0] +
world[(x + SIZEX - 1) % SIZEX][y][0] +
world[x][(y + SIZEY - 1) % SIZEY][0] +
world[(x + 1) % SIZEX][(y + 1) % SIZEY][0] +
world[(x + SIZEX - 1) % SIZEX][(y + 1) % SIZEY][0] +
world[(x + SIZEX - 1) % SIZEX][(y + SIZEY - 1) % SIZEY][0] +
world[(x + 1) % SIZEX][(y + SIZEY - 1) % SIZEY][0];
}
@@ -1,134 +0,0 @@
/*
DoubleHelix
written by Zach Archer http://zacharcher.com/
NOTES:
- Requires the LoLshield library to run. Get the library here: http://code.google.com/p/lolshield/downloads/
- How to install the library: http://www.arduino.cc/en/Hacking/Libraries
This sketch draws two sine waves with different brightness values.
The phase of the "darker" sine wave will drift a bit.
On every other column, LEDs between the sines will be subtly lit (hopefully resembling DNA nucleobases).
*/
#include "Charliplexing.h" //initializes the LoL Sheild library
/////////////////////////////////////////////////////////////////////////////
//
// You can tweak these values to create a custom DNA molecule :)
//
const float stretch = 0.44; // The width of each sine wave. Smaller values create wider sine waves. I like 0.44 .
const float phaseIncrement = 0.1; // How fast the sines move. I like 0.1 .
// The phase of the "darker" sine wave will drift (relative to the "lighter" sine wave).
// This makes the DoubleHelix more organic/hypnotic .
const float driftIncrement = 0.019; // The speed it drifts back and forth. Larger == faster. I like 0.019 .
const float driftForce = 0.4; // The visual amount of drift. I like 0.4 .
// On every other column, light the LEDs between the sine waves, resembling the nucleotides of a DNA molecule.
// This looks good if we switch between lighting odd columns, then even columns -- the molecule appears to be moving.
const float barPhaseIncrement = 0.09; // Bar movement speed. Plz use values between 0..1 . I like 0.09 .
// Brightness values. Range is 0..7
const byte lightSineBrightness = 7;
const byte darkSineBrightness = 3;
const byte barBrightness = 1;
// (End tweak section)
/////////////////////////////////////////////////////////////////////////////
// These values change every frame:
float phase = 0.0; // This is how "far" we've travelled along the DNA.
float driftPhase = 0.0;
float barPhase = 0.0;
// This function is called once, when the sketch starts.
void setup() {
LedSign::Init(DOUBLE_BUFFER | GRAYSCALE); // Initializes a grayscale frame buffer.
}
// This function is called every frame.
void loop() {
phase += phaseIncrement; // Move the sine waves forward.
// The "darker" sine wave drifts (relative to the "lighter" sine wave).
driftPhase += driftIncrement;
// Increment the position of the bars.
barPhase += barPhaseIncrement;
if( barPhase > 1.0 ) barPhase -= 1.0; // Wrap this value between 0..1 .
// We'll hilite either the even columns, or odd columns, depending on the value of barPhase.
boolean drawEvenBars = (barPhase < 0.5);
byte row, col;
// For each column of LEDs...
for( col=0; col<14; col++ ) {
// This is the "raw" value for the lighter sine wave. Range: -1.0...1.0
float lightSineThisColumn = sin( phase + float(col)*stretch );
// Scale the "raw" value and round it off, so the range is 0..8 . This is the LED we're going to light in this column.
int lightSine = int( round( lightSineThisColumn*4.0 ) ) + 4;
// driftPhase controls the phase drift of the "darker" sine.
// The drift amount is derived from this sin() function, so it will drift back and forth.
// Orbit around 2.1, which is about 1/3 phase offset from the lighter sine wave (2*PI/3). Looks pretty good.
float drift = 2.1 + (driftForce * sin( driftPhase ));
// This is the LED we're going to light for the "dark" sine wave.
// This is similar to computing the lightSine value, but it's compacted into one line :P
int darkSine = int( round( sin(phase+drift+float(col)*stretch)*4.0 ) ) + 4;
// For each LED within the column...
for( row=0; row<9; row++ ) {
// Does this LED belong to our light sine wave?
if( row==lightSine ) {
LedSign::Set( col, row, lightSineBrightness ); // The third argument is the brightness. Max bright == 7.
// Does this LED belong to our dark sine wave?
} else if( row==darkSine ) {
LedSign::Set( col, row, darkSineBrightness ); // The third argument is the brightness.
} else {
// This LED doesn't belong to either sine wave. So we'll turn it off, unless it belongs to a vertical bar.
int color = 0; // 0 == unlit
// Alternate even/odd columns:
// If col is an odd number, (col & 0x1) evaluates to true. (Example: 13 == B1101, rightmost bit is 1, so it's odd!)
// The ^ operator is binary XOR. So this statement evaluates true if _one_ condition is met, but _not_ both.
if( (col & 0x1) ^ (drawEvenBars) ) {
// If lightSine is above this LED, and darkSine is below, then this LED belongs to a vertical bar.
if( lightSine < darkSine ) {
if( lightSine<row && row<darkSine ) {
color = barBrightness;
}
// If darkSine is above, and lightSine is below, this LED belongs to a vertical bar.
} else if( darkSine < lightSine ) {
if( darkSine<row && row<lightSine ) {
color = barBrightness;
}
}
}
LedSign::Set( col, row, color );
}
}
}
LedSign::Flip(true);
}
@@ -1,117 +0,0 @@
/*
Conway's "Life"
Writen for the LoL Shield, designed by Jimmie Rodgers:
http://jimmieprodgers.com/kits/lolshield/
This needs the Charliplexing library, which you can get at the
LoL Shield project page: http://code.google.com/p/lolshield/
Created by Jimmie Rodgers on 12/30/2009.
Adapted from: http://www.arduino.cc/playground/Main/DirectDriveLEDMatrix
History:
December 30, 2009 - V1.0 first version written at 26C3/Berlin
This is free software; you can redistribute it and/or
modify it under the terms of the GNU Version 3 General Public
License as published by the Free Software Foundation;
or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Charliplexing.h> //Imports the library, which needs to be
//Initialized in setup.
#define DELAY 150 //Sets the time each generation is shown
#define RESEEDRATE 100 //Sets the rate the world is re-seeded
#define SIZEX DISPLAY_COLS //Sets the X axis size
#define SIZEY DISPLAY_ROWS //Sets the Y axis size
byte world[2][SIZEX][SIZEY]; //Creates a double buffer world
const int density = 50; //Sets density % during seeding
int geck = 0; //Counter for re-seeding
void setup() {
LedSign::Init(); //Initilizes the LoL Shield
randomSeed(analogRead(5));
seedWorld();
}
void loop() {
static byte boring = 0;
byte changed = 0;
// Birth and death cycle
for (byte x = 0; x < SIZEX; x++) {
for (byte y = 0; y < SIZEY; y++) {
// Default is for cell to stay the same
byte alive = world[0][x][y];
LedSign::Set(x, y, alive);
byte count = neighbours(x, y);
if (count == 3 && !alive) {
// A new cell is born
alive = 1;
++changed;
} else if ((count < 2 || count > 3) && alive) {
// Cell dies
alive = 0;
++changed;
}
world[1][x][y] = alive;
}
}
// Copy next generation into place
for (byte x = 0; x < SIZEX; x++) {
for (byte y = 0; y < SIZEY; y++) {
world[0][x][y] = world[1][x][y];
}
}
if (changed)
boring = 0;
else
++boring;
//Counts and then checks for re-seeding
//Otherwise the display will die out at some point
if (boring >= 5 || ++geck >= RESEEDRATE) {
geck = 0;
seedWorld();
}
delay(DELAY);
}
//Re-seeds based off of RESEEDRATE
void seedWorld(){
for (byte i = 0; i < SIZEX; i++) {
for (byte j = 0; j < SIZEY; j++) {
if (random(100) < density)
world[0][i][j] = 1;
else
world[0][i][j] = 0;
}
}
}
//Runs the rule checks, including screen wrap
byte neighbours(byte x, byte y) {
return world[0][(x + 1) % SIZEX][y] +
world[0][x][(y + 1) % SIZEY] +
world[0][(x + SIZEX - 1) % SIZEX][y] +
world[0][x][(y + SIZEY - 1) % SIZEY] +
world[0][(x + 1) % SIZEX][(y + 1) % SIZEY] +
world[0][(x + SIZEX - 1) % SIZEX][(y + 1) % SIZEY] +
world[0][(x + SIZEX - 1) % SIZEX][(y + SIZEY - 1) % SIZEY] +
world[0][(x + 1) % SIZEX][(y + SIZEY - 1) % SIZEY];
}
@@ -1,83 +0,0 @@
/*
Plasma
written by Zach Archer http://zacharcher.com/
NOTES:
- Requires the LoLshield library to run. Get the library here: http://code.google.com/p/lolshield/downloads/
- How to install the library: http://www.arduino.cc/en/Hacking/Libraries
This sketch moves two points along Lissajious curves. See: http://en.wikipedia.org/wiki/Lissajous_curve
The distances between each LED and each point are multiplied,
then this value is shaped using a sine function, and this sets the brightness of each LED.
*/
#include "Charliplexing.h" //initializes the LoL Sheild library
// Convenient 2D point structure
struct Point {
float x;
float y;
};
float phase = 0.0;
float phaseIncrement = 0.08; // Controls the speed of the moving points. Higher == faster. I like 0.08 .
float colorStretch = 0.11; // Higher numbers will produce tighter color bands. I like 0.11 .
// This function is called once, when the sketch starts.
void setup() {
LedSign::Init(DOUBLE_BUFFER | GRAYSCALE);
}
// This function is called every frame.
void loop() {
phase += phaseIncrement;
// The two points move along Lissajious curves, see: http://en.wikipedia.org/wiki/Lissajous_curve
// We want values that fit the LED grid: x values between 0..13, y values between 0..8 .
// The sin() function returns values in the range of -1.0..1.0, so scale these to our desired ranges.
// The phase value is multiplied by various constants; I chose these semi-randomly, to produce a nice motion.
Point p1 = { (sin(phase*1.000)+1.0) * 7.5, (sin(phase*1.310)+1.0) * 4.0 };
Point p2 = { (sin(phase*1.770)+1.0) * 7.5, (sin(phase*2.865)+1.0) * 4.0 };
byte row, col;
// For each row...
for( row=0; row<9; row++ ) {
float row_f = float(row); // Optimization: Keep a floating point value of the row number, instead of recasting it repeatedly.
// For each column...
for( col=0; col<14; col++ ) {
float col_f = float(col); // Optimization.
// Calculate the distance between this LED, and p1.
Point dist1 = { col_f - p1.x, row_f - p1.y }; // The vector from p1 to this LED.
float distance = dist1.x*dist1.x + dist1.y*dist1.y;
// Calculate the distance between this LED, and p2.
Point dist2 = { col_f - p2.x, row_f - p2.y }; // The vector from p2 to this LED.
// Multiply this with the other distance, this will create weird plasma values :)
distance *= dist2.x*dist2.x + dist2.y*dist2.y;
distance = sqrt(distance);
// Warp the distance with a sin() function. As the distance value increases, the LEDs will get light,dark,light,dark,etc...
// You can use a cos() for slightly different shading, or experiment with other functions. Go crazy!
float color_f = (sin( distance * colorStretch ) + 1.0) * 0.5; // range: 0.0...1.0
// Square the color_f value to weight it towards 0. The image will be darker and have higher contrast.
color_f *= color_f;
//color_f *= color_f*color_f*color_f; // Uncomment this line to make it even darker :)
// Scale the color up to 0..7 . Max brightness is 7.
LedSign::Set( col, row, byte( round(color_f * 7.0) ) );
}
}
LedSign::Flip(true);
}
@@ -1,39 +0,0 @@
#include "Charliplexing.h"
#include "Myfont.h"
#include "Arduino.h"
int leng=0; //provides the length of the char array
unsigned char test[]="full ASCII charset: $ % & ! [ ] { } \0"; //text has to end with '\0' !!!!!!
/* ----------------------------------------------------------------- */
/** MAIN program Setup
*/
void setup() // run once, when the sketch starts
{
LedSign::Init();
for(int i=0; ; i++){ //get the length of the text
if(test[i]==0){
leng=i;
break;
}
}
}
/* ----------------------------------------------------------------- */
/** MAIN program Loop
*/
void loop() // run over and over again
{
Myfont::Banner(leng,test);
}
@@ -1,314 +0,0 @@
/*
Space Invader, a shoot-them-up game for LOL Shield for Arduino
Copyright 2009/2010 Benjamin Sonntag <benjamin@sonntag.fr> http://benjamin.sonntag.fr/
History:
2009-12-30 - V0.0 Initial code at Berlin during 26C3
2009-12-31 - V1.0 Score Drawing, at Berlin after 26C3 ;)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include "Charliplexing.h"
#include "Figure.h"
#include "Font.h"
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
/* ----------------------------------------------------------------- */
/* ----------------------------------------------------------------- */
/* SPACE INVADER CODE !!! */
/* ----------------------------------------------------------------- */
/* ----------------------------------------------------------------- */
// Number of fire we can use before having to wait
#define MAXFIRE 3
// Number of lives you have :
#define STARTLIVES 4
// Maximum number of ennemies at one :
#define MAXENNEMIES 8
// Speed of ennemies arrival : (between 0 & 20, 20 = rare, 0 = often )
#define ENNEMIESRATE 6
/** The score of the user (number of points = speed of each killed ennemy - number of ennemies missed) */
int score=0;
/** Position of the ship between 1 & 7 */
byte shippos=4;
/** Number of lives of the user */
byte lives;
/** Position of the bullets of the ship, [0]=x [1]=y */
byte firepos[9][2]={
{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}
};
/** Position and speed of the ennemies [0]=x [1]=y [2]=speed [3]=speed counter */
byte ennemypos[8][4]={
{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}
};
/* ----------------------------------------------------------------- */
/** Draw the ship at its current position.
* @param set 1 or 0 to set or clear the led.
*/
void drawShip(uint8_t c=1) {
LedSign::Set(0,shippos-1,c);
LedSign::Set(0,shippos ,c);
LedSign::Set(0,shippos+1,c);
LedSign::Set(1,shippos ,c);
}
/* ----------------------------------------------------------------- */
/** Draw the number of lives remaining at the top left of the screen
*/
void drawLives() {
for(byte i=0;i<STARTLIVES;i++) {
LedSign::Set(13-i,0,(i<lives)?1:0);
}
}
/* ----------------------------------------------------------------- */
/** end of the game, draw the Scores using a scrolling
*/
void endGame() {
for(byte x=4;x<=8;x++)
for(byte y=0;y<=8;y++)
LedSign::Set(x,y,0);
Figure::Scroll90(score);
for(byte i=0;i<30;i++) {
drawShip(0);
delay(5*(30-i));
drawShip(0);
delay(5*(30-i));
}
}
/* ----------------------------------------------------------------- */
/** Initialize a new game (lives, screen, score, ship ...)
*/
void initGame() {
lives=STARTLIVES;
score=0;
shippos=4;
LedSign::Clear();
drawLives();
drawShip();
}
/* ----------------------------------------------------------------- */
/** Check the variator to know the position of the ship.
* Move and redraw the ship in case of change.
*/
void moveShip()
{
// Ship have 7 positions. Let's use a third of the variator position.
int newshpos=7-(analogRead(5)/72); // we reverse the command (variator wrongly connected ;) )
if (newshpos>7) newshpos=7;
if (newshpos<1) newshpos=1;
if (newshpos!=shippos) {
drawShip(0);
for(byte i=0;i<8;i++)
LedSign::Set(0,i,0);
shippos=newshpos;
drawShip(1);
}
}
/* ----------------------------------------------------------------- */
/** Check the fire button and fire if it has been pushed.
* Please note that we use a static status to check that the user
* pull the button between each fire.
*/
void fireShip()
{
static byte status=0;
if (status==0) {
// Ship may fire 10 times (not more...)
if (analogRead(4)>1000) {
// FIRE !
status=1;
for(byte i=0;i<MAXFIRE;i++) {
if (firepos[i][0]==0) {
firepos[i][0]=2; firepos[i][1]=shippos;
break;
}
}
}
} else {
if (analogRead(4)<1000) status=0;
}
}
/* ----------------------------------------------------------------- */
/** Crash : called when an ennemy touched the ship (failure!)
*/
void crash() {
drawShip(1);
delay(150);
drawShip(0);
delay(150);
drawShip(1);
delay(150);
drawShip(0);
delay(150);
for(byte i=0;i<MAXENNEMIES;i++)
if (ennemypos[i][0]!=0) {
LedSign::Set(ennemypos[i][0],ennemypos[i][1],0);
ennemypos[i][0]=0;
}
for(byte i=0;i<MAXFIRE;i++)
firepos[i][0]=0;
lives--;
if (lives==0) {
endGame();
initGame();
} else {
LedSign::Clear();
drawLives();
drawShip();
}
}
/* ----------------------------------------------------------------- */
/** Add ennemies at the top randomly, with random speed too
*/
void addEnnemies()
{
if (random(0,ENNEMIESRATE)==0) {
// ENNEMY COMING !
for(byte i=0;i<MAXENNEMIES;i++) {
if (ennemypos[i][0]==0) {
ennemypos[i][0]=13; ennemypos[i][1]=random(1,8);
ennemypos[i][2]=random(2,5); // Speed of ennemies between 1 and 5 (5=slower)
ennemypos[i][3]=0;
break;
}
}
}
}
/* ----------------------------------------------------------------- */
/** Move the ennemies, and check the collision with the ship
*/
void moveEnnemies()
{
for(byte i=0;i<MAXENNEMIES;i++) {
if (ennemypos[i][0]!=0) {
ennemypos[i][3]++;
if (ennemypos[i][2]==ennemypos[i][3]) {
ennemypos[i][3]=0;
LedSign::Set(ennemypos[i][0],ennemypos[i][1],0);
ennemypos[i][0]--;
// collision with the top of the ship
if (ennemypos[i][0]==1 && shippos==ennemypos[i][1]) {
crash();
} else {
if (ennemypos[i][0]==0) { // Collision detection
ennemypos[i][0]=0;
if (score>0) score-=1;
if (shippos==ennemypos[i][1] || shippos-1==ennemypos[i][1] || shippos+1==ennemypos[i][1]) {
crash();
} else {
LedSign::Set(ennemypos[i][0],ennemypos[i][1],0);
}
}
}
} else {
LedSign::Set(ennemypos[i][0],ennemypos[i][1],1);
}
}
}
}
/* ----------------------------------------------------------------- */
/** Move the bullets, draw them, and check the collision with
* ennemies.
*/
void moveFires()
{
for(byte i=0;i<MAXFIRE;i++) {
if (firepos[i][0]!=0) {
LedSign::Set(firepos[i][0],firepos[i][1],0);
firepos[i][0]++;
// Let's detect collision with ennemies :
for(byte j=0;j<MAXENNEMIES;j++) {
if (ennemypos[j][0]!=0) {
if ((ennemypos[j][0]==firepos[i][0] || ennemypos[j][0]==firepos[i][0]+1) && ennemypos[j][1]==firepos[i][1]) {
// Ennemy destroyed
LedSign::Set(ennemypos[j][0],ennemypos[j][1],0);
ennemypos[j][0]=0;
firepos[i][0]=0;
score+=(6-ennemypos[j][2]); // Change it in case of ennemy speed change ;) score is 5-speed
}
}
}
if (firepos[i][0]==14) {
firepos[i][0]=0;
} else {
LedSign::Set(firepos[i][0],firepos[i][1],1);
}
}
}
}
/* ----------------------------------------------------------------- */
/** MAIN program Setup
*/
void setup() // run once, when the sketch starts
{
LedSign::Init();
randomSeed(analogRead(2));
initGame();
drawShip();
}
/* ----------------------------------------------------------------- */
/** MAIN program Loop
*/
void loop() // run over and over again
{
moveShip();
fireShip();
moveFires();
moveEnnemies();
addEnnemies();
delay(100);
}
@@ -1,226 +0,0 @@
#include <Charliplexing.h>
#include <avr/pgmspace.h>
//**************************************************************//
// Name : Pong for Arduino / Charlieplexing //
// Author : Benjamin Sonntag http://benjamin.sonntag.fr/ //
// Modified: Matt Mets http://cibomahto.com //
// Date : 28 May 2010 //
// Version : 0.2 //
// Notes : Uses Charlieplexing library to light up //
// : a matrix of 126 LEDs in a 9x14 grid //
// : from Jimmie P Rodgers www.jimmieprodgers.com //
//**************************************************************//
/* ---------------------------------------------------------------------------*/
/** The figures from 0 to 9 encoded in 7 lines of 5 bits :
*/
PROGMEM const byte figures[][7] = {
{14,17,17,17,17,17,14},
{4,6,4,4,4,4,14},
{14,17,16,14,1,1,31},
{14,17,16,14,16,17,14},
{8,12,10,9,31,8,8},
{31,1,1,15,16,16,15},
{14,17,1,15,17,17,14},
{31,16,8,8,4,4,4},
{14,17,17,14,17,17,14},
{14,17,17,30,16,16,15},
};
int8_t x,y,dx,dy;
int8_t sh1y,sh2y,s1,s2;
/* ---------------------------------------------------------------------------*/
/* Arduino setup func
*/
void setup() {
LedSign::Init(DOUBLE_BUFFER);
x = 3;
y = 7;
sh1y=3;
sh2y=3;
dx = 1;
dy = 1;
s1 = 0;
s2 = 0;
randomSeed(analogRead(0));
drawscores();
}
/* ---------------------------------------------------------------------------*/
/* Arduino main loop
*/
void loop() {
int8_t randommove;
// The Ball shall bounce on the walls :
if (x==12 || x==1) {
dx=-dx;
// Collision detection
if (x==1) {
// check the first ship (left side)
if (sh1y!=y && sh1y+1!=y) {
s2++;
drawscores();
checkscores();
}
} else {
// check the second ship (right side)
if (sh2y!=y && sh2y+1!=y) {
s1++;
drawscores();
checkscores();
}
}
}
if (y==8 || y==0) dy=-dy;
// Clear the non-active screen
LedSign::Clear();
// Move the BALL :
x=x+dx;
y=y+dy;
// Draw the ball :
LedSign::Set(x,y,1);
// Draw the Ship
LedSign::Set(0, sh1y, 1);
LedSign::Set(0, sh1y+1, 1);
LedSign::Set(13, sh2y, 1);
LedSign::Set(13, sh2y+1, 1);
// The ships moves when the ball go in their direction. They follow it magically ;) :
/* This code is too smart, in fact he is perfekt :)
if (dx<0) {
if (sh1y>y) {
sh1y--;
}
if (sh1y<y) {
sh1y++;
}
}
// let's code a dummy one
*/
if (dx>0) {
// the ball goes away from me, let's move randomly
randommove=random(0,3);
if (randommove==0) {
sh1y--;
}
if (randommove==1) {
sh1y++;
}
} else {
if (sh1y>y && (random(0,12)<10 || x<3)) {
sh1y--;
}
if (sh1y<y && (random(0,12)<10 || x<3)) {
sh1y++;
}
if (random(0,8)==0) {
if (sh1y>y) {
sh1y++;
}
if (sh1y<y) {
sh1y--;
}
}
}
// Human Player
// 1/4 of the variator is used. If we use it fully, it's too hard to play.
// To use it fully replace 36 by 146
sh2y=analogRead(5)/72;
// Sanity checks for the ships :
if (sh1y>7) sh1y=7;
if (sh2y>7) sh2y=7;
if (sh1y<0) sh1y=0;
if (sh2y<0) sh2y=0;
// swap the screens ;) (sometime we may need this double-buffer algorithm...
// of course, as of today it's a little bit overkill ...)
LedSign::Flip();
// Display the bitmap some times
delay(200);
// loop :)
}
/* ---------------------------------------------------------------------------*/
/** Check if a player won !
* If one of the players won, let's show a funny animation ;)
*/
void checkscores() {
// TODO : DO the animation ;)
}
/* ---------------------------------------------------------------------------*/
/** Draw the scores in a lovely scrolling :)
* Use the current active screen brutally ...
*/
void drawscores() {
int8_t i,j,ps1;
for(ps1=0;ps1<8;ps1++) {
LedSign::Clear(); // Clear the active screen
LedSign::Set(6,4,1); // dash between the scores
LedSign::Set(7,4,1);
// Fill it with both scores :
// Left score goes up>down
for (i=ps1, j=6; i>=0 && j>=0; i--, j--) {
byte f = pgm_read_byte_near(&figures[s1][j]);
for (uint8_t k = 0; k < 5; k++, f>>=1)
LedSign::Set(k, i, f & 1);
}
// Right score goes down>up
for (i=8-ps1, j=0; i<=8 && j<=6; i++, j++) {
byte f = pgm_read_byte_near(&figures[s2][j]);
for (uint8_t k = 0; k < 5; k++, f>>=1)
LedSign::Set(k+9, i, f & 1);
}
LedSign::Flip();
delay(200);
}
delay(1500);
LedSign::Clear(0);
if (s1==9 || s2==9) {
for(ps1=0;ps1<3;ps1++) {
LedSign::Flip();
delay(300);
LedSign::Flip();
delay(600);
}
delay(1500);
s1=0; s2=0;
drawscores();
}
}
@@ -1,59 +0,0 @@
/*
Tetris, an adaptation for LOL Shield for Arduino
Copyright 2009/2010 Aurélien Couderc <acouderc@april.org>
With the kind help and good ideas of Benjamin Sonntag <benjamin@sonntag.fr> http://benjamin.sonntag.fr/
History:
2010-01-01 - V1.0 Initial version, at Berlin after 26C3 :D
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
/**
* The coord struct holds an (x,y) pair, as used in the pieces declarations
* an in the position structure.
*/
typedef struct coord {
int8_t x;
int8_t y;
} coord_t;
typedef struct coordPacked {
unsigned x:2, y:2;
} coordPacked_t;
/**
* One piece view. Each Tetris piece may have one to four views.
*/
typedef struct pieceView {
coordPacked_t elements[4];
} pieceView_t;
/**
* One Tetris piece object, made of one to four views.
*/
typedef struct piece {
pieceView_t views[4];
} piece_t;
/**
* Structure to hold the current position and view of the piece
* being played.
*/
typedef struct pos {
coord_t coord;
uint8_t view;
} pos_t;
@@ -1,391 +0,0 @@
/*
Tetris, an adaptation for LOL Shield for Arduino
Copyright 2009/2010 Aurélien Couderc <acouderc@april.org>
With the kind help and good ideas of Benjamin Sonntag <benjamin@sonntag.fr> http://benjamin.sonntag.fr/
History:
2010-01-01 - V1.0 Initial version, at Berlin after 26C3 :D
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include "Charliplexing.h"
#include "Figure.h"
#include "LoLShield_Tetris.h"
/** The current level. */
int level;
/** The score of the user (number of points = speed of each killed ennemy - number of ennemies missed) */
int score;
/** Number of lines cleared at current level. */
byte linesCleared;
/** The game grid size. */
const uint8_t GRID_HEIGHT = 14;
const uint8_t GRID_WIDTH = 9;
boolean playGrid[GRID_HEIGHT][GRID_WIDTH];
const piece_t pieces[7] = {
{{
// The single view of the square piece :
// 00
// 00
{{{1,1}, {2,1}, {1,2}, {2,2}}},
{{{1,1}, {2,1}, {1,2}, {2,2}}},
{{{1,1}, {2,1}, {1,2}, {2,2}}},
{{{1,1}, {2,1}, {1,2}, {2,2}}},
}},
{{
// The two views of the bar piece :
// 0000
{{{0,1}, {1,1}, {2,1}, {3,1}}},
{{{2,0}, {2,1}, {2,2}, {2,3}}},
{{{0,1}, {1,1}, {2,1}, {3,1}}},
{{{2,0}, {2,1}, {2,2}, {2,3}}},
}},
{{
// The two views of the first S :
// 00
// 00
{{{0,1}, {1,1}, {1,2}, {2,2}}},
{{{1,1}, {1,2}, {2,0}, {2,1}}},
{{{0,1}, {1,1}, {1,2}, {2,2}}},
{{{1,1}, {1,2}, {2,0}, {2,1}}},
}},
{{
// The two views of the second S :
// 00
// 00
{{{0,2}, {1,1}, {1,2}, {2,1}}},
{{{0,0}, {0,1}, {1,1}, {1,2}}},
{{{0,2}, {1,1}, {1,2}, {2,1}}},
{{{0,0}, {0,1}, {1,1}, {1,2}}},
}},
{{
// The four views of the first L :
// 000
// 0
{{{0,1}, {0,2}, {1,1}, {2,1}}},
{{{0,0}, {1,0}, {1,1}, {1,2}}},
{{{0,1}, {1,1}, {2,0}, {2,1}}},
{{{1,0}, {1,1}, {1,2}, {2,2}}},
}},
{{
// The four views of the second L :
// 000
// 0
{{{0,1}, {1,1}, {2,1}, {2,2}}},
{{{1,0}, {1,1}, {1,2}, {2,0}}},
{{{0,0}, {0,1}, {1,1}, {2,1}}},
{{{0,2}, {1,0}, {1,1}, {1,2}}},
}},
{{
// The four views of the T :
// 000
// 0
{{{0,1}, {1,1}, {1,2}, {2,1}}},
{{{1,0}, {1,1}, {1,2}, {2,1}}},
{{{0,1}, {1,0}, {1,1}, {2,1}}},
{{{0,1}, {1,0}, {1,1}, {1,2}}},
}},
};
const int levelMultiplier[] = {1, 1, 2, 2, 3, 3, 4, 4, 5, 5};
const int linesMultiplier[] = {100, 400, 900, 2000};
/** The piece being played. */
const piece_t* currentPiece;
/** The current position and view of the piece being played. */
pos_t position;
/* ----------------------------------------------------------------- */
/** Switches on or off the display of a Tetris piece.
* @param piece the piece to be displayed or removed.
* @param position the position and view of the piece to draw or remove.
* @param set 1 or 0 to draw or remove the piece.
*/
void switchPiece(const piece_t* piece, const pos_t& position, uint8_t c=1) {
for(uint8_t i=0;i<4;i++) {
coordPacked_t element = piece->views[position.view].elements[i];
uint8_t eltXPos = element.x+position.coord.x;
uint8_t eltYPos = element.y+position.coord.y;
LedSign::Set(13-eltYPos, eltXPos, c);
}
}
/* ----------------------------------------------------------------- */
/**
* Redraw a section of the tetris play grid between the given
* indexes (included).
* @param top the index of the top line of the section to redraw.
* @param bottom the index the bottom line of the section to redraw.
* This parameter MUST be greater or equal than top.
*/
void redrawLines(uint8_t top, uint8_t bottom) {
for (uint8_t y=top; y<=bottom; y++)
for (uint8_t x=0; x<GRID_WIDTH; x++)
LedSign::Set(13-y,x,playGrid[y][x]);
}
/* ----------------------------------------------------------------- */
/**
* End of the game, draw the score using a scroll.
*/
void endGame() {
for (uint8_t y=0;y<=13;y++) {
LedSign::Vertical(13-y, 0);
delay(100);
}
// Draw the score and scroll it
Figure::Scroll90(score);
}
/* ----------------------------------------------------------------- */
/**
* Game initialization, or reinitialization after a game over.
*/
void startGame() {
// Initialize variables.
level = 0;
score = 0;
linesCleared = 0;
memset(playGrid, '\0', sizeof(playGrid));
LedSign::Clear();
}
/* ----------------------------------------------------------------- */
/**
* Test whether a given piece can be put at a given location in the
* given location. This is used to check all piece moves.
* @param piece the piece to try and put on the play grid.
* @param position the position and view to try and put the piece.
*/
boolean checkPieceMove(const piece_t* piece, const pos_t& position) {
for (uint8_t i=0; i<4; i++) {
coordPacked_t element = piece->views[position.view].elements[i];
int8_t eltXPos = element.x+position.coord.x;
int8_t eltYPos = element.y+position.coord.y;
// Check x boundaries.
if (eltXPos>8 || eltXPos<0)
return false;
// Check y boundaries.
if (eltYPos>13 || eltYPos<0)
return false;
// Check collisions in grid.
if (playGrid[eltYPos][eltXPos])
return false;
}
return true;
}
/* ----------------------------------------------------------------- */
/**
* Handle player actions : left/right move and piece rotation.
*/
void playerMovePiece()
{
boolean moveSuccess;
int inputPos;
pos_t newPos;
// First try rotating the piece if requested.
// Ensure the player released the rotation button before doing a second one.
static byte status=0;
if (status == 0) {
if (analogRead(4)>1000) {
status = 1;
newPos = position;
newPos.view = (newPos.view+1)&3;
moveSuccess = checkPieceMove(currentPiece, newPos);
if (moveSuccess) {
switchPiece(currentPiece, position, 0);
switchPiece(currentPiece, newPos, 1);
position = newPos;
}
}
} else {
if (analogRead(4)<1000) {
status = 0;
}
}
newPos = position;
// Tweak the analog input to get a playable input.
inputPos=8-(analogRead(5)/72); // we reverse the command (variator wrongly connected ;) )
if (inputPos != position.coord.x) {
// Try moving the piece to the requested position.
// We must do it step by step and leave the loop at the first impossible movement otherwise we might
// traverse pieces already in the game grid if the user changes the input fast between two game loop iterations.
int diffSign = (inputPos>position.coord.x) ? 1 : -1;
for(int i=position.coord.x;(inputPos-i)*diffSign>=0;i+=diffSign) {
newPos.coord.x = i;
if (i<-1 || i>8) {
// Skip out of screen iterations.
// Don't skip -2, it's a correct x position for certain pieces' views.
continue;
} else {
moveSuccess = checkPieceMove(currentPiece, newPos);
if (moveSuccess) {
switchPiece(currentPiece, position, 0);
switchPiece(currentPiece, newPos, 1);
position = newPos;
} else {
break;
}
}
}
}
}
/* ----------------------------------------------------------------- */
/**
* Handle the current piece going down every few game loop iterations.
* @param count game loop counter, used to know if the piece should go
* down at each call.
*/
void timerPieceDown(uint32_t& count) {
// Every 10-level iterations, make the piece go down.
// TODO The level change code is largely untested and surely needs tweaking.
if (++count % (10-level) == 0) {
pos_t newPos = position;
newPos.coord.y++;
boolean moveSuccess = checkPieceMove(currentPiece, newPos);
if (moveSuccess) {
switchPiece(currentPiece, position, 0);
switchPiece(currentPiece, newPos, 1);
position = newPos;
} else {
// Drop the piece on the grid.
for (uint8_t i=0; i<4; i++) {
coordPacked_t element = currentPiece->views[position.view].elements[i];
uint8_t eltXPos = element.x+position.coord.x;
uint8_t eltYPos = element.y+position.coord.y;
playGrid[eltYPos][eltXPos] = true;
}
processEndPiece();
nextPiece();
}
}
}
/* ----------------------------------------------------------------- */
/**
* Handles :
* - the dropping of the current piece on the game grid when it can't
* go lower ;
* - the detection and removal of full lines ;
* - the score update ;
* - the level update when needed.
*/
void processEndPiece() {
uint8_t fullLines[4];
uint8_t numFull = 0;
for (int8_t y=13; y>=0; y--) {
boolean full = true;
for (uint8_t x=0; x<9; x++)
if (!playGrid[y][x])
full = false;
if (full)
fullLines[numFull++] = y;
}
if (numFull) {
// Blink full lines.
for (uint8_t i=0; i<5; i++) {
for (uint8_t j=0; j<numFull; j++)
LedSign::Vertical(13-fullLines[j], i&1);
delay(150);
}
// Remove full lines from the array.
for (uint8_t i=0; i<numFull; i++) {
uint8_t lineIdx = fullLines[i];
// Move all lines above one step down.
for (uint8_t j=lineIdx; j>0; j--)
memcpy(playGrid+j, playGrid+j-1, GRID_WIDTH*sizeof(boolean));
memset(playGrid, '\0', GRID_WIDTH*sizeof(boolean));
// Update the indexes of the other lines to remove.
for (uint8_t k=i; k<numFull; k++)
fullLines[k]++;
}
// Update the display.
redrawLines(0, fullLines[0]);
// Sega scoring algorithm.
score += levelMultiplier[level] * linesMultiplier[numFull-1];
// Level update.
linesCleared += numFull;
if (linesCleared >= 4) {
linesCleared = 0;
level++;
}
}
}
/* ----------------------------------------------------------------- */
/**
* Start dropping a new randomly chosen piece.
*/
void nextPiece() {
currentPiece = &pieces[random(0,7)];
position.coord.x = 3;
position.coord.y = -1;
position.view = 0;
if (!checkPieceMove(currentPiece, position)) {
endGame();
startGame();
}
}
/* ----------------------------------------------------------------- */
/** MAIN program Setup
*/
void setup() // run once, when the sketch starts
{
LedSign::Init();
randomSeed(analogRead(2));
startGame();
nextPiece();
}
/* ----------------------------------------------------------------- */
/** MAIN program Loop
*/
void loop() // run over and over again
{
static uint32_t counter = 0;
playerMovePiece();
timerPieceDown(counter);
delay(40);
}
@@ -1,186 +0,0 @@
/*
Basic LoL Shield Test
Writen for the LoL Shield, designed by Jimmie Rodgers:
http://jimmieprodgers.com/kits/lolshield/
This needs the Charliplexing library, which you can get at the
LoL Shield project page: http://code.google.com/p/lolshield/
Created by Jimmie Rodgers on 12/30/2009.
Adapted from: http://www.arduino.cc/playground/Code/BitMath
History:
December 30, 2009 - V1.0 first version written at 26C3/Berlin
This is free software; you can redistribute it and/or
modify it under the terms of the GNU Version 3 General Public
License as published by the Free Software Foundation;
or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <avr/pgmspace.h> //AVR library for writing to ROM
#include <Charliplexing.h> //Imports the library, which needs to be
//Initialized in setup.
//Sets the time each frame is shown (milliseconds)
const unsigned int blinkdelay = 75;
boolean fadeMode = false;
byte brightness = 7; //Brightness goes from 0-7
/*
The BitMap array is what contains the frame data. Each line is one full frame.
Since each number is 16 bits, we can easily fit all 14 LEDs per row into it.
The number is calculated by adding up all the bits, starting with lowest on
the left of each row. 18000 was chosen as the kill number, so make sure that
is at the end of the matrix, or the program will continue to read into memory.
Here PROGMEM is called, which stores the array into ROM, which leaves us
with our RAM. You cannot change the array during run-time, only when you
upload to the Arduino. You will need to pull it out of ROM, which is covered
below. If you want it to stay in RAM, just delete PROGMEM
*/
PROGMEM const uint16_t BitMap[][9] = {
//Diaganal swipe across the screen
{1, 0, 0, 0, 0, 0, 0, 0, 0},
{3, 1, 0, 0, 0, 0, 0, 0, 0},
{7, 3, 1, 0, 0, 0, 0, 0, 0},
{15, 7, 3, 1, 0, 0, 0, 0, 0},
{31, 15, 7, 3, 1, 0, 0, 0, 0},
{63, 31, 15, 7, 3, 1, 0, 0, 0},
{127, 63, 31, 15, 7, 3, 1, 0, 0},
{255, 127, 63, 31, 15, 7, 3, 1, 0},
{511, 255, 127, 63, 31, 15, 7, 3, 1},
{1023, 511, 255, 127, 63, 31, 15, 7, 3},
{2047, 1023, 511, 255, 127, 63, 31, 15, 7},
{4095, 2047, 1023, 511, 255, 127, 63, 31, 15},
{8191, 4095, 2047, 1023, 511, 255, 127, 63, 31},
{16383, 8191, 4095, 2047, 1023, 511, 255, 127, 63},
{16383, 16383, 8191, 4095, 2047, 1023, 511, 255, 127},
{16383, 16383, 16383, 8191, 4095, 2047, 1023, 511, 255},
{16383, 16383, 16383, 16383, 8191, 4095, 2047, 1023, 511},
{16383, 16383, 16383, 16383, 16383, 8191, 4095, 2047, 1023},
{16383, 16383, 16383, 16383, 16383, 16383, 8191, 4095, 2047},
{16383, 16383, 16383, 16383, 16383, 16383, 16383, 8191, 4095},
{16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 8191},
{16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383},
{16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383},
{16382, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383},
{16380, 16382, 16383, 16383, 16383, 16383, 16383, 16383, 16383},
{16376, 16380, 16382, 16383, 16383, 16383, 16383, 16383, 16383},
{16368, 16376, 16380, 16382, 16383, 16383, 16383, 16383, 16383},
{16352, 16368, 16376, 16380, 16382, 16383, 16383, 16383, 16383},
{16320, 16352, 16368, 16376, 16380, 16382, 16383, 16383, 16383},
{16256, 16320, 16352, 16368, 16376, 16380, 16382, 16383, 16383},
{16128, 16256, 16320, 16352, 16368, 16376, 16380, 16382, 16383},
{15872, 16128, 16256, 16320, 16352, 16368, 16376, 16380, 16382},
{15360, 15872, 16128, 16256, 16320, 16352, 16368, 16376, 16380},
{14336, 15360, 15872, 16128, 16256, 16320, 16352, 16368, 16376},
{12288, 14336, 15360, 15872, 16128, 16256, 16320, 16352, 16368},
{8192, 12288, 14336, 15360, 15872, 16128, 16256, 16320, 16352},
{0, 8192, 12288, 14336, 15360, 15872, 16128, 16256, 16320},
{0, 0, 8192, 12288, 14336, 15360, 15872, 16128, 16256},
{0, 0, 0, 8192, 12288, 14336, 15360, 15872, 16128},
{0, 0, 0, 0, 8192, 12288, 14336, 15360, 15872},
{0, 0, 0, 0, 0, 8192, 12288, 14336, 15360},
{0, 0, 0, 0, 0, 0, 8192, 12288, 14336},
{0, 0, 0, 0, 0, 0, 0, 8192, 12288},
{0, 0, 0, 0, 0, 0, 0, 0, 8192},
{0, 0, 0, 0, 0, 0, 0, 0, 0},
//Horizontal swipe
{1, 1, 1, 1, 1, 1, 1, 1, 1} ,
{3, 3, 3, 3, 3, 3, 3, 3, 3},
{7, 7, 7, 7, 7, 7, 7, 7, 7},
{15, 15, 15, 15, 15, 15, 15, 15, 15},
{31, 31, 31, 31, 31, 31, 31, 31, 31},
{63, 63, 63, 63, 63, 63, 63, 63, 63},
{127, 127, 127, 127, 127, 127, 127, 127, 127},
{255, 255, 255, 255, 255, 255, 255, 255, 255},
{511, 511, 511, 511, 511, 511, 511, 511, 511},
{1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023},
{2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047},
{4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095},
{8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191},
{16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383},
{16382, 16382, 16382, 16382, 16382, 16382, 16382, 16382, 16382},
{16380, 16380, 16380, 16380, 16380, 16380, 16380, 16380, 16380},
{16376, 16376, 16376, 16376, 16376, 16376, 16376, 16376, 16376},
{16368, 16368, 16368, 16368, 16368, 16368, 16368, 16368, 16368},
{16352, 16352, 16352, 16352, 16352, 16352, 16352, 16352, 16352},
{16320, 16320, 16320, 16320, 16320, 16320, 16320, 16320, 16320},
{16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256},
{16128, 16128, 16128, 16128, 16128, 16128, 16128, 16128, 16128},
{15872, 15872, 15872, 15872, 15872, 15872, 15872, 15872, 15872},
{15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360},
{14336, 14336, 14336, 14336, 14336, 14336, 14336, 14336, 14336},
{12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288},
{8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192},
{0, 0, 0, 0, 0, 0, 0, 0, 0},
{18000}
};
void setup() {
LedSign::Init(GRAYSCALE); //Initializes the screen
}
void loop() {
if(fadeMode)
for (uint8_t gray = 1; gray < SHADES; gray++)
DisplayBitMap(gray); //Displays the bitmap
else DisplayBitMap(brightness); //Displays the bitmap
}
void DisplayBitMap(uint8_t grayscale)
{
boolean run=true; //While this is true, the screen updates
byte frame = 0; //Frame counter
byte line = 0; //Row counter
unsigned long data; //Temporary storage of the row data
unsigned long start = 0;
while(run == true) {
for(line = 0; line < 9; line++) {
//Here we fetch data from program memory with a pointer.
data = pgm_read_word_near (&BitMap[frame][line]);
//Kills the loop if the kill number is found
if (data==18000){
run=false;
}
//This is where the bit-shifting happens to pull out
//each LED from a row. If the bit is 1, then the LED
//is turned on, otherwise it is turned off.
else for (byte led=0; led<14; ++led) {
if (data & (1<<led)) {
LedSign::Set(led, line, grayscale);
}
else {
LedSign::Set(led, line, 0);
}
}
}
LedSign::Flip(true);
unsigned long end = millis();
unsigned long diff = end - start;
if ( start && (diff < blinkdelay) )
delay( blinkdelay - diff );
start = end;
frame++;
}
}
@@ -1,74 +0,0 @@
/*
LoL Shield grayscale / fading test
Writen for the LoL Shield, designed by Jimmie Rodgers:
http://jimmieprodgers.com/kits/lolshield/
Written by Thilo Fromm <kontakt@thilo-fromm.de>
largely based on the work of Matt Mets <Matt.Mets@gmail.com>.
This is free software; you can redistribute it and/or
modify it under the terms of the GNU Version 3 General Public
License as published by the Free Software Foundation;
or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "Charliplexing.h"
// Screen "refresh"
const unsigned int fps = 40;
const unsigned int fps_ms = 1000 / fps;
unsigned int frames = 0;
// number of frames to wait before advance animation
const unsigned int frames_per_step = 10;
void setup() // run once, when the sketch starts
{
LedSign::Init(DOUBLE_BUFFER | GRAYSCALE);
}
uint8_t i = 0;
void loop() // run over and over again
{
static unsigned long start = 0;
unsigned long end;
for (int row = 0; row < DISPLAY_ROWS; row++)
for (int col = 0; col < DISPLAY_COLS; col++)
LedSign::Set(col, row, (row+col + i)%SHADES);
LedSign::Flip(true);
if (0 == (frames++) % frames_per_step)
i++;
end = millis();
if (start) {
unsigned long diff = end - start;
if ( diff < fps_ms ) {
delay( fps_ms - diff );
} else {
// Signal that we're too slow...
LedSign::Clear(0);
LedSign::Flip();
delay(500);
LedSign::Clear(SHADES-1);
LedSign::Flip();
delay(500);
// re-set timeout
end = millis();
}
}
start = end;
}
@@ -1,64 +0,0 @@
/*
TEXT SAMPLE CODE for LOL Shield for Arduino
Copyright 2009/2010 Benjamin Sonntag <benjamin@sonntag.fr> http://benjamin.sonntag.fr/
History:
2009-12-31 - V1.0 FONT Drawing, at Berlin after 26C3 ;)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include "Charliplexing.h"
#include "Font.h"
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
/* ----------------------------------------------------------------- */
/** MAIN program Setup
*/
void setup() // run once, when the sketch starts
{
LedSign::Init();
}
/* ----------------------------------------------------------------- */
/** MAIN program Loop
*/
static const char test[]="HELLO WORLD! ";
void loop() // run over and over again
{
for (int8_t x=DISPLAY_COLS, i=0;; x--) {
LedSign::Clear();
for (int8_t x2=x, i2=i; x2<DISPLAY_COLS;) {
int8_t w = Font::Draw(test[i2], x2, 0);
x2 += w, i2 = (i2+1)%strlen(test);
if (x2 <= 0) // off the display completely?
x = x2, i = i2;
}
delay(80);
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

-110
View File
@@ -1,110 +0,0 @@
/*
Base 12 Clock
Writen for the LoL Shield, designed by Jimmie Rodgers:
http://jimmieprodgers.com/kits/lolshield/
This needs the Charliplexing library, which you can get at the
LoL Shield project page: http://code.google.com/p/lolshield/
This also uses the Adafruit DS1307 breakout, which you will also
need the library for:
http://www.ladyada.net/learn/breakoutplus/ds1307rtc.html
Created by Jimmie Rodgers on 2/2/2011.
This is free software; you can redistribute it and/or
modify it under the terms of the GNU Version 3 General Public
License as published by the Free Software Foundation;
or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
//These libraries need to be included for both the LoL Shield
//and DS1307 breakout.
#include "Charliplexing.h"
#include "WProgram.h"
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;
void setup () {
LedSign::Init(); //initializes the LoL Shield frame buffer
pinMode(16, OUTPUT); //16 and 17 power the DS1307
pinMode(17, OUTPUT);
digitalWrite(16, LOW); //ground for the DS1307
digitalWrite(17, HIGH);//provides 5v for the DS1307
Wire.begin(); //starts the I2C serial on pins 18&19
RTC.begin(); //starts communication with the DS1307
}
void loop(){
DateTime now = RTC.now(); //creates a DateTime object
//I set the time all at once so that it doesn't cause
//strange timing issues
int hour = now.hour();
int minute = now.minute();
int second = now.second();
//These are used to easily parse the seconds
int fiveCount = second / 5;
int tenCount = second % 10;
//It only needs to clear on counts of 10, as that
//is the only time the display really changes.
if (tenCount == 0 )LedSign::Clear();
//These loops set the seconds on the LoL Shield.
for (int i=0; i < tenCount+1; i++){
if (i < 5)LedSign::Set(i+1, 8, 1);
else LedSign::Set(i+3, 8, 1);
}
for (int i=0; i < fiveCount+1;i++){
LedSign::Set(i+1, 7, 1);
}
//This loop sets the hour.
for (int x=0; x < hour; x++){
if(x < 12){
if (x < 6)LedSign::Set(x, 0, 1);
else LedSign::Set(x+1, 0, 1);
}
else{
if (x < 18)LedSign::Set(x-12, 1, 1);
else LedSign::Set(x-11, 1, 1);
}
}
//This loop sets the minutes
for (int x=0; x < minute; x++){
if(x < 12){
if (x < 6)LedSign::Set(x+1, 2, 1);
else LedSign::Set(x+2, 2, 1);
}
else if (x < 24){
if (x < 18)LedSign::Set(x-11, 3, 1);
else LedSign::Set(x-10, 3, 1);
}
else if (x < 36){
if (x < 30)LedSign::Set(x-23, 4, 1);
else LedSign::Set(x-22, 4, 1);
}
else if (x < 48){
if (x < 42)LedSign::Set(x-35, 5, 1);
else LedSign::Set(x-34, 5, 1);
}
else if (x < 60){
if (x < 54)LedSign::Set(x-47, 6, 1);
else LedSign::Set(x-46, 6, 1);
}
}
delay(500);//no reason to update much more than this
}
-510
View File
@@ -1,510 +0,0 @@
//This is a series of animations for a belt buckle. You can cycle the animations by cycling the power.
#include "Charliplexing.h"
#include "Myfont.h"
#include "Arduino.h"
#include <EEPROM.h>
int toggleState;
int EEPROMaddress = 0;
int charLength[]={
20, 14, 23, 30};
unsigned char text0[]="My eyes are up there";
unsigned char text1[]="Blinky or GTFO";
unsigned char text2[]="Enjoying the lightshow?";
unsigned char text3[]="Would you like to play a game?";
//Game of Life stuff
#define DELAY 150 //Sets the time each generation is shown
#define RESEEDRATE 5000 //Sets the rate the world is re-seeded
#define SIZEX 14 //Sets the X axis size
#define SIZEY 9 //Sets the Y axis size
byte world[SIZEX][SIZEY][2]; //Creates a double buffer world
long density = 50; //Sets density % during seeding
int geck = 0; //Counter for re-seeding
//ball stuff
int collision[14][9];
void setup(){
toggleState = EEPROM.read(EEPROMaddress);
upToggleState();
if (1==toggleState || 7==toggleState){
LedSign::Init(GRAYSCALE);
}
else{
LedSign::Init();
}
for (int i = toggleState+1; i > 0; i--){
LedSign::Set(i-1, 0, 255);
}
delay(1000);
LedSign::Clear(0);
}
void loop(){
/*
0 "My eyes are up there"
1 *Plasma
2 "Blinky or GTFO"
3 *Game of Life
4 "Enjoying the lightshow?"
5 *Balls
6 "Would you like to play a game?"
7 *Double Helix
*/
switch(toggleState){
case 0:
Myfont::Banner(charLength[0],text0);
break;
case 1:
plasma();
break;
case 2:
Myfont::Banner(charLength[1],text1);
break;
case 3:
life();
case 4:
Myfont::Banner(charLength[2],text2);
break;
case 5:
balls();
break;
case 6:
Myfont::Banner(charLength[3],text3);
break;
case 7:
DNA();
break;
default:
EEPROM.write(EEPROMaddress, 0);
}
}
//Ups or resets the state counter
void upToggleState(){
toggleState++;
if (toggleState > 7) toggleState = 0;
EEPROM.write(EEPROMaddress, toggleState);
}
void plasma(){
/*
Plasma
written by Zach Archer http://zacharcher.com/
NOTES:
- Requires the LoLshield library to run. Get the library here: http://code.google.com/p/lolshield/downloads/
- How to install the library: http://www.arduino.cc/en/Hacking/Libraries
This sketch moves two points along Lissajious curves. See: http://en.wikipedia.org/wiki/Lissajous_curve
The distances between each LED and each point are multiplied,
then this value is shaped using a sine function, and this sets the brightness of each LED.
*/
// Convenient 2D point structure
struct Point {
float x;
float y;
};
float phase = 0.0;
float phaseIncrement = 0.08; // Controls the speed of the moving points. Higher == faster. I like 0.08 .
float colorStretch = 0.11; // Higher numbers will produce tighter color bands. I like 0.11 .
// This function is called every frame.
while(true) {
phase += phaseIncrement;
// The two points move along Lissajious curves, see: http://en.wikipedia.org/wiki/Lissajous_curve
// We want values that fit the LED grid: x values between 0..13, y values between 0..8 .
// The sin() function returns values in the range of -1.0..1.0, so scale these to our desired ranges.
// The phase value is multiplied by various constants; I chose these semi-randomly, to produce a nice motion.
Point p1 = {
(sin(phase*1.000)+1.0) * 7.5, (sin(phase*1.310)+1.0) * 4.0 };
Point p2 = {
(sin(phase*1.770)+1.0) * 7.5, (sin(phase*2.865)+1.0) * 4.0 };
byte row, col;
// For each row...
for( row=0; row<9; row++ ) {
float row_f = float(row); // Optimization: Keep a floating point value of the row number, instead of recasting it repeatedly.
// For each column...
for( col=0; col<14; col++ ) {
float col_f = float(col); // Optimization.
// Calculate the distance between this LED, and p1.
Point dist1 = {
col_f - p1.x, row_f - p1.y }; // The vector from p1 to this LED.
float distance = sqrt( dist1.x*dist1.x + dist1.y*dist1.y );
// Calculate the distance between this LED, and p2.
Point dist2 = {
col_f - p2.x, row_f - p2.y }; // The vector from p2 to this LED.
// Multiply this with the other distance, this will create weird plasma values :)
distance *= sqrt( dist2.x*dist2.x + dist2.y*dist2.y );
//distance += sqrt( dist2.x*dist2.x + dist2.y*dist2.y ); // Variation: weird linear color bands. Might need to increase colorStretch
// Warp the distance with a sin() function. As the distance value increases, the LEDs will get light,dark,light,dark,etc...
// You can use a cos() for slightly different shading, or experiment with other functions. Go crazy!
float color_f = (sin( distance * colorStretch ) + 1.0) * 0.5; // range: 0.0...1.0
// Square the color_f value to weight it towards 0. The image will be darker and have higher contrast.
color_f *= color_f;
//color_f *= color_f*color_f*color_f; // Uncomment this line to make it even darker :)
// Scale the color up to 0..7 . Max brightness is 7.
LedSign::Set( col, row, byte( round(color_f * 7.0) ) );
}
}
// There's so much math happening, it's already a bit slow ;) No need for extra delays!
//delay( 20 );
}
}
void DNA(){
/*
DoubleHelix
written by Zach Archer http://zacharcher.com/
NOTES:
- Requires the LoLshield library to run. Get the library here: http://code.google.com/p/lolshield/downloads/
- How to install the library: http://www.arduino.cc/en/Hacking/Libraries
This sketch draws two sine waves with different brightness values.
The phase of the "darker" sine wave will drift a bit.
On every other column, LEDs between the sines will be subtly lit (hopefully resembling DNA nucleobases).
*/
// You can tweak these values to create a custom DNA molecule :)
float stretch = 0.44; // The width of each sine wave. Smaller values create wider sine waves. I like 0.44 .
float phaseIncrement = 0.1; // How fast the sines move. I like 0.1 .
// The phase of the "darker" sine wave will drift (relative to the "lighter" sine wave).
// This makes the DoubleHelix more organic/hypnotic .
float driftIncrement = 0.019; // The speed it drifts back and forth. Larger == faster. I like 0.019 .
float driftForce = 0.4; // The visual amount of drift. I like 0.4 .
// On every other column, light the LEDs between the sine waves, resembling the nucleotides of a DNA molecule.
// This looks good if we switch between lighting odd columns, then even columns -- the molecule appears to be moving.
float barPhaseIncrement = 0.09; // Bar movement speed. Plz use values between 0..1 . I like 0.09 .
// Brightness values. Range is 0..7
byte lightSineBrightness = 7;
byte darkSineBrightness = 3;
byte barBrightness = 1;
// (End tweak section)
// These values change every frame:
float phase = 0.0; // This is how "far" we've travelled along the DNA.
float driftPhase = 0.0;
float barPhase = 0.0;
// This function is called every frame.
while(true) {
phase += phaseIncrement; // Move the sine waves forward.
// The "darker" sine wave drifts (relative to the "lighter" sine wave).
driftPhase += driftIncrement;
// Increment the position of the bars.
barPhase += barPhaseIncrement;
if( barPhase > 1.0 ) barPhase -= 1.0; // Wrap this value between 0..1 .
// We'll hilite either the even columns, or odd columns, depending on the value of barPhase.
boolean drawEvenBars = (barPhase < 0.5);
byte row, col;
// For each column of LEDs...
for( col=0; col<14; col++ ) {
// This is the "raw" value for the lighter sine wave. Range: -1.0...1.0
float lightSineThisColumn = sin( phase + float(col)*stretch );
// Scale the "raw" value and round it off, so the range is 0..8 . This is the LED we're going to light in this column.
int lightSine = int( round( lightSineThisColumn*4.0 ) ) + 4;
// driftPhase controls the phase drift of the "darker" sine.
// The drift amount is derived from this sin() function, so it will drift back and forth.
// Orbit around 2.1, which is about 1/3 phase offset from the lighter sine wave (2*PI/3). Looks pretty good.
float drift = 2.1 + (driftForce * sin( driftPhase ));
// This is the LED we're going to light for the "dark" sine wave.
// This is similar to computing the lightSine value, but it's compacted into one line :P
int darkSine = int( round( sin(phase+drift+float(col)*stretch)*4.0 ) ) + 4;
// For each LED within the column...
for( row=0; row<9; row++ ) {
// Does this LED belong to our light sine wave?
if( row==lightSine ) {
LedSign::Set( col, row, lightSineBrightness ); // The third argument is the brightness. Max bright == 7.
// Does this LED belong to our dark sine wave?
}
else if( row==darkSine ) {
LedSign::Set( col, row, darkSineBrightness ); // The third argument is the brightness.
}
else {
// This LED doesn't belong to either sine wave. So we'll turn it off, unless it belongs to a vertical bar.
int color = 0; // 0 == unlit
// Alternate even/odd columns:
// If col is an odd number, (col & 0x1) evaluates to true. (Example: 13 == B1101, rightmost bit is 1, so it's odd!)
// The ^ operator is binary XOR. So this statement evaluates true if _one_ condition is met, but _not_ both.
if( (col & 0x1) ^ (drawEvenBars) ) {
// If lightSine is above this LED, and darkSine is below, then this LED belongs to a vertical bar.
if( lightSine < darkSine ) {
if( lightSine<row && row<darkSine ) {
color = barBrightness;
}
// If darkSine is above, and lightSine is below, this LED belongs to a vertical bar.
}
else if( darkSine < lightSine ) {
if( darkSine<row && row<lightSine ) {
color = barBrightness;
}
}
}
LedSign::Set( col, row, color );
}
}
}
// Wait between frames to slow down the animation.
delay( 20 );
}
}
void balls(){
//0 = xPos, 1 = xDir, 2 = yPos, 3 = yDir
/*int balls [][4] = {
{0,1,8,1},
{1,1,7,1},
{2,1,6,1},
{3,1,5,1},
{4,1,4,1},
{5,1,3,1},
{6,1,2,1},
{7,1,1,1},
{8,1,0,1},
{1,1,1,1},
{255}};
*/
int balls [][4] = {
{
7,1,0,1 }
,
{
6,1,1,1 }
,
{
8,1,1,1 }
,
{
5,1,2,1 }
,
{
9,1,2,1 }
,
{
4,1,3,1 }
,
{
10,1,3,1 }
,
{
5,1,4,1 }
,
{
9,1,4,1 }
,
{
6,1,5,1 }
,
{
8,1,5,1 }
,
{
7,1,6,1 }
,
{
255 }
};
int numBalls;
int scrollSpeed = 100; //delay between frames
int collision[14][9];
//int clearedCollision[14][9];
LedSign::Init(); //initializes a grayscale frame buffer
for (numBalls = 0; numBalls < 255; numBalls++){
if(balls[numBalls][0] == 255) break;
}
while(true) // run over and over again
{
for (int i = 0; i < numBalls; i++)moveBall(balls[i]);
delay(scrollSpeed);
LedSign::Clear(0);
for (int x = 0; x < 14; x++) for (int y = 0; y <9; y++) collision[x][y] = 0;
}
}
void moveBall(int ball[])
{
//0 = xPos, 1 = Dir, 2 = yPos, 3 = yDir
if (ball[0] == 13)ball[1] = 0;
if (ball[0] == 0)ball[1] = 1;
if (ball[2] == 8)ball[3] = 0;
if (ball[2] == 0)ball[3] = 1;
if ((ball[1] == 1) && (collision[ball[0]+1][ball[2]]==1)) ball[1]= !ball[1];
if ((ball[1] == 0) && (collision[ball[0]-1][ball[2]]==1)) ball[1]= !ball[1];
if ((ball[3] == 1) && (collision[ball[0]][ball[2]+1]==1)) ball[3]= !ball[3];
if ((ball[3] == 0) && (collision[ball[0]][ball[2]-1]==1)) ball[3]= !ball[3];
if (ball[1]) ball[0]++;
else ball[0]--;
if (ball[3]) ball[2]++;
else ball[2]--;
collision[ball[0]][ball[2]] = 1;
LedSign::Set(ball[0], ball[2], 1);
}
void life(){
/*
Conway's "Life"
Writen for the LoL Shield, designed by Jimmie Rodgers:
http://jimmieprodgers.com/kits/lolshield/
This needs the Charliplexing library, which you can get at the
LoL Shield project page: http://code.google.com/p/lolshield/
Created by Jimmie Rodgers on 12/30/2009.
Adapted from: http://www.arduino.cc/playground/Main/DirectDriveLEDMatrix
History:
December 30, 2009 - V1.0 first version written at 26C3/Berlin
This is free software; you can redistribute it and/or
modify it under the terms of the GNU Version 3 General Public
License as published by the Free Software Foundation;
or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
//#include <Charliplexing.h> //Imports the library, which needs to be
//Initialized in setup.
randomSeed(analogRead(5));
//Builds the world with an initial seed.
for (int i = 0; i < SIZEX; i++) {
for (int j = 0; j < SIZEY; j++) {
if (random(100) < density) {
world[i][j][0] = 1;
}
else {
world[i][j][0] = 0;
}
world[i][j][1] = 0;
}
}
while(true) {
// Birth and death cycle
for (int x = 0; x < SIZEX; x++) {
for (int y = 0; y < SIZEY; y++) {
// Default is for cell to stay the same
world[x][y][1] = world[x][y][0];
int count = neighbours(x, y);
geck++;
if (count == 3 && world[x][y][0] == 0) {
// A new cell is born
world[x][y][1] = 1;
LedSign::Set(x,y,1);
}
else if ((count < 2 || count > 3) && world[x][y][0] == 1) {
// Cell dies
world[x][y][1] = 0;
LedSign::Set(x,y,0);
}
}
}
//Counts and then checks for re-seeding
//Otherwise the display will die out at some point
geck++;
if (geck > RESEEDRATE){
seedWorld();
geck = 0;
}
// Copy next generation into place
for (int x = 0; x < SIZEX; x++) {
for (int y = 0; y < SIZEY; y++) {
world[x][y][0] = world[x][y][1];
}
}
delay(DELAY);
}
//Re-seeds based off of RESEEDRATE
//Runs the rule checks, including screen wrap
}
void seedWorld(){
randomSeed(analogRead(5));
for (int i = 0; i < SIZEX; i++) {
for (int j = 0; j < SIZEY; j++) {
if (random(100) < density) {
world[i][j][1] = 1;
}
}
}
}
int neighbours(int x, int y) {
return world[(x + 1) % SIZEX][y][0] +
world[x][(y + 1) % SIZEY][0] +
world[(x + SIZEX - 1) % SIZEX][y][0] +
world[x][(y + SIZEY - 1) % SIZEY][0] +
world[(x + 1) % SIZEX][(y + 1) % SIZEY][0] +
world[(x + SIZEX - 1) % SIZEX][(y + 1) % SIZEY][0] +
world[(x + SIZEX - 1) % SIZEX][(y + SIZEY - 1) % SIZEY][0] +
world[(x + 1) % SIZEX][(y + SIZEY - 1) % SIZEY][0];
}
-153
View File
@@ -1,153 +0,0 @@
#!/usr/bin/env python
# This program by Adam Mayer
# http://www.nycresistor.com/2010/03/22/march-madness-backlog-microcontroller-pixel-font/
from PIL import Image
from optparse import OptionParser
from string import Template
import sys
# pngToFont takes a simple 1-bit image of a pixel font
# and converts it to a chunk of C code that we can use
# in microcontroller code.
# Edit this to reflect the order that characters appear
# in your font. Each character should be seperated by
# one column of white pixels.
char_order = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.!?@/:;()"
# Header and types for font.
# We're a little tight on space, so it's program memory
# for you. Hooray for Harvard architectures.
font_header_templ = Template("""
#include <stdint.h>
#include <avr/pgmspace.h>
typedef struct {
uint8_t offset;
uint8_t len;
} PROGMEM char_entry;
#define FONT_HEIGHT $height
#define FONT_DATA_SIZE $data_size
extern char_entry font_table[128];
extern prog_uint8_t font_data[FONT_DATA_SIZE];
uint8_t get_char_len(uint8_t c);
uint8_t get_char_bit(uint8_t c, uint8_t row, uint8_t column);
""")
font_source_templ = Template("""
#include "$header"
char_entry font_table[128] PROGMEM = {
$font_table
};
prog_uint8_t font_data[FONT_DATA_SIZE] PROGMEM = {
$font_data
};
uint8_t get_char_len(uint8_t c) {
return pgm_read_byte(&(font_table[c].len));
}
uint8_t get_char_bit(uint8_t c, uint8_t row, uint8_t column) {
uint8_t offset = pgm_read_byte(&(font_table[c].offset));
uint8_t col = pgm_read_byte(&(font_data[offset+column]));
return ((col & _BV(row)) == 0)?0:1;
}
""")
def get_column(im,x_offset):
"Get the bitmap column as an int, with black pixels as 1"
(_, height) = im.size
val = 0
for bit in range(height):
if im.getpixel((x_offset,bit)) == 0:
val = val | (1 << bit)
return val
class Character:
def __init__(self,im,x_offset):
self.len = 0
self.seeklen = 0
self.columns = []
column = get_column(im,x_offset)
# Skip leading whitespace
while column == 0:
x_offset = x_offset + 1
column = get_column(im,x_offset)
self.seeklen = self.seeklen + 1
while column != 0:
self.columns.append(column)
self.len = self.len + 1
self.seeklen = self.seeklen + 1
x_offset = x_offset + 1
column = get_column(im,x_offset)
charmap = {}
def png_to_font(im,c_path,h_path):
c_file = open(c_path,"w")
h_file = open(h_path,"w")
x_offset = 0
data_size = 0
# load all the characters from the image file
for char in char_order:
charmap[char] = Character(im,x_offset)
x_offset = x_offset + charmap[char].seeklen + 1
data_size = data_size + charmap[char].len
print "Char " + char + " is len " + str(charmap[char].len) + ", but took " + str(charmap[char].seeklen)
# write out the header
h_file.write(font_header_templ.substitute(
count=len(char_order),
data_size=data_size,
height=im.size[1]))
h_file.close
# build the tables
font_data = ""
font_table = ""
offset = 0
for i in range(128):
char = chr(i)
if charmap.has_key(char):
c = charmap[char]
c.offset = offset
font_table = font_table + " {%d, %d},\n" % (offset,c.len)
font_data = font_data + ",\n".join(map(hex,c.columns)) + ",\n"
offset = offset + c.len
else:
font_table = font_table + " {0,0},\n"
# write out the source
c_file.write(font_source_templ.substitute(
font_table = font_table,
font_data = font_data,
header=h_path))
c_file.close()
def main():
parser = OptionParser(usage="usage: %prog [options] source")
parser.add_option("-o","--output",dest="out_path",
help="output to given base path")
(options,args) = parser.parse_args()
if len(args) != 1:
parser.error("Please provide a single input file.")
image = Image.open(args[0])
image = image.convert("L")
c_path = "font.cpp"
h_path = "font.h"
if (options.out_path):
c_path = options.out_path + ".c"
h_path = options.out_path + ".h"
png_to_font(image,c_path,h_path)
if __name__ == "__main__":
main()
-60
View File
@@ -1,60 +0,0 @@
#!/usr/bin/python
# Python script to convert a 14x9 pixel animated gif into a format that can
# be displayed on the LoLShield.
#
# By Matt Mets
#
# Requires Python and the Python Imaging Library (PIL)
# It would be nice if this was available using a more common language.
import sys, os, Image
class ImageSequence:
def __init__(self, im):
self.im = im
def __getitem__(self, ix):
try:
if ix:
self.im.seek(ix)
return self.im
except EOFError:
raise IndexError # end of sequence
# Open image
filename = sys.argv[1]
filenameBase = os.path.splitext(os.path.split(filename)[1])[0]
im = Image.open(filename)
# Print the variable declaration
print "uint16_t " + filenameBase + "[][9] PROGMEM = {"
# For each frame in the image, convert it to black & white, then into the
# LoLShield format
for frame in ImageSequence(im):
# Convert to black and white
converted = frame.convert("1")
print " {",
frameString = converted.tostring()
# For each row in the image
for row in range (0, 9):
charA = ord(frameString[row*2])
charB = ord(frameString[row*2 + 1])
rowTotal = 0
# Handle the first 8 bits
for col in range (0, 8):
shiftAmount = 7-col
rowTotal += ((charA >> shiftAmount) & 1) * 2**col
# Then the next 6
for col in range (0, 6):
shiftAmount = 7-col
rowTotal += ((charB >> shiftAmount) & 1) * 2**(col+8)
# And output the total for this row
print rowTotal, ",",
print "},"
print "};"
-8
View File
@@ -1,8 +0,0 @@
.PHONY: clean
control: control.c ../lolcomm/lolproto.h
${CC} -Wall -I../lolcomm -o $@ $< -lm
clean:
rm -f control
-247
View File
@@ -1,247 +0,0 @@
/*
Linux LoLShield communication lib command line client.
Written by Thilo Fromm <kontakt@thilo-fromm.de>.
---------------
THIS IS NOT AN ARDUINO APPLICATION.
It is a remote control tool for Linux hosts
which lets you set LEDs via the command line.
DO NOT TRY TO COMPILE THIS WITH ARDUINO. IT WON'T WORK.
---------------
Writen for the lolcomm example, which was written for the
LoL Shield, designed by Jimmie Rodgers:
http://jimmieprodgers.com/kits/lolshield/
This is free software; you can redistribute it and/or
modify it under the terms of the GNU Version 3 General Public
License as published by the Free Software Foundation;
or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "lolproto.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define BAUDRATE B115200
#define MODEMDEVICE "/dev/ttyUSB0"
static int setup_serial( struct termios * oldtio )
{
int fd;
struct termios newtio;
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
if (fd <0) {perror(MODEMDEVICE); exit(-1); }
tcgetattr(fd,oldtio); /* save current port settings */
bzero(&newtio, sizeof(newtio));
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
/* set input mode (non-canonical, no echo,...) */
newtio.c_lflag = 0;
newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
newtio.c_cc[VMIN] = sizeof(struct lolret); /* blocking read until 5 chars received */
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
return fd;
}
/* --- */
static void close_serial( int fd, struct termios * oldtio )
{
tcsetattr( fd,TCSANOW,oldtio );
close( fd );
}
/* --- */
static unsigned int do_setled( int fd, int argc, char ** argv )
{
uint8_t cmd = cmd_setled;
struct cmd_setled_payload setled;
if (argc != 3) {
printf("\nInvalid number of arguments for command."
" Have %d, want %d.\n\n", argc, 3);
return 1;
}
setled.coord.x = atoi( argv[0] );
setled.coord.y = atoi( argv[1] );
setled.brightness = atoi( argv[2] );
write( fd, &cmd, sizeof( cmd ) );
write( fd, &setled, sizeof( setled ) );
return 0;
}
/* --- */
static unsigned int do_setall( int fd, int argc, char ** argv )
{
uint8_t cmd = cmd_setall;
struct cmd_setall_payload setall;
if (argc != 1) {
printf("\nInvalid number of arguments for command."
" Have %d, want %d.\n\n", argc, 1);
return 1;
}
setall.brightness = atoi( argv[0] );
write( fd, &cmd, sizeof( cmd ) );
write( fd, &setall, sizeof( setall ) );
return 0;
}
/* --- */
static unsigned int do_pulseall( int fd, int argc, char ** argv )
{
uint8_t cmd = cmd_pulseall;
struct cmd_pulseall_payload pulse;
if (argc != 6) {
printf("\nInvalid number of arguments for command."
" Have %d, want %d.\n\n", argc, 1);
return 1;
}
pulse.ramp_up_time_ms_pow2 = sqrt( atoi( argv[0] ) );
pulse.ramp_up_modifier = atoi( argv[1] );
pulse.lit_time_ms_pow2 = sqrt( atoi( argv[2] ) );
pulse.ramp_dn_time_ms_pow2 = sqrt( atoi( argv[3] ) );
pulse.ramp_dn_modifier = atoi( argv[4] );
pulse.off_time_ms_pow2 = sqrt( atoi( argv[5] ) );
write( fd, &cmd, sizeof( cmd ) );
write( fd, &pulse, sizeof( pulse ) );
return 0;
}
/* --- */
static unsigned int do_pulseled( int fd, int argc, char ** argv )
{
uint8_t cmd = cmd_pulseled;
struct cmd_pulseled_payload pulse;
if (argc != 8) {
printf("\nInvalid number of arguments for command."
" Have %d, want %d.\n\n", argc, 1);
return 1;
}
pulse.coord.x = atoi( argv[0] );
pulse.coord.y = atoi( argv[1] );
pulse.ramp_up_time_ms_pow2 = sqrt( atoi( argv[2] ) );
pulse.ramp_up_modifier = atoi( argv[3] );
pulse.lit_time_ms_pow2 = sqrt( atoi( argv[4] ) );
pulse.ramp_dn_time_ms_pow2 = sqrt( atoi( argv[5] ) );
pulse.ramp_dn_modifier = atoi( argv[6] );
pulse.off_time_ms_pow2 = sqrt( atoi( argv[7] ) );
write( fd, &cmd, sizeof( cmd ) );
write( fd, &pulse, sizeof( pulse ) );
return 0;
}
/* --- */
static void usage(char ** argv)
{
printf("\nUsage: %s <command> <command specific number of arguments>\n", argv[0]);
printf("Supported commands:\n\n");
printf(" setled Set a single LED. Command syntax:\n");
printf(" %s setled <x> <y> <brightness>\n\n", argv[0]);
printf(" setall Set all LEDs at once. Command syntax:\n");
printf(" %s setall <brightness>\n\n", argv[0]);
printf(" pulseled Pulse a single LED. Command syntax:\n");
printf(" %s pulseled <x> <y> <ramp-up-time> "
"<ramp-up-modifier> <lit-time> "
"<ramp-dn-time> <ramp-dn-modifier> "
"<off-time> \n", argv[0]);
printf(" All time values in ms. The modifier"
" will stretch the first and shorten the"
" last iterations of ram-up.\n\n");
printf(" pulseall Pulse all LEDs. Command syntax:\n");
printf(" %s pulseall <ramp-up-time> "
"<ramp-up-modifier> <lit-time> "
"<ramp-dn-time> <ramp-dn-modifier> "
"<off-time>\n", argv[0]);
printf(" All time values in ms. The modifier"
" will stretch the first and shorten the"
" last iterations of ram-up.\n\n");
}
/* --- */
int main(int argc, char ** argv)
{
struct termios oldtio;
int tty_fd;
struct lolret ret;
int err = 0;
if ( argc < 2 ) {
usage(argv);
return 0;
}
tty_fd = setup_serial( &oldtio );
if ( 0 == strcmp(argv[1], "setled" ) )
err = do_setled(tty_fd, argc - 2, argv + 2);
else if ( 0 == strcmp(argv[1], "setall" ) )
err = do_setall(tty_fd, argc - 2, argv + 2);
else if ( 0 == strcmp(argv[1], "pulseall" ) )
err = do_pulseall(tty_fd, argc - 2, argv + 2);
else if ( 0 == strcmp(argv[1], "pulseled" ) )
err = do_pulseled(tty_fd, argc - 2, argv + 2);
else {
printf("Unknown command %s. Run %s (without arguments) to get help.\n",
argv[1], argv[0]);
err=1;
}
if (err) {
printf("Execution of %s failed.\n\n", argv[1]);
usage(argv);
} else {
read( tty_fd, &ret, sizeof( ret ) );
}
close_serial( tty_fd, &oldtio );
return err ? err : ret.ret;
}
-102
View File
@@ -1,102 +0,0 @@
/*
The LoLComm LED communication library.
Written by Thilo Fromm <kontakt@thilo-fromm.de>.
This library enables you to set LEDs on the LoLShield
via a serial connection.
Writen for the LoL Shield, designed by Jimmie Rodgers:
http://jimmieprodgers.com/kits/lolshield/
This is free software; you can redistribute it and/or
modify it under the terms of the GNU Version 3 General Public
License as published by the Free Software Foundation;
or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "Charliplexing.h"
#include "lolproto.h"
#include "lolcommand_funcs.h"
void setup()
{
LedSign::Init(DOUBLE_BUFFER | GRAYSCALE);
Serial.begin(115200); // 8N1
}
/* --- */
static void read_bytes(uint8_t * buf, uint8_t len)
{
uint8_t read = 0;
while ( read < len ) {
int ret = Serial.read();
if ( 0 > ret )
continue;
buf[read] = (uint8_t) ret;
read++;
}
}
/* --- */
void loop()
{
uint8_t command, oldcmd=0, payload[64];
struct lolret response;
read_bytes( &command, sizeof(command) );
response.cmd = command;
if (command != oldcmd) {
LedSign::Clear();
LedSign::Flip(true);
}
switch ( command ) {
case cmd_setall:
read_bytes( payload, sizeof( struct cmd_setall_payload ) );
response.ret = handle_setall(
(struct cmd_setall_payload *) payload);
break;
case cmd_setled:
read_bytes( payload, sizeof( struct cmd_setled_payload ) );
response.ret = handle_setled(
(struct cmd_setled_payload *) payload);
break;
case cmd_pulseall:
read_bytes( payload, sizeof( struct cmd_pulseall_payload ) );
response.ret = handle_pulseall(
(struct cmd_pulseall_payload *) payload);
break;
case cmd_pulseled:
read_bytes( payload, sizeof( struct cmd_pulseled_payload ) );
response.ret = handle_pulseled(
(struct cmd_pulseled_payload *) payload);
break;
case cmd_full_frame:
read_bytes( payload, sizeof( payload ) );
response.ret = handle_full_frame( payload );
break;
default:
response.ret = ret_wtf;
break;
}
Serial.write((uint8_t *) &response, sizeof(response));
}
/* --- */
-55
View File
@@ -1,55 +0,0 @@
/*
The LoLComm LED communication library command definitions.
Written by Thilo Fromm <kontakt@thilo-fromm.de>.
Writen for the lolcomm app, which was written for the
LoL Shield, designed by Jimmie Rodgers:
http://jimmieprodgers.com/kits/lolshield/
This is free software; you can redistribute it and/or
modify it under the terms of the GNU Version 3 General Public
License as published by the Free Software Foundation;
or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <inttypes.h>
#include "lolproto.h"
#ifndef __lolcommands_h__
#define __lolcommands_h__
#ifdef __cplusplus
extern "C" {
#endif
uint8_t handle_setall( struct cmd_setall_payload * pld );
uint8_t handle_setled( struct cmd_setled_payload * pld );
uint8_t handle_pulseall( struct cmd_pulseall_payload * pld );
uint8_t handle_pulseled( struct cmd_pulseled_payload * pld );
uint8_t handle_full_frame( uint8_t data[64] );
/*
* Ideas section for more commands:
* - draw line
* - draw rect (line brightness, fill brightness, maybe even pulse line, pulse fill)
*/
#ifdef __cplusplus
}
#endif
#endif // #ifndef __lolcommands_h__
-125
View File
@@ -1,125 +0,0 @@
/*
The LoLComm LED communication library command implementations.
Written by Thilo Fromm <kontakt@thilo-fromm.de>.
Writen for the lolcomm app, which was written for the
LoL Shield, designed by Jimmie Rodgers:
http://jimmieprodgers.com/kits/lolshield/
This is free software; you can redistribute it and/or
modify it under the terms of the GNU Version 3 General Public
License as published by the Free Software Foundation;
or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <math.h>
#include "Charliplexing.h"
#include "lolproto.h"
#include "lolcommand_funcs.h"
/* lol-level-implementation (bwwee-hee-hee) of lolcomm commands. */
uint8_t handle_setall( struct cmd_setall_payload * pld )
{
LedSign::Clear(pld->brightness);
LedSign::Flip(true);
return ret_ack;
}
/* --- */
uint8_t handle_setled( struct cmd_setled_payload * pld )
{
LedSign::Set( pld->coord.x, pld->coord.y, pld->brightness );
LedSign::Flip(true);
return ret_nack;
}
/* --- */
uint8_t handle_pulseall( struct cmd_pulseall_payload * pld )
{
unsigned int ramp_up = pow( pld->ramp_up_time_ms_pow2, 2) ;
unsigned int ramp_dn = pow( pld->ramp_dn_time_ms_pow2, 2) ;
unsigned int lit_time = pow( pld->lit_time_ms_pow2, 2) ;
unsigned int off_time = pow( pld->off_time_ms_pow2, 2) ;
/* ramp-up */
for (int8_t i=0; i <= SHADES; i++) {
uint8_t sleep = ramp_up / SHADES
+ ( SHADES / 2 - i )
* ( ramp_up / (SHADES * pld->ramp_up_modifier ) );
LedSign::Clear(i);
LedSign::Flip(true);
delay( sleep );
}
delay( lit_time );
// exhale
for (int8_t i=SHADES; i >= 0; i--) {
uint8_t sleep = ramp_dn / SHADES
+ ( SHADES / 2 - i )
* ( ramp_dn / (SHADES * pld->ramp_dn_modifier ) );
LedSign::Clear(i);
LedSign::Flip(true);
delay( sleep );
}
// pause
delay( off_time );
return ret_ack;
}
/* --- */
uint8_t handle_pulseled( struct cmd_pulseled_payload * pld )
{
unsigned int ramp_up = pow( pld->ramp_up_time_ms_pow2, 2) ;
unsigned int ramp_dn = pow( pld->ramp_dn_time_ms_pow2, 2) ;
unsigned int lit_time = pow( pld->lit_time_ms_pow2, 2) ;
unsigned int off_time = pow( pld->off_time_ms_pow2, 2) ;
/* ramp-up */
for (int8_t i=0; i <= SHADES; i++) {
uint8_t sleep = ramp_up / SHADES
+ ( SHADES / 2 - i )
* ( ramp_up / (SHADES * pld->ramp_up_modifier ) );
LedSign::Set(pld->coord.x, pld->coord.y, i);
LedSign::Flip(true);
delay( sleep );
}
delay( lit_time );
// exhale
for (int8_t i=SHADES; i >= 0; i--) {
uint8_t sleep = ramp_dn / SHADES
+ ( SHADES / 2 - i )
* ( ramp_dn / (SHADES * pld->ramp_dn_modifier ) );
LedSign::Set(pld->coord.x, pld->coord.y, i);
LedSign::Flip(true);
delay( sleep );
}
// pause
delay( off_time );
return ret_ack;
}
/* --- */
uint8_t handle_full_frame( uint8_t data[64] )
{
return ret_nack;
}
/* --- */
-141
View File
@@ -1,141 +0,0 @@
/*
The LoLComm LED communication library protocol definitions.
Written by Thilo Fromm <kontakt@thilo-fromm.de>.
Writen for the lolcomm app, which was written for the
LoL Shield, designed by Jimmie Rodgers:
http://jimmieprodgers.com/kits/lolshield/
This is free software; you can redistribute it and/or
modify it under the terms of the GNU Version 3 General Public
License as published by the Free Software Foundation;
or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <inttypes.h>
#ifndef __lolprot_h__
#define __lolprot_h__
#ifdef __cplusplus
extern "C" {
#endif
#define p(x) Serial.print(x)
/*
* LoL Response (return code)
* --------------------------
*
* The lolcresponse is sent from Arduino to the host.
* Is is used to acknowlegde stateful commands via the
* RESULT field.
*/
#define ret_ack 0 // eveything went fine
#define ret_nack 1 // command execution failed
#define ret_wtf 2 // something very strange happened
struct lolret {
uint8_t cmd;
uint8_t ret;
} __attribute__ ((packed));
/*
* LoL Commands
* ------------
*
* LoL commands go from a host system to the Arduino board.
* Commands are used to remote-control a LoLShield.
*
* Command size is a byte.
*/
struct coord {
uint8_t x: 4;
uint8_t y: 4;
} __attribute__ ((packed));
/*
* setall - set all LEDs to a specified brightness.
*/
#define cmd_setall 1
struct cmd_setall_payload {
uint8_t brightness;
uint8_t unused;
} __attribute__ ((packed));
/* --- */
/*
* setled - set one LED to a specified brightness.
*/
#define cmd_setled 2
struct cmd_setled_payload {
struct coord coord;
uint8_t brightness;
} __attribute__ ((packed));
/* --- */
/*
* pulse-all - let the whole screen pulse.
*/
#define cmd_pulseall 3
struct cmd_pulseall_payload {
uint8_t ramp_up_time_ms_pow2;
uint8_t ramp_up_modifier;
uint8_t ramp_dn_time_ms_pow2;
uint8_t ramp_dn_modifier;
uint8_t lit_time_ms_pow2;
uint8_t off_time_ms_pow2;
} __attribute__ ((packed));
/* --- */
/*
* pulse-led - let a single LED pulse.
*/
#define cmd_pulseled 4
struct cmd_pulseled_payload {
struct coord coord;
uint8_t ramp_up_time_ms_pow2;
uint8_t ramp_up_modifier;
uint8_t ramp_dn_time_ms_pow2;
uint8_t ramp_dn_modifier;
uint8_t lit_time_ms_pow2;
uint8_t off_time_ms_pow2;
} __attribute__ ((packed));
/* --- */
#define cmd_full_frame 5
/* 64 bytes of payload; 4 bit brightness value per LED. */
/* --- */
/*
* Ideas section for more commands:
* - draw line, brightness, pulse
* - draw rect, fill, brightness, pulse
* - draw circle, fill, brightness, pulse
*/
#ifdef __cplusplus
}
#endif
#endif // #ifndef __lolprot_h__
Binary file not shown.

Before

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 735 B

-9
View File
@@ -1,9 +0,0 @@
...
.O.
.O.
.O.
.O.
.O.
...
.O.
...
-9
View File
@@ -1,9 +0,0 @@
....
..O.
..O.
.O..
....
....
....
....
....
-9
View File
@@ -1,9 +0,0 @@
....
....
....
....
....
..O.
..O.
.O..
....
-9
View File
@@ -1,9 +0,0 @@
......
.OOO..
O...O.
O...O.
O...O.
O...O.
O...O.
.OOO..
......
-9
View File
@@ -1,9 +0,0 @@
.....
..O..
.OO..
..O..
..O..
..O..
..O..
.OOO.
.....
-9
View File
@@ -1,9 +0,0 @@
......
.OOO..
O...O.
....O.
.OOO..
O.....
O.....
OOOOO.
......
-9
View File
@@ -1,9 +0,0 @@
......
.OOO..
O...O.
....O.
.OOO..
....O.
O...O.
.OOO..
......
-9
View File
@@ -1,9 +0,0 @@
......
...O..
..OO..
.O.O..
O..O..
OOOOO.
...O..
...O..
......
-9
View File
@@ -1,9 +0,0 @@
......
OOOOO.
O.....
O.....
OOOO..
....O.
....O.
OOOO..
......
-9
View File
@@ -1,9 +0,0 @@
......
.OOO..
O...O.
O.....
OOOO..
O...O.
O...O.
.OOO..
......
-9
View File
@@ -1,9 +0,0 @@
......
OOOOO.
....O.
...O..
...O..
..O...
..O...
..O...
......
-9
View File
@@ -1,9 +0,0 @@
......
.OOO..
O...O.
O...O.
.OOO..
O...O.
O...O.
.OOO..
......
-9
View File
@@ -1,9 +0,0 @@
......
.OOO..
O...O.
O...O.
.OOOO.
....O.
....O.
OOOO..
......
-9
View File
@@ -1,9 +0,0 @@
.....
.OO..
O..O.
O..O.
OOOO.
O..O.
O..O.
O..O.
.....
-9
View File
@@ -1,9 +0,0 @@
.....
OOO..
O..O.
O..O.
OOO..
O..O.
O..O.
OOO..
.....
-9
View File
@@ -1,9 +0,0 @@
.....
.OOO.
O....
O....
O....
O....
O....
.OOO.
.....
-9
View File
@@ -1,9 +0,0 @@
.....
OOO..
O..O.
O..O.
O..O.
O..O.
O..O.
OOO..
.....
-9
View File
@@ -1,9 +0,0 @@
.....
OOOO.
O....
O....
OOOO.
O....
O....
OOOO.
.....
-9
View File
@@ -1,9 +0,0 @@
.....
OOOO.
O....
O....
OOOO.
O....
O....
O....
.....
-9
View File
@@ -1,9 +0,0 @@
.....
OOOO.
O..O.
O....
O.OO.
O..O.
O..O.
OOOO.
.....
-9
View File
@@ -1,9 +0,0 @@
.....
O..O.
O..O.
O..O.
OOOO.
O..O.
O..O.
O..O.
.....
-9
View File
@@ -1,9 +0,0 @@
....
OOO.
.O..
.O..
.O..
.O..
.O..
OOO.
....
-9
View File
@@ -1,9 +0,0 @@
.....
.OOO.
..O..
..O..
..O..
..O..
..O..
OO...
.....
-9
View File
@@ -1,9 +0,0 @@
.....
O..O.
O..O.
O.O..
OO...
O.O..
O..O.
O..O.
.....
-9
View File
@@ -1,9 +0,0 @@
.....
O....
O....
O....
O....
O....
O....
OOOO.
.....
-9
View File
@@ -1,9 +0,0 @@
......
O...O.
OO.OO.
O.O.O.
O...O.
O...O.
O...O.
O...O.
......
-9
View File
@@ -1,9 +0,0 @@
......
O...O.
OO..O.
O.O.O.
O..OO.
O...O.
O...O.
O...O.
......
-9
View File
@@ -1,9 +0,0 @@
.....
.OO..
O..O.
O..O.
O..O.
O..O.
O..O.
.OO..
.....
-9
View File
@@ -1,9 +0,0 @@
.....
OOO..
O..O.
O..O.
OOO..
O....
O....
O....
.....
-9
View File
@@ -1,9 +0,0 @@
......
.OOO..
O...O.
O...O.
O...O.
O.O.O.
O..O..
.OO.O.
......
-9
View File
@@ -1,9 +0,0 @@
......
OOOO..
O...O.
O...O.
OOOO..
O.O...
O..O..
O...O.
......
-9
View File
@@ -1,9 +0,0 @@
.....
.OOO.
O....
O....
.OO..
...O.
...O.
OOO..
.....
-9
View File
@@ -1,9 +0,0 @@
....
OOO.
.O..
.O..
.O..
.O..
.O..
.O..
....
-9
View File
@@ -1,9 +0,0 @@
.....
O..O.
O..O.
O..O.
O..O.
O..O.
O..O.
.OO..
.....
-9
View File
@@ -1,9 +0,0 @@
......
O...O.
O...O.
O...O.
O...O.
O...O.
.O.O..
..O...
......
-9
View File
@@ -1,9 +0,0 @@
......
O...O.
O...O.
O...O.
O...O.
O.O.O.
OO.OO.
O...O.
......
-9
View File
@@ -1,9 +0,0 @@
......
O...O.
O...O.
.O.O..
..O...
.O.O..
O...O.
O...O.
......
-9
View File
@@ -1,9 +0,0 @@
......
O...O.
O...O.
.O.O..
..O...
..O...
..O...
..O...
......
-9
View File
@@ -1,9 +0,0 @@
......
OOOOO.
....O.
...O..
..O...
.O....
O.....
OOOOO.
......
-9
View File
@@ -1,9 +0,0 @@
.....
.....
.....
.OO..
...O.
.OOO.
O..O.
OOOO.
.....
-9
View File
@@ -1,9 +0,0 @@
.....
O....
O....
O....
OOO..
O..O.
O..O.
OOO..
.....
-9
View File
@@ -1,9 +0,0 @@
.....
.....
.....
.....
.OOO.
O....
O....
.OOO.
.....
-9
View File
@@ -1,9 +0,0 @@
.....
.OOO.
O..O.
O..O.
.OOO.
...O.
...O.
.OO..
.....
-9
View File
@@ -1,9 +0,0 @@
.....
.....
.....
.OO..
O..O.
OOOO.
O....
.OOO.
.....
-9
View File
@@ -1,9 +0,0 @@
.....
.OOO.
.O...
.O...
.O...
OOO..
.O...
.O...
.....
-50
View File
@@ -1,50 +0,0 @@
<?php
$d=opendir(".");
$vstar=array();
$vmin=128;
$vmax=0;
while (($c=readdir($d))!==false) {
if (substr($c,0,1)!="." && strlen($c)==1) {
$letters[$c]=explode("\n",file_get_contents($c));
$ct=0;
echo "uint8_t letters_".ord($c)."[] = { ";
$o=ord($c);
if ($o<$vmin) $vmin=$o;
if ($o>$vmax) $vmax=$o;
$vstar[$o] = 1;
for($j=0;$j<=5;$j++) {
for($k=0;$k<=8;$k++) {
if (substr($letters[$c][$k],$j,1)=="O") {
echo "".$j.",".$k.", ";
$ct++;
}
}
}
echo "9,9";
echo " };\n";
}
} // while
closedir($d);
echo "\n";
$already=false;
echo "void * font[] = { ";
for($i=$vmin;$i<=$vmax;$i++) {
if ($already) echo ", ";
if ($vstar[$i]) {
echo " &letters_".$i." /*".chr($i)."*/";
} else {
echo " 0";
}
$already=true;
}
echo "\n};\n\n";
echo "uint8_t fontMin=$vmin;\n";
echo "uint8_t fontMax=$vmax;\n";
-9
View File
@@ -1,9 +0,0 @@
.....
.....
.OOO.
O..O.
O..O.
.OOO.
...O.
...O.
OOO..
-9
View File
@@ -1,9 +0,0 @@
.....
O....
O....
O....
OOO..
O..O.
O..O.
O..O.
.....
-9
View File
@@ -1,9 +0,0 @@
....
OOO.
.O..
.O..
.O..
.O..
.O..
OOO.
....
-9
View File
@@ -1,9 +0,0 @@
.....
.OOO.
..O..
..O..
..O..
..O..
..O..
OO...
.....
-9
View File
@@ -1,9 +0,0 @@
.....
O....
O....
O..O.
O.O..
OO...
O.O..
O..O.
.....
-9
View File
@@ -1,9 +0,0 @@
.....
O....
O....
O....
O....
O....
O....
OOOO.
.....
-9
View File
@@ -1,9 +0,0 @@
......
......
......
......
OO.O..
O.O.O.
O.O.O.
O.O.O.
......
-9
View File
@@ -1,9 +0,0 @@
......
O...O.
OO..O.
O.O.O.
O..OO.
O...O.
O...O.
O...O.
......
-9
View File
@@ -1,9 +0,0 @@
.....
.....
.....
.....
.OO..
O..O.
O..O.
.OO..
.....
-9
View File
@@ -1,9 +0,0 @@
.....
OOO..
O..O.
O..O.
OOO..
O....
O....
O....
.....
-9
View File
@@ -1,9 +0,0 @@
......
.OOO..
O...O.
O...O.
O...O.
O.O.O.
O..O..
.OO.O.
......
-9
View File
@@ -1,9 +0,0 @@
......
OOOO..
O...O.
O...O.
OOOO..
O.O...
O..O..
O...O.
......
-9
View File
@@ -1,9 +0,0 @@
.....
.....
.....
OOOO.
O....
.OOO.
...O.
OOOO.
.....

Some files were not shown because too many files have changed in this diff Show More