mirror of https://github.com/arendst/Tasmota.git
use LedMatrix 1234
This commit is contained in:
parent
b3dd33f248
commit
532e506946
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* LedMatrix.h - Extends the Library LedControl for multiple LED dot matrix modules, based on MAX7219/MAX7221
|
||||
* Copyright (c) 2021 Michael Beuss
|
||||
*
|
||||
* 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:
|
||||
*
|
||||
* 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 "LedMatrix.h"
|
||||
|
||||
// public
|
||||
LedMatrix::LedMatrix(int dataPin, int clkPin, int csPin, unsigned int colums, unsigned int rows)
|
||||
{
|
||||
if (colums * rows > MATRIX_MAX_MODULES)
|
||||
{
|
||||
// dimension exeeds maximum buffer size
|
||||
if (colums >= MATRIX_MAX_MODULES)
|
||||
{
|
||||
colums = MATRIX_MAX_MODULES;
|
||||
rows = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
rows = MATRIX_MAX_MODULES / colums;
|
||||
}
|
||||
}
|
||||
|
||||
modulesPerRow = colums;
|
||||
modulesPerCol = rows;
|
||||
width = colums * 8;
|
||||
height = rows * 8;
|
||||
modules = colums * rows;
|
||||
moduleOrientation = ORIENTATION_UPSIDE_DOWN;
|
||||
ledControl = new LedControl(dataPin, clkPin, csPin, modules);
|
||||
shutdown(false); // false: on, true: off
|
||||
clear();
|
||||
setIntensity(7);
|
||||
}
|
||||
|
||||
bool LedMatrix::clear(void)
|
||||
{
|
||||
for (int i = 0; i < MATRIX_BUFFER_SIZE; i++)
|
||||
{
|
||||
buffer[i] = 0;
|
||||
}
|
||||
for (int addr = 0; addr < modules; addr++)
|
||||
{
|
||||
ledControl->clearDisplay(addr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LedMatrix::setIntensity(byte dim)
|
||||
{
|
||||
for (int addr = 0; addr < modules; addr++)
|
||||
{
|
||||
ledControl->setIntensity(addr, dim); // 1..15
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LedMatrix::setOrientation(ModuleOrientation orientation)
|
||||
{
|
||||
moduleOrientation = orientation;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LedMatrix::setPixel(int x, int y, bool on)
|
||||
{
|
||||
if (x >= width || y >= height)
|
||||
return false;
|
||||
|
||||
int modul_col = x / 8; // x pos divided by 8 is the index of the modul to the right
|
||||
int buffer_pos = modul_col + y * width / 8;
|
||||
byte buffer_byte = 8 >> (x % 8);
|
||||
if (on)
|
||||
{
|
||||
buffer[buffer_pos] |= buffer_byte; // set bit
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[buffer_pos] &= ~buffer_byte; // reset bit
|
||||
}
|
||||
refreshByteOfBuffer(buffer_pos);
|
||||
return true;
|
||||
}
|
||||
|
||||
void LedMatrix::test()
|
||||
{
|
||||
const static byte testMatrix[] PROGMEM = {
|
||||
B00000010, B00111100, B00111100, B00001000,
|
||||
B00000110, B01000010, B01000010, B00010000,
|
||||
B00001010, B00000010, B00000010, B00100000,
|
||||
B00000010, B00000100, B00001100, B01000100,
|
||||
B00000010, B00011000, B00000010, B01111110,
|
||||
B00000010, B00100000, B01000010, B00000100,
|
||||
B00000000, B11111110, B00111100, B00000100,
|
||||
B00000000, B00000000, B00000000, B00000000,
|
||||
};
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
buffer[i] = testMatrix[i];
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
|
||||
// private
|
||||
bool LedMatrix::shutdown(bool b)
|
||||
{
|
||||
for (int addr = 0; addr < modules; addr++)
|
||||
{
|
||||
ledControl->shutdown(addr, b); // b: false: on, true: off
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void LedMatrix::refresh()
|
||||
{
|
||||
for (int i = 0; i < modulesPerRow * height; i++)
|
||||
{
|
||||
refreshByteOfBuffer(i);
|
||||
}
|
||||
}
|
||||
|
||||
void LedMatrix::refreshByteOfBuffer(int i)
|
||||
{
|
||||
int line = i / modulesPerRow;
|
||||
int addr = line / 8 + i % modulesPerRow;
|
||||
byte b = buffer[i];
|
||||
if (moduleOrientation == ORIENTATION_NORMAL || moduleOrientation == ORIENTATION_UPSIDE_DOWN)
|
||||
{
|
||||
int rowOfAddr = 0;
|
||||
if (moduleOrientation == ORIENTATION_NORMAL)
|
||||
{
|
||||
rowOfAddr = line % 8; // ORIENTATION_NORMAL
|
||||
}
|
||||
else
|
||||
{
|
||||
rowOfAddr = 7 - line % 8; // ORIENTATION_UPSIDE_DOWN
|
||||
b = revereBitorder(b);
|
||||
}
|
||||
ledControl->setRow(addr, rowOfAddr, b);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ORIENTATION_TURN_RIGHT or ORIENTATION_TURN_LEFT
|
||||
int colOfAddr = 0;
|
||||
if (moduleOrientation == ORIENTATION_TURN_LEFT)
|
||||
{
|
||||
colOfAddr = line % 8; // ORIENTATION_TURN_LEFT
|
||||
}
|
||||
else
|
||||
{
|
||||
colOfAddr = 7 - line % 8; // ORIENTATION_TURN_RIGHT
|
||||
b = revereBitorder(b);
|
||||
}
|
||||
ledControl->setColumn(addr, colOfAddr, b);
|
||||
}
|
||||
}
|
||||
|
||||
byte LedMatrix::revereBitorder (byte b)
|
||||
{
|
||||
const static byte lookup[] PROGMEM = {
|
||||
0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
|
||||
0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf,
|
||||
};
|
||||
return (lookup[b & 0b1111] << 4) | lookup[b >> 4];
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* LedMatrix.h - Extends the Library LedControl for multiple LED dot matrix modules, based on MAX7219/MAX7221
|
||||
* Copyright (c) 2021 Michael Beuss
|
||||
*
|
||||
* 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:
|
||||
*
|
||||
* 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 LedMatrix_h
|
||||
#define LedMatrix_h
|
||||
|
||||
#include <LedControl.h>
|
||||
|
||||
#define MATRIX_MAX_MODULES 32
|
||||
#define MATRIX_BUFFER_SIZE MATRIX_MAX_MODULES * 8 // 8 bytes per modul. One byte represents 8 LEDs.
|
||||
|
||||
|
||||
/**
|
||||
* @brief LedMatric controls multiple 8x8 LED dot matrx modules.
|
||||
* All modules in rows and clolums together build a common matrix.
|
||||
*
|
||||
*/
|
||||
class LedMatrix
|
||||
{
|
||||
public:
|
||||
enum ModuleOrientation // orientation of 8x8 LED dot matrix mdules (first module is top left)
|
||||
{
|
||||
ORIENTATION_NORMAL, // first pixel is on top left, no turn is necessary
|
||||
ORIENTATION_TURN_RIGHT, // first pixel is on bottom left, for correction it has to turn 90° right
|
||||
ORIENTATION_UPSIDE_DOWN, // first pixel is on bottom right, fpr correction it has to turn 180°
|
||||
ORIENTATION_TURN_LEFT, // first pixel is on top right, for correction is has to turn 90° left.
|
||||
};
|
||||
|
||||
private:
|
||||
unsigned int modulesPerRow;
|
||||
unsigned int modulesPerCol;
|
||||
unsigned int width; // matrix width [pixel]
|
||||
unsigned int height; // matrix height [pixel]
|
||||
unsigned int modules; // number of 8x8 mudules
|
||||
ModuleOrientation moduleOrientation;
|
||||
byte buffer[MATRIX_BUFFER_SIZE];
|
||||
LedControl* ledControl;
|
||||
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Led Matrix object
|
||||
*
|
||||
* @param colums of 8x8 LED dot matrix modules
|
||||
* @param rows of 8x8 LED dot matrix modules
|
||||
*/
|
||||
LedMatrix(int dataPin, int clkPin, int csPin, unsigned int colums, unsigned int rows);
|
||||
|
||||
/**
|
||||
* @brief Set all LEDs off.
|
||||
*
|
||||
*/
|
||||
bool clear(void);
|
||||
|
||||
/**
|
||||
* @brief Set the brightness of the display
|
||||
*
|
||||
* @param dim 0..15
|
||||
*/
|
||||
bool setIntensity(byte dim);
|
||||
|
||||
/**
|
||||
* @brief Switches the display on or off
|
||||
*
|
||||
* @param on true: on false: off
|
||||
*/
|
||||
void power( bool on );
|
||||
|
||||
/**
|
||||
* @brief Set the orientation of the 8x8 LED dot matrix module
|
||||
*
|
||||
* @param orientation
|
||||
*/
|
||||
bool setOrientation(ModuleOrientation orientation);
|
||||
|
||||
/**
|
||||
* @brief Set the Pixel object
|
||||
*
|
||||
* @param x horizontal position from left
|
||||
* @param y vertical position from top
|
||||
* @param on true: on, false: off
|
||||
*/
|
||||
bool setPixel( int x, int y, bool on);
|
||||
void test();
|
||||
|
||||
private:
|
||||
bool shutdown(bool b);
|
||||
|
||||
/**
|
||||
* @brief sends the changed content of the buffer to the display
|
||||
*
|
||||
*/
|
||||
void refresh();
|
||||
|
||||
void refreshByteOfBuffer( int i);
|
||||
|
||||
byte revereBitorder (byte b);
|
||||
|
||||
};
|
||||
|
||||
#endif //LedMatrix_h
|
|
@ -133,70 +133,45 @@ and setting it to 3 alternates between time and date.
|
|||
#define XDSP_19 19
|
||||
#define CMD_MAX_LEN 55
|
||||
|
||||
#include <LedMatrix.h>
|
||||
|
||||
#include <LedControl.h>
|
||||
|
||||
LedControl *max7219_Matrix;
|
||||
LedMatrix *max7219_Matrix;
|
||||
bool max2791Matrix_init_done = false;
|
||||
byte modulesPerRow = 4;
|
||||
|
||||
byte modulesPerCol = 1;
|
||||
|
||||
bool MAX7291Matrix_init(void)
|
||||
{
|
||||
if (!PinUsed(GPIO_MAX7219DIN) || !PinUsed(GPIO_MAX7219CLK) || !PinUsed(GPIO_MAX7219CS))
|
||||
{
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("DSP: MAX7291Matrix_init GPIO pins missing DIN, CLK or CS"));
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("DSP: MAX7291Matrix_init GPIO pins missing DIN:%d, CLK:%d, CS:%d"), Pin(GPIO_MAX7219DIN), Pin(GPIO_MAX7219CLK), Pin(GPIO_MAX7219CS) );
|
||||
return false; // ensure necessariy pins are configurated
|
||||
}
|
||||
|
||||
Settings->display_model = XDSP_19;
|
||||
if (Settings->display_width) // [pixel]
|
||||
{
|
||||
modulesPerRow = (Settings->display_width - 1) / 8 + 1;
|
||||
}
|
||||
Settings->display_width = 8 * modulesPerRow;
|
||||
Settings->display_cols[0] = Settings->display_width;
|
||||
Settings->display_height = 1;
|
||||
if (Settings->display_height) // [pixel]
|
||||
{
|
||||
modulesPerCol = (Settings->display_height - 1) / 8 + 1;
|
||||
}
|
||||
Settings->display_height = 8 * modulesPerCol;
|
||||
Settings->display_rows = Settings->display_height;
|
||||
max7219_Matrix = new LedControl(Pin(GPIO_MAX7219DIN), Pin(GPIO_MAX7219CLK), Pin(GPIO_MAX7219CS), modulesPerRow);
|
||||
MAX7291Matrix_On(true);
|
||||
MAX7291Matrix_Clear();
|
||||
MAX7291Matrix_Dim();
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("DSP: MAX7291Matrix_init"));
|
||||
Settings->display_cols[1] = Settings->display_height;
|
||||
max7219_Matrix = new LedMatrix(Pin(GPIO_MAX7219DIN), Pin(GPIO_MAX7219CLK), Pin(GPIO_MAX7219CS), modulesPerRow, modulesPerCol);
|
||||
int intensity = GetDisplayDimmer16(); // 0..15
|
||||
max7219_Matrix->setIntensity(intensity);
|
||||
int orientation = Settings->display_rotate;
|
||||
max7219_Matrix->setOrientation((LedMatrix::ModuleOrientation)orientation );
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("DSP: MAX7291Matrix_init %dx%d modules, orientation: %d, intensity: %d"), modulesPerRow , modulesPerCol, orientation, intensity);
|
||||
max2791Matrix_init_done = true;
|
||||
|
||||
max7219_Matrix->setLed(0, 3, 3, true);
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("DSP: setLed 3,3"));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MAX7291Matrix_On( bool on )
|
||||
{
|
||||
for (int addr = 0; addr < modulesPerRow; addr++)
|
||||
{
|
||||
max7219_Matrix->shutdown (addr, !on); // false: on, true: off
|
||||
}
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("MTX: On %d"), on);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool MAX7291Matrix_Dim(void)
|
||||
{
|
||||
int dim = GetDisplayDimmer16();
|
||||
for (int addr = 0; addr < modulesPerRow; addr++)
|
||||
{
|
||||
max7219_Matrix->setIntensity(addr, dim); // 1..15
|
||||
}
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("DSP: Dim %d"), dim);
|
||||
return true;
|
||||
}
|
||||
|
||||
// /*********************************************************************************************\
|
||||
// * Clears the display
|
||||
// * Command: DisplayClear
|
||||
// \*********************************************************************************************/
|
||||
bool MAX7291Matrix_Clear(void)
|
||||
{
|
||||
for(int addr=0; addr<modulesPerRow; addr++){
|
||||
max7219_Matrix->clearDisplay(addr);
|
||||
}
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("DSP: Clear"));
|
||||
max7219_Matrix->test();
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("DSP: display test"));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -208,17 +183,18 @@ bool MAX7291Matrix_Text()
|
|||
{
|
||||
char sString[CMD_MAX_LEN + 1];
|
||||
subStr(sString, XdrvMailbox.data, ",", 1);
|
||||
MAX7291Matrix_Clear;
|
||||
max7219_Matrix->clear();
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("MTX: sString %s"), sString);
|
||||
|
||||
// test
|
||||
uint8_t length = strlen(sString);
|
||||
//if(length > modulesPerRow)
|
||||
length = modulesPerRow;
|
||||
//if(length > modulesPerRow)
|
||||
length = modulesPerRow;
|
||||
|
||||
for(int addr = 0; addr<length; addr++ ){
|
||||
max7219_Matrix->setLed(addr, 0, 1, true);
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("MTX: setLed() %d, 0, 1)"), addr);
|
||||
for (int addr = 0; addr < length; addr++)
|
||||
{
|
||||
max7219_Matrix->setPixel(addr, addr, true);
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("MTX: setPixel() %d, %d)"), addr, addr);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -226,50 +202,48 @@ bool MAX7291Matrix_Text()
|
|||
|
||||
bool Xdsp19(uint8_t function)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
bool result = false;
|
||||
|
||||
if (FUNC_DISPLAY_INIT_DRIVER == function)
|
||||
{
|
||||
result = MAX7291Matrix_init();
|
||||
}
|
||||
else{
|
||||
//if (max2791Matrix_init_done && (XDSP_19 == Settings->display_model)) {
|
||||
switch (function) {
|
||||
case FUNC_DISPLAY_MODEL:
|
||||
result = true;
|
||||
break;
|
||||
case FUNC_DISPLAY_CLEAR:
|
||||
result = MAX7291Matrix_Clear();
|
||||
break;
|
||||
case FUNC_DISPLAY_DIM:
|
||||
result = MAX7291Matrix_Dim();
|
||||
break;
|
||||
case FUNC_DISPLAY_SEVENSEG_TEXT:
|
||||
case FUNC_DISPLAY_SEVENSEG_TEXTNC:
|
||||
case FUNC_DISPLAY_NUMBER:
|
||||
case FUNC_DISPLAY_NUMBERNC:
|
||||
case FUNC_DISPLAY_FLOAT:
|
||||
case FUNC_DISPLAY_FLOATNC:
|
||||
case FUNC_DISPLAY_RAW:
|
||||
case FUNC_DISPLAY_LEVEL:
|
||||
case FUNC_DISPLAY_SCROLLTEXT:
|
||||
case FUNC_DISPLAY_CLOCK:
|
||||
case FUNC_DISPLAY_DRAW_STRING:
|
||||
result = MAX7291Matrix_Text();
|
||||
break;
|
||||
case FUNC_DISPLAY_EVERY_50_MSECOND:
|
||||
case FUNC_DISPLAY_EVERY_SECOND:
|
||||
// ignore
|
||||
return false;
|
||||
default:
|
||||
result = false;
|
||||
else if (max7219_Matrix && (XDSP_19 == Settings->display_model))
|
||||
{
|
||||
switch (function)
|
||||
{
|
||||
case FUNC_DISPLAY_MODEL:
|
||||
result = true;
|
||||
break;
|
||||
case FUNC_DISPLAY_CLEAR:
|
||||
result = max7219_Matrix->clear();
|
||||
break;
|
||||
case FUNC_DISPLAY_DIM:
|
||||
result = max7219_Matrix->setIntensity(GetDisplayDimmer16());
|
||||
break;
|
||||
case FUNC_DISPLAY_SEVENSEG_TEXT:
|
||||
case FUNC_DISPLAY_SEVENSEG_TEXTNC:
|
||||
case FUNC_DISPLAY_NUMBER:
|
||||
case FUNC_DISPLAY_NUMBERNC:
|
||||
case FUNC_DISPLAY_FLOAT:
|
||||
case FUNC_DISPLAY_FLOATNC:
|
||||
case FUNC_DISPLAY_RAW:
|
||||
case FUNC_DISPLAY_LEVEL:
|
||||
case FUNC_DISPLAY_SCROLLTEXT:
|
||||
case FUNC_DISPLAY_CLOCK:
|
||||
case FUNC_DISPLAY_DRAW_STRING:
|
||||
result = MAX7291Matrix_Text();
|
||||
break;
|
||||
case FUNC_DISPLAY_EVERY_50_MSECOND:
|
||||
case FUNC_DISPLAY_EVERY_SECOND:
|
||||
// ignore
|
||||
return false;
|
||||
default:
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // USE_DISPLAY_MAX7219_MATRIX
|
||||
#endif // USE_DISPLAY
|
||||
|
|
Loading…
Reference in New Issue