Skocz do zawartości

Pomocna odpowiedź

Dobra, ponownie pojawił się problem, którego nie jestem w stanie naprawić. Połączyłem ze sobą Arduino z NodeMCU (bez konwertera poziomów logicznych) i wszystko działało pięknie do pewnego czasu (mogłem postawić serwer i po prostu przesłać dane z Arduino do NodeMCU). Jednakże z niewiadomych mi przyczyn nagle wszystko przestało działać. Chciałem więc wrócić do podstaw i po prostu przesłać jakikolwiek tekst z Arduino do NodeMCU i już nie zadziałało. (Płytka była ustawiana jako Generic 8266 oraz NodeMCU 1.0 z polecenia @Belferek, bo powiem szczerze nie widziałem tej opcji, i na żadnej już mi nie działa nawet proste przesyłanie danych tak jak we wcześniejszym poście). 

Próbowałem zmontować nawet prosty konwerter poziomów logicznych z wykorzystaniem dzielnika napięć do którego łącznie wykorzystałem 6 rezystorów 1kR (po 3 na piny RX i TX) i również nic to nie pomogło. Sprawdziłem napięcia jakie wychodzą z Arduino po przejściu przez dzielnik napięć i dla pinu D6, który idzie do RX NodeMCU daje ok 3.3V, ale dla pinu D5 Arduino po przejściu przez dzielnik daje wartość około 0.12V. Sprawdziłem więc ile V da ten pin bez dzielnika i daje w granicach 4.7V, a D6 daje około 5V (Za żadne skarby nie wiem czemu daje taką niską wartość).  

Link to post
Share on other sites

Udało mi się naprawić. Spróbowałem połączyć Arduino i NodeMCU trochę innym sposobem niż podałem powyżej. Znalazłem poradnik i go wykorzystałem. Dla potomnych. Schemat:

image.thumb.png.b88b9ad94b1efac4bdb442b1aa396557.png

Kod Arduino: 

#include <SoftwareSerial.h>

SoftwareSerial espSerial(5, 6);
String str;
int count = 0;

void setup(){
  Serial.begin(9600);
  espSerial.begin(9600);
  delay(2000);
}
void loop()
{
  count++;
  str = String("coming from arduino: ")+String(count);
  espSerial.write(count);
  delay(1000);
}

Kod NodeMCU:

#include <SoftwareSerial.h>
SoftwareSerial Arduino(D6, D5);

int count;
void setup() {
  Serial.begin(9600);
  Arduino.begin(9600);
}
void loop() { // run over and over
  if (Arduino.available() > 0) {
    count = Arduino.read();
  Serial.println(count);
    
  }
}

PS: Hindusi są dobrzy w te klocki 😅. Większość poradników stworzona przez nich. 

Link to post
Share on other sites
8 godzin temu, Krst0 napisał:

PS: Hindusi są dobrzy w te klocki 😅. Większość poradników stworzona przez nich.

Hindusi są dobrzy w te i inne klocki od dawna, tylko dopiero ostatnio zasypali YT tutorialami 😉 jak przełkniesz angielski akcent, to można znaleźć naprawdę sporo wnikliwych materiałów.

Link to post
Share on other sites
16 minut temu, Belferek napisał:

Przeczytaj ciekawy artykuł: zobacz

Akurat rozumiem o co chodzi z tą konwersją stanów logicznych, jednakże zastanawia mnie multum tutoriali bazujących i pracujących bez tego konwertera. Zamówić go i tak zamówię, żeby było wedle sztuki. 😉

Link to post
Share on other sites

