Skocz do zawartości

Czujnik jakości powietrza


Pomocna odpowiedź

Szczerze powiem, że z moich wczorajszych dokonań jestem bardzo zadowolony :). Może dla Was do pestka, ale dla mnie to nowe doświadczenie. Dotychczas void setup() i void loop () to dla mnie taka świętość była po kursach Forbota ale uświadomiliście mi, że to zwykłe pętle jak każde inne i można z nimi robić to co się chce.

Sposób z przyciskiem i dwoma różnymi programami, super pomocne.

OTA, ekstra sprawa!:)

Najważniejsze (i jestem z siebie dumny;)), że umiem już to zastosować w praktyce. Trochę czasu to zajęło i bez Waszej pomocy nic bym nie zdziałał, ale wczorajsza satysfakcja z udanych szkiców   ... bezcenna:)

Wracając do OTA, mie wiem dokładnie co robi ta funkcja ArduinoOTA.handle();, czy od niej zależą całe ustawienia OTA i wystawianie portu internetowego czy tylko odpowiada za "nasłuch" nowego wysłanego szkicu... 

Link do komentarza
Share on other sites

W dużym skrócie: ArduinoOTA.handle() robi wszystko czym się nie chcesz zajmować. Oczywiście potrzebna jest inicjalizacja (w sumie wystarczą ArduinoOTA.setHostname() i ArduinoOTA.begin()) i połączenie z netem. Więcej nie powinno Cię interesować (ze szczególnym uwzględnieniem mało interesujących metod  onStart, onEnd i ogólnie onCośtam, bez których normalni ludzie mogą się obejść).

 

  • Lubię! 2
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

(edytowany)
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

const char* ssid = "xxx";
const char* password = "xxx";
void setup() {
  pinMode(D2, INPUT_PULLUP);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
   if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    delay(5000);
    ESP.restart();
   }
 ArduinoOTA.begin();
 pinMode(D4,OUTPUT);
    }
  

void loop() {
  ArduinoOTA.handle();
      digitalWrite(D4, HIGH);   
  delay(200);                       
  digitalWrite(D4, LOW);    
  delay(200);     
    }

Tak?

co to "ArduinoOTA.setHostname()"? Co robi? Też do setup-a?

Co z yield();?

Czy takie OTA uruchomione "w tle" gryzie się jakoś z normalna komunikacją z siecią wykonywaną przez "główny" program?

Edytowano przez SOYER
Poprawiłem formatowanie.
Link do komentarza
Share on other sites

Coś w tym stylu.

setHostname do setupa, wykonujesz raz, powoduje to, że możesz znaleźć swojego ESP po nazwie a nie tylko po IP (inaczej mówiąc mDNS).

Przykład (bardzo skrócony) mojego kodu:

void setup()
{
    WiFi.begin(ssid, pass);
    WiFi.config(MY_IP, MY_Gateway, MY_Netmask, MY_Nameserver);
    ArduinoOTA.setHostname("lazienka");
}

I efekt działania:

ethanak@moiraine:~$ ping -c 4 lazienka.local
PING lazienka.local (192.168.1.37) 56(84) bytes of data.
64 bytes from 192.168.1.37 (192.168.1.37): icmp_seq=1 ttl=128 time=10.6 ms
64 bytes from 192.168.1.37 (192.168.1.37): icmp_seq=2 ttl=128 time=9.24 ms
64 bytes from 192.168.1.37 (192.168.1.37): icmp_seq=3 ttl=128 time=3.79 ms
64 bytes from 192.168.1.37 (192.168.1.37): icmp_seq=4 ttl=128 time=1.03 ms

--- lazienka.local ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 1.039/6.190/10.683/3.930 ms

yield() to to samo co delay(0) - czyli jeśli wywołujesz delay() odpowiednio często nie potrzebujesz yield(). Oprócz tego yield wywoływany jest za każdym obrotem pętli loop.

  • Lubię! 1
  • Pomogłeś! 1
Link do komentarza
Share on other sites

(edytowany)
3 godziny temu, ethanak napisał:

ArduinoOTA.setHostname("lazienka");

