Veja a página da tarefa em grupo.
Comecei esta tarefa com a intenção de melhorar a automação da irrigação da fazenda. A gente já tem um ESP8266 controlando uma bomba e 4 relés e monitorando a corrente da bomba. O problema é que o ESP8266, com o programa dele, não responde bem, e isso faz com que configurar os horários leve muito tempo. Isso acontece por causa de uma limitação no número de pinos ADC. Quem me explicou foi o Shakeel, um voluntário que a gente teve na fazenda: o ESP8266 usa o único pino ADC que tem para monitorar a conexão wifi, então ele criou um programa que reduz as amostras feitas pelo amperímetro para poder dividir o pino com o wifi. Bom, isso funciona, mas deixa a conexão wifi instável, então meu desafio vai ser tentar entender o ESP32 para conseguir portar o programa dele e, ao mesmo tempo, completar a tarefa. Vamos tentar!
A outra coisa que eu queria destacar é que vou focar mais no código, porque já mostrei o processo de fabricação de placas nas outras semanas. Além disso, uma grande mudança na forma como faço a tarefa é que vou documentar enquanto aprendo e faço as coisas, então a tarefa vai parecer mais um diário do que um tutorial.
Meu objetivo inicial vai ser entender melhor o ESP32; depois, como segundo objetivo, fazer ele substituir o controle de irrigação atual; o terceiro objetivo vai ser aplicar tudo isso no meu projeto final da chocadeira.