Po pierwsze najgorszym rozwiązaniem jest zastosowanie potencjometru.Potencjometr to taki element w którym szczególnie uwidaczniają się wady rezystorów.Starzenie się elementu jest bardzo szybkie co powoduje zmiany rezystancji.W związku z tym twoja kalibracja jest dobra na dość krótki czas by nie powiedzieć na bardzo krótki czas.Przewożenie skalibrowanego czujnika spowoduje  jego dekalibrację.Po drugie zapoznaj się jakie zjawisko wykorzystuje się w takim czujniku. Na egzaminie ktoś zada z głupia frant pytanie o zjawisko i co wtedy.Jak już będziesz wiedział jakie zjawisko jest wykorzystywane to dowiesz się,że nie tylko te gazy wymienione w fig.3 będą oddziaływać na czujnik.Musisz wiedzieć co mierzy czujnik a mierzy sumę wszystkich gazów będących w powietrzu.Zadaj sobie pytanie jaka będzie wartość odczytu jeśli wilgotność powietrza będzie znacznie wyższa niż 65% albo znacznie niższa.Na tym forum już komuś doradzałem co ma zrobić i wystarczy odnaleźć moje posty w tej sprawie(czujnik MQ135). Do tego masz napisać zapewne program obsługujący czujnik oraz użytkownika.Przy odrobinie szczęścia myślowego(możesz przejść w stan iluminacji) możesz dowiedzieć się na jak niskim poziomie rozwoju jest ziemska cywilizacja. 

Link to post
Share on other sites
1 godzinę temu, szymonw napisał:

Po pierwsze najgorszym rozwiązaniem jest zastosowanie potencjometru.Potencjometr to taki element w którym szczególnie uwidaczniają się wady rezystorów.Starzenie się elementu jest bardzo szybkie co powoduje zmiany rezystancji.W związku z tym twoja kalibracja jest dobra na dość krótki czas by nie powiedzieć na bardzo krótki czas.Przewożenie skalibrowanego czujnika spowoduje  jego dekalibrację.Po drugie zapoznaj się jakie zjawisko wykorzystuje się w takim czujniku. Na egzaminie ktoś zada z głupia frant pytanie o zjawisko i co wtedy.Jak już będziesz wiedział jakie zjawisko jest wykorzystywane to dowiesz się,że nie tylko te gazy wymienione w fig.3 będą oddziaływać na czujnik.Musisz wiedzieć co mierzy czujnik a mierzy sumę wszystkich gazów będących w powietrzu.Zadaj sobie pytanie jaka będzie wartość odczytu jeśli wilgotność powietrza będzie znacznie wyższa niż 65% albo znacznie niższa.Na tym forum już komuś doradzałem co ma zrobić i wystarczy odnaleźć moje posty w tej sprawie(czujnik MQ135). Do tego masz napisać zapewne program obsługujący czujnik oraz użytkownika.Przy odrobinie szczęścia myślowego(możesz przejść w stan iluminacji) możesz dowiedzieć się na jak niskim poziomie rozwoju jest ziemska cywilizacja. 

Jeśli chodzi o rezystor i potencjometr to zapewne masz rację, dlatego zdecydowałem się dodatkowo na zakup konwertera poziomów logicznych. O zjawisko jakie zachodzi to ja wiem na czym to polega, bardzo dużo o tym czytałem, ale mimo wszystko raczej nie zdecyduję na uwzględnianie wilgotności, bo w samej pracy piszę o tym, że projekt ten należy traktować w kategorii ciekawostki i wyników nie należy traktować jako wyrocznię ze względu na reaktywność na inne gazy. Pisałem o tym zresztą w nieco wcześniejszych postach, że wynik dot. stężenia CO może być zakłamany, bo ktoś na czujnik podał przeogromne stężenia gazu z zapalniczki (tak to ja wcześniej 🤡).

Link to post
Share on other sites
(edytowany)

Aktualizacja postępów pracy:

Otrzymałem konwerter poziomów logicznych, wszystko podpiąłem i jeśli chodzi o sczytywanie danych z pms przez konwerter poziomów logicznych do arduino działa to świetnie. Podobnie sprawa ma się jak przesyłam dane z Arduino do NodeMCU z użyciem konwertera, też wszystko działa. Więc oczywistym następstwem było połączenie tego do kupy, czyli PMS daje dane Arduino i ten przekazuje je do NodeMCU. No i nie działa. 