Super sprawa, jak się ma więcej urządzeń do obsłużenia to trudno pamiętać ich IP. Czyli ta funkcja nadaje unikalną nazwę w sieci urządzeniu na którym jest uruchamiana.

3 godziny temu, ethanak napisał:

yield() to to samo co delay(0) - czyli jeśli wywołujesz delay() odpowiednio często nie potrzebujesz yield(). Oprócz tego yield wywoływany jest za każdym obrotem pętli loop.

Czy dobrze rozumiem: jeśli w programie jest często wywoływane delay(), to nie ma potrzeby używania yield() przy OTA(OTA wykonuje się w czasie delay ew. yield??), jeśli jednak ktoś nie używa delay(jak ja się staram), ale pętla często(jak często?) "zawija do początku" czyli nie trwa długo, to z racji tego, że yield jest z automatu wykonywane(tak?) z każdym obrotem pętli to nie ma potrzeby wywolywania yield... TAK??

.

Kompletny kod obsługujący mój projekt z PMS5003, LCD, DHT, wentylatorem, obslugą BLYNK-a...oraz oczywiście OTA. Program cały czas czeka na moją aktualizację, w arduino IDE wyświetla mi sie nazwa urządzenia w porcie internetowym. Gniazdo USB na obudowie stało się zbędne:-).

#include <Wire.h>
#include <SoftwareSerial.h>
SoftwareSerial swSer(D5, D6, false, 256);
#include "PMS.h"
#include <Timers.h>
#include <SimpleDHT.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include "RTClib.h"
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

int pinDHT11 = D4;
SimpleDHT11 dht11(pinDHT11);
char auth[] = "x";
char ssid[] = "xx";
char pass[] = "xxx";

Timer sekunda;//led
Timer minutDwie;//
Timer sekundPiec;
Timer sekundTrzydziesci;
Timer minuta;
//Timer minutPiec;
Timer minutDziesiec;
Timer sekundDziesiec;
Timer klapka;

PMS pms(swSer);
PMS::DATA data;

byte temperatura;
byte wilgotnosc;

RTC_DS1307 rtc;

#define treconnect 30 //czasy wywoływania Blynk.run przy braku łączności w sek
int liczreconnect = 10;

enum FIRST { ONE=1,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,TEN};
int menu=THREE;
LiquidCrystal_I2C lcd(0x3F,16,2);
#define pin1silnika D7
#define pin2silnika D8
#define pinFan D3
#define pinPrzekaznik D0
WidgetLED ledNode(V41);
int blueLED = 0;

boolean dhtStart = 0;

void setup()
{
  Wire.begin(D2,D1);
  Serial.begin(9600);   // GPIO1, GPIO3 (TX/RX pin on ESP-12E Development Board)
  swSer.begin(9600);
  WiFi.begin(ssid, pass);
  Blynk.begin(auth, ssid, pass);
  
  Blynk.config(auth, IPAddress(139, 59, 206, 133));
  Blynk.connect(); 
  ArduinoOTA.setHostname("PMS5003_ESP");   
  ArduinoOTA.begin();    
 //rtc.adjust(DateTime(__DATE__, __TIME__));
  rtc.begin();
  pms.passiveMode();    // Switch to passive mode
  lcd.init();                      // initialize the lcd 
  lcd.backlight();
  pinMode(pin1silnika, OUTPUT); //Sygnały sterujące kierunkiem obrotów silnika nr 1
  pinMode(pin2silnika, OUTPUT);
  pinMode(pinFan, OUTPUT);
  digitalWrite(pinFan, HIGH);
  sekunda.begin(995);
  minutDwie.begin(120000);//spr. DHT
  sekundPiec.begin(4850);//przeł. one<->two
  sekundTrzydziesci.begin(9998);//po wybudzeniu PMS
  minutDziesiec.begin(600000);//uspienie PMS
  minuta.begin(59987);//went
  sekundDziesiec.begin(9689);//blynk run
  klapka.begin(3000);//klapka
  //minutPiec.begin(299895);
}
void loop() {
  ArduinoOTA.handle();
  miganieLED();
  Blynk.run();
switch(menu){
  case ONE:
   
   one();
   checkTimeAndHumidity();
   if(sekundPiec.available()){
    lcd.clear();
    sekundPiec.restart();
    menu=TWO;
   }
  break;
  case TWO:
   two();
   checkTimeAndHumidity();
   if(sekundPiec.available()){
    lcd.clear();
    sekundPiec.restart();
    menu=ONE;
   }
  break;
  case THREE:
   three();
  break;
  case FOUR:
   four();
  break;
  case FIVE:
   five();
  break;
  case SIX:
   six();
  break;
  case SEVEN:
   seven();
  break;
  case EIGHT:
   eight();
  break;
  case NINE:
   nine();
  break;
  case TEN:
  ten();
  break;
}
}
 
