1
0
mirror of https://github.com/taigrr/arduinolibs synced 2025-01-18 04:33:12 -08:00

Library for using Freetronics dot matrix displays

This commit is contained in:
Rhys Weatherley 2012-05-25 17:41:27 +10:00
parent d26dcdc740
commit 081aab987b
20 changed files with 3030 additions and 2 deletions

View File

@ -610,7 +610,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories # directories like "/usr/src/myproject". Separate the files or directories
# with spaces. # with spaces.
INPUT = ../libraries/LCD ../libraries/BlinkLED ../libraries/I2C ../libraries/RTC ../libraries/Melody ../libraries/PowerSave . INPUT = ../libraries/LCD ../libraries/BlinkLED ../libraries/I2C ../libraries/RTC ../libraries/Melody ../libraries/PowerSave ../libraries/DMD .
# This tag can be used to specify the character encoding of the source files # This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@ -688,7 +688,7 @@ EXAMPLE_RECURSIVE = NO
# directories that contain image that are included in the documentation (see # directories that contain image that are included in the documentation (see
# the \image command). # the \image command).
IMAGE_PATH = ../libraries/BlinkLED/examples/Cylon ../libraries/BlinkLED/examples/Cylon4 ../libraries/BlinkLED/examples/StarTrek ../libraries/LCD/examples/HelloWorld ../libraries/LCD/examples/Form ../libraries/RTC/examples/AlarmClock IMAGE_PATH = ../libraries/BlinkLED/examples/Cylon ../libraries/BlinkLED/examples/Cylon4 ../libraries/BlinkLED/examples/StarTrek ../libraries/LCD/examples/HelloWorld ../libraries/LCD/examples/Form ../libraries/RTC/examples/AlarmClock ../libraries/DMD
# The INPUT_FILTER tag can be used to specify a program that doxygen should # The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program # invoke to filter for each input file. Doxygen will invoke the filter program

48
gen/genflip.c Normal file
View File