Testowałem różne warianty co może powodować błąd. Doszedłem do wniosku, że PMS nie sczytuje mi danych, gdy mam podłączony NodeMCU, a właściwie, gdy mam utworzony nowy SoftwareSerial dla niego. Wtedy PMS jakby nie chciał działać i nie wiem jak obejść ten problem.

Tutaj znajduje się mój kod:

#include "PMS.h"
#include <SoftwareSerial.h>
#include <Adafruit_Sensor.h> 
#include <Adafruit_BME280.h> 

//D2 - 9     D3 - 7
SoftwareSerial PMSSerial(2,3);
SoftwareSerial ESPSerial(5,6);
PMS pms(PMSSerial);
PMS::DATA data;

//MQ-2 wejście analogowe
#define mq2_pin A0
#define mq135_pin A1
#define mq2_RL 5
#define mq135_RL 1
#define mq2_air_factor 9.8
#define mq135_air_factor 3.7 
#define SEALEVELPRESSURE_HPA (1013.25) 
float mq2_R0 = 0.0;
float mq135_R0 = 0.0;
float co_PPM = 0.0;
float co2_PPM = 0.0;
float temperature = 0.0;
float humidity = 0.0;
float pressure = 0.0;
float PM_10 = 0.0;
float PM_1_0 = 0.0;
float PM_2_5 = 0.0;

struct GasData{
  float x0;
  float f_x0;
  float x1;
  float f_x1;
  float slope;
  float shift;
};
GasData co_data = {200, 5.1, 10000, 1.35};
GasData co2_data = {10, 2.35, 200, 0.8}; 

Adafruit_BME280 bme; 

void CalculateParameters(){
  co_data.slope = log10(co_data.f_x1/co_data.f_x0)/log10(co_data.x1/co_data.x0);
  co2_data.slope = log10(co2_data.f_x1/co2_data.f_x0)/log10(co2_data.x1/co2_data.x0);
  
  co_data.shift = log10(co_data.f_x1) - co_data.slope * log10(co_data.x1);
  co2_data.shift = log10(co2_data.f_x1) - co2_data.slope * log10(co2_data.x1);  
}

float CalibrationMQ(int pin, float RL, float air_factor, int samples, int interval){
  float adc_value = 0.0;
  float RS = 0.0; 
  float RZero = 0.0;

  Serial.println("Obliczanie wartosci R0 czujnika");
  for(int i = 0; i < samples;  i++){
    adc_value = analogRead(pin);
    RS += ((float)RL * (1023.0 - adc_value) / adc_value);
    if(i % (samples/10) == 0)
      Serial.print("=");
    delay(interval);
  }
  Serial.println();
  
  RZero = (RS / samples) / air_factor;
  return RZero;
}

float GetPPMValue(struct GasData data, int pin, float RL, float R0, int samples, int interval){
  float adc_value = 0.0;
  float RS = 0.0;
  float RS_R0_Ratio = 0.0;
  
  for (int i = 0; i < samples; i++){
    adc_value = analogRead(pin);
    RS += ((float)RL * (1023.0 - adc_value) / adc_value);
    delay(interval);
  }
  RS /= samples;
  RS_R0_Ratio = RS / R0;
  float PPM_value_in_log = (log10(RS_R0_Ratio) - data.shift) / data.slope;
  float PPM_value = pow(10, PPM_value_in_log);
  return PPM_value;
}

void setup()
{
  Serial.begin(9600);
  PMSSerial.begin(9600);
  ESPSerial.begin(115200);
  //Obliczanie parametrów a oraz b dla krzywej funkcji z wykresu dla CO.
  CalculateParameters();
  Serial.println("Kalibracja mq-2");
  mq2_R0 = 5; //CalibrationMQ(mq2_pin, mq2_RL, mq2_air_factor, 1, 500);
  Serial.println("Skalibrowano mq-2");
  Serial.println("\nKalibracja mq-135");
  mq135_R0 = 5; //CalibrationMQ(mq135_pin, mq135_RL, mq135_air_factor, 1, 500);
  Serial.println("Skalibrowano mq-135");
}