void one(){
  DateTime now = rtc.now();
  lcd.setCursor(0,0);
  lcd.print("      ");
  lcd.print(now.hour(), DEC);
  lcd.print(":");
  lcd.print(now.minute(), DEC);
  lcd.setCursor(0,1);
  lcd.print("   ");
  lcd.print(now.day(), DEC);
  lcd.print('.');
  lcd.print(now.month(), DEC);
  lcd.print('.');
  lcd.print(now.year(), DEC);
 }
 void two(){
  lcd.setCursor(0,0);
  lcd.print("PM1 ");
  lcd.print(data.PM_AE_UG_1_0);
  lcd.print(" PM2,5 ");
  lcd.print(data.PM_AE_UG_2_5);
  lcd.setCursor(0,1);
  lcd.print("    PM 10  ");
  lcd.print(data.PM_AE_UG_10_0);
 }
 void three(){
  lcd.setCursor(0,0);
  lcd.print("  Wilg. < 70%");
  lcd.setCursor(0,1);
  lcd.print("  Wybudzam PMS");
  
  pms.wakeUp(); //30 sekund poczekaj
  if(sekundTrzydziesci.available()){
    lcd.clear();
    sekundPiec.restart();
    menu=FOUR;
  }
 }
void four(){
  
  lcd.setCursor(0,0);
  lcd.print("      PMS");
  lcd.setCursor(0,1);
  lcd.print("wykonuje pomiar");
  pms.requestRead();
  pms.readUntil(data);
  if(sekundPiec.available()){
    Blynk.virtualWrite(35,"   ",data.PM_AE_UG_1_0," ","ug/m3");
    Blynk.virtualWrite(36,"   ",data.PM_AE_UG_2_5," ","ug/m3");
    Blynk.virtualWrite(37,"   ",data.PM_AE_UG_10_0," ","ug/m3");
    Blynk.virtualWrite(38,data.PM_AE_UG_1_0);
    Blynk.virtualWrite(39,data.PM_AE_UG_2_5);
    Blynk.virtualWrite(40,data.PM_AE_UG_10_0);
    lcd.clear();
    sekundPiec.restart();
    menu=FIVE;
  }
 }
 void five(){
  
  lcd.setCursor(0,0);
  lcd.print("Usypiam czujnik");
  lcd.setCursor(0,1);
  lcd.print("  na 10 minut");
  pms.sleep();
  if(sekundPiec.available()){
    lcd.clear();
    sekundPiec.restart();
    klapka.restart();
    menu=SIX;
  }
 }
 void six(){
  
  lcd.setCursor(0,0);
  lcd.print("Otwieram doplyw");
  lcd.setCursor(0,1);
  lcd.print("   powietrza");
  digitalWrite(pin1silnika, LOW); //Silnik nr 1 - obroty w lewo
  digitalWrite(pin2silnika, HIGH); 
  if(klapka.available()){
  digitalWrite(pin1silnika, LOW); //Silnik nr 1 - obroty stop
  digitalWrite(pin2silnika, LOW); 
  }
   if(sekundPiec.available()){
    lcd.clear();
    minuta.restart();
    menu=SEVEN;
  }
 }
 void seven(){
  
  lcd.setCursor(0,0);
  lcd.print("   Wentylator");
  lcd.setCursor(0,1);
  lcd.print("    wlaczony");
  digitalWrite(pinFan, LOW);
  if(minuta.available()){
    lcd.clear();
     sekundPiec.restart();
    menu=EIGHT;
  }
  
 }
 void eight(){
 
  lcd.setCursor(0,0);
  lcd.print("   Wentylator");
  lcd.setCursor(0,1);
  lcd.print("   wylaczony");
  digitalWrite(pinFan, HIGH);
  if(sekundPiec.available()){
    lcd.clear();
     sekundPiec.restart();
     dhtStart=false;
     klapka.restart();
    menu=NINE;
  }
 
 }
 void nine(){
 
  lcd.setCursor(0,0);
  lcd.print(" Zamykam doplyw");
  lcd.setCursor(0,1);
  lcd.print("   powietrza");
  digitalWrite(pin1silnika, HIGH); //Silnik nr 1 - obroty w lewo
  digitalWrite(pin2silnika, LOW); 
  if(klapka.available()){
  digitalWrite(pin1silnika, LOW); //Silnik nr 1 - obroty stop
  digitalWrite(pin2silnika, LOW); 
  }
  if(dhtStart==false){
    dht11.read(&temperatura, &wilgotnosc, NULL);
   Serial.println(temperatura);
   Serial.println(wilgotnosc);
   dhtStart=true;
  }
  if(sekundPiec.available()){
    lcd.clear();
    sekundPiec.restart();
    menu=TEN;
  }
 }
 void ten(){
  
  lcd.setCursor(0,0);
  lcd.print("   Temp.  ");
  lcd.print(temperatura);
  lcd.print(" *C");
  lcd.setCursor(0,1);
  lcd.print("   Wilg.  ");
  lcd.print(wilgotnosc);
  lcd.print(" %RH");
  if(sekundPiec.available()){
    lcd.clear();
    sekundPiec.restart();
    menu=ONE;
  }
 }
 void checkTimeAndHumidity(){
  if(minutDwie.available()){
   dht11.read(&temperatura, &wilgotnosc, NULL);
  Serial.println(temperatura);
  Serial.println(wilgotnosc);
  minutDwie.restart();
  }
  if((minutDziesiec.available()) && (wilgotnosc < 77)){
    lcd.clear();
    sekundTrzydziesci.restart();
    minutDziesiec.restart();
    menu=THREE;
  }
 }
 