Comecei olhando o site techtutorialsx.com.
Como a página explica, o código para ligar um relé é bem parecido com outros códigos de Arduino que já vi, então vamos ver.
Vou usar int pumprelayPin1 = 22; para definir a variável pumprelayPin1 como o pino 22, e ela vai guardar o valor como um inteiro.
pinMode(pumprelayPin1, OUTPUT); define o modo do pino pumprelayPin1 como saída, ou seja, ele vai ser ativo, ao contrário de uma entrada, que fica monitorando um sinal de forma passiva.
digitalWrite(pumprelayPin1, LOW); vai colocar o pino no estado desligado com o LOW.
delay(4000); vai mandar o programa esperar 4 segundos, ou 4000 milissegundos.
É assim que meu código está até agora:
int pumprelayPin1 = 22;
void setup() {
pinMode(pumprelayPin1, OUTPUT);
digitalWrite(pumprelayPin1, LOW);
}
void loop() {
digitalWrite(pumprelayPin1, HIGH);
delay(4000);
digitalWrite(pumprelayPin1, LOW);
delay(4000);
}
Até aqui, este código vai iniciar e depois ligar e desligar o relé com 4 segundos entre cada operação.
Agora, para a segunda parte, quero pegar a hora de um relógio de tempo real (RTC) para ligar a bomba em certos horários. Então, primeiro preciso incluir a biblioteca do relógio RTC. Estou usando um chip de relógio RTC DS1302, então esta biblioteca deve resolver com este código #include <virtuabotixRTC.h>, de acordo com a documentação da biblioteca aqui.
Segundo, a gente precisa declarar os pinos do relógio RTC com este código virtuabotixRTC myRTC(5, 18, 19); e RtcDS1302<ThreeWire> Rtc(myWire);. Isso quer dizer que, quando o ESP32 se comunicar com o chip do relógio de tempo real, ele vai usar o pino 5 para CLK, o 18 para DAT e o 19 para RST.
Atenção: RtcDS1302<ThreeWire> Rtc(myWire); é de outra biblioteca (a Rtc do Makuna, RtcDS1302.h) e myWire nunca é definido, então essa linha não compila do jeito que está. Com a biblioteca virtuabotixRTC usada aqui, basta virtuabotixRTC myRTC(5, 18, 19);.
Agora, para mostrar a hora do relógio de tempo real, coloco isto na área void setup() {} ou na área void loop() {}. A primeira vai imprimir uma vez só; a segunda vai imprimir enquanto eu deixar rodando. Claro que a gente precisa colocar um delay de pelo menos um minuto com delay(60000);. A unidade da variável é milissegundo, então 1000 quer dizer 1 segundo e 60000 quer dizer 60 segundos.
Serial.begin(115200);
myRTC.updateTime();
Serial.println();
Se o RTC nunca foi usado antes, você pode acertar a hora rodando uma vez o seguinte código: myRTC.setDS1302Time(00, 28, 16, 7, 23, 5, 2020);, sendo os primeiros números os segundos, depois minutos, horas (modo 24h), dia da semana, dia do mês, mês e ano. (Corrigido depois: o dia da semana conta a partir de 1 = domingo, então sábado 23/05/2020 é 7 e domingo 24/05/2020 é 1; o código tinha 6 nos dois.)
É assim que o código está ficando:
#include <virtuabotixRTC.h>
virtuabotixRTC myRTC(5, 18, 19);// (CLK,DAT,RST)
int pumprelayPin1 = 22;
void setup() {
Serial.begin(115200);
pinMode(pumprelayPin1, OUTPUT);
}
void loop() {
myRTC.updateTime();
Serial.print(myRTC.hours);
Serial.print(":");
Serial.print(myRTC.minutes);
delay(58000);
digitalWrite(pumprelayPin1, HIGH);
delay(1000);
digitalWrite(pumprelayPin1, LOW);
delay(1000);
}
Até aqui não tem nenhum teste lógico: o código mostra a hora a cada minuto e liga e desliga o relé. Então, para adicionar um teste lógico, a gente precisa do comando if. Ele verifica se alguma coisa é verdadeira e aí executa o que vem em seguida no programa.
Tirado da referência do Arduino:
if (condition) {
//statement(s)
}
Então, para verificar a hora e ligar meu relé, vou tentar algo assim: if ((myRTC.hours) == 15 && (myRTC.minutes) == 0) {digitalWrite(pumprelayPin1, HIGH);}
Para desligar, o código vai ser assim: if ((myRTC.hours) >= 15 && (myRTC.minutes) >= 1) {digitalWrite(pumprelayPin1, LOW);}
Agora meu código está assim:
//libraries
#include <virtuabotixRTC.h>
//Settings
virtuabotixRTC myRTC(5, 18, 19);// (CLK,DAT,RST)
int pumprelayPin1 = 22;
//run once
void setup() {
Serial.begin(115200);
myRTC.setDS1302Time(50, 15, 16, 1, 24, 5, 2020); // sets seconds, minutes, hours (24h mode), day of the week, day, month, year) comment after first compile
pinMode(pumprelayPin1, OUTPUT);
}
//run in loop
void loop() {
myRTC.updateTime();//updates time
Serial.print("Current Time: ");
Serial.print(myRTC.hours);
Serial.print(":");
Serial.print(myRTC.minutes);
Serial.print(":");
Serial.print(myRTC.seconds);
Serial.println();
delay (1000);
//condition (logic test)
if ((myRTC.minutes) == 16) digitalWrite(pumprelayPin1, HIGH);
if ((myRTC.minutes) >= 17) digitalWrite(pumprelayPin1, LOW);
}
Veja como ele roda na placa de desenvolvimento ESP32:
Para esta placa vou precisar de pelo menos 4 pinos digitais, e de um pino analógico se eu quiser medir a corrente da bomba no futuro. Então acho que o ATtiny44 vai dar conta. Vou deixar o ESP32 para a semana de Networking ;-). Além disso, meus componentes SMD de ESP32 ainda não chegaram; acho que é por causa da quebra das cadeias de fornecimento com a COVID-19. Por isso fiz os experimentos com a placa de desenvolvimento ESP32 que eu tinha à mão.

