Szukaj na tym blogu

sobota, 13 lipca 2013

Odczyty z bezprzewodowej sondy po I2C - POC

Wstęp

Ostatnio zmontowałem układ do odczytu bezprzewodowej sondy temperatury i wilgotności. Patrz:
Teraz postanowiłem podłączyć go do układu odczytującego temperatury i wilgotności z czujników podłączonych kabelkami (patrz np http://arduinoj.blogspot.com/2013/04/pierwsza-produkcyjna-implementacja_28.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ła
// 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
który odpowiada za dołączenie definicji interfejsu I2C do szkicu i zdefiniowanie wewnętrznego nr urządzenia.
Kolejny kawałek:
#ifdef WIRE_SERVER
  void wireRequestEvent()
  {
    uint32_t buf [3] = { nLastChannel, nLastTemp, nLastHumidity };
   
    Wire.write ((byte*) buf, 12);
  }
#endif
to funkcja wysyłająca dane na żądanie serwera. To już wszystkie fragmenty kodu odpowiedzialne za transfer informacji po I2C.

Na arduino napisałem prosty programik, który:
Kod tego programu jest następujący:

#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);
  }
 

}
 O samym podłączaniu "drucików" nie będę już pisał teraz, napiszę o tym jak zmontuję docelowy układ.

Brak komentarzy:

Prześlij komentarz