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