Algumas alterações feitas na biblioteca LedControl.
Quando usamos repetidamente o método setLed da biblioteca LedControl, percebemos um atraso na atualização dos displays (como pode ser visto no vídeo abaixo). Isso acontece, pois a cada chamada de setLed, é feito o envio do status de todos os leds do display, inclusive, os que não tiveram alterações, o que compromete muito a eficiência do código.
Para melhorar a performance da biblioteca foi incluída uma nova funcionalidade, a qual permite atualizar os status dos leds sem enviar os dados para os registradores de deslocamento (Max7219), ou seja, as alterações são mantidas na memória, e depois do processamento terminado, os dados são, então, enviados todos de uma única vez aos registradores. Essa funcionalidade se chama "Auto Send".
Por default a biblioteca funciona da mesma forma que é originalmente, com o auto send igual a true, ou seja, cada chamada a clear(), setLed(), setRow() ou setColumn() continua enviando os dados aos registradores. Mas caso o programador queira fazer um conjunto de alterações nos leds e só enviar as informações para os registradores após todas as alterações estarem prontas, deve-se então, usar o método startWrite().
Depois de chamado startWrite(), os dados serão alterados mas apenas na memória e só serão enviados aos registradores através de um outro método que foi criado. O método send().
No código-fonte a baixo, vemos o uso desses dois métodos, na função update_display. Como pode ser visto, antes de iniciar o processamento dos dados, é feita uma chamada a startWrite(), e ao final uma chamada a send().
void update_displays() {
lc.startWrite();
for (int lin=0; lin<8; lin++) {
for (int col=0; col<16; col++) {
for (int i=0; i<2; i++) {
int l = lin;
int c = col - (i*8);
if (l>=0 && l<=7 && c>=0 && c<=7) {
lc.setLed(i, l, c, (l+c+cont)%2 );
}
}
}
}
cont++;
lc.send();
}
Observações: No código abaixo, foram removidas as funcionalidades voltadas ao uso de displays de 7 segmentos, pois não serão utilizados nos meu projetos futuros, mas nada impede que sejam inclusos novamente.
Código-fonte:
/*************************************************************************************************************
*******************************LEDCONTROL ALTERADA************************************************************
**************************************************************************************************************/
//the opcodes for the MAX7221 and MAX7219
#define OP_DECODEMODE 9
#define OP_INTENSITY 10
#define OP_SCANLIMIT 11
#define OP_SHUTDOWN 12
#define OP_DISPLAYTEST 15
class LedControl {
private :
byte spidata[16];
byte * status;
int SPI_MOSI;
int SPI_CLK;
int SPI_CS;
int maxDevices;
int _auto_send;
void spiTransfer(int addr, volatile byte opcode, volatile byte data) {
int offset = addr*2;
int maxbytes = maxDevices*2;
for(int i=0;i<maxbytes;i++) { spidata[i]=(byte)0; }
spidata[offset+1] = opcode;
spidata[offset] = data;
digitalWrite(SPI_CS,LOW);
for(int i=maxbytes;i>0;i--) { shiftOut(SPI_MOSI,SPI_CLK,MSBFIRST,spidata[i-1]); }
digitalWrite(SPI_CS,HIGH);
}
public:
LedControl(int dataPin, int clkPin, int csPin, int numDevices) {
_auto_send = true;
SPI_MOSI = dataPin;
SPI_CLK = clkPin;
SPI_CS = csPin;
maxDevices = numDevices;
pinMode(SPI_MOSI, OUTPUT);
pinMode(SPI_CLK, OUTPUT);
pinMode(SPI_CS, OUTPUT);
digitalWrite(SPI_CS, HIGH);
status = new byte[maxDevices * 8]; //instancia o array de acordo com a quantia de displays usados
for(int i=0;i<maxDevices * 8 ;i++) { status[i]=0x00; }
for(int i=0;i<maxDevices;i++) {
spiTransfer(i, OP_DISPLAYTEST,0);
setScanLimit(i, 7); //scanlimit is set to max on startup
spiTransfer(i, OP_DECODEMODE,0); //decode is done in source
clearDisplay(i);
shutdown(i,true); //we go into shutdown-mode on startup
}
}
void startWrite() { _auto_send = false; };
void send() {
for (int j=0; j<maxDevices; j++) {
int offset = j*8;
for(int i=0;i<8;i++) { spiTransfer(j, i+1, status[offset+i]); }
}
_auto_send = true;
}
int getDeviceCount(){ return maxDevices; }
void shutdown(int addr, bool b){
if(addr<0 || addr>=maxDevices) return;
spiTransfer(addr, OP_SHUTDOWN, b ? 0 : 1);
}
void setScanLimit(int addr, int limit){
if(addr<0 || addr>=maxDevices) return;
if(limit>=0 && limit<8) spiTransfer(addr, OP_SCANLIMIT,limit);
}
void setIntensity(int addr, int intensity) {
if(addr<0 || addr>=maxDevices) { return; }
if(intensity>=0 && intensity<16) { spiTransfer(addr, OP_INTENSITY, intensity); }
}
void clearDisplay(int addr){
if(addr<0 || addr>=maxDevices) return;
int offset = addr*8;
for(int i=0;i<8;i++) {
status[offset+i] = 0;
if (_auto_send) { spiTransfer(addr, i+1, status[offset+i]); }
}
}
void setLed(int addr, int row, int column, boolean state) {
if(addr<0 || addr>=maxDevices) { return; }
if(row<0 || row>7 || column<0 || column>7) { return; }
int offset = addr*8;
byte val = B10000000 >> column;
if(state) { status[offset+row] = status[offset+row] | val; }
else {
val=~val;
status[offset+row] = status[offset+row]&val;
}
if (_auto_send) { spiTransfer(addr, row+1, status[offset+row]); }
}
void setRow(int addr, int row, byte value) {
if(addr<0 || addr>=maxDevices) return;
if(row<0 || row>7) return;
int offset = addr*8;
status[offset+row] = value;
if (_auto_send) {
spiTransfer(addr, row+1, status[offset+row]);
}
}
void setColumn(int addr, int col, byte value) {
if(addr<0 || addr>=maxDevices) return;
if(col<0 || col>7) return;
byte val;
for(int row=0; row<8; row++) {
val=value >> (7-row);
val=val & 0x01;
setLed(addr,row,col,val);
}
}
};
/*************************************************************************************************************
*******************************FIM LEDCONTROL ALTERADA********************************************************
**************************************************************************************************************/
/*
pin 4 is connected to the DataIn
pin 6 is connected to the CLK
pin 5 is connected to LOAD
*/
LedControl lc=LedControl(4,6,5,2);
const int LINHAS = 8;
const int COLUNAS = 16;
int cont=0;
void update_displays() {
lc.startWrite();
for (int lin=0; lin<8; lin++) {
for (int col=0; col<16; col++) {
for (int i=0; i<2; i++) {
int l = lin;
int c = col - (i*8);
if (l>=0 && l<=7 && c>=0 && c<=7) {
lc.setLed(i, l, c, (l+c+cont)%2 );
}
}
}
}
cont++;
lc.send();
}
void setup() {
lc.shutdown(0,false);
lc.setIntensity(0,8);
lc.clearDisplay(0);
lc.shutdown(1,false);
lc.setIntensity(1,8);
lc.clearDisplay(1);
Serial.begin(9600);
}
void loop() {
update_displays();
for(int i=0;i<LINHAS;i++){
for(int j=0;j<COLUNAS;j++){
Serial.print( (i+j)%2 );
Serial.print(" ");
}
Serial.println(" ");
}
Serial.println(" ");
delay(2000);
}
Nenhum comentário:
Postar um comentário