void miganieLED(){
  if(sekunda.available()){
   blueLED = !blueLED ;
   if (blueLED == 0) {
    ledNode.off(); //miganie vLED dla kontroli połączenia
   }
     else {
    ledNode.on();
    }
    sekunda.restart();
}
}

Dziękuję Ethanak:-)

 

P.S. Jak teraz zrobić to samo dla arduino MEGA podpięte z ethernet shieldem (https://elty.pl/pl/p/Ethernet-shield-W5100-for-Arduino-/965)podpiętym kablem do neta... da się? Czy muszę wymienić na shielda z esp?

Edytowano przez SOYER
Poprawiłem formatowanie.
Link do komentarza
Share on other sites

Hej, jako, że przerobilem trochę sprawę dolotów powietrza i ich zamykania i otwierania, postanowiłem dołożyć do serw diodę ktora pokazuje czy są one zasilane czy nie. Tak dla bajeru. Generalnie zasilanie serw włączam przed ich wysterowaniem i wyłączam po, żeby się tam nie grzały czy coś. Pojawił się taki problem, że kiedy zasilanie serw jest odłączone to dioda i tak delikatnie swieci, okazało się, że na lini zasilania pojawia się napięcie z lini sterowania(po odpięciu lini sterowania dioda gaśnie). Temat obszedłem dokładając linijkę ustawiającą linię sterowania serw w stan niski. Jednak wtedy serwo przestało być sterowane w następnym obiegu. Wywaliłem więc z setup "serwo.attach(D8)" i wpisałem w loop przed miejscem gdzie serwo ma się uruchomić. Niestety w drugim obiegu serwo już nie działa. 
Czyli jeśli dam stan LOW na pinie sterującym serwem do pomimo późniejszego wywolania funkcji serwo.attach() już się nie da nim sterować?

Wykomentowałem to pinMode(D8, LOW); i proszę was o radę jak zgasić tą diodę? 😉

Kod:

#include <Wire.h>
#include <SoftwareSerial.h>
SoftwareSerial swSer(D5, D6, false, 256);
#include "PMS.h"
#include <Timers.h>
#include <SimpleDHT.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include "RTClib.h"
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <Servo.h>

int pinDHT11 = D4;
SimpleDHT11 dht11(pinDHT11);
char auth[] = "4fc87431c0ec4c1e90778d8c5765b1c8";
char ssid[] = "eiNET_eu_035A9922";
char pass[] = "305937442";

Timer sekunda;//led
Timer minutDwie;//
Timer sekundPiec;
Timer sekundTrzydziesci;
Timer minuta;
Timer minutDziesiec;
Timer sekundDziesiec;

PMS pms(swSer);
PMS::DATA data;

byte temperatura;
byte wilgotnosc;

Servo serwo;

RTC_DS1307 rtc;

enum FIRST { ONE=1,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,TEN};
int menu=THREE;
LiquidCrystal_I2C lcd(0x3F,16,2);

#define pinFan D3
#define przekaznikSerwo D0
WidgetLED ledNode(V41);
int blueLED = 0;

boolean dhtStart = 0;

void setup()
{
  Wire.begin(D2,D1);
  Serial.begin(9600);   // GPIO1, GPIO3 (TX/RX pin on ESP-12E Development Board)
  swSer.begin(9600);
  WiFi.begin(ssid, pass);
  Blynk.begin(auth, ssid, pass);
  
  Blynk.config(auth, IPAddress(139, 59, 206, 133));
  Blynk.connect(); 
  ArduinoOTA.setHostname("PMS5003_ESP");   
  ArduinoOTA.begin();    
 //rtc.adjust(DateTime(__DATE__, __TIME__));
  rtc.begin();
  pms.passiveMode();    // Switch to passive mode
  lcd.init();                      // initialize the lcd 
  lcd.backlight();
  //serwo.attach(D8);
  pinMode(przekaznikSerwo, OUTPUT);
  digitalWrite(przekaznikSerwo, HIGH);
  pinMode(pinFan, OUTPUT);
  digitalWrite(pinFan, HIGH);
  sekunda.begin(995);
  minutDwie.begin(120000);//spr. DHT
  sekundPiec.begin(4850);//przeł. one<->two
  sekundTrzydziesci.begin(9998);//po wybudzeniu PMS
  minutDziesiec.begin(600000);//uspienie PMS
  minuta.begin(59987);//went
  sekundDziesiec.begin(9689);//blynk run
}
void loop() {
  ArduinoOTA.handle();
  miganieLED();
  Blynk.run();

switch(menu){
  case ONE:
   one();
   checkTimeAndHumidity();
   if(sekundPiec.available()){
    lcd.clear();
    sekundPiec.restart();
    menu=TWO;
   }
  break;
  case TWO:
   two();
   checkTimeAndHumidity();
   if(sekundPiec.available()){
    lcd.clear();
    sekundPiec.restart();
    menu=ONE;
   }
  break;
  case THREE:
   three();
  break;
  case FOUR:
   four();
  break;
  case FIVE:
   five();
  break;
  case SIX:
   six();
  break;
  case SEVEN:
   seven();
  break;
  case EIGHT:
   eight();
  break;
  case NINE:
   nine();
  break;
  case TEN:
  ten();
  break;
}
}
 
void one(){
  DateTime now = rtc.now();
  lcd.setCursor(0,0);
  lcd.print("      ");
  lcd.print(now.hour(), DEC);
  lcd.print(":");
  if(now.minute()<10){
    lcd.print("0");
  }
  lcd.print(now.minute(), DEC);
  lcd.setCursor(0,1);
  lcd.print("   ");
  if(now.day()<10){
    lcd.print("0");
  }
  lcd.print(now.day(), DEC);
  lcd.print('.');
  if(now.month()<10){
    lcd.print("0");
  }
  lcd.print(now.month(), DEC);
  lcd.print('.');
  lcd.print(now.year(), DEC);
 }
 void two(){
  lcd.setCursor(0,0);
  lcd.print("PM1 ");
  lcd.print(data.PM_AE_UG_1_0);
  lcd.print(" PM2,5 ");
  lcd.print(data.PM_AE_UG_2_5);
  lcd.setCursor(0,1);
  lcd.print("    PM 10  ");
  lcd.print(data.PM_AE_UG_10_0);
 }
 void three(){
  lcd.setCursor(0,0);
  lcd.print("  Wilg. < 70%");
  lcd.setCursor(0,1);
  lcd.print("  Wybudzam PMS");
  pms.wakeUp(); //30 sekund poczekaj
  if(sekundTrzydziesci.available()){
    lcd.clear();
    sekundPiec.restart();
    menu=FOUR;
  }
 }
void four(){
  lcd.setCursor(0,0);
  lcd.print("      PMS");
  lcd.setCursor(0,1);
  lcd.print("wykonuje pomiar");
  pms.requestRead();
  pms.readUntil(data);
  if(sekundPiec.available()){
    Blynk.virtualWrite(35,"   ",data.PM_AE_UG_1_0," ","ug/m3");
    Blynk.virtualWrite(36,"   ",data.PM_AE_UG_2_5," ","ug/m3");
    Blynk.virtualWrite(37,"   ",data.PM_AE_UG_10_0," ","ug/m3");
    Blynk.virtualWrite(38,data.PM_AE_UG_1_0);
    Blynk.virtualWrite(39,data.PM_AE_UG_2_5);
    Blynk.virtualWrite(40,data.PM_AE_UG_10_0);
    lcd.clear();
    sekundPiec.restart();
    menu=FIVE;
  }
 }
 void five(){
  lcd.setCursor(0,0);
  lcd.print("Usypiam czujnik");
  lcd.setCursor(0,1);
  lcd.print("  na 10 minut");
  pms.sleep();
  if(sekundPiec.available()){
    lcd.clear();
    sekundPiec.restart();
    digitalWrite(przekaznikSerwo, LOW);
    serwo.attach(D8);
    menu=SIX;
  }
 }
 void six(){
  lcd.setCursor(0,0);
  lcd.print("Otwieram doplyw");
  lcd.setCursor(0,1);
  lcd.print("   powietrza");
  serwo.write(20);
   if(sekundPiec.available()){
    lcd.clear();
    minuta.restart();
    menu=SEVEN;
  }
 }
 void seven(){
  lcd.setCursor(0,0);
  lcd.print("   Wentylator");
  lcd.setCursor(0,1);
  lcd.print("    wlaczony");
  digitalWrite(pinFan, LOW);
  if(minuta.available()){
    lcd.clear();
     sekundPiec.restart();
    menu=EIGHT;
  }
 }
 void eight(){
  lcd.setCursor(0,0);
  lcd.print("   Wentylator");
  lcd.setCursor(0,1);
  lcd.print("   wylaczony");
  digitalWrite(pinFan, HIGH);
  if(sekundPiec.available()){
    lcd.clear();
     sekundPiec.restart();
     dhtStart=false;
    menu=NINE;
  }
 }
 void nine(){
  lcd.setCursor(0,0);
  lcd.print(" Zamykam doplyw");
  lcd.setCursor(0,1);
  lcd.print("   powietrza");
  serwo.write(160);
  if(dhtStart==false){
    dht11.read(&temperatura, &wilgotnosc, NULL);
   Serial.println(temperatura);
   Serial.println(wilgotnosc);
   dhtStart=true;
  }
  if(sekundPiec.available()){
    lcd.clear();
    sekundPiec.restart();
    digitalWrite(przekaznikSerwo, HIGH); 
    //pinMode(D8,LOW);
    menu=TEN;
  }
 }
 void ten(){
  lcd.setCursor(0,0);
  lcd.print("   Temp.  ");
  lcd.print(temperatura);
  lcd.print(" *C");
  lcd.setCursor(0,1);
  lcd.print("   Wilg.  ");
  lcd.print(wilgotnosc);
  lcd.print(" %RH");
  if(sekundPiec.available()){
    lcd.clear();
    sekundPiec.restart();
    menu=ONE;
  }
 }
 void checkTimeAndHumidity(){
  if(minutDwie.available()){
   dht11.read(&temperatura, &wilgotnosc, NULL);
  Serial.println(temperatura);
  Serial.println(wilgotnosc);
  minutDwie.restart();
  }
  if((minutDziesiec.available()) && (wilgotnosc < 77)){
    lcd.clear();
    sekundTrzydziesci.restart();
    minutDziesiec.restart();
    menu=THREE;
  }
 }
 
void miganieLED(){
  if(sekunda.available()){
   blueLED = !blueLED ;
   if (blueLED == 0) {
    ledNode.off(); //miganie vLED dla kontroli połączenia
   }
     else {
    ledNode.on();
    }
    sekunda.restart();
}
}

Jest funkcja w bibliotece serva ustawiająca pin sterujący tak by tam nie było zasilania?

Edit: po ustawieniu lini sterującej

serwo.write(0);

dioda ledwo, ledwo świeci, ale jednak, jak ją zgasić?

Edit2: dioda prostownicza na lini zasilającej serwo między serwem, a diodą? Czy jednak da się to programowo zrobić??

Edit3: wydaje się, że poradziłem, zamiast funkcji "gaszącej diodę"

digitalWrite(D8, LOW);

użyłem

analogWrite(D8, 0);

bo przecież serwo jest sterowane PWM, więc ok, diodę wygasza, a w następnym obiegu serwo rusza bez problemów. 

Tylko kto mi wytłumaczy dlaczego tak jest,  że jeśli użyję digitala to serwo już nie ruszy pomimo komendy serwo.write()...??

Przecież jak było sterowane PWM serwo, a kilka linijem później wpisałem digitalWrite to ten ostatni zadziałał, a odwrotnie już nie?

Link do komentarza
Share on other sites

No niestety, często tak jest że układy (np elektronika serwa) mają przejście diodowe od wejścia do własnego zasilania. To może być celowe (zabezpieczenie nadnapięciowe) a może przypadkowe (diody w scalaku/bramce wejściowej). Coś takiego nie przeszkadza w normalnej pracy, gdy zasilanie jest obecne i jest zawsze najwyższym potencjałem, ale w przypadku jego braku stany wejść "podbijają" linię zasilania i to widać u Ciebie. Przede wszystkim nie powinno się sterować pinami czegoś, czego zasilanie jest wyłączone. Tylko niewiele scalaków to wytrzymuje i jest "fabrycznie" odpornych na takie traktowanie. Serwo jest przeznaczone do pracy w trudnych warunkach i ma zapewne na wejściu jakieś buforowanie żeby to nie było niszczące, choć po efektach widać, że bardzo to się nie postarali. Na pewno powinieneś zadbać o niewysyłanie impulsów podczas wyłączonego zasilania. O ile pamiętam w bibliotece servo jest też bliźniacza funkcja detach():

https://www.arduino.cc/en/Reference/Servo

Próbowałeś? Sekwencja powinna chyba wyglądać jakoś tak:

1. Włączasz zasilanie serwomechanizmu
2. Czekasz ze 200ms na stabilizację elektroniki
3. servo.attach()
4. serwo.write()
5. Czekasz z 500ms na dojazd do pozycji
6. servo.detach()
7. Wystawiasz zero na pin.
8. Wyłączasz mu zasilanie serwa.

W zależności od typu serwa czasy mogą być inne a wręcz być może trzeba najpierw zacząć wysyłać impulsy a dopiero potem włączyć zasilanie. Tego się z góry nie przewidzi, bo chińczycy pakują tam co popadnie i nie ma reguły na zachowanie serwa w sytuacjach nienormalnych.

  • Lubię! 1
  • Pomogłeś! 1
Link do komentarza
Share on other sites

6 godzin temu, marek1707 napisał:

. Na pewno powinieneś zadbać o niewysyłanie impulsów podczas wyłączonego zasilania

Jednak trochę niżej piszesz :

"wręcz być może trzeba najpierw zacząć wysyłać impulsy a dopiero potem włączyć zasilanie".

Wrócę do domu to posprawdzam, tą funkcję serwo.detach() też...

Link do komentarza
Share on other sites

Z punktu widzenia "czystości elektronicznej" projektu nie powinieneś wysyłać żadnego napięcia po linii sygnałowej do serwa (i nie tylko serwa) w czasie gdy nie ma ono zasilania. Ale z drugiej strony wiemy, że akurat serwa mogą bardzo różnie reagować na stan gdy są zasilane a nie mają impulsów. Mam w moich modelach i pudełkach na rupiecie pewnie z kilkadziesiąt serwomechanizmów i nigdy nie jestem pewien czym zaskoczy mnie kolejne. Zawsze muszę tak projektować zakresy ruchów sterów, by wychylenie serwa nawet do granicy jego działania nie powodowało zerwania bowdena lub zgięcia jakiegoś elementu, bo po podłączeniu akumulatora niektóre odbiorniki RC potrzebują nawet kilku sekund by dosrtoić się do nadajnika i zacząć produkować impulsy. A wtedy jedne serwa stoją spokojnie w pozycji neutralnej a inne szaleją lub wychylają się do swojego punktu oporu. I dlatego piszę, że być może będziesz musiał wysyłać impulsy wcześniej, tuż przed momentem właczenia zasilania by wstająca elektronika serwa od razu widziała sygnał PWM. Nie chodzi mi że dużo wcześniej, to może być prawie jednoczesny start, ale być może kolejność zdarzeń i wielkość opóźnień będzie ważna. Po prostu zrób próbę z tym swoim i napisz jak poszło. Jeśli nie głupieje bez impulsów, to wporzo, możesz zapodawać je kiedykolwiek i będzie dobrze.

  • Lubię! 2
Link do komentarza
Share on other sites

(edytowany)

No i bingo, ja właśnie dlatego mam ustawianie pozycji przed włączeniem, żeby mi nie pokrzywiło cięgien, lub co gorsza nie rozwaliło samo siebie. Jako, że nie mam doświadczenia w serwach, a otwarcie i zamknięcie mam ustawione na 20 i 160 (serwo.write()) to gdybym poslał zasilanie w momencie jak mam ustawione na lini sygnalowej serwo.write(np.10) to bym sobie coś uszkodził... Czyli dobrze zrozumiałem, nie powinno się, ale życie jest życiem;-)

