Soru:
ESP8266 Analog okuma wifi ile karışıyor mu?
JanG
2016-01-21 05:13:21 UTC
view on stackexchange narkive permalink

Kısa sürüm: ESP8266'mı WIFI'a bağlayan bir programım var, böylece ona internet üzerinden veya bir düğme üzerinden bağlı bir röleyi kontrol edebiliyorum. Ayrıca kapım için bir sensörüm var. Bu yazılım, ışığa bağımlı bir direnç eklersem (bu, ondan okuma aldığım için doğru şekilde bağlanır) ve verileri okumaya başlarsam mükemmel çalışıyor ve WIFI bağlantımı kaybediyorum. Bunun neden olduğu hakkında bir fikri olan var mı?

Uzun versiyon:

Bu programı Esp8266'mda çalıştırıyorum

  #include <ESP8266WiFi.h>IPAddress ip (192, 168, 0, 150); IPAddress ağ geçidi (192, 168, 0, 1); IPAddress alt ağı (255, 255, 255, 0); const char * ssid = "mySSID"; const char * password = "myPSW"; const char * host = "192.168.0.228"; const int buttonPin = 0; const int rölePin = 4; const int doorPin = 5; const int ldrPin = A0; / / int ldrState; // int serialCount = 0; // int ldrMin = 0; // int ldrMax = 1024; int buttonState = 0; int doorState = 0; bayt Main_Light_State_Begin; bool Main_Light_State; bool doorNotified = false; bool button_action_taken = false ; bool Main_Light_DBR = true; String HTTP_Get_Response; WiFiServer sunucusu (80); // FunctionsString HTTP_Get (char * Adress, String URL, bool Last_Line_Bool) {WiFiClient client; const int httpPort = 80; eğer (! client.connect (Adres, httpPort)) {Serial.println ("bağlantı başarısız"); "Başarısız" dönüşü; } Seri.print ("İstenen URL:"); Serial.println (URL); Serial.println ("adreste"); Serial.println (Adres); client.print (Dize ("GET") + URL + "HTTP / 1.1 \ r \ n" + "Ana Bilgisayar:" + Adres + "\ r \ n" + "Bağlantı: kapat \ r \ n \ r \ n" ); gecikme (10); Dize Yanıtı; String Last_Line; while (client.available ()) {String line = client.readStringUntil ('\ r'); Seri baskı (satır); Yanıt = Yanıt + satır; } dönüş yanıtı; Serial.println (); Serial.println ("bağlantı kapatılıyor");} void setup () {Serial.begin (115200); gecikme (1000); Serial.println (); Serial.println ();
