ea industrial que não foi muito longe pois existe muitos obstáculos para a rede mas também fiz e em uma area residencial consegui da a volta no meu quarteirão tranquilo sem perda de dados o ponto mais longe foi de 200 metros de um Esp32LoRa da Heltec do outro
Mas isto eu fiz configurando um como Receptor e outro como Transmissor, mas eu queria utiliza-los como os 2 sendo Receptor e Transmissor para fazer uma comunicação de mão dupla os 2 mandam informações e os 2 recebe informações
Tentei simplesmente misturar os 2 programas o do Receptor com Transmissor mas parece que não estou conseguindo configura-lo... Fiquei ate na duvida se e possível mesmo fazer com mão dupla ?
Alguém teria alguma ideia de como fazer ?
PROGRAMA DO RECEPTOR
/* This is a simple example show the Heltec.LoRa recived data in OLED.
The onboard OLED display is SSD1306 driver and I2C interface. In order to make the OLED correctly operation, you should output a high-low-high(1-0-1) signal by soft- ware to OLED's reset pin, the low-level signal at least 5ms.
OLED pins to ESP32 GPIOs via this connecthin: OLED_SDA -- GPIO4 OLED_SCL -- GPIO15 OLED_RST -- GPIO16
by Aaron.Lee from HelTec AutoMation, ChengDu, China 成都惠利特自动化科技有限公司 www.heltec.cn
This project is also available on GitHub: https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series */ #include "heltec.h"
#define BAND 915E6 //you can set band here directly,e.g. 868E6,915E6,433E6 String rssi = "RSSI --"; String packSize = "--"; String packet ;
void LoRaData() { Heltec.display->clear(); Heltec.display->setTextAlignment(TEXT_ALIGN_LEFT); Heltec.display->setFont(ArialMT_Plain_10); Heltec.display->drawString(0 , 15 , "Recebido " + packSize + " bytes"); Heltec.display->drawStringMaxWidth(0 , 26 , 128, packet); Heltec.display->drawString(0, 0, rssi); Heltec.display->display(); }
void cbk(int packetSize) { packet = ""; packSize = String(packetSize, DEC); for (int i = 0; i < packetSize; i++) { packet += (char) LoRa.read(); } rssi = "RSSI " + String(LoRa.packetRssi(), DEC) ; LoRaData();
}
void setup() {
Serial.begin(115200); //WIFI Kit series V1 not support Vext control Heltec.begin(true /*DisplayEnable Enable*/, true /*Heltec.Heltec.Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/);
Heltec.display->init(); Heltec.display->flipScreenVertically(); Heltec.display->setFont(ArialMT_Plain_10); delay(1500); Heltec.display->clear();
Heltec.display->drawString(0, 0, "CNCTEX.Lora Iniciado!"); Heltec.display->drawString(0, 10, "Espere o dado recebido ..."); Heltec.display->display(); delay(1000); //LoRa.onReceive(cbk); LoRa.receive(); }
void loop() { int packetSize = LoRa.parsePacket(); if (packetSize) { cbk(packetSize); } }
PROGRAMA DO TRANSMISSOR
/* This is a simple example show the Heltec.LoRa sended data in OLED.
The onboard OLED display is SSD1306 driver and I2C interface. In order to make the OLED correctly operation, you should output a high-low-high(1-0-1) signal by soft- ware to OLED's reset pin, the low-level signal at least 5ms.
OLED pins to ESP32 GPIOs via this connecthin: OLED_SDA -- GPIO4 OLED_SCL -- GPIO15 OLED_RST -- GPIO16
by Aaron.Lee from HelTec AutoMation, ChengDu, China 成都惠利特自动化科技有限公司 https://heltec.org
this project also realess in GitHub: https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series */
#include "heltec.h"
#define BAND 915E6 //you can set band here directly,e.g. 868E6,915E6,433E6
unsigned int counter = 0; String rssi = "RSSI --"; String packSize = "--"; String packet ;
void setup() { //WIFI Kit series V1 not support Vext control Heltec.begin(true /*DisplayEnable Enable*/, true /*Heltec.Heltec.Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/);
Heltec.display->init(); Heltec.display->flipScreenVertically(); Heltec.display->setFont(ArialMT_Plain_10); delay(1500); Heltec.display->clear();
Heltec.display->drawString(0, 0, "CNCTEX.Lora Iniciado!"); Heltec.display->display(); delay(1000); } void loop() { Heltec.display->clear(); Heltec.display->setTextAlignment(TEXT_ALIGN_LEFT); Heltec.display->setFont(ArialMT_Plain_10);
Heltec.display->drawString(0, 0, "Sending packet: "); Heltec.display->drawString(90, 0, String(counter)); Heltec.display->display();
// send packet LoRa.beginPacket(); /* LoRa.setTxPower(txPower,RFOUT_pin); txPower -- 0 ~ 20 RFOUT_pin could be RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO - RF_PACONFIG_PASELECT_PABOOST -- LoRa single output via PABOOST, maximum output 20dBm - RF_PACONFIG_PASELECT_RFO -- LoRa single output via RFO_HF / RFO_LF, maximum output 14dBm */ LoRa.setTxPower(14, RF_PACONFIG_PASELECT_PABOOST); LoRa.print("Hello "); LoRa.print(counter); LoRa.endPacket();
counter++; digitalWrite(LED, HIGH); // turn the LED on (HIGH is the voltage level) delay(10); // wait for a second digitalWrite(LED, LOW); // turn the LED off by making the voltage LOW delay(10); // wait for a second }// =========================================================== //
RESOLVIDO
Eu mudei o código para facilitar, ao invés de mandar informações escrita no display fiz ele apenas com 2 botoes e 2 leds um acedendo um lede do outro
Um liga o led do outro com um interruptor que eu fiz pelo software usando um micro swith
lembrando os botoes tem que esta cons resistores pro pull down
PROGRAMA DO TRANSMISSOR RECEPTOR (so passar esse programa no 2 microcontrolador)
/*This is a simple example show the Heltec.LoRa sended data in OLED.
The onboard OLED display is SSD1306 driver and I2C interface. In order to make theOLED correctly operation, you should output a high-low-high(1-0-1) signal by soft-ware to OLED's reset pin, the low-level signal at least 5ms.
OLED pins to ESP32 GPIOs via this connecthin:OLED_SDA -- GPIO4OLED_SCL -- GPIO15OLED_RST -- GPIO16
by Aaron.Lee from HelTec AutoMation, ChengDu, China成都惠利特自动化科技有限公司https://heltec.org
this project also realess in GitHub:https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series*/
#include "heltec.h"
#define BAND 915E6 //you can set band here directly,e.g. 868E6,915E6,433E6
#define botao 36#define led 12
boolean status_Botao = LOW;boolean statusAnt_Botao = LOW;boolean sinal = 0;String packSize = "--";String packet ;
void cbk(int packetSize) { // recebe e converte dos dados recebidos em texto para facilitar o manuzeiopacket = "";packSize = String(packetSize, DEC);for (int i = 0; i < packetSize; i++) {packet += (char) LoRa.read();}}
void setup() {
pinMode (botao, INPUT);pinMode (led , OUTPUT);
//WIFI Kit series V1 not support Vext controlHeltec.begin(true /*DisplayEnable Enable*/, true /*Heltec.Heltec.Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/);LoRa.receive();}void loop() {
status_Botao = digitalRead (botao);delay(5);if (status_Botao == HIGH) statusAnt_Botao = HIGH;if (status_Botao == LOW && statusAnt_Botao == HIGH) {sinal = !sinal;statusAnt_Botao = LOW;LoRa.beginPacket(); // liga o envioLoRa.setTxPower(14, RF_PACONFIG_PASELECT_PABOOST);LoRa.print(sinal);LoRa.endPacket(); // deliga o envio}
// LoRa.onReceive(cbk);
int packetSize = LoRa.parsePacket();if (packetSize) {cbk(packetSize);}
if (packet == "1") {digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)//delay(10); // wait for a second}
if (packet == "0") {digitalWrite(led, LOW); // turn the LED off by making the voltage LOW//delay(10);}}…
Adicionado por Vitor S Costa ao 10:11 em 30 julho 2020
ê tem uma fonte de tensão, a qual tem uma saída entre 1,25V e 22V, ajustável em dois potenciômetros. Se sua fonte for exatamente como o esquema elétrico que você postou, então fica claro que um dos potenciômetros (o de 4.7k) é para ajuste "normal" da tensão, e o outro (o de 470 ohm) é para o ajuste "fino" da tensão de saída. E há dois transistores TIP 147 os quais são os drivers de potência para a tensão de saída da fonte. Inclusive, analisando as ligações destes dois TIPs, vê-se estão corretas. O regulador de tensão é o LM338T, e os diodos 1N4002 (D7 e D8) são para proteção deste LM338T. Esta é uma proteção contra corrente reversa excessiva proveniente de C4 e C5 quando a fonte é desligada, mas segundo o datasheet do LM338, ela só é necessária quando C4 e C5 tem valores muito altos (o que não é o seu caso, já no seu circuito C4 e C5 tem apenas 1uF).
E o que entendi sobre o que você deseja implementar: acrescentar à esta Fonte uma saída de corrente ajustável.
Mas há informações faltando: 1) qual a faixa de corrente ajustável que você pretende ter na saída de corrente? 2) qual a tensão máxima de saída para esta fonte de corrente?
Eu não sei qual seu conhecimento de eletrônica. Mas estou assumindo que você não conheça muito os conceitos relacionados à uma Fonte de Corrente. Assim, vou usar o conceito de Fonte de Tensão para ajudar você a entender os conceitos similares para uma Fonte de Corrente. Uma Fonte de Tensão, fornece uma tensão constante, à qual é entregue a uma carga qualquer. Mesmo que a tensão seja ajustável, ainda assim é uma Fonte de Tensão, pois uma vez ajustada, a tensão se mantém constante e independente da carga conectada. Como essa carga possui uma resistência elétrica, digamos "R1", a corrente "i1" pela carga será i1=V/R1 , sendo "V" a tensão fornecida pela fonte. Se você muda a carga, e ela tem uma resistência "R2", então a corrente "i2" nesta carga será i2=V/R2. Como você pode perceber, nos dois casos a tensão é constante e igual a "V", porém em cada caso a corrente foi diferente e dependente da resistência elétrica da carga. Em outras palavras: numa Fonte de Tensão, a tensão de saída se mantém constante, e a corrente de saída depende da carga. Uma consequencia disso, é que a Potência fornecida pela fonte será variável, e dada por: P=V*i, sendo "i" a corrente fornecida (e dependente da resistência da carga). Mas é claro que há um limite para a Potência fornecida, senão poderíamos "puxar" cada vez mais corrente (diminuindo a resistência da carga), e isso indefinidamente nos levaria a uma Potência infinita (o que não é possível). Logo, há um limite para a Potência máxima fornecida pela Fonte de Tensão, o que nos permite calcular a corrente máxima de saída, que será iMax= Pmax/V. Note na equação que "V" é o mesmo de sempre. E o que ocorre se você conectar cargas que tentem puxar mais corrente? simples: como a Potência da fonte tem um limite (Pmax), a tensão de saída começa a diminuir (olhe a equação e isto fica claro), deixando portanto de ser constante. Logo o que se conclui? também simples: que a tensão de saída de uma Fonte de Tensão, se mantém constante, desde que vc não ultrapasse a máxima potência fornecida pela Fonte.
Para uma Fonte de Corrente ocorre um comportamento idêntico, porém quem se mantém constante é a corrente. Neste caso, é a tensão de saída que mudará, conforme a resistência elétrica da carga que você conectar à fonte, e o valor desta tensão será V=R*i, sendo "R" a resistência da carga, "i" a corrente constante da Fonte de Corrente. Note que a equação é a mesma de uma Fonte de Tensão constante, porém no caso de uma Fonte de Corrente quem se mantém constante é a corrente (e a tensão se ajusta conforme a resistência elétrica da carga). Mas afinal, nós podemos aumentar "R" indefinidamente e ainda assim a corrente se manterá a mesma? Obviamente que não, porque se isso ocorresse, a tensão de saída para uma carga "aberta" (fonte sem carga conectada), seria infinita para que a corrente se mantivesse a mesma, o que sabemos não é possível. Este comportamento ocorre exatamente pelo mesmo motivo que limitava a Fonte de Tensão: a Potência máxima fornecida pela fonte. Como P=V*i, se há uma potência máxima Pmax, o valor máximo da tensão de saída em uma Fonte de Corrente será Vmax= Pmax/i, sendo "i" a corrente constante da fonte. Quando a tensão de saída atinge esse valor Vmax, terá sido alcançado a Potência máxima da fonte, e a partir daí a corrente cai, não sendo mais o valor constante nominal.
Sabendo estes conceitos e comportamentos das Fontes de Tensão e das Fontes de Corrente, permite a você calcular ou determinar os limites reais que serão possíveis de se obter na prática, quando se tem Fontes ajustáveis.
Mas há uma implicação mais severa ainda destes conceitos: não há como você ter simultaneamente nos mesmos terminais de saída de uma fonte, tensão constante e corrente constante. Note que a palavra chave aqui é "simultaneamente". Isto porque se a tensão fosse constante e a corrente fosse também constante, qualquer carga conectada a esta fonte, teria sempre a mesma resistência elétrica, a qual seria R=V/i. Sabemos que isso não é possível, já que a resistência elétrica é uma característica intrínseca dos materiais e substâncias existentes na Natureza (e não são determinadas pelas tensões e correntes de uma fonte: estas resistências são o que são e ponto!!!).
Logo, se sua intensão era ter uma fonte onde nos mesmos terminais de saída você ajusta a tensão e a corrente fornecidas, então vai ter que tentar projetar isso em uma outra dimensão espacial, onde talvez as leis da física sejam outras.
Mas é possível ter uma Fonte de Tensão e uma Fonte de Corrente de forma simultânea, desde que não compartilhem exatamente os terminais. Desenhei junto ao circuito da sua Fonte de Tensão, um protótipo de uma Fonte de Corrente ajustável, e que é mostrada na região de cor verde na figura a seguir:
A corrente é ajustável em "P1", e seu valor é "Ix", fornecida no conector marcado como "saída da corrente" (observe as polaridades + e -). Os valores dos resistores e capacitores descritos no circuito, são típicos e caso você deseje saber como eu os determinei, te explicarei em outro post.
Observe que usei o TIP 147 como "driver" para a corrente de saída, já que você já estava usando este transistor. Assim como na sua fonte original, esse TIP 147 deve ser provido de dissipador.
Note que o AmpOp (Amplificador Operacional) no circuito da fonte, é alimentado pela tensão "VF", e portanto tem que ser capaz de suportar essa tensão em condições normais. Provavelmente este é o ponto mais crítico desse projeto, já que a maioria dos AmpOp que existem por aí, não costuma trabalhar com tensões acima de 32V (e pelo que entendi, sua tensão "VF" é de 35,6V). Mas existem sim AmpOps capazes de trabalhar com tensões desse nível, mas são mais incomuns.
Outro ponto importante, é que é desejável que o AmpOp seja do tipo "Output Rail to Rail", ou então que a sua tensão máxima de saída esteja dentro de 0,5V abaixo da tensão de alimentação. Esse valor piora com o aumento da corrente na saía do AmpOp, porém na configuração mostrada, essa corrente é muito baixa, principalmente porque o TIP 147 é do tipo "Darlington" com ganho HFE maior que 1000.
O fato do TIP 147 ser "Darlington", também implica que a tensão base-emissor é bem maior que em transistores simples. Isso ajuda muito, pois para garantir o corte total do transistor, não é preciso que a tensão de saída do AmpOp esteja dentro de 0,5V abaixo da tensão de alimentação "VF", pois a tensão base-emissor do TIP é pelo menos o dobro desse valor.
Um AmpOp que quase atende tudo isso, é o LM358. Porém a máxima tensão de alimentação do mesmo, é de 32V. Caso a tensão "VF" da sua fonte possa ser reduzida para estes 32V, então o LM358 pode ser usado. Estou mencionando o LM358 devido à sua imensa popularidade e baixo custo.
E como determinar a corrente de saída? Não é complicado. Ela é determinada da seguinte forma: Ix= (VF-Vc) / Rx. Assim o que se precisa fazer, é primeiro determinar o valor máximo que se deseja para a corrente Ix. Com isso determinado, escolhe-se um valor característico para Rx (tipo 10 ohms, 5 ohms, 1 ohm, dependendo do valor máximo de Ix), e então se calcula o valor de "Vc", já que Vc=VF - (Ix*Rx). Esse valor calculado, é o valor mínimo de Vc, que dará a máxima corrente da Fonte de Corrente ajustável. Podemos chamá-lo de "VcMIN", e ele é exatamente o valor da tensão "Vy" sobre o resistor "Ry". Portanto, conhecido este valor "Vy", é possível calcular o valor de "Ry" e do Potenciômetro "P1", já que formam um divisor de tensão. A dica aqui é: escolha um valor adequado para "Ry" (exemplo: 10k, 47k, 100k), e então calcule P1 por divisor de tensão. Como P1 é um potenciômetro, não é preciso que ele tenha o "valor exato" calculado, e se esse valor for muito distante dos valores comerciais, basta alterar ligeiramente o valor de "Ry" e refazer o cálculo de P1 de forma a se obter um valor mais próximo aos comerciais. Atente que o valor de P1 determina a máxima corrente Ix e portanto procure evitar escolher um valor comercial maior que o valor calculado, justamente para que a corrente máxima Ix não ultrapasse o limite pretendido.
A princípio pode parecer complexo, mas na realidade é muito simples. Assim não se intimide pela aparente complexidade. E se vc tiver alguma dúvida, estou à disposição para ajudar a esclarecer. Não se intimide pela aparente complexidade.
Observações finais: veja que a "topologia" da Fonte de Corrente que mostrei na figura anterior, é do tipo para "Carga Aterrada", também chamada de tipo que "fornece" corrente. A característica dessa topologia, é que a carga é sempre ligada entre o GND ("terra" do circuito, que é o terminal "-" da saída da Fonte de Corrente) e o terminal "+" da saída (que é o coletor do TIP). Em outras palavras: a corrente é fornecida pelo terminal "+", passa pela carga, e retorna para o GND (o "-" da fonte de corrente). A única dificuldade dessa topologia, é que o AmpOp tem que ser alimentado pela tensão "VF", a qual pode ter valores mais altos (que é o seu caso).
No entanto, se não for uma necessidade que sua carga seja "aterrada", vc pode usar a topologia de "drenagem de corrente". Esta topologia é mais comum e portanto a mais utilizada nos circuitos. O circuito é quase idêntico ao da topologia de "carga aterrada". No entanto há uma grande vantagem na topologia de "drenagem de corrente": o AmpOp pode ter alimentação completamente diferente da tensão "VF". Por exemplo, na topologia de "drenagem de corrente" você pode estar usando o seu valor de 35,6V para "VF", e o AmpOp ser alimentado com apenas 5V. Então isso facilita enormemente escolher um AmpOp comercial (o popular LM358 é ainda mais perfeito nesta topologia). E como a carga é ligada nesta topologia "drenagem de corrente"? simples: é ligada entre o coletor do transistor driver (que passa a ser o terminal "-" da fonte), e a tensão "VF" (que passa a ser o terminal "+" da fonte). Na figura a seguir mostro a topologia de "drenagem de corrente":
Observe que nesta topologia, o transistor deve ser do tipo NPN, por isso está como TIP 142, que é o par complementar do TIP 147.
O cálculo dos componentes, é praticamente idêntico à toplogia de "carga aterrada", porém no lugar de "VF" nas equações, usamos o GND, ou seja 0V, o que causa uma ligeira simplificação.
Mais uma vez, fico à disposição para ajudar em quaisquer esclarecimentos e orientações.
Abrçs,
Elcids
…
Adicionado por Elcids Chagas ao 7:14 em 18 maio 2018
mo 5V ou 12V por exemplo). E sobre isso, falarei mais à frente (uso de um “driver” simples).
Sobre vc ter usado o TIP122 inicialmente, veja que as características de Potência são parecidas com as do TIP41, e portanto vc também estava forçando a junção Base-Emissor com correntes um tanto altas. Se a junção Base-Emissor é danificada, então o Transistor não é mais confiável, pois não irá se comportar como esperado.
Sobre a aquisição do MOSFET, verifique o famoso site de compras “ML” (pelas iniciais vc sabe qual é). Facilmente vc encontrará diversos modelos de MOSFET. Aconselho procurar anúncios que vendam múltiplos de 5 ou 10 unidades, pois neste caso compensará mais em termos de frete. E certamente vc encontrará lá no ML, anúncios de cidades de SC ou mesmo de Curitiba, o que implicará em custo de envio menor devido à sua proximidade geográfica.
Para o seu caso, eu recomendo usar o IRF540. Ele é muito comum e popular, e suas características elétricas atendem seu caso, pois seu “RDS ON” (“impedância ON”) é menor que 100 mili-Ohms. Com esse baixo “RDS ON”, a Potência dissipada pelo IRF540 a uma corrente de 3A, seria menor que 1W, dispensando o uso de um dissipador de calor.
Sobre o circuito, veja o exemplo mostrado na figura a seguir, que simulei no Proteus:
(clique na figura para “zoom”)
Observe as formas de onda no Osciloscópio virtual, principalmente a amplitude. Note que para o sinal que emula um PWM (na figura o sinal com nome “Pulse”), usei um gerador de pulsos, onde pode-se mudar o percentual % (portanto o duty cycle).
Veja que usei uma amplitude de 3.3V, para ficar conforme o ESP8266. Claro vc pode estar se perguntando: mas a amplitude não irá diminuir quando drenamos corrente? Sim, isso ocorre, porém no circuito mostrado o dreno de corrente da saída digital será muito baixo, e isso garante queda mínima na tensão correspondente ao Nível Lógico “1”.
Mas sobre este circuito, há outras características importantes que vc precisa estar a par. Seguem elas enumeradas:
1) veja que usei um BC337 como “driver” intermediário entre a saída digital do ESP8266 (o sinal “Pulse” no circuito), e o Gate do MOSFET. Isto é necessário para garantir sem falhas, que o MOSFET será acionado (explico logo adiante). Veja a figura a seguir onde marquei em verde claro o pior caso da tensão VGS do IRF540:
(clique na figura para “zoom”)
Veja que no pior caso, temos VGS = 4V. Isto significa que no pior caso, se a tensão de controle (o VGS) estiver acima de 4V, o MOSFET será acionado (irá conduzir). Além disso, é preciso garantir que o MOSFET conduza “bem”, ou seja, tenha um “RDS ON” realmente baixo. Com este “driver” via BC337, o “VGS ON” será de 12V, garantindo uma ótima condução do IRF540.
Esta figura foi preparada a partir do datasheet do IRF540 do fabricante Vishay. Os dados da figura estão na página 2 do datasheet, na Tabela de nome “SPECIFICATIONS”. O datasheet é este aqui: "IRF540_Vishay.pdf"
Atenção: não vá interpretar errado os valores mínimo e máximo mostrados na figura anterior para o VGS do IRF540. Eles se referem ao VGS(th) ou VGS de Threshold (ou VGS “limiar”). Quem não é especialista, vai achar que são valores limitantes para o VGS, mas esta interpretação está totalmente incorreta. Estes limites mínimo e máximo, se referem à produção (fabricação) do componente eletrônico, ou seja, se referem à estatística de fabricação. Assim, para os IRF540 produzidos e testados em fábrica, o pior caso medido para a tensão VGS(th), será 4V, o que significa que no pior caso, é preciso aplicar pelo menos 4V para o IRF540 conduzir. Obseve que no melhor caso estatístico, VGS(th) será de 2V, mas se vc considerar esse valor em um Projeto, pode dar “azar” e adquirir um componente que tem o VGS(th) mais próximo a 4V, e aí claro vai dar zica.
Sobre o valor “extremo” do VGS, vc encontra isso na primeira página do datasheet, na Tabela “ABSOLUTE MAXIMUM RATINGS”. Este valor é de 20V, e não deve ser alcançado. Aliás, se qualquer valor dessa Tabela for alcançado, o Fabricante não mais garante que o componente terá o desempenho especificado no restante do datasheet. Note que para o VDS, o valor extremo é 100V.
Pelas informações acima, vc pode concluir que se usar a saída digital do ESP8266 @3.3V diretamente no Gate do IRF540 (ou seja, sem o driver intermediário com BC337), vc não terá como sempre garantir o acionamento do MOSFET, caso o VGS(th) de algum IRF540 que vc venha a adquirir seja acima de 3.3V.
2) note que o Diodo em paralelo com o Motor (ou “anti-paralelo” como alguns preferem dizer), é um 1N4937. Este é um Diodo de comutação rápida. Não use diodos como 1N4007, ou da série 1N400x, pois estes são diodos “lentos”, que são ótimos para a rede de 60Hz, mas que são inadequados para circuitos de alta-frequência ou onde a comutação deve ser rápida. O papel desse diodo é absorver a energia eletromotriz gerada pelo Motor quando o MOSFET corta a corrente. Assim que essa corrente é interrompida, durante um curto instante de tempo, um spike de alta tensão será produzido nos terminais do Motor, e com polaridade contrária à tensão de 12V aplicada antes do corte. Como essa tensão gerada sobe muito rápido (em alguns micro-segundos ou até menos), é importante que o Diodo em paralelo, “perceba” rapidamente o surgimento dessa tensão, e absorva sua energia associada. E depois quando o MOSFET conduzir novamente, o Diodo ficará reversamente polarizado, e por ser rápido ele cortará também rapidamente, permitindo o acionamento do Motor.
Não precisa ser o 1N4937. Pode ser qualquer outro Diodo rápido que tolere altas tensões reversas (ou seja, diodos como 1N4148 não servem neste caso, embora sejam rápidos). A tensão reversa repetitiva para o 1N4937 é de 600V (lembrando que ao se colocar dois diodos em série, e com a polaridade correta, essa tensão dobrará).
3) observe que vc não deve aplicar ao Motor, um sinal PWM com qualquer frequência. A frequência que será efetiva, dependerá da Potência do Motor, ou seja, dependerá da Indutância que este Motor apresenta ao circuito. Motores mais potentes, terão maior indutância, e a frequência adequada do PWM diminui com o aumento dessa indutância. Maior indutância, menor frequência para o PWM.
Isso ocorre, porque ao usar o PWM no Motor, vc também estará chaveando uma indutância. Assim, conforme se aumenta a frequência do PWM, chegará a um ponto que o chaveamento não é mais eficiente, pois a inércia de energia do Motor girando não consegue acompanhar o liga/desliga do PWM. Assim é preciso usar uma frequência que permita aos enrolamentos do Motor “perceber” de forma clara que a corrente foi cortada, e sentir o efeito disso.
Este é um aspecto muito prático, pois além de depender da Potência do Motor, depende também da carga que está sendo acionada pelo eixo do Motor. Mas em geral, dificilmente vc precisará de mais que algumas centenas de Hz para o PWM. O ideal é começar com uma frequência intermediária, como por exemplo 500Hz, e então aumentar e diminuir a partir desse valor, observando se o controle PWM se comporta “suave”, ou se não responde mais. Claro, nesta avaliação, é preciso também variar o percentual do PWM, de 0% a 100%, para cada frequência avaliada, observando a resposta do Motor.
4) atenção: o driver com BC337, inverte o sinal PWM (vc pode conferir isso nos sinais mostrados no Osciloscópio virtual na primeira figura). Assim por exemplo para obter um PWM de 80%, vc deve programar o percentual PWM na saída digital do ESP8266, para 20% (ou seja, 100% - 80% = 20%). Para isso vc pode criar uma função muito simples que faz este cálculo e também já programa o PWM com este resultado. Se tiver alguma dificuldade com isso, avise aqui que coloco um exemplo conforme o caso ser com valores percentuais (0 a 100%) ou com valores absolutos (0 a 255 na resolução padrão do Arduino).
Caso use o Proteus e queira fazer algumas análises, segue o circuito que usei para simulação: "Motor_IRF540_Proteus.zip"
Observe no entanto, que o Motor que usei na simulação, é um dos que estavam disponíveis no Proteus. Mas vc pode ajustar os parâmetros do mesmo (como a indutância vista e a carga mecânica no eixo). Lembre-se também que a simulação “ocorre” num “tempo virtual” que sempre será mais lento que o “tempo real”.
Espero ter ajudado.
Abrçs,
Elcids…
Adicionado por Elcids Chagas ao 22:50 em 5 setembro 2020
ONCRETO, facilmente assimilável ou entendida – Todos que atuam nessa ÁREA são considerados MALUCOS ! ! ! ! ! !
Recomendo iniciar, dando uma lida sobre o Tema / Assunto o que está disponível no Wilkpédia (Link abaixo), certo que perceberá que a Humanidade, ainda, Muito MAL conhece o Mundo da Matéria que representa apenas 50 % do TOTAL (Mundo da Matéria + Mundo da Anti–Matéria).
http://pt.wikipedia.org/wiki/Antimat%C3%A9ria
Através de uma Busca poderá encontrar muitos TRABALHOS interessantes, mas fique certo que a maior parte das informações existentes são TEÓRICAS e pouca há de Dados Experimentais.
Tudo que é QUENTE tende–se a perder Energia e Tudo que FRIO tende–se a ganhar Energia, como consequência a tendência é parar / finalizar num Ponto de Equilíbrio ou ESTADO de EQUILÍBRIO. Outros Fenômenos Naturais, também, tendem a parar / finalizar num Ponto de Equilíbrio.
A Tendência Universal é o ESTADO de EQUILÍBRIO => |Mundo da Matéria| = |Mundo da Anti–Matéria|.
Na Atualidade o UNIVERSO está em EXPANSÃO, segundo Renomados Pesquisadores, e por isso a |MASSA do Mundo da Matéria| é MAIOR (! ? ! ? ! ? ! ?) que a |MASSA do Mundo da Anti–Matéria|, mas no Futuro Distante (Bilhões ou Trilhões de Anos ! ? ! ? ! ? ! ?) o processo se INVERTERÁ iniciando–se a sua CONTRAÇÃO – é o Único Moto Perpétuo que Nunca irá PARAR.
Há vários Motos Quase–Perpétuos, com base nas principais Fontes Energéticas que estão ao nosso alcance:
1) Radiação Solar
2) Forças das ÁGUAS (Correntes Marinhas / Rios e Represas)
3) Ventos
4) Calor Geotérmicas
5) Outras
Todas as Fontes Energéticas são GRATUITAS – temos alguns PROJETOS, em andamento, para Produção de Energia Elétrica a CUSTO “ZERO”, mas só será divulgado depois que for encontrado a SOLUÇÃO que seguramente evite o USO NÃO–ÉTICO do RECURSO.
A Equipe BR do AGUAPÉ agradece e aguarda Manifestações dos Colegas Garagistas.
NOTA: “Quando Sonhamos SOZINHOS é só um SONHO, mas quando Sonhamos JUNTOS é o início de uma Nova Realidade” (D. Helder Câmara) - apresente as suas MANIFESTAÇÕES (Críticas, Sugestões, ETC.), utilizando o Endereço Eletrônico: missao.tanizaki@gmail.com, certo que muitos na Sociedade Brasileira, inclusive a Equipe BR do A G U A P É, te agradeçerão.
Um Abraço Fraterno aos Interessados pelo A G U A P É,
MISSAO TANIZAKI
Servidor Público Federal
Bacharel em Química
missao.tanizaki@gmail.com (Usual)
missaotanizaki@yahoo.com.br (Alternativo)
OSCIPE (*) - Equipe BR do A G U A P É
TUDO POR UM BRASIL & MUNDO MELHOR
(*) REF.: Definições do SEBRAE
…
LE )
Os sonhos são como uma humana interna holodeck . Dentro de sua mente, tudo é possível, de seus desejos mais grandiosos a seus piores pesadelos. Isto é tudo muito bem, mas e se você pudesse controlar seus sonhos e se tornar o deus onisciente de uma realidade escolhidos a dedo, sempre que você vai dormir? Inception levou essa idéia ao extremo lógico invadindo os sonhos de outras pessoas.
Enquanto nós não podemos invadir os sonhos dos outros, podemos definitivamente ter um astro de ação filme herói da nossa própria! Ao usar certas técnicas de sonhos lúcidos , você pode fazer exatamente isso. Durante o sonho lúcido, o sonhador dormindo está consciente de que eles estão em um sonho, mas permanece no sono. Isso permite que você conscientemente manipular e transformar o mundo de sonhos como em Inception .
Hoje, nós vamos fazer os nossos próprios sonhos lúcidos óculos e cortar nosso subconsciente em sua apresentação.
Materiais
Os óculos
LEDs (2)
ATTINY85 microcontrolador ( ESTOU USANDO O ARDUINO MESMO )
8 pinos titular de chips
AVR programador ou Arduino
3 volts bateria de célula tipo moeda
Suporte da bateria
perfboard
Mudar
Passo 1 Corte os óculos
Marque onde o seu nível de olho é em cada lente dos óculos. Certifique-se de testar se eles são grandes o suficiente para caber os LEDs que você tem.
Idealmente, o buraco deve ser grande o suficiente apenas que os LEDs são mantidos no lugar.
Etapa 2 do Programa de Chip
Para programar o ATTINY85, tudo o que precisamos é um Arduino e uma placa de montagem.Siga as instruções aqui sobre como usar um Arduino como um programador ISP. Uma vez que o programador está configurado, coloque este código para o chip. O código executa as seguintes tarefas cada vez que você ligar os óculos de proteção:
Pisque uma vez para sinalizar energia.
Esperar duas horas para o usuário para adormecer.
Blink padrão de luz uma vez a cada dez minutos para sempre.
O padrão pisca a cada dez minutos, na tentativa de pegá-lo no sono REM (movimento rápido dos olhos). REM é a fase do sono mais probabilidade de resultar em atividade sonho, e os ciclos de seu cérebro por essa fase do sono várias vezes ao longo da noite. Para se certificar de que vemos o padrão de luz durante o sono REM, que repeti-la em intervalos de dez minutos.
Passo 3 Breadboard o Circuito
Breadboard o circuito de acordo com o diagrama abaixo.
A grande coisa sobre o uso de uma fonte de 3 volts é que não precisa mesmo de resistores par com os LEDs, porque não há nenhuma corrente extra para protegê-los.
Passo 4 Layout e solda do Conselho
Agora que entendemos o nosso circuito, podemos movê-lo para um conselho permanente.Afaste os componentes em torno da perfboard experimentar com diferentes layouts. Tente encontrar o melhor compromisso de utilidade e estética.
Você vai passar por vários layouts experimentais. Tive sorte e meus LEDs se estendia desde a prancha certa para os buracos nas óculos.
Lembre-se de usar uma tomada para que você possa remover o chip se quiser reprogramá-lo mais tarde.
Eu prefiro a fios de solda na parte traseira para que a frente do conselho é bom e puro.
Passo 5 Anexar a Goggles
Coloque a placa sobre os óculos de proteção para que os LEDs picar através dos buracos dos olhos. Minas fica em apenas pela força dos LEDs, mas você pode colar ou parafusar a placa em que os óculos para uma conexão mais segura.
Passo 6 testá-lo!
Para utilizar os seus novos óculos de sonhos lúcidos, usá-los por alguns minutos por dia e tomar nota do padrão de luz. Cada vez que você notar o padrão, pense em seu entorno e como você chegou lá. Se você é na vida real, você vai se lembrar detalhes, mas no mundo dos sonhos, a maioria das coisas são vagas.
Ligue os óculos e colocá-los em apenas antes de ir para a cama. Se um dos flashes pega-lo em sua fase REM do sono e você está interessado o suficiente para notar que em seu sonho, você pode ser o deus do seu cérebro! Tudo o que precisamos é saber que você está sonhando sem acordar!
Eu não sugiro abrir os olhos enquanto o piscar LEDs. Ele pode lhe dar bastante dor de cabeça.
VIDEO
__________________________________________________________________
Olha que coisa Linda que ficou o meu!
Agora eu vou testa-lo Hahahahahaha
…
qual era seu problema, por dois motivos: 1) estes problemas são algo comum de ocorrer, quando não se utiliza a abordagem adequada, e portanto são bem conhecidos, fazendo com que eu já imagine o que está ocorrendo; 2) neste momento, estou tentando ter uma visualização melhor do panorama do seu Sistema, quais recursos e elementos existem nele, como eles interagem entre si, e como este Sistema deve se comportar.
Logo, o objetivo neste momento é elucidar o seu Sistema, clarificando alguns aspectos do funcionamento dele, e relacionar comportamentos e efeitos colaterais, em abordagens e cuidados mais comuns que se deve tomar em elementos individuais. Posteriormente, podemos abordar diretamente as tratativas, de forma que sejam incisivas e com muito alta confiabilidade.
Iniciando com suas informações preliminares, podemos fazer um Diagrama em Blocos do seu Sistema, ainda assim com algum caráter genérico, pois não estou fixando a quantidade de PCFs:
(clique na figura para "zoom")
Observe que apesar do Barramento I2C poder ter velocidade de 400 KHz, marquei como sendo de 100 Khz, pois você está conectando apenas os PCF8574, os quais tem a limitação de até 100 Khz no I2C (conforme datasheet).
Sobre o ESP-01, marquei como rodando a 80MHz (mais usado), já que vc não disse a velocidade (80 ou 160 MHz).
Sobre a configuração de I/Os dos PCFs, está um tanto genérica (apenas saídas, apenas entradas, e um "mix" de saídas/entradas em um mesmo PCF). O total de PCFs neste Sistema, é "n".
Finalmente, como provavelmente você estará acionando (On/Off) dispositivos ligados às saídas digitais, e provavelmente lendo status ("On/Off" ou "1/0") via entradas digitais, então marquei desta forma no diagrama.
Então, vamos comentar cada um dos itens que enumerei no post anterior, de acordo com as informações que vc forneceu, e acrescentando um panorama sobre cada um:
1) você informou estar usando neste momento apenas um PCF, mas que acabará por ter quatro (e talvez até mais, já que especificações de Projeto podem mudar mesmo durante o andamento das coisas). Bem, isto é o primeiro e principal indicativo de que vc tem de fato uma encrenca, pois um controle adequado deste único PCF no Sistema, não deveria de forma alguma resultar em problema.
O PCF8574 vai até 100KHz (no I2C). Você pode até aumentar esta velocidade (apenas via código), e provavelmente funcionará (talvez até uns 200KHz, ou até mais), porém estará indo contra o especificado no Datasheet do PCF8574 o que seria um dos primeiros passos para o "dark side".
Para análise, vamos considerar as transações mais simples do I2C, onde em um ciclo com um dispositivo, ou é enviado um Byte, ou é lido um Byte deste dispositivo. Isto pode ser bem observado na Especificação I2C (ver neste link da NXP: I2C Bus Specification), conforme mostrado na figura a seguir:
Veja que para a transmissão mais simples do "Master" (Arduino) para o "Device" (neste caso o PCF, no I2C chamado de "Slave"), ou seja para enviar apenas um Byte ao "Device", teríamos 20 bits (faça a contagem na figura anterior: "Fig 11"). Façamos o cálculo de quanto tempo leva isso no I2C@100KHz: tempo de envio = 20/100000 = 200 us (duzentos micro segundos, ou 0.2 mili segundos).
Na direção contrária, ou seja para ler um Byte do "Device", confira (na "Fig 12") e veja que são os mesmos 20 bits. Logo também gasta-se 200us, ou 0.2 ms.
Observe que estas transações são cerca de 1500 vezes mais lentas que um I/O convencional no Arduino UNO (instruções "OUT" e "IN" do AVR@16MHz), e cerca de 250 vezes mais lentas que uma transação SPI (SCLK@10MHz). Tendo estas comparações em mente, permite-se avaliar abordagens das soluções e seus resultados preliminares.
Se essas transações estivessem sendo gerenciadas por DMA, não haveria muito que se preocupar com estes tempos. Mas Raphael, não é o caso no seu Sistema (o UNO não tem DMA). No seu Sistema, a forma como funciona a "Wire" força o código a acompanhar bem de perto a transação I2C que ocorre no Hardware, o que tem um impacto direto na performance de execução do código. Se vc abrir a "wire.c" e "twi.c", vai ficar espantado com toda a tratativa burocrática que é feita para fazer a cadência de controle do I2C. Claro, isto tem seus motivos (filosofia), mas não vou entrar nesta questão.
Eu ainda não medi o impacto sobre a execução do código no UNO, que essa burocracia toda do I2C tem. Mas quando tiver algum tempo irei medir, a fim de ter dados mais precisos sobre isto. Independente disso, dando uma rápida olhada no código interno das Libs "wire.c" e "twi.c" (isso sem contar a Lib dos próprios dispositivos, como por exemplo um RTC que usa I2C), sabemos que não podemos esperar nenhum código executando como um "foguete" no UNO (que já não é "rápido" por natureza).
Para cada PCF que vc utiliza, uma transação ocorre para atualizar as saídas ou para ler entradas. Se um PCF tem um "mix" de entradas e saídas, então para cada PCF assim, pode-se dizer que ocorrerá no mínimo duas transações (uma para ler, outra para escrever). Então, aqui já temos um ponto para abordar na tratativa, onde considera-se também o gerenciamento da taxa de atualização dos PCFs (o que já deu pra perceber, tem tudo a ver).
2) Você disse estar usando 9600 bps entre Arduino e ESP. Não é porque seu Sistema trabalha e controla "elementos" lentos (como Motores, Relés, Chaves, etc), que seu Sistema deve ser "taxado" para baixo em termos de velocidade de comunicação. A taxa de 9600 é considerada uma das mais baixas. Será ela adequada neste caso? Isto depende do que mais há no seu Sistema, e do impacto que estas "outras coisas" tem na execução do seu código.
Nessa velocidade de 9600, um Byte será transmitido ou recebido em cerca de 1ms (faça a s contas: [1 start bit + 8 bits dados + 1 stop bit]/9600 = 10/9600 = ~1ms) . Parece rápido, principalmente porque o Hardware da UART do Atmega328 (assim como no ESP) gerencia o streaming de bits na transmissão/recepção (claro, no I2C também é assim). Porém, vc não pode esquecer que assim como ocorria no I2C, também há uma burocracia associada à Serial, e ela não deve ser ignorada (esse é um erro quase fatal, dependendo das suas necessidades de transferência de dados e do Protocolo usado).
Para mostrar parte desta "burocracia", sem entrar em análise de código em Libs, vamos dar uma olhada na função "Main.c" do Arduino, que é a "mãezona" que cadencia a execução de seu código no Arduino. Lá esperamos encontrar um código de inicialização, um código em loop infinito, e algumas coisinhas mais. Vejamos:
Vemos que há algumas funções de inicialização ("init", "initVariant", etc), uma das quais é o "setup" do Arduino que conhecemos bem. Depois disso, o código do Arduino entra no "for(;;)", que é um loop infinito. Dentro desse "for", encontramos o famoso "loop" do Arduino, que o mundo Ocidental e Oriental adora como se ele fosse um Faraó do Egito ou Deus Asteca.
Uma vez dentro da função "loop", temos "total" controle (pelo menos é o que todo mundo pensa, né?). Mas note, o que ocorre depois que se encerra um ciclo de execução da função "loop": há um "if", onde o código no Arduino vai dar tratamento para eventos da Serial ("serialEventRun"). Isto é apenas parte da burocracia que mencionei sobre a Serial. E vc não tem como evitá-la: ela vai consumir clocks de execução do seu Processador. Pode parecer que isto é um prelúdio do fim pras nossas esperanças. Mas não é.
Sabendo adequar de forma favorável a temporização do seu Sistema, e tendo uma taxa de bits também adequada (Serial), você pode garantir um funcionamento "suave", sem trancos e barrancos. Neste caso específico da Serial, é quase imprescindível que o Protocolo entre Arduino e ESP tenha sido implementado de forma adequada. Do contrário...
3) como vc informou que a "massa de dados" entre Arduino e ESP é mínima e esporádica, isso é uma enorme boa notícia para vc, pois implica que é relativamente muito tranquilo e fácil de se fazer a temporização adequada que mencionei acima (item "2"), de forma a garantir o funcionamento "suave" sem trancos e barrancos no seu Sistema. Se no entanto a "massa de dados" fosse centenas de bytes por transação, aí a coisa mudaria de figura, mas não é este o seu caso.
A questão de haver comunicação esporádica, acrescenta ao seu Sistema, um elemento que chamamos tecnicamente de "Evento Assíncrono", o que significa que durante o funcionamento do seu Sistema e respectiva temporização, ele deve ser capaz de tratar qualquer evento relacionado à comunicação entre o Arduino e ESP, independente do momento em que isto ocorra, e de forma eficiente, pois do contrário poderá prejudicar qualquer outra tarefa que esteja sendo executada no momento em que o evento assíncrono ocorre, comprometendo a confiabilidade do funcionamento.
Para isto, muitas vezes é preciso não somente olhar com cuidado as tarefas de gerenciamento da comunicação, mas também olhar com mais atenção ainda, as demais tarefas sendo executadas, e analisar qual seria o impacto se uma destas tarefas fosse "interrompida" por um evento assíncrono, ou analisar se o gerenciamento necessário para tratar esse evento pode aguardar até que a tarefa seja concluída (ou pelo menos a parte "crítica" dela).
Neste ponto, vai aparecer muita gente aqui (e por aí afora) dizendo pra vc: "ah, usa logo um RTOS que resolve seu problema". Já vi muita coisa semelhante sendo dita. De fato, é quase certo que o uso de um RTOS ajuda muito nisso. Mas é o que vc procura? ou será que vc quer não somente ver seu Sistema funcionando, mas também ter o prazer de dominar as técnicas adequadas e poder sentir que aquilo tudo está nas suas mãos. Aí é com vc, né Raphael?
Mas já te digo: é relativamente fácil implementar seu Sistema sem precisar de um RTOS, e ainda assim ele se manter simples e eficiente. Além disso, o ESP já funciona (mesmo que vc não perceba e não use explicitamente) sobre a "casca" de um RTOS, e isso não é a solução escancarada na nossa cara, e nem foi até o momento a solução para seu Sistema. Mas e quanto ao Arduino UNO que tem baixa performance de execução, um RTOS funcionará de forma eficiente nele? essa é outra questão que não abordarei, para não destoar mais ainda aqui, mas vc pode pensar (ou pesquisar) sobre isso, sem esquecer que o Arduino não é apenas Hardware e Código, ele é todo um Sistema, com uma infinidade de dispositivos e módulos disponíveis no mercado para uso imediato, em uma Plataforma aberta, com abrangência praticamente imensurável. Atente pra isto: qualquer coisa funciona no Windows? sim, desde que esta coisa se adeque e respeite as regras do Windows. O mesmo vale para um RTOS (o Windows é um deles).
4) vc disse que está usando um Protocolo "padrão" entre Arduino e ESP, mas não disse se há algum "handshaking" nesse processo, e por conta disso tenho que desconfiar que vc não está usando um Protocolo de fato, uma vez que qualquer um deles bem sedimentado, tem "handshaking". Acredito que o que vc está entendendo como Protocolo, é o enviar e receber Bytes via Serial do Arduino e ESP. Mas isso não é um Protocolo, isso é o "streaming" de dados entre Hardware/Firmware.
Usar um Protocolo, mesmo que seja um muito simples e desenvolvido por vc, é quase imprescindível para que seu Sistema funcione de forma confiável, e novamente: sem trancos e barrancos. Há duas coisas antagônicas entre si a respeito de Protocolos de Comunicação: primeiro, eles são uma chatice (porque cada um faz o seu e quer que ele seja engolido guela abaixo de todos, tornando o Mundo cada vez mais complicado), e segundo: eles são sensacionais (porque vc tem a liberdade de fazer o que é adequado para vc, eventualmente sem depender de nenhum outro Protocolo já zanzando por aí).
Pelo que vc informou no item 3, sobre a "massa de dados", parece claro que vc precisa de um Protocolo simples e eficiente. E felizmente, isto é bem fácil de se fazer (dada a simplicidade dos elementos no seu Hardware), e tornaria o seu Sistema praticamente 100% confiável. E claro, isto contribuiria para a execução suave do seu código, mesmo que diversas tarefas estejam sendo executadas nele (a única questão mais delicada e que exige mais atenção, que vejo neste momento, é a Gravação de dados na EEPROM, mas dando a tratativa adequada, não há com que se preocupar).
5) ok, eu já imaginava que seria algo assim como vc descreveu, devido à informações que vc passou no item "3". Aqui há duas abordagens semelhantes. A primeira é que o recebimento de dados via ESP, força vc a atualizar de forma sistemática (e como se fosse em "tempo real"), os PCFs configurados como saídas. Algo tranquilo, mas que vincula o "Evento de Recepção" via ESP, à atualização pontual dos PCFs, e este vínculo tem que ser bem tratado para não causar um "lag de tempo" estranho ao mundo real. A segunda, é que dados lidos dos PCFs devem ser enviados ao ESP via Serial. Vc não deixou claro, se os dados são enviados rotineiramente em uma taxa constante (e portanto interpretados exclusivamente por quem receber estes dados), ou se uma mudança de estado nos Ports de Entrada dos PCFs, dispara um evento que deve ser interpretado e sinalizado através de envio de dados ao ESP via Serial. Claro que a tratativa para estes dois casos é semelhante, mas não é igual, porque uma envia dados numa taxa constante enquanto a outra envia dados devido a um "Evento Assíncrono" (nota: o fato de o "Wire.requestFrom" estar dentro do "loop" do Arduino, não é conclusivo sobre isso). Eu ressaltei esta diferença, porque se for um evento que exige interpretação e cause efeitos mais complexos e pesados em termos de processamento, deve-se tentar desvincular a leitura de dados (do PCF), da tratativa de eventos relacionados aos dados, e do envio de dados propriamente dito (claro: sempre que isto for possível). Não se assuste achando que isso parece complicado, pois não é.
Sobre o uso do "Wire.requestFrom", tudo bem. Eu tenho usado I2C no Arduino apenas através das Libs de módulos, como por exemplo de RTCs e Displays, e estas Libs já fazem uma tratativa própria, a qual quase sempre não possui a melhor performance. E elas raramente tem algum "callback" que possa ser setado (possivelmente elas usam algum "callback", mas restringem seu uso dentro delas, de forma que a implementação da Classe torna isso "invisível" para nós).
Um "callback" geralmente está associado a alguma Interrupção do Processador, de forma que é chamado como resultado de algum "hook" que esteja ou dentro da respectiva ISR, ou após o término de um ciclo de execução da função "loop" do Arduino (neste caso, dentro da ISR é setada uma "flag" indicadora de que o "callback" deve ser executado após o "loop" do Arduino). E não se iluda achando que porque vc não conectou o pino "INT#" do PCF a um pino de IRQ do Arduino, não estão ocorrendo Interrupções resultantes do funcionamento do I2C. Veja o capítulo sobre "TWI" no datasheet (versão "full") do Atmega328, e vai obter a resposta a isso (claro, a resposta é bem óbvia, mas se puder ler e aprender sobre isso...).
Mas por que estou falando sobre isto? Simples: se puder usar alguma forma de "callback" (seja onde for que ele seja chamado), vc poderá setar uma "flag" dentro desse "callback", sinalizando assim um Evento ocorrido ou detectado, e dessa forma estaria tratando o evento de forma assíncrona à ocorrência dele, mas ainda assim rápido o suficiente para parecer "suave" ao mundo real. E claro: o tratamento assíncrono a esta Evento (indicado pela "flag" setada), estaria em perfeita harmonia com todos os outros elementos existentes no código do seu Sistema (incluindo o próprio envio/recepção via Serial para o ESP). Observe que nem sempre é adequado fazer processamento dentro de um "callback", porque muitas vezes vc não sabe de onde ele será chamado. Então usando uma "flag", vc pode isolar a tratativa com total segurança, encaixando-a numa tarefa que concorra de forma controlada com as demais tarefas no seu Sistema, e assim obtendo um funcionamento "suave".
Por favor: não pense que isto é complicado. Não é. Quando se faz a implementação disto, se constata que é simples (e depois o trabalho pesado fica por conta das Máquinas). É com técnicas assim que se projeta Máquinas para o mundo real (ou pelo menos deveria ser, já que algumas por aí afora funcionam a trancos e barrancos e eventualmente tem comportamentos esquisitos). Pode parecer complicado, mas é apenas aparente, como já dizia nosso grande e saudoso mestre Bêda Marques.
A coisa pode parecer se resumir em apenas escrever dados nos PCFs e ler dados dos PCFs, mas pode haver muito mais coelhos nesta cartola do que parecia inicialmente. Mas isso não significa a existência de algo complicado (como eu disse antes, não é).
Continua no post seguinte, para não estourar a capacidade de texto de um post único.
…
Adicionado por Elcids Chagas ao 18:06 em 17 março 2019
ciar de algum ponto, e o importante é isso: ir em frente.
Primeiro, respondendo suas perguntas, na sequência que vc as colocou:
1) olhei na Internet o seu modelo de Arduino UNO "Lafvin". Ele é um Arduino UNO convencional, e pode ser utilizado como qualquer outro UNO. Então vc não precisa se referir a ele especificamente por "Lafvin". Chame-o apenas de "UNO".
2) os "comandos" "sei()" e "cli()" a que vc se refere, nós chamamos tecnicamente de "statements", e nada mais são do que funções para controle da Interrupção Geral do Processador "AVR" (o Processador do Arduino UNO) , e que são equivalentes respectivamente às funções "interrupts()" e "noInterrupts()" do Arduino. Assim dê uma olhada no site do Arduino sobre estas duas funções. Os links são estes dois: "interrupts" e "noInterrupts". O site estará em inglês, então use o tradutor do Google conforme preferir.
Estes dois "comandos", só devem ser utilizados se vc tiver uma boa experiência com Programação (não precisa ser do Arduino). Isto porque, eles tem consequências diversas para o funcionamento adequado do Sistema, e se utilizados de forma inadequada, seu Sistema poderá ter efeitos colaterais estranhos e que poderão até confundir vc.
E para o que vc quer fazer, não é necessário usar estes dois "comandos", como mostrarei adiante (no código que implementei).
3) o fato dos dois "comandos" não aparecerem "grafados" como vc diz, é irrelevante. Vou explicar. Os "comandos" que aparecem "grafados", aparecem assim porque eles estão descritos em um arquivo texto em alguma Biblioteca do Arduino, e estes arquivos sempre tem o nome "keywords.txt". Isto é usado apenas para ressaltar a visualização dos "comandos" no Editor do Arduino, e nada mais. Ou seja, não tem efeito no resultado da compilação do código. Então não se preocupe com isso. Além disso, o "sei" e o "cli" não deveriam mesmo aparecerem "grafados", pois são "primitivas" do Compilador AVR, e não exatamente "comandos", e de fato não deveriam estar em nenhum arquivo "keywords.txt" (e se estiverem, a pessoa que fez isso se equivocou, pois não domina a fundo o ambiente).
4) os valores e informações não aparecem adequadamente no Display LCD, porque simplesmente os "comandos" (ou "statements"), estão sendo usados de forma totalmente equivocada no seu código. A forma de se usar isto, é simples na plataforma Arduino. Então vc precisa "estudar" um pouco mais sobre isso, e certamente vai entender como usá-los (no código que estou postando mais adiante, vc poderá ver como isso é feito, e então usar como exemplo).
5) como vc está bem "verde" em Programação, primeiro vc precisa fazer o básico no seu código, e isto nada mais é do que medir a vazão em Litros/minuto de forma adequada e confiável, e então depois disso fazer a parte um pouco mais elaborada que vc descreveu (usando dois Sensores de Fluxo "yf-s201c" e um fim-de-curso). Veja: se vc medir adequadamente o Fluxo em um Sensor, então conseguirá medir em dois (ou a quantidade de sensores que vc quiser). Então bastará fazer os cálculos (algo muito simples em Programação) no momento adequado (conforme o seu fim-de-curso). E exibir os resultados no Display, será da mesma forma de sempre. Mas há Técnicas de Programação, que vc certamente terá que ficar mais acostumado. O que posso te dizer sobre isso, é que as pessoas sempre complicam e são muito desorganizadas, e isto é a chave pra tudo dar errado em Programação. Programação, exige que vc seja organizado, é imperativo. Se vc não for assim, então em algum momento vai ter problemas com seu Sistema, e provavelmente eles serão difíceis de resolver (não vou explicar os motivos disto neste momento).
Então pra dar um empurrão, estou postando um código para o Sistema que vc descreveu no seu código original. Veja: não é para o Sistema com dois sensores, pois quero te mostrar como se faz a coisa mais simples primeiro. O pessoal que me acompanha aqui, sabe que os Sistemas que posto aqui são bastante completos em termos de explicação e documentação, e os códigos são totalmente comentados de forma funcional. E 99% das vezes, eu posto também uma simulação do Sistema (usando o Proteus, devido à popularidade do mesmo).
Então o que está sendo feito neste código? Ele simplesmente mede o Fluxo de um Sensor (e nem precisa do "sei" e do "cli"), e exibe isto no Display, e após um minuto (ou 60 amostras), ele calcula a Média da Vazão. Ou seja, exatamente o que vc tentou fazer no seu código original. No entanto vc vai perceber, que o código que estou postando, é completamente diferente do seu original. Então analise o mesmo com atenção, sem pressa, e com a intenção de aprender. No código, estou usando técnicas clássicas para obter os resultados esperados. Assim se vc conseguir aprender, terá avançado tremendamente, e poderá seguir em frente com ainda mais confiança.
Implementei também a Simulação do seu Sistema usando o Proteus, e o Hardware equivalente, vc pode ver na figura a seguir:
(clique na figura para "zoom")
Se ficar estranho pra vc o Hardware na figura anterior, não se preocupe, pois realmente isso vai ocorrer se vc não está familiarizado com Hardware, com Eletrônica, e com o próprio Proteus. O importante é não achar que é algo transcendental ou do Egito antigo.
O resultado da Simulação vc pode ver nas figuras a seguir, onde "printei" a tela do Proteus em três momentos diferentes: 4 segundos após iniciar a execução do código, depois após 32 segundos, e finalmente após 60 segundos (quando a média é calculada e exibida). Após a exibição da Média da Vazão, o Sistema reinicia todo o processo de medição, e isto se repete indefinidamente. Veja os resultados nas figuras:
(clique nas figuras para "zoom")
O código, vc pode usar diretamente no seu Hardware para verificar o resultado. Apenas atente que o LCD I2C usado no código e no Hardware, tem a "pinagem" padrão desses módulos comercializados na Internet, e que está especificado na linha 48 no código, conforme vc pode ver na figura a seguir:
(clique na figura para "zoom")
Embora esta questão da "pinagem" do LCD I2C estivesse muito confusa (e equivocada) no seu código original, eu assumi que vc tem um módulo e Display I2C padrões, e a "pinagem" que usei corresponde a isso. Mas caso seja diferente (acho pouco provável), informe aqui, que tratarei da melhor forma que eu puder.
O código está aqui: "Fluxo_Agua_02.zip"
Como eu disse, vc pode usar este código diretamente no seu Sistema, pois eu segui as definições e pinagens descritas no seu código original.
E no arquivo zipado, vc também encontrará os arquivos para Simulação no Proteus, caso deseje fazer a Simulação (lá vc pode variar a vazão, através de um Potenciômetro que altera a taxa de pulsos de forma equivalente ao Sensor "real", e pode até desligar o Fluxo através de uma chave equivalente a um "Registro" hidráulico).
Espero ter ajudado.
Abrçs
Elcids…
Adicionado por Elcids Chagas ao 23:01 em 31 março 2020
guinte: tenho vários motores instalados em uma fábrica, estes motores possuem contatos auxiliares de alarme para informar quando um motor entrar em sobrecarga. Gostaria que o Arduíno Mega/Emissor recebesse o sinal (5V) destes contatos e me enviasse uma SMS informando que o motor está desarmado. A idéia básica é a seguinte:No Emissor:Eu recebo o sinal de 5V no pino 22 do arduino mega, por exemplo, recebendo este sinal eu escrevo na serial o valor "A".Eu recebo o sinal de 5V no pino 23 do arduino mega, por exemplo, recebendo este sinal eu escrevo na serial o valor "B". Eassim sucessivamente.No receptor (Arduíno Uno + Shield SIM 900 ICOMSAT 1.1):No receptor eu leio o que está escrito na serial e faço meu comando.Se ler o caracter 'A' na serial, envia SMS "M1 DESARMADO".Se ler o caracter 'B' na serial, envia SMS "M2 DESARMADO".O problemas destes códigos é que fica enviando SMS sem parar.
Vcs poderiam me dar uma luz para este caso? Segue abaixo os códigos:
//Arduino Mega (emissor)
byte contatoM1=22; //define o contato do motor M1byte contatoM2=23; //define o contato do motor M2byte contatoM3=24; //define o contato do motor M3byte contatoM4=25; //define o contato do motor M4byte contatoM5=26; //define o contato do motor M5byte contatoM6=27; //define o contato do motor M6byte contatoM7=28; //define o contato do motor M7byte contatoM8=29; //define o contato do motor M8byte contatoM9=30; //define o contato do motor M9byte contatoM10=31;//define o contato do motor M10byte contatoM11=32; //define o contato do motor M11byte contatoM12=33; //define o contato do motor M12byte contatoM13=34; //define o contato do motor M13byte contatoM14=35; //define o contato do motor M14byte contatoM15=36; //define o contato do motor M15byte contatoM16=37; //define o contato do motor M16byte contatoM17=38;//define o contato do motor M17byte A, B, C, D, E,F, G,H,I,J,L,M,N,O,Q,R,S;boolean enviouA, enviouB,enviouC, enviouD,enviouE, enviouF,enviouG, enviouH,enviouI, enviouJ,enviouL, enviouM,enviouN, enviouO,enviouQ, enviouR,enviouS=false; // flags booleanasbyte tx=1; // define o pino de saída Serial
boolean tempodecorte() { static unsigned long last_interrupt_time = 0; // define o tempo de referencia como zero unsigned long interrupt_time = millis(); // comeca a contagem do tempo if(interrupt_time - last_interrupt_time > 5000) // aplica a condição tempo de contagem maior que 5 s do que o tempo de referencia { last_interrupt_time = interrupt_time; // se a condicao é satisfeita redefine o tempo de referencia como o tempo de contagem return true; // e contabiliza o voto } return false; // se nao, nao contabiliza o voto }
void setup() { Serial.begin(9600); // inicializa o Serial com 9600 bauds pinMode(contatoM1, INPUT); pinMode(contatoM2, INPUT); pinMode(contatoM3, INPUT); pinMode(contatoM4, INPUT); pinMode(contatoM5, INPUT); pinMode(contatoM6, INPUT); pinMode(contatoM7, INPUT); pinMode(contatoM8, INPUT); pinMode(contatoM9, INPUT); pinMode(contatoM10, INPUT); pinMode(contatoM11, INPUT); pinMode(contatoM12, INPUT); pinMode(contatoM13, INPUT); pinMode(contatoM14, INPUT); pinMode(contatoM15, INPUT); pinMode(contatoM16, INPUT); pinMode(contatoM17, INPUT); pinMode(tx,OUTPUT); digitalWrite(tx,HIGH); // "liga" o pino de saída Serial } void loop() { A=digitalRead(contatoM1); B=digitalRead(contatoM2); C=digitalRead(contatoM3); D=digitalRead(contatoM4); E=digitalRead(contatoM5); F=digitalRead(contatoM6); G=digitalRead(contatoM7); H=digitalRead(contatoM8); I=digitalRead(contatoM9); J=digitalRead(contatoM10); L=digitalRead(contatoM11); M=digitalRead(contatoM12); N=digitalRead(contatoM13); O=digitalRead(contatoM14); Q=digitalRead(contatoM15); R=digitalRead(contatoM16); S=digitalRead(contatoM17); if(tempodecorte()){ // chama funcao para o tempo em que o botao deve ser pressionado para ser considerado um voto if(A==HIGH && enviouA == false){ Serial.write('A'); // armazena A no Serial enviouA = true; delay(5000); } if(A==LOW){ // se mudou o valor de A, altera a flag para quando mudar novamente ele enviar enviouA = false; } // o if do B não deve ter nada a ver com o A, pois são motores diferentes if(B==HIGH && enviouB == false){ Serial.write('B'); // armazena B no Serial enviouB = true; delay(5000); } if(B==LOW){ enviouB = false; } if(C==HIGH && enviouC == false){ Serial.write('C'); // armazena C no Serial enviouC = true; delay(5000); } if(C==LOW){ enviouC = false; } if(D==HIGH && enviouD == false){ Serial.write('D'); // armazena D no Serial enviouD = true; delay(5000); } if(D==LOW){ enviouD = false; } if(E==HIGH && enviouE == false){ Serial.write('E'); // armazena E no Serial enviouE = true; delay(5000); } if(E==LOW){ enviouE = false; } if(F==HIGH && enviouF == false){ Serial.write('F'); // armazena F no Serial enviouF = true; delay(5000); } if(F==LOW){ enviouF = false; } if(G==HIGH && enviouG == false){ Serial.write('G'); // armazena G no Serial enviouG = true; delay(5000); } if(G==LOW){ enviouG = false; } if(H==HIGH && enviouH == false){ Serial.write('H'); // armazena H no Serial enviouH = true; delay(5000); } if(H==LOW){ enviouH = false; } if(I==HIGH && enviouI == false){ Serial.write('I'); // armazena I no Serial enviouI = true; delay(5000); } if(I==LOW){ enviouI = false; } if(J==HIGH && enviouJ == false){ Serial.write('J'); // armazena J no Serial enviouJ = true; delay(5000); } if(J==LOW){ enviouJ = false; } if(L==HIGH && enviouL == false){ Serial.write('L'); // armazena L no Serial enviouL = true; delay(5000); } if(L==LOW){ enviouL = false; } if(M==HIGH && enviouM == false){ Serial.write('M'); // armazena M no Serial enviouM = true; delay(5000); } if(M==LOW){ enviouM = false; } if(N==HIGH && enviouN == false){ Serial.write('N'); // armazena N no Serial enviouN = true; delay(5000); } if(N==LOW){ enviouN = false; } if(O==HIGH && enviouO == false){ Serial.write('O'); // armazena O no Serial enviouO = true; delay(5000); } if(O==LOW){ enviouO = false; } if(Q==HIGH && enviouQ == false){ Serial.write('Q'); // armazena Q no Serial enviouQ = true; delay(5000); } if(Q==LOW){ enviouQ = false; } if(R==HIGH && enviouR == false){ Serial.write('R'); // armazena R no Serial enviouR = true; delay(5000); } if(R==LOW){ enviouR = false; } if(S==HIGH && enviouS == false){ Serial.write('S'); // armazena S no Serial enviouS = true; delay(5000); } if(S==LOW){ enviouS = false; } } }
//Receptor (Arduíno Uno + Shield SIM 900 ICOMSAT 1.1)#include "SIM900.h"#include <SoftwareSerial.h>#include "sms.h"#include "GSM.h"SMSGSM sms;boolean started=false;byte rx=0;char x=0;int pinState = 0;int powerkey = 9; int statuspin = 4;void setup() {Serial.begin(9600); pinMode(rx,INPUT); pinMode(statuspin, INPUT);pinMode(pinState, INPUT);pinMode(powerkey, OUTPUT);pinState = digitalRead(statuspin); if(pinState==LOW){ digitalWrite(powerkey, HIGH); delay(2000); digitalWrite(powerkey, LOW); delay(2000);} Serial.println("GSM Shield testing."); if (gsm.begin(2400)){ Serial.println("\nstatus=READY"); started=true; } else Serial.println("\nstatus=IDLE"); }void loop() { if(Serial.available()){ x = Serial.read(); { if (x =='A'){ sms.SendSMS("+559888021164", "M1 DESARMADO"); delay(5000); } if (x =='B'){ sms.SendSMS("+559888021164", "M2 DESARMADO"); delay(5000); } if (x =='C'){ sms.SendSMS("+559888021164", "M3 DESARMADO"); delay(5000); } if (x =='D'){ sms.SendSMS("+559888021164", "M4 DESARMADO"); delay(5000); } if (x =='E'){ sms.SendSMS("+559888021164", "M5 DESARMADO"); delay(5000); } if (x =='F'){ sms.SendSMS("+559888021164", "M6 DESARMADO"); delay(5000); } if (x =='G'){ sms.SendSMS("+559888021164", "M7 DESARMADO"); delay(5000); } if (x =='H'){ sms.SendSMS("+559888021164", "M8 DESARMADO"); delay(5000); } if (x =='I'){ sms.SendSMS("+559888021164", "M9 DESARMADO"); delay(5000); } if (x =='J'){ sms.SendSMS("+559888021164", "M10 DESARMADO"); delay(5000); } if (x =='L'){ sms.SendSMS("+559888021164", "M11 DESARMADO"); delay(5000); } if (x =='M'){ sms.SendSMS("+559888021164", "M12 DESARMADO"); delay(5000); } if (x =='N'){ sms.SendSMS("+559888021164", "M13 DESARMADO"); delay(5000); } if (x =='O'){ sms.SendSMS("+559888021164", "M14 DESARMADO"); delay(5000); } if (x =='Q'){ sms.SendSMS("+559888021164", "M15 DESARMADO"); delay(5000); } if (x =='R'){ sms.SendSMS("+559888021164", "M16 DESARMADO"); delay(5000); } if (x =='S'){ sms.SendSMS("+559888021164", "M17 DESARMADO"); delay(5000); } else{ x=0; } }}}
…
Adicionado por Edson Diniz ao 14:50 em 12 agosto 2014
e-se garantir que os Níveis Lógicos sejam corretamente interpretados em cada ponta do cabo, e isso se refere tanto aos níveis de tensão, quanto às transições dos sinais digitais de LOW pra HIGH e de HIGH pra LOW (onde os tempos são chamados de "rise time" e "fall time" respectivamente) e os tempos mínimos que os sinais ficam em "LOW" ou em "HIGH".
No caso da Interface "One Wire", especificamente no caso Sensor DS18B20, isto pode ser resumido na figura mostrada a seguir que capturei do datasheet do sensor:
(clique na figura para "zoom")
O ponto fundamental a observar nesta figura, são os tempos de "slot", que nada mais são do que intervalos de tempo usados para sincronizar e garantir a correta interpretação dos bits usados na comunicação entre o DS18B20 e quem está se comunicando com sensor. E como se vê na figura anterior, são uma série de parâmetros, a maioria da ordem de algumas dezenas de micro-segundos.
Na figura anterior, a parte marcada na área na cor azul, é quando o estamos enviando um comando para o DS18B20. Já na área marcada na cor verde, é quando estamos lendo os dados fornecidos pelo DS18B20.
Especificamente, quando se está lendo os dados do DS18B20, o datasheet do mesmo faz algumas considerações a serem seguidas, e isto pode ser visto na figura a seguir:
(clique na figura para "zoom")
Na figura anterior, os pontos mais críticos eu marquei em rosa e em amarelo (são intervalos de tempo). Basicamente, a responsabilidade de seguir estas especificações, é da Biblioteca que vc está usando. Então acredita-se que esta Biblioteca siga isto corretamente. Mas como eu disse no início, os sinais digitais em cabos de longa distância, podem se degradar, tanto em termos de tensão quanto em termos de tempo, e aí reside a maioria dos problemas, pois é muito comum que as áreas que marquei em rosa e amarelo, se degradem causando a interpretação errada dos bits.
A recomendação, está em uma página do datasheet do DS18B20 que eu marquei na cor amarela mostrado na figura a seguir:
(clique na figura para "zoom")
Caso vc queira saber mais sobre as temporizações mostradas nas figuras, basta perguntar aqui no tópico.
2) segundo, deve-se prover a proteção adequada para os circuitos, em cada ponta do cabo. Ocorre que devido ao grande comprimento do cabo, aparecem "spikes" de tensão nas pontas (e claro, ao longo do cabo também). Estes "spikes" podem ter amplitudes muito maiores que as tensões de trabalho dos circuitos que estão conectados às pontas dos cabos. Por exemplo, se os sinais digitais usados são de 5V, facilmente podem aparecerem "spikes" de mais de 50V nas pontas. E aí já viu, né? Mesmo que estes "spikes" durem alguns micro-segundos ou nano-segundos, eles podem ser suficientes para danificar permanentemente os circuitos conectados às pontas dos cabos (e isto é bem fácil de ocorrer). Às vezes os "spikes" não danificam os circuitos de imediato, mas já viu o ditado: "água mole em pedra dura, tanto bate até que fura" (e acredite, neste caso ocorre mesmo um "furo" no componente eletrônico, claro, um furo microscópico que só é possível ver através de processos e instrumentos adequados).
Assim, para seu caso, proceda como no diagrama mostrado na figura a seguir:
(clique na figura para "zoom")
Vou fazer algumas considerações sobre alguns pontos desse circuito:
1) a tensão de alimentação enviada pelo cabo, é de 5V. Como vc está usando o ESP32, a melhor forma de se obter essa tensão, vai depender de como vc está alimentado a placa do ESP32. Por exemplo: se vc está alimentando via conector USB, então vc pode obter essa tensão a partir do pino "VIN" da plaquinha do ESP, pois embora a tensão ali presente seja um pouco menor que 5V (será algo próximo a 4.7V), ainda assim está dentro de uma margem aceitável para o Sistema. Mas se vc estiver alimentando a plaquinha do ESP justamente pelo pino "VIN", e esta tensão for de 5V, então pode usar este pino da mesma forma.
Observe no diagrama, que a tensão de alimentação, é enviada através de um "par trançado" do cabo CAT5 (no diagrama, é o par "laranja - branco/laranja"). O uso do "par trançado" para enviar a alimentação, é essencial, pois diversos ruídos de alta frequência serão filtrados com isso. Mas cuidado para não trocar o 5V com o GND em cada ponta do cabo (senão já sabe o que ocorre).
2) na região marcada com linha tracejada na cor azul, que fica do lado do ESP32, está o circuito que filtra o sinal digital "vindo" do DS18B20, e protege o pino do ESP32 contra "spikes" de alta-tensão existentes no cabo (que aparecem quando os sinais digitais mudam de estado). Este circuito não interfere quando é o ESP32 quem envia bits para o DS18B20. A proteção, é implementada tanto com o Resistor R1, quanto pelos Diodos D1 e D2. Observe que o Katodo de D1 está ligado aos 3.3V, ou seja, ligado à tensão de alimentação do ESP32.
O Resistor R2 (de valor 2k2), faz o papel do pullpup do Barramento "One Wire", mas do lado do ESP32. Ele é essencial para o funcionamento correto do Sistema (e haverá outro, já no lado do Sensor).
Observe que como marcado na figura, esta região em azul tracejado, deverá ficar o mais próxima possível da plaquinha do ESP32 (evite passar de 30 centímetros).
E veja que para o sinal de comunicação, é usado um fio simples (no diagrama, é o fio "branco/verde"). Ou seja: não use um "par trançado" com as pontas curto-circuitadas. Isso é para não aumentar a Capacitância entre este sinal e os demais fios (Alimentação e Blindagem). Assim escolha um fio e use apenas ele para o sinal de comunicação do "One Wire".
3) dentro da região tracejada na cor verde no lado do Sensor, temos uma área também na cor verde, onde estão os componentes R3, C2, e C3. Estes constituem um filtro para a alimentação do DS18B20. Este filtro é fundamental. Nele, R3 e C2 filtram oscilações de baixa frequência, enquanto que R3 e C3 filtram as de alta-frequência. Sem este filtro, não é possível garantir a estabilidade primária do sinal digital fornecido pelo DS18B20, quando estamos lendo os dados do mesmo.
Atenção à polaridade do Capacitor Eletrolítico C2 (o positivo está marcado na figura com um "+" na cor vermelha). A tensão de trabalho desse Capacitor deve ser acima de 16V, mas evite que seja muito alta (até 100V está de bom tamanho).
4) sobre R4, C4, D3, e D4, estes fazem a mesma coisa que aqueles componentes de mesmo valor fazem no lado do ESP32. Então não é preciso dizer mais nada sobre eles. Apenas notar que aqui, o Katodo de D3 está ligado aos 5V (no lado do ESP, o Katodo de D1 vai aos 3.3V).
E o Resistor R5 faz o mesmo que R2 faz do lado do ESP32. E estes dois Resistores são fundamentais.
5) notar que todo o circuito dentro da região tracejada na cor verde, deve ficar o mais próximo possível do Sensor DS18B20. Por isso, se possível, corte o cabo original que vem com o Sensor de forma a reduzir a distância em questão. Se a princípio vc não quiser fazer isso, tudo bem, pode manter o cabo do Sensor com o comprimento original, mas claro, se vc manter o cabo assim, faça vários testes pra ver se está tudo funcionando corretamente (ou seja, se o comprimento do cabo original não está afetando o funcionamento do Sistema) e de forma estável.
6) se o cabo CAT5 tiver malha de blindagem, NÃO ligue esta blindagem. Deixe desconectada nas duas extremidades do cabo. Embora a blindagem possa até eliminar algumas interferências, este benefício não compensa neste Sistema. Isto porque se vc ligar a blindagem ao GND, irá aumentar a Capacitância distribuída no cabo, especificamente entre o sinal do fio de comunicação e o GND, o que será péssimo para aquele sinal. Não queremos que esta Capacitância aumente, porque ela degrada o sinal de comunicação. Então deixe desligada a blindagem.
7) se existir um TERRA (da instalação da rede elétrica) no lado do DS18B20, não ligue este TERRA ao GND do circuito do DS18B20. Este tipo de ligação, tem alguns benefícios, mas não é necessário no seu Sistema, pois há também "malefícios" e por isso a princípio não compensa.
8) finalmente, atente para os tipos de alguns componentes. Especificamente, C1, C3, e C4, devem ser obrigatoriamente do tipo "Cerâmico" (NÃO serve de poliéster metalizado !!!). Atenção aos valores de C1 e C4, que são de 100pF (100 pico Farad). Não aumente além disso. Já C3 pode ter outro valor, desde que maior que 100nF (100 nano Farad, ou 100 kpF).
Já os Diodos D1 a D4, use preferencialmente do tipo "Schottky" (pode ser BAT85, BAT82, ou similares). Mas pode tentar também com o famigerado 1N4148. Já os 1N400x (os 1N4001, 1N4002, 1N4007, etc), nem pensar, pois são inadequados para esta aplicação.
Para detalhes do circuito, use o PDF que imprimi: "DS18B20_longa_distancia_01.pdf"
Ah sim: se possível use no seu código, o método de "leitura assíncrona" para o DS18B20. É muito mais eficiente em termos de tempo de processamento, e praticamente não bloqueia seu código. Mas isso é apenas uma recomendação. Se tiver alguma dúvida de como implementar isso, pergunte aqui (mas há exemplo na própria Biblioteca do Sensor).
Espero ter ajudado.
Abrçs,
Elcids…
Adicionado por Elcids Chagas ao 12:12 em 17 julho 2021