Wstęp
Ostatnio zmontowałem układ do odczytu bezprzewodowej sondy temperatury i wilgotności. Patrz:- http://arduinoj.blogspot.com/2013/05/odczyt-bezprzewodowej-sondy-temperatury.html
- http://arduinoj.blogspot.com/2013/05/odczyt-bezprzewodowej-sondy-programowa.html
- http://arduinoj.blogspot.com/2013/06/pierwszy-artyku-na-majsterkowopl.html
Wybór padł na interfejs I2C. Czemu akurat ten. A bez konkretnego powodu, raz żeby go poznać, a dwa bo jakoś intuicyjnie wydał mi się dobry.
Na zdjęciu poniżej widać wszystko co akurat mam zmontowane i oryginalną stację odczytującą dane z tej samej bezprzewodowej sondy.
Opis rozwiązania
Dzisiaj nie uruchomiłem jeszcze docelowego rozwiązania, a tylko zrobiłem Proof Of Concept przy użyciu mikrokontrrolera i arduino.Pierwsze to podłączyłem odbiornik 433MHz do mikrokontrolera i wrzuciłem tam program do odczytu danych z bezprzewodowej sondy. Program ten wzbogaciłem o kawałki kodu odpowiedzialne za przesyłanie danych po I2C. Te kawałki to:
// jeżeli WIRE_SERVER jest ustawione to programik działaktóry odpowiada za dołączenie definicji interfejsu I2C do szkicu i zdefiniowanie wewnętrznego nr urządzenia.
// jako serwer I2C
// UWAGA: przy włączonym pełnym debuggowaniu zaczyna brakować pamięci
#define WIRE_SERVER
#ifdef WIRE_SERVER
#include "Wire.h"
#define WIRE_ADDRESS 7
#endif
Kolejny kawałek:
#ifdef WIRE_SERVERto funkcja wysyłająca dane na żądanie serwera. To już wszystkie fragmenty kodu odpowiedzialne za transfer informacji po I2C.
void wireRequestEvent()
{
uint32_t buf [3] = { nLastChannel, nLastTemp, nLastHumidity };
Wire.write ((byte*) buf, 12);
}
#endif
Na arduino napisałem prosty programik, który:
- pobiera z zegara aktualny czas (patrz http://arduinoj.blogspot.com/2013/07/wyswietlacz-lcd-po-i2c-i-zegar-rtc.html)
- pobiera z powyższego układu wskazania sondy
- wyświetla wszystko na LCD
O samym podłączaniu "drucików" nie będę już pisał teraz, napiszę o tym jak zmontuję docelowy układ.
#include <Wire.h>
#include <DS1307.h>
#include <LiquidCrystal_I2C.h>
// set the LCD address to 0x20 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x20,16,2);
#define BAD_VALUE 0b1000000000000000
uint32_t nLastChannel = BAD_VALUE;
uint32_t nLastTemp = BAD_VALUE;
uint32_t nLastHumidity = BAD_VALUE;
void getWeather()
{
uint32_t buf [3];
// request 12 bytes from slave device #7
Wire.requestFrom(7, 12);
int i = 0;
// slave may send less than requested
while(Wire.available())
{
((byte*) buf) [i] = Wire.read();
Serial.print((unsigned byte) ((byte*)buf)[i]);
Serial.print(", ");
i++;
}
Serial.println();
nLastChannel = buf[0];
nLastTemp = buf[1];
nLastHumidity = buf[2];
}
void setup()
{
Serial.begin(9600);
Serial.println("odczyt pogody i na lcd");
lcd.init(); // initialize the lcd
// Print a message to the LCD.
lcd.backlight();
}
int last_sec = -1;
long num_of_measures = 0;
unsigned long last_time = 0;
const char *days [7] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
void loop()
{
unsigned long time = millis();
int sec = RTC.get(DS1307_SEC,true);
if (sec != last_sec)
{
last_sec = sec;
lcd.home();
char buf [17];
// sprintf(buf, "%02d-%02d-%d %s",
// RTC.get (DS1307_DATE, false),
// RTC.get (DS1307_MTH, false),
// RTC.get (DS1307_YR, false),
// days [RTC.get (DS1307_DOW, false) - 1]
// );
sprintf(buf, "%02d-%02d-%d",
RTC.get (DS1307_DATE, false),
RTC.get (DS1307_MTH, false),
RTC.get (DS1307_YR, false)
);
lcd.print(buf);
lcd.setCursor(0, 1);
// sprintf (buf, "%02d:%02d:%02d %7d",
// RTC.get (DS1307_HR, false),
// RTC.get (DS1307_MIN, false),
// sec,
// last_time
// );
sprintf (buf, "%02d:%02d:%02d",
RTC.get (DS1307_HR, false),
RTC.get (DS1307_MIN, false),
sec
);
lcd.print(buf);
getWeather();
lcd.setCursor(12, 0);
if (nLastHumidity == BAD_VALUE)
{
lcd.print(F("??%"));
}
else
{
sprintf(buf, "%02d%%", nLastHumidity);
lcd.print(buf);
}
lcd.setCursor(9, 1);
if (nLastChannel == BAD_VALUE)
{
lcd.print(F("?:"));
}
else
{
sprintf(buf, "%1d:", nLastChannel + 1);
lcd.print(buf);
}
if (nLastTemp == BAD_VALUE)
{
lcd.print(F("??.?C"));
}
else
{
sprintf(buf, "%02d.%1dC", (int) (nLastTemp / 10), (int) (nLastTemp % 10));
lcd.print(buf);
}
num_of_measures = 0;
last_time = millis() - time;
}
else
{
num_of_measures++;
delay(100);
}
}
Brak komentarzy:
Prześlij komentarz