Com isso em mãos, vou modificar a placa tiny45 que fiz na semana de Input Devices, adicionando mais um header para programar e monitorar a serial com mais conforto, além de todos os pinos, para deixar esta placa o mais modular possível.
Não vou detalhar o design no Eagle nem a fresagem, porque já fiz isso na semana de Input Devices. Em vez disso, vou mostrar só os comandos que talvez eu não tenha usado, como o replace, e depois algumas hero shots e testes.
Então vamos começar o redesign!
Estes são o esquemático e o layout da placa:
Layout da placa
Depois rodo a ULP pcb-gcode, do jeito que expliquei em Input Devices.
Visualização do G-code de isolamento
Depois uso o programa Autoleveller, também explicado em Input Devices, e consigo um G-code ajustado às imperfeições da placa virgem.
Resultado do Autoleveller
Fresando a placa
A placa fresada
Placa fresada
A placa ATtiny44 com os componentes soldados fica assim.
Placa montada
Agora que a placa está pronta, mudei o código para rodar no ATtiny44. Uma coisa que vale destacar é que o ATtiny44 precisa de uma biblioteca de serial por software, que chamei com este código #include <SoftwareSerial.h>. Mais duas coisas para a serial funcionar: a biblioteca precisa saber quais pinos vão ser o RX e o TX, SoftwareSerial Monitor(1, 0);; em void setup() {} coloquei a inicialização do monitor serial com Monitor.begin(115200); em vez do habitual Serial.begin(115200);; e, por fim, em void loop() {}, toda vez que eu queria que a serial imprimisse alguma coisa, precisava usar o código Monitor.print(); em vez do habitual Serial.print();.
No fim, meu código de teste ficou assim:
//libraries
#include <virtuabotixRTC.h>
#include <SoftwareSerial.h>
//Settings
virtuabotixRTC myRTC(3, 8, 7);// (CLK,DAT,RST)
int pumprelayPin1 = 2;
SoftwareSerial Monitor(1, 0);
//run once
void setup() {
Monitor.begin(115200);
myRTC.setDS1302Time(50, 15, 16, 1, 24, 5, 2020); // sets seconds, minutes, hours (24h mode), day of the week, day, month, year) comment after first compile
pinMode(pumprelayPin1, OUTPUT);
}
//run in loop
void loop() {
myRTC.updateTime();//updates time
Monitor.print("Current Time: ");
Monitor.print(myRTC.hours);
Monitor.print(":");
Monitor.print(myRTC.minutes);
Monitor.print(":");
Monitor.print(myRTC.seconds);
Monitor.println();
delay (1000);
//condition (logic test)
if ((myRTC.minutes) == 16) digitalWrite(pumprelayPin1, HIGH);
if ((myRTC.minutes) >= 17) digitalWrite(pumprelayPin1, LOW);
}
Atenção: SoftwareSerial a 115200 baud no ATtiny44 rodando com o oscilador interno de 8 MHz é pouco confiável (o erro de tempo embaralha os caracteres). Use Monitor.begin(9600); e coloque o monitor serial em 9600, que é a velocidade segura.
Agora vamos programar! Para outro método sem a Arduino IDE, veja Embedded Programming.
USBasp
Programando uma placa ATtiny44 com Arduino usando o USBasp.
FabISP
Programar uma placa ATtiny44 com Arduino usando um FabTinyISP ou USBtinyISP que eu fiz foi tranquilo. O único inconveniente é ter que alimentar a placa alvo.
Comece abrindo a Arduino IDE, depois em Tools escolha a placa, no meu caso ATtiny24/44/84. Em seguida, em Processor, escolhi ATtiny44.

Depois escolha o clock. Como não estou usando cristal externo, escolhi "Internal 8MHz".

Depois vá em Programmer: "USBasp", ou "USBtiny" para o FabISP.

No vídeo abaixo, mostro o processo de programação com o FabISP.
Para ver o vídeo em resolução total, acesse o YouTube
Neste vídeo, mostro o processo de programação com o USBasp.
Para ver o vídeo em resolução total, acesse o YouTube
Dá para ver o ATtiny44 controlando um relé para ligar um compressor num horário definido no programa.
Para ver o vídeo em resolução total, acesse o YouTube
Hero shot
Hero shot
Ver no futuro como usar o millis.
← (15 abr) Aplicações e Implicações · todas as semanas · Moldagem e Fundição (29 abr) →