INFORMACJA: Poniższy post nie wydostał się z Poczekalni :(
Witam wszystkich majsterkowiczów. Chcę wam przedstawić projekt wykorzystujący dwa Arduino gdzie jedno jest nadajnikiem i wysyła temperaturę a drugi jest odbiornikiem i odbiera temperaturę. Jedno arduino w moim przypadku jest przy oknie, a drugie u mnie na biurku.
W tym celu wykorzystamy:
- Dwa Arduino (w moim przypadku nano),
- Cyfrowy czujnik temperatury DS18B20,
- Rezystor 4.7k Ohm,
- Ekran LCD na I2C (Ja użyłem ekranu 20×4),
- Moduł radiowy i odbiornik 315Mhz lub 433Mhz,
- Przewody połączeniowe,
- Mała płytka stykowa.
Na początku musimy wgrać potrzebne nam biblioteki:
Łączymy wszystko zgodnie ze schematem:
Pora napisać program na nasz nadajnik:
#include <OneWire.h> #include <DallasTemperature.h> #include <VirtualWire.h> const int NadajnikRF = 3; // Port do, którego podłączyliśmy nadajnik // ===Inicjalizacja czujnika temperatury=== #define ONE_WIRE_BUS 2 // Zmieniamy liczbę 2 jeżeli podłączyliśmy nasz czujnik do innego portu w Arduino OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); DeviceAddress insideThermometer; // ======================================== void setup() { Serial.begin(9600); // Rozpoczynamy komunikację szeregową w celu debugowania sensors.begin(); // Rozpoczęcie pracy czujnika if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Nie znaleziono czujnika"); Serial.print("Adres czujnika temperatury: "); printAddress(insideThermometer); sensors.setResolution(insideThermometer, 9); vw_setup(4000); // Szybkość transferu danych vw_set_rx_pin(NadajnikRF); // Port ustalony wyżej } void printTemperature(DeviceAddress deviceAddress) // Funkcja, która odpowiada za odczyt temperatury i wysłanie jej do Raspberry { float tempC = sensors.getTempC(deviceAddress); // Zapisanie temperatury do zmiennej Float int tempCx100 = (int)(tempC*100); // Zmiana floata na inta Serial.print("Temp C: "); // Wyświetlenie temperatury na serial monitorze Serial.print(tempC); // Wyświetlenie temperatury na serial monitorze char msg[5]; // Tworzymy tablicę typu Char String doWyslania = (String(tempCx100, DEC)); doWyslania.toCharArray(msg, doWyslania.length() + 1); // Konwersja inta do tablicy Char vw_send((uint8_t *)msg, strlen(msg)); // Wysyłanie temperatury do Raspberry vw_wait_tx(); } void loop() { sensors.requestTemperatures(); // Pomiar temperatury printTemperature(insideThermometer); // Użycie funkcji printTemperature delay(2000); // przerwa 2000ms = 2s } void printAddress(DeviceAddress deviceAddress) // Funkcja służąca do wyświetlenia adresu czujnika DS18B20 { for (uint8_t i = 0; i < 8; i++) { if (deviceAddress[i] < 16) Serial.println("0"); Serial.print(deviceAddress[i], HEX); } }
Gdy już wgraliśmy nasz przykład możemy przystąpić do przygotowania odbiornika.
Najpierw musimy sprawdzić jaki adres ma nasz LCD, aby to sprawdzić wgrywamy sketcha:
// -------------------------------------- // i2c_scanner // // Version 1 // This program (or code that looks like it) // can be found in many places. // For example on the Arduino.cc forum. // The original author is not know. // Version 2, Juni 2012, Using Arduino 1.0.1 // Adapted to be as simple as possible by Arduino.cc user Krodal // Version 3, Feb 26 2013 // V3 by louarnold // Version 4, March 3, 2013, Using Arduino 1.0.3 // by Arduino.cc user Krodal. // Changes by louarnold removed. // Scanning addresses changed from 0...127 to 1...119, // according to the i2c scanner by Nick Gammon // http://www.gammon.com.au/forum/?id=10896 // Version 5, March 28, 2013 // As version 4, but address scans now to 127. // A sensor seems to use address 120. // Version 6, November 27, 2015. // Added waiting for the Leonardo serial communication. // // // This sketch tests the standard 7-bit addresses // Devices with higher bit address might not be seen properly. // #include <Wire.h> void setup() { Wire.begin(); Serial.begin(9600); while (!Serial); // Leonardo: wait for serial monitor Serial.println("\nI2C Scanner"); } void loop() { byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for(address = 1; address < 127; address++ ) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address<16) Serial.print("0"); Serial.print(address,HEX); Serial.println(" !"); nDevices++; } else if (error==4) { Serial.print("Unknow error at address 0x"); if (address<16) Serial.print("0"); Serial.println(address,HEX); } } if (nDevices == 0) Serial.println("No I2C devices found\n"); else Serial.println("done\n"); delay(5000); // wait 5 seconds for next scan }
Otwieramy serial monitor i sprawdzamy adres naszego wyświetlacza, w moim przypadku jest to 0x3F.
Teraz możemy przystąpić do pisania kodu na nasz odbiornik:
#include <LiquidCrystal_I2C.h> #include <Wire.h> #include <VirtualWire.h> const int OdbiornikRF = 2; #define BACKLIGHT_PIN 3 LiquidCrystal_I2C lcd(0x3F, 2,1,0,4,5,6,7); // Tutaj należy zmienić adres naszego wyświetlacza char temperatura; int temperatura1; float temperaturafloat; byte znak1[8] = { 0b00110, 0b01001, 0b01001, 0b00110, 0b00000, 0b00000, 0b00000, 0b00000 }; byte znak2[8] = { 0b01110, 0b11011, 0b11000, 0b11000, 0b11000, 0b11011, 0b01110, 0b00000 }; void setup() { Serial.begin(9600); // Rozpoczynamy komunikację szeregową w celu sprawdzenia czy wszystko działa poprawnie lcd.begin(20,4); // Inicjalizacja LCD, zmieniamy jego wielkość, ja mam ekran 20x4 więc wpisuję 20, 4 lcd.setBacklightPin (BACKLIGHT_PIN, POSITIVE); lcd.setBacklight (HIGH); // Włączamy podświetlenie lcd.home(); lcd.clear(); lcd.createChar(1,znak1); lcd.createChar(2,znak2); vw_set_rx_pin(OdbiornikRF); vw_setup(4000); vw_rx_start(); } void loop() { uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; lcd.clear(); if (vw_get_message(buf, &buflen)) { int i; lcd.setCursor(0, 0); lcd.print("Temperatura: "); Serial.println("Otrzymano: "); for (i=0;i<buflen;i++) { temperatura = char(buf[i]); Serial.print(buf[i], HEX); } temperatura1 = (int)temperatura; temperaturafloat = temperatura1 / 1000; lcd.setCursor(0,1); lcd.print(temperaturafloat); lcd.write(byte(1)); lcd.write(byte(2)); } }
Gotowe :)
Zdjęcia:
Udało się wyświetlić temperaturę z nadajnika na naszym ekranie.
Jak macie jakieś pytania lub zauważyliście błąd piszcie w komentarzach. Pozdrawiam Mateusz :)
INFORMACJA: Poniższy post nie wydostał się z Poczekalni :(
było