Skocz do zawartości

Nodemcu v3 - zapis danych z karty sd do zmiennej.


Xele

Pomocna odpowiedź

Witam

Zapisuję pomiary na karcie sd w takim formacie:

2020-12-06 00:48:19|24.26|38.08|1014.37

Dane są oddzielone znakiem "|"  i potrzebuję np. zmienna1 = "2020-12-06 00:48:19"      zmienna2 = 24.26  itd.

Chciałbym te dane przekonwertować do zmiennych a następnie wysłać na serwer php żeby zapisać to do bazy sql. Problem jest taki, że męczę się z tym od kilku dni i nie jestem w stanie zapisać nic. Potrafię tylko odczytywać pojedynczo znaki. Więc moja wiedza jest za mała i nie wiem dokładnie z czego się nauczyć. Jeśli ktoś poda mi jakieś przykłady, kurs albo cokolwiek co mi pomoże to będę bardzo wdzięczny.

Próbowałem różnych metod z char itd. i często mi się esp wysypuje i resetuje. Dodam jeszcze, że maksymalnie takich linijek w pliku mogę mieć z 500 i każdą linijkę muszę wysłać na serwer. Może powinienem wysłać plik na serwer php i w php obrobić dane, ale też nie wiem jak to zrobić. Będę dalej kombinować, w każdym bądź razie dzięki za jakąkolwiek pomoc.

Link do komentarza
Share on other sites

3 godziny temu, Xele napisał:

Próbowałem różnych metod z char itd. i często mi się esp wysypuje i resetuje. Dodam jeszcze, że maksymalnie takich linijek w pliku mogę mieć z 500 i każdą linijkę muszę wysłać na serwer. Może powinienem wysłać plik na serwer php i w php obrobić dane, ale też nie wiem jak to zrobić. Będę dalej kombinować, w każdym bądź razie dzięki za jakąkolwiek pomoc.

@Xele najprostszą metodą do implementacji będzie pewnie wysłanie tych danych za pomocą metody GET. Czy ten ciąg, który chcesz dzielić na podstawie "|" będzie miał zawsze tyle samo zmiennych czy może on być różny?

Link do komentarza
Share on other sites

@Treker tak każda linijka danych będzie wyglądać tak samo tylko inne wartości. Może każdą wartość zapisywać do innego pliku? 

Rozpiszę bardziej jak to wygląda: ESP po podłączeniu do wifi co 4 minuty pobiera czas z serwera NTP, następnie dane z czujnika i wysyła dane na stronę php, gdzie sobie zapisuje to do bazy. Tylko data i czas zapisują się automatycznie w bazie  jako MySQL TIMESTAMP. Po wyłączeniu wifi, ESP przechodzi w tryb "offline" gdzie zapisuje dane na kartę sd, czas bierze z RTC, który aktualizuje się przy podłączeniu do wifi ze względu na gubienie sekund ileś tam na rok. 

Jak działa wifi to dane wysyłam za pomocą tego kodu:

HTTPClient http;

      http.begin(serverName);
      http.addHeader("Content-Type", "application/x-www-form-urlencoded");

      String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName + "&temp_value=" + String(bme.readTemperature())
                               + "&hum_value=" + String(bme.readHumidity()) + "&pres_value=" + String(bme.readPressure() / 100.0F + 9) + "&rain_drop=" + String(rain_read()) + "";

      int httpResponseCode = http.POST(httpRequestData);

Po utracie wifi, powiedzmy na 24h będę mieć na karcie sd około 360 linijek danych: w takim formacie 2020-12-06 00:48:19|24.26|38.08|1014.37. Nie wiem czy to odpowiedni format danych. Chciałbym te dane wyodrębnić i wysłać w ten sam sposób co kod wyżej tylko zastępując wartości z sensorów wyodrębnionymi danymi z SD w zmiennych.

Na początku myślałem, że wyślę ten plik na stronę php i tam zapiszę do tablicy i dalej już bym sobie z tym poradził, ale też mam problem jak to zrobić. Potrzebuję rady jak właściwie to przesłać, czego użyć. Dodam jeszcze, że na bieżąco się uczę od zera i przed tym projektem mało co umiałem.  Dzięki 

Link do komentarza
Share on other sites

A jak odczytujesz te dane z karty? W języku C jest dużo funkcji do przetwarzania łańcuchów, a w Arduino IDE masz dostępną powszechnie krytykowaną (ale działającą) klasę String z jej metodami np. indexOf(). Metoda ta może "przeszukać" obiekt typu Sting w poszukiwaniu np. znaku '|'. Znając jego pozycję (index) możesz wybrać "substring" itd.

https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/indexof/

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

@Belferek 

Cytat

A jak odczytujesz te dane z karty?

