Zapisywanie danych z czujnika na karcie SD w systemie Arduino

Prezentujemy przykład zapisywania danych na karcie SD w systemie Arduino. Rejestrowane będą dane o temperaturze otoczenia, pobrane z popularnego sensora DS18B20. Cały projekt działa na płytce Cytron Maker Uno, w pełni kompatybilnej z Arduino UNO.

W roli modułu czytnika kard SD wykorzystano płytkę Fermion: SD Card Module z oferty DFRobot. Płytka zawiera slot na karty typu microSD i komunikuje się poprzez interfejs SPI. Zawiera wlutowane złącze szpilkowe, co pozwala na dołączenie modułu do płytki stykowej.

Rys. 1. Moduł czytnika kart SD Fermion: SD Card Module

W roli źródła danych zapisywanych na karcie SD zastosowano czujnik temperatury DS18B20. Pozwala na pomiar temperatury w zakresie -55~+125°C z dokładnością ±0,5°C (w zakresie -10~+85°C). Do komunikacji wykorzystywany jest interfejs 1-Wire. W celu łatwiejszego podłączenia do Arduino, skorzystamy z płytki KAmodDS18B20. Ta płytka jest wyposażona w złącza w standardzie Pmod oraz KAmod, ale można też skorzystać z tradycyjnych, pojedynczych przewodów.

Rys. 2. Moduł KAmodDS18B20 z czujnikiem temperatury DS18B20

 

Połączenie modułów do płytki Arduino

Sensor temperatury korzysta z interfejsu 1-Wire, natomiast czytnik kart z SPI. Arduino Uno ma wystarczającą liczbę wyprowadzeń, aby bez problemu podłączyć oba moduły. Oba korzystają z zasilania 5 V, co oznacza, że prawdopodobnie będzie trzeba je rozgałęzić, na przykład poprzez szynę zasilania na płytce stykowej.

Oto tabele prezentujące połączenia modułów z płytką Arduino:

Tab. 1. Połączenie płytki KAmodDS18B20 z Arduino

KAmodDS18B20 Maker Uno
VDD 5V
GND GND
1-W 2

 

Tab. 2. Połączenie czytnika kart SD z Arduino

Fermion: SD Card Module Maker Uno
MISO 12
SCK 13
SS 4
MOSI 11
GND GND
+5V 5V
 

Rys. 3. Połączenie wszystkich elementów układu

Kod przykładu

Tak jak wspomniano wcześniej, kod ma za zadanie odczytać dane z sensora temperatury, a następnie zapisać je w pliku na karcie SD. Dane będą zapisywane w pliku typu CSV z danymi oddzielonymi średnikiem, co pozwoli od razu otworzyć plik w programie Excel i LibreOffice.

Pierwszą kolumną danych będzie oznaczenie czasu pomiaru. W tym przypadku jest to aktualny wynik funkcji millis(), ale można łatwo zmodyfikować projekt, aby zapisywał w tym miejscu aktualną datę i godzinę. Drugą kolumną jest oczywiście aktualna temperatura.

Na początku importujemy niezbędne biblioteki. Do obsługi czytnika kart użyjemy dedykowanej biblioteki dla kart SD, a także pakietu do obsługi SPI. Podobna sytuacja jest w przypadku termometru, gdzie korzystamy z biblioteki DallasTemperature.h do obsługi czujnika oraz OneWire.h do obsługi interfejsu.

W kolejnym kroku definiujemy wyprowadzenia używane przez poszczególne moduły. Przede wszystkim chodzi tu o port Chip Select interfejsu SPI oraz linię danych magistrali 1-Wire.

Następnie definiujemy zmienne współpracujące z funkcją millis. W previousMillis będziemy przechowywać dane o poprzednio zapisanej wartości funkcji, którą potem będziemy porównywać z wartością aktualną. Stała interval natomiast przechowuje częstotliwość powtarzania pętli operacyjnej – będzie to 1000 ms, czyli 1 sekunda.

Inicjalizujemy jeszcze obiekty klas OneWire i DallasTemperature, co umożliwi obsługę sensora temperatury.

Instrukcje w funkcji setup

W funkcji setup uruchamiam port szeregowy, inicjalizuję czujnik oraz kartę SD. Na porcie szeregowym wyświetlona zostanie informacja, czy karta jest poprawnie widoczna w systemie czy też nie (np. na skutek braku karty w slocie).

Pętla główna

W pętli głównej programu inicjalizujemy zmienną currentMillis i zapisujemy do niej czas pracy programu w milisekundach. Następnie w warunku if sprawdzamy czy od ostatniego wykonania programu minęło zdefiniowane wcześniej 1000 ms. Dalsza część pętli nie wykona się o ile warunek ten nie zostanie spełniony.

Po spełnieniu warunku if, zapisujemy aktualną wartość czasową w zmiennej previousMillis do kolejnych porównań. Tworzymy teraz łańcuch znaków dataString, w którym będziemy zapisywać dane w postaci tekstowej. Do pustego łańcucha dodajemy timestamp ze zmiennej previousMillis, a następnie średnik i spację.

W kolejnym kroku uruchamiamy pomiar temperatury i wpisujemy go do zmiennej tempC. Zmienna ta bez problemu daje się dodać do łańcucha znaków za pomocą operatora +=.

Następnie inicjujemy kotwicę do otwarcia pliku jednocześnie otwierając sam plik. Jeśli plik zostanie prawidłowo otwarty, to w następnym kroku program zapisze do niego utworzoną linijkę danych i zamknie plik. Następnie ta sama linijka zostanie wypisana na port szeregowy.

Taki sposób obsługi pliku oznacza, że plik otwierany jest tylko przez krótką chwilę na czas zapisania danych. Można więc odłączyć urządzenie od zasilania prawie bez obaw o uszkodzenie pliku. Po odłączeniu zasilania program zaczyna bez problemu z powrotem zapisywać dane w utworzonym pliku (aczkolwiek funkcja millis liczy od początku). Ciekawostką jest też fakt, że po włączeniu portu szeregowego, funkcja millis również rozpoczyna zliczanie od początku.

Pełen kod programu

Pliki projektowe są dostępne w sekcji Do pobrania.

Wynik pracy programu

Jak wspominałem, program zapisuje dane w pliku CSV w dwóch kolumnach oddzielonych średnikiem. Pozwala to łatwo zaimportować plik do Excela oraz wielu innych programów, ze względu na prostotę i powszechność tego formatu. Oczywiście po implementacji można dokonać analizy danych w bardzo szerokim zakresie.

Rys. 4. Dane z pliku zaimportowane w Excelu

Wszystkie komponenty użyte w projekcie są dostępne w ofercie sklepu Kamami.pl

Do pobrania

O autorze