Wpis z mikrobloga

Mireczki, mam problem, którego nie mogę za nic rozwiązać.
Na arduino składam system, którego jedną z funkcjonalności ma być odczyt temperatury z czujnika (na razie DHT11) i wyświetlenie na wyświetlaczu.
Wywołuję odczyt, wrzucam wynik do zmiennej >temperatura< typu float, później dane zawarte w tej zmiennej wyświetlam na wyświetlaczu. Wszystko działa.
Problem pojawia się kiedy chcę, żeby w przypadku błędu wyświetlić "err" zamiast danych z czujnika. W tym celu po odczycie dałem ifa, który sprawdza, czy w zmiennej >temperatura< jest liczba i jeśli jest, nic nie robi, a jeśli nie, ma zamienić tą zmienną na String i wpisać do niej tekst "err". To nie chce działać i problem jest na pewno przy operacji zamiany tej zmiennej, bo w ifa wykrywającego liczbę wrzuciłem linijkę, która ma wyświetlić "błąd" na terminalu i rzeczywiście wyświetla (więc dobrze wykrywa liczbę), ale zamiast wrzucić do zmiennej >temperatura< tekst "err", zostaje tam "nan" i tak też pokazuje wyświetlacz.
Macie jakiś pomysł? Jak byście zrealizowali zamianę float na string i wrzucenie do niej tekstu? Ja w żaden sposób nie mogę sobie poradzić. Załączam kawałek programu.

float wilgotnosc = dht.readHumidity();
float temperatura = dht.readTemperature();
if (isnan(temperatura) & isnan(wilgotnosc))
{
Serial.println("blad");
String(temperatura) = "err";
String(wilgotnosc) = "err";
}

#arduino #programowanie #majsterkowanie #elektronika
  • 23
@dktr:

void loop() {
int jasnosc=70;
int jasnoscpwm=255;
jasnoscpwm = map(jasnosc,0,100,255,0);
analogWrite (bcl,jasnoscpwm);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(BLACK);


float wilgotnosc = dht.readHumidity();
float temperatura = dht.readTemperature();
if (isnan(temperatura) & isnan(wilgotnosc))
{
Serial.println("blad");
String(temperatura) = "err";
String(wilgotnosc) = "err";
}

display.setCursor(1,1);
display.print("temperatura i wilgotnosc");
display.setCursor(5,20);
display.print("Temp: ");
display.setCursor(34,20);
display.print(temperatura);
display.print((char)247);
display.print("C");
display.setCursor(5,30);
display.print("Wilg: ");
display.setCursor(34,30);
display.print(wilgotnosc);
display.print("%");
display.setCursor(6,40);
display.print("Jasnosc: ");
display.setCursor(54,40);
display.print(jasnosc);
display.print("%");
display.display();

Serial.print("wilgotnosc-");
Serial.print(wilgotnosc);
Serial.print("%RH | ");
Serial.print("temperatura-");
Serial.print(temperatura);
Serial.println("*C");
@keton22: Czyli muszę to zrobić przez samym wyświetlaniem, żeby po wykryciu błedu napisał err zamiast wyświetlać zmienną?
Wolałem operować na zmiennych, wydaje mi się to bardziej optymalnym, przejrzystym i ułatwiającym rozbudowę rozwiązaniem.
@pawel1410: float jest zmienną która przechowa wyłącznie liczbę zmiennoprzecinkową. Zmienna mają typy, typy są raz na zawsze. Kombinowanie z przetypowywaniem w locie zwykle jest znakiem kiepskiego pomysłu.
@pawel1410: kombinujesz jakby arduino było inteligentne...
1. Nie używaj float (!) na 8bit arduino. To tak jakbyś używał Nvidia Cuda na programatorze od pralki...
2. Jak dokonujesz pomiaru, i wychodzi bzdrura - to ustawiaj w zmiennej temperatura jakąś bzdurną wartość, np -200'C, wtedy łatwo to wyłowić ifem (że temperatura jest spoza zakresu) i wyświetlić ERR
@pawel1410: najpierw rób odczyt, potem go weryfikuj, a na końcu wyświetlaj. Skoro to wyświetlacz lcd alfanumeryczny zdefiniuj dwie zmiennie string np lcdline1, lcd-line2 i na tym operuj w ifach np lcdline1="Temperatura"+String(temp)+chr(244)+"C";
@pawel1410: po prostu nie ma możliwości wpisania do zmiennej temperatura tekstu "err" bo przyjmuje tylko liczby.
if(isnan(temperatura) {
display.print("err");
} else {
display.print(temperatura);
}
@hrumque: Mogę wrzucić wynik pomiaru w int, tylko wtedy przy błędzie dostaję 0, które jest w zakresie pomiarowym. Mógłbym zmienić bibliotekę na taką, która da mi logiczne potwierdzenie poprawności odczytu danych. Tylko dalej nie rozwiązuje to problemu wyświetlania danych ze zmiennej.
Chciałym uniknąć zrobienia w miejscu wyświetlania czegos takiego

if (mam dobry odczyt)

{
wyswietl wartosc z temperatura
}

else
{
wyswietl napis "error"
}
@pawel1410: możesz jeszcze od razu po pomiarze ustawić sobie jakąś flagę czy był dobry odczyt. Albo od razu po pomiarze przerobić temperaturę na tekst - albo String(temperatura) albo "err" a potem już operować tylko zmienną tekstową.
@keton22: @dktr: @hrumque: @atehxx: @Portier-Harry_Portier:

Dziękuję kochani, działa tak, jak chciałem. Zrobiłem tak:

float wilgotnosc = dht.readHumidity();
float temperatura = dht.readTemperature();
String stringtemperatura = String(temperatura);
String stringwilgotnosc = String(wilgotnosc);

if (isnan(temperatura) && isnan(wilgotnosc))
{
Serial.println("blad");
stringtemperatura = "err";
stringwilgotnosc = "err";
}

I na wyświetlaczu wyświetlam zmienną stringtemperatura.
Może nie jest to najoptymalniejsze rozwiązanie pod kątem pamięci, ale działa. danych z czujnika niestety nie chce wrzucić bezpośrednio
@pawel1410:
http://mikrokontrolery.blogspot.com/2011/02/kurs-jezyka-c-spis-tresci.html

http://mikrokontrolery.blogspot.com/2011/02/kurs-jezyka-c-rzutowanie-promocja-typow.html

a to String(temperatura) to żadna konwersja, tylko stworzenie obiektu za pomocą odpowiedniego konstruktora.
no można powiedzieć że jest konwersja w środku, ale to co innego niż typowa konwersja typów czy rzutowanie.
https://www.arduino.cc/reference/en/language/variables/data-types/stringobject/
Zawsze konwersja będzie tak wyglądała i zawsze, jak chcę przekonwertować jakąś zmienną na inny typ, to muszę stworzyć nową, nie da się tego zrobić bezpośrednio?


@pawel1410: W języku C (w którym programujesz swoje arduino) tak.
zmienna liczbowa przechowuje tylko liczby (wartość, a nie cyferki żeby było jasne).
int a = 123;
oraz
char b[3] = "123";
są zupełnie inaczej zapisane w pamięci i nie da się między nimi skakać dowolnie.

Nie
@atehxx: @Tymian: Dzięki za naprowadzenie, poczytam sobie głębiej na ten temat.

Czy jeżeli chciałbym dostać temperaturę z dokładnością do jedengo miejsca po przecinku (22,3*C), jestem w stanie zrobić to nie korzystająć z float?