Niby tak ale jak np. zaczynam od testu funkcji potencjometru to i tak na monitorze portu nie mam żadnych danych pokazanych (mimo iż ta funkcja na 100% działa odpowiednio) więc nie wiem jak ja mam testować te funkcję po kolei :)
A baud
masz ten sam ustawiony w komputerku co w konsoli w IDE? I czy w ogóle ustaliłeś go w funkcji setup
za pomocą Serial.begin
? To akurat bardzo ważne.
Tak, to wszystko zrobiłem+ w monitorze portu szeregowego ustawiłem taką samą wartość :)
A Twój poprzedni kod po wrzuceniu na komputerek działa prawidłowo? Jeżeli tak, to czy jeśli dodasz do tego starego kodu instrukcje Serial.print
to w do konsoli trafiają prawidłowe dane?
Tak , ten kod bazowy - bez dodawania histerezy - działa jak należy :) Lecz w przypadku gdy również próbuje wyświetlić dane w monitorze to program przestaje działać . Więc sprawa wygląda tak że bazowy kod działa ale wyświetlanie na monitorze nie , kod z histerezą w ogóle nie działa i wyświetlanie na monitorze też nie :D
Szukaj więc informacji na temat tego, co może powodować problem podczas przesyłania danych do konsoli. Na pewno już niejeden miał ten sam problem.
Tzn zwykły serial.print(" coś tam") działa poprawnie - tu chodzi o te zmienne. Więc nawet ciężko powiedzieć na jaki temat szukać informacji.
Coś nam ciężko idzie ta dyskusja… ;)
Jeśli Serial.print
działa prawidłowo i wyrzuca w konsoli prawidłowe dane, to z urządzeniem i samą transmisją danych wszystko jest w porządku. To jednocześnie oznacza, że nowy kod jest błędny i wcale nie wykonuje się tak jak tego oczekujesz. Jeśli dane żadnych zmiennych nie są wyświetlane w konsoli, to instrukcje Serial.print
w ogóle nie zostają wykonane.
Dlatego zasugerowałem Ci okrojenie nowego kodu do minimum, naprzemienne wrzucanie go do urządzenia, testowanie, dodawanie kolejnej funkcji, wrzucanie go do komputerka, testowanie i tak w kółko, aż znajdziesz problematyczną funkcję. Szycbiej byłoby ten program debuggować, ale na ten temat nie mam (jeszcze) wiedzy.
Jeżeli chodzi o debuggowanie to potrzebny jest dodatkowy element w tym celu więc raczej odpada :D dobrze, tak zrobię - po kolei będę wklepywał funkcję do momentu aż program przestanie działać i wtedy będzie wiadomo z którą funkcją jest problem :) dam znać w najbliższym czasie bo obecnie to porządku wigilijne itd :D postaram się jeszcze dziś testować :D
Z tego co zauważyłem problem zaczyna się od tej funkcji :
int getNewState()
{
int value = potentiometerMeasurement();
int stateXLeftMin = humidity - sizeRangeB - sizeRangeX;
int stateXLeftMax = humidity - sizeRangeB;
int stateXRightMin = humidity + sizeRangeB;
int stateXRightMax = humidity + sizeRangeB + sizeRangeX;
if (value >= stateXLeftMin && value <= stateXLeftMax)
return stateX;
if (value >= stateXRightMin && value <= stateXRightMax)
return stateX;
if (value < stateXLeftMin)
return stateA;
if (value > stateXRightMax)
return stateC;
return stateB;
}
W takim razie wyświetl w konsoli wartości wszystkich zmiennych lokalnych i wartość stanu jaki zwraca.
Ale w konsoli te zmienne nie wyświetlają się ale po dodaniu tej funckji program " siada" ;)
PS. Spróbuję napisać post na forum dotyczącym konkretnie Arduino - może ktoś tam "wpadnie" na pomysł co jest nie tak :D
Sprawdziłem wszystkie obliczenia związane z wyznaczaniem bieżącego stanu i jego zmiany – ostatecznie potwierdzam ich poprawność. Do tego celu napisałem sobie prostą aplikację okienkową z dwoma suwakami – jeden imituje czujnik wilgotności, a drugi imituje położenie potencjometru.
Tego małego bufora cyklicznego do przechowywania pięciu ostatnich odczytów nie implementowałem, bo jego istnienie nie wpływa na ostateczne działanie programu (nie ma on związku z obecnym problemem).
Stan ”urządzenia” prawidłowo zmienia się zarówno podczas zmiany wartości wilgotności (górny suwak aka czujnik), jak i podczas zmiany wartości środka zakresu stanu B
(dolny suwak aka potencjometr).
Tak więc jeśli Twój program nie działa prawidłowo, to musiałeś w drodze przenoszenia i spolszczania mojego kodu popełnić gdzieś błąd. Do załączników dorzucam aplikację testową wraz ze źródłami – pobaw się i zobacz jak to powinno działać.
Twoja funkcja getNewState
powinna posiadać mniej więcej taki kształt:
int getNewState()
{
/* tu pobieramy bieżące odczyty */
int humidity = // tu wpisz zmapowaną wartość wilgotności
int potentiometer = // tu wpisz zmapowane położenie potencjometru
/* tu wyznaczamy wartości przedziałów na podstawie wskazania potencjometru */
int stateXLeftMin = potentiometer - sizeRangeB - sizeRangeX;
int stateXLeftMax = potentiometer - sizeRangeB;
int stateXRightMin = potentiometer + sizeRangeB;
int stateXRightMax = potentiometer + sizeRangeB + sizeRangeX;
/* tu porówujemy wartość wilgotności z ustalonymi zakresami stanów i histerezy */
if (humidity >= stateXLeftMin && humidity <= stateXLeftMax) return stateX;
if (humidity >= stateXRightMin && humidity <= stateXRightMax) return stateX;
if (humidity < stateXLeftMin) return stateA;
if (humidity > stateXRightMax) return stateC;
return stateB;
}
Twój obecny kod zawsze utrzymuje włączony stan B
, bez względu na położenie potencjometru i wartość wilgotności.
Dziękuję Ci furious za wszelką pomoc i czas jaki poświęciłeś na koszt tego tematu :) naprawdę jesteś człowiek wielki :) co do działania - raz się program wgrywa i częściowo działa a raz nie , rozmuje że może być problem z płytką jednak będę próbował do skutku zmieniając m.in. kolejność funkcji itd :) na PW wyśle Ci informacje o ewentualnym powodzeniu całego programu - na ten moment jeszcze raz baardzo dziękuję :)
Pamiętaj, że jak już będziesz po kolei dodawał nowe funkcje do programu, to wartość wilgotności należy porównywać z zakresami obliczonymi na podstawie położenia potencjometru. Czyli tak jak pokazałem w poprzednim poście. I pamiętaj też, że do zmiennej humidity
w funkcji getNewState
, czyli tej:
int getNewState()
{
/* tu pobieramy bieżące odczyty */
int humidity = // tu wpisz zmapowaną wartość wilgotności
musisz wpisywać średnią wilgotność, bo używasz bufora cyklicznego do zapamiętywania pięciu ostatnich odczytów.
W razie większych problemów z działaniem kodu, wywal go i napisz wszystko od nowa – tym razem powoli i spokojnie, dbając o czytelność, formatowanie i ładny podział na małe funkcje. Cały program nie jest duży, więc w razie czego napisanie go jeszcze raz nie potrwa zbyt długo.
Powodzenia w takim razie. ;)
To znaczy wilgotność nie jest liczona średnia tylko wartość z potencjometru :D chyba literówkę tam zrobiłeś pisząc, że wilgotność jest liczona jako średnia :D
Skoro tak twierdzisz to pewnie nastąpiła pomyłka. ;)
Chodzi mi o średnią wartość wyznaczoną na podstawie pięciu poprzednich odczytów, co realizowałeś za pomocą kodu podanego w tym poście. Problem w tym, że sam mianem „wilgotności” określałem odczyt z czujnika, a nie pozycję potencjometru (ten nazywałem po prostu potencjometrem lub środkiem stanu B
).
Skoro tak, to nie widzę powodu, aby liczyć średnią z kilku odczytów potencjometru. To przecież nie ma sensu, bo nie kręcisz nim jak kierownicą w samochodzie. IMO w celu zapobieżenia świrowaniu urządzenia powinieneś przechowywać wartości kilku poptrzednich odczytów z czujnika wilgotności, bo ten faktycznie może zwracać wartości szybko zmieniające się w czasie. Ten problem można zlikwidować właśnie za pomocą uśredniania wartości kilku poprzednich pomiarów.
Dobrze , mianem wilgotności jest określana wartość czujnika , natomiast średnia jest liczona z "pomiarów" potencjometrem ponieważ zapobiega to nadmiernym "skokom" wartości potencjometru wyświetlanej na wyświetlaczu ;) a jeśli chodzi o wartości zwracane przez czujnik to nie mają one " dużego" skoku - wzrastaja/maleją stopniowo ;)
No nie mów, że jak kręcisz potencjometrem to wartość na wyświetlaczu wariuje, zamiast rosnąć/maleć płynnie. :/
To znaczy w sensie wartość już ustalona np 75% skacze na poziomie 74-75% i w tym celu została zastosowana ta tablica :D
Meh… to do takich ”skoków” Twoja tablica nie jest potrzebna, bo nie daje żadnych korzyści.
Miałoby to sens gdybyś operował na liczbach zmiennoprzecinkowych, ale w przypadku tego projektu, wyliczona średnia jest zawsze zaokrąglana/docinana do int
a. Wywal tę tablicę – szkoda brudzić kod zbędnymi danymi i funkcjami.
Ale nie mogą być takie skoki bo mi się styki przekaźnika "popalą" dlatego musi być uśrednienie
Po to właśnie dodajesz do kodu strefy histerezy, aby przekaźnik nie załączał obwodu i go rozłączał, gdy wejściowa wartość będzie oscylować wokół tej granicznej. Zobacz na moją testową aplikację – nieważne czy zmienia się wartość wilgotności z czujnika (górny suwak), czy pozycja potencjometru (dolny suwak), strefy histerezy wykluczają tak szybkie przełączanie stanów urządzenia.
Jeśli będziesz kręcił potencjometrem jak oszalały to ani strefy histerezy, ani nawet uśrednianie pomiarów w niczym nie pomoże. Przy czym strefa histerezy o wielkości 2
jest praktycznie bezużyteczna i powinna być większa. Bo im większa, tym bardziej urządzenie będzie odporne na wahania pomiarów.