void loop()
{
  if (pms.read(data))
  {
    PM_1_0 = data.PM_AE_UG_1_0;
    PM_2_5 = data.PM_AE_UG_2_5;
    PM_10 = data.PM_AE_UG_10_0;
    
    Serial.print("PM 1.0 (ug/m3): "); Serial.println(data.PM_AE_UG_1_0);
    /*
    co_PPM = GetPPMValue(co_data, mq2_pin, mq2_RL, mq2_R0, 5, 50);
    co2_PPM = GetPPMValue(co2_data, mq135_pin, mq135_RL, mq135_R0, 50, 50);
    temperature = bme.readTemperature();
    pressure = bme.readPressure() / 100.0F;
    humidity = bme.readHumidity();
    
    Serial.print("CO: "); Serial.print(co_PPM); Serial.println(" PPM"); 
    Serial.print("CO2: "); Serial.print(co2_PPM); Serial.println(" PPM");
    Serial.print("Temperature: "); Serial.print(temperature); Serial.println(" *C");
    Serial.print("Pressure: "); Serial.print(pressure); Serial.println(" hPa");
    Serial.print("Humidity: "); Serial.print(humidity); Serial.println(" %");
    Serial.print("PM 1.0 (ug/m3): "); Serial.println(data.PM_AE_UG_1_0);
    Serial.print("PM 2.5 (ug/m3): "); Serial.println(data.PM_AE_UG_2_5);
    Serial.print("PM 10.0 (ug/m3): "); Serial.println(data.PM_AE_UG_10_0);
    Serial.println();*/
  }
}

Oczywiście te wszystkie funkcje i definicje na początku programu nie są ważne. Ważne są nastepujące elementy, dlatego tutaj na dole będzie skrócony kod, który może komuś ułatwi odczyt:

#include "PMS.h"
#include <SoftwareSerial.h>

SoftwareSerial PMSSerial(2,3);
SoftwareSerial ESPSerial(5,6);

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

float PM_10 = 0.0;
float PM_1_0 = 0.0;
float PM_2_5 = 0.0;

void setup()
{
  Serial.begin(9600);
  PMSSerial.begin(9600);
  ESPSerial.begin(115200);
}

void loop()
{
  if (pms.read(data))
  {
    PM_1_0 = data.PM_AE_UG_1_0;
    PM_2_5 = data.PM_AE_UG_2_5;
    PM_10 = data.PM_AE_UG_10_0;
    
    Serial.print("PM 1.0 (ug/m3): "); Serial.println(data.PM_AE_UG_1_0);
  }
}

Oczywiście jak tutaj widzicie staram się wyświetlić na Serial Monitorze Arduino, nie próbowałem przesyłać dalej, bo nawet to mi nie działa przy podłączonych do arduino dwóch modułach jedocześnie. Jakby ktoś był w stanie pomóc byłbym bardzo wdzięczny. 

Edytowano przez Krst0
Link to post
Share on other sites
(edytowany)

Dobra, już wszystko rozumiem, ale nie umiem tego wytłumaczyć i faktycznie to nie może działać. Arduino jako ostatnie połączył sobie ESP w tym przykładzie i dlatego nie nasłuchiwał PMS. 

EDIT:

Znalazłem chyba rozwiązanie. Udało mi się dotrzeć do informacji, że można ręcznie zmieniać na jakim porcie nasłuchuje Arduino. Wystarczy tylko podać mu odpowiedni serial i wywołać na nim funkcję listen(). Trochę ciśnienie mi zeszło. Ufff. Jak się mylę to może mnie ktoś poprawić. 

Edytowano przez Krst0
Link to post
Share on other sites
(edytowany)

No i za szybko się ucieszyłem. Niestety rozwiązanie to nie chce działać w moim przypadku. Czytałem w poradniku, że działa to na Arduino Mega, ale patrząc w dokumentacji nic o tym nie było wspomniane. Może ma ktoś pomysł jak rozwiązać ten problem? Próbowałem skorzystać z biblioteki NewSoftSerial, która umożliwia przełączanie nasłuchiwania portów dla Arduino Uno, ale przy próbie kompilacji pojawia się błąd wewnątrz biblioteki (z tego co rozumiem błąd konstruktora). 