Właśnie to największy problem nie umiem jeszcze tego odczytać. Jak już odczytam i będę mieć dane w zmiennych to wysłanie powinno być proste.

Cytat

W języku C jest dużo funkcji do przetwarzania łańcuchów, a w Arduino IDE masz dostępną powszechnie krytykowaną (ale działającą) klasę String z jej metodami np. indexOf(). Metoda ta może "przeszukać" obiekt typu Sting w poszukiwaniu np. znaku '|'. Znając jego pozycję (index) możesz wybrać "substring" itd.

https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/indexof/

Możliwe, że to jest to czego potrzebuję, sprawdzę to jak tylko będę mieć czas. Proszę o cierpliwość bo czasu mam bardzo mało i może mi to zając kilka dni. Dzięki za odpowiedzi. 

Link do komentarza
Share on other sites

1 godzinę temu, Belferek napisał:

powszechnie krytykowaną (ale działającą) klasę String

To nie klasa String jest krytykowana, a 90% sposobów jej użycia bez zapoznania się z pewnymi niebezpieczeństwami stosowania tej klasy.

A jeśli już jesteśmy przy krytykowanych - jest taka (już bardzo powszechnie krytykowana, tym niemniej działająca) funkcja strtok (ew. strtok_r), specjalnie stworzona do podziału łańcucha znaków na części.

Link do komentarza
Share on other sites

Udało mi się sporo ogarnąć, ale mam teraz pewien problem i nie mogę znaleźć przyczyny.

Zacznę od początku.


void setup () {

read_data();
change_data_and_send();
}

void read_data()
{
  myFile = SD.open("pomiary.txt");
  if (myFile)
  {
    while (myFile.available())
    {
      char inChar = myFile.read();  //get a character
      if (inChar == '\n') //if it is a newline
      {
        recordNum++;
        charNum = 0;  //start again at the beginning of the array record
        strcpy(parameterArray[index2], aRecord);
        index2++;
      }
      else
      {
        aRecord[charNum] = inChar;  //add character to record
        charNum++;  //increment character index
        aRecord[charNum] = '\0';  //terminate the record
      }
    }
    myFile.close();
  }
}

void change_data_and_send()
{
  for (int index = 0; index < NUMBER_OF_RECORDS; index++)
  {
    String wiersz = String(parameterArray[index]);
    String data = getValue(wiersz, '|', 0);
    String temp = getValue(wiersz, '|', 1);
    String hum = getValue(wiersz, '|', 2);
    String pres = getValue(wiersz, '|', 3);
    String rain = getValue(wiersz, '|', 4);

 HTTPClient http;
    http.begin(serverName);

    http.addHeader("Content-Type", "application/x-www-form-urlencoded");
    // Prepare your HTTP POST request data
    String httpRequestData = "api_key3=" + apiKeyValue3 + "&sensor=" + sensorName + "&temp_value=" + String(temp) + "&hum_value=" + String(hum) + "&pres_value=" + String(pres) + "&rain_drop=" + String(rain) + "&reading_time=" + String(data) + "";

    int httpResponseCode = http.POST(httpRequestData);
    if (httpResponseCode > 0) {
      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
    }
    else {
      Serial.print("Error code: ");
      Serial.println(httpResponseCode);
    }
    // Free resources
    http.end();
  }
}



String getValue(String data, char separator, int index)
{
  int found = 0;
  int strIndex[] = {0, -1};
  int maxIndex = data.length() - 1;

  for (int i = 0; i <= maxIndex && found <= index; i++) {
    if (data.charAt(i) == separator || i == maxIndex) {
      found++;
      strIndex[0] = strIndex[1] + 1;
      strIndex[1] = (i == maxIndex) ? i + 1 : i;
    }
  }

  return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}

wkleiłem część kodu i opiszę mniej więcej o co chodzi, większość wziąłem z neta.

1. read_data()  - odczytuje znaki z pliku sd i zapisuje do tablicy, póki co testuje na 5 rekordach.

2. change_data_and_send() - wyciąga z rekordów wartości, zapisuje do zmiennych w formacie string i wysyła je na serwer php.

3. getValue() - wziąłem z neta i ładnie wyciąga wartości, które są oddzielone jakimś znakiem u mnie jest to znak "|".

Problem z odczytem danych z karty sd i zapisanie ich do zmiennych został rozwiązany, lecz przy wysyłaniu danych na stronę dostaje error = httpResposneCode error -21. Poczytałem, że jest to błąd:

411 Length Required

The request did not specify the length of its content, which is required by the requested resource.

Nie wiem jak go rozwiązać, będę szukać dalej rozwiązania, możliwe że robię jakiś prosty błąd. 

Link do komentarza
Share on other sites

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.