Command for all Modules at once

This commit is contained in:
Michael 2021-11-30 14:18:26 +01:00
parent 5b3266e7ca
commit 09974f8873
4 changed files with 104 additions and 29 deletions

View File

@ -55,18 +55,20 @@ LedControl::LedControl(int dataPin, int clkPin, int csPin, int numDevices) {
pinMode(SPI_CS,OUTPUT);
digitalWrite(SPI_CS,HIGH);
SPI_MOSI=dataPin;
for (int i = 0; i < 8 * MAX72XX_MAX_DEVICES; i++)
status[i] = 0x00;
for(int i=0;i<maxDevices;i++) {
spiTransfer(i,OP_DISPLAYTEST,0);
//scanlimit is set to max on startup
setScanLimit(i,7);
//decode is done in source
spiTransfer(i,OP_DECODEMODE,0);
clearDisplay(i);
//we go into shutdown-mode on startup
shutdown(i,true);
}
memset(status, (byte)0, 8 * MAX72XX_MAX_DEVICES);
memset(deviceDataBuff, (byte)0, MAX72XX_MAX_DEVICES);
// display test
spiTransfer_allDevices(OP_DISPLAYTEST, deviceDataBuff);
//scanlimit is set to max on startup
setScanLimit_allDevices(7);
//decode is done in source
memset(deviceDataBuff, (byte)0, MAX72XX_MAX_DEVICES);
spiTransfer_allDevices(OP_DECODEMODE, deviceDataBuff);
clearDisplay_allDevices();
//we go into shutdown-mode on startup
shutdown_allDevices(true);
}
int LedControl::getDeviceCount() {
@ -82,6 +84,11 @@ void LedControl::shutdown(int addr, bool b) {
spiTransfer(addr, OP_SHUTDOWN,1);
}
void LedControl::shutdown_allDevices(bool b) {
memset(deviceDataBuff, (byte)b, maxDevices);
spiTransfer_allDevices(OP_SHUTDOWN, deviceDataBuff);
}
void LedControl::setScanLimit(int addr, int limit) {
if(addr<0 || addr>=maxDevices)
return;
@ -89,6 +96,13 @@ void LedControl::setScanLimit(int addr, int limit) {
spiTransfer(addr, OP_SCANLIMIT,limit);
}
void LedControl::setScanLimit_allDevices(int limit) {
if(limit <0 || limit>8) return;
memset(deviceDataBuff, (byte)limit, maxDevices);
spiTransfer_allDevices(OP_SCANLIMIT,deviceDataBuff);
}
void LedControl::setIntensity(int addr, int intensity) {
if(addr<0 || addr>=maxDevices)
return;
@ -96,6 +110,15 @@ void LedControl::setIntensity(int addr, int intensity) {
spiTransfer(addr, OP_INTENSITY,intensity);
}
void LedControl::setIntensity_allDevices(int intensity)
{
if (intensity < 0 | intensity > 15)
return;
memset(deviceDataBuff, (byte)intensity, maxDevices);
spiTransfer_allDevices(OP_INTENSITY, deviceDataBuff);
}
void LedControl::clearDisplay(int addr) {
int offset;
@ -108,6 +131,16 @@ void LedControl::clearDisplay(int addr) {
}
}
void LedControl::clearDisplay_allDevices()
{
memset(status, (byte)0, 8 * maxDevices);
memset(deviceDataBuff, (byte)0, maxDevices);
for (int row = 0; row < 8; row++)
{
spiTransfer_allDevices(row + 1, deviceDataBuff);
}
}
void LedControl::setLed(int addr, int row, int column, boolean state) {
int offset;
byte val=0x00;
@ -138,13 +171,13 @@ void LedControl::setRow(int addr, int row, byte value) {
spiTransfer(addr, row+1,status[offset+row]);
}
void LedControl::setRowLong(int row, byte *value)
void LedControl::setRow_allDevices(int row, byte *value)
{
if (row < 0 || row > 7)
return;
for (int addr = 0; addr < maxDevices; addr++)
status[addr * 8 + row] = value[addr];
spiTransferLong(row + 1, value);
spiTransfer_allDevices(row + 1, value);
}
void LedControl::setColumn(int addr, int col, byte value) {
@ -217,7 +250,7 @@ void LedControl::spiTransfer(int addr, volatile byte opcode, volatile byte data)
digitalWrite(SPI_CS,HIGH);
}
void LedControl::spiTransferLong(byte opcode, const byte* data) {
void LedControl::spiTransfer_allDevices(byte opcode, const byte* data) {
//Create an array with the data to shift out
for (int addr = 0; addr < maxDevices; addr++)
{
@ -227,8 +260,8 @@ void LedControl::spiTransferLong(byte opcode, const byte* data) {
//enable the line
digitalWrite(SPI_CS, LOW);
//Now shift out the data
for (int i = maxDevices * 2; i > 0; i--)
shiftOut(SPI_MOSI, SPI_CLK, MSBFIRST, spidata[i - 1]);
for (int i = maxDevices * 2 -1; i >= 0; i--)
shiftOut(SPI_MOSI, SPI_CLK, MSBFIRST, spidata[i]);
//latch the data onto the display
digitalWrite(SPI_CS, HIGH);
}

View File

@ -69,10 +69,11 @@ class LedControl {
/* Send out a single command to one device */
void spiTransfer(int addr, byte opcode, byte data);
/* Send out a command with the same opcode to all devices */
void spiTransferLong(byte opcode, const byte* data);
void spiTransfer_allDevices(byte opcode, const byte* data);
/* We keep track of the led-status for all 8 devices in this array */
byte status[8 * MAX72XX_MAX_DEVICES];
byte deviceDataBuff[MAX72XX_MAX_DEVICES];
/* Data is shifted out of this pin*/
int SPI_MOSI;
/* The clock is signaled on this pin */
@ -108,6 +109,7 @@ class LedControl {
* for normal operation.
*/
void shutdown(int addr, bool status);
void shutdown_allDevices( bool status);
/*
* Set the number of digits (or rows) to be displayed.
@ -118,6 +120,7 @@ class LedControl {
* limit number of digits to be displayed (1..8)
*/
void setScanLimit(int addr, int limit);
void setScanLimit_allDevices(int limit);
/*
* Set the brightness of the display.
@ -126,6 +129,7 @@ class LedControl {
* intensity the brightness of the display. (0..15)
*/
void setIntensity(int addr, int intensity);
void setIntensity_allDevices(int intensity);
/*
* Switch all Leds on the display off.
@ -133,6 +137,7 @@ class LedControl {
* addr address of the display to control
*/
void clearDisplay(int addr);
void clearDisplay_allDevices();
/*
* Set the status of a single Led.
@ -161,7 +166,7 @@ class LedControl {
* @param row [0..8]
* @param value array of bytes, one for each device
*/
void setRowLong(int row, byte* value);
void setRow_allDevices(int row, byte* value);
/*
* Set all 8 Led's in a column to a new state

View File

@ -139,10 +139,7 @@ bool LedMatrix::clearDisplay(void)
bool LedMatrix::setIntensity(byte dim)
{
for (int addr = 0; addr < modules; addr++)
{
ledControl->setIntensity(addr, dim); // 1..15
}
ledControl->setIntensity_allDevices(dim); // 1..15
return true;
}
@ -183,9 +180,51 @@ bool LedMatrix::setPixel(const int x, const int y, bool on)
void LedMatrix::refresh()
{
for (int i = 0; i < modulesPerRow * displayHeight; i++)
int col = 0;
int pixelRow = 0;
int bufPos = 0;
int deviceRow = 0;
for(int ledRow = 7; ledRow >= 0; ledRow--) // refresh from buttom to top
{
refreshByteOfBuffer(i);
for( int addr = 0; addr < modules; addr++)
{
switch(moduleOrientation)
{
case ORIENTATION_NORMAL:
col = addr % modulesPerRow;
pixelRow = (addr / modulesPerRow) * 8 + ledRow;
bufPos = pixelRow * modulesPerRow + col;
deviceDataBuff[addr] = buffer[bufPos];
deviceRow = ledRow;
break;
case ORIENTATION_UPSIDE_DOWN:
col = addr % modulesPerRow;
pixelRow = (addr / modulesPerRow) * 8 + deviceRow;
bufPos = pixelRow * modulesPerRow + col;
deviceDataBuff[addr] = revereBitorder(buffer[bufPos]); // mirror
deviceRow = 7 - ledRow; // upside down
break;
}
if(moduleOrientation == ORIENTATION_NORMAL || moduleOrientation == ORIENTATION_UPSIDE_DOWN)
{
col = addr % modulesPerRow;
pixelRow = (addr / modulesPerRow) * 8 + ledRow;
bufPos = pixelRow * modulesPerRow + col;
if(moduleOrientation == ORIENTATION_NORMAL)
{
// ORIENTATION_NORMAL
deviceDataBuff[addr] = buffer[bufPos];
deviceRow = ledRow;
}
else
{
// ORIENTATION_UPSIDE_DOWN
deviceDataBuff[addr] = revereBitorder(buffer[bufPos]); // mirror
deviceRow = 7 - ledRow; // upside down
}
}
}
ledControl->setRow_allDevices(deviceRow, deviceDataBuff); // upside down
}
}
@ -227,10 +266,7 @@ bool LedMatrix::shutdown(bool b)
bool LedMatrix::clear(void)
{
memset(buffer, 0, MATRIX_BUFFER_SIZE);
for (int addr = 0; addr < modules; addr++)
{
ledControl->clearDisplay(addr);
}
ledControl->clearDisplay_allDevices();
return true;
}

View File

@ -154,6 +154,7 @@ class LedMatrix
unsigned int modules; // number of 8x8 mudules
uint8_t moduleOrientation;
byte buffer[MATRIX_BUFFER_SIZE];
byte deviceDataBuff[MAX72XX_MAX_DEVICES];
LedControl* ledControl;
int charWidth;
int charHeight;