@ -0,0 +1,48 @@
/*
* Copyright (C) 2012 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <stdio.h>
int main(int argc, char *argv[])
{
int value;
printf("static const uint8_t flipBits[256] PROGMEM = {\n");
for (value = 0; value < 256; ++value) {
int flipped =
((value & 0x01) << 7) | ((value & 0x02) << 5) |
((value & 0x04) << 3) | ((value & 0x08) << 1) |
((value & 0x10) >> 1) | ((value & 0x20) >> 3) |
((value & 0x40) >> 5) | ((value & 0x80) >> 7);
if ((value % 12) == 0)
printf(" ");
else
printf(" ");
if (value != 255)
printf("0x%02X,", flipped);
else
printf("0x%02X", flipped);
if ((value % 12) == 11)
printf("\n");
}
printf("\n};\n");
return 0;
}

956
libraries/DMD/Bitmap.cpp Normal file
View File

@ -0,0 +1,956 @@
/*
* Copyright (C) 2012 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "Bitmap.h"
#include <WString.h>
#include <string.h>
#include <stdlib.h>
/**
* \class Bitmap Bitmap.h <Bitmap.h>
* \brief Represents a monochrome bitmap within main memory.
*
* Bitmaps are a rectangular arrangement of width() x height() pixels,
* with each pixel set to either \ref Black or \ref White. The co-ordinate
* system has origin (0, 0) at the top-left of the bitmap.
*
* Functions within this class can be used to draw various shapes into
* the bitmap's data() buffer; e.g. drawLine(), drawRect(), drawBitmap(),
* drawText(), clear(), fill(), etc.
*
* \sa DMD
*/
/**
* \typedef Bitmap::Color
* \brief Type that represents the color of a pixel in a bitmap.
*
* \sa Black, White
*/
/**
* \var Bitmap::Black
* \brief Color value corresponding to "black".
*/
/**
* \var Bitmap::White
* \brief Color value corresponding to "white". If the bitmap is
* displayed on a LED array, then it may have a different physical color.
*
* Note: while the value of this constant is 1, the bitmap itself stores
* white pixels as 0 and black as 1 because the DMD display uses 1 to
* indicate a pixel being off.
*/
/**
* \var Bitmap::NoFill
* \brief Special color value that is used with drawRect() and drawCircle()
* to indicate that the interior of the shape should not be filled.
* For all other uses, \ref NoFill is equivalent to \ref White.
*/
/**
* \brief Constructs a new in-memory bitmap that is \a width x \a height
* pixels in size.
*
* \sa width(), height(), isValid()
*/
Bitmap::Bitmap(int width, int height)
: _width(width)
, _height(height)
, _stride((width + 7) / 8)
, fb(0)
, _font(0)
, _textColor(White)
{
// Allocate memory for the framebuffer and clear it (1 = pixel off).
unsigned int size = _stride * _height;
fb = (uint8_t *)malloc(size);
if (fb)
memset(fb, 0xFF, size);
}
/**
* \brief Destroys this bitmap.
*/
Bitmap::~Bitmap()
{
if (fb)
free(fb);
}
/**
* \fn bool Bitmap::isValid() const
* \brief Returns true if the memory for this bitmap is valid; false otherwise.
*
* This function can be called just after the constructor to determine if
* the memory for the bitmap was allocated successfully.
*/
/**
* \fn int Bitmap::width() const
* \brief Returns the width of the bitmap in pixels.
*
* \sa height(), stride(), bitsPerPixel()
*/
/**
* \fn int Bitmap::height() const
* \brief Returns the height of the bitmap in pixels.
*
* \sa width(), bitsPerPixel()
*/
/**
* \fn int Bitmap::stride() const
* \brief Returns the number of bytes in each line of the bitmap's data() buffer.
*
* \sa width(), bitsPerPixel(), data()
*/
/**
* \fn int Bitmap::bitsPerPixel() const
* \brief Returns the number of bits per pixel for the bitmap; always 1.
*
* \sa width(), height()
*/
/**
* \fn uint8_t *Bitmap::data()
* \brief Returns a pointer to the start of the bitmap's data buffer.
*
* The data is organized as height() lines of stride() bytes, laid out
* horizontally across the extent of width() pixels. The most significant
* bit in each byte has the lowest x value.
*
* Note: bits within the data are 1 for \ref Black and 0 for \ref White,
* which is the reverse of the constant values. This differs from pixel()
* which returns the correct constant.
*
* \sa pixel(), stride()
*/
/**
* \fn const uint8_t *Bitmap::data() const
* \brief Returns a constant pointer to the start of the bitmap's data buffer.
* \overload
*/
/**
* \brief Clears the entire bitmap to the specified \a color.
*
* \sa fill()
*/
void Bitmap::clear(Color color)
{
unsigned int size = _stride * _height;
if (color == Black)
memset(fb, 0xFF, size);
else
memset(fb, 0x00, size);
}
/**
* \brief Returns the color of the pixel at (\a x, \a y); either \ref Black
* or \ref White.
*
* Returns \a Black if \a x or \a y is out of range.
*
* \sa setPixel(), data()
*/
Bitmap::Color Bitmap::pixel(int x, int y) const
{
if (((unsigned int)x) >= ((unsigned int)_width) ||
((unsigned int)y) >= ((unsigned int)_height))
return Black;
uint8_t *ptr = fb + y * _stride + (x >> 3);
if (*ptr & ((uint8_t)0x80) >> (x & 0x07))
return Black;
else
return White;
}
/**
* \brief Sets the pixel at (\a x, \a y) to \a color.
*
* \sa pixel()
*/
void Bitmap::setPixel(int x, int y, Color color)
{
if (((unsigned int)x) >= ((unsigned int)_width) ||
((unsigned int)y) >= ((unsigned int)_height))
return; // Pixel is off-screen.
uint8_t *ptr = fb + y * _stride + (x >> 3);
if (color)
*ptr &= ~(((uint8_t)0x80) >> (x & 0x07));
else
*ptr |= (((uint8_t)0x80) >> (x & 0x07));
}
/**
* \brief Draws a line from (\a x1, \a y1) to (\a x2, \a y2) in \a color.
*
* \sa drawRect(), drawCircle()
*/
void Bitmap::drawLine(int x1, int y1, int x2, int y2, Color color)
{
// Midpoint line scan-conversion algorithm from "Computer Graphics:
// Principles and Practice", Second Edition, Foley, van Dam, et al.
int dx = x2 - x1;
int dy = y2 - y1;
int xstep, ystep;
int d, incrE, incrNE;
if (dx < 0) {
xstep = -1;
dx = -dx;
} else {
xstep = 1;
}
if (dy < 0) {
ystep = -1;
dy = -dy;
} else {
ystep = 1;
}
if (dx >= dy) {
d = 2 * dy - dx;
incrE = 2 * dy;
incrNE = 2 * (dy - dx);
setPixel(x1, y1, color);
while (x1 != x2) {
if (d <= 0) {
d += incrE;
} else {
d += incrNE;
y1 += ystep;
}
x1 += xstep;
setPixel(x1, y1, color);
}
} else {
d = 2 * dx - dy;
incrE = 2 * dx;
incrNE = 2 * (dx - dy);
setPixel(x1, y1, color);
while (y1 != y2) {
if (d <= 0) {
d += incrE;
} else {
d += incrNE;
x1 += xstep;
}
y1 += ystep;
setPixel(x1, y1, color);
}
}
}
/**
* \brief Draws a rectangle from (\a x1, \a y1) to (\a x2, \a y2), with the
* outline in \a borderColor and the interior filled with \a fillColor.
*
* If \a fillColor is \ref NoFill, then the interior is not filled.
*
* \sa drawFilledRect(), drawLine(), drawCircle(), fill()
*/
void Bitmap::drawRect(int x1, int y1, int x2, int y2, Color borderColor, Color fillColor)
{
int temp;
if (x1 > x2) {
temp = x1;
x1 = x2;
x2 = temp;
}
if (y1 > y2) {
temp = y1;
y1 = y2;
y2 = temp;
}
if (fillColor == borderColor) {
fill(x1, y1, x2 - x1 + 1, y2 - y1 + 1, fillColor);
} else {
drawLine(x1, y1, x2, y1, borderColor);
if (y1 < y2)
drawLine(x2, y1 + 1, x2, y2, borderColor);
if (x1 < x2)
drawLine(x2 - 1, y2, x1, y2, borderColor);
if (y1 < (y2 - 1))
drawLine(x1, y2 - 1, x1, y1 + 1, borderColor);
if (fillColor != NoFill)
fill(x1 + 1, y1 + 1, x2 - x1 - 1, y2 - y1 - 1, fillColor);
}
}
/**
* \fn void Bitmap::drawFilledRect(int x1, int y1, int x2, int y2, Color color)
* \brief Draws a filled rectangle from (\a x1, \a y1) to (\a x2, \a y2)
* in \a color.
*
* This is a convenience function that is equivalent to
* drawRect(\a x1, \a y1, \a x2, \a y2, \a color, \a color).
*
* \sa drawRect(), drawFilledCircle()
*/
/**
* \brief Draws a circle with a specific center (\a centerX, \a centerY)
* and \a radius, with the outline in \a borderColor and the interior
* filled with \a fillColor.
*
* If \a fillColor is \ref NoFill, then the interior is not filled.
*
* \sa drawFilledCircle(), drawLine(), drawRect()
*/
void Bitmap::drawCircle(int centerX, int centerY, int radius, Color borderColor, Color fillColor)
{
// Midpoint circle scan-conversion algorithm using second-order
// differences from "Computer Graphics: Principles and Practice",
// Second Edition, Foley, van Dam, et al.
if (radius < 0)
radius = -radius;
int x = 0;
int y = radius;
int d = 1 - radius;
int deltaE = 3;
int deltaSE = 5 - 2 * radius;
drawCirclePoints(centerX, centerY, radius, x, y, borderColor, fillColor);
while (y > x) {
if (d < 0) {
d += deltaE;
deltaE += 2;
deltaSE += 2;
} else {
d += deltaSE;
deltaE += 2;
deltaSE += 4;
--y;
}
++x;
drawCirclePoints(centerX, centerY, radius, x, y, borderColor, fillColor);
}
}
/**
* \fn void Bitmap::drawFilledCircle(int centerX, int centerY, int radius, Color color)
* \brief Draws a filled circle with a specific center (\a centerX, \a centerY)
* and \a radius in \a color.
*
* This is a convenience function that is equivalent to
* drawCircle(\a centerX, \a centerY, \a radius, \a color, \a color).
*
* \sa drawCircle(), drawFilledRect()
*/
/**
* \brief Draws \a bitmap at (\a x, \a y) in \a color.
*
* Bits that are set to \ref White in the \a bitmap are drawn with \a color.
* Bits that are set to \ref Black in the \a bitmap are drawn with the
* inverse of \a color. The pixel at (\a x, \a y) will be the top-left
* corner of the drawn image.
*
* Note: \a bitmap must not be the same as this object or the behaviour will
* be undefined. To copy a region of a bitmap to elsewhere within the
* same bitmap, use copy() instead.
*
* \sa drawInvertedBitmap(), copy()
*/
void Bitmap::drawBitmap(int x, int y, const Bitmap &bitmap, Color color)
{
int w = bitmap.width();
int s = bitmap.stride();
int h = bitmap.height();
Color invColor = !color;
for (uint8_t by = 0; by < h; ++by) {
const uint8_t *line = bitmap.data() + by * s;
uint8_t mask = 0x80;
uint8_t value = *line++;
for (uint8_t bx = 0; bx < w; ++bx) {
if (value & mask)
setPixel(x + bx, y + by, invColor);
else
setPixel(x + bx, y + by, color);
mask >>= 1;
if (!mask) {
mask = 0x80;
value = *line++;
}
}
}
}
/**
* \brief Draws \a bitmap at (\a x, \a y) in \a color.
*
* The \a bitmap must point to program memory. The first two bytes are the
* width and height of the bitmap in pixels. The rest of the data contains
* the pixels for the bitmap, with lines byte-aligned.
*
* Bits that are 1 in the \a bitmap are drawn with \a color. Bits that are
* 0 in the \a bitmap are drawn with the inverse of \a color. The pixel at
* (\a x, \a y) will be the top-left corner of the drawn image.
*
* \sa drawInvertedBitmap(), fill()
*/
void Bitmap::drawBitmap(int x, int y, const prog_uint8_t *bitmap, Color color)
{
uint8_t w = pgm_read_byte(bitmap);
uint8_t s = (w + 7) >> 3;
uint8_t h = pgm_read_byte(bitmap + 1);
Color invColor = !color;
for (uint8_t by = 0; by < h; ++by) {
const prog_uint8_t *line = bitmap + 2 + by * s;
uint8_t mask = 0x80;
uint8_t value = pgm_read_byte(line);
for (uint8_t bx = 0; bx < w; ++bx) {
if (value & mask)
setPixel(x + bx, y + by, color);
else
setPixel(x + bx, y + by, invColor);
mask >>= 1;
if (!mask) {
mask = 0x80;
++line;
value = pgm_read_byte(line);
}
}
}
}
/**
* \fn void Bitmap::drawInvertedBitmap(int x, int y, const Bitmap &bitmap)
* \brief Draws \a bitmap at (\a x, \a y) in inverted colors.
*
* This is a convenience function that is equivalent to
* drawBitmap(\a x, \a y, \a bitmap, \ref Black).
*
* \sa drawBitmap()
*/
/**
* \fn void Bitmap::drawInvertedBitmap(int x, int y, const prog_uint8_t *bitmap)
* \brief Draws \a bitmap at (\a x, \a y) in inverted colors.
*
* This is a convenience function that is equivalent to
* drawBitmap(\a x, \a y, \a bitmap, \ref Black).
*
* \sa drawBitmap()
*/
/**
* \fn const prog_uint8_t *Bitmap::font() const
* \brief Returns the currently selected font, or null if none selected.
*
* \sa setFont(), drawText(), drawChar(), charWidth()
*/
/**
* \fn void Bitmap::setFont(const prog_uint8_t *font)
* \brief Sets the \a font for use with drawText() and drawChar().
*
* \code
* #include <DejaVuSans9.h>
*
* display.setFont(DejaVuSans9);
* display.drawText(0, 0, "Hello");
* \endcode
*
* New fonts can be generated with <a href="https://code.google.com/p/glcd-arduino/downloads/detail?name=GLCDFontCreator2.zip&can=2&q=">GLCDFontCreator2</a>.
*
* \sa font(), drawText(), drawChar()
*/
/**
* \fn Color Bitmap::textColor() const
* \brief Returns the color that will be used for drawing text with
* drawText() and drawChar(). The default is \ref White.
*
* \sa setTextColor(), drawText(), drawChar()
*/
/**
* \fn void Bitmap::setTextColor(Color textColor)
* \brief Sets the \a color that will be used for drawing text with
* drawText() and drawChar().
*
* \sa textColor(), drawText(), drawChar()
*/
#define fontIsFixed(font) (pgm_read_byte((font)) == 0 && \
pgm_read_byte((font) + 1) == 0)
#define fontWidth(font) (pgm_read_byte((font) + 2))
#define fontHeight(font) (pgm_read_byte((font) + 3))
#define fontFirstChar(font) (pgm_read_byte((font) + 4))
#define fontCharCount(font) (pgm_read_byte((font) + 5))
/**
* \brief Draws the \a len characters of \a str at (\a x, \a y).
*
* If \a len is less than zero, then the actual length of \a str will be used.
*
* The position (\a x, \a y) will be the upper-left pixel of the first
* character that is drawn.
*
* \sa drawChar(), textColor(), font()
*/
void Bitmap::drawText(int x, int y, const char *str, int len)
{
if (!_font)
return;
uint8_t height = fontHeight(_font);
if (len < 0)
len = strlen(str);
while (len-- > 0) {
x += drawChar(x, y, *str++);
if (len > 0) {
fill(x, y, 1, height, !_textColor);
++x;
}
if (x >= _width)
break;
}
}
/**
* \brief Draws \a len characters starting at \a start from \a str to the
* screen at (\a x, \a y).
*
* If \a len is less than zero, then the actual length of \a str will be used.
*
* The position (\a x, \a y) will be the upper-left pixel of the first
* character that is drawn.
*
* \sa drawChar(), textColor(), font()
*/
void Bitmap::drawText(int x, int y, const String &str, int start, int len)
{
if (!_font)
return;
uint8_t height = fontHeight(_font);
if (len < 0)
len = str.length() - start;
while (len-- > 0) {
x += drawChar(x, y, str[start++]);
if (len > 0) {
fill(x, y, 1, height, !_textColor);
++x;
}
if (x >= _width)
break;
}
}
/**
* \brief Draws a single character \a ch at (\a x, \a y).
*
* Returns the width of the character in pixels so that higher-order functions
* like drawText() can advance \a x to the location of the next character
* to be drawn. The width does not include inter-character spacing.
*
* The position (\a x, \a y) will be the upper-left pixel of the drawn
* character.
*
* \sa drawText(), textColor(), font(), charWidth()
*/
int Bitmap::drawChar(int x, int y, char ch)
{
uint8_t height = fontHeight(_font);
if (ch == ' ') {
// Font may not have space, or it is zero-width. Calculate
// the real size and fill the space.
int spaceWidth = charWidth('n');
fill(x, y, spaceWidth, height, !_textColor);
return spaceWidth;
}
uint8_t first = fontFirstChar(_font);
uint8_t count = fontCharCount(_font);
uint8_t index = (uint8_t)ch;
if (index < first || index >= (first + count))
return 0;
index -= first;
uint8_t heightBytes = (height + 7) >> 3;;
uint8_t width;
const prog_uint8_t *image;
if (fontIsFixed(_font)) {
// Fixed-width font.
width = fontWidth(_font);
image = _font + 6 + index * heightBytes * width;
} else {
// Variable-width font.
width = pgm_read_byte(_font + 6 + index);
image = _font + 6 + count;
for (uint8_t temp = 0; temp < index; ++temp) {
// Scan through all previous characters to find the starting
// location for this one.
image += pgm_read_byte(_font + 6 + temp) * heightBytes;
}
}
if ((x + width) <= 0 || (y + height) <= 0)
return width; // Character is off the top or left of the screen.
Color invColor = !_textColor;
for (uint8_t cx = 0; cx < width; ++cx) {
for (uint8_t cy = 0; cy < heightBytes; ++cy) {
uint8_t value = pgm_read_byte(image + cy * width + cx);
int posn;
if (heightBytes > 1 && cy == (heightBytes - 1))
posn = height - 8;
else
posn = cy * 8;
for (uint8_t bit = 0; bit < 8; ++bit) {
if ((posn + bit) >= (cy * 8) && (posn + bit) <= height) {
if (value & 0x01)
setPixel(x + cx, y + posn + bit, _textColor);
else
setPixel(x + cx, y + posn + bit, invColor);
}
value >>= 1;
}
}
}
return width;
}
/**
* \brief Returns the width in pixels of \a ch in the current font().
*
* Returns zero if font() is not set, or \a ch is not present in font().
*
* \sa drawChar(), font(), textWidth(), textHeight()
*/
int Bitmap::charWidth(char ch) const
{
uint8_t index = (uint8_t)ch;
if (!_font)
return 0;
uint8_t first = fontFirstChar(_font);
uint8_t count = fontCharCount(_font);
if (index == ' ')
index = 'n'; // In case the font does not contain space.
if (index < first || index >= (first + count))
return 0;
if (fontIsFixed(_font))
return fontWidth(_font);
else
return pgm_read_byte(_font + 6 + (index - first));
}
/**
* \brief Returns the width in pixels of the \a len characters of \a str
* in the current font(), including inter-character spacing.
*
* If \a len is less than zero, then the actual length of \a str will be used.
*
* \sa drawText(), charWidth(), textHeight()
*/
int Bitmap::textWidth(const char *str, int len) const
{
int width = 0;
if (len < 0)
len = strlen(str);
while (len-- > 0) {
width += charWidth(*str++);
if (len > 0)
++width;
}
return width;
}
/**
* \brief Returns the width in pixels of the \a len characters of \a str
* in the current font(), starting at \a start, including inter-character
* spacing.
*
* If \a len is less than zero, then the actual length of \a str will be used.
*
* \sa drawText(), charWidth(), textHeight()
*/
int Bitmap::textWidth(const String &str, int start, int len) const
{
int width = 0;
if (len < 0)
len = str.length() - start;
while (len-- > 0) {
width += charWidth(str[start++]);
if (len > 0)
++width;
}
return width;
}
/**
* \brief Returns the height in pixels of the current text drawing font();
* or zero if font() is not set.
*
* \sa font(), charWidth(), textWidth()
*/
int Bitmap::textHeight() const
{
if (_font)
return fontHeight(_font);
else
return 0;
}
/**
* \brief Copies the \a width x \a height pixels starting at top-left
* corner (\a x, \a y) to (\a destX, \a destY) in the bitmap \a dest.
*
* The \a dest bitmap can be the same as this object, in which case the copy
* will be performed in a manner that correctly handles overlapping regions.
*
* If some part of the source region is outside the bounds of this object,
* then the value \ref Black will be copied to \a dest for those pixels.
* This can be used to produce a behaviour similar to scroll() when
* \a bitmap is the same as this object.
*
* \sa drawBitmap(), fill(), scroll()
*/
void Bitmap::copy(int x, int y, int width, int height, Bitmap *dest, int destX, int destY)
{
if (dest == this) {
// Copying to within the same bitmap, so copy in a direction
// that will prevent problems with overlap.
blit(x, y, x + width - 1, y + height - 1, destX, destY);
} else {
// Copying to a different bitmap.
while (height > 0) {
for (int tempx = 0; tempx < width; ++tempx)
dest->setPixel(destX + tempx, destY, pixel(x + tempx, y));
++y;
++destY;
--height;
}
}
}
/**
* \brief Fills the \a width x \a height pixels starting at top-left
* corner (\a x, \a y) with \a color.
*
* \sa copy(), clear(), invert(), drawRect()
*/
void Bitmap::fill(int x, int y, int width, int height, Color color)
{
while (height > 0) {
for (int temp = 0; temp < width; ++temp)
setPixel(x + temp, y, color);
++y;
--height;
}
}
/**
* \brief Fills the \a width x \a height pixels starting at top-left
* corner (\a x, \a y) with the contents of \a pattern.
*
* The \a pattern must point to program memory. The first two bytes are the
* width and height of the pattern in pixels. The rest of the data contains
* the pixels for the pattern, with lines byte-aligned.
*
* Bits that are 1 in the \a pattern are drawn with \a color. Bits that are
* 0 in the \a pattern are drawn with the inverse of \a color.
*
* \sa drawBitmap(), clear(), invert()
*/
void Bitmap::fill(int x, int y, int width, int height, const prog_uint8_t *pattern, Color color)
{
uint8_t w = pgm_read_byte(pattern);
uint8_t s = (w + 7) >> 3;
uint8_t h = pgm_read_byte(pattern + 1);
if (!w || !h)
return;
Color invColor = !color;
for (int tempy = 0; tempy < height; ++tempy) {
const prog_uint8_t *startLine = pattern + 2 + (tempy % h) * s;
const prog_uint8_t *line = startLine;
uint8_t mask = 0x80;
uint8_t value = pgm_read_byte(line++);
int bit = 0;
for (int tempx = 0; tempx < width; ++tempx) {
if (value & mask)
setPixel(x + tempx, y + tempy, color);
else
setPixel(x + tempx, y + tempy, invColor);
if (++bit >= w) {
mask = 0x80;
line = startLine;
value = pgm_read_byte(line++);
bit = 0;
} else {
mask >>= 1;
if (!mask) {
mask = 0x80;
value = pgm_read_byte(line++);
}
}
}
}
}
/**
* \fn void Bitmap::scroll(int dx, int dy, Color fillColor)
* \brief Scrolls the entire contents of the bitmap by \a dx and \a dy.
*
* If \a dx is 2 and \a dy is -1, then the region will be scrolled two
* pixels to the right and one pixel up. Pixels that are uncovered
* by the scroll are filled with \a fillColor.
*
* \sa copy(), fill()
*/
/**
* \brief Scrolls the \a width x \a height pixels starting at top-left
* corner (\a x, \a y) by \a dx and \a dy.
*
* If \a dx is 2 and \a dy is -1, then the region will be scrolled two
* pixels to the right and one pixel up. Pixels that are uncovered
* by the scroll are filled with \a fillColor.
*
* \sa copy(), fill()
*/
void Bitmap::scroll(int x, int y, int width, int height, int dx, int dy, Color fillColor)
{
// Bail out if no scrolling at all.
if (!dx && !dy)
return;
// Clamp the scroll region to the extents of the bitmap.
if (x < 0) {
width += x;
x = 0;
}
if (y < 0) {
height += y;
y = 0;
}
if ((x + width) > _width)
width = _width - x;
if ((y + height) > _height)
height = _height - y;
if (width <= 0 || height <= 0)
return;
// Scroll the region in the specified direction.
if (dy < 0) {
if (dx < 0)
blit(x - dx, y - dy, x + width - 1 + dx, y + height - 1 + dy, x, y);
else
blit(x, y - dy, x + width - 1 - dx, y + height - 1 + dy, x + dx, y);
} else {
if (dx < 0)
blit(x - dx, y, x + width - 1 + dx, y + height - 1 - dy, x, y + dy);
else
blit(x, y, x + width - 1 - dx, y + height - 1 - dy, x + dx, y + dy);
}
// Fill the pixels that were uncovered by the scroll.
if (dy < 0) {
fill(x, y + height + dy, width, -dy, fillColor);
if (dx < 0)
fill(x + width + dx, y, -dx, height + dy, fillColor);
else if (dx > 0)
fill(x, y, dx, height + dy, fillColor);
} else if (dy > 0) {
fill(x, y, width, -dy, fillColor);
if (dx < 0)
fill(x + width + dx, y + dy, -dx, height - dy, fillColor);
else if (dx > 0)
fill(x, y + dy, dx, height - dy, fillColor);
} else if (dx < 0) {
fill(x + width + dx, y, -dx, height, fillColor);
} else if (dx > 0) {
fill(x, y, dx, height, fillColor);
}
}
/**
* \brief Inverts the \a width x \a height pixels starting at top-left
* corner (\a x, \a y).
*
* \sa fill()
*/
void Bitmap::invert(int x, int y, int width, int height)
{
while (height > 0) {
for (int tempx = x + width - 1; tempx >= x; --tempx)
setPixel(tempx, y, !pixel(tempx, y));
--height;
++y;
}
}
void Bitmap::blit(int x1, int y1, int x2, int y2, int x3, int y3)
{
if (y3 < y1 || (y1 == y3 && x3 <= x1)) {
for (int tempy = y1; tempy <= y2; ++tempy) {
int y = y1 - tempy + y3;
int x = x3 - x1;
for (int tempx = x1; tempx <= x2; ++tempx)
setPixel(x + tempx, y, pixel(tempx, tempy));
}
} else {
for (int tempy = y2; tempy >= y1; --tempy) {
int y = y1 - tempy + y3;
int x = x3 - x1;
for (int tempx = x2; tempx >= x1; --tempx)
setPixel(x + tempx, y, pixel(tempx, tempy));
}
}
}
void Bitmap::drawCirclePoints(int centerX, int centerY, int radius, int x, int y, Color borderColor, Color fillColor)
{
if (x != y) {
setPixel(centerX + x, centerY + y, borderColor);
setPixel(centerX + y, centerY + x, borderColor);
setPixel(centerX + y, centerY - x, borderColor);
setPixel(centerX + x, centerY - y, borderColor);
setPixel(centerX - x, centerY - y, borderColor);
setPixel(centerX - y, centerY - x, borderColor);
setPixel(centerX - y, centerY + x, borderColor);
setPixel(centerX - x, centerY + y, borderColor);
if (fillColor != NoFill) {
if (radius > 1) {
drawLine(centerX - x + 1, centerY + y, centerX + x - 1, centerY + y, fillColor);
drawLine(centerX - y + 1, centerY + x, centerX + y - 1, centerY + x, fillColor);
drawLine(centerX - x + 1, centerY - y, centerX + x - 1, centerY - y, fillColor);
drawLine(centerX - y + 1, centerY - x, centerX + y - 1, centerY - x, fillColor);
} else if (radius == 1) {
setPixel(centerX, centerY, fillColor);
}
}
} else {
setPixel(centerX + x, centerY + y, borderColor);
setPixel(centerX + y, centerY - x, borderColor);
setPixel(centerX - x, centerY - y, borderColor);
setPixel(centerX - y, centerY + x, borderColor);
if (fillColor != NoFill) {
if (radius > 1) {
drawLine(centerX - x + 1, centerY + y, centerX + x - 1, centerY + y, fillColor);
drawLine(centerX - x + 1, centerY - y, centerX + x - 1, centerY - y, fillColor);
} else if (radius == 1) {
setPixel(centerX, centerY, fillColor);
}
}
}
}

