Publicidade:

segunda-feira, 28 de setembro de 2015

Arduino - Hack da parte frontal de uma impressora HP Deskjet F4280




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);
  
  
}



3 comentários:

  1. muito bom ter pessoas como vc poder compartilha com os outros o que vc sabe que Deus abençoe vc e família e cada dia ele te de saúdes

    ResponderExcluir
  2. Thank you, can you please provide me details on system issues you foresee while you install a printer, any external software to be downloaded?

    hp deskjet 112 installation

    ResponderExcluir
  3. Excellent information.I like the way of writing and presenting.

    123.hp.com/dj1118

    ResponderExcluir