Szukam sposobu, żeby może za pomocą I2C połączyć albo SPI, ale nie wiem na ile to rozwiąże mój problem. 

Edytowano przez Krst0
Link to post
Share on other sites

Czy odbierasz coś z ESP czy tylko nadajesz? Czy nadajesz coś z czujnika czy tylko odbierasz?

Jeśli tak a prędkości się zgadzają (tzn. możesz gadać z ESP na 9600), możesz podpiąć wszystko pod jeden software serial.

Jeśli prędkości się nie zgadzają, a do ESP tylko nadajesz, poszukaj w googlu "software serial tx only", może to będzie rozwiązanie.

Wracając do konwertera poziomów: według producenta ESP8266 powinien wytrzymać podłączenie do logiki 5V (dlatego działa bez konwertera), ale nie jest to wskazane. I tu uwaga: nie dotyczy to ESP32!

Link to post
Share on other sites
Cytat

Czy odbierasz coś z ESP czy tylko nadajesz? Czy nadajesz coś z czujnika czy tylko odbierasz?

Tylko wysyłam dane do ESP i on ma je wyświetlić na serwerze, także pewnie to będzie rozwiązanie

Cytat

Wracając do konwertera poziomów: według producenta ESP8266 powinien wytrzymać podłączenie do logiki 5V (dlatego działa bez konwertera), ale nie jest to wskazane.

Dokładnie, przeczytałem, że ma zabezpieczenie antyprzepięciowe (nie wiem jak to nazwać 😅). Dowiedziałem się, że pozwala to się nie zepsuć NodeMCU jak da się większe napięcie niż 3.3 V. 

Link to post
Share on other sites
(edytowany)

Ostatnio nie miałem czasu wziąć się za prackę, więc dlatego opóźnienie. Natknąłem się na kolejny problem.

Jestem w stanie na Arduino Uno sczytać wszystkie wartości czujników i połączyć się z NodeMCU. Ba, jestem w stanie nawet wysłać do NodeMCU pojedynczą wartość zmiennej. Chciałem więc przesłać do NodeMCU więcej wartości, ale nie wiem jak.

Próbowałem za pomocą ArduinoJson wysłać jakieś dane i je odebrać na NodeMCU i o ile z wysyłaniem danych za pomocą JSONa nie jest trudne, to nie mam kompletnie pojęcia w jaki sposób powinien wówczas wyglądać kod odbioru tych danych. Dodam, że jechałem nawet według poradników podanych w internecie jak korzystać z tej biblioteki i w moim przypadku to nie działa.

Próbowałem również wszystkie dane wepnąć w strukturę i ją przesłać, ale tu również podczas odbierania danych napotykam na problemy.

Miałby ktoś pomysł w jaki sposób można przesłać kilka zmiennych między Arduino i NodeMCU? (Nie podoba mi się rozwiąznanie, gdzie przesyłałbym to za pomocą char[] z danymi rozdzielonymi za pomocą ",". Chyba, że innej metody nie ma).

Edit:

Chyba, bo kilku dniach szukania informacji w końcu wpadł błysk do mojej głowy i zrozumiałem jak powinienem to zrobić z użyciem ArduinoJSON. Na platformie Arduino serializuję dane i tworzę z niego char[] wyglądający brzydko. Następnie ten ciąg znaków wysyłam za pomocą Serial do NodeMCU i tam za pomocą deserializacji rozbijam ten ciąg znaków.

Wcześniej myślałem, że wysyłam po prostu taki json, a tak naprawdę wysyłam stringa, który deserializuję. Jakbym zgubił jeden krok.

Zawsze tak mam, że jak już tracę nadzieję i wiarę we własne umiejętności rozumienia i szukania to piszę o pomoc po czym sam na to wpadam. Dzisiaj po pracy testuję i powiem jak wygląda sytuacja.

Edytowano przez Krst0
Link to post
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

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.