138
libraries/DMD/Bitmap.h Normal file
View File

@ -0,0 +1,138 @@
/*
* Copyright (C) 2012 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef Bitmap_h
#define Bitmap_h
#include <inttypes.h>
#include <avr/pgmspace.h>
class DMD;
class String;
class Bitmap
{
public:
Bitmap(int width, int height);
~Bitmap();
bool isValid() const { return fb != 0; }
typedef uint8_t Color;
static const Color Black = 0;
static const Color White = 1;
static const Color NoFill = 2;
int width() const { return _width; }
int height() const { return _height; }
int stride() const { return _stride; }
int bitsPerPixel() const { return 1; }
uint8_t *data() { return fb; }
const uint8_t *data() const { return fb; }
void clear(Color color = Black);
Color pixel(int x, int y) const;
void setPixel(int x, int y, Color color);
void drawLine(int x1, int y1, int x2, int y2, Color color = White);
void drawRect(int x1, int y1, int x2, int y2, Color borderColor = White, Color fillColor = NoFill);
void drawFilledRect(int x1, int y1, int x2, int y2, Color color = White);
void drawCircle(int centerX, int centerY, int radius, Color borderColor = White, Color fillColor = NoFill);
void drawFilledCircle(int centerX, int centerY, int radius, Color color = White);
void drawBitmap(int x, int y, const Bitmap &bitmap, Color color = White);
void drawBitmap(int x, int y, const prog_uint8_t *bitmap, Color color = White);
void drawInvertedBitmap(int x, int y, const Bitmap &bitmap);
void drawInvertedBitmap(int x, int y, const prog_uint8_t *bitmap);
const prog_uint8_t *font() const { return _font; }
void setFont(const prog_uint8_t *font) { _font = font; }
Color textColor() const { return _textColor; }
void setTextColor(Color color) { _textColor = color; }
void drawText(int x, int y, const char *str, int len = -1);
void drawText(int x, int y, const String &str, int start = 0, int len = -1);
int drawChar(int x, int y, char ch);
int charWidth(char ch) const;
int textWidth(const char *str, int len = -1) const;
int textWidth(const String &str, int start = 0, int len = -1) const;
int textHeight() const;
void copy(int x, int y, int width, int height, Bitmap *dest, int destX, int destY);
void fill(int x, int y, int width, int height, Color color);
void fill(int x, int y, int width, int height, const prog_uint8_t *pattern, Color color = White);
void scroll(int dx, int dy, Color fillColor = Black);
void scroll(int x, int y, int width, int height, int dx, int dy, Color fillColor = Black);
void invert(int x, int y, int width, int height);
private:
// Disable copy constructor and operator=().
Bitmap(const Bitmap &) {}
Bitmap &operator=(const Bitmap &) { return *this; }
int _width;
int _height;
int _stride;
uint8_t *fb;
const prog_uint8_t *_font;
Color _textColor;
friend class DMD;
void blit(int x1, int y1, int x2, int y2, int x3, int y3);
void drawCirclePoints(int centerX, int centerY, int radius, int x, int y, Color borderColor, Color fillColor);
};
inline void Bitmap::drawFilledRect(int x1, int y1, int x2, int y2, Color color)
{
drawRect(x1, y1, x2, y2, color, color);
}
inline void Bitmap::drawFilledCircle(int centerX, int centerY, int radius, Color color)
{
drawCircle(centerX, centerY, radius, color, color);
}
inline void Bitmap::drawInvertedBitmap(int x, int y, const Bitmap &bitmap)
{
drawBitmap(x, y, bitmap, Black);
}
inline void Bitmap::drawInvertedBitmap(int x, int y, const prog_uint8_t *bitmap)
{
drawBitmap(x, y, bitmap, Black);
}
inline void Bitmap::scroll(int dx, int dy, Color fillColor)
{
scroll(0, 0, _width, _height, dx, dy, fillColor);
}
#endif

618
libraries/DMD/DMD.cpp Normal file
View File

@ -0,0 +1,618 @@
/*
* Copyright (C) 2012 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "DMD.h"
#if defined(ARDUINO) && ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#include <pins_arduino.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdlib.h>
/**
* \class DMD DMD.h <DMD.h>
* \brief Handle large dot matrix displays composed of LED's.
*
* This class is designed for use with
* <a href="http://www.freetronics.com/dmd">Freetronics Large Dot Matrix
* Displays</a>. These displays have 512 LED's arranged in a 32x16 matrix
* and controlled by an SPI interface. The displays are available in
* red, blue, green, yellow, and white variations (for which this class
* always uses the constant \ref White regardless of the physical color).
*
* \section dmd_drawing Drawing
*
* DMD inherits from Bitmap so that any of the drawing functions in that
* class can be used to draw directly to dot matrix displays. The following
* example initializes a single display panel and draws a rectangle and a
* circle into it at setup time:
*
* \code
* #include <DMD.h>
*
* DMD display;
*
* void setup() {
* display.drawRect(5, 2, 27, 13);
* display.drawCircle(16, 8, 4);
* }
* \endcode
*
* The display must be updated frequently from the application's main loop:
*
* \code
* void loop() {
* display.loop();
* }
* \endcode
*
* \section dmd_interrupts Interrupt-driven display refresh
*
* The loop() method simplifies updating the display from the application's
* main loop but it can sometimes be inconvenient to arrange for it to be
* called regularly, especially if the application wishes to use
* <tt>delay()</tt> or <tt>delayMicroseconds()</tt>.
*
* DMD provides an asynchronous display update mechanism using Timer1
* interrupts. The application turns on interrupts using enableTimer1()
* and then calls refresh() from the interrupt service routine:
*
* \code
* #include <DMD.h>
*
* DMD display;
*
* ISR(TIMER1_OVF_vect)
* {
* display.refresh();
* }
*
* void setup() {
* display.enableTimer1();
* }
* \endcode
*
* DMD can also be used with third-party timer libraries such as
* <a href="http://code.google.com/p/arduino-timerone/downloads/list">TimerOne</a>:
*
* \code
* #include <DMD.h>
* #include <TimerOne.h>
*
* DMD display;
*
* void refreshDisplay()
* {
* display.refresh();
* }
*
* void setup() {
* Timer1.initialize(5000);
* Timer1.attachInterrupt(refreshDisplay);
* }
* \endcode
*
* \section dmd_double_buffer Double buffering
*
* When using interrupts, the system can sometimes exhibit "tearing" artifacts
* where half-finished images are displayed because an interrupt fired in
* the middle of a screen update.
*
* This problem can be alleviated using double buffering: all rendering is done
* to an off-screen buffer that is swapped onto the screen once it is ready
* for display. Rendering then switches to the other buffer that is now
* off-screen. The following example demonstrates this:
*
* \code
* #include <DMD.h>
*
* DMD display;
*
* ISR(TIMER1_OVF_vect)
* {
* display.refresh();
* }
*
* void setup() {
* display.setDoubleBuffer(true);
* display.enableTimer1();
* }
*
* void loop() {
* updateDisplay();
* display.swapBuffers();
* delay(50); // Delay between frames.
* }
*
* void updateDisplay() {
* // Draw the new display contents into the off-screen buffer.
* display.clear();
* ...
* }
* \endcode
*
* The downside of double buffering is that it uses twice as much main memory
* to manage the contents of the screen.
*
* \section dmd_multi Multiple panels
*
* Multiple panels can be daisy-chained together using ribbon cables.
* If there is a single row of panels, then they must be connected
* to the Arduino board as follows:
*
* \image html dmd-4x1.png
*
* If there are multiple rows of panels, then alternating rows are
* flipped upside-down so that the short ribbon cables provided by
* Freetronics reach (this technique is thanks to Chris Debenham; see
* http://www.adebenham.com/category/arduino/dmd/ for more details):
*
* \image html dmd-4x2.png
*
* This technique can be repeated for as many rows as required, with the
* bottom row always right-way-up:
*
* \image html dmd-4x3.png
*
* DMD automatically takes care of flipping the data for panels in the
* alternating rows. No special action is required by the user except
* to physically connect the panels as shown and to initialize the DMD
* class appropriately:
*
* \code
* #include <DMD.h>
*
* DMD display(4, 2); // 4 panels wide, 2 panels high
* \endcode
*/
// Pins on the DMD connector board.
#define DMD_PIN_PHASE_LSB 6 // A
#define DMD_PIN_PHASE_MSB 7 // B
#define DMD_PIN_LATCH 8 // SCLK
#define DMD_PIN_OUTPUT_ENABLE 9 // nOE
#define DMD_PIN_SPI_SS SS // SPI Slave Select
#define DMD_PIN_SPI_MOSI MOSI // SPI Master Out, Slave In (R)
#define DMD_PIN_SPI_MISO MISO // SPI Master In, Slave Out
#define DMD_PIN_SPI_SCK SCK // SPI Serial Clock (CLK)
// Dimension information for the display.
#define DMD_NUM_COLUMNS 32 // Number of columns in a panel.
#define DMD_NUM_ROWS 16 // Number of rows in a panel.
// Refresh times.
#define DMD_REFRESH_MS 5
#define DMD_REFRESH_US 5000
/**
* \brief Constructs a new dot matrix display handler for a display that
* is \a widthPanels x \a heightPanels in size.
*
* Note: the parameters to this constructor are specified in panels,
* whereas width() and height() are specified in pixels.
*
* \sa width(), height()
*/
DMD::DMD(int widthPanels, int heightPanels)
: Bitmap(widthPanels * DMD_NUM_COLUMNS, heightPanels * DMD_NUM_ROWS)
, _doubleBuffer(false)
, phase(0)
, fb0(0)
, fb1(0)
, displayfb(0)
, lastRefresh(millis())
{
// Both rendering and display are to fb0 initially.
fb0 = displayfb = fb;
// Initialize SPI to MSB-first, mode 0, clock divider = 2.
pinMode(DMD_PIN_SPI_SCK, OUTPUT);
pinMode(DMD_PIN_SPI_MOSI, OUTPUT);
pinMode(DMD_PIN_SPI_SS, OUTPUT);
digitalWrite(DMD_PIN_SPI_SCK, LOW);
digitalWrite(DMD_PIN_SPI_MOSI, LOW);
digitalWrite(DMD_PIN_SPI_SS, HIGH);
SPCR |= _BV(MSTR);
SPCR |= _BV(SPE);
SPCR &= ~(_BV(DORD)); // MSB-first
SPCR &= ~0x0C; // Mode 0
SPCR &= ~0x03; // Clock divider rate 2
SPSR |= 0x01; // MSB of clock divider rate
// Initialize the DMD-specific pins.
pinMode(DMD_PIN_PHASE_LSB, OUTPUT);
pinMode(DMD_PIN_PHASE_MSB, OUTPUT);
pinMode(DMD_PIN_LATCH, OUTPUT);
pinMode(DMD_PIN_OUTPUT_ENABLE, OUTPUT);
digitalWrite(DMD_PIN_PHASE_LSB, LOW);
digitalWrite(DMD_PIN_PHASE_MSB, LOW);
digitalWrite(DMD_PIN_LATCH, LOW);
digitalWrite(DMD_PIN_OUTPUT_ENABLE, LOW);
digitalWrite(DMD_PIN_SPI_MOSI, HIGH);
}
/**
* \brief Destroys this dot matrix display handler.
*/
DMD::~DMD()
{
if (fb0)
free(fb0);
if (fb1)
free(fb1);
fb = 0; // Don't free the buffer again in the base class.
}
/**
* \fn bool DMD::doubleBuffer() const
* \brief Returns true if the display is double-buffered; false if
* single-buffered. The default is false.
*
* \sa setDoubleBuffer(), swapBuffers(), refresh()
*/
/**
* \brief Enables or disables double-buffering according to \a doubleBuffer.
*
* When double-buffering is enabled, rendering operations are sent to a
* memory buffer that isn't currently displayed on-screen. Once the
* application has completed the screen update, it calls swapBuffers()
* to display the current buffer and switch rendering to the other
* now invisible buffer.
*
* Double-buffering is recommended if refresh() is being called from an
* interrupt service routine, to prevent "tearing" artifacts that result
* from simultaneous update of a single shared buffer.
*
* This function will allocate memory for the extra buffer when
* \a doubleBuffer is true. If there is insufficient memory for the
* second screen buffer, then this class will revert to single-buffered mode.
*
* \sa doubleBuffer(), swapBuffers(), refresh()
*/
void DMD::setDoubleBuffer(bool doubleBuffer)
{
if (doubleBuffer != _doubleBuffer) {
_doubleBuffer = doubleBuffer;
if (doubleBuffer) {
// Allocate a new back buffer.
unsigned int size = _stride * _height;
fb1 = (uint8_t *)malloc(size);
// Clear the new back buffer and then switch to it, leaving
// the current contents of fb0 on the screen.
if (fb1) {
memset(fb1, 0xFF, size);
cli();
fb = fb1;
displayfb = fb0;
sei();
} else {
// Failed to allocate the memory, so revert to single-buffered.
_doubleBuffer = false;
}
} else if (fb1) {
// Disabling double-buffering, so forcibly switch to fb0.
cli();
fb = fb0;
displayfb = fb0;
sei();
// Free the unnecessary buffer.
free(fb1);
fb1 = 0;
}
}
}
/**
* \brief Swaps the buffers that are used for rendering to the display.
*
* When doubleBuffer() is false, this function does nothing.
* Otherwise the front and back rendering buffers are swapped.
* See the description of setDoubleBuffer() for more information.
*
* The new rendering back buffer will have undefined contents and will
* probably need to be re-inialized with clear() or fill() before
* drawing to it. The swapBuffersAndCopy() function can be used instead
* to preserve the screen contents from one frame to the next.
*
* \sa swapBuffersAndCopy(), setDoubleBuffer()
*/
void DMD::swapBuffers()
{
if (_doubleBuffer) {
// Turn off interrupts while swapping buffers so that we don't
// accidentally try to refresh() in the middle of this code.
cli();
if (fb == fb0) {
fb = fb1;
displayfb = fb0;
} else {
fb = fb0;
displayfb = fb1;
}
sei();
}
}
/**
* \brief Swaps the buffers that are used for rendering to the display
* and copies the former back buffer contents to the new back buffer.
*
* Normally when swapBuffers() is called, the new rendering back buffer
* will have undefined contents from two frames prior and must be cleared
* with clear() or fill() before writing new contents to it.
* This function instead copies the previous frame into the new
* rendering buffer so that it can be updated in-place.
*
* This function is useful if the screen does not change much from one
* frame to the next. If the screen changes a lot between frames, then it
* is usually better to explicitly clear() or fill() the new back buffer.
*
* \sa swapBuffers(), setDoubleBuffer()
*/
void DMD::swapBuffersAndCopy()
{
swapBuffers();
if (_doubleBuffer)
memcpy(fb, displayfb, _stride * _height);
}
/**
* \brief Performs regular display refresh activities from the
* application's main loop.
*
* \code
* DMD display;
*
* void loop() {
* display.loop();
* }
* \endcode
*
* If you are using a timer interrupt service routine, then call
* refresh() in response to the interrupt instead of calling loop().
*
* \sa refresh()
*/
void DMD::loop()
{
unsigned long currentTime = millis();
if ((currentTime - lastRefresh) >= DMD_REFRESH_MS) {
lastRefresh = currentTime;
refresh();
}
}
// Send a single byte via SPI.
static inline void spiSend(byte value)
{
SPDR = value;
while (!(SPSR & _BV(SPIF)))
; // Wait for the transfer to complete.
}
// Flip the bits in a byte. Table generated by genflip.c
static const uint8_t flipBits[256] PROGMEM = {
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0,
0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4,
0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC,
0x3C, 0xBC, 0x7C, 0xFC, 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA,
0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6,
0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81, 0x41, 0xC1,
0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9,
0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD,
0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3,
0x33, 0xB3, 0x73, 0xF3, 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7,
0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF,
0x3F, 0xBF, 0x7F, 0xFF
};
/**
* \brief Refresh the display.
*
* This function must be called at least once every 5 milliseconds
* for smooth non-flickering update of the display. It is usually
* called by loop(), but can also be called in response to a
* timer interrupt.
*
* If this function is called from an interrupt service routine,
* then it is recommended that double-buffering be enabled with
* setDoubleBuffer() to prevent "tearing" artifacts that result
* from simultaneous update of a single shared buffer.
*
* \sa loop(), setDoubleBuffer(), enableTimer1()
*/
void DMD::refresh()
{
// Bail out if there is a conflict on the SPI bus.
if (!digitalRead(DMD_PIN_SPI_SS))
return;
// Transfer the data for the next group of interleaved rows.
int stride4 = _stride * 4;
uint8_t *data0;
uint8_t *data1;
uint8_t *data2;
uint8_t *data3;
bool flipRow = ((_height & 0x10) == 0);
for (int y = 0; y < _height; y += 16) {
if (!flipRow) {
// The panels in this row are the right way up.
data0 = displayfb + _stride * (y + phase);
data1 = data0 + stride4;
data2 = data1 + stride4;
data3 = data2 + stride4;
for (int x = _stride; x > 0; --x) {
spiSend(*data3++);
spiSend(*data2++);
spiSend(*data1++);
spiSend(*data0++);
}
flipRow = true;
} else {
// The panels in this row are upside-down and reversed.
data0 = displayfb + _stride * (y + 16 - phase) - 1;
data1 = data0 - stride4;
data2 = data1 - stride4;
data3 = data2 - stride4;
for (int x = _stride; x > 0; --x) {
spiSend(pgm_read_byte(&(flipBits[*data3--])));
spiSend(pgm_read_byte(&(flipBits[*data2--])));
spiSend(pgm_read_byte(&(flipBits[*data1--])));
spiSend(pgm_read_byte(&(flipBits[*data0--])));
}
flipRow = false;
}
}
// Latch the data from the shift registers onto the actual display.
digitalWrite(DMD_PIN_OUTPUT_ENABLE, LOW);
digitalWrite(DMD_PIN_LATCH, HIGH);
digitalWrite(DMD_PIN_LATCH, LOW);
if (phase & 0x02)
digitalWrite(DMD_PIN_PHASE_MSB, HIGH);
else
digitalWrite(DMD_PIN_PHASE_MSB, LOW);
if (phase & 0x01)
digitalWrite(DMD_PIN_PHASE_LSB, HIGH);
else
digitalWrite(DMD_PIN_PHASE_LSB, LOW);
digitalWrite(DMD_PIN_OUTPUT_ENABLE, HIGH);
phase = (phase + 1) & 0x03;
}
/**
* \brief Enables Timer1 overflow interrupts for updating this display.
*
* The application must also provide an interrupt service routine for
* Timer1 that calls refresh():
*
* \code
* #include <DMD.h>
*
* DMD display;
*
* ISR(TIMER1_OVF_vect)
* {
* display.refresh();
* }
*
* void setup() {
* display.enableTimer1();
* }
* \endcode
*
* If timer interrupts are being used to update the display, then it is
* unnecessary to call loop().
*
* \sa refresh(), disableTimer1(), setDoubleBuffer()
*/
void DMD::enableTimer1()
{
// Number of CPU cycles in the display's refresh period.
unsigned long numCycles = (F_CPU / 2000000) * DMD_REFRESH_US;
// Determine the prescaler to be used.
#define TIMER1_RESOLUTION 65536UL
uint8_t prescaler;
if (numCycles < TIMER1_RESOLUTION) {
// No prescaling required.
prescaler = _BV(CS10);
} else if (numCycles < TIMER1_RESOLUTION * 8) {
// Prescaler = 8.
prescaler = _BV(CS11);
numCycles >>= 3;
} else if (numCycles < TIMER1_RESOLUTION * 64) {
// Prescaler = 64.
prescaler = _BV(CS11) | _BV(CS10);
numCycles >>= 6;
} else if (numCycles < TIMER1_RESOLUTION * 256) {
// Prescaler = 256.
prescaler = _BV(CS12);
numCycles >>= 8;
} else if (numCycles < TIMER1_RESOLUTION * 1024) {
// Prescaler = 1024.
prescaler = _BV(CS12) | _BV(CS10);
numCycles >>= 10;
} else {
// Too long, so set the maximum timeout.
prescaler = _BV(CS12) | _BV(CS10);
numCycles = TIMER1_RESOLUTION - 1;
}
// Configure Timer1 for the period we want.
TCCR1A = 0;
TCCR1B = _BV(WGM13);
uint8_t saveSREG = SREG;
cli();
ICR1 = numCycles;
SREG = saveSREG; // Implicit sei() if interrupts were on previously.
TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11) | _BV(CS10))) | prescaler;
// Turn on the Timer1 overflow interrupt.
TIMSK1 |= _BV(TOIE1);
}
/**
* \brief Disables Timer1 overflow interrupts.
*
* \sa enableTimer1()
*/
void DMD::disableTimer1()
{
// Turn off the Timer1 overflow interrupt.
TIMSK1 &= ~_BV(TOIE1);
}
/**
* \brief Converts an RGB value into a pixel color value.
*
* Returns \ref White if any of \a r, \a g, or \a b are non-zero;
* otherwise returns \ref Black.
*
* This function is provided for upwards compatibility with future
* displays that support full color. Monochrome applications should
* use the \ref Black and \ref White constants directly.
*/
DMD::Color DMD::fromRGB(uint8_t r, uint8_t g, uint8_t b)
{
if (r || g || b)
return White;
else
return Black;
}