Serial.print ("Bağlanılıyor"); Serial.println (ssid); WiFi.begin (ssid, şifre); WiFi.config (ip, ağ geçidi, alt ağ); while (WiFi.status ()! = WL_CONNECTED) {gecikme (500); Seri.baskı ("."); } Serial.println (""); Serial.println ("WiFi bağlı"); server.begin (); - Serial.println ("Sunucu başlatıldı"); Serial.println (WiFi.localIP ()); pinMode (relayPin, OUTPUT); pinMode (buttonPin, INPUT); pinMode (doorPin, INPUT); // pinMode (ldrPin, INPUT);} void loop () {if (WiFi.status ()! = WL_CONNECTED) {Serial.println ("Wifi Bağlı Değil"); } // Sensörler buttonState = digitalRead (buttonPin); doorState = digitalRead (doorPin); // ldrState = map (analogRead (ldrPin), ldrMin, ldrMax, 0, 100); //Serial.println(analogRead(ldrPin));// if (serialCount == 1000) {// Serial.println (ldrState); // serialCount = 0; //} else {// serialCount ++; // } // Kapı sensörü if (doorState == HIGH) {if (doorNotified == false) {Serial.println ("DOOR"); HTTP_Get_Response = HTTP_Get ("192.168.0.228", "/index.php/?door_opened=true", false); doorNotified = true; }} else if (doorState == LOW) {if (doorNotified == true) {doorNotified = false; gecikme (500); } else {doorNotified = yanlış; }} // Button if (buttonState == LOW) {if (button_action_taken == false) {if (Main_Light_State == true) {Serial.println ("SWITCH"); Main_Light_State = yanlış; digitalWrite (RölePin, YÜKSEK); gecikme (500); Main_Light_DBR = yanlış; } else if (Main_Light_State == false) {Serial.println ("SWITCH"); Main_Light_State = true; digitalWrite (RölePin, DÜŞÜK); gecikme (500); Main_Light_DBR = yanlış; } button_action_taken = true; }} else if (buttonState == HIGH) {if (button_action_taken == true) {button_action_taken = false; gecikme (500); } else {button_action_taken = false; }} // Main_Light_State if (Main_Light_State == true) {
digitalWrite (RölePin, DÜŞÜK); eğer (Main_Light_DBR == false) {HTTP_Get_Response = HTTP_Get ("192.168.0.228", "/index.php/?main_light_on_dbr=true", false); Main_Light_DBR = true; }} else if (Main_Light_State == false) {digitalWrite (RölePin, YÜKSEK); eğer (Main_Light_DBR == false) {HTTP_Get_Response = HTTP_Get ("192.168.0.228", "/index.php/?main_light_off_dbr=true", false); Main_Light_DBR = true; }} WiFiClient client = server.available (); eğer (! müşteri) {dönüş; } Serial.println ("yeni müşteri"); while (! client.available ()) {delay (1); } Dize req = client.readStringUntil ('\ r'); Serial.println (gerekli); client.flush (); eğer (req.indexOf ("/ main_light / on")! = -1) {Main_Light_State = true; Main_Light_DBR = yanlış; } else if (req.indexOf ("/ main_light / off")! = -1) {Main_Light_State = false; Main_Light_DBR = yanlış; } else if (req.indexOf ("/ main_light / switch")! = -1) {Serial.println ("SWITCH"); eğer (Main_Light_State == true) {Main_Light_State = false; } else if (Main_Light_State == false) {Main_Light_State = true; } Main_Light_DBR = false; } else if (req.indexOf ("/ main_light / state")! = -1) {} else {Serial.println ("geçersiz istek"); client.stop (); dönüş; } client.flush (); String s = "HTTP / 1.1 200 Tamam \ r \ nİçerik-Türü: text / html \ r \ n \ r \ n"; s + = (Main_Light_State)? "1": "0"; client.print (ler); gecikme (1); Serial.println ("İstemci bağlantısı kesildi");}  

Yukarıdaki gibi yorum yaptığım satırlarda her şey yolunda gidiyor. A0'a bağlı ışığa bağlı bir direncim var (doğru, ondan doğru ölçümler alıyorum). Şu andan itibaren bu LDR'yi içeren satırları açıklamıyorum ve böylece ondan veri okumaya başlıyorum, wifi bağlantımı kaybediyorum. Bunun neden olduğu hakkında bir fikri olan var mı? Teşekkür ederim!

