Manual

do

Maker

.

com

Como expandir GPIO do Digispark Attiny85

Como expandir GPIO do Digispark Attiny85

O Digispark é viciante, principalmente esse modelo que não necessita de cabo, basta encaixá-lo na USB do computador para programá-lo ou em um carregador de celular para utilizá-lo. O dispositivo é tão pequeno que tive várias ideias pra ele e vou escrevendo conforme possível. Dessa vez, vamos ver como expandir GPIO do Digispark.

Se você ainda não utilizou o Digispark e/ou não o conhece, sugiro esses artigos que escrevi a respeito:

Apesar de tanta praticidade, o lado negativo de seu tamanho reduzido está no conjunto reduzido de recursos, dentre eles, os pinos. E é esse o problema que iremos contornar nesse artigo.

expandir GPIO do Digispark com PCF8574 (digital)

Se você precisa de mais pinos digitais, você pode utilizar um PCF8574 como entrada e saída. Com ele você expande de 8 portas a até 127x8 portas, pois utiliza-se do barramento I²C, de modo que você pode tê-los interconectados.

Com um PCF8574 você pode ter entradas e saídas em apenas 1 circuito e se desejar, pode utilizar interrupção, pois o PCF8574 conta com um pino extra apenas para interrupção. Assim, invés de ficar fazendo polling, você pode deixar a MCU sem processamento e reagindo somente no momento de um evento. Alguns artigos que escrevi sobre o PCF8574:

Expandindo ADC com ADS1115 (analógico)

Se sua necessidade é leitura analógica, do mesmo modo poderá fazê-lo com um módulo ADS1115. Trata-se de um módulo com excelente resolução (16 bits!) e também utiliza-se do barramento I²C. Uma introdução ótima a respeito pode ser vista nesse artigo que escrevi a respeito.

Pondo em prática

Essa referências anteriormente citadas são ótimas e certamente resolverão qualquer necessidade, mas atualmente o Digispark não precisa de nenhum port da biblioteca I²C do Arduino porque ele já vem funcionando com uma versão compatível do Wire, inclusive você encontra nos exemplo da IDE do Arduino (após configurar o suporte à Digispark, descrito nesse artigo)

Pinos I²C

Os pinos relacionados ao I²C são Pin0 para SDA e Pin2 para SCK. Sobre a board você encontra um silk com a nomeclatura dos pinos, não tem erro.

ADC

Antes que você compre um ADS1115, tenha em mente que o Attiny faz leitura analógica também, só use o ADS1115 para o caso de precisar expandir.

 

Wiring do PCF8574

O wiring você já sabe, como citado mais acima; Pin0 para SDA e Pin2 para SCK. Além desses dois, você deve alimentar o PCF8574 com 5V e também conectar o GND.

Código

Um código bastante simples mas que servirá de exemplo é esse a seguir. Você precisará incluir a biblioteca TinyWireM.h, ajustar o endereço do PCF8574 e iniciar a comunicação. A comunicação é por I²C e você terá que iniciar a transmissão, escrever e finalizar a conexão. Quando quiser ler, simplesmente chame o método passando o endereço como referência, então pegue o valor com o método .receive(). Para não ficar repetindo linha, é uma boa opção criar uma função para escrever e uma para ler, só pra facilitar. No exemplo não seria necessário, mas vou deixar pronto para lhe poupar trabalho, ok?

 

I²C scanner

Utilize primeiramente o scanner I²C (dos exemplos da IDE do Arduino para o Digispark) caso não saiba o endereço em que se encontra seu PCF8574. Olhando para o PCF8574 com os pinos voltados para a esquerda, os jumpers todos para a direita representa o endereço 0x20. Caso deseje utilizar mais que um PCF8574 simultaneamente, o scanner ajudará identificá-los, apenas lembre-se de não deixá-los ambos com o mesmo endereço. Vou deixar o código caso tenha preguiça de procurá-lo:

#include <Wire.h>
#include <DigiKeyboard.h>

void setup()
{

  Wire.begin();
  DigiKeyboard.delay(3000);

  DigiKeyboard.println("\nI2C Scanner");
}


void loop()
{
  byte error, address;
  int nDevices;

  DigiKeyboard.println("Scanning...");

  nDevices = 0;
  for (address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      DigiKeyboard.print("I2C device found at address 0x");
      if (address < 16)
        DigiKeyboard.print("0");
      DigiKeyboard.print(address, HEX);
      DigiKeyboard.println("  !");

      nDevices++;
    }
    else if (error == 4)
    {
      DigiKeyboard.print("Unknow error at address 0x");
      if (address < 16)
        DigiKeyboard.print("0");
      DigiKeyboard.println(address, HEX);
    }
  }
  if (nDevices == 0)
    DigiKeyboard.println("No I2C devices found\n");
  else
    DigiKeyboard.println("done\n");

  DigiKeyboard.delay(5000);           // wait 5 seconds for next scan
}

lembre-se desse artigo no que se refere ao debug do Digispark; ele não tem monitor serial, portanto você deverá abrir um editor de texto qualquer e colocá-lo em foco. O Digispark atuará como um teclado USB e "escreverá" o resultado do scan no editor de texto. Depois de identificar o endereço, adapte-o ao código a seguir.

Usando o PCF8574 com o Digispark

Um tutorial bem elaborado sobre a manipulação de endereços pode ser vista aqui, recomendo a leitura. Se não estiver com vontade de fazer a leitura desse outro artigo ou já tiver conhecimento o suficiente para interação com o PCF8574, então siga adiante. Apesar desse artigo ser sobre PCF8574 com Raspberry, cito características importantes dele, como por exemplo, para acender um LED você deve aterrá-lo no PCF8574 invés de alimentá-lo a partir do PCF8574 porque o dispositivo não tem corrente suficiente para "drivar" um LED. Como inicialmente todos os pinos do PCF8574 estão em HIGH, você não terá problemas em controlar o LED com estado inicial desligado.

Vou deixar a mesma tabela que montei no artigo supracitado para utilizar com referência para nosso teste.

Addr1286432168421
0xF00x400x200x100x080x040x020x01
0x20
0x22
0x24
87654321

Como você pode notar na tabela, os endereços estão dispostos nas base decimal, hexadecimal e a posição do bit. Na coluna na esquerda "Addr" são os endereços de 3 PCF8574 que utilizei em outro teste. Então, se você quiser acender o LED que está no pino 4 do PCF8574 que está no endereço 0x20, basta enviar 0x08 para 0x20. Vamos ver isso no código?

#include <Wire.h>

void setup()
{
  Wire.begin();
}


void loop()
{

  Wire.beginTransmission(0x20);
  Wire.beginTransmission(0x20);
  Wire.send(0b00000000);
  Wire.endTransmission();
  delay(1000);

  Wire.beginTransmission(0x20);
  Wire.send(0b00000001);
  Wire.endTransmission();
  delay(1000);

  Wire.beginTransmission(0x20);
  Wire.send(0b00000010);
  Wire.endTransmission();
  delay(1000);

  Wire.beginTransmission(0x20);
  Wire.send(0b00000011);
  Wire.endTransmission();
  delay(1000);
}

O código está pra lá de horroroso, mas é só pra mostrar a lógica; inicia a transmissão pro endereço selecionado, envia o dado, encerra a transmissão. Ponto.

Espero que lhe tenha sido útil esse pequeno tutorial.

https://youtu.be/tpkRzf0FA5k

Inscreva-se no nosso canal Manual do Maker no YouTube.

Também estamos no Instagram.

Nome do Autor

Djames Suhanko

Autor do blog "Do bit Ao Byte / Manual do Maker".

Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.