15 de maio de 2021

Do bit Ao Byte

Embarcados, Linux e programação

Desafio maker 01: Solução

solução | TaskHandle | PORTB | bitwise | bit field | função lambda | função recursiva em C++

Se não viu o “Desafio maker 01: Caixa d’água“, pare a leitura desse artigo e leia-o primeiro.  Agora vamos à solução do desafio proposto.

Solução

A solução é extremamente simples, como citei no desafio. O enunciado foi mais complexo

1 – Criar um array

Primeiramente, como vamos exibir uma mensagem diferente conforme cada condição sem utilizar condicionais? Inicialmente precisamos de um array de array de char para comportar as mensagens. Vai ficar claro mais adiante, mas basicamente criamos um  “cardápio” agora:

char *messages[] = {"Vazio",
                    "25%",
                    "50% (Sensor 1 off)",
                    "50%",
                    "75% (Sensor 1 e 2 off)",
                    "75% (Sensor 2 off)",
                    "75% (Sensor 1 off)",
                    "75%",
                    "100% (Sensor 1,2,3 off)",
                    "100% (Sensor 2 e 3 off)",
                    "100% (Sensor 1 e 3 off)",
                    "100% (Sensor 3 off)",
                    "100% (Sensor 1 e 2 off)",
                    "100% (Sensor 2 off)",
                    "100% (Sensor 1 off)",
                    "100%"};

2 – Definir os pinos das boias

Devemos definir quatro pinos para as boias. Para ficar organizado e objetivo, uma struct me parece uma boa opção:

struct pins_of_pull {
  byte QUARTER = GPIO_NUM_12;
  byte HALF    = GPIO_NUM_27;
  byte TQUART  = GPIO_NUM_25;
  byte FULL    = GPIO_NUM_32;
};

No caso, usei ESP32 quando fiz essa implementação em um projeto de um cliente, por isso a definição do GPIO tem o formato GPIO_NUM_.

Chamei de “polling”, mas isso é indiferente, desde que seu código esteja adaptado para o usar o nome escolhido:

pins_of_pull polling;

3 – Configurar os pinos como INPUT

Em setup() colocamos os pinos em INPUT:

void setup(){
  //Configuração dos pinos de polling - INPUT para leitura
    pinMode(polling.QUARTER,INPUT);
    pinMode(polling.HALF,INPUT);
    pinMode(polling.TQUART,INPUT);
    pinMode(polling.FULL,INPUT);

...
}

Lá no começo do sketch, adicione a variável st:

uint8_t st = 0;

4 – Fazer bitwise com os valores dos pinos

No projeto que fiz utilizei interrupção, mas para o desafio basta fazer polling mesmo. Na função loop() devemos varrer o estado dos pinos a cada 5 segundos, conforme especificado no desafio. Com um deslocamento de bits, descobrimos que mensagem deve ser exibida:

void loop(){
    st = 0;
    st = st|digitalRead(polling.QUARTER)<<0;
    st = st|digitalRead(polling.HALF)<<1;
    st = st|digitalRead(polling.TQUART)<<2;
    st = st|digitalRead(polling.FULL)<<3;

    Serial.println(messages[st]);

    delay(5000);
}

Explicação do código na função loop()

Se não leu, recomendo a leitura do artigo “Dominando PCF8574 com Arduino“, onde detalho o uso de bitwise com mais exemplo. Aqui estamos fazendo o seguinte:

  • Zerando a variável st.
  • Colocando o valor da boia de 25% na posição 0.
  • Colocando o valor da boia de 50% na posição 1.
  • Colocando o valor da boia de 75% na posição 2.
  • Colocando o valor da boia de 100% na posição 3.

Como extraímos 16 valores de 4 estados? – Simples. São 4 bits, que em binário são 0b1111, ou 15 em decimal. Com o valor 0, temos 16 condições. Quando empurramos o valor da boia de 100% (3), se for 1 e o resto 0, o valor da variável st será 8. No print da função loop será exibida a mensagem “100% (Sensor 1,2,3 off)“. Pra ficar mais claro, os valores possíveis são:

0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111

E o que definirá a sequência de bits será o estado de cada pino, conforme coletado no loop e colocado em sua respectiva posição. Compare com o array, dá pra fazer o teste de cabeça. Qual seria a mensagem para 1011? De cara da pra ver que uma boia falhou.

E essa é a solução para o Desafio maker 01. Nos próximos devo dar um intervalo maior para a resposta, esse fica como amostra da intenção. Gostou? Comente lá na página no facebook!

Saravati

Esse artigo é um oferecimento da Saravati, que possui loja online e física (na Santa Efigênia, em São Paulo). Passe no site para conferir a variedade e divirta-se.

Até o próximo desafio!