60
libraries/DMD/DMD.h Normal file
View File

@ -0,0 +1,60 @@
/*
* Copyright (C) 2012 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef DMD_h
#define DMD_h
#include "Bitmap.h"
class DMD : public Bitmap
{
public:
explicit DMD(int widthPanels = 1, int heightPanels = 1);
~DMD();
bool doubleBuffer() const { return _doubleBuffer; }
void setDoubleBuffer(bool doubleBuffer);
void swapBuffers();
void swapBuffersAndCopy();
void loop();
void refresh();
void enableTimer1();
void disableTimer1();
static Color fromRGB(uint8_t r, uint8_t g, uint8_t b);
private:
// Disable copy constructor and operator=().
DMD(const DMD &other) : Bitmap(other) {}
DMD &operator=(const DMD &) { return *this; }
bool _doubleBuffer;
uint8_t phase;
uint8_t *fb0;
uint8_t *fb1;
uint8_t *displayfb;
unsigned long lastRefresh;
};
#endif

166
libraries/DMD/DejaVuSans9.h Normal file
View File

@ -0,0 +1,166 @@
/*
*
* DejaVuSans9
*
* created with FontCreator
* written by F. Maximilian Thiele
*
* http://www.apetech.de/fontCreator
* me@apetech.de
*
* File Name : DejaVuSans9.h
* Date : 28.05.2012
* Font size in bytes : 3962
* Font width : 10
* Font height : 10
* Font first char : 32
* Font last char : 128
* Font used chars : 96
*
* The font data are defined as
*
* struct _FONT_ {
* uint16_t font_Size_in_Bytes_over_all_included_Size_it_self;
* uint8_t font_Width_in_Pixel_for_fixed_drawing;
* uint8_t font_Height_in_Pixel_for_all_characters;
* unit8_t font_First_Char;
* uint8_t font_Char_Count;
*
* uint8_t font_Char_Widths[font_Last_Char - font_First_Char +1];
* // for each character the separate width in pixels,
* // characters < 128 have an implicit virtual right empty row
*
* uint8_t font_data[];
* // bit field of all characters
*/
#include <inttypes.h>
#include <avr/pgmspace.h>
#ifndef DEJAVUSANS9_H
#define DEJAVUSANS9_H
#define DEJAVUSANS9_WIDTH 10
#define DEJAVUSANS9_HEIGHT 10
static uint8_t DejaVuSans9[] PROGMEM = {
0x0F, 0x7A, // size
0x0A, // width
0x0A, // height
0x20, // first char
0x60, // char count
// char widths
0x00, 0x01, 0x03, 0x06, 0x05, 0x08, 0x06, 0x01, 0x02, 0x02,
0x05, 0x05, 0x01, 0x02, 0x01, 0x03, 0x04, 0x03, 0x04, 0x04,
0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x01, 0x01, 0x06, 0x06,
0x06, 0x04, 0x08, 0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x05,
0x05, 0x01, 0x02, 0x05, 0x04, 0x06, 0x05, 0x05, 0x04, 0x05,
0x05, 0x05, 0x05, 0x05, 0x06, 0x07, 0x06, 0x05, 0x05, 0x02,
0x03, 0x02, 0x04, 0x05, 0x02, 0x04, 0x04, 0x04, 0x04, 0x04,
0x03, 0x04, 0x04, 0x01, 0x02, 0x04, 0x01, 0x07, 0x04, 0x04,
0x04, 0x04, 0x03, 0x03, 0x04, 0x04, 0x05, 0x07, 0x05, 0x05,
0x04, 0x03, 0x01, 0x03, 0x06, 0x05,
// font data
0xBE, 0x00, // 33
0x06, 0x00, 0x06, 0x00, 0x00, 0x00, // 34
0x28, 0xE8, 0x3E, 0xE8, 0x3E, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 35
0x98, 0x94, 0xFE, 0xA4, 0x64, 0x00, 0x00, 0x40, 0x00, 0x00, // 36
0x1E, 0x12, 0xDE, 0x30, 0x18, 0xF6, 0x90, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 37
0x60, 0x9C, 0x92, 0x62, 0xC4, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 38
0x06, 0x00, // 39
0x7E, 0x81, 0x00, 0x00, // 40
0xC3, 0x3C, 0x00, 0x00, // 41
0x12, 0x0C, 0x1E, 0x0C, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, // 42
0x20, 0x20, 0xF8, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, // 43
0x80, 0x40, // 44
0x20, 0x20, 0x00, 0x00, // 45
0x80, 0x00, // 46
0xC0, 0x38, 0x06, 0x00, 0x00, 0x00, // 47
0x7C, 0x82, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, // 48
0x82, 0xFE, 0x80, 0x00, 0x00, 0x00, // 49
0xC4, 0xA2, 0x92, 0x8C, 0x00, 0x00, 0x00, 0x00, // 50
0x84, 0x92, 0x92, 0x6C, 0x00, 0x00, 0x00, 0x00, // 51
0x60, 0x58, 0x44, 0xFE, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, // 52
0x9E, 0x92, 0x92, 0x62, 0x00, 0x00, 0x00, 0x00, // 53
0x7C, 0x96, 0x92, 0x62, 0x00, 0x00, 0x00, 0x00, // 54
0x02, 0xC2, 0x3A, 0x06, 0x00, 0x00, 0x00, 0x00, // 55
0x6C, 0x92, 0x92, 0x6C, 0x00, 0x00, 0x00, 0x00, // 56
0x9C, 0x92, 0xD2, 0x7C, 0x00, 0x00, 0x00, 0x00, // 57
0x88, 0x00, // 58
0x88, 0x40, // 59
0x20, 0x20, 0x50, 0x50, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 60
0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 61
0x88, 0x50, 0x50, 0x50, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 62
0x02, 0xB2, 0x0A, 0x06, 0x00, 0x00, 0x00, 0x00, // 63
0x78, 0x84, 0x32, 0x4A, 0x4A, 0xFA, 0x44, 0x38, 0x00, 0x00, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, // 64
0xC0, 0x38, 0x26, 0x26, 0x38, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 65
0xFE, 0x92, 0x92, 0x92, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, // 66
0x7C, 0xC6, 0x82, 0x82, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, // 67
0xFE, 0x82, 0x82, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, // 68
0xFE, 0x92, 0x92, 0x92, 0x00, 0x00, 0x00, 0x00, // 69
0xFE, 0x12, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, // 70
0x7C, 0xC6, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, // 71
0xFE, 0x10, 0x10, 0x10, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, // 72
0xFE, 0x00, // 73
0x00, 0xFE, 0x80, 0x40, // 74
0xFE, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, // 75
0xFE, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, // 76
0xFE, 0x0C, 0x30, 0x30, 0x0C, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 77
0xFE, 0x0C, 0x10, 0x60, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, // 78
0x7C, 0xC6, 0x82, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, // 79
0xFE, 0x12, 0x12, 0x0C, 0x00, 0x00, 0x00, 0x00, // 80
0x7C, 0xC6, 0x82, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x40, 0x00, // 81
0xFE, 0x12, 0x32, 0x4E, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, // 82
0x4C, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, // 83
0x02, 0x02, 0xFE, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // 84
0x7E, 0x80, 0x80, 0x80, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, // 85
0x06, 0x38, 0xC0, 0xC0, 0x38, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 86
0x06, 0x38, 0xE0, 0x1E, 0xE0, 0x38, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 87
0x82, 0x46, 0x38, 0x38, 0xC6, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 88
0x02, 0x0C, 0xF0, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // 89
0xC2, 0xA2, 0x92, 0x8A, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, // 90
0xFE, 0x02, 0x40, 0x40, // 91
0x06, 0x38, 0xC0, 0x00, 0x00, 0x00, // 92
0x02, 0xFE, 0x40, 0x40, // 93
0x04, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, // 94
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, // 95
0x01, 0x02, 0x00, 0x00, // 96
0xE0, 0xA8, 0xA8, 0xF8, 0x00, 0x00, 0x00, 0x00, // 97
0xFF, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, // 98
0x70, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, // 99
0x70, 0x88, 0x88, 0xFF, 0x00, 0x00, 0x00, 0x00, // 100
0x70, 0xA8, 0xA8, 0xB0, 0x00, 0x00, 0x00, 0x00, // 101
0x08, 0xFF, 0x09, 0x00, 0x00, 0x00, // 102
0x70, 0x88, 0x88, 0xF8, 0x00, 0x80, 0x80, 0x40, // 103
0xFF, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, // 104
0xFA, 0x00, // 105
0x00, 0xFA, 0x80, 0xC0, // 106
0xFF, 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00, // 107
0xFF, 0x00, // 108
0xF8, 0x08, 0x08, 0xF8, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 109
0xF8, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, // 110
0x70, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, // 111
0xF8, 0x88, 0x88, 0x70, 0xC0, 0x00, 0x00, 0x00, // 112
0x70, 0x88, 0x88, 0xF8, 0x00, 0x00, 0x00, 0xC0, // 113
0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, // 114
0x98, 0xA8, 0xE8, 0x00, 0x00, 0x00, // 115
0x08, 0xFC, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, // 116
0xF8, 0x80, 0x80, 0xF8, 0x00, 0x00, 0x00, 0x00, // 117
0x18, 0x60, 0x80, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // 118
0x38, 0xC0, 0x30, 0x08, 0x30, 0xC0, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 119
0x88, 0x50, 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, // 120
0x18, 0x60, 0x80, 0x60, 0x18, 0x80, 0x80, 0x40, 0x00, 0x00, // 121
0x88, 0xC8, 0xA8, 0x98, 0x00, 0x00, 0x00, 0x00, // 122
0x10, 0xEE, 0x02, 0x00, 0x40, 0x40, // 123
0xFE, 0xC0, // 124
0x02, 0xEE, 0x10, 0x40, 0x40, 0x00, // 125
0x20, 0x10, 0x10, 0x20, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 126
0xFC, 0x04, 0x04, 0x04, 0xFC, 0xC0, 0x80, 0x80, 0x80, 0xC0 // 127
};
#endif