* Hangi * ESP8266? Her biri farklı yeteneklere ve olanaklara sahip birçok sürüm vardır.
@Majenko Kart üzerinde seri çip ve güç regülatörü olan. (Diymall NodeMCU Devkit 1.0 CP2102 IIC SPI for Apple'ın MAC OS https://www.amazon.co.uk/dp/B00XJG7GEK/ref=cm_sw_r_other_awd_UnhOwbBSFS1GS)
AnalogRead problemleri hakkında bilgi ararken bununla karşılaştım. Bence "daha zarif çözüm" birkaç sorunu olabilir. Sorun 1. Sensör okuma ve işleme 1 ms'den az sürerse, döngü geri dönebilir ve aynı milisaniye içinde birden fazla analogRead yürütmesi elde edersiniz - istenen sonuç değil. AnalogRead (A0) 'ın kendisinin sadece 70 mikrosaniye sürdüğünü düşünürsek, eğer işlem hızlıysa, o milisaniye içinde 10 veya daha fazla analogRead (A0) yürütmesine sahip olabilirsiniz. Sorun 2. Tamamlanması birkaç mili saniye süren başka şeyler varsa (ör.
üç yanıtlar:
JanG
2016-01-21 22:18:55 UTC
view on stackexchange narkive permalink

Bunun, analog pini kısa bir süre içinde birçok kez okumaktan kaynaklandığını buldum. Değiştirdim

  ldrState = map (analogRead (ldrPin), ldrMin, ldrMax, 0, 100); Serial.println (analogRead (ldrPin)); eğer (serialCount == 1000) {Serial.println (ldrState); serialCount = 0; } else {serialCount ++; }  

bununla:

  if (serialCount == 10000) {ldrState = map (analogRead (ldrPin), ldrMin, ldrMax, 0, 100) ; Serial.println (ldrState); serialCount = 0;} else {serialCount ++;}  

Bu yaklaşımı daha önce düşünmüş olsam da, hatam kod her döngüde sensörü hala okuyor olmamdı. Her 100. döngüye kadar seri monitöre yazdırmak.

Bu hala bana saniyede birkaç kez okuma sağlıyor, bu da ihtiyacım olandan çok daha fazla. Her neyse, artık ESP8266 Analog pinimi saniyede birçok kez okuyamadığımı veya wifi bağlantısının kesileceğini biliyorum (en azından Arduino IDE ile kullanırken)

Bu harika çalışıyor, tam 4 yıl boyunca bu problemi yaşadım. Bunun rapor edilmiş bir hata olup olmadığını bilen var mı? Muhtemelen olmalı.
Phil
2017-05-30 19:35:56 UTC
view on stackexchange narkive permalink

Bu yanıtlanmış eski bir soru, ancak biraz daha zarif bir çözüm sunmak istiyorum (IMO!):

Analog verileri okuyan yöntemimde kontrol ediyor ve sadece her 50 milisaniyede bir:

  void readAnalogSensor () {if (millis ()% 50! = 0) return; . . // Sensörünüzü buradan okuyup işleyin.}  

Bu, bir döngü sayısı tutmak zorunda kalmaz ve daha belirleyici görünür - döngü sayısı değeri, neye bağlı olarak tutarlı bir şekilde artmayabilir. döngüde başka şey oluyor. Milis değerlerinin mevcut olması, bazı düğme geri alma kodu uygulamanız gerektiğinde de yararlıdır.

Vay canına, gerçekten çok uzun zaman oldu, adamım bu projeyi tekrar almalıyım! Bu gerçekten daha şık bir çözüm, teşekkürler!
farmerkeith
2017-10-16 14:27:11 UTC
view on stackexchange narkive permalink

Sabit aralıklarla tekrar vermek için genellikle yaptığım şey:

  void readAnalogSensor () {if (millis () <taskTime) return; // zaman henüz dolmadı taskTime + = 50; // aşağıdaki yürütme için zamanı ayarlayın // .... her 50 ms'de bir gerçekleştirilen görev için daha fazla kod}  

Bu, işaretsiz uzun görevTime code gerektirir >. 50 yerine bir sabit de kullanabilirsiniz.
taskTime , setup () işleminin sonunda millis () değerine yakın bir değere ayarlanmalıdır , aksi takdirde taskTime , millis () 'i yakalarken hızlı bir yürütme dizisi olacaktır.

Neredeyse doğru. Zamanlama Rollover'ı unuttunuz (https://playground.arduino.cc/Code/TimingRollover). Her 49 günde bir, mili () sıfıra çevirin ve çok düşük bir değeri (milisaniye) çok büyük bir değerle (taskTime) karşılaştırırsınız. Doğru yollar her zaman `milis () 'ile milisaniye cinsinden aralık süresi arasındaki farkı karşılaştırmaktır.
Teşekkür ederim. Döngünün her geçişinde aritmetik yapmaktan kaçınmak istedim, ancak rollover hatasına neden olmadan bu mümkün değil gibi görünüyor.
Harcanacak çok zamanın var. Çalışan tek programın sizinki olduğunu unutmayın. Zaten bekliyorsanız, döngüleri kaydetmek için hiçbir neden yoktur.


Bu Soru-Cevap, otomatik olarak İngilizce dilinden çevrilmiştir.Orijinal içerik, dağıtıldığı cc by-sa 3.0 lisansı için teşekkür ettiğimiz stackexchange'ta mevcuttur.
Loading...