diff options
author | Alexander Kauerz <kauerz@informatik.uni-luebeck.de> | 2012-02-09 22:59:58 +0100 |
---|---|---|
committer | Alexander Kauerz <kauerz@informatik.uni-luebeck.de> | 2012-02-09 22:59:58 +0100 |
commit | fbea3ae42daade09ad42fe9ae9ca542f77b96c20 (patch) | |
tree | 4d2162027b1bac7830569d5f8efd9813f3497902 /Matrix_9x14/libraries/Charliplexing | |
parent | 8f428f51b4b62d1f07c88cace7bb127e436271a5 (diff) | |
download | ledmatrix-fbea3ae42daade09ad42fe9ae9ca542f77b96c20.tar ledmatrix-fbea3ae42daade09ad42fe9ae9ca542f77b96c20.zip |
lolshield-matrix hinzu
Diffstat (limited to 'Matrix_9x14/libraries/Charliplexing')
15 files changed, 2254 insertions, 0 deletions
diff --git a/Matrix_9x14/libraries/Charliplexing/.svn/all-wcprops b/Matrix_9x14/libraries/Charliplexing/.svn/all-wcprops new file mode 100644 index 0000000..e64fbe9 --- /dev/null +++ b/Matrix_9x14/libraries/Charliplexing/.svn/all-wcprops @@ -0,0 +1,47 @@ +K 25 +svn:wc:ra_dav:version-url +V 26 +/svn/!svn/ver/24/trunk/lib +END +Charliplexing.h +K 25 +svn:wc:ra_dav:version-url +V 42 +/svn/!svn/ver/23/trunk/lib/Charliplexing.h +END +Figure.cpp +K 25 +svn:wc:ra_dav:version-url +V 37 +/svn/!svn/ver/20/trunk/lib/Figure.cpp +END +keywords.txt +K 25 +svn:wc:ra_dav:version-url +V 38 +/svn/!svn/ver/6/trunk/lib/keywords.txt +END +Figure.h +K 25 +svn:wc:ra_dav:version-url +V 34 +/svn/!svn/ver/2/trunk/lib/Figure.h +END +Font.cpp +K 25 +svn:wc:ra_dav:version-url +V 34 +/svn/!svn/ver/7/trunk/lib/Font.cpp +END +Charliplexing.cpp +K 25 +svn:wc:ra_dav:version-url +V 44 +/svn/!svn/ver/23/trunk/lib/Charliplexing.cpp +END +Font.h +K 25 +svn:wc:ra_dav:version-url +V 32 +/svn/!svn/ver/7/trunk/lib/Font.h +END diff --git a/Matrix_9x14/libraries/Charliplexing/.svn/entries b/Matrix_9x14/libraries/Charliplexing/.svn/entries new file mode 100644 index 0000000..470af9f --- /dev/null +++ b/Matrix_9x14/libraries/Charliplexing/.svn/entries @@ -0,0 +1,269 @@ +10 + +dir +26 +http://lolshield.googlecode.com/svn/trunk/lib +http://lolshield.googlecode.com/svn + + + +2012-01-13T17:54:37.624437Z +24 +thilo.alexander@gmail.com + + + + + + + + + + + + + + +a9283160-f6ed-11de-885d-7376d8f76b83 + +Charliplexing.h +file + + + + +2012-02-09T20:19:37.528308Z +5cd52a3fe91e62b285b19574f0d9be0e +2012-01-07T22:37:32.348571Z +23 +thilo.alexander@gmail.com + + + + + + + + + + + + + + + + + + + + + +979 + +Figure.cpp +file + + + + +2012-02-09T20:19:37.528308Z +c4b4529e0fd718132e2e7fea79305d5d +2012-01-07T07:24:41.729156Z +20 +thilo.alexander@gmail.com + + + + + + + + + + + + + + + + + + + + + +4422 + +keywords.txt +file + + + + +2012-02-09T20:19:37.532308Z +4bed9c76c30b8f7d93feb19bd7aae30e +2010-05-28T07:21:20.858041Z +6 +matt.mets@gmail.com + + + + + + + + + + + + + + + + + + + + + +219 + +Figure.h +file + + + + +2012-02-09T20:19:37.532308Z +157c938fc59e7d5e34fd5ae27527ccad +2010-01-07T16:19:43.833624Z +2 +BenjaminSonntag + + + + + + + + + + + + + + + + + + + + + +1171 + +Font.cpp +file + + + + +2012-02-09T20:19:37.532308Z +d23679dd846a915028f30b8f6b08e465 +2010-07-19T06:45:40.102535Z +7 +matt.mets@gmail.com + + + + + + + + + + + + + + + + + + + + + +11343 + +Charliplexing.cpp +file + + + + +2012-02-09T20:19:37.536308Z +dd9e42d06689a07a57ef2517b96cfa35 +2012-01-07T22:37:32.348571Z +23 +thilo.alexander@gmail.com + + + + + + + + + + + + + + + + + + + + + +15883 + +Font.h +file + + + + +2012-02-09T20:19:37.536308Z +863d12dac57c9c0562b87b43b1e0090a +2010-07-19T06:45:40.102535Z +7 +matt.mets@gmail.com + + + + + + + + + + + + + + + + + + + + + +1131 + +examples +dir + diff --git a/Matrix_9x14/libraries/Charliplexing/.svn/text-base/Charliplexing.cpp.svn-base b/Matrix_9x14/libraries/Charliplexing/.svn/text-base/Charliplexing.cpp.svn-base new file mode 100644 index 0000000..d68b209 --- /dev/null +++ b/Matrix_9x14/libraries/Charliplexing/.svn/text-base/Charliplexing.cpp.svn-base @@ -0,0 +1,502 @@ +/* + 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 "Charliplexing.h" + +volatile unsigned int LedSign::tcnt2; + + +struct videoPage { + uint8_t pixels[SHADES][48]; // TODO: is 48 right? +}; + +/* ----------------------------------------------------------------- */ +/** Table for the LED multiplexing cycles + * Each frame is made of 24 bytes (for the 24 display cycles) + * There are SHADES frames per buffer in grayscale mode (one for each brigtness) + * and twice that many to support double-buffered grayscale. + */ +videoPage leds[2]; + +/// Determines whether the display is in single or double buffer mode +uint8_t displayMode = SINGLE_BUFFER; + +/// Flag indicating that the display page should be flipped as soon as the +/// current frame is displayed +volatile boolean videoFlipPage = false; + +/// Pointer to the buffer that is currently being displayed +videoPage* displayBuffer; + +/// Pointer to the buffer that should currently be drawn to +videoPage* workBuffer; + +/// Flag indicating that the timer buffer should be flipped as soon as the +/// current frame is displayed +volatile boolean videoFlipTimer = false; + + +// Timer counts to display each page for, plus off time +typedef struct timerInfo { + uint8_t counts[SHADES]; + uint8_t prescaler[SHADES]; +}; + +// Double buffer the timing information, of course. +timerInfo* frontTimer; +timerInfo* backTimer; + +timerInfo* tempTimer; + +timerInfo timer[2]; + +// Record a slow and fast prescaler for later use +typedef struct prescalerInfo { + uint8_t relativeSpeed; + uint8_t TCCR2; +}; + +// TODO: Generate these based on processor type and clock speed +prescalerInfo slowPrescaler = {1, 0x03}; +//prescalerInfo fastPrescaler = {32, 0x01}; +prescalerInfo fastPrescaler = {4, 0x02}; + +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 +#define MEASURE_ISR_TIME +#ifdef MEASURE_ISR_TIME +uint8_t statusPIN = 19; +#endif + +typedef struct LEDPosition { + uint8_t high; + uint8_t low; +}; + + +/* ----------------------------------------------------------------- */ +/** Table for LED Position in leds[] ram table + */ + +const LEDPosition ledMap[126] = { + {13, 5}, {13, 6}, {13, 7}, {13, 8}, {13, 9}, {13,10}, {13,11}, {13,12}, + {13, 4}, { 4,13}, {13, 3}, { 3,13}, {13, 2}, { 2,13}, + {12, 5}, {12, 6}, {12, 7}, {12, 8}, {12, 9}, {12,10}, {12,11}, {12,13}, + {12, 4}, { 4,12}, {12, 3}, { 3,12}, {12, 2}, { 2,12}, + {11, 5}, {11, 6}, {11, 7}, {11, 8}, {11, 9}, {11,10}, {11,12}, {11,13}, + {11, 4}, { 4,11}, {11, 3}, { 3,11}, {11, 2}, { 2,11}, + {10, 5}, {10, 6}, {10, 7}, {10, 8}, {10, 9}, {10,11}, {10,12}, {10,13}, + {10, 4}, { 4,10}, {10, 3}, { 3,10}, {10, 2}, { 2,10}, + { 9, 5}, { 9, 6}, { 9, 7}, { 9, 8}, { 9,10}, { 9,11}, { 9,12}, { 9,13}, + { 9, 4}, { 4, 9}, { 9, 3}, { 3, 9}, { 9, 2}, { 2, 9}, + { 8, 5}, { 8, 6}, { 8, 7}, { 8, 9}, { 8,10}, { 8,11}, { 8,12}, { 8,13}, + { 8, 4}, { 4, 8}, { 8, 3}, { 3, 8}, { 8, 2}, { 2, 8}, + { 7, 5}, { 7, 6}, { 7, 8}, { 7, 9}, { 7,10}, { 7,11}, { 7,12}, { 7,13}, + { 7, 4}, { 4, 7}, { 7, 3}, { 3, 7}, { 7, 2}, { 2, 7}, + { 6, 5}, { 6, 7}, { 6, 8}, { 6, 9}, { 6,10}, { 6,11}, { 6,12}, { 6,13}, + { 6, 4}, { 4, 6}, { 6, 3}, { 3, 6}, { 6, 2}, { 2, 6}, + { 5, 6}, { 5, 7}, { 5, 8}, { 5, 9}, { 5,10}, { 5,11}, { 5,12}, { 5,13}, + { 5, 4}, { 4, 5}, { 5, 3}, { 3, 5}, { 5, 2}, { 2, 5}, +}; + + +/* ----------------------------------------------------------------- */ +/** 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 + + float prescaler = 0.0; + +#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || (__AVR_ATmega1280__) + TIMSK2 &= ~(1<<TOIE2); + TCCR2A &= ~((1<<WGM21) | (1<<WGM20)); + TCCR2B &= ~(1<<WGM22); + ASSR &= ~(1<<AS2); + TIMSK2 &= ~(1<<OCIE2A); + + if ((F_CPU >= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64 + TCCR2B |= ((1<<CS21) | (1<<CS20)); + TCCR2B &= ~(1<<CS22); + prescaler = 32.0; + } else if (F_CPU < 1000000UL) { // prescaler set to 8 + TCCR2B |= (1<<CS21); + TCCR2B &= ~((1<<CS22) | (1<<CS20)); + prescaler = 8.0; + } else { // F_CPU > 16Mhz, prescaler set to 128 + TCCR2B |= (1<<CS22); + TCCR2B &= ~((1<<CS21) | (1<<CS20)); + prescaler = 64.0; + } +#elif defined (__AVR_ATmega8__) + TIMSK &= ~(1<<TOIE2); + TCCR2 &= ~((1<<WGM21) | (1<<WGM20)); + TIMSK &= ~(1<<OCIE2); + ASSR &= ~(1<<AS2); + + if ((F_CPU >= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64 + TCCR2 |= (1<<CS22); + TCCR2 &= ~((1<<CS21) | (1<<CS20)); + prescaler = 64.0; + } else if (F_CPU < 1000000UL) { // prescaler set to 8 + TCCR2 |= (1<<CS21); + TCCR2 &= ~((1<<CS22) | (1<<CS20)); + prescaler = 8.0; + } else { // F_CPU > 16Mhz, prescaler set to 128 + TCCR2 |= ((1<<CS22) && (1<<CS20)); + TCCR2 &= ~(1<<CS21); + prescaler = 128.0; + } +#elif defined (__AVR_ATmega128__) + TIMSK &= ~(1<<TOIE2); + TCCR2 &= ~((1<<WGM21) | (1<<WGM20)); + TIMSK &= ~(1<<OCIE2); + + if ((F_CPU >= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64 + TCCR2 |= ((1<<CS21) | (1<<CS20)); + TCCR2 &= ~(1<<CS22); + prescaler = 64.0; + } else if (F_CPU < 1000000UL) { // prescaler set to 8 + TCCR2 |= (1<<CS21); + TCCR2 &= ~((1<<CS22) | (1<<CS20)); + prescaler = 8.0; + } else { // F_CPU > 16Mhz, prescaler set to 256 + TCCR2 |= (1<<CS22); + TCCR2 &= ~((1<<CS21) | (1<<CS20)); + prescaler = 256.0; + } +#endif + + tcnt2 = 256 - (int)((float)F_CPU * 0.0005 / prescaler); + + // Record whether we are in single or double buffer mode + displayMode = mode; + videoFlipPage = false; + + // Point the display buffer to the first physical buffer + displayBuffer = &leds[0]; + + // 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 = displayBuffer; + } + + // Set up the timer buffering + frontTimer = &timer[0]; + backTimer = &timer[1]; + + videoFlipTimer = false; + SetBrightness(127); + + // Clear the buffer and display it + LedSign::Clear(0); + LedSign::Flip(false); + + // Then start the display + TCNT2 = tcnt2; +#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || (__AVR_ATmega1280__) + TIMSK2 |= (1<<TOIE2); +#elif defined (__AVR_ATmega128__) || defined (__AVR_ATmega8__) + TIMSK |= (1<<TOIE2); +#endif + + // If we are in double-buffer mode, wait until the display flips before we + // return + if (displayMode & DOUBLE_BUFFER) + { + while (videoFlipPage) { + delay(1); + } + } + + initialized = true; +} + + +/* ----------------------------------------------------------------- */ +/** 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) +{ + if (displayMode & DOUBLE_BUFFER) + { + // Just set the flip flag, the buffer will flip between redraws + videoFlipPage = true; + + // If we are blocking, sit here until the page flips. + while (blocking && videoFlipPage) { + delay(1); + } + } +} + + +/* ----------------------------------------------------------------- */ +/** Clear the screen completely + * @param set if 1 : make all led ON, if not set or 0 : make all led OFF + */ +void LedSign::Clear(int set) { + for(int x=0;x<14;x++) + for(int y=0;y<9;y++) + Set(x,y,set); +} + + +/* ----------------------------------------------------------------- */ +/** 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(int y, int set) { + for(int x=0;x<14;x++) + Set(x,y,set); +} + + +/* ----------------------------------------------------------------- */ +/** 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(int x, int set) { + for(int y=0;y<9;y++) + Set(x,y,set); +} + + +/* ----------------------------------------------------------------- */ +/** 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) +{ + uint8_t pin_high = ledMap[x+y*14].high; + uint8_t pin_low = ledMap[x+y*14].low; + // pin_low is directly the address in the led array (minus 2 because the + // first two bytes are used for RS232 communication), but + // as it is a two byte array we need to check pin_high also. + // If pin_high is bigger than 8 address has to be increased by one + + uint8_t bufferNum = (pin_low-2)*2 + (pin_high / 8) + ((pin_high > 7)?24:0); + uint8_t work = _BV(pin_high & 0x07); + + // If we aren't in grayscale mode, just map any pin brightness to max + if (c > 0 && !(displayMode & GRAYSCALE)) { + c = SHADES-1; + } + + for (int i = 0; i < SHADES-1; i++) { + if( c > i ) { + workBuffer->pixels[i][bufferNum] |= work; // ON + } + else { + workBuffer->pixels[i][bufferNum] &= ~work; // OFF + } + } +} + + +/* 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 + float brightnessPercent = ((float)brightness / 127)*((float)brightness / 127); + uint8_t difference = 0; + + /* ---- This needs review! Please review. -- thilo */ + // set up page counts + // TODO: make SHADES a function parameter. This would require some refactoring. + int start = 15; + int max = 255; + float scale = 1.5; + float delta = pow( max - start , 1.0 / scale) / (SHADES - 1); + uint8_t pageCounts[SHADES]; + + pageCounts[0] = max - start; + for (uint8_t i=1; i<SHADES; i++) { + pageCounts[i] = max - ( pow( i * delta, scale ) + start ); + } + Serial.end(); + + if (! initialized) { + // set front timer defaults + for (int i = 0; i < SHADES; i++) { + frontTimer->counts[i] = pageCounts[i]; + // TODO: Generate this dynamically + frontTimer->prescaler[i] = slowPrescaler.TCCR2; + } + } + + // Wait until the previous brightness request goes through + while( videoFlipTimer ) { + delay(1); + } + + // Compute on time for each of the pages + // Use the fast timer; slow timer is only useful for < 3 shades. + for (uint8_t i = 0; i < SHADES - 1; i++) { + uint8_t interval = 255 - pageCounts[i]; + + backTimer->counts[i] = 255 - brightnessPercent + * interval + * fastPrescaler.relativeSpeed; + backTimer->prescaler[i] = fastPrescaler.TCCR2; + difference += backTimer->counts[i] - pageCounts[i]; + } + + // Compute off time + backTimer->counts[SHADES - 1] = 255 - difference; + backTimer->prescaler[SHADES - 1] = slowPrescaler.TCCR2; + + /* ---- End of "This needs review! Please review." -- thilo */ + + // Have the ISR update the timer registers next run + videoFlipTimer = true; +} + + +/* ----------------------------------------------------------------- */ +/** The Interrupt code goes here ! + */ +ISR(TIMER2_OVF_vect) { + DDRD = 0x0; + DDRB = 0x0; +#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; + + TCCR2B = frontTimer->prescaler[page]; + TCNT2 = frontTimer->counts[page]; + + if ( page < SHADES - 1) { + + if (cycle < 6) { + DDRD = _BV(cycle+2) | displayBuffer->pixels[page][cycle*2]; + PORTD = displayBuffer->pixels[page][cycle*2]; + + DDRB = displayBuffer->pixels[page][cycle*2+1]; + PORTB = displayBuffer->pixels[page][cycle*2+1]; + } else if (cycle < 12) { + DDRD = displayBuffer->pixels[page][cycle*2]; + PORTD = displayBuffer->pixels[page][cycle*2]; + + DDRB = _BV(cycle-6) | displayBuffer->pixels[page][cycle*2+1]; + PORTB = displayBuffer->pixels[page][cycle*2+1]; + } else if (cycle < 18) { + DDRD = _BV(cycle+2-12) | displayBuffer->pixels[page][cycle*2]; + PORTD = displayBuffer->pixels[page][cycle*2]; + + DDRB = displayBuffer->pixels[page][cycle*2+1]; + PORTB = displayBuffer->pixels[page][cycle*2+1]; + } else { + DDRD = displayBuffer->pixels[page][cycle*2]; + PORTD = displayBuffer->pixels[page][cycle*2]; + + DDRB = _BV(cycle-6-12) | displayBuffer->pixels[page][cycle*2+1]; + PORTB = displayBuffer->pixels[page][cycle*2+1]; + } + } + else { + // Turn everything off + DDRD = 0x0; + DDRB = 0x0; + } + + page++; + + if (page >= SHADES) { + page = 0; + cycle++; + } + + if (cycle > 24) { + cycle = 0; + + // If the page should be flipped, do it here. + if (videoFlipPage && (displayMode & DOUBLE_BUFFER)) + { + // TODO: is this an atomic operation? + videoFlipPage = false; + + videoPage* temp = displayBuffer; + displayBuffer = workBuffer; + workBuffer = temp; + } + + if (videoFlipTimer) { + videoFlipTimer = false; + + tempTimer = frontTimer; + frontTimer = backTimer; + backTimer = tempTimer; + } + } + +#ifdef MEASURE_ISR_TIME + digitalWrite(statusPIN, LOW); +#endif +} diff --git a/Matrix_9x14/libraries/Charliplexing/.svn/text-base/Charliplexing.h.svn-base b/Matrix_9x14/libraries/Charliplexing/.svn/text-base/Charliplexing.h.svn-base new file mode 100644 index 0000000..6054dc4 --- /dev/null +++ b/Matrix_9x14/libraries/Charliplexing/.svn/text-base/Charliplexing.h.svn-base @@ -0,0 +1,34 @@ +/* + 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 +#define GRAYSCALE 2 + +#define DISPLAY_COLS 14 // Number of columns in the display +#define DISPLAY_ROWS 9 // Number of rows in the display +#define SHADES 8 // Number of distinct shades to display, including black, i.e. OFF + +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); + extern volatile unsigned int tcnt2; + extern void Flip(bool blocking = false); + extern void Clear(int set=0); + extern void Horizontal(int y, int set=0); + extern void Vertical(int x, int set=0); +}; + +#endif diff --git a/Matrix_9x14/libraries/Charliplexing/.svn/text-base/Figure.cpp.svn-base b/Matrix_9x14/libraries/Charliplexing/.svn/text-base/Figure.cpp.svn-base new file mode 100644 index 0000000..1b8c9db --- /dev/null +++ b/Matrix_9x14/libraries/Charliplexing/.svn/text-base/Figure.cpp.svn-base @@ -0,0 +1,125 @@ +/* + 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 "Charliplexing.h" +#include "Figure.h" + +#if defined(ARDUINO) && ARDUINO >= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif +#include <inttypes.h> + + +uint8_t figuresData[][14][2] = { +{ {0,0}, {1,0}, {2,0}, {0,1}, {2,1}, {0,2}, {2,2}, {0,3}, {2,3}, {0,4}, {1,4}, {2,4}, {9,9}, {9,9} }, +{ {1,0}, {0,1}, {1,1}, {1,2}, {1,3}, {0,4}, {1,4}, {2,4}, {9,9}, {9,9}, {9,9}, {9,9}, {9,9}, {9,9} }, +{ {0,0}, {1,0}, {2,0}, {2,1}, {1,2}, {0,3}, {0,4}, {1,4}, {2,4}, {9,9}, {9,9}, {9,9}, {9,9}, {9,9} }, +{ {0,0}, {1,0}, {2,0}, {2,1}, {0,2}, {1,2}, {2,3}, {0,4}, {1,4}, {2,4}, {9,9}, {9,9}, {9,9}, {9,9} }, +{ {0,0}, {2,0}, {0,1}, {2,1}, {0,2}, {1,2}, {2,2}, {2,3}, {2,4}, {9,9}, {9,9}, {9,9}, {9,9}, {9,9} }, +{ {0,0}, {1,0}, {2,0}, {0,1}, {0,2}, {1,2}, {2,2}, {2,3}, {0,4}, {1,4}, {2,4}, {9,9}, {9,9}, {9,9} }, +{ {0,0}, {1,0}, {2,0}, {0,1}, {0,2}, {1,2}, {2,2}, {0,3}, {2,3}, {0,4}, {1,4}, {2,4}, {9,9}, {9,9} }, +{ {0,0}, {1,0}, {2,0}, {2,1}, {2,2}, {1,3}, {1,4}, {9,9}, {9,9}, {9,9}, {9,9}, {9,9}, {9,9}, {9,9} }, +{ {0,0}, {1,0}, {2,0}, {0,1}, {2,1}, {0,2}, {1,2}, {2,2}, {0,3}, {2,3}, {0,4}, {1,4}, {2,4}, {9,9} }, +{ {0,0}, {1,0}, {2,0}, {0,1}, {2,1}, {0,2}, {1,2}, {2,2}, {2,3}, {0,4}, {1,4}, {9,9}, {9,9}, {9,9} } +}; + + +/* ----------------------------------------------------------------- */ +/** 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(int figure,int x,int y,int set) { + for(int i=0;i<14;i++) { + if (figuresData[figure][i][0]==9) break; + if ( + figuresData[figure][i][0]+x<13 && + figuresData[figure][i][0]+x>=0 && + figuresData[figure][i][1]+y<8 && + figuresData[figure][i][1]+y>=0 + ) { + LedSign::Set(figuresData[figure][i][0]+x,figuresData[figure][i][1]+y,set); + } + } +} + + +/* ----------------------------------------------------------------- */ +/** 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(int figure,int x,int y,int set) { + for(int i=0;i<14;i++) { + if (figuresData[figure][i][0]==9) break; + if ( + (5-figuresData[figure][i][1])+x<13 && + (5-figuresData[figure][i][1])+x>=0 && + figuresData[figure][i][0]+y<8 && + figuresData[figure][i][0]+y>=0 + ) { + LedSign::Set((5-figuresData[figure][i][1])+x,figuresData[figure][i][0]+y,set); + } + } +} + + +/* ----------------------------------------------------------------- */ +/** 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) { + int i,j,k; + uint8_t figures[]={ + (value%10000000)/1000000, + (value%1000000)/100000, + (value%100000)/10000, + (value%10000)/1000, + (value%1000)/100, + (value%100)/10, + (value%10) + }; + j=0; + while (figures[j]==0 && j<6) j++; + + for(i=0;i<9+(7-j)*5;i++) { + for(k=j;k<=6;k++) + Figure::Draw90(figures[k],3,-i+9+4*(k-j) ,1); + delay(100); + for(k=j;k<=6;k++) + Figure::Draw90(figures[k],3,-i+9+4*(k-j) ,0); + } +} + + diff --git a/Matrix_9x14/libraries/Charliplexing/.svn/text-base/Figure.h.svn-base b/Matrix_9x14/libraries/Charliplexing/.svn/text-base/Figure.h.svn-base new file mode 100644 index 0000000..1b3f1fe --- /dev/null +++ b/Matrix_9x14/libraries/Charliplexing/.svn/text-base/Figure.h.svn-base @@ -0,0 +1,42 @@ +/* + 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(int figure,int x,int y,int set=1); + +extern void Draw90(int figure,int x,int y,int set=1); + +extern void Scroll90(unsigned long value,uint8_t x=3); + +} + +#endif + diff --git a/Matrix_9x14/libraries/Charliplexing/.svn/text-base/Font.cpp.svn-base b/Matrix_9x14/libraries/Charliplexing/.svn/text-base/Font.cpp.svn-base new file mode 100644 index 0000000..441e29c --- /dev/null +++ b/Matrix_9x14/libraries/Charliplexing/.svn/text-base/Font.cpp.svn-base @@ -0,0 +1,219 @@ +#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> + +prog_uchar letters_71[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,1, 1,7, 2,1, 2,4, 2,7, 3,1, 3,2, 3,4, 3,5, 3,6, 3,7, 9,9 }; +prog_uchar letters_83[] PROGMEM = { 0,2, 0,3, 0,7, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,1, 3,5, 3,6, 9,9 }; +prog_uchar letters_67[] PROGMEM = { 0,2, 0,3, 0,4, 0,5, 0,6, 1,1, 1,7, 2,1, 2,7, 3,1, 3,7, 9,9 }; +prog_uchar letters_76[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,7, 2,7, 3,7, 9,9 }; +prog_uchar letters_89[] PROGMEM = { 0,1, 0,2, 1,3, 2,4, 2,5, 2,6, 2,7, 3,3, 4,1, 4,2, 9,9 }; +prog_uchar letters_82[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,1, 1,4, 2,1, 2,4, 2,5, 3,1, 3,4, 3,6, 4,2, 4,3, 4,7, 9,9 }; +prog_uchar letters_79[] PROGMEM = { 0,2, 0,3, 0,4, 0,5, 0,6, 1,1, 1,7, 2,1, 2,7, 3,2, 3,3, 3,4, 3,5, 3,6, 9,9 }; +prog_uchar letters_33[] PROGMEM = { 1,1, 1,2, 1,3, 1,4, 1,5, 1,7, 9,9 }; +prog_uchar letters_65[] PROGMEM = { 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,1, 1,4, 2,1, 2,4, 3,2, 3,3, 3,4, 3,5, 3,6, 3,7, 9,9 }; +prog_uchar letters_87[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,6, 2,5, 3,6, 4,1, 4,2, 4,3, 4,4, 4,5, 4,6, 4,7, 9,9 }; +prog_uchar letters_69[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,1, 3,4, 3,7, 9,9 }; +prog_uchar letters_80[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,1, 1,4, 2,1, 2,4, 3,2, 3,3, 9,9 }; +prog_uchar letters_50[] PROGMEM = { 0,2, 0,5, 0,6, 0,7, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,1, 3,4, 3,7, 4,2, 4,3, 4,7, 9,9 }; +prog_uchar letters_49[] PROGMEM = { 1,2, 1,7, 2,1, 2,2, 2,3, 2,4, 2,5, 2,6, 2,7, 3,7, 9,9 }; +prog_uchar letters_74[] PROGMEM = { 0,7, 1,1, 1,7, 2,1, 2,2, 2,3, 2,4, 2,5, 2,6, 3,1, 9,9 }; +prog_uchar letters_68[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,1, 1,7, 2,1, 2,7, 3,2, 3,3, 3,4, 3,5, 3,6, 9,9 }; +prog_uchar letters_90[] PROGMEM = { 0,1, 0,6, 0,7, 1,1, 1,5, 1,7, 2,1, 2,4, 2,7, 3,1, 3,3, 3,7, 4,1, 4,2, 4,7, 9,9 }; +prog_uchar letters_70[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,1, 1,4, 2,1, 2,4, 3,1, 3,4, 9,9 }; +prog_uchar letters_88[] PROGMEM = { 0,1, 0,2, 0,6, 0,7, 1,3, 1,5, 2,4, 3,3, 3,5, 4,1, 4,2, 4,6, 4,7, 9,9 }; +prog_uchar letters_75[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,4, 2,3, 2,5, 3,1, 3,2, 3,6, 3,7, 9,9 }; +prog_uchar letters_53[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,7, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,1, 3,4, 3,7, 4,1, 4,5, 4,6, 9,9 }; +prog_uchar letters_48[] PROGMEM = { 0,2, 0,3, 0,4, 0,5, 0,6, 1,1, 1,7, 2,1, 2,7, 3,1, 3,7, 4,2, 4,3, 4,4, 4,5, 4,6, 9,9 }; +prog_uchar letters_77[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,2, 2,3, 3,2, 4,1, 4,2, 4,3, 4,4, 4,5, 4,6, 4,7, 9,9 }; +prog_uchar letters_54[] PROGMEM = { 0,2, 0,3, 0,4, 0,5, 0,6, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,1, 3,4, 3,7, 4,2, 4,5, 4,6, 9,9 }; +prog_uchar letters_39[] PROGMEM = { 1,3, 2,1, 2,2, 9,9 }; +prog_uchar letters_85[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 1,7, 2,7, 3,1, 3,2, 3,3, 3,4, 3,5, 3,6, 9,9 }; +prog_uchar letters_57[] PROGMEM = { 0,2, 0,3, 0,7, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,1, 3,4, 3,7, 4,2, 4,3, 4,4, 4,5, 4,6, 9,9 }; +prog_uchar letters_78[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,2, 2,3, 3,4, 4,1, 4,2, 4,3, 4,4, 4,5, 4,6, 4,7, 9,9 }; +prog_uchar letters_84[] PROGMEM = { 0,1, 1,1, 1,2, 1,3, 1,4, 1,5, 1,6, 1,7, 2,1, 9,9 }; +prog_uchar letters_81[] PROGMEM = { 0,2, 0,3, 0,4, 0,5, 0,6, 1,1, 1,7, 2,1, 2,5, 2,7, 3,1, 3,6, 4,2, 4,3, 4,4, 4,5, 4,7, 9,9 }; +prog_uchar letters_51[] PROGMEM = { 0,2, 0,6, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,1, 3,4, 3,7, 4,2, 4,3, 4,5, 4,6, 9,9 }; +prog_uchar letters_86[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 1,6, 2,7, 3,6, 4,1, 4,2, 4,3, 4,4, 4,5, 9,9 }; +prog_uchar letters_72[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,4, 2,4, 3,1, 3,2, 3,3, 3,4, 3,5, 3,6, 3,7, 9,9 }; +prog_uchar letters_73[] PROGMEM = { 0,1, 0,7, 1,1, 1,2, 1,3, 1,4, 1,5, 1,6, 1,7, 2,1, 2,7, 9,9 }; +prog_uchar letters_44[] PROGMEM = { 1,7, 2,5, 2,6, 9,9 }; +prog_uchar letters_56[] PROGMEM = { 0,2, 0,3, 0,5, 0,6, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,1, 3,4, 3,7, 4,2, 4,3, 4,5, 4,6, 9,9 }; +prog_uchar letters_66[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,2, 3,3, 3,5, 3,6, 9,9 }; +prog_uchar letters_52[] PROGMEM = { 0,4, 0,5, 1,3, 1,5, 2,2, 2,5, 3,1, 3,2, 3,3, 3,4, 3,5, 3,6, 3,7, 4,5, 9,9 }; +prog_uchar letters_55[] PROGMEM = { 0,1, 1,1, 2,1, 2,5, 2,6, 2,7, 3,1, 3,3, 3,4, 4,1, 4,2, 9,9 }; + +prog_uchar* font[] = { letters_33 /*!*/, 0, 0, 0, 0, 0, letters_39 /*'*/, 0, 0, 0, 0, letters_44 /*,*/, 0, 0, 0, +letters_48 /*0*/, letters_49 /*1*/, letters_50 /*2*/, letters_51 /*3*/, letters_52 /*4*/, letters_53 /*5*/, +letters_54 /*6*/, letters_55 /*7*/, letters_56 /*8*/, letters_57 /*9*/, 0, 0, 0, 0, 0, 0, 0, letters_65 /*A*/, +letters_66 /*B*/, letters_67 /*C*/, letters_68 /*D*/, letters_69 /*E*/, letters_70 /*F*/, letters_71 /*G*/, +letters_72 /*H*/, letters_73 /*I*/, letters_74 /*J*/, letters_75 /*K*/, letters_76 /*L*/, letters_77 /*M*/, +letters_78 /*N*/, letters_79 /*O*/, letters_80 /*P*/, letters_81 /*Q*/, letters_82 /*R*/, letters_83 /*S*/, +letters_84 /*T*/, letters_85 /*U*/, letters_86 /*V*/, letters_87 /*W*/, letters_88 /*X*/, letters_89 /*Y*/, +letters_90 /*Z*/ +}; + + +uint16_t fontMin=33; +uint16_t fontMax=90; + +#if 0 + +// This section of the font works now, but doesn't appear to be correct. + +prog_uchar letters_117[] PROGMEM = { 0,4, 0,5, 0,6, 1,7, 2,7, 3,4, 3,5, 3,6, 3,7, 9,9 }; +prog_uchar letters_104[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,4, 2,4, 3,5, 3,6, 3,7, 9,9 }; +prog_uchar letters_109[] PROGMEM = { 0,4, 0,5, 0,6, 0,7, 1,4, 2,5, 2,6, 2,7, 3,4, 4,5, 4,6, 4,7, 9,9 }; +prog_uchar letters_114[] PROGMEM = { 0,4, 0,5, 0,6, 0,7, 1,4, 2,4, 9,9 }; +prog_uchar letters_108[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 9,9 }; +prog_uchar letters_116[] PROGMEM = { 0,2, 1,1, 1,2, 1,3, 1,4, 1,5, 1,6, 1,7, 2,2, 2,7, 3,7, 9,9 }; +prog_uchar letters_107[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,5, 2,4, 2,6, 3,3, 3,7, 9,9 }; +prog_uchar letters_118[] PROGMEM = { 0,4, 0,5, 1,6, 2,7, 3,6, 4,4, 4,5, 9,9 }; +prog_uchar letters_98[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,4, 1,7, 2,4, 2,7, 3,5, 3,6, 9,9 }; +prog_uchar letters_120[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,5, 2,4, 2,6, 3,3, 3,7, 9,9 }; +prog_uchar letters_119[] PROGMEM = { 0,4, 0,5, 1,6, 1,7, 2,4, 2,5, 3,6, 3,7, 4,4, 4,5, 9,9 }; +prog_uchar letters_111[] PROGMEM = { 0,5, 0,6, 1,4, 1,7, 2,4, 2,7, 3,5, 3,6, 9,9 }; +prog_uchar letters_105[] PROGMEM = { 0,1, 0,3, 0,4, 0,5, 0,6, 0,7, 9,9 }; +prog_uchar letters_110[] PROGMEM = { 0,4, 0,5, 0,6, 0,7, 1,4, 2,4, 3,5, 3,6, 3,7, 9,9 }; +prog_uchar letters_113[] PROGMEM = { 0,4, 0,5, 1,3, 1,6, 2,3, 2,6, 3,3, 3,4, 3,5, 3,6, 3,7, 3,8, 9,9 }; +prog_uchar letters_100[] PROGMEM = { 0,2, 0,3, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,1, 3,2, 3,3, 3,4, 3,5, 3,6, 9,9 }; +prog_uchar letters_103[] PROGMEM = { 0,3, 0,4, 0,8, 1,2, 1,5, 1,8, 2,2, 2,5, 2,8, 3,2, 3,3, 3,4, 3,5, 3,6, 3,7, 9,9 }; +prog_uchar letters_112[] PROGMEM = { 0,3, 0,4, 0,5, 0,6, 0,7, 0,8, 1,3, 1,6, 2,3, 2,6, 3,4, 3,5, 9,9 }; +prog_uchar letters_101[] PROGMEM = { 0,4, 0,5, 0,6, 1,3, 1,5, 1,7, 2,3, 2,5, 2,7, 3,4, 3,5, 3,7, 9,9 }; +prog_uchar letters_102[] PROGMEM = { 0,5, 1,1, 1,2, 1,3, 1,4, 1,5, 1,6, 1,7, 2,1, 2,5, 3,1, 9,9 }; +prog_uchar letters_115[] PROGMEM = { 0,3, 0,4, 0,7, 1,3, 1,5, 1,7, 2,3, 2,5, 2,7, 3,3, 3,5, 3,6, 3,7, 9,9 }; +prog_uchar letters_99[] PROGMEM = { 0,5, 0,6, 1,4, 1,7, 2,4, 2,7, 3,4, 3,7, 9,9 }; +prog_uchar letters_106[] PROGMEM = { 0,8, 1,2, 1,4, 1,5, 1,6, 1,7, 1,8, 9,9 }; +prog_uchar letters_97[] PROGMEM = { 0,6, 0,7, 1,3, 1,5, 1,7, 2,3, 2,5, 2,7, 3,4, 3,5, 3,6, 3,7, 9,9 }; + +prog_uchar* font2[] = { 0, 0, 0, 0, 0, 0, letters_97 /*a*/, letters_98 /*b*/, letters_99 /*c*/, letters_100 /*d*/, letters_101 /*e*/, letters_102 /*f*/, letters_103 /*g*/, letters_104 /*h*/, letters_105 /*i*/, letters_106 /*j*/, letters_107 /*k*/, letters_108 /*l*/, letters_109 /*m*/, letters_110 /*n*/, letters_111 /*o*/, letters_112 /*p*/, letters_113 /*q*/, letters_114 /*r*/, letters_115 /*s*/, letters_116 /*t*/, letters_117 /*u*/, letters_118 /*v*/, letters_119 /*w*/, letters_120 /*x*/ }; +*/ + +#endif + +/* ----------------------------------------------------------------- */ +/** 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 + */ +uint8_t Font::Draw(unsigned char letter,int x,int y,int set) { + uint16_t maxx=0; + + uint8_t charCol; + uint8_t charRow; + + prog_uchar* character; + if (letter==' ') return 3+2; + if (letter<fontMin || letter>fontMax) { + return 0; + } + +// if (letter>90) { +// character = font2[letter-90]; +// } else { + character = font[letter-fontMin]; +// } + + int i=0; + + charCol = pgm_read_byte_near(character); + charRow = pgm_read_byte_near(character + 1); + + while (charRow!=9) { + if (charCol>maxx) maxx=charCol; + if ( + charCol + x <14 && + charCol + x >=0 && + charRow + y <8 && + charRow + y >=0 + ) { + LedSign::Set(charCol + x, charRow+y, set); + } + i+=2; + + charCol = pgm_read_byte_near(character + i); + charRow = pgm_read_byte_near(character + 1 + i); + } + return maxx+2; +} + + +/* ----------------------------------------------------------------- */ +/** Draw a figure in the other direction (rotated 90°) + * @param figure is the figure [0-9] + * @param x,y coordinates, + * @param set is 1 or 0 to draw or clear it +*/ +uint8_t Font::Draw90(unsigned char letter,int x,int y,int set) { + uint16_t maxx=0; + + uint8_t charCol; + uint8_t charRow; + + prog_uchar* character; + if (letter==' ') return 3+2; + if (letter<fontMin || letter>fontMax) { + return 0; + } + +// if (letter>90) { +// character = font2[letter-90]; +// } else { + character = font[letter-fontMin]; +// } + + int i=0; + + charCol = pgm_read_byte_near(character); + charRow = pgm_read_byte_near(character + 1); + + while (charRow!=9) { + if (charCol>maxx) maxx=charCol; + if ( + charRow + x <14 && + charRow + x >=0 && + charCol + y <8 && + charCol + y >=0 + ) { + LedSign::Set(7 - charRow + x, charCol + y, set); + } + i+=2; + + charCol = pgm_read_byte_near(character + i); + charRow = pgm_read_byte_near(character + 1 + i); + } + return maxx+2; + +} + + + + + diff --git a/Matrix_9x14/libraries/Charliplexing/.svn/text-base/Font.h.svn-base b/Matrix_9x14/libraries/Charliplexing/.svn/text-base/Font.h.svn-base new file mode 100644 index 0000000..84dd77a --- /dev/null +++ b/Matrix_9x14/libraries/Charliplexing/.svn/text-base/Font.h.svn-base @@ -0,0 +1,40 @@ +/* + 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> + +namespace Font +{ + +extern uint8_t Draw(unsigned char letter,int x,int y,int set=1); + +extern uint8_t Draw90(unsigned char letter,int x,int y,int set=1); + +} + +#endif + diff --git a/Matrix_9x14/libraries/Charliplexing/.svn/text-base/keywords.txt.svn-base b/Matrix_9x14/libraries/Charliplexing/.svn/text-base/keywords.txt.svn-base new file mode 100644 index 0000000..99c8d02 --- /dev/null +++ b/Matrix_9x14/libraries/Charliplexing/.svn/text-base/keywords.txt.svn-base @@ -0,0 +1,14 @@ +LedSign KEYWORD1 +Init KEYWORD2 +Set KEYWORD2 +Flip KEYWORD2 +Clear KEYWORD2 +Horizontal KEYWORD2 +Vertical KEYWORD2 +Figure KEYWORD1 +Draw KEYWORD2 +Draw90 KEYWORD2 +Scroll90 KEYWORD2 +Font KEYWORD1 +Draw KEYWORD2 +Draw90 KEYWORD2 diff --git a/Matrix_9x14/libraries/Charliplexing/Charliplexing.cpp b/Matrix_9x14/libraries/Charliplexing/Charliplexing.cpp new file mode 100644 index 0000000..d68b209 --- /dev/null +++ b/Matrix_9x14/libraries/Charliplexing/Charliplexing.cpp @@ -0,0 +1,502 @@ +/* + 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 "Charliplexing.h" + +volatile unsigned int LedSign::tcnt2; + + +struct videoPage { + uint8_t pixels[SHADES][48]; // TODO: is 48 right? +}; + +/* ----------------------------------------------------------------- */ +/** Table for the LED multiplexing cycles + * Each frame is made of 24 bytes (for the 24 display cycles) + * There are SHADES frames per buffer in grayscale mode (one for each brigtness) + * and twice that many to support double-buffered grayscale. + */ +videoPage leds[2]; + +/// Determines whether the display is in single or double buffer mode +uint8_t displayMode = SINGLE_BUFFER; + +/// Flag indicating that the display page should be flipped as soon as the +/// current frame is displayed +volatile boolean videoFlipPage = false; + +/// Pointer to the buffer that is currently being displayed +videoPage* displayBuffer; + +/// Pointer to the buffer that should currently be drawn to +videoPage* workBuffer; + +/// Flag indicating that the timer buffer should be flipped as soon as the +/// current frame is displayed +volatile boolean videoFlipTimer = false; + + +// Timer counts to display each page for, plus off time +typedef struct timerInfo { + uint8_t counts[SHADES]; + uint8_t prescaler[SHADES]; +}; + +// Double buffer the timing information, of course. +timerInfo* frontTimer; +timerInfo* backTimer; + +timerInfo* tempTimer; + +timerInfo timer[2]; + +// Record a slow and fast prescaler for later use +typedef struct prescalerInfo { + uint8_t relativeSpeed; + uint8_t TCCR2; +}; + +// TODO: Generate these based on processor type and clock speed +prescalerInfo slowPrescaler = {1, 0x03}; +//prescalerInfo fastPrescaler = {32, 0x01}; +prescalerInfo fastPrescaler = {4, 0x02}; + +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 +#define MEASURE_ISR_TIME +#ifdef MEASURE_ISR_TIME +uint8_t statusPIN = 19; +#endif + +typedef struct LEDPosition { + uint8_t high; + uint8_t low; +}; + + +/* ----------------------------------------------------------------- */ +/** Table for LED Position in leds[] ram table + */ + +const LEDPosition ledMap[126] = { + {13, 5}, {13, 6}, {13, 7}, {13, 8}, {13, 9}, {13,10}, {13,11}, {13,12}, + {13, 4}, { 4,13}, {13, 3}, { 3,13}, {13, 2}, { 2,13}, + {12, 5}, {12, 6}, {12, 7}, {12, 8}, {12, 9}, {12,10}, {12,11}, {12,13}, + {12, 4}, { 4,12}, {12, 3}, { 3,12}, {12, 2}, { 2,12}, + {11, 5}, {11, 6}, {11, 7}, {11, 8}, {11, 9}, {11,10}, {11,12}, {11,13}, + {11, 4}, { 4,11}, {11, 3}, { 3,11}, {11, 2}, { 2,11}, + {10, 5}, {10, 6}, {10, 7}, {10, 8}, {10, 9}, {10,11}, {10,12}, {10,13}, + {10, 4}, { 4,10}, {10, 3}, { 3,10}, {10, 2}, { 2,10}, + { 9, 5}, { 9, 6}, { 9, 7}, { 9, 8}, { 9,10}, { 9,11}, { 9,12}, { 9,13}, + { 9, 4}, { 4, 9}, { 9, 3}, { 3, 9}, { 9, 2}, { 2, 9}, + { 8, 5}, { 8, 6}, { 8, 7}, { 8, 9}, { 8,10}, { 8,11}, { 8,12}, { 8,13}, + { 8, 4}, { 4, 8}, { 8, 3}, { 3, 8}, { 8, 2}, { 2, 8}, + { 7, 5}, { 7, 6}, { 7, 8}, { 7, 9}, { 7,10}, { 7,11}, { 7,12}, { 7,13}, + { 7, 4}, { 4, 7}, { 7, 3}, { 3, 7}, { 7, 2}, { 2, 7}, + { 6, 5}, { 6, 7}, { 6, 8}, { 6, 9}, { 6,10}, { 6,11}, { 6,12}, { 6,13}, + { 6, 4}, { 4, 6}, { 6, 3}, { 3, 6}, { 6, 2}, { 2, 6}, + { 5, 6}, { 5, 7}, { 5, 8}, { 5, 9}, { 5,10}, { 5,11}, { 5,12}, { 5,13}, + { 5, 4}, { 4, 5}, { 5, 3}, { 3, 5}, { 5, 2}, { 2, 5}, +}; + + +/* ----------------------------------------------------------------- */ +/** 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 + + float prescaler = 0.0; + +#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || (__AVR_ATmega1280__) + TIMSK2 &= ~(1<<TOIE2); + TCCR2A &= ~((1<<WGM21) | (1<<WGM20)); + TCCR2B &= ~(1<<WGM22); + ASSR &= ~(1<<AS2); + TIMSK2 &= ~(1<<OCIE2A); + + if ((F_CPU >= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64 + TCCR2B |= ((1<<CS21) | (1<<CS20)); + TCCR2B &= ~(1<<CS22); + prescaler = 32.0; + } else if (F_CPU < 1000000UL) { // prescaler set to 8 + TCCR2B |= (1<<CS21); + TCCR2B &= ~((1<<CS22) | (1<<CS20)); + prescaler = 8.0; + } else { // F_CPU > 16Mhz, prescaler set to 128 + TCCR2B |= (1<<CS22); + TCCR2B &= ~((1<<CS21) | (1<<CS20)); + prescaler = 64.0; + } +#elif defined (__AVR_ATmega8__) + TIMSK &= ~(1<<TOIE2); + TCCR2 &= ~((1<<WGM21) | (1<<WGM20)); + TIMSK &= ~(1<<OCIE2); + ASSR &= ~(1<<AS2); + + if ((F_CPU >= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64 + TCCR2 |= (1<<CS22); + TCCR2 &= ~((1<<CS21) | (1<<CS20)); + prescaler = 64.0; + } else if (F_CPU < 1000000UL) { // prescaler set to 8 + TCCR2 |= (1<<CS21); + TCCR2 &= ~((1<<CS22) | (1<<CS20)); + prescaler = 8.0; + } else { // F_CPU > 16Mhz, prescaler set to 128 + TCCR2 |= ((1<<CS22) && (1<<CS20)); + TCCR2 &= ~(1<<CS21); + prescaler = 128.0; + } +#elif defined (__AVR_ATmega128__) + TIMSK &= ~(1<<TOIE2); + TCCR2 &= ~((1<<WGM21) | (1<<WGM20)); + TIMSK &= ~(1<<OCIE2); + + if ((F_CPU >= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64 + TCCR2 |= ((1<<CS21) | (1<<CS20)); + TCCR2 &= ~(1<<CS22); + prescaler = 64.0; + } else if (F_CPU < 1000000UL) { // prescaler set to 8 + TCCR2 |= (1<<CS21); + TCCR2 &= ~((1<<CS22) | (1<<CS20)); + prescaler = 8.0; + } else { // F_CPU > 16Mhz, prescaler set to 256 + TCCR2 |= (1<<CS22); + TCCR2 &= ~((1<<CS21) | (1<<CS20)); + prescaler = 256.0; + } +#endif + + tcnt2 = 256 - (int)((float)F_CPU * 0.0005 / prescaler); + + // Record whether we are in single or double buffer mode + displayMode = mode; + videoFlipPage = false; + + // Point the display buffer to the first physical buffer + displayBuffer = &leds[0]; + + // 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 = displayBuffer; + } + + // Set up the timer buffering + frontTimer = &timer[0]; + backTimer = &timer[1]; + + videoFlipTimer = false; + SetBrightness(127); + + // Clear the buffer and display it + LedSign::Clear(0); + LedSign::Flip(false); + + // Then start the display + TCNT2 = tcnt2; +#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || (__AVR_ATmega1280__) + TIMSK2 |= (1<<TOIE2); +#elif defined (__AVR_ATmega128__) || defined (__AVR_ATmega8__) + TIMSK |= (1<<TOIE2); +#endif + + // If we are in double-buffer mode, wait until the display flips before we + // return + if (displayMode & DOUBLE_BUFFER) + { + while (videoFlipPage) { + delay(1); + } + } + + initialized = true; +} + + +/* ----------------------------------------------------------------- */ +/** 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) +{ + if (displayMode & DOUBLE_BUFFER) + { + // Just set the flip flag, the buffer will flip between redraws + videoFlipPage = true; + + // If we are blocking, sit here until the page flips. + while (blocking && videoFlipPage) { + delay(1); + } + } +} + + +/* ----------------------------------------------------------------- */ +/** Clear the screen completely + * @param set if 1 : make all led ON, if not set or 0 : make all led OFF + */ +void LedSign::Clear(int set) { + for(int x=0;x<14;x++) + for(int y=0;y<9;y++) + Set(x,y,set); +} + + +/* ----------------------------------------------------------------- */ +/** 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(int y, int set) { + for(int x=0;x<14;x++) + Set(x,y,set); +} + + +/* ----------------------------------------------------------------- */ +/** 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(int x, int set) { + for(int y=0;y<9;y++) + Set(x,y,set); +} + + +/* ----------------------------------------------------------------- */ +/** 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) +{ + uint8_t pin_high = ledMap[x+y*14].high; + uint8_t pin_low = ledMap[x+y*14].low; + // pin_low is directly the address in the led array (minus 2 because the + // first two bytes are used for RS232 communication), but + // as it is a two byte array we need to check pin_high also. + // If pin_high is bigger than 8 address has to be increased by one + + uint8_t bufferNum = (pin_low-2)*2 + (pin_high / 8) + ((pin_high > 7)?24:0); + uint8_t work = _BV(pin_high & 0x07); + + // If we aren't in grayscale mode, just map any pin brightness to max + if (c > 0 && !(displayMode & GRAYSCALE)) { + c = SHADES-1; + } + + for (int i = 0; i < SHADES-1; i++) { + if( c > i ) { + workBuffer->pixels[i][bufferNum] |= work; // ON + } + else { + workBuffer->pixels[i][bufferNum] &= ~work; // OFF + } + } +} + + +/* 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 + float brightnessPercent = ((float)brightness / 127)*((float)brightness / 127); + uint8_t difference = 0; + + /* ---- This needs review! Please review. -- thilo */ + // set up page counts + // TODO: make SHADES a function parameter. This would require some refactoring. + int start = 15; + int max = 255; + float scale = 1.5; + float delta = pow( max - start , 1.0 / scale) / (SHADES - 1); + uint8_t pageCounts[SHADES]; + + pageCounts[0] = max - start; + for (uint8_t i=1; i<SHADES; i++) { + pageCounts[i] = max - ( pow( i * delta, scale ) + start ); + } + Serial.end(); + + if (! initialized) { + // set front timer defaults + for (int i = 0; i < SHADES; i++) { + frontTimer->counts[i] = pageCounts[i]; + // TODO: Generate this dynamically + frontTimer->prescaler[i] = slowPrescaler.TCCR2; + } + } + + // Wait until the previous brightness request goes through + while( videoFlipTimer ) { + delay(1); + } + + // Compute on time for each of the pages + // Use the fast timer; slow timer is only useful for < 3 shades. + for (uint8_t i = 0; i < SHADES - 1; i++) { + uint8_t interval = 255 - pageCounts[i]; + + backTimer->counts[i] = 255 - brightnessPercent + * interval + * fastPrescaler.relativeSpeed; + backTimer->prescaler[i] = fastPrescaler.TCCR2; + difference += backTimer->counts[i] - pageCounts[i]; + } + + // Compute off time + backTimer->counts[SHADES - 1] = 255 - difference; + backTimer->prescaler[SHADES - 1] = slowPrescaler.TCCR2; + + /* ---- End of "This needs review! Please review." -- thilo */ + + // Have the ISR update the timer registers next run + videoFlipTimer = true; +} + + +/* ----------------------------------------------------------------- */ +/** The Interrupt code goes here ! + */ +ISR(TIMER2_OVF_vect) { + DDRD = 0x0; + DDRB = 0x0; +#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; + + TCCR2B = frontTimer->prescaler[page]; + TCNT2 = frontTimer->counts[page]; + + if ( page < SHADES - 1) { + + if (cycle < 6) { + DDRD = _BV(cycle+2) | displayBuffer->pixels[page][cycle*2]; + PORTD = displayBuffer->pixels[page][cycle*2]; + + DDRB = displayBuffer->pixels[page][cycle*2+1]; + PORTB = displayBuffer->pixels[page][cycle*2+1]; + } else if (cycle < 12) { + DDRD = displayBuffer->pixels[page][cycle*2]; + PORTD = displayBuffer->pixels[page][cycle*2]; + + DDRB = _BV(cycle-6) | displayBuffer->pixels[page][cycle*2+1]; + PORTB = displayBuffer->pixels[page][cycle*2+1]; + } else if (cycle < 18) { + DDRD = _BV(cycle+2-12) | displayBuffer->pixels[page][cycle*2]; + PORTD = displayBuffer->pixels[page][cycle*2]; + + DDRB = displayBuffer->pixels[page][cycle*2+1]; + PORTB = displayBuffer->pixels[page][cycle*2+1]; + } else { + DDRD = displayBuffer->pixels[page][cycle*2]; + PORTD = displayBuffer->pixels[page][cycle*2]; + + DDRB = _BV(cycle-6-12) | displayBuffer->pixels[page][cycle*2+1]; + PORTB = displayBuffer->pixels[page][cycle*2+1]; + } + } + else { + // Turn everything off + DDRD = 0x0; + DDRB = 0x0; + } + + page++; + + if (page >= SHADES) { + page = 0; + cycle++; + } + + if (cycle > 24) { + cycle = 0; + + // If the page should be flipped, do it here. + if (videoFlipPage && (displayMode & DOUBLE_BUFFER)) + { + // TODO: is this an atomic operation? + videoFlipPage = false; + + videoPage* temp = displayBuffer; + displayBuffer = workBuffer; + workBuffer = temp; + } + + if (videoFlipTimer) { + videoFlipTimer = false; + + tempTimer = frontTimer; + frontTimer = backTimer; + backTimer = tempTimer; + } + } + +#ifdef MEASURE_ISR_TIME + digitalWrite(statusPIN, LOW); +#endif +} diff --git a/Matrix_9x14/libraries/Charliplexing/Charliplexing.h b/Matrix_9x14/libraries/Charliplexing/Charliplexing.h new file mode 100644 index 0000000..6054dc4 --- /dev/null +++ b/Matrix_9x14/libraries/Charliplexing/Charliplexing.h @@ -0,0 +1,34 @@ +/* + 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 +#define GRAYSCALE 2 + +#define DISPLAY_COLS 14 // Number of columns in the display +#define DISPLAY_ROWS 9 // Number of rows in the display +#define SHADES 8 // Number of distinct shades to display, including black, i.e. OFF + +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); + extern volatile unsigned int tcnt2; + extern void Flip(bool blocking = false); + extern void Clear(int set=0); + extern void Horizontal(int y, int set=0); + extern void Vertical(int x, int set=0); +}; + +#endif diff --git a/Matrix_9x14/libraries/Charliplexing/Figure.cpp b/Matrix_9x14/libraries/Charliplexing/Figure.cpp new file mode 100644 index 0000000..1b8c9db --- /dev/null +++ b/Matrix_9x14/libraries/Charliplexing/Figure.cpp @@ -0,0 +1,125 @@ +/* + 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 "Charliplexing.h" +#include "Figure.h" + +#if defined(ARDUINO) && ARDUINO >= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif +#include <inttypes.h> + + +uint8_t figuresData[][14][2] = { +{ {0,0}, {1,0}, {2,0}, {0,1}, {2,1}, {0,2}, {2,2}, {0,3}, {2,3}, {0,4}, {1,4}, {2,4}, {9,9}, {9,9} }, +{ {1,0}, {0,1}, {1,1}, {1,2}, {1,3}, {0,4}, {1,4}, {2,4}, {9,9}, {9,9}, {9,9}, {9,9}, {9,9}, {9,9} }, +{ {0,0}, {1,0}, {2,0}, {2,1}, {1,2}, {0,3}, {0,4}, {1,4}, {2,4}, {9,9}, {9,9}, {9,9}, {9,9}, {9,9} }, +{ {0,0}, {1,0}, {2,0}, {2,1}, {0,2}, {1,2}, {2,3}, {0,4}, {1,4}, {2,4}, {9,9}, {9,9}, {9,9}, {9,9} }, +{ {0,0}, {2,0}, {0,1}, {2,1}, {0,2}, {1,2}, {2,2}, {2,3}, {2,4}, {9,9}, {9,9}, {9,9}, {9,9}, {9,9} }, +{ {0,0}, {1,0}, {2,0}, {0,1}, {0,2}, {1,2}, {2,2}, {2,3}, {0,4}, {1,4}, {2,4}, {9,9}, {9,9}, {9,9} }, +{ {0,0}, {1,0}, {2,0}, {0,1}, {0,2}, {1,2}, {2,2}, {0,3}, {2,3}, {0,4}, {1,4}, {2,4}, {9,9}, {9,9} }, +{ {0,0}, {1,0}, {2,0}, {2,1}, {2,2}, {1,3}, {1,4}, {9,9}, {9,9}, {9,9}, {9,9}, {9,9}, {9,9}, {9,9} }, +{ {0,0}, {1,0}, {2,0}, {0,1}, {2,1}, {0,2}, {1,2}, {2,2}, {0,3}, {2,3}, {0,4}, {1,4}, {2,4}, {9,9} }, +{ {0,0}, {1,0}, {2,0}, {0,1}, {2,1}, {0,2}, {1,2}, {2,2}, {2,3}, {0,4}, {1,4}, {9,9}, {9,9}, {9,9} } +}; + + +/* ----------------------------------------------------------------- */ +/** 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(int figure,int x,int y,int set) { + for(int i=0;i<14;i++) { + if (figuresData[figure][i][0]==9) break; + if ( + figuresData[figure][i][0]+x<13 && + figuresData[figure][i][0]+x>=0 && + figuresData[figure][i][1]+y<8 && + figuresData[figure][i][1]+y>=0 + ) { + LedSign::Set(figuresData[figure][i][0]+x,figuresData[figure][i][1]+y,set); + } + } +} + + +/* ----------------------------------------------------------------- */ +/** 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(int figure,int x,int y,int set) { + for(int i=0;i<14;i++) { + if (figuresData[figure][i][0]==9) break; + if ( + (5-figuresData[figure][i][1])+x<13 && + (5-figuresData[figure][i][1])+x>=0 && + figuresData[figure][i][0]+y<8 && + figuresData[figure][i][0]+y>=0 + ) { + LedSign::Set((5-figuresData[figure][i][1])+x,figuresData[figure][i][0]+y,set); + } + } +} + + +/* ----------------------------------------------------------------- */ +/** 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) { + int i,j,k; + uint8_t figures[]={ + (value%10000000)/1000000, + (value%1000000)/100000, + (value%100000)/10000, + (value%10000)/1000, + (value%1000)/100, + (value%100)/10, + (value%10) + }; + j=0; + while (figures[j]==0 && j<6) j++; + + for(i=0;i<9+(7-j)*5;i++) { + for(k=j;k<=6;k++) + Figure::Draw90(figures[k],3,-i+9+4*(k-j) ,1); + delay(100); + for(k=j;k<=6;k++) + Figure::Draw90(figures[k],3,-i+9+4*(k-j) ,0); + } +} + + diff --git a/Matrix_9x14/libraries/Charliplexing/Figure.h b/Matrix_9x14/libraries/Charliplexing/Figure.h new file mode 100644 index 0000000..1b3f1fe --- /dev/null +++ b/Matrix_9x14/libraries/Charliplexing/Figure.h @@ -0,0 +1,42 @@ +/* + 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(int figure,int x,int y,int set=1); + +extern void Draw90(int figure,int x,int y,int set=1); + +extern void Scroll90(unsigned long value,uint8_t x=3); + +} + +#endif + diff --git a/Matrix_9x14/libraries/Charliplexing/Font.cpp b/Matrix_9x14/libraries/Charliplexing/Font.cpp new file mode 100644 index 0000000..441e29c --- /dev/null +++ b/Matrix_9x14/libraries/Charliplexing/Font.cpp @@ -0,0 +1,219 @@ +#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> + +prog_uchar letters_71[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,1, 1,7, 2,1, 2,4, 2,7, 3,1, 3,2, 3,4, 3,5, 3,6, 3,7, 9,9 }; +prog_uchar letters_83[] PROGMEM = { 0,2, 0,3, 0,7, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,1, 3,5, 3,6, 9,9 }; +prog_uchar letters_67[] PROGMEM = { 0,2, 0,3, 0,4, 0,5, 0,6, 1,1, 1,7, 2,1, 2,7, 3,1, 3,7, 9,9 }; +prog_uchar letters_76[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,7, 2,7, 3,7, 9,9 }; +prog_uchar letters_89[] PROGMEM = { 0,1, 0,2, 1,3, 2,4, 2,5, 2,6, 2,7, 3,3, 4,1, 4,2, 9,9 }; +prog_uchar letters_82[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,1, 1,4, 2,1, 2,4, 2,5, 3,1, 3,4, 3,6, 4,2, 4,3, 4,7, 9,9 }; +prog_uchar letters_79[] PROGMEM = { 0,2, 0,3, 0,4, 0,5, 0,6, 1,1, 1,7, 2,1, 2,7, 3,2, 3,3, 3,4, 3,5, 3,6, 9,9 }; +prog_uchar letters_33[] PROGMEM = { 1,1, 1,2, 1,3, 1,4, 1,5, 1,7, 9,9 }; +prog_uchar letters_65[] PROGMEM = { 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,1, 1,4, 2,1, 2,4, 3,2, 3,3, 3,4, 3,5, 3,6, 3,7, 9,9 }; +prog_uchar letters_87[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,6, 2,5, 3,6, 4,1, 4,2, 4,3, 4,4, 4,5, 4,6, 4,7, 9,9 }; +prog_uchar letters_69[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,1, 3,4, 3,7, 9,9 }; +prog_uchar letters_80[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,1, 1,4, 2,1, 2,4, 3,2, 3,3, 9,9 }; +prog_uchar letters_50[] PROGMEM = { 0,2, 0,5, 0,6, 0,7, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,1, 3,4, 3,7, 4,2, 4,3, 4,7, 9,9 }; +prog_uchar letters_49[] PROGMEM = { 1,2, 1,7, 2,1, 2,2, 2,3, 2,4, 2,5, 2,6, 2,7, 3,7, 9,9 }; +prog_uchar letters_74[] PROGMEM = { 0,7, 1,1, 1,7, 2,1, 2,2, 2,3, 2,4, 2,5, 2,6, 3,1, 9,9 }; +prog_uchar letters_68[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,1, 1,7, 2,1, 2,7, 3,2, 3,3, 3,4, 3,5, 3,6, 9,9 }; +prog_uchar letters_90[] PROGMEM = { 0,1, 0,6, 0,7, 1,1, 1,5, 1,7, 2,1, 2,4, 2,7, 3,1, 3,3, 3,7, 4,1, 4,2, 4,7, 9,9 }; +prog_uchar letters_70[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,1, 1,4, 2,1, 2,4, 3,1, 3,4, 9,9 }; +prog_uchar letters_88[] PROGMEM = { 0,1, 0,2, 0,6, 0,7, 1,3, 1,5, 2,4, 3,3, 3,5, 4,1, 4,2, 4,6, 4,7, 9,9 }; +prog_uchar letters_75[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,4, 2,3, 2,5, 3,1, 3,2, 3,6, 3,7, 9,9 }; +prog_uchar letters_53[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,7, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,1, 3,4, 3,7, 4,1, 4,5, 4,6, 9,9 }; +prog_uchar letters_48[] PROGMEM = { 0,2, 0,3, 0,4, 0,5, 0,6, 1,1, 1,7, 2,1, 2,7, 3,1, 3,7, 4,2, 4,3, 4,4, 4,5, 4,6, 9,9 }; +prog_uchar letters_77[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,2, 2,3, 3,2, 4,1, 4,2, 4,3, 4,4, 4,5, 4,6, 4,7, 9,9 }; +prog_uchar letters_54[] PROGMEM = { 0,2, 0,3, 0,4, 0,5, 0,6, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,1, 3,4, 3,7, 4,2, 4,5, 4,6, 9,9 }; +prog_uchar letters_39[] PROGMEM = { 1,3, 2,1, 2,2, 9,9 }; +prog_uchar letters_85[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 1,7, 2,7, 3,1, 3,2, 3,3, 3,4, 3,5, 3,6, 9,9 }; +prog_uchar letters_57[] PROGMEM = { 0,2, 0,3, 0,7, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,1, 3,4, 3,7, 4,2, 4,3, 4,4, 4,5, 4,6, 9,9 }; +prog_uchar letters_78[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,2, 2,3, 3,4, 4,1, 4,2, 4,3, 4,4, 4,5, 4,6, 4,7, 9,9 }; +prog_uchar letters_84[] PROGMEM = { 0,1, 1,1, 1,2, 1,3, 1,4, 1,5, 1,6, 1,7, 2,1, 9,9 }; +prog_uchar letters_81[] PROGMEM = { 0,2, 0,3, 0,4, 0,5, 0,6, 1,1, 1,7, 2,1, 2,5, 2,7, 3,1, 3,6, 4,2, 4,3, 4,4, 4,5, 4,7, 9,9 }; +prog_uchar letters_51[] PROGMEM = { 0,2, 0,6, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,1, 3,4, 3,7, 4,2, 4,3, 4,5, 4,6, 9,9 }; +prog_uchar letters_86[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 1,6, 2,7, 3,6, 4,1, 4,2, 4,3, 4,4, 4,5, 9,9 }; +prog_uchar letters_72[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,4, 2,4, 3,1, 3,2, 3,3, 3,4, 3,5, 3,6, 3,7, 9,9 }; +prog_uchar letters_73[] PROGMEM = { 0,1, 0,7, 1,1, 1,2, 1,3, 1,4, 1,5, 1,6, 1,7, 2,1, 2,7, 9,9 }; +prog_uchar letters_44[] PROGMEM = { 1,7, 2,5, 2,6, 9,9 }; +prog_uchar letters_56[] PROGMEM = { 0,2, 0,3, 0,5, 0,6, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,1, 3,4, 3,7, 4,2, 4,3, 4,5, 4,6, 9,9 }; +prog_uchar letters_66[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,2, 3,3, 3,5, 3,6, 9,9 }; +prog_uchar letters_52[] PROGMEM = { 0,4, 0,5, 1,3, 1,5, 2,2, 2,5, 3,1, 3,2, 3,3, 3,4, 3,5, 3,6, 3,7, 4,5, 9,9 }; +prog_uchar letters_55[] PROGMEM = { 0,1, 1,1, 2,1, 2,5, 2,6, 2,7, 3,1, 3,3, 3,4, 4,1, 4,2, 9,9 }; + +prog_uchar* font[] = { letters_33 /*!*/, 0, 0, 0, 0, 0, letters_39 /*'*/, 0, 0, 0, 0, letters_44 /*,*/, 0, 0, 0, +letters_48 /*0*/, letters_49 /*1*/, letters_50 /*2*/, letters_51 /*3*/, letters_52 /*4*/, letters_53 /*5*/, +letters_54 /*6*/, letters_55 /*7*/, letters_56 /*8*/, letters_57 /*9*/, 0, 0, 0, 0, 0, 0, 0, letters_65 /*A*/, +letters_66 /*B*/, letters_67 /*C*/, letters_68 /*D*/, letters_69 /*E*/, letters_70 /*F*/, letters_71 /*G*/, +letters_72 /*H*/, letters_73 /*I*/, letters_74 /*J*/, letters_75 /*K*/, letters_76 /*L*/, letters_77 /*M*/, +letters_78 /*N*/, letters_79 /*O*/, letters_80 /*P*/, letters_81 /*Q*/, letters_82 /*R*/, letters_83 /*S*/, +letters_84 /*T*/, letters_85 /*U*/, letters_86 /*V*/, letters_87 /*W*/, letters_88 /*X*/, letters_89 /*Y*/, +letters_90 /*Z*/ +}; + + +uint16_t fontMin=33; +uint16_t fontMax=90; + +#if 0 + +// This section of the font works now, but doesn't appear to be correct. + +prog_uchar letters_117[] PROGMEM = { 0,4, 0,5, 0,6, 1,7, 2,7, 3,4, 3,5, 3,6, 3,7, 9,9 }; +prog_uchar letters_104[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,4, 2,4, 3,5, 3,6, 3,7, 9,9 }; +prog_uchar letters_109[] PROGMEM = { 0,4, 0,5, 0,6, 0,7, 1,4, 2,5, 2,6, 2,7, 3,4, 4,5, 4,6, 4,7, 9,9 }; +prog_uchar letters_114[] PROGMEM = { 0,4, 0,5, 0,6, 0,7, 1,4, 2,4, 9,9 }; +prog_uchar letters_108[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 9,9 }; +prog_uchar letters_116[] PROGMEM = { 0,2, 1,1, 1,2, 1,3, 1,4, 1,5, 1,6, 1,7, 2,2, 2,7, 3,7, 9,9 }; +prog_uchar letters_107[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,5, 2,4, 2,6, 3,3, 3,7, 9,9 }; +prog_uchar letters_118[] PROGMEM = { 0,4, 0,5, 1,6, 2,7, 3,6, 4,4, 4,5, 9,9 }; +prog_uchar letters_98[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,4, 1,7, 2,4, 2,7, 3,5, 3,6, 9,9 }; +prog_uchar letters_120[] PROGMEM = { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 1,5, 2,4, 2,6, 3,3, 3,7, 9,9 }; +prog_uchar letters_119[] PROGMEM = { 0,4, 0,5, 1,6, 1,7, 2,4, 2,5, 3,6, 3,7, 4,4, 4,5, 9,9 }; +prog_uchar letters_111[] PROGMEM = { 0,5, 0,6, 1,4, 1,7, 2,4, 2,7, 3,5, 3,6, 9,9 }; +prog_uchar letters_105[] PROGMEM = { 0,1, 0,3, 0,4, 0,5, 0,6, 0,7, 9,9 }; +prog_uchar letters_110[] PROGMEM = { 0,4, 0,5, 0,6, 0,7, 1,4, 2,4, 3,5, 3,6, 3,7, 9,9 }; +prog_uchar letters_113[] PROGMEM = { 0,4, 0,5, 1,3, 1,6, 2,3, 2,6, 3,3, 3,4, 3,5, 3,6, 3,7, 3,8, 9,9 }; +prog_uchar letters_100[] PROGMEM = { 0,2, 0,3, 1,1, 1,4, 1,7, 2,1, 2,4, 2,7, 3,1, 3,2, 3,3, 3,4, 3,5, 3,6, 9,9 }; +prog_uchar letters_103[] PROGMEM = { 0,3, 0,4, 0,8, 1,2, 1,5, 1,8, 2,2, 2,5, 2,8, 3,2, 3,3, 3,4, 3,5, 3,6, 3,7, 9,9 }; +prog_uchar letters_112[] PROGMEM = { 0,3, 0,4, 0,5, 0,6, 0,7, 0,8, 1,3, 1,6, 2,3, 2,6, 3,4, 3,5, 9,9 }; +prog_uchar letters_101[] PROGMEM = { 0,4, 0,5, 0,6, 1,3, 1,5, 1,7, 2,3, 2,5, 2,7, 3,4, 3,5, 3,7, 9,9 }; +prog_uchar letters_102[] PROGMEM = { 0,5, 1,1, 1,2, 1,3, 1,4, 1,5, 1,6, 1,7, 2,1, 2,5, 3,1, 9,9 }; +prog_uchar letters_115[] PROGMEM = { 0,3, 0,4, 0,7, 1,3, 1,5, 1,7, 2,3, 2,5, 2,7, 3,3, 3,5, 3,6, 3,7, 9,9 }; +prog_uchar letters_99[] PROGMEM = { 0,5, 0,6, 1,4, 1,7, 2,4, 2,7, 3,4, 3,7, 9,9 }; +prog_uchar letters_106[] PROGMEM = { 0,8, 1,2, 1,4, 1,5, 1,6, 1,7, 1,8, 9,9 }; +prog_uchar letters_97[] PROGMEM = { 0,6, 0,7, 1,3, 1,5, 1,7, 2,3, 2,5, 2,7, 3,4, 3,5, 3,6, 3,7, 9,9 }; + +prog_uchar* font2[] = { 0, 0, 0, 0, 0, 0, letters_97 /*a*/, letters_98 /*b*/, letters_99 /*c*/, letters_100 /*d*/, letters_101 /*e*/, letters_102 /*f*/, letters_103 /*g*/, letters_104 /*h*/, letters_105 /*i*/, letters_106 /*j*/, letters_107 /*k*/, letters_108 /*l*/, letters_109 /*m*/, letters_110 /*n*/, letters_111 /*o*/, letters_112 /*p*/, letters_113 /*q*/, letters_114 /*r*/, letters_115 /*s*/, letters_116 /*t*/, letters_117 /*u*/, letters_118 /*v*/, letters_119 /*w*/, letters_120 /*x*/ }; +*/ + +#endif + +/* ----------------------------------------------------------------- */ +/** 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 + */ +uint8_t Font::Draw(unsigned char letter,int x,int y,int set) { + uint16_t maxx=0; + + uint8_t charCol; + uint8_t charRow; + + prog_uchar* character; + if (letter==' ') return 3+2; + if (letter<fontMin || letter>fontMax) { + return 0; + } + +// if (letter>90) { +// character = font2[letter-90]; +// } else { + character = font[letter-fontMin]; +// } + + int i=0; + + charCol = pgm_read_byte_near(character); + charRow = pgm_read_byte_near(character + 1); + + while (charRow!=9) { + if (charCol>maxx) maxx=charCol; + if ( + charCol + x <14 && + charCol + x >=0 && + charRow + y <8 && + charRow + y >=0 + ) { + LedSign::Set(charCol + x, charRow+y, set); + } + i+=2; + + charCol = pgm_read_byte_near(character + i); + charRow = pgm_read_byte_near(character + 1 + i); + } + return maxx+2; +} + + +/* ----------------------------------------------------------------- */ +/** Draw a figure in the other direction (rotated 90°) + * @param figure is the figure [0-9] + * @param x,y coordinates, + * @param set is 1 or 0 to draw or clear it +*/ +uint8_t Font::Draw90(unsigned char letter,int x,int y,int set) { + uint16_t maxx=0; + + uint8_t charCol; + uint8_t charRow; + + prog_uchar* character; + if (letter==' ') return 3+2; + if (letter<fontMin || letter>fontMax) { + return 0; + } + +// if (letter>90) { +// character = font2[letter-90]; +// } else { + character = font[letter-fontMin]; +// } + + int i=0; + + charCol = pgm_read_byte_near(character); + charRow = pgm_read_byte_near(character + 1); + + while (charRow!=9) { + if (charCol>maxx) maxx=charCol; + if ( + charRow + x <14 && + charRow + x >=0 && + charCol + y <8 && + charCol + y >=0 + ) { + LedSign::Set(7 - charRow + x, charCol + y, set); + } + i+=2; + + charCol = pgm_read_byte_near(character + i); + charRow = pgm_read_byte_near(character + 1 + i); + } + return maxx+2; + +} + + + + + diff --git a/Matrix_9x14/libraries/Charliplexing/Font.h b/Matrix_9x14/libraries/Charliplexing/Font.h new file mode 100644 index 0000000..84dd77a --- /dev/null +++ b/Matrix_9x14/libraries/Charliplexing/Font.h @@ -0,0 +1,40 @@ +/* + 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> + +namespace Font +{ + +extern uint8_t Draw(unsigned char letter,int x,int y,int set=1); + +extern uint8_t Draw90(unsigned char letter,int x,int y,int set=1); + +} + +#endif + |