View File

@ -0,0 +1,166 @@
/*
*
* DejaVuSansBold9
*
* created with FontCreator
* written by F. Maximilian Thiele
*
* http://www.apetech.de/fontCreator
* me@apetech.de
*
* File Name : DejaVuSansBold9.h
* Date : 28.05.2012
* Font size in bytes : 4662
* Font width : 10
* Font height : 10
* Font first char : 32
* Font last char : 128
* Font used chars : 96
*
* The font data are defined as
*
* struct _FONT_ {
* uint16_t font_Size_in_Bytes_over_all_included_Size_it_self;
* uint8_t font_Width_in_Pixel_for_fixed_drawing;
* uint8_t font_Height_in_Pixel_for_all_characters;
* unit8_t font_First_Char;
* uint8_t font_Char_Count;
*
* uint8_t font_Char_Widths[font_Last_Char - font_First_Char +1];
* // for each character the separate width in pixels,
* // characters < 128 have an implicit virtual right empty row
*
* uint8_t font_data[];
* // bit field of all characters
*/
#include <inttypes.h>
#include <avr/pgmspace.h>
#ifndef DEJAVUSANSBOLD9_H
#define DEJAVUSANSBOLD9_H
#define DEJAVUSANSBOLD9_WIDTH 10
#define DEJAVUSANSBOLD9_HEIGHT 10
static uint8_t DejaVuSansBold9[] PROGMEM = {
0x12, 0x36, // size
0x0A, // width
0x0A, // height
0x20, // first char
0x60, // char count
// char widths
0x00, 0x02, 0x03, 0x06, 0x05, 0x08, 0x07, 0x01, 0x03, 0x03,
0x05, 0x05, 0x02, 0x03, 0x02, 0x03, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x02, 0x02, 0x06, 0x06,
0x06, 0x04, 0x08, 0x07, 0x05, 0x06, 0x06, 0x05, 0x05, 0x06,
0x07, 0x02, 0x03, 0x06, 0x05, 0x07, 0x06, 0x06, 0x05, 0x06,
0x06, 0x05, 0x06, 0x06, 0x07, 0x09, 0x07, 0x06, 0x06, 0x03,
0x03, 0x03, 0x04, 0x05, 0x02, 0x05, 0x05, 0x04, 0x05, 0x05,
0x04, 0x05, 0x05, 0x02, 0x03, 0x05, 0x02, 0x08, 0x05, 0x05,
0x05, 0x05, 0x03, 0x04, 0x03, 0x05, 0x06, 0x08, 0x06, 0x06,
0x04, 0x04, 0x01, 0x04, 0x06, 0x05,
// font data
0xDE, 0xDE, 0x00, 0x00, // 33
0x06, 0x00, 0x06, 0x00, 0x00, 0x00, // 34
0x28, 0xF8, 0x2E, 0xF8, 0x2E, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 35
0x98, 0xB4, 0xFE, 0xB4, 0x64, 0x00, 0x00, 0x40, 0x00, 0x00, // 36
0x0C, 0x12, 0xD2, 0x7C, 0x78, 0x96, 0x90, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 37
0x60, 0xFC, 0x9E, 0xB2, 0x62, 0xE0, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 38
0x06, 0x00, // 39
0x3C, 0xFF, 0x81, 0x00, 0x00, 0x00, // 40
0x81, 0xFF, 0x3C, 0x00, 0x00, 0x00, // 41
0x14, 0x18, 0x3E, 0x18, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, // 42
0x20, 0x20, 0xF8, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, // 43
0xC0, 0xC0, 0x40, 0x00, // 44
0x20, 0x20, 0x20, 0x00, 0x00, 0x00, // 45
0xC0, 0xC0, 0x00, 0x00, // 46
0xC0, 0x38, 0x06, 0x00, 0x00, 0x00, // 47
0x7C, 0xFE, 0x82, 0xFE, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, // 48
0x82, 0x82, 0xFE, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, // 49
0xC2, 0xE2, 0xB2, 0x9E, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, // 50
0x82, 0x92, 0x92, 0xFE, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, // 51
0x60, 0x58, 0x44, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, // 52
0x9E, 0x9E, 0x92, 0xF2, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, // 53
0x7C, 0xFE, 0x96, 0xF2, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, // 54
0x82, 0xE2, 0x7A, 0x1E, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, // 55
0x6C, 0xEE, 0x92, 0xEE, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, // 56
0x8C, 0x9E, 0xD2, 0xFE, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, // 57
0xD8, 0xD8, 0x00, 0x00, // 58
0xD8, 0xD8, 0x40, 0x00, // 59
0x20, 0x50, 0x50, 0x50, 0xD8, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 60
0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 61
0x88, 0xD8, 0x50, 0x50, 0x50, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 62
0x02, 0xDA, 0xDE, 0x0E, 0x00, 0x00, 0x00, 0x00, // 63
0x78, 0x84, 0x32, 0x4A, 0x4A, 0xFA, 0x44, 0x38, 0x00, 0x00, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, // 64
0x80, 0xF0, 0x7E, 0x4E, 0x7E, 0xF0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 65
0xFE, 0xFE, 0x92, 0xFE, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, // 66
0x38, 0x7C, 0xC6, 0x82, 0x82, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 67
0xFE, 0xFE, 0x82, 0x82, 0xFE, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 68
0xFE, 0xFE, 0x92, 0x92, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, // 69
0xFE, 0xFE, 0x12, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, // 70
0x78, 0xFC, 0x86, 0x92, 0xF2, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 71
0xFE, 0xFE, 0x10, 0x10, 0x10, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 72
0xFE, 0xFE, 0x00, 0x00, // 73
0x00, 0xFE, 0xFE, 0x80, 0xC0, 0x40, // 74
0xFE, 0xFE, 0x38, 0x6C, 0xC6, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 75
0xFE, 0xFE, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, // 76
0xFE, 0xFE, 0x0C, 0x30, 0x0C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 77
0xFE, 0xFE, 0x0C, 0x30, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 78
0x7C, 0xFE, 0x82, 0x82, 0xFE, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 79
0xFE, 0xFE, 0x12, 0x1E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, // 80
0x7C, 0xFE, 0x82, 0x82, 0xFE, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, // 81
0xFE, 0xFE, 0x12, 0x7E, 0xEC, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 82
0xCC, 0x9E, 0x92, 0xF2, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, // 83
0x02, 0x02, 0xFE, 0xFE, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 84
0x7E, 0xFE, 0x80, 0x80, 0xFE, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 85
0x02, 0x1E, 0xF8, 0xC0, 0xF8, 0x1E, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 86
0x0E, 0xFE, 0xE0, 0x3C, 0x06, 0x3C, 0xE0, 0xFE, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 87
0x82, 0xC6, 0x7C, 0x10, 0x7C, 0xC6, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 88
0x06, 0x0E, 0xF8, 0xF8, 0x0E, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 89
0xC2, 0xE2, 0xB2, 0x9A, 0x8E, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 90
0xFF, 0xFF, 0x81, 0x00, 0x00, 0x00, // 91
0x06, 0x38, 0xC0, 0x00, 0x00, 0x00, // 92
0x81, 0xFF, 0xFF, 0x00, 0x00, 0x00, // 93
0x04, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, // 94
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, // 95
0x01, 0x02, 0x00, 0x00, // 96
0xE8, 0xE8, 0xA8, 0xF8, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, // 97
0xFF, 0xFF, 0x88, 0xF8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, // 98
0x70, 0xF8, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, // 99
0x70, 0xF8, 0x88, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, // 100
0x70, 0xF8, 0xA8, 0xB8, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, // 101
0x08, 0xFE, 0xFF, 0x09, 0x00, 0x00, 0x00, 0x00, // 102
0x70, 0xF8, 0x88, 0xF8, 0xF8, 0x00, 0x80, 0x80, 0xC0, 0x40, // 103
0xFF, 0xFF, 0x08, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, // 104
0xFB, 0xFB, 0x00, 0x00, // 105
0x00, 0xFB, 0xFB, 0x80, 0xC0, 0x40, // 106
0xFF, 0xFF, 0x70, 0xD8, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, // 107
0xFF, 0xFF, 0x00, 0x00, // 108
0xF8, 0xF8, 0x08, 0xF8, 0xF8, 0x08, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 109
0xF8, 0xF8, 0x08, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, // 110
0x70, 0xF8, 0x88, 0xF8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, // 111
0xF8, 0xF8, 0x88, 0xF8, 0x70, 0xC0, 0xC0, 0x00, 0x00, 0x00, // 112
0x70, 0xF8, 0x88, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0xC0, 0xC0, // 113
0xF8, 0xF8, 0x08, 0x00, 0x00, 0x00, // 114
0xB0, 0xB8, 0xE8, 0x68, 0x00, 0x00, 0x00, 0x00, // 115
0xFC, 0xFC, 0x88, 0x00, 0x00, 0x00, // 116
0xF8, 0xF8, 0x80, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, // 117
0x18, 0x78, 0xC0, 0xC0, 0x78, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 118
0x18, 0xF8, 0xE0, 0x38, 0x38, 0xE0, 0xF8, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 119
0x88, 0xD8, 0x70, 0x70, 0xD8, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 120
0x08, 0x38, 0xE0, 0xE0, 0x38, 0x08, 0x00, 0x80, 0xC0, 0x00, 0x00, 0x00, // 121
0xC8, 0xE8, 0xB8, 0x98, 0x00, 0x00, 0x00, 0x00, // 122
0x08, 0xFF, 0xF7, 0x81, 0x00, 0x00, 0x00, 0x00, // 123
0xFE, 0xC0, // 124
0x81, 0xF7, 0xFF, 0x08, 0x00, 0x00, 0x00, 0x00, // 125
0x20, 0x10, 0x10, 0x20, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 126
0xFC, 0x04, 0x04, 0x04, 0xFC, 0xC0, 0x80, 0x80, 0x80, 0xC0 // 127
};
#endif

