Temperatura i LCD
W ofercie Nettigo dziś pojawił się zestaw LCD do Arduino – jest to moduł LCD alfanumeryczny, 2×16 z przylutowaną złączką pasującą do płytki prototypowej, oraz potencjometr 10 kΩ, liniowy do regulacji kontrastu.
Moduł LCD posiada kontroler zgodny z HD44780, co oznacza, że biblioteka LiquidCrystal będzie go obsługiwała. Jak go podłączyć?
Zacznijmy od kodu:
#include <LiquidCrystal.h> float temp; LiquidCrystal lcd (12,11,10,9,8,7); void setup() { analogReference(EXTERNAL); }; void loop () { temp = analogRead(0)*3.3/1024.0; temp = temp - 0.5; temp = temp / 0.01; delay(500); lcd.print("Temp: "); lcd.print(temp); lcd.print(" "); lcd.setCursor(0,0); };
Obsługa LCD w podstawowym zakresie sprowadza się do podłączenia go (o tym za chwilę), zainicjowaniu go:
LiquidCrystal lcd (12,11,10,9,8,7);
Powyższe definiuje zmienną lcd
, przez którą będziemy się komunikować z modułem. Tutaj przyjmujemy najprostszą postać czyli podajemy do których pinów Arduino podłączamy kolejno:
- pin RS modułu
- pin ENABLE modułu
- piny danych modułu D4, D5, D6, D7
W tym przykładzie 12 – RS, 11 – ENABLE, 10-7 D4-D7. Poza tym do modułu musimy podłączyć zasilanie oraz sygnał R/W modułu LCD do masy (nie będziemy nic do niego zapisywać). Nawet jak to wszystko podłączymy po uruchomieniu zobaczymy co najwyżej 32 czarne kwadraciki. Musimy jeszcze wyregulować kontrast. Odbywa się to przez podanie napięcia między 0 a 5V na pin Vo modułu. Aby móc regulować to napięcie skorzystamy z potencjometru będącego w zestawie. Całość podłączenia zilustrowana we Fritzingu (za MCP9700 robi symbol tranzystora, ale to dlatego, że nie ma takiego elementu we Fritzingu, obudowa jest taka sam (TO92):
Następnie w pętli loop
odczytujemy temperaturę z czujnika MCP-9700 (opisanego w tym poście). Mając temperaturę wyświetlamy napis Temp: potem wartość odczytu i wracamy na początek linii.
Jak poprawić odczyt temperatury?
Odczyt temperatury (w postaci napięcia mierzonego przez wejście analogowe 0) podawany przez MCP9700 jest podawany z dokładnością zależną od przetwornika napięcia w Arduino. Jest on 10-cio bitowy i domyślnie mierzy napięcia od 0 do 5V. 10 bitów oznacza to że mamy 1024 kroki w odczycie napięcia. Dlatego napięcie jest mierzone z krokiem 4.88 mV (5/1024).
Czujnik MCP9700 ma czułość 10 mV na stopień, czyli w praktyce znaczy to że mamy dokładność odczytu do pół stopnia (nie mówimy tutaj o jakości czujnika tylko o tym jak Arduino jest w stanie dokładnie odczytać napięcie).
Przetwornik A/D Arduino ma możliwość podania napięcia odniesienia (AREF – skrajne wyprowadzenie w rzędzie, gdzie są wejście/wyjścia cyfrowe), które zastąpi domyślne 5V. Napięcie to może być mniejsze lub większe od 5V.EDIT – niestety, ale pomyliłem się tutaj – z danych przetwornika wynika, że maksymalne napięcie odniesienia to napięcie zasilania – dla Arduino to oznacza 5V – jak koś musi mierzyć większe napięcie to dzielnik napięcia zostaje…
UWAGA!
Potencjalne zagrożenie. Wg dokumentacji funkcji analogReference, domyślne ustawienie (czyli gdy nie wywołamy w ogóle analogReference lub gdy zrobimy to z wartością DEFAULT), jest podatne na uszkodzenia gdy podamy napięcie na wejście AREF!
Z danych katalogowych MCP9700 wynika że maksymalne napięcie wyjściowe to 500 mV+ 125*10mV = 1.75V. Najlepiej byłoby zmusić przetwornik do pomiaru napięć w przedziale 0-1.75V, ale wymagało by to dodania dzielnika napięcia abyśmy taką wartość uzyskali. Nie jest to żadna skomplikowana sprawa, ale aby nie komplikować bardziej tego przykładu wykorzystamy prosty sposób na poprawę jakości odczytu, bez dodawania nowych elementów. Wykorzystamy fakt, że Arduino dostarcza nam poza 5V również 3.3V i bez żadnych kłopotów możemy poprawić czułość odczytu napięcia.
Dlatego w setup
jest wywołanie analogReference(EXTERNAL) (nie wystarczy podać samego napięcia na AREF) a w loop
zmienia się wzór do obliczania temperatury. Po zmianie napięcai odniesienia mamy krok odczytu napięcia 3.2 mV, co oznacza że odczyt pomiaru temperatury jest z dokładnością 0.3°C a nie 0.5°C jak wcześniej.
UWAGA – to jest tylko dokładność odczytu pomiaru a nie poprawa dokładności pomiaru. Czujnik ma, tak jak miał wcześniej dokładność +-2°C :) ta sztuczka poprawi tylko nasze samopoczucie, że odczyt nie skacze tak bardzo :)
Oczywiście, zmiana AREF dotyczy wszystkich wejść analogowych…
Mimo to skacze.
Ja robię 4-5 pomiarów raz za razem i je uśredniam. Dokładność prawie jak dallas (w zakresie 25-75 dokładność czujnika jest +- .5 stopnia. Jest to pomiar analogowy i bardzo czuły na dobre połączenia. W płytce testowej poruszanie czujnikiem powoduje duże skoki temperatury (napięcia na połączeniach)
Połączyłem 8x dallas 18B20 i obliczam średnią z 10 pomiarów. Mam stabilny wynik z dokładnością do 0,01stopnia!
Maksymalny rozrzut poszczególnych termometrów nie przekracza 2/16 stopnia.
Oczywiście docelowo termometry nie będą obok siebie, ale eksperyment ciekawy.
Wydaje mi się, że w schemacie z fritzinga jest błąd: (1) Moduł LCD potrzebuje 5V, które musi trafić do pierwszej nóżki potencjometru. (2) Czujnik też potrzebuje zasilania. (3) Sam czujnik na schemacie wydaje się być odwrócony. Po podłączeniu z uwzględnieniem 1-3 hula, aż miło. Oryginalna wersja natomiast nie chciała działać. ;-)
Tomek: Masz rację :)
Swoją drogą dodam, że porównałem odczyty z innego rodzaju sensorami i w kodzie od temperatury odejmuję 0.48 zamiast 0.5. Ale to też zależy od warunków konkretnego układu, także po pierwszym podłączeniu warto go wyskalować. Dla współczynnika korekcji 0.48 odczyt zgadza się na pewno w przedziale 15 do 36 stopni. ;-)
Dzięki za informacje.
Z tego co wiem to najlepiej amatorsko się sprawdzało wkładając czujnik do lodu z wodą i do gotującej się wody. Mając z tego przeliczniki dla 0 i 100 *C można ostatecznie wynik skalibrować z własnym ciałem na 36.6.