Dobra potestuje trochę i napisze jak to wygląda. Mam te malutkie serwa z kursu arduino, zdaje się SG90, czy jakoś tak, bo naklejki odpadły...

EDIT:

Ok szybki szpil, wywaliłem analogWrite() i wstawiłem serwo.detach(). Działa "identycznie" tzn. dioda gaśnie całkowicie. W opisie funkcji detach jest napisane, jak dobrze rozumiem, że odłącza ona przypisanie serwa do pinów i można z tymi pinami robić coś innego w tym czasie dopóki znowu nie uzyjemy serwo.attach(). Generalnie problem rozwiązany. Dzięki.

Nawiasem mówiąc to OTA jest mega wygodne!!

Da się też OTA, lub coś innego by wgrywać szkic zdalnie,  zrobić na ethernet shieldzie (W5100) i arduino?

Edytowano przez SOYER
Link do komentarza
Share on other sites

Dla SG90 (przynajmniej tych które mam) wystarczy detach() aby serwo się wyłączyło. Ale już np. S90 Redoxa po odłączeniu PWM wariuje...a jakieś inne które mam pamięta ostatnie położenie... tak że na detach() polegać nie można.

 

  • Lubię! 1
Link do komentarza
Share on other sites

(edytowany)

Hej, wydaje sie, że skończyłem projekt:-) Zrobiłem dzisiaj do końca ten moduł odcinający dopływ i wylot powietrza.

DSC_0222.thumb.JPG.dacb537e82e1a88d831258e14d868049.JPGDSC_0224.JPGDSC_0225.thumb.JPG.1da177f1a84992219b65c5ea08e59eab.JPGDSC_0228.thumb.JPG.aa2ede87ff51e8ca8385d780cf6a0bcd.JPG

Krótki filmik z działania, przepraszam za jakość, ale to moja pierwsza obróbka wideo;-):

 

Dziękuję za wszelką pomoc i rady przy budowie i programowaniu:-).

 

 

Edytowano przez SOYER
  • Lubię! 1
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.