Resultados da busca - %E6%81%92%E8%BE%BE%E5%A8%B1%E4%B9%9021960%E4%BB%A3%E7%90%86%E3%80%90%E2%94%8B%E5%B8%82%E5%9C%BA%E9%83%A82%E2%92%8F7%E2%92%8F01705%5B%E6%89%A3%5D%E3%80%93%E3%80%91
uele código faz.
2) sobre a questão da velocidade do Processador. Veja: no UNO o clock do Processador é de 16 MHz, o que dá um ciclo de 62.5 ns, que é o tempo de execução da instrução mais curta do AVR. Isto é bem maior que os tempos mínimos necessários para o HC595 (setup, hold, twH e twL, @5V). Além disso sabemos que a função "digitalWrite" é bem mais lenta que isso. Então no UNO não há problemas. Mas no ESP8266 vc pode estar usando o clock de 80 MHz ou o de 160 MHz, correspondendo a períodos de 12.5 ns e 6.5 ns, respectivamente. Veja que estes tempos podem não atender as especificações de temporização do HC595, caso o código de I/O resulte efetivamente em uma única instrução (o que é perfeitamente possível de ocorrer). Isto vai depender do Compilador C/C++, e de otimizações feitas por ele. Uma vez que o código tenha sido lido da Flash para a RAM do ESP8266, ele executará absurdamente mais rápido que o UNO. Então cuidados devem ser tomados para não depender do resultado da Compilação. Os tempos de 1us que acrescentei, garantem isso, sem acrescentar um "overhead" no funcionamento do seu Sistema, então aconselho manter essa temporização.
3) sobre o Capacitor C3. Nenhum CI Digital convencional tolera altas capacitâncias ligadas às suas saídas (sejam MOSFETs ou BJTs). E estamos falando de dezenas a centenas de nF (nano Farad). Então imagina esse C3 que vc usou. A consequência disto, irá variar conforme a tecnologia do CI, podendo apenas causar anomalias no funcionamento, ou mesmo um dano permanente. Cuidado aqui, pois danos permanentes nos circuitos internos dos CIs HCMOS, são extremamente traiçoeiros, podendo levar vc a confundir o que está de fato causando o problema (o motivo disso é que a coisa é digital, ou seja, se vc estiver no "limiar", poderá ser decidido para "0" ou para "1", e isto poderá corresponder ou não ao resultado que vc espera, o que certamente vai te pregar uma grande peça, e uma grande dor de cabeça).
Se vc ligou a alimentação, e acionou de "0" para "1", ou de "1" para "0", aquele C3 pode ter feito um estrago interno no HC595 (ou seja: não se restringe apenas aos dois MOSFETs de saída daquele pino 5), e portanto este CI não é mais confiável. Então a regra é clara: elimine o C3, e substitua aquele HC595. Mas veja: não adianta eliminar C3 e manter o dreno de corrente para o Backlight do Display, se esta corrente for demasiada para uma saída do HC595.
Sobre o "fader", não adianta vc colocar "Diodo-->Resistor-->Capacitor", pois provavelmente a corrente DC drenada será muito além dos limites do HC595. Então essa topologia não adiantaria. Use um MOSFET canal P para drivar o Anodo do Backlight do Display. Entre o pino do Backlight e o GND, coloque um Resistor de 10k, para fechar o circuito do MOSFET. Acrescente também um Resistor de 1k entre o Source e o Gate do MOSFET, e outro Resistor entre o Gate e o pino de controle (HC595 ou ESP). Então vc pode usar PWM para controlar a intensidade luminosa do Backlight, ou simplesmente fazer um ON/OFF simples. Claro, se usar um MOSFET adequado, poderá acrescentar uma Capacitância alta como seu C3. Mas veja: temporizações são muitas vezes controladas pela constante de tempo "RC" (acredite: Resistência Elétrica multiplicada pela Capacitância, resulta em unidades de tempo), e assim um "RC" adequado em um circuito onde "C" tem baixa capacitância pode eventualmente ser uma opção.
A outra técnica (que já usei também), é implementar uma Fonte de Corrente para o Backlight, e controlar esta corrente (pode ser via DAC discreto, aproveitando saídas que estão sobrando dos HC595). O circuito é simples, mas como sua placa já está pronta, teria que ser feito fora dela. Isso é mais usado quando há DACs disponíveis na CPU. A opção do PWM via MOSFET, é mais efetiva e mais simples, e portanto a melhor opção.
4) sobre o "R20". Ficou clara sua jsutificativa. Porém em Projetos não fazemos isso. O "correto" seria acrescentar um AmpOp configurado como seguidor de tensão após o 4051, e então fazer o divisor de tensão após o AmpOp, mas usando Resistores entre 1k e 3k3. Ou seja: para sinais enviados a um ADC, não se usa divisores com altas impedâncias. O motivo? Basicamente dois: garantir que o sample_&_hold se complete corretamente no ADC, e impedir que ruídos de alta frequência tenham amplitude considerável em relação do step do ADC (ou seja, garantir uma boa relação sinal ruído, do contrário pode ser um desastre, pois implicaria em sub-amostragem e nenhum DSP no planeta conseguiria eliminar esse ruído com pós-processamento digital).
5) sobre o HC594 x HC595, peço que veja os links que mostrei no post anterior. Uma coisa que ajuda vc a entender, é o olhar o circuito lógico interno dos dois CIs, e certamente isso irá lhe acrescentar know-how. O HC595 é mais adequado para barramentos tri-state. o HC594 é mais adequado para I/Os convencionais, onde um "PUC" (Power Up Clear) é desejado.
6) sobre o layout. Rapaz, quase dá pra dizer que não há padrão no seu layout. Mas isto seria uma injustiça, pois vc pode usar um padrão que vc determinou, e sempre seguir o mesmo em todas as suas placas. O assunto layout é algo extremamente denso e minucioso. Há uma infinidade de aspectos a serem considerados. Além disso, a prática e o tempo de experiência acumulados são essenciais. Então isso poderia nos levar a pensar: "ah, então qualquer um que comece a fazer layouts, nunca irá ter bom resultados". Mas não é bem assim, afinal existem cursos de layout e técnicas para aprender.
Quando eu carreguei o layer de cobre "Bottom", o View Mate já indicou um problema, que mostro na figura a seguir:
(clique nas figuras para "zoom")
Este problema em específico geralmente ocorre devido a uma distração do layoutista. Mas se vc usar programas de layout que façam verificação de erros (Design Errors Check), eles irão apontar isso antes, e vc poderá corrigir.
O Polígono problemático em questão, eu salientei na figura a seguir.
(clique na figura para "zoom")
Confira ele no seu layout. A versão do Proteus que tenho aqui não abre seus arquivos, pois eles são de uma versão mais recente. Por isso usei o View Mate para ver o Gerber. Mas essencialmente, em algum ponto vc "dobrou" o Polígono sobre ele mesmo, e dependendo de onde isto ocorreu, poderá ou não ser um problema para seu circuito (isto não dá pra explicar aqui, pois estenderia muito).
A sua placa, com "Top", "Bottom", "Sold Masks", e "Silk", mostrada na figura a seguir (capturada do Gerber), revela algumas coisas estranhas.
(clique na figura para "zoom")
Veja no "Bottom" alguns pontos que salientei:
(clique na figura para "zoom")
Além disso, nem sempre um sinal correndo paralelo a uma trilha de GND, é a opção adequada, pois isto aumenta a capacitância entre o sinal e o GND, e se a frequência desse sinal for alta, já sabe o que pode acontecer. Outro exemplo que contraria o que seria corretamente óbvio, é quando vc tem AmpOps de alta-frequência: colocar um plano de GND ou VCC logo abaixo dos sinais, provavelmente será um desastre (por exemplo, veja o datasheet do THS4131 neste link ). Então "espalhar" áreas de cobre de GND pela placa, pode não combinar com alguns circuitos.
Sobre padrões, certamente uma coisa que chama a atenção no seu layout, é a referência para os CIs. Geralmente se usa "U" para essa referência. Vc usou o próprio nome dos CIs. Na indústria isso não seria tolerável, mas como o layout é particular e seu, tudo bem, é vc quem irá usá-lo e assim faz do jeito que achar mais adequado.
Mas ainda há uma série de outros pontos, que não dá pra abordar aqui, por exemplo as regras de Design. Eu uso o Eagle, e capturei algumas figuras para mostrar alguns settings:
(clique nas figuras para "zoom")
Veja, vc pode especificar os settings. Mas há regras, há limites, há padrões. Uma fábrica de PCIs que se preze, irá reportar a vc problemas relacionados a esses padrões, antes de iniciar a fabricação, te dando a chance de corrigir esses "problemas".
Uma boa maneira de aprender sobre layout (além da prática é claro), é ler "APP-Notes" dos Fabricantes. Eles são mais curtos para se ler do que livros, e vão mais direto ao ponto, reduzindo o tempo de aprendizado. Bons fabricantes tem muitos "APP-Notes" para isso, como é o caso da Texas (recomendo muito), Microchip, NXP, e até mesmo Intel. Geralmente são ótimos. Mas estão em inglês, e exigem também outros conhecimentos técnicos (principalmente em Circuitos). Então nem sempre será um caminho fácil, já que é um assunto denso e muito técnico.
Sobre o problema com o HC595, vamos torcer pra que seja algo pontual nesta placa. O mais provável é que seja uma bobagem (estas coisas são muito traiçoeiras e confundem muito, dando pistas erradas). Mas uma técnica adequada de depuração do Hardware, sempre irá convergir para o problema.
abrçs,
Elcids…
Adicionado por Elcids Chagas ao 19:57 em 31 agosto 2021
onhecimento).
Coloquei ainda no Loop para mostrar o resultado da monitoração após o recebimento de todas as repetições (aguarda 2 segundos sem receber transmissão).
Para mostrar o resultado, acrescentei um if e uma chamada à função millis() em todas as execuções da função loop. Isso simularia um pequeno overhead de processamento num programa real que faz alguma coisa além de simplesmente reconhecer código recebidos, as instruções dentro do if só são executadas quando não há transmissão.
#include <EEPROM.h>#define DUMP//# undef DUMP
const byte pinRF = 2; // Pin where RF Module is connected. If necessary, change this for your project
int lambda; // on pulse clock width (if fosc = 2KHz than lambda = 500 us)
struct rfControl //Struct for RF Remote Controls{ unsigned long addr; //ADDRESS CODE boolean btn1; //BUTTON 1 boolean btn2; //BUTTON 2 unsigned long milisecs; // quando terminou de reconhecer};#ifdef DUMP// buffer para armazenar os reconhecimentosunsigned int reg = 0;struct rfControl rfs[30];#endif
boolean ACT_HT6P20B_RX(struct rfControl &_rfControl){ static boolean startbit; //checks if start bit was identified static int counter; //received bits counter: 22 of Address + 2 of Data + 4 of EndCode (Anti-Code) static unsigned long buffer; //buffer for received data storage int dur0, dur1; // pulses durations (auxiliary) if (!startbit) {// Check the PILOT CODE until START BIT; dur0 = pulseIn(pinRF, LOW); //Check how long DOUT was "0" (ZERO) (refers to PILOT CODE) //If time at "0" is between 9200 us (23 cycles of 400us) and 13800 us (23 cycles of 600 us). if((dur0 > 9200) && (dur0 < 13800) && !startbit) { //calculate wave length - lambda lambda = dur0 / 23; //Reset variables dur0 = 0; buffer = 0; counter = 0; startbit = true; } }
//If Start Bit is OK, then starts measure os how long the signal is level "1" and check is value is into acceptable range. // ********** trocar o IF abaixo por WHILE para que o código na função LOOP não interfira no reconhecimento. // while (startbit && counter < 28) if (startbit && counter < 28) { ++counter; dur1 = pulseIn(pinRF, HIGH); if((dur1 > 0.5 * lambda) && (dur1 < (1.5 * lambda))) //If pulse width at "1" is between "0.5 and 1.5 lambda", means that pulse is only one lambda, so the data é "1". { buffer = (buffer 1) + 1; // add "1" on data buffer } else if((dur1 > 1.5 * lambda) && (dur1 < (2.5 * lambda))) //If pulse width at "1" is between "1.5 and 2.5 lambda", means that pulse is two lambdas, so the data é "0". { buffer = (buffer 1); // add "0" on data buffer } else { //Reset the loop startbit = false; } } //Check if all 28 bits were received (22 of Address + 2 of Data + 4 of Anti-Code) if (counter==28) { // Check if Anti-Code is OK (last 4 bits of buffer equal "0101") if ((bitRead(buffer, 0) == 1) && (bitRead(buffer, 1) == 0) && (bitRead(buffer, 2) == 1) && (bitRead(buffer, 3) == 0)) { counter = 0; startbit = false; //Get ADDRESS CODE from Buffer _rfControl.addr = buffer >> 6; //Get Buttons from Buffer _rfControl.btn1 = bitRead(buffer,4); _rfControl.btn2 = bitRead(buffer,5); #ifdef DUMP // armazena para conferência memcpy(&rfs[reg], &_rfControl, 10); // 4 + 1 + 1 + 4 rfs[reg++].milisecs = millis(); #endif //If a valid data is received, return OK return true; } else { //Reset the loop startbit = false; #ifdef DUMP //Get ADDRESS CODE from Buffer_rfControl.addr = buffer >> 6;//Get Buttons from Buffer_rfControl.btn1 = bitRead(buffer,4);_rfControl.btn2 = bitRead(buffer,5);
// armazena para conferência memcpy(&rfs[reg], &_rfControl, 10); // 4 + 1 + 1 + 4 rfs[reg++].milisecs = millis(); #endif } } //If none valid data is received, return NULL and FALSE values _rfControl.addr = NULL; _rfControl.btn1 = NULL; _rfControl.btn2 = NULL; return false;}
void setup(){ pinMode(pinRF, INPUT); pinMode(13, OUTPUT); reg = 0; Serial.begin(9600);}unsigned long lastrecon = 0;void loop(){ digitalWrite(13, digitalRead(pinRF)); //blink de onboard LED when receive something struct rfControl rfControl_1; //Set variable rfControl_1 as rfControl type if(ACT_HT6P20B_RX(rfControl_1)) { lastrecon = millis(); //If a valid data is received, print ADDRESS CODE and Buttons values Serial.print("Address: "); Serial.print(rfControl_1.addr, HEX); Serial.print(" B1: "); Serial.print(rfControl_1.btn1, BIN); Serial.print(" B2: "); Serial.println(rfControl_1.btn2, BIN); } // este trecho aproveita que não está reconhecendo nada no momento e mostra os dados dos erros // além disso, inclui um pouco de overhead de processamento quando está reconhecendo algo (uma chamada a millis() e um if simples) // no caso de trocar o if pelo while na rotina de reconhecimento, este overhead deixa de existir. #ifdef DUMP unsigned long now = millis(); if (now - lastrecon > 2000 && reg > 0) { // passou mais de 2 segundos do último reconhecimento, então acabaram as repetições automáticas da transmissão do código for (int i = 0; i < reg; i++) { Serial.print(rfs[i].addr, HEX); Serial.print(" "); Serial.print(rfs[i].btn1, BIN); Serial.print(rfs[i].btn2, BIN); Serial.print(","); Serial.print(rfs[i].milisecs); Serial.println(); } reg = 0; } #endif}
…
ção sobre suas dúvidas:
1a resposta :
Posso deixar meu celular carregando a noite inteira?
A resposta esta correta sobre o funcionamento do carregador. Deixar o carregador ligado não danifica a bateria.
Mas não recomendo de forma alguma ! A minha visão é sobre segurança !
Imagine se houver alguma falha elétrica no carregador ou na bateria, e provocar um incêndio ?
Os produtos eletrônicos não são infalíveis. Se um raio cair perto da sua casa, pode explodir o carregador.
E sabendo que o único sentido que não alerta o ser humano quando esta dormindo é o olfato, existe o risco.
Isso eu aprendi com um neuro-cirurgião amigo meu. Eu não sabia dessa limitação do homem.
Por isso é perigoso acender uma lareira no quarto de dormir. Várias pessoas já morreram com a fumaça.
A unica certeza é de morrer com um sono tranquilo.
2a;
Devo deixar bateria acabar por completo para não viciá-la. Mito ou verdade?
Baterias de Lítio tem algumas regras de uso bem conhecidas . Nunca exceda a tensão de carga e nunca descarregue a bateria abaixo da tensão de limite minimo ! Como você esta questionando sobre bateria de celular, não precisa se preocupar com isso, pois existem circuitos internos no celular ( ou no carregador) que limitam essa tensão máxima de carga e tensão mínima de descarga. Quando a bateria descarrega até o limite mínimo, o celular é desligado ! Por isso não se preocupe com isso.
E mais, Baterias de Lítio não tem efeito de memória.
Para baterias de Li Ion :
Tensão de carga max = 4,20 V
Tensão mínima = 3,0 V
OBs: os aparelhos novos usam Baterias LiPo , e esses valores podem ser diferentes.
Se quiser aprender mais, recomendo a leitura desse site ( o site mais completo que eu conheço) :
https://batteryuniversity.com/learn/
https://batteryuniversity.com/learn/article/charging_lithium_ion_ba...
https://batteryuniversity.com/learn/article/discharge_characteristi...
https://batteryuniversity.com/learn/article/how_to_prolong_lithium_...
https://batteryuniversity.com/learn/article/bu_808b_what_causes_li_...
Se o seu smartphone for Android, recomendo esse aplicativo muito legal ! Sensores Multitarefa
https://play.google.com/store/apps/details?id=com.wered.sensorsmult...
Com esse aplicativo, poderá ver a tensão e temperatura da bateria.
Aproveite e veja todos os sensores do seu aparelho. Muito legal.
…
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
mplos. Se vc não fizer isso, será uma empreitada difícil e ainda poderá não ter bons resultados. Então dedique-se e observe as coisas com a devida atenção.
Vamos então falar dos pontos enumerados que postei e vc respondeu. Então, seguindo a mesma enumeração:
1) ok, acho que ficou claro como os 3 LEDs (verde, vermelho, e amarelo) devem se comportar.
Mas conferindo se realmente entendi: o "verde" indica que o Sistema está funcionando e fica piscando indicando isso, mas pára de piscar quando algum problema é detectado (e claro, volta automaticamente a piscar quando o problema deixa de existir).
O "vermelho" pisca enquanto os Sensores de Pressão indicarem problema.
E o "amarelo" pisca enquanto o Sensor de Umidade indicar problema.
Mas ainda tenho uma questão sobre os níveis de Umidade, porém irei falar sobre isso mais à frente.
Sobre o envio de SMS, no seu código original este envio é feito apenas para problemas nos níveis de Pressão. Mas no post anterior, vc disse que deveria também ser enviado SMS para problemas de Umidade. Então pergunto: afinal, em que situações um SMS deve ser enviado?
2) ok, pelo código já tinha visto que era um Sensor de Pressão com saída analógica (eu só não sabia se era um único Sensor com dois sinais ou se eram dois Sensores independentes cada um com seu sinal). Sobre a parte da aferição, tenho um comentário a fazer, porém só o farei depois que publicar o código (mas não se preocupe porque é tranquilo, e se eu me esquecer disso, por favor me lembre).
Mas há uma consideração sobre a conexão dos Sensores de Pressão, que tem implicação no código. Vou esclarecer parcialmente (posteriormente darei mais detalhes). Veja este trecho do seu código original, onde vc faz as conversões AD para obter os níveis de pressão indicados pelos sensores, conforme mostro na figura a seguir salientado em amarelo:
(clique na figura para "zoom")
Observe que existe um "delay" de 80 mili-segundos entre a conversão AD (função "analogRead") do primeiro Sensor e a conversão do segundo Sensor de Pressão. A pergunta é: porque vc inseriu este "delay"? sem ele vc estava obtendo valores incorretos? Vou explicar porque estou perguntando sobre isso:
Ocorre que se vc não fizer a conexão adequada de um sinal analógico ao Arduino, poderão ocorrer erros nos valores convertidos, especialmente se existir no Sistema mais de um Canal Analógico sendo utilizado (que é o seu caso, pois além dos dois sensores de pressão vc tem também o sensor de Umidade).
Este problema ocorre porque a "impedância AC" do sinal analógico não é baixa o suficiente para permitir que o Conversor AD faça um sample adequado (o problema pode ocorrer mesmo quando a "impedância DC" é baixa, embora neste caso seja mesmo perceptível). Como consequência aparece um erro no valor convertido, quando se troca de um canal para outro (e também ocorre um problema chamado "Injeção de Carga", que os Fabricantes de Chips não gostam de falar porque nem sempre é fácil eliminar e eles não querem admitir ou evidenciar o problema).
Existem essencialmente duas técnicas para se eliminar esses erros (ou reduzi-los de forma que não sejam perceptíveis), e uma delas é fazer algo parecido com o que vc fez, acrescentando algo semelhante ao "delay". A outra forma é conectando adequadamente o sinal analógico, e esta é a forma preferível. Eventualmente inclusive, se utiliza as duas técnicas, se a coisa for muito "braba" (ou por precaução, como sempre faço).
Assim eu te aconselharia a usar a técnica de conectar de forma adequada o sinal dos seus Sensores ao Arduino. No entanto isso exige que vc acrescente um Resistor e um Capacitor em cada sinal. Mas isso fica a seu critério, e eu não posso determinar isso. Caso vc decida usar essa técnica, eu calcularei os Resistores e os Capacitores mais adequados, e mostrarei como vc deve fazer as conexões (é bem simples).
Então pense sobre isso. Mas se vc quiser usar apenas a técnica no código, tranquilo, farei isso mas sem usar o "delay" pois não é com ele que se implementa isso. Aproveito para dizer, que por regra geral, não se deve usar o "delay" fora da função "setup" do Arduino, e posteriormente explicarei porque.
Ainda sobre a Pressão, por favor veja a figura a seguir:
(clique na figura para "zoom")
Na parte marcada em "rosa", ficou claro que a Pressão é calculada em unidades de "bar", sendo esta a unidade que vc exibe no Display LCD. E portanto também fica claro que é esta unidade de pressão que seu Sistema realmente irá trabalhar depois de obter o valor do Sinal dos Sensores de Pressão.
Mas na parte em "verde" na figura, vc faz a conversão para uma outra unidade intermediária, antes de finalmente converter para "bar". Então pergunto: que unidade intermediária é esta? Vc faz isso pra facilitar seu sistema de calibração para cada um dos Sensores? (eu tenho quase certeza que seja isso, mas é melhor perguntar). Pergunto também, porque como eu disse antes, eu irei posteriormente fazer algumas considerações sobre a calibração, e que pode vir a te ajudar nesse processo.
Sobre o Sensor de Umidade, há uma sugestão que eu gostaria de te fazer. Vc não acha que seria mais adequado ter o valor da Umidade sendo diretamente proporcional à Umidade real? Veja: atualmente no seu Sistema, este valor é inversamente proporcional à Umidade real, ou seja, o máximo valor (no caso "1023") se refere à mínima Umidade, enquanto que o mínimo valor que é "0" (zero) se refere à máxima Umidade. Se fosse diretamente proporcional, este valor resultante poderia ser chamado de "Índice de Umidade", e quando seu valor for "0" indicará também a mínima Umidade. Esta forma me parece ter mais sentido. O que vc acha?
Sei que no código vc está usando a forma inversamente proporcional porque é assim que o pessoal usa por aí em blogs e sites na Internet. Eles simplesmente fazem a conversão AD no Arduino sem mais nenhum tratamento e que resulta nesse comportamento. Como vc disse que obteve pedaços de código aqui e ali na Internet, por tabela acabou seguindo esta regra "invertida". Mas pense sobre a sugestão que fiz.
3) sobre o Buzzer, está bem claro como deverá funcionar. Mas tenho uma questão sobre o Buzzer em si. Me parece que vc está usando um "Buzzer passivo", que é aquele que só emite som quando vc gera o sinal de som no Arduino (e seu código faz isso através da função "tone"). Para melhor entender veja a figura a seguir:
(clique na figura para "zoom")
Observe que marquei em "verde", uma informação na plaquinha do Buzzer que diz qual é o nível lógico que "aciona" o Buzzer. Este da figura é o mais comum, e vc pode ver que está marcado na placa que ele é acionado por nível lógico "LOW". É importante saber qual é este nível para o "Buzzer passivo", pois isto permite que efetivamente não seja aplicada tensão sobre o "Buzzer" quando este não está emitindo som. Veja: quando termina a ação da função "tone" (ou quando se usa a função "noTone"), o nível lógico que fica na saída do Arduino é justamente o nível "LOW", e no caso da plaquinha da figura estaríamos aplicando tensão ao Buzzer, embora este não emita som (pois o sinal aplicado é agora estático). Isto força o "piezzo" do Buzzer, e a médio ou longo prazo poderá danificá-lo. Então é melhor evitar isso. Para tal, basta aplicar-se o nível lógico adequado ao Buzzer logo após parar o sinal do som. Já fiz isso no código, porém não sei qual é o nível lógico que liga seu Buzzer. Então por favor, verifique qual é, e se possível coloque aqui uma foto da sua plaquinha Buzzer, para deixarmos claro.
4) sobre as mensagens de SMS, tranquilo, eu imaginava que vc iria ainda ajustar isso adequadamente. Mas lembre-se que o bom-senso nos diz: não deixe para depois o que se pode facilmente fazer agora.
No código irei colocar mensagens que estejam relacionadas a cada alerta, e depois vc altera isso da forma que vc achar mais adequado. O mesmo se aplica para as mensagens exibidas no Display LCD para as Pressões medidas.
Sobre a questão do "auto-teste" tanto para os LEDs quanto para os demais elementos (Buzzer, SMS, etc), é tranquilo de implementar. Mas irei fazer isso somente depois que vc disser que todo o restante está funcionando da forma correta, ok?
Eu ainda tenho uma dúvida sobre as faixas de Umidade que vc usa para sinalizar os alertas (se vc olhar com cuidado seu código original, talvez vc já descubra que dúvida é esta). Mas irei perguntar depois, já que isto praticamente não tem impacto no código.
O código está 99% pronto. Falta apenas esclarecer os pontos aqui mencionados.
Fico no aguardo de um retorno seu sobre estes pontos.
Ah Cabana, por favor, mude o título deste tópico para um que tenha realmente sentido sobre o que vc está implementando, porque este nome que vc colocou, pelo amor de Deus. E ainda é o mesmo nome do seu tópico anterior. Jesus.
Abrçs,
Elcids…
Adicionado por Elcids Chagas ao 19:55 em 29 fevereiro 2020