feat: 全量同步 254 个常用的 Arduino 扩展库文件
This commit is contained in:
@@ -0,0 +1,660 @@
|
||||
/*
|
||||
MD_MAXPanel - Library for MAX7219/7221 LED Panel
|
||||
|
||||
See header file for comments
|
||||
|
||||
This file contains class and hardware related methods.
|
||||
|
||||
Copyright (C) 2018 Marco Colli. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
#include "MD_MAXPanel.h"
|
||||
#include "MD_MAXPanel_lib.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief Implements class graphics methods
|
||||
*/
|
||||
|
||||
MD_MAXPanel::MD_MAXPanel(MD_MAX72XX::moduleType_t mod, uint8_t dataPin, uint8_t clkPin, uint8_t csPin, uint8_t xDevices, uint8_t yDevices) :
|
||||
_xDevices(xDevices), _yDevices(yDevices), _rotatedDisplay(false)
|
||||
{
|
||||
_D = new MD_MAX72XX(mod, dataPin, clkPin, csPin, xDevices*yDevices);
|
||||
_killOnDestruct = true;
|
||||
}
|
||||
|
||||
MD_MAXPanel::MD_MAXPanel(MD_MAX72XX::moduleType_t mod, uint8_t csPin, uint8_t xDevices, uint8_t yDevices) :
|
||||
_xDevices(xDevices), _yDevices(yDevices), _rotatedDisplay(false)
|
||||
{
|
||||
_D = new MD_MAX72XX(mod, csPin, xDevices*yDevices);
|
||||
_killOnDestruct = true;
|
||||
}
|
||||
|
||||
MD_MAXPanel::MD_MAXPanel(MD_MAX72XX *D, uint8_t xDevices, uint8_t yDevices) :
|
||||
_xDevices(xDevices), _yDevices(yDevices), _rotatedDisplay(false)
|
||||
{
|
||||
_D = D;
|
||||
_killOnDestruct = false;
|
||||
}
|
||||
|
||||
void MD_MAXPanel::begin(void)
|
||||
{
|
||||
_D->begin();
|
||||
_charSpacing = CHAR_SPACING_DEFAULT;
|
||||
_updateEnabled = true;
|
||||
}
|
||||
|
||||
MD_MAXPanel::~MD_MAXPanel(void)
|
||||
{
|
||||
if (_killOnDestruct) delete _D;
|
||||
}
|
||||
|
||||
uint16_t MD_MAXPanel::getXMax(void)
|
||||
{
|
||||
uint16_t m;
|
||||
|
||||
if (_rotatedDisplay)
|
||||
m = (_yDevices * ROW_SIZE) - 1;
|
||||
else
|
||||
m = (_xDevices * COL_SIZE) - 1;
|
||||
|
||||
return(m);
|
||||
}
|
||||
|
||||
uint16_t MD_MAXPanel::getYMax(void)
|
||||
{
|
||||
uint16_t m;
|
||||
|
||||
if (_rotatedDisplay)
|
||||
m = (_xDevices * COL_SIZE) - 1;
|
||||
else
|
||||
m = (_yDevices * ROW_SIZE) - 1;
|
||||
|
||||
return(m);
|
||||
}
|
||||
|
||||
bool MD_MAXPanel::drawHLine(uint16_t y, uint16_t x1, uint16_t x2, bool state)
|
||||
// draw a horizontal line at row y between columns x1 and x2 inclusive
|
||||
{
|
||||
bool b = true;
|
||||
|
||||
_D->control(MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);
|
||||
|
||||
if (x1 > x2) // swap x1/x2
|
||||
{
|
||||
uint16_t t = x1;
|
||||
x1 = x2;
|
||||
x2 = t;
|
||||
}
|
||||
|
||||
for (uint16_t i = x1; i <= x2; i++)
|
||||
b &= setPoint(i, y, state);
|
||||
|
||||
update(_updateEnabled);
|
||||
|
||||
return(b);
|
||||
}
|
||||
|
||||
bool MD_MAXPanel::drawVLine(uint16_t x, uint16_t y1, uint16_t y2, bool state)
|
||||
// draw a vertical line at column x between rows y1 and y2 inclusive
|
||||
{
|
||||
bool b = true;
|
||||
|
||||
_D->control(MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);
|
||||
|
||||
if (y1 > y2) // swap y1/y2
|
||||
{
|
||||
uint8_t t = y1;
|
||||
y1 = y2;
|
||||
y2 = t;
|
||||
}
|
||||
|
||||
for (uint8_t i = y1; i <= y2; i++)
|
||||
b &= setPoint(x, i, state);
|
||||
|
||||
update(_updateEnabled);
|
||||
|
||||
return(b);
|
||||
}
|
||||
|
||||
bool MD_MAXPanel::drawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool state)
|
||||
// draw an arbitrary line between two points using Bresentham's line algorithm
|
||||
// Bresentham's line algorithm at https://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#C
|
||||
{
|
||||
bool b = true;
|
||||
|
||||
_D->control(MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);
|
||||
|
||||
PRINT("\n\nLine from ", x1); PRINT(",", y1);
|
||||
PRINT(" to ", x2); PRINT(",", y2);
|
||||
|
||||
if (x1 > x2) // swap direction for line
|
||||
{
|
||||
uint16_t t;
|
||||
|
||||
t = x1; x1 = x2; x2 = t;
|
||||
t = y1; y1 = y2; y2 = t;
|
||||
// PRINTS(" SWAP X");
|
||||
}
|
||||
|
||||
// PRINT("\nPlotting from ", x1); PRINT(",", y1);
|
||||
// PRINT(" to ", x2); PRINT(",", y2);
|
||||
|
||||
int16_t dx = x2 - x1;
|
||||
int16_t sx = 1;
|
||||
int16_t dy = y2 - y1;
|
||||
if (dy < 0) dy = -dy;
|
||||
int16_t sy = y1 < y2 ? 1 : -1;
|
||||
int16_t err = (dx > dy ? dx : -dy) / 2;
|
||||
int16_t e2;
|
||||
|
||||
// PRINT("\ndx=", dx);
|
||||
// PRINT(" dy=", dy);
|
||||
// PRINT(" ystep=", sy);
|
||||
// PRINT(" xstep=", sx);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// PRINT("\nerror=", err);
|
||||
// PRINT(" [", x1); PRINT(",", y1); PRINTS("]");
|
||||
|
||||
b &= setPoint(x1, y1, state);
|
||||
if (x1 == x2 && y1 == y2) break;
|
||||
e2 = err;
|
||||
if (e2 >-dx) { err -= dy; x1 += sx; }
|
||||
if (e2 < dy) { err += dx; y1 += sy; }
|
||||
}
|
||||
|
||||
update(_updateEnabled);
|
||||
|
||||
return(b);
|
||||
}
|
||||
|
||||
bool MD_MAXPanel::drawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool state)
|
||||
// draw a rectangle given the 2 diagonal vertices
|
||||
{
|
||||
bool b = true;
|
||||
bool u = _updateEnabled;
|
||||
|
||||
_D->control(MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);
|
||||
update(false);
|
||||
|
||||
b &= drawHLine(y1, x1, x2, state);
|
||||
b &= drawHLine(y2, x1, x2, state);
|
||||
b &= drawVLine(x1, y1, y2, state);
|
||||
b &= drawVLine(x2, y1, y2, state);
|
||||
|
||||
update(u);
|
||||
|
||||
return(b);
|
||||
}
|
||||
|
||||
bool MD_MAXPanel::drawFillRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool state)
|
||||
{
|
||||
bool b = true;
|
||||
bool u = _updateEnabled;
|
||||
|
||||
_D->control(MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);
|
||||
update(false);
|
||||
|
||||
for (uint8_t i = x1; i <= x2; i++)
|
||||
drawVLine(i, y1, y2, state);
|
||||
|
||||
update(u);
|
||||
|
||||
return(b);
|
||||
};
|
||||
|
||||
bool MD_MAXPanel::drawQuadrilateral(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t x4, uint16_t y4, bool state)
|
||||
// draw a arbitrary quadrilateral given the 4 corner vertices
|
||||
{
|
||||
bool b = true;
|
||||
bool u = _updateEnabled;
|
||||
|
||||
_D->control(MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);
|
||||
update(false);
|
||||
|
||||
b &= drawLine(x1, y1, x2, y2, state);
|
||||
b &= drawLine(x2, y2, x3, y3, state);
|
||||
b &= drawLine(x3, y3, x4, y4, state);
|
||||
b &= drawLine(x4, y4, x1, y1, state);
|
||||
|
||||
update(u);
|
||||
|
||||
return(b);
|
||||
}
|
||||
|
||||
bool MD_MAXPanel::drawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, bool state)
|
||||
// draw an arbitrary triangle given the 3 corner vertices
|
||||
{
|
||||
bool b = true;
|
||||
bool u = _updateEnabled;
|
||||
|
||||
_D->control(MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);
|
||||
update(false);
|
||||
|
||||
b &= drawLine(x1, y1, x2, y2, state);
|
||||
b &= drawLine(x2, y2, x3, y3, state);
|
||||
b &= drawLine(x3, y3, x1, y1, state);
|
||||
|
||||
update(u);
|
||||
|
||||
return(b);
|
||||
}
|
||||
|
||||
/*
|
||||
bool MD_MAXPanel::drawFillTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, bool state)
|
||||
// draw an arbitrary filled triangle given the 3 corner vertices
|
||||
// Uses slope method, originally from Adafruit Industries
|
||||
{
|
||||
#define SWAP(a, b) { uint16_t t = a; a = b; b = t; }
|
||||
|
||||
uint8_t a, b, y, last;
|
||||
bool r = true;
|
||||
bool u = _updateEnabled;
|
||||
|
||||
_D->control(MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);
|
||||
update(false);
|
||||
|
||||
// Sort coordinates by Y order (y3 >= y2 >= y1)
|
||||
if (y1 > y2) { SWAP(y1, y2); SWAP(x1, x2); }
|
||||
if (y2 > y3) { SWAP(y3, y2); SWAP(x3, x2); }
|
||||
if (y1 > y2) { SWAP(y1, y2); SWAP(x1, x2); }
|
||||
|
||||
if (y1 == y3) // All in same line
|
||||
{
|
||||
a = b = x1;
|
||||
if (x2 < a) a = x2;
|
||||
else if (x2 > b) b = x2;
|
||||
|
||||
if (x3 < a) a = x3;
|
||||
else if (x3 > b) b = x3;
|
||||
|
||||
r &= drawHLine(y1, a, b, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
int8_t dx12 = x2 - x1;
|
||||
int8_t dy12 = y2 - y1;
|
||||
int8_t dx13 = x3 - x1;
|
||||
int8_t dy13 = y3 - y1;
|
||||
int8_t dx23 = x3 - x2;
|
||||
int8_t dy23 = y3 - y2;
|
||||
int16_t sa = 0, sb = 0;
|
||||
|
||||
// For upper part of triangle, find scanline crossings for segment
|
||||
// 1-2 and 1-3. If y2=y3 (flat-bottomed triangle), the scanline y
|
||||
// is included here (and second loop will be skipped, avoiding a /0
|
||||
// error there), otherwise scanline y2 is skipped here and handle
|
||||
// in the second loop...which also avoids a /0 error here if y1=y
|
||||
// (flat-topped triangle)
|
||||
if (y2 == y3) last = y2; // Include y2 scanline
|
||||
else last = y2 - 1; // Skip it
|
||||
|
||||
for (y = y1; y <= last; y++)
|
||||
{
|
||||
a = x1 + sa / dy12;
|
||||
b = x1 + sb / dy13;
|
||||
sa += dx12;
|
||||
sb += dx13;
|
||||
// longhand a = x1 + (x2 - x1) * (y - y1) / (y2 - y1)
|
||||
// b = x0 + (x3 - x1) * (y - y1) / (y3 - y1)
|
||||
r &= drawHLine(y, a, b, state);
|
||||
}
|
||||
|
||||
// For lower part of triangle, find scanline crossings for segment
|
||||
// 1-3 and 2-3. This loop is skipped if y2=y3
|
||||
sa = dx23 * (y - y2);
|
||||
sb = dx13 * (y - y1);
|
||||
for (; y <= y3; y++)
|
||||
{
|
||||
a = x2 + sa / dy23;
|
||||
b = x1 + sb / dy13;
|
||||
sa += dx23;
|
||||
sb += dx13;
|
||||
// longhand a = x2 + (x3 - x2) * (y - y2) / (y3 - y2)
|
||||
// b = x1 + (x2 - x1) * (y - y1) / (y3 - y1)
|
||||
r &= drawHLine(y, a, b, state);
|
||||
}
|
||||
}
|
||||
|
||||
update(u);
|
||||
|
||||
return(r);
|
||||
}
|
||||
*/
|
||||
|
||||
bool MD_MAXPanel::drawFillTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, bool state)
|
||||
// Fill a triangle - Bresenham method
|
||||
// Original from http://www.sunshine2k.de/coding/java/TriangleRasterization/TriangleRasterization.html
|
||||
{
|
||||
#define SWAP(a, b) { uint16_t t = a; a = b; b = t; }
|
||||
|
||||
uint8_t t1x, t2x, y, minx, maxx, t1xp, t2xp;
|
||||
bool changed1 = false;
|
||||
bool changed2 = false;
|
||||
int8_t signx1, signx2, dx1, dy1, dx2, dy2;
|
||||
uint8_t e1, e2;
|
||||
bool b = true;
|
||||
bool u = _updateEnabled;
|
||||
|
||||
_D->control(MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);
|
||||
update(false);
|
||||
|
||||
// Sort vertices
|
||||
if (y1>y2) { SWAP(y1, y2); SWAP(x1, x2); }
|
||||
if (y1>y3) { SWAP(y1, y3); SWAP(x1, x3); }
|
||||
if (y2>y3) { SWAP(y2, y3); SWAP(x2, x3); }
|
||||
|
||||
t1x = t2x = x1; y = y1; // Starting points
|
||||
|
||||
dx1 = (int8_t)(x2 - x1);
|
||||
if (dx1<0) { dx1 = -dx1; signx1 = -1; }
|
||||
else signx1 = 1;
|
||||
dy1 = (int8_t)(y2 - y1);
|
||||
|
||||
dx2 = (int8_t)(x3 - x1);
|
||||
if (dx2<0) { dx2 = -dx2; signx2 = -1; }
|
||||
else signx2 = 1;
|
||||
dy2 = (int8_t)(y3 - y1);
|
||||
|
||||
if (dy1 > dx1) // swap values
|
||||
{
|
||||
SWAP(dx1, dy1);
|
||||
changed1 = true;
|
||||
}
|
||||
if (dy2 > dx2) // swap values
|
||||
{
|
||||
SWAP(dy2, dx2);
|
||||
changed2 = true;
|
||||
}
|
||||
|
||||
e2 = (uint8_t)(dx2 >> 1);
|
||||
// Flat top, just process the second half
|
||||
if (y1 == y2) goto next;
|
||||
e1 = (uint8_t)(dx1 >> 1);
|
||||
|
||||
for (uint8_t i = 0; i < dx1;)
|
||||
{
|
||||
t1xp = 0; t2xp = 0;
|
||||
if (t1x<t2x) { minx = t1x; maxx = t2x; }
|
||||
else { minx = t2x; maxx = t1x; }
|
||||
// process first line until y value is about to change
|
||||
while (i<dx1)
|
||||
{
|
||||
i++;
|
||||
e1 += dy1;
|
||||
while (e1 >= dx1)
|
||||
{
|
||||
e1 -= dx1;
|
||||
if (changed1) t1xp = signx1;//t1x += signx1;
|
||||
else goto next1;
|
||||
}
|
||||
if (changed1) break;
|
||||
else t1x += signx1;
|
||||
}
|
||||
// Move line
|
||||
next1:
|
||||
// process second line until y value is about to change
|
||||
while (1)
|
||||
{
|
||||
e2 += dy2;
|
||||
while (e2 >= dx2)
|
||||
{
|
||||
e2 -= dx2;
|
||||
if (changed2) t2xp = signx2;//t2x += signx2;
|
||||
else goto next2;
|
||||
}
|
||||
if (changed2) break;
|
||||
else t2x += signx2;
|
||||
}
|
||||
next2:
|
||||
if (minx>t1x) minx = t1x;
|
||||
if (minx>t2x) minx = t2x;
|
||||
if (maxx<t1x) maxx = t1x;
|
||||
if (maxx<t2x) maxx = t2x;
|
||||
b &= drawHLine(y, minx, maxx, state); // Draw line from min to max points found on the y
|
||||
// Now increase y
|
||||
if (!changed1) t1x += signx1;
|
||||
t1x += t1xp;
|
||||
if (!changed2) t2x += signx2;
|
||||
t2x += t2xp;
|
||||
y += 1;
|
||||
if (y == y2) break;
|
||||
|
||||
}
|
||||
next:
|
||||
// Second half
|
||||
dx1 = (int8_t)(x3 - x2);
|
||||
if (dx1<0) { dx1 = -dx1; signx1 = -1; }
|
||||
else signx1 = 1;
|
||||
dy1 = (int8_t)(y3 - y2);
|
||||
t1x = x2;
|
||||
|
||||
if (dy1 > dx1)
|
||||
{ // swap values
|
||||
SWAP(dy1, dx1);
|
||||
changed1 = true;
|
||||
}
|
||||
else changed1 = false;
|
||||
|
||||
e1 = (uint8_t)(dx1 >> 1);
|
||||
|
||||
for (uint8_t i = 0; i <= dx1; i++)
|
||||
{
|
||||
t1xp = 0; t2xp = 0;
|
||||
if (t1x<t2x) { minx = t1x; maxx = t2x; }
|
||||
else { minx = t2x; maxx = t1x; }
|
||||
// process first line until y value is about to change
|
||||
while (i<dx1)
|
||||
{
|
||||
e1 += dy1;
|
||||
while (e1 >= dx1)
|
||||
{
|
||||
e1 -= dx1;
|
||||
if (changed1) { t1xp = signx1; break; }//t1x += signx1;
|
||||
else goto next3;
|
||||
}
|
||||
if (changed1) break;
|
||||
else t1x += signx1;
|
||||
if (i<dx1) i++;
|
||||
}
|
||||
next3:
|
||||
// process second line until y value is about to change
|
||||
while (t2x != x3)
|
||||
{
|
||||
e2 += dy2;
|
||||
while (e2 >= dx2)
|
||||
{
|
||||
e2 -= dx2;
|
||||
if (changed2) t2xp = signx2;
|
||||
else goto next4;
|
||||
}
|
||||
if (changed2) break;
|
||||
else t2x += signx2;
|
||||
}
|
||||
next4:
|
||||
|
||||
if (minx>t1x) minx = t1x;
|
||||
if (minx>t2x) minx = t2x;
|
||||
if (maxx<t1x) maxx = t1x;
|
||||
if (maxx<t2x) maxx = t2x;
|
||||
b &= drawHLine(y, minx, maxx, state); // Draw line from min to max points found on the y
|
||||
// Now increase y
|
||||
if (!changed1) t1x += signx1;
|
||||
t1x += t1xp;
|
||||
if (!changed2) t2x += signx2;
|
||||
t2x += t2xp;
|
||||
y += 1;
|
||||
if (y>y3) goto outtahere;
|
||||
}
|
||||
|
||||
outtahere:
|
||||
update(u);
|
||||
|
||||
return(b);
|
||||
}
|
||||
|
||||
|
||||
bool MD_MAXPanel::drawCirclePoints(uint16_t xc, uint16_t yc, uint16_t x, uint16_t y, bool state)
|
||||
// draw symmetrical circle points
|
||||
{
|
||||
bool b = true;
|
||||
|
||||
b &= setPoint(xc + x, yc + y, state);
|
||||
b &= setPoint(xc - x, yc + y, state);
|
||||
b &= setPoint(xc + x, yc - y, state);
|
||||
b &= setPoint(xc - x, yc - y, state);
|
||||
b &= setPoint(xc + y, yc + x, state);
|
||||
b &= setPoint(xc - y, yc + x, state);
|
||||
b &= setPoint(xc + y, yc - x, state);
|
||||
b &= setPoint(xc - y, yc - x, state);
|
||||
|
||||
return(b);
|
||||
}
|
||||
|
||||
bool MD_MAXPanel::drawCircle(uint16_t xc, uint16_t yc, uint16_t r, bool state)
|
||||
// draw a circle given center and radius
|
||||
// Bresenhams Algorith from http://www.pracspedia.com/CG/bresenhamcircle.html
|
||||
{
|
||||
int x = 0, y = r;
|
||||
int pk = 3 - (2 * r);
|
||||
bool b = false;
|
||||
|
||||
_D->control(MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);
|
||||
|
||||
PRINT("\n\nCircle center ", xc); PRINT(",", yc); PRINT(" radius ", r);
|
||||
|
||||
b &= drawCirclePoints(xc, yc, x, y, state);
|
||||
|
||||
while (x < y)
|
||||
{
|
||||
// check for decision parameter and correspondingly update pk, x, y
|
||||
if (pk <= 0)
|
||||
{
|
||||
pk = pk + (4 * x) + 6;
|
||||
b &= drawCirclePoints(xc, yc, ++x, y, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
pk = pk + (4 * (x - y)) + 10;
|
||||
b &= drawCirclePoints(xc, yc, ++x, --y, state);
|
||||
}
|
||||
}
|
||||
|
||||
update(_updateEnabled);
|
||||
|
||||
return(b);
|
||||
}
|
||||
|
||||
bool MD_MAXPanel::drawCircleLines(uint16_t xc, uint16_t yc, uint16_t x, uint16_t y, bool state)
|
||||
// draw symmetrical circle lines for the filled circle
|
||||
{
|
||||
bool b = true;
|
||||
|
||||
b &= drawHLine(yc - y, xc - x, xc + x, state);
|
||||
b &= drawHLine(yc + y, xc - x, xc + x, state);
|
||||
b &= drawHLine(yc - x, xc - y, xc + y, state);
|
||||
b &= drawHLine(yc + x, xc - y, xc + y, state);
|
||||
|
||||
return(b);
|
||||
}
|
||||
|
||||
bool MD_MAXPanel::drawFillCircle(uint16_t xc, uint16_t yc, uint16_t r, bool state)
|
||||
// Draw a filled circle given center and radius
|
||||
// Bresenhams Algorith from http://www.pracspedia.com/CG/bresenhamcircle.html
|
||||
{
|
||||
int x = 0, y = r;
|
||||
int pk = 3 - (2 * r);
|
||||
bool b = false;
|
||||
bool u = _updateEnabled;
|
||||
|
||||
_D->control(MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);
|
||||
update(false);
|
||||
|
||||
PRINT("\n\nFilled Circle center ", xc); PRINT(",", yc); PRINT(" radius ", r);
|
||||
b &= drawCircleLines(xc, yc, x, y, state);
|
||||
while (x < y)
|
||||
{
|
||||
// check for decision parameter and correspondingly update pk, x, y
|
||||
if (pk <= 0)
|
||||
{
|
||||
pk = pk + (4 * x) + 6;
|
||||
b &= drawCircleLines(xc, yc, ++x, y, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
pk = pk + (4 * (x - y)) + 10;
|
||||
b &= drawCircleLines(xc, yc, ++x, --y, state);
|
||||
}
|
||||
}
|
||||
|
||||
update(u);
|
||||
|
||||
return(b);
|
||||
}
|
||||
|
||||
uint16_t MD_MAXPanel::Y2Row(uint16_t x, uint16_t y)
|
||||
// Convert y coord to linear coord
|
||||
{
|
||||
uint16_t Y;
|
||||
|
||||
if (_rotatedDisplay)
|
||||
{
|
||||
x = getXMax() - x;
|
||||
Y = (ROW_SIZE - (x % ROW_SIZE) - 1);
|
||||
}
|
||||
else
|
||||
Y = (ROW_SIZE - (y % ROW_SIZE) - 1);
|
||||
|
||||
return(Y);
|
||||
}
|
||||
|
||||
uint16_t MD_MAXPanel::X2Col(uint16_t x, uint16_t y)
|
||||
// Convert x coord to linear coord
|
||||
{
|
||||
uint16_t X;
|
||||
|
||||
if (_rotatedDisplay)
|
||||
{
|
||||
x = getXMax() - x;
|
||||
X = ((x / ROW_SIZE) * (_xDevices * COL_SIZE) + (_xDevices * COL_SIZE) - 1 - (y % (_xDevices * COL_SIZE)));
|
||||
}
|
||||
else
|
||||
X = ((y / ROW_SIZE) * (_xDevices * COL_SIZE) + (_xDevices * COL_SIZE) - 1 - (x % (_xDevices * COL_SIZE)));
|
||||
|
||||
return(X);
|
||||
}
|
||||
|
||||
bool MD_MAXPanel::getPoint(uint16_t x, uint16_t y)
|
||||
{
|
||||
if (x > getXMax() || y > getYMax())
|
||||
return(false);
|
||||
|
||||
return(_D->getPoint(Y2Row(x,y), X2Col(x,y)));
|
||||
}
|
||||
|
||||
bool MD_MAXPanel::setPoint(uint16_t x, uint16_t y, bool state)
|
||||
{
|
||||
if (x > getXMax() || y > getYMax())
|
||||
return(false);
|
||||
|
||||
//PRINT("[", x); PRINT(",", y); PRINTS("]");
|
||||
|
||||
return(_D->setPoint(Y2Row(x,y), X2Col(x,y), state));
|
||||
}
|
||||
|
||||
618
arduino-libs/arduino-cli/libraries/MD_MAXPanel/src/MD_MAXPanel.h
Normal file
618
arduino-libs/arduino-cli/libraries/MD_MAXPanel/src/MD_MAXPanel.h
Normal file
@@ -0,0 +1,618 @@
|
||||
#ifndef MD_MAXPANEL_h
|
||||
#define MD_MAXPANEL_h
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <MD_MAX72xx.h>
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief Main header file for the MD_MAXPanel library
|
||||
*/
|
||||
|
||||
/**
|
||||
\mainpage Arduino LED Matrix Panel Library
|
||||
The MD_MAXPanel Library
|
||||
-----------------------
|
||||
This library implements functions that allows cascaded MAX72xx LED modules
|
||||
(64 individual LEDs)to be used for LED matrix panels, allowing the programmer
|
||||
to use the LED matrix as an pixel addressable display device, as shown in the
|
||||
photo below.
|
||||
|
||||
![MD_MAXPanel Display Panel] (MAXPanel_Display.jpg "MD_MAXPanel Display Panel")
|
||||
|
||||
The MAX7219/MAX7221 are compact, serial input/output display drivers that
|
||||
interface microprocessors to 7-segment numeric LED displays of up to 8 digits,
|
||||
bar-graph displays, or 64 individual LEDs.
|
||||
|
||||
A 4-wire serial interface (SPI) allows the devices to be cascaded, with
|
||||
communications passed through the first device in the chain to all others.
|
||||
Individual elements may be addressed and updated without rewriting the entire
|
||||
display.
|
||||
|
||||
In order for this library to work, the MD_MAX72xx library must be installed and
|
||||
the correct LED module type selected. The individual LED modules must also be
|
||||
arranged in a zig-zag fashion, as shown in the figure below. The number of modules
|
||||
per row and the number of rows may vary, but the arrangement of the modules must
|
||||
follow the example.
|
||||
|
||||
![MD_MAXPanel Module Arrangement] (MAXPanel_Diagram.jpg "MD_MAXPanel Module Arrangement")
|
||||
|
||||
The wiring for the modules can be simplified as the only signal that needs to be truly
|
||||
cascaded is the MD_MAX72xx IC Data Out to the next IC Data In. The rest can be wired in
|
||||
parallel, as shown in the photo.
|
||||
|
||||
![MD_MAXPanel Module Wiring] (MAXPanel_Wiring.jpg "MD_MAXPanel Module Wiring")
|
||||
|
||||
Topics
|
||||
------
|
||||
- \subpage pageSoftware
|
||||
- \subpage pageRevisionHistory
|
||||
- \subpage pageCopyright
|
||||
- \subpage pageDonation
|
||||
|
||||
\page pageDonation Support the Library
|
||||
If you like and use this library please consider making a small donation using [PayPal](https://paypal.me/MajicDesigns/4USD)
|
||||
|
||||
\page pageCopyright Copyright
|
||||
Copyright (C) 2018 Marco Colli. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\page pageRevisionHistory Revision History
|
||||
Nov 2018 version 1.2.3
|
||||
- Corrected default parameters for WEMOS compiler
|
||||
|
||||
Oct 2018 version 1.2.2
|
||||
- Corrected some documentation mistakes
|
||||
|
||||
Oct 2018 version 1.2.1
|
||||
- Updated library.properties and READ.MD files
|
||||
|
||||
Sep 2018 version 1.2.0
|
||||
- Fixed reported WEMOS D1 compiler issues
|
||||
- Added polygon Fill functions contributed by AndreasPercher
|
||||
|
||||
Jul 2018 version 1.1.1
|
||||
- Finalized preferred orientation for examples
|
||||
|
||||
Jul 2018 version 1.1.0
|
||||
- Renamed textRotation_t to rotation_t
|
||||
- Allow rotation of display (eg, landscape to portrait)
|
||||
- Restored missing bricks example
|
||||
|
||||
Jun 2018 version 1.0.1
|
||||
- Extracted common elements of examples in .h file
|
||||
|
||||
Jun 2018 version 1.0.0
|
||||
- First Release
|
||||
|
||||
\page pageSoftware Software Library
|
||||
The Library
|
||||
-----------
|
||||
The library implements functions that allow the MAX72xx matrix modules
|
||||
to be used cascaded and built up into LED matrix panels. This allows the
|
||||
programmer to control the individual panel LEDs using cartesian coordinates.
|
||||
The library provides support for standard graphics elements (such as lines,
|
||||
triangles, rectangles, circles) and text.
|
||||
|
||||
The origin for the coordinate system is always in the lowest left hand corner.
|
||||
- X coordinate increase to the right.
|
||||
- Y coordinate increase to upwards.
|
||||
|
||||
In trigonometric terms, the display is located in the first quadrant.
|
||||
|
||||
The library is relies on the related MD_MAX72xx library to provide the
|
||||
device control elements.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core object for the MD_MAXPanel library
|
||||
*/
|
||||
class MD_MAXPanel
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Rotation enumerated type specification.
|
||||
*
|
||||
* Used to define rotation orientation (eg, text or display).
|
||||
* For text the normal rotation is the standard Latin language left to right
|
||||
* orientation. Rotation is specified anchored to the first character of the
|
||||
* string - 0 points >, 90 ^, 180 < and 270 v.
|
||||
* For the display rotation 0 and 180 and are identical and 90 and 270 are identical.
|
||||
* The rotation will shift the display between landscape and portrait mode.
|
||||
*/
|
||||
enum rotation_t
|
||||
{
|
||||
ROT_0, ///< Rotation 0 degrees
|
||||
ROT_90, ///< Rotation 90 degrees
|
||||
ROT_180, ///< Rotation 180 degrees
|
||||
ROT_270, ///< Rotation 270 degrees
|
||||
};
|
||||
|
||||
/**
|
||||
* Class Constructor - arbitrary digital interface.
|
||||
*
|
||||
* Instantiate a new instance of the class. The parameters passed are used to
|
||||
* connect the software to the hardware. Multiple instances may co-exist
|
||||
* but they should not share the same hardware CS pin (SPI interface).
|
||||
*
|
||||
* \param mod the hardware module being used, one of the MD_MAX72XX::moduleType_t values
|
||||
* \param dataPin output on the Arduino where data gets shifted out.
|
||||
* \param clkPin output for the clock signal.
|
||||
* \param csPin output for selecting the device.
|
||||
* \param xDevices number of LED matrix modules for the width of the panel.
|
||||
* \param yDevices number of LED matrix modules for the height of the panel.
|
||||
*/
|
||||
MD_MAXPanel(MD_MAX72XX::moduleType_t mod, uint8_t dataPin, uint8_t clkPin, uint8_t csPin, uint8_t xDevices, uint8_t yDevices);
|
||||
|
||||
/**
|
||||
* Class Constructor - SPI hardware interface.
|
||||
*
|
||||
* Instantiate a new instance of the class. The parameters passed are used to
|
||||
* connect the software to the hardware. Multiple instances may co-exist
|
||||
* but they should not share the same hardware CS pin (SPI interface).
|
||||
* The dataPin and the clockPin are defined by the Arduino hardware definition
|
||||
* (SPI MOSI and SCK signals).
|
||||
*
|
||||
* \param mod the hardware module being used, one of the MD_MAX72XX::moduleType_t values
|
||||
* \param csPin output for selecting the device.
|
||||
* \param xDevices number of LED matrix modules for the width of the panel.
|
||||
* \param yDevices number of LED matrix modules for the height of the panel.
|
||||
*/
|
||||
MD_MAXPanel(MD_MAX72XX::moduleType_t mod, uint8_t csPin, uint8_t xDevices, uint8_t yDevices);
|
||||
|
||||
/**
|
||||
* Class Constructor - Existing MD_MAX72XX object.
|
||||
*
|
||||
* Instantiate a new instance of the class. The parameters passed are used to
|
||||
* connect the software to the hardware. The MD_MAX72X object has been created
|
||||
* outside this object and it is up to the programmer to ensure that the correct
|
||||
* parameters are used when this object is created.
|
||||
*
|
||||
* \param D pointer to the existing MD_MAX72XX object.
|
||||
* \param xDevices number of LED matrix modules for the width of the panel.
|
||||
* \param yDevices number of LED matrix modules for the height of the panel.
|
||||
*/
|
||||
MD_MAXPanel(MD_MAX72XX *D, uint8_t xDevices, uint8_t yDevices);
|
||||
|
||||
/**
|
||||
* Initialize the object.
|
||||
*
|
||||
* Initialize the object data. This needs to be called during setup() to initialize
|
||||
* new data for the class that cannot be done during the object creation.
|
||||
*/
|
||||
void begin(void);
|
||||
|
||||
/**
|
||||
* Class Destructor.
|
||||
*
|
||||
* Released allocated memory and does the necessary to clean up once the object is
|
||||
* no longer required.
|
||||
*/
|
||||
~MD_MAXPanel();
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/** \name Methods for object management.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Clear all the display data on all the display devices.
|
||||
*
|
||||
* \return No return value.
|
||||
*/
|
||||
void clear(void) { _D->clear(0, _xDevices*_yDevices); };
|
||||
|
||||
/**
|
||||
* Clear the specified display area.
|
||||
*
|
||||
* Clear the rectangular area specified by the coordinates by setting the pixels
|
||||
* to the state specified (default is off).
|
||||
*
|
||||
* \param x1 the upper left x coordinate of the window
|
||||
* \param y1 the upper left y coordinate of the window
|
||||
* \param x2 the lower right x coordinate of the window
|
||||
* \param y2 the upper lower right y coordinate of the window
|
||||
* \param state true - switch pixels on; false - switch pixels off. If omitted, default to false.
|
||||
* \return No return value.
|
||||
*/
|
||||
void clear(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool state = false) { for (uint8_t i=x1; i<=x2; i++) drawVLine(i, y1, y2, state); };
|
||||
|
||||
/**
|
||||
* Get a pointer to the instantiated graphics object.
|
||||
*
|
||||
* Provides a pointer to the MD_MAX72XX object to allow access to
|
||||
* the display graphics functions.
|
||||
*
|
||||
* \return Pointer to the MD_MAX72xx object used by the library.
|
||||
*/
|
||||
MD_MAX72XX *getGraphicObject(void) { return(_D); }
|
||||
|
||||
/**
|
||||
* Gets the maximum X coordinate.
|
||||
*
|
||||
* Depends on the rotation status of the display.
|
||||
*
|
||||
* \return uint8_t the maximum X coordinate.
|
||||
*/
|
||||
uint16_t getXMax(void);
|
||||
|
||||
/**
|
||||
* Gets the maximum Y coordinate.
|
||||
*
|
||||
* Depends on the rotation status of the display.
|
||||
*
|
||||
* \return uint16_t representing the number of columns.
|
||||
*/
|
||||
uint16_t getYMax(void);
|
||||
|
||||
/**
|
||||
* Get the rotation status of the display
|
||||
*
|
||||
* \return rotation_t value for the current rotation (ROT_0 or ROT_90)
|
||||
*/
|
||||
rotation_t getRotation(void) { return(_rotatedDisplay ? ROT_90 : ROT_0); }
|
||||
|
||||
/**
|
||||
* Set rotation status of the display
|
||||
*
|
||||
* Set the display to be rotated or not. ROT_90 and ROT_270 rotate the display
|
||||
* by 90 degrees in the same direction. ROT_O and ROT_180 are an unrotated display.
|
||||
* The default is ROT_O (unrotated).
|
||||
*
|
||||
* \param r rotation_t value for the current rotation (ROT_0 or ROT_90);
|
||||
* \return No return value
|
||||
*/
|
||||
void setRotation(rotation_t r) { _rotatedDisplay = (r == ROT_90) || (r == ROT_270); }
|
||||
|
||||
/**
|
||||
* Turn auto display updates on or off.
|
||||
*
|
||||
* Turn auto updates on and off, as required. When auto updates are turned OFF the
|
||||
* display will not update after each operation. Display updates can be forced at any
|
||||
* time using using a call to update() with no parameters.
|
||||
*
|
||||
* \param state true to enable update, false to suspend updates.
|
||||
* \return No return value.
|
||||
*/
|
||||
void update(bool state) { _updateEnabled = state; _D->control(MD_MAX72XX::UPDATE, state ? MD_MAX72XX::ON : MD_MAX72XX::OFF); };
|
||||
|
||||
/**
|
||||
* Force a display update.
|
||||
*
|
||||
* Force a display update of any changes since the last update. This overrides the
|
||||
* current setting for display updates.
|
||||
*
|
||||
* \return No return value.
|
||||
*/
|
||||
void update() { _D->update(); };
|
||||
|
||||
/**
|
||||
* Set the display intensity.
|
||||
*
|
||||
* Set the intensity (brightness) of the display.
|
||||
*
|
||||
* \param intensity the intensity to set the display (0-15).
|
||||
* \return No return value.
|
||||
*/
|
||||
void setIntensity(uint8_t intensity) { _D->control(MD_MAX72XX::INTENSITY, intensity); }
|
||||
|
||||
/** @} */
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/** \name Methods for drawing graphics.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Draw a horizontal line between two points on the display
|
||||
*
|
||||
* Draw a horizontal line between the specified points. The LED will be turned on or
|
||||
* off depending on the value supplied. The column number will be dereferenced
|
||||
* into the device and column within the device, allowing the LEDs to be treated
|
||||
* as a continuous pixel field.
|
||||
*
|
||||
* \param y y coordinate for the line [0..getYMax()].
|
||||
* \param x1 starting x coordinate for the point [0..getXMax()].
|
||||
* \param x2 ending x coordinate for the point [0..getXMax()].
|
||||
* \param state true - switch on; false - switch off. If omitted, default to true.
|
||||
* \return false if any point is drawn outside the display, true otherwise.
|
||||
*/
|
||||
bool drawHLine(uint16_t y, uint16_t x1, uint16_t x2, bool state = true);
|
||||
|
||||
/**
|
||||
* Draw an arbitrary line between two points on the display
|
||||
*
|
||||
* Draw a line between the specified points using Bresenham's algorithm.
|
||||
* The LED will be turned on or off depending on the value supplied. The
|
||||
* column number will be dereferenced into the device and column within
|
||||
* the device, allowing the LEDs to be treated as a continuous pixel field.
|
||||
*
|
||||
* \param x1 starting x coordinate for the point [0..getXMax()].
|
||||
* \param y1 starting y coordinate for the point [0..getYMax()].
|
||||
* \param x2 ending x coordinate for the point [0..getXMax()].
|
||||
* \param y2 ending y coordinate for the point [0..getYMax()].
|
||||
* \param state true - switch on; false - switch off. If omitted, default to true.
|
||||
* \return false if any point is drawn outside the display, true otherwise.
|
||||
*/
|
||||
bool drawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool state = true);
|
||||
|
||||
/**
|
||||
* Draw a vertical line between two points on the display
|
||||
*
|
||||
* Draw a horizontal line between the specified points. The LED will be turned on or
|
||||
* off depending on the value supplied. The column number will be dereferenced
|
||||
* into the device and column within the device, allowing the LEDs to be treated
|
||||
* as a continuous pixel field.
|
||||
*
|
||||
* \param x x coordinate for the line [0..getXMax()].
|
||||
* \param y1 starting y coordinate for the point [0..getYMax()].
|
||||
* \param y2 ending y coordinate for the point [0..getYMax()].
|
||||
* \param state true - switch on; false - switch off. If omitted, default to true.
|
||||
* \return false if any point is drawn outside the display, true otherwise.
|
||||
*/
|
||||
bool drawVLine(uint16_t x, uint16_t y1, uint16_t y2, bool state = true);
|
||||
|
||||
/**
|
||||
* Draw a rectangle given two diagonal vertices
|
||||
*
|
||||
* Draw a rectangle given the points across the diagonal. The LED will be turned on or
|
||||
* off depending on the value supplied. The coordinates will be dereferenced
|
||||
* into the device and column within the device, allowing the LEDs to be treated
|
||||
* as a continuous pixel field.
|
||||
*
|
||||
* \param x1 starting x coordinate for the point [0..getXMax()].
|
||||
* \param y1 starting y coordinate for the point [0..getYMax()].
|
||||
* \param x2 ending x coordinate for the point [0..getXMax()].
|
||||
* \param y2 ending y coordinate for the point [0..getYMax()].
|
||||
* \param state true - switch on; false - switch off. If omitted, default to true.
|
||||
* \return false if any point is drawn outside the display, true otherwise.
|
||||
*/
|
||||
bool drawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool state = true);
|
||||
|
||||
/**
|
||||
* Draw a filled rectangle given two diagonal vertices
|
||||
*
|
||||
* Draw a filled rectangle given the points across the diagonal. The LEDs inside
|
||||
* and on the border will be turned on or off depending on the value supplied.
|
||||
* The coordinates will be dereferenced into the device and column within the
|
||||
* device, allowing the LEDs to be treated as a continuous pixel field.
|
||||
*
|
||||
* \param x1 starting x coordinate for the point [0..getXMax()].
|
||||
* \param y1 starting y coordinate for the point [0..getYMax()].
|
||||
* \param x2 ending x coordinate for the point [0..getXMax()].
|
||||
* \param y2 ending y coordinate for the point [0..getYMax()].
|
||||
* \param state true - switch on; false - switch off. If omitted, default to true.
|
||||
* \return false if any point is drawn outside the display, true otherwise.
|
||||
*/
|
||||
bool drawFillRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool state = true);
|
||||
|
||||
/**
|
||||
* Draw a triangle given 3 vertices
|
||||
*
|
||||
* Draw a triangle given the all the corner points. The LED will be turned on or
|
||||
* off depending on the value supplied. The coordinates will be dereferenced
|
||||
* into the device and column within the device, allowing the LEDs to be treated
|
||||
* as a continuous pixel field.
|
||||
*
|
||||
* \param x1 first x coordinate for the point [0..getXMax()].
|
||||
* \param y1 first y coordinate for the point [0..getYMax()].
|
||||
* \param x2 second x coordinate for the point [0..getXMax()].
|
||||
* \param y2 second y coordinate for the point [0..getYMax()].
|
||||
* \param x3 third x coordinate for the point [0..getXMax()].
|
||||
* \param y3 third y coordinate for the point [0..getYMax()].
|
||||
* \param state true - switch on; false - switch off. If omitted, default to true.
|
||||
* \return false if any point is drawn outside the display, true otherwise.
|
||||
*/
|
||||
bool drawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, bool state = true);
|
||||
|
||||
/**
|
||||
* Draw a filled triangle given 3 vertices
|
||||
*
|
||||
* Draw a filled triangle given the all the corner points. The LED for
|
||||
* the border and fill will be turned on or off depending on the value
|
||||
* supplied. The coordinates will be dereferenced into the device and
|
||||
* column within the device, allowing the LEDs to be treated as a
|
||||
* continuous pixel field.
|
||||
*
|
||||
* \param x1 first x coordinate for the point [0..getXMax()].
|
||||
* \param y1 first y coordinate for the point [0..getYMax()].
|
||||
* \param x2 second x coordinate for the point [0..getXMax()].
|
||||
* \param y2 second y coordinate for the point [0..getYMax()].
|
||||
* \param x3 third x coordinate for the point [0..getXMax()].
|
||||
* \param y3 third y coordinate for the point [0..getYMax()].
|
||||
* \param state true - switch on; false - switch off. If omitted, default to true.
|
||||
* \return false if any point is drawn outside the display, true otherwise.
|
||||
*/
|
||||
bool drawFillTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, bool state = true);
|
||||
|
||||
/**
|
||||
* Draw a quadrilateral given 4 vertices
|
||||
*
|
||||
* Draw a quadrilateral given the all the corner points. The LED will be turned on or
|
||||
* off depending on the value supplied. The coordinates will be dereferenced
|
||||
* into the device and column within the device, allowing the LEDs to be treated
|
||||
* as a continuous pixel field.
|
||||
*
|
||||
* \param x1 first x coordinate for the point [0..getXMax()].
|
||||
* \param y1 first y coordinate for the point [0..getYMax()].
|
||||
* \param x2 second x coordinate for the point [0..getXMax()].
|
||||
* \param y2 second y coordinate for the point [0..getYMax()].
|
||||
* \param x3 third x coordinate for the point [0..getXMax()].
|
||||
* \param y3 third y coordinate for the point [0..getYMax()].
|
||||
* \param x4 fourth x coordinate for the point [0..getXMax()].
|
||||
* \param y4 fourth y coordinate for the point [0..getYMax()].
|
||||
* \param state true - switch on; false - switch off. If omitted, default to true.
|
||||
* \return false if any point is drawn outside the display, true otherwise.
|
||||
*/
|
||||
bool drawQuadrilateral(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t x4, uint16_t y4, bool state = true);
|
||||
|
||||
/**
|
||||
* Draw a circle given center and radius
|
||||
*
|
||||
* Draw a circle given center and radius. The LEDs will be turned
|
||||
* on or off depending on the value supplied. The coordinates will
|
||||
* be dereferenced into the device and column within the device,
|
||||
* allowing the LEDs to be treated as a continuous pixel field.
|
||||
*
|
||||
* \param xc x coordinate for the center point [0..getXMax()].
|
||||
* \param yc y coordinate for the center point [0..getYMax()].
|
||||
* \param r radius of the circle.
|
||||
* \param state true - switch on; false - switch off. If omitted, default to true.
|
||||
* \return false if any point is drawn outside the display, true otherwise.
|
||||
*/
|
||||
bool drawCircle(uint16_t xc, uint16_t yc, uint16_t r, bool state = true);
|
||||
|
||||
/**
|
||||
* Draw a filled circle given center and radius
|
||||
*
|
||||
* Draw a circle given center and radius. The LEDs for the border
|
||||
* and fill will be turned on or off depending on the value supplied.
|
||||
* The coordinates will be dereferenced into the device and column
|
||||
* within the device, allowing the LEDs to be treated as a continuous
|
||||
* pixel field.
|
||||
*
|
||||
* \param xc x coordinate for the center point [0..getXMax()].
|
||||
* \param yc y coordinate for the center point [0..getYMax()].
|
||||
* \param r radius of the circle.
|
||||
* \param state true - switch on; false - switch off. If omitted, default to true.
|
||||
* \return false if any point is drawn outside the display, true otherwise.
|
||||
*/
|
||||
bool drawFillCircle(uint16_t xc, uint16_t yc, uint16_t r, bool state = true);
|
||||
|
||||
/**
|
||||
* Get the status of a single LED, addressed as a pixel.
|
||||
*
|
||||
* The method will get the status of a specific LED element based on its
|
||||
* coordinate position. The column number is dereferenced into the device
|
||||
* and column within the device, allowing the LEDs to be treated as a
|
||||
* planar pixel field.
|
||||
*
|
||||
* \param x x coordinate [0..getXMax()].
|
||||
* \param y y coordinate [0..getYMax()].
|
||||
* \return true if LED is on, false if off or parameter errors.
|
||||
*/
|
||||
bool getPoint(uint16_t x, uint16_t y);
|
||||
|
||||
/**
|
||||
* Set the status of a single LED, addressed as a pixel.
|
||||
*
|
||||
* The method will set the value of a specific LED element based on its
|
||||
* coordinate position. The LED will be turned on or off depending on the
|
||||
* value supplied. The column number is dereferenced into the device and
|
||||
* column within the device, allowing the LEDs to be treated as a
|
||||
* planar pixel field.
|
||||
*
|
||||
* \param x x coordinate [0..getXMax()].
|
||||
* \param y y coordinate [0..getYMax()].
|
||||
* \param state true - switch on; false - switch off. If omitted, default to true.
|
||||
* \return false if parameter errors, true otherwise.
|
||||
*/
|
||||
bool setPoint(uint16_t x, uint16_t y, bool state = true);
|
||||
|
||||
/** @} */
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/** \name Methods for Fonts and text.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* Set the display font.
|
||||
*
|
||||
* Set the display font to a user defined font table. This can be created using the
|
||||
* MD_MAX72xx font builder (refer to documentation for the tool and the MD_MAX72xx library).
|
||||
* Passing nullptr resets to the library default font.
|
||||
*
|
||||
* \param fontDef Pointer to the font definition to be used.
|
||||
* \return No return value.
|
||||
*/
|
||||
void setFont(MD_MAX72XX::fontType_t *fontDef) { _D->setFont(fontDef); }
|
||||
|
||||
/**
|
||||
* Set the spacing between characters.
|
||||
*
|
||||
* Set number of pixel columns between each character in a displayed text.
|
||||
*
|
||||
* \param spacing the spacing between characters.
|
||||
* \return No return value.
|
||||
*/
|
||||
void setCharSpacing(uint8_t spacing) { _charSpacing = spacing; }
|
||||
|
||||
/**
|
||||
* Get the spacing between characters.
|
||||
*
|
||||
* Get number of pixel columns between each character in a displayed text.
|
||||
*
|
||||
* \return the spacing between characters.
|
||||
*/
|
||||
uint8_t getCharSpacing(void) { return(_charSpacing); }
|
||||
|
||||
/**
|
||||
* Get the length of a text string in pixels.
|
||||
*
|
||||
* Get the length of a string in pixels. The text is a nul terminated characters array.
|
||||
* The returned length will include all inter-character Set number of pixel columns between each character in a displayed text.
|
||||
*
|
||||
* \param psz the text string as a nul terminated character array.
|
||||
* \return the length in pixels.
|
||||
*/
|
||||
uint16_t getTextWidth(const char *psz);
|
||||
|
||||
/**
|
||||
* Get the height of the current font in pixels.
|
||||
*
|
||||
* Get the specified of height of the current font in pixels. All the characters of the
|
||||
* font will fit with this height.
|
||||
*
|
||||
* \return the height in pixels.
|
||||
*/
|
||||
uint16_t getFontHeight(void) { return(_D->getFontHeight()); }
|
||||
|
||||
/**
|
||||
* Draw text on the display.
|
||||
*
|
||||
* Get the specified of height of the current font in pixels. All the characters of the
|
||||
* font will fit with this height.
|
||||
*
|
||||
* \param x the x coordinate for the top left corner of the first character.
|
||||
* \param y the Y coordinate for the top left corner of the first character.
|
||||
* \param psz the text to be displayed as a nul terminated character array.
|
||||
* \param rot the required rotation orientation for the text as described in textRotation_t. Default is ROT_0.
|
||||
* \param state true - switch on; false - switch off. If omitted, default to true.
|
||||
* \return the length of the text in pixels.
|
||||
*/
|
||||
uint16_t drawText(uint16_t x, uint16_t y, const char *psz, rotation_t rot = ROT_0, bool state = true);
|
||||
|
||||
/** @} */
|
||||
|
||||
private:
|
||||
// Device buffer data
|
||||
uint8_t _xDevices; // number of devices in the width of the panel
|
||||
uint8_t _yDevices; // number of devices in the height of the panel
|
||||
|
||||
MD_MAX72XX *_D; // hardware driver
|
||||
bool _killOnDestruct; // true if we have allocated the MD_MAX72XX object
|
||||
|
||||
bool _updateEnabled; // true if display updates are suspended
|
||||
uint8_t _charSpacing; // number of pixel columns between characters
|
||||
bool _rotatedDisplay; // true if the display is rotated
|
||||
|
||||
bool drawCirclePoints(uint16_t xc, uint16_t yc, uint16_t x, uint16_t y, bool state);
|
||||
bool drawCircleLines(uint16_t xc, uint16_t yc, uint16_t x, uint16_t y, bool state);
|
||||
uint16_t Y2Row(uint16_t x, uint16_t y); // Convert y coord to linear coord
|
||||
uint16_t X2Col(uint16_t x, uint16_t y); // Convert x coord to linear coord
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
MD_MAXPanel - Library for MAX7219/7221 LED Panel
|
||||
|
||||
See header file for comments
|
||||
|
||||
This file contains font and text related methods.
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
#include "MD_MAXPanel.h"
|
||||
#include "MD_MAXPanel_lib.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief Implements font and text methods
|
||||
*/
|
||||
|
||||
uint16_t MD_MAXPanel::getTextWidth(const char *psz)
|
||||
{
|
||||
uint16_t sum = 0;
|
||||
uint8_t bufSize = _D->getMaxFontWidth();
|
||||
uint8_t buf[bufSize];
|
||||
|
||||
while (*psz != '\0')
|
||||
{
|
||||
sum += _D->getChar(*psz++, bufSize, buf);
|
||||
if (*psz) sum += _charSpacing; // next character is not nul, so add inter-character spacing
|
||||
}
|
||||
|
||||
return(sum);
|
||||
}
|
||||
|
||||
uint16_t MD_MAXPanel::drawText(uint16_t x, uint16_t y, const char *psz, rotation_t rot, bool state)
|
||||
{
|
||||
uint8_t height = _D->getFontHeight();
|
||||
uint8_t bufSize = _D->getMaxFontWidth() + _charSpacing;
|
||||
uint8_t buf[bufSize];
|
||||
uint8_t size;
|
||||
uint16_t sum = 0;
|
||||
|
||||
int16_t nextPos;
|
||||
|
||||
PRINT("\ndrawText: ", psz);
|
||||
PRINT(" height ", height);
|
||||
while (*psz != '\0')
|
||||
{
|
||||
PRINT("\nChar ", *psz);
|
||||
memset(buf, '\0', bufSize*sizeof(uint8_t));
|
||||
size = _D->getChar(*psz, bufSize, buf);
|
||||
psz++;
|
||||
if (*psz != '\0') size += _charSpacing; // add in the blank columns
|
||||
sum += size;
|
||||
|
||||
// now display the char depending on what the orientation is
|
||||
switch (rot)
|
||||
{
|
||||
case ROT_0:
|
||||
for (uint16_t i = 0; i < size; i++)
|
||||
for (uint16_t j = 0; j < height; j++)
|
||||
setPoint(x + i, y - j, (buf[i] & (1 << j) ? state : !state));
|
||||
x += size;
|
||||
break;
|
||||
|
||||
case ROT_90:
|
||||
for (uint16_t j = 0; j < size; j++)
|
||||
for (uint16_t i = 0; i < height; i++)
|
||||
setPoint(x + i, y + j, (buf[j] & (1 << i) ? state : !state));
|
||||
y += size;
|
||||
break;
|
||||
|
||||
case ROT_180:
|
||||
for (uint16_t i = 0; i < size; i++)
|
||||
for (uint16_t j = 0; j < height; j++)
|
||||
setPoint(x - i, y + j, (buf[i] & (1 << j) ? state : !state));
|
||||
x -= size;
|
||||
break;
|
||||
|
||||
case ROT_270:
|
||||
for (uint16_t j = 0; j < size; j++)
|
||||
for (uint16_t i = 0; i < height; i++)
|
||||
setPoint(x - i, y - j, (buf[j] & (1 << i) ? state : !state));
|
||||
y -= size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(sum);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
MD_MAXPanel - Library for panels of MAX72xx LED matrix controllers
|
||||
|
||||
See header file for comments
|
||||
|
||||
This file contains library related definitions and is not visible
|
||||
to user code.
|
||||
|
||||
Copyright (C) 2018 Marco Colli. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief Includes library only definitions
|
||||
*/
|
||||
|
||||
#define MP_DEBUG 0 ///< Enable or disable (default) debugging output from the MD_MAX72xx library
|
||||
|
||||
#if MP_DEBUG
|
||||
#define PRINT(s, v) { Serial.print(F(s)); Serial.print(v); } ///< Print a string followed by a value (decimal)
|
||||
#define PRINTX(s, v) { Serial.print(F(s)); Serial.print(v, HEX); } ///< Print a string followed by a value (hex)
|
||||
#define PRINTB(s, v) { Serial.print(F(s)); Serial.print(v, BIN); } ///< Print a string followed by a value (binary)
|
||||
#define PRINTS(s) { Serial.print(F(s)); } ///< Print a string
|
||||
#else
|
||||
#define PRINT(s, v) ///< Print a string followed by a value (decimal)
|
||||
#define PRINTX(s, v) ///< Print a string followed by a value (hex)
|
||||
#define PRINTB(s, v) ///< Print a string followed by a value (binary)
|
||||
#define PRINTS(s) ///< Print a string
|
||||
#endif
|
||||
|
||||
#define X2COL(x, y) (((y / ROW_SIZE) * (getXMax() + 1)) + (getXMax() - (x % (getXMax() + 1)))) ///< Convert x coord to linear coord
|
||||
#define Y2ROW(x, y) (ROW_SIZE - (y % ROW_SIZE) - 1) ///< Convert y coord to linear coord
|
||||
|
||||
#define CHAR_SPACING_DEFAULT 1 ///< Default number of pixels between characters
|
||||
Reference in New Issue
Block a user