Nesse fim de semana peguei uma impressora velha, uma HP Deskjet F4280 e tentei ver o que dava pra fazer com o display. Analisando os componentes que haviam na placa, identifiquei 3 registradores de deslocamento 595 - clique para ver o datasheet - (expansores de saídas) e 1 165 - clique para ver o datasheet - (expansor de entrada). Essa placa se comunicava com outra placa, através de um cabo flat através de 7 vias. Com ajuda de um multímetro identifiquei onde cada uma das vias estava chegando no circuito:
- 1 - pino 11 do 595 (SH_CP) e pino 2 do 165 (CLOCK)
- 2 - gnd
- 3 - pino 9 do 165 (QH)
- 4 - pino 14 do 595 (DS)
- 5 - vcc
- 6 - pino 12 do 595 (ST_CP) e pino 1 do 165 (LOAD)
- 7 - botão on/off - ligado diretamente
Com os pinos identificados, cortei com um tesoura um das extremidades do cabo flat e separei cada uma das trilhas. Com as pontas separadas, queimei o plástico que fica em volta do cabo flat para que apenas a trilha ficasse exposta, depois com um bombril removi os resíduos de plástico queimado dos terminais. Depois soldei essas trilhas em uma pequena placa, de modo que fosse possível conecta-las com o arduino através de jumpers.
--vou colocar uma foto de como foi feito
conforme as trilhas identificadas e numeradas acima, fiz a seguinte ligações no arduino:
- 1 --> arduino : pino 8
- 2 --> arduino : gnd
- 3 --> arduino : pino 2
- 4 --> arduino : pino 9
- 5 --> arduino : vcc
- 6 --> arduino : pino 10
- 7 --> arduino : não utilizado nesse exemplo. mas poderia ser ligado como qualquer pino e configura-lo como entrada
O próximo passo foi identificar como cada botão e cada led estavam sendo controlados. Os botões são controlados pelo único 165, e ao lado de cada botão (na cor preta) mostro qual o bit que é usado para representá-lo. Os outros 3 595 estão ligados em cascata, e têm suas saídas ligadas nos leds conforme numerados abaixo. O primeiro 595 está na cor Azul, o segundo na cor Vermelha e o terceira na Cor Verde.
Com tudo identificado, o próximo passo foi fazer a programação, pra isso aproveitei uma classe que eu já havia criado pra se comunicar com os registradores 595 e 165 juntos (veja o artigo aqui). Porém, o esquema desse display, não está exatamente da forma que mostrei no artigo citado, mas ainda assim deu pra aproveitar a classe, apenas fazendo algumas modificações. A principal delas, foi que quando é enviado HIGH para acionar um led, os leds são apagados.
Código-fonte:
/* Criado em 27/09/2015 Por: Fabiano A. Arndt http://www.youtube.com/fabianoallex http://fabianoallex.blogspot.com.br fabianoallex@gmail.com */ /******************************************************************************************** *******************CLASSE Expansor74HC595_74HC165 INICIO********************************* *********************************************************************************************/ class Expansor74HC595_74HC165 { private: int _pin_clock; int _pin_latch; int _pin_data; byte* _pins_out; byte* _pins_in; int _num_cis_out; int _num_cis_in; public: Expansor74HC595_74HC165(int pin_clock, int pin_latch, int pin_data, int num_cis_out, int num_cis_in){ _pin_clock = pin_clock; _pin_latch = pin_latch; _pin_data = pin_data; _num_cis_out = num_cis_out; _num_cis_in = num_cis_in; _pins_out = new byte[num_cis_out]; _pins_in = new byte[num_cis_in]; pinMode(_pin_clock,OUTPUT); pinMode(_pin_latch,OUTPUT); clear(); } void clear(){ for (int i=0; i<_num_cis_out; i++){ _pins_out[i] = B11111111; } update(); } void update(){ digitalWrite(_pin_clock, LOW); digitalWrite(_pin_latch, LOW); digitalWrite(_pin_latch, HIGH); for(int i=max(_num_cis_in, _num_cis_out) * 8 - 1; i>=0; i-- ) { //max -->o for vai até o que tiver mais, ou entradas, ou saidas int pos = i / 8; int pin = 7-(i % 8); if (i < _num_cis_in * 8){ pinMode(2, INPUT); if ( digitalRead(2) ){ _pins_in[pos] |= (1 << pin); //set a bit HIGH } else { _pins_in[pos] &= ~(1 << pin); //set a bit LOW } } if (i < _num_cis_out * 8){ pinMode(_pin_data, OUTPUT); digitalWrite(_pin_data, (_pins_out[pos] & (1 << pin)) != 0 ); } digitalWrite(_pin_clock, HIGH); digitalWrite(_pin_clock, LOW); } digitalWrite(_pin_latch, LOW); digitalWrite(_pin_latch, HIGH); //pinMode(_pin_data, INPUT); //removido } int read(int pin){ int pos = pin / 8; pin = 7-(pin % 8); if (pos > _num_cis_out) { pos = pos - _num_cis_out; return ( (_pins_in[pos] & (1 << pin)) != 0 ); } else { return ( (_pins_out[pos] & (1 << pin)) != 0 ); } } byte readByte(int num_ci) { if (num_ci >= _num_cis_out) { num_ci = num_ci - _num_cis_out; return _pins_in[num_ci]; } else { return _pins_out[num_ci]; } } void write(int pin, int value){ if (pin >= _num_cis_out*8) { return; } int pos = pin / 8; //pos -> indica qual ci será atualizado. pin = 7-(pin % 8); if (pos > _num_cis_out) { return; //se estiver tentando escrever um pino de entrada, apenas retorna, sem fazer nada. } else { if (value){ _pins_out[pos] |= (1 << pin); //set a bit HIGH } else { _pins_out[pos] &= ~(1 << pin); //set a bit LOW } } } void writeByte(int num_ci, byte b, int first = MSBFIRST) { if (num_ci > _num_cis_out) { return; //se estiver tentando escrever um pino de entrada, apenas retorna, sem fazer nada. } if (first == LSBFIRST) { byte r=0; for(int i=0;i<8;i++) { r |= ((b>>i) & 0b1)<<(7-i); } b = r; } _pins_out[num_ci] = b; } ; }; /******************************************************************************************** *******************CLASSE Expansor74HC595_74HC165 FIM *********************************** *********************************************************************************************/ const int PIN_CLOCK = 8; const int PIN_LATCH = 10; const int PIN_DATA_595 = 9; const int PIN_DATA_165 = 2; Expansor74HC595_74HC165 * exp1; //controla as saídas Expansor74HC595_74HC165 * exp2; //controla as entradas void setup() { exp1 = new Expansor74HC595_74HC165(PIN_CLOCK, PIN_LATCH, PIN_DATA_595, 3, 0); exp2 = new Expansor74HC595_74HC165(PIN_CLOCK, PIN_LATCH, PIN_DATA_165, 0, 3); exp1->writeByte(0, B11111111); exp1->writeByte(1, B11111111); exp1->writeByte(2, B11111111); Serial.begin(9600); } byte digitos[] = { B01000000, B01011110, B00100100, B00001100, B00011010, B10001000, B10000000, B01011100, B00000000, B00001000, B00010000, B10000010, B11100000, B00000110, B10100000, B10110000 }; byte leds[] = {20, 21, 22, 23, 4, 19, 18, 17, 16, 5}; unsigned int dig=0; unsigned int opt=0; unsigned int led=0; void loop() { exp2->update(); //primeiro verifica o estado dos botões if (!exp2->read(5+16)) { exp1->write(15, !exp1->read(15)); } if (!exp2->read(2+16)) { exp1->write(6, !exp1->read(6)); } if (!exp2->read(0+16)) { dig++; } if (!exp2->read(4+16)) { dig--; } byte temp = exp1->read(15); exp1->writeByte(1, digitos[dig%16]); exp1->write(15, temp); if (!exp2->read(6+16)) { opt++; } exp1->write(1, opt%3+1==1); exp1->write(2, opt%3+1==2); exp1->write(3, opt%3+1==3); if (!exp2->read(3+16)) { for (int i=0; i<10; i++){ exp1->write(leds[i], led%10!=i); } led++; } exp1->update(); //agora envia o estado dos leds Serial.println(exp1->readByte(0), BIN); //LE O PRIMEIRO CI (595) Serial.println(exp1->readByte(1), BIN); //LE O SEGUNDO CI (595) Serial.println(exp1->readByte(2), BIN); //LE O TERCEIRO CI (165) Serial.println(exp2->readByte(2), BIN); //LE O QUARTO CI (165) Serial.println(""); delay(100); }