View File

@ -0,0 +1,166 @@
/*
*
* DejaVuSansItalic9
*
* created with FontCreator
* written by F. Maximilian Thiele
*
* http://www.apetech.de/fontCreator
* me@apetech.de
*
* File Name : DejaVuSansItalic9.h
* Date : 28.05.2012
* Font size in bytes : 4572
* Font width : 10
* Font height : 10
* Font first char : 32
* Font last char : 128
* Font used chars : 96
*
* The font data are defined as
*
* struct _FONT_ {
* uint16_t font_Size_in_Bytes_over_all_included_Size_it_self;
* uint8_t font_Width_in_Pixel_for_fixed_drawing;
* uint8_t font_Height_in_Pixel_for_all_characters;
* unit8_t font_First_Char;
* uint8_t font_Char_Count;
*
* uint8_t font_Char_Widths[font_Last_Char - font_First_Char +1];
* // for each character the separate width in pixels,
* // characters < 128 have an implicit virtual right empty row
*
* uint8_t font_data[];
* // bit field of all characters
*/
#include <inttypes.h>
#include <avr/pgmspace.h>
#ifndef DEJAVUSANSITALIC9_H
#define DEJAVUSANSITALIC9_H
#define DEJAVUSANSITALIC9_WIDTH 10
#define DEJAVUSANSITALIC9_HEIGHT 10
static uint8_t DejaVuSansItalic9[] PROGMEM = {
0x11, 0xDC, // size
0x0A, // width
0x0A, // height
0x20, // first char
0x60, // char count
// char widths
0x00, 0x03, 0x03, 0x06, 0x04, 0x07, 0x06, 0x01, 0x03, 0x03,
0x05, 0x05, 0x01, 0x03, 0x01, 0x03, 0x05, 0x04, 0x05, 0x05,
0x05, 0x05, 0x04, 0x05, 0x05, 0x05, 0x02, 0x02, 0x06, 0x06,
0x06, 0x04, 0x08, 0x06, 0x05, 0x06, 0x06, 0x05, 0x05, 0x06,
0x07, 0x03, 0x03, 0x06, 0x04, 0x08, 0x07, 0x06, 0x05, 0x06,
0x05, 0x06, 0x05, 0x06, 0x05, 0x08, 0x06, 0x05, 0x06, 0x04,
0x02, 0x04, 0x04, 0x05, 0x02, 0x05, 0x05, 0x04, 0x06, 0x05,
0x03, 0x05, 0x05, 0x03, 0x03, 0x05, 0x03, 0x08, 0x05, 0x05,
0x05, 0x05, 0x04, 0x04, 0x03, 0x05, 0x05, 0x07, 0x05, 0x05,
0x05, 0x04, 0x01, 0x05, 0x06, 0x05,
// font data
0x80, 0x38, 0x06, 0x00, 0x00, 0x00, // 33
0x06, 0x00, 0x06, 0x00, 0x00, 0x00, // 34
0x20, 0xF8, 0x2E, 0xF8, 0x2E, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 35
0x98, 0xDC, 0xA6, 0x64, 0x00, 0x40, 0x00, 0x00, // 36
0x1C, 0xD2, 0x2E, 0x10, 0xEC, 0x92, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 37
0x60, 0x9C, 0x92, 0xA2, 0x64, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 38
0x06, 0x00, // 39
0xF8, 0x06, 0x01, 0x00, 0x00, 0x00, // 40
0x80, 0x61, 0x1E, 0x00, 0x00, 0x00, // 41
0x12, 0x0C, 0x1E, 0x0C, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, // 42
0x20, 0x20, 0xF8, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, // 43
0x80, 0x00, // 44
0x20, 0x20, 0x20, 0x00, 0x00, 0x00, // 45
0x80, 0x00, // 46
0x60, 0x30, 0x0C, 0x00, 0x00, 0x00, // 47
0x78, 0x84, 0x82, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, // 48
0x80, 0x82, 0xF2, 0x8E, 0x00, 0x00, 0x00, 0x00, // 49
0x80, 0xC4, 0xA2, 0x92, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, // 50
0x40, 0x84, 0x92, 0x92, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, // 51
0x40, 0x70, 0xC8, 0x7C, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, // 52
0x80, 0x9C, 0x92, 0x92, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, // 53
0x78, 0x94, 0x92, 0x72, 0x00, 0x00, 0x00, 0x00, // 54
0x82, 0x42, 0x32, 0x0E, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // 55
0x60, 0xAC, 0x92, 0x92, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, // 56
0x80, 0x9C, 0x92, 0x72, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, // 57
0x80, 0x08, 0x00, 0x00, // 58
0x80, 0x08, 0x00, 0x00, // 59
0x20, 0x20, 0x50, 0x50, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 60
0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 61
0x88, 0x50, 0x50, 0x50, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 62
0x82, 0x32, 0x0A, 0x06, 0x00, 0x00, 0x00, 0x00, // 63
0xE0, 0x18, 0xE8, 0x94, 0x94, 0xF4, 0xCC, 0x78, 0x40, 0xC0, 0x80, 0x80, 0x80, 0x40, 0x00, 0x00, // 64
0x80, 0x60, 0x38, 0x24, 0x3E, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 65
0xC0, 0xB8, 0x96, 0x92, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, // 66
0x78, 0x84, 0x82, 0x82, 0x82, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 67
0xC0, 0xB8, 0x86, 0x82, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 68
0xC0, 0xB8, 0x96, 0x92, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // 69
0xC0, 0x38, 0x16, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // 70
0x78, 0x84, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 71
0xC0, 0x38, 0x16, 0x10, 0xD0, 0x38, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 72
0xC0, 0x38, 0x06, 0x00, 0x00, 0x00, // 73
0x00, 0xF0, 0x0E, 0xC0, 0x00, 0x00, // 74
0xC0, 0x38, 0x16, 0x68, 0x84, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 75
0xC0, 0xB8, 0x86, 0x80, 0x00, 0x00, 0x00, 0x00, // 76
0xC0, 0x38, 0x06, 0x38, 0x10, 0xC8, 0x3C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 77
0xC0, 0x38, 0x06, 0x38, 0xC0, 0x38, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 78
0x78, 0x84, 0x82, 0x82, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 79
0xC0, 0x38, 0x16, 0x12, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, // 80
0x78, 0x84, 0x82, 0x82, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, // 81
0xC0, 0x38, 0x16, 0x72, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, // 82
0x40, 0x8C, 0x92, 0x92, 0x62, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 83
0x02, 0xC2, 0x3A, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // 84
0x78, 0x86, 0x80, 0x80, 0x78, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 85
0x0E, 0xF0, 0x40, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, // 86
0xFE, 0x60, 0x1C, 0x02, 0xFE, 0x60, 0x1C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 87
0x80, 0x42, 0x2C, 0x10, 0x6C, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 88
0x02, 0xCC, 0x30, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // 89
0x80, 0xC2, 0xA2, 0x92, 0x8A, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 90
0xC0, 0xBC, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, // 91
0x1E, 0xE0, 0x00, 0x00, // 92
0x80, 0xC0, 0x3D, 0x03, 0x00, 0x00, 0x00, 0x00, // 93
0x04, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, // 94
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, // 95
0x01, 0x02, 0x00, 0x00, // 96
0xC0, 0xA8, 0xA8, 0xE8, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, // 97
0xC0, 0x7C, 0x93, 0x88, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, // 98
0xF0, 0x98, 0x88, 0x08, 0x00, 0x00, 0x00, 0x00, // 99
0xF0, 0x98, 0x88, 0xC8, 0x3C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 100
0x70, 0xB8, 0xA8, 0xA8, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, // 101
0xC8, 0x3E, 0x09, 0x00, 0x00, 0x00, // 102
0xF0, 0x98, 0x88, 0xC8, 0x38, 0x80, 0x80, 0x80, 0x40, 0x00, // 103
0xC0, 0x3C, 0x13, 0xC8, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, // 104
0xE0, 0x38, 0x01, 0x00, 0x00, 0x00, // 105
0xC0, 0x38, 0x01, 0xC0, 0x00, 0x00, // 106
0xC0, 0x3C, 0x23, 0xD0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, // 107
0xC0, 0x3C, 0x03, 0x00, 0x00, 0x00, // 108
0xE0, 0x18, 0x08, 0xC8, 0x78, 0x10, 0xC8, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 109
0xE0, 0x38, 0x08, 0xC8, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, // 110
0x70, 0x98, 0x88, 0xC8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, // 111
0xE0, 0x98, 0x88, 0xC8, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, // 112
0xF0, 0x88, 0x88, 0xF0, 0x18, 0x00, 0x00, 0xC0, 0x00, 0x00, // 113
0xE0, 0x38, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, // 114
0x80, 0xB8, 0xA8, 0xE8, 0x00, 0x00, 0x00, 0x00, // 115
0xF8, 0x8C, 0x08, 0x00, 0x00, 0x00, // 116
0xE0, 0x98, 0x80, 0xE0, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, // 117
0x38, 0xC0, 0x60, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, // 118
0xF8, 0x60, 0x10, 0xF8, 0x40, 0x30, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 119
0x80, 0x48, 0x30, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, // 120
0x00, 0xF8, 0x60, 0x10, 0x08, 0x80, 0x40, 0x00, 0x00, 0x00, // 121
0x80, 0xC8, 0xA8, 0x98, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, // 122
0x08, 0xF8, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, // 123
0xFE, 0xC0, // 124
0x80, 0x80, 0x71, 0x0F, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, // 125
0x20, 0x10, 0x10, 0x20, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 126
0xFC, 0x04, 0x04, 0x04, 0xFC, 0xC0, 0x80, 0x80, 0x80, 0xC0 // 127
};
#endif

155
libraries/DMD/Mono5x7.h Normal file
View File

@ -0,0 +1,155 @@
/*
*
* Mono5x7
*
* created with FontCreator
* written by F. Maximilian Thiele
*
* http://www.apetech.de/fontCreator
* me@apetech.de
*
* File Name : Mono5x7.h
* Date : 29.05.2012
* Font size in bytes : 3462
* Font width : 5
* Font height : 7
* Font first char : 32
* Font last char : 128
* Font used chars : 96
*
* The font data are defined as
*
* struct _FONT_ {
* uint16_t font_Size_in_Bytes_over_all_included_Size_it_self;
* uint8_t font_Width_in_Pixel_for_fixed_drawing;
* uint8_t font_Height_in_Pixel_for_all_characters;
* unit8_t font_First_Char;
* uint8_t font_Char_Count;
*
* uint8_t font_Char_Widths[font_Last_Char - font_First_Char +1];
* // for each character the separate width in pixels,
* // characters < 128 have an implicit virtual right empty row
*
* uint8_t font_data[];
* // bit field of all characters
*/
#include <inttypes.h>
#include <avr/pgmspace.h>
#ifndef MONO5X7_H
#define MONO5X7_H
#define MONO5X7_WIDTH 5
#define MONO5X7_HEIGHT 7
static uint8_t Mono5x7[] PROGMEM = {
0x00, 0x00, // size
0x05, // width
0x07, // height
0x20, // first char
0x60, // char count
// font data
0x00, 0x00, 0x00, 0x00, 0x00, // 32
0x00, 0x00, 0x5F, 0x00, 0x00, // 33
0x00, 0x07, 0x00, 0x07, 0x00, // 34
0x14, 0x7F, 0x14, 0x7F, 0x14, // 35
0x24, 0x2A, 0x7F, 0x2A, 0x12, // 36
0x23, 0x13, 0x08, 0x64, 0x62, // 37
0x36, 0x49, 0x55, 0x22, 0x50, // 38
0x00, 0x05, 0x03, 0x00, 0x00, // 39
0x00, 0x1C, 0x22, 0x41, 0x00, // 40
0x00, 0x41, 0x22, 0x1C, 0x00, // 41
0x14, 0x08, 0x3E, 0x08, 0x14, // 42
0x08, 0x08, 0x3E, 0x08, 0x08, // 43
0x00, 0x50, 0x30, 0x00, 0x00, // 44
0x08, 0x08, 0x08, 0x08, 0x08, // 45
0x00, 0x60, 0x60, 0x00, 0x00, // 46
0x20, 0x10, 0x08, 0x04, 0x02, // 47
0x3E, 0x51, 0x49, 0x45, 0x3E, // 48
0x00, 0x42, 0x7F, 0x40, 0x00, // 49
0x42, 0x61, 0x51, 0x49, 0x46, // 50
0x21, 0x41, 0x45, 0x4B, 0x31, // 51
0x18, 0x14, 0x12, 0x7F, 0x10, // 52
0x27, 0x45, 0x45, 0x45, 0x39, // 53
0x3C, 0x4A, 0x49, 0x49, 0x30, // 54
0x01, 0x71, 0x09, 0x05, 0x03, // 55
0x36, 0x49, 0x49, 0x49, 0x36, // 56
0x06, 0x49, 0x49, 0x29, 0x1E, // 57
0x00, 0x36, 0x36, 0x00, 0x00, // 58
0x00, 0x56, 0x36, 0x00, 0x00, // 59
0x08, 0x14, 0x22, 0x41, 0x00, // 60
0x14, 0x14, 0x14, 0x14, 0x14, // 61
0x00, 0x41, 0x22, 0x14, 0x08, // 62
0x02, 0x01, 0x51, 0x09, 0x06, // 63
0x32, 0x49, 0x79, 0x41, 0x3E, // 64
0x7E, 0x11, 0x11, 0x11, 0x7E, // 65
0x7F, 0x49, 0x49, 0x49, 0x36, // 66
0x3E, 0x41, 0x41, 0x41, 0x22, // 67
0x7F, 0x41, 0x41, 0x22, 0x1C, // 68
0x7F, 0x49, 0x49, 0x49, 0x41, // 69
0x7F, 0x09, 0x09, 0x09, 0x01, // 70
0x3E, 0x41, 0x49, 0x49, 0x78, // 71
0x7F, 0x08, 0x08, 0x08, 0x7F, // 72
0x00, 0x41, 0x7F, 0x41, 0x00, // 73
0x20, 0x40, 0x41, 0x3F, 0x01, // 74
0x7F, 0x08, 0x14, 0x22, 0x41, // 75
0x7F, 0x40, 0x40, 0x40, 0x40, // 76
0x7F, 0x02, 0x0C, 0x02, 0x7F, // 77
0x7F, 0x04, 0x08, 0x10, 0x7F, // 78
0x3E, 0x41, 0x41, 0x41, 0x3E, // 79
0x7F, 0x09, 0x09, 0x09, 0x06, // 80
0x3E, 0x41, 0x51, 0x21, 0x5E, // 81
0x7F, 0x09, 0x19, 0x29, 0x46, // 82
0x46, 0x49, 0x49, 0x49, 0x31, // 83
0x01, 0x01, 0x7F, 0x01, 0x01, // 84
0x3F, 0x40, 0x40, 0x40, 0x3F, // 85
0x1F, 0x20, 0x40, 0x20, 0x1F, // 86
0x3F, 0x40, 0x38, 0x40, 0x3F, // 87
0x63, 0x14, 0x08, 0x14, 0x63, // 88
0x07, 0x08, 0x70, 0x08, 0x07, // 89
0x61, 0x51, 0x49, 0x45, 0x43, // 90
0x00, 0x7F, 0x41, 0x41, 0x00, // 91
0x02, 0x04, 0x08, 0x10, 0x20, // 92
0x00, 0x41, 0x41, 0x7F, 0x00, // 93
0x04, 0x02, 0x01, 0x02, 0x04, // 94
0x40, 0x40, 0x40, 0x40, 0x40, // 95
0x00, 0x02, 0x04, 0x08, 0x00, // 96
0x20, 0x54, 0x54, 0x54, 0x78, // 97
0x7F, 0x48, 0x44, 0x44, 0x38, // 98
0x38, 0x44, 0x44, 0x44, 0x20, // 99
0x38, 0x44, 0x44, 0x48, 0x7F, // 100
0x38, 0x54, 0x54, 0x54, 0x18, // 101
0x08, 0x7E, 0x09, 0x01, 0x02, // 102
0x0C, 0x52, 0x52, 0x52, 0x3E, // 103
0x7F, 0x08, 0x04, 0x04, 0x78, // 104
0x00, 0x44, 0x7D, 0x40, 0x00, // 105
0x20, 0x40, 0x44, 0x3D, 0x00, // 106
0x7F, 0x10, 0x28, 0x44, 0x00, // 107
0x00, 0x41, 0x7F, 0x40, 0x00, // 108
0x7C, 0x04, 0x18, 0x04, 0x78, // 109
0x7C, 0x08, 0x04, 0x04, 0x78, // 110
0x38, 0x44, 0x44, 0x44, 0x38, // 111
0x7C, 0x14, 0x14, 0x14, 0x08, // 112
0x08, 0x14, 0x14, 0x18, 0x7C, // 113
0x7C, 0x08, 0x04, 0x04, 0x08, // 114
0x48, 0x54, 0x54, 0x54, 0x20, // 115
0x04, 0x3F, 0x44, 0x40, 0x00, // 116
0x3C, 0x40, 0x40, 0x20, 0x7C, // 117
0x1C, 0x20, 0x40, 0x20, 0x1C, // 118
0x3C, 0x40, 0x30, 0x40, 0x3C, // 119
0x44, 0x28, 0x10, 0x28, 0x44, // 120
0x0C, 0x50, 0x50, 0x50, 0x3C, // 121
0x44, 0x64, 0x54, 0x4C, 0x44, // 122
0x00, 0x08, 0x36, 0x41, 0x00, // 123
0x00, 0x00, 0x7F, 0x00, 0x00, // 124
0x00, 0x41, 0x36, 0x08, 0x00, // 125
0x08, 0x04, 0x08, 0x10, 0x08, // 126
0x00, 0x00, 0x00, 0x00, 0x00 // 127
};
#endif

36
libraries/DMD/dmd-4x1.fig Normal file
View File

@ -0,0 +1,36 @@
#FIG 3.2 Produced by xfig version 3.2.5b
Landscape
Center
Metric
A4
100.00
Single
-2
1200 2
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
3375 2700 4500 2700 4500 3375 3375 3375 3375 2700
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
4950 2700 6075 2700 6075 3375 4950 3375 4950 2700
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
6525 2700 7650 2700 7650 3375 6525 3375 6525 2700
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
8100 2700 9225 2700 9225 3375 8100 3375 8100 2700
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
4950 3060 4500 3060
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
6525 3060 6075 3060
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
8100 3060 7650 3060
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
9900 3060 9225 3060
2 2 0 1 0 26 50 -1 -1 0.000 1 0 -1 0 0 5
9900 2835 10800 2835 10800 3285 9900 3285 9900 2835
4 0 0 50 -1 0 12 0.0000 4 135 675 10035 3105 Arduino\001
4 0 0 50 -1 0 12 0.0000 4 135 600 8370 3105 Panel 4\001
4 0 0 50 -1 0 12 0.0000 4 135 600 6795 3105 Panel 3\001
4 0 0 50 -1 0 12 0.0000 4 135 600 5220 3105 Panel 2\001
4 0 0 50 -1 0 12 0.0000 4 135 600 3645 3105 Panel 1\001

BIN
libraries/DMD/dmd-4x1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

60
libraries/DMD/dmd-4x2.fig Normal file
View File

@ -0,0 +1,60 @@
#FIG 3.2 Produced by xfig version 3.2.5b
Landscape
Center
Metric
A4
100.00
Single
-2
1200 2
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
9900 3060 9225 3060
2 2 0 1 0 26 50 -1 -1 0.000 1 0 -1 0 0 5
9900 2835 10800 2835 10800 3285 9900 3285 9900 2835
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
3375 1575 4500 1575 4500 2250 3375 2250 3375 1575
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
4950 1575 6075 1575 6075 2250 4950 2250 4950 1575
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
8100 1575 9225 1575 9225 2250 8100 2250 8100 1575
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
7650 1935 8100 1935
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
6525 1575 7650 1575 7650 2250 6525 2250 6525 1575
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
6075 1935 6525 1935
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
4500 1935 4950 1935
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 4
1 1 3.00 60.00 120.00
3375 3015 2925 3015 2925 1890 3375 1890
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
3375 2700 4500 2700 4500 3375 3375 3375 3375 2700
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
4950 2700 6075 2700 6075 3375 4950 3375 4950 2700
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
6525 2700 7650 2700 7650 3375 6525 3375 6525 2700
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
8100 2700 9225 2700 9225 3375 8100 3375 8100 2700
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
4950 3060 4500 3060
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
6525 3060 6075 3060
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
8100 3060 7650 3060
4 0 0 50 -1 0 12 0.0000 4 135 675 10035 3105 Arduino\001
4 0 0 50 -1 0 12 0.0000 4 135 600 8370 3105 Panel 8\001
4 0 0 50 -1 0 12 0.0000 4 135 600 6795 3105 Panel 7\001
4 0 0 50 -1 0 12 0.0000 4 135 600 5220 3105 Panel 6\001
4 0 0 50 -1 0 12 0.0000 4 135 600 3645 3105 Panel 5\001
4 0 0 50 -1 0 12 3.1416 4 135 600 4230 1845 Panel 4\001
4 0 0 50 -1 0 12 3.1416 4 135 600 5805 1845 Panel 3\001
4 0 0 50 -1 0 12 3.1416 4 135 600 7380 1845 Panel 2\001
4 0 0 50 -1 0 12 3.1416 4 135 600 8955 1845 Panel 1\001

BIN
libraries/DMD/dmd-4x2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

84
libraries/DMD/dmd-4x3.fig Normal file
View File

@ -0,0 +1,84 @@
#FIG 3.2 Produced by xfig version 3.2.5b
Landscape
Center
Metric
A4
100.00
Single
-2
1200 2
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
9900 3060 9225 3060
2 2 0 1 0 26 50 -1 -1 0.000 1 0 -1 0 0 5
9900 2835 10800 2835 10800 3285 9900 3285 9900 2835
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
3375 1575 4500 1575 4500 2250 3375 2250 3375 1575
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
4950 1575 6075 1575 6075 2250 4950 2250 4950 1575
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
8100 1575 9225 1575 9225 2250 8100 2250 8100 1575
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
7650 1935 8100 1935
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
6525 1575 7650 1575 7650 2250 6525 2250 6525 1575
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
6075 1935 6525 1935
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
4500 1935 4950 1935
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 4
1 1 3.00 60.00 120.00
3375 3015 2925 3015 2925 1890 3375 1890
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 4
1 1 3.00 60.00 120.00
9225 1890 9675 1890 9675 765 9225 765
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
3375 450 4500 450 4500 1125 3375 1125 3375 450
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
4950 450 6075 450 6075 1125 4950 1125 4950 450
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
6525 450 7650 450 7650 1125 6525 1125 6525 450
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
8100 450 9225 450 9225 1125 8100 1125 8100 450
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
4950 810 4500 810
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
6525 810 6075 810
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
8100 810 7650 810
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
3375 2700 4500 2700 4500 3375 3375 3375 3375 2700
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
4950 2700 6075 2700 6075 3375 4950 3375 4950 2700
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
6525 2700 7650 2700 7650 3375 6525 3375 6525 2700
2 2 0 1 0 7 50 -1 -1 0.000 1 0 -1 0 0 5
8100 2700 9225 2700 9225 3375 8100 3375 8100 2700
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
4950 3060 4500 3060
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
6525 3060 6075 3060
2 1 0 4 11 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 60.00 120.00
8100 3060 7650 3060
4 0 0 50 -1 0 12 0.0000 4 135 675 10035 3105 Arduino\001
4 0 0 50 -1 0 12 0.0000 4 135 600 3645 3105 Panel 9\001
4 0 0 50 -1 0 12 0.0000 4 135 705 5175 3105 Panel 10\001
4 0 0 50 -1 0 12 0.0000 4 135 705 6750 3105 Panel 11\001
4 0 0 50 -1 0 12 0.0000 4 135 705 8325 3105 Panel 12\001
4 0 0 50 -1 0 12 3.1416 4 135 600 8955 1845 Panel 5\001
4 0 0 50 -1 0 12 3.1416 4 135 600 7380 1845 Panel 6\001
4 0 0 50 -1 0 12 3.1416 4 135 600 5805 1845 Panel 7\001
4 0 0 50 -1 0 12 3.1416 4 135 600 4230 1845 Panel 8\001
4 0 0 50 -1 0 12 0.0000 4 135 600 3645 855 Panel 1\001
4 0 0 50 -1 0 12 0.0000 4 135 600 5220 855 Panel 2\001
4 0 0 50 -1 0 12 0.0000 4 135 600 6795 855 Panel 3\001
4 0 0 50 -1 0 12 0.0000 4 135 600 8370 855 Panel 4\001

BIN
libraries/DMD/dmd-4x3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -0,0 +1,53 @@
Description of the interface to the Freetronics Dot Matrix Display (DMD)
========================================================================
Pins:
D6: A - interleave phase select LSB
D7: B - interleave phase select MSB (set the MSB first)
D8: SCLK - this is the "latch" pin that copies all previously transferred
data from the shift register to the actual display. Normally low,
then flip to high and then low again to latch the data.
D9: nOE - Output enable (when low).
D10: Conflict detect (if it goes low, something else is using SPI)
This is the standard SPI SS - Slave select - pin.
D11: R - this is the standard SPI MOSI - Master out, slave in - pin.
D12: MISO - master in, slave out - unused
D13: CLK - standard Serial Clock pin for SPI
Initialisation:
SPI: bit order = MSB-first, data mode = 0, clock divider = 128
(use a smaller clock divider, such as 2, for better performance
when driving multiple displays)
Set A, B, CLK, SCLK, and nOE to LOW outputs
Set R to HIGH output
phase = 0
Every 5ms, do the following to refresh the display:
Send the bytes for 4 interleaved rows based on phase, via SPI:
phase == 0: 0, 4, 8, 12 (actually sent in the order 12, 8, 4, 0)
phase == 1: 1, 5, 9, 13
phase == 2: 2, 6, 10, 14
phase == 3: 3, 7, 11, 15
Then latch the data for the rows as follows:
Set nOE to LOW
Set SCLK to HIGH and then back to LOW
Set A and B to indicate the current phase
Set nOE to HIGH
Finally, increment the phase, wrapping around from 3 to 0
The above code assumes the following memory organisation:
The display is W panels wide and H panels high.
Each panel is 32 pixels wide (4 bytes) and 16 pixels high.
Memory is organised as W * H * 4 bytes for each row, and 16 rows.
That is, the 2D arrangement of panels is flattened into 1D for
clocking the data out.
In addition, a 1 bit in memory is a LED that is *off*.
Other things:
Multiple panels need to be daisy-chained in the order N, ..., 1 with N
plugged into the connector board on the Arduino and 1 at the end of
the daisy-chain. Because the shipped cables are short, multiple rows
can be oriented in alternating order with odd-numbered rows
(counting from 1) upside-down and reversed. More details here:
http://www.adebenham.com/category/arduino/dmd/

View File

@ -0,0 +1,144 @@
/*
This example demonstrates how to use the DMD and related classes to
draw things on a Freetronics Large Dot Matrix Display.
This example is placed into the public domain.
*/
#include <DMD.h>
#include <DejaVuSans9.h>
#include <DejaVuSansBold9.h>
#include <DejaVuSansItalic9.h>
#include <Mono5x7.h>
DMD display;
ISR(TIMER1_OVF_vect)
{
display.refresh();
}
void setup() {
display.enableTimer1();
}
void loop() {
drawShapes();
delay(1000);
drawBricks();
delay(1000);
drawStickFigures();
delay(1000);
drawText();
delay(1000);
drawBoldText();
delay(1000);
drawItalicText();
delay(1000);
drawMonoText();
delay(1000);
drawMarquee();
delay(500);
}
void drawShapes()
{
display.clear();
display.drawCircle(6, 8, 3);
display.drawFilledCircle(16, 8, 3);
display.drawLine(22, 5, 28, 11);
display.drawLine(28, 5, 22, 11);
display.drawRect(0, 0, display.width() - 1, display.height() - 1);
}
void drawBricks()
{
static const uint8_t bricks[] PROGMEM = {
16, 6,
B11111111, B11111111,
B10000000, B10000000,
B10000000, B10000000,
B11111111, B11111111,
B00001000, B00001000,
B00001000, B00001000
};
display.fill(0, 0, display.width(), display.height(), bricks);
}
void drawStickFigures()
{
static const uint8_t stickFigure[] PROGMEM = {
9, 13,
B00111110, B00000000,
B01000001, B00000000,
B01000001, B00000000,
B00111110, B00000000,
B00001000, B00000000,
B00001000, B00000000,
B11111111, B10000000,
B00001000, B00000000,
B00001000, B00000000,
B00010100, B00000000,
B00100010, B00000000,
B01000001, B00000000,
B10000000, B10000000
};
display.clear();
display.drawBitmap(2, 1, stickFigure);
display.drawInvertedBitmap(12, 1, stickFigure);
display.drawBitmap(22, 1, stickFigure);
}
void drawText()
{
display.clear();
display.setFont(DejaVuSans9);
display.drawText(0, 0, "Hello");
display.drawText(9, 8, "World");
}
void drawBoldText()
{
display.clear();
display.setFont(DejaVuSansBold9);
display.drawText(0, 0, "Hello");
display.drawText(4, 8, "World");
}
void drawItalicText()
{
display.clear();
display.setFont(DejaVuSansItalic9);
display.drawText(0, 0, "Hello");
display.drawText(2, 8, "World");
}
void drawMonoText()
{
display.clear();
display.setFont(Mono5x7);
display.drawText(0, 0, "Hello");
display.drawText(3, 8, "World");
}
static const char message[] = "Eat at Joes!";
void drawMarquee()
{
int width = display.width();
display.setFont(DejaVuSans9);
int msgWidth = display.textWidth(message);
int fullScroll = msgWidth + width + 1;
for (int x = 0; x < fullScroll; ++x) {
display.clear();
display.drawText(width - x, 3, message);
delay(50);
}
}

View File

@ -0,0 +1,135 @@
/*
* Copyright (C) 2012 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <DMD.h>
DMD display;
// Running stick figure pictures are loosely based on those from this tutorial:
// http://www.fluidanims.com/FAelite/phpBB3/viewtopic.php?f=10&t=102
byte const run1[] PROGMEM = {
16, 16,
B00000000, B00001100,
B00000000, B00011110,
B00000111, B11111110,
B00001111, B11111110,
B00011100, B11111100,
B00000001, B11111100,
B00000001, B11110000,
B00000011, B11111000,
B00000111, B00011000,
B00001110, B01110000,
B00011100, B01100000,
B00111000, B00000000,
B01110000, B00000000,
B01100000, B00000000,
B01000000, B00000000,
B00000000, B00000000
};
byte const run2[] PROGMEM = {
18, 16,
B00000000, B01110011, B10000000,
B00000000, B11111111, B10000000,
B00000000, B00011111, B10000000,
B00000000, B00111111, B11000000,
B00000000, B01111011, B11000000,
B00000000, B11110011, B10000000,
B00000001, B11100000, B00000000,
B00000011, B11100000, B00000000,
B00000111, B01110000, B00000000,
B01111110, B00111000, B00000000,
B11111100, B00011100, B00000000,
B00000000, B00001110, B00000000,
B00000000, B00000111, B00000000,
B00000000, B00000011, B10000000,
B00000000, B00000001, B00000000,
B00000000, B00000000, B00000000
};
byte const run3[] PROGMEM = {
18, 16,
B00000000, B00110000, B00000000,
B00000000, B01111000, B00000000,
B00000000, B00011111, B00000000,
B00000000, B00011111, B00000000,
B00000000, B00111111, B10000000,
B00000000, B01111111, B11000000,
B00000000, B11100011, B10000000,
B00000001, B11000000, B00000000,
B00000011, B11100000, B00000000,
B11111111, B01110000, B00000000,
B11111110, B00111000, B00000000,
B00000000, B00011000, B00000000,
B00000000, B00011100, B00000000,
B00000000, B00001110, B00000000,
B00000000, B00000100, B00000000,
B00000000, B00000000, B00000000
};
byte const run4[] PROGMEM = {
16, 16,
B00000001, B11100000,
B00000011, B11111100,
B00000000, B00111110,
B00000000, B01111110,
B00000000, B11111100,
B00000001, B10011111,
B00000011, B00001110,
B00000011, B00000000,
B00000011, B10000000,
B11111111, B10000000,
B11111000, B11000000,
B00000001, B11000000,
B00000011, B10000000,
B00000111, B00000000,
B00000110, B00000000,
B00000100, B00000000
};
const prog_uint8_t *frames[] = {
run1,
run2,
run3,
run4
};
#define NUM_FRAMES (sizeof(frames) / sizeof(frames[0]))
#define ADVANCE_MS (1000 / NUM_FRAMES)
unsigned int frame = 0;
unsigned long lastFrame;
void setup() {
display.drawBitmap(8, 0, run1);
lastFrame = millis();
}
void loop() {
if ((millis() - lastFrame) >= ADVANCE_MS) {
frame = (frame + 1) % NUM_FRAMES;
display.clear();
int x = (32 - pgm_read_byte(frames[frame])) / 2;
display.drawBitmap(x, 0, frames[frame]);
lastFrame += ADVANCE_MS;
}
display.loop();
}

View File

@ -0,0 +1,43 @@
DMD KEYWORD1
Bitmap KEYWORD1
doubleBuffer KEYWORD2
setDoubleBuffer KEYWORD2
swapBuffers KEYWORD2
swapBuffersAndCopy KEYWORD2
refresh KEYWORD2
enableTimer1 KEYWORD2
disableTimer1 KEYWORD2
isValid KEYWORD2
width KEYWORD2
height KEYWORD2
stride KEYWORD2
bitsPerPixel KEYWORD2
clear KEYWORD2
pixel KEYWORD2
setPixel KEYWORD2
drawLine KEYWORD2
drawRect KEYWORD2
drawFilledRect KEYWORD2
drawCircle KEYWORD2
drawFilledCircle KEYWORD2
drawBitmap KEYWORD2
drawInvertedBitmap KEYWORD2
font KEYWORD2
setFont KEYWORD2
textColor KEYWORD2
setTextColor KEYWORD2
drawText KEYWORD2
drawChar KEYWORD2
charWidth KEYWORD2
textWidth KEYWORD2
textHeight KEYWORD2
copy KEYWORD2
fill KEYWORD2
scroll KEYWORD2
invert KEYWORD2
Black LITERAL1
White LITERAL1
NoFill LITERAL1