1-WIRE cz11

Protokół 1-Wire został opracowany przez firmę Dallas Semiconductor. Zapewnia on stosunkowo niewielką przepustowość transmisji danych – standardowo 16 kbps w trybie regular do 115,2 kbps w trybie overdrive. Jego nazwa wywodzi się z faktu, że do komunikacji używana jest tylko jedna linia danych.

Niektóre odbiorniki nie potrzebują dodatkowej linii zasilania, ponieważ są wyposażone w kondensator, który się ładuje z  linii danych – następnie energia w nim zgromadzona używana jest do zasilania odbiornika.

1-Wire jest podobne do interfejsu I²C, lecz z uwagi na pojedynczą linię komunikacyjną jest zarówno wolniejsze, jak i tańsze. Interfejs 1-Wire jest zazwyczaj używany do komunikacji pomiędzy niewielkimi urządzeniami, takimi jak: termometry cyfrowe, instrumenty metrologiczne, sterowniki ładowania akumulatorów, zamki elektroniczne typu iButton itd.

Do jednej linii danych może być podpiętych wiele urządzeń. Każde z nich posiada bowiem unikatowy 64-bitowy numer identyfikacyjny.

Zadanie:

Stwórz układ oparty na dwóch czujnikach temperatury DS18B20. Odczytaj ich wartość w serial monitorze.

Schemat połączenia:

schemat

Mamy dwa czujniki DS18B20. Każde z nich posiada swój własny unikatowy adres identyfikacyjny. Aby móc obsługiwać czujniki za pomocą 1-Wire musimy pierwsze stworzyć program, który odczyta te adresy.

Kod Programu do odczytu adresu:
// Biblioteki, które musimy zainstalować
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 4 // definicja pinu OneWire
OneWire oneWire(ONE_WIRE_BUS); // Podłączenie do ONE_WIRE_BUS
DallasTemperature sensors(&oneWire); // Przekazania informacji do biblioteki
DeviceAddress Adress; // Zmienna przechowująca adres

int deviceCount = 0;

void setup(void)
{
    Serial.begin(9600);
    sensors.begin(); //Inicjalizacja czujników

    Serial.print("Znaleziono ");
    deviceCount = sensors.getDeviceCount(); // Przypisz liczbę czujników do deviceCount
    Serial.print(deviceCount, DEC); // Wyślij na serial monitor ilość czujników
    Serial.println("");

    Serial.println("Adresy:");
    for (int i = 0; i < deviceCount; i++) // wykonaj tyle razy ile jest deviceCount
    {
        Serial.print("DS18B20 ");
        Serial.print(i + 1);
        Serial.print(" : ");
        sensors.getAddress(Adress, i); // pobierz Adres do zmiennej Adress czujnika i
        printAddress(Adress); // Wyświetl adres
    }
}

void loop(void){}

void printAddress(DeviceAddress device)  // funkcja wyświetlająca adres
{
    for (uint8_t i = 0; i < 8; i++)
    {
        Serial.print("0x");
        if (device[i] < 0x10) Serial.print("0");
        Serial.print(device[i], HEX);
        if (i < 7) Serial.print(", ");
    }
    Serial.println("");
}
Wynik:

wynik

Otrzymaliśmy dwa adresy czujników w monitorze portu szeregowego. Aby je rozróżnić możemy odłączyć jeden z nich i zrestartować Arduino, wtedy otrzymamy jeden adres. Posiadając adresy możemy przejść do rozwiązania zadania.

Kod programu:
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 4 // Definicja pinu OneWire

OneWire oneWire(ONE_WIRE_BUS); // Podłączenie do ONE_WIRE_BUS
DallasTemperature sensors(&oneWire); // Przekazania informacji do biblioteki

// Deklaracja zmiennych z wczesniej odczytanymi adresami
uint8_t sensor1[8] = { 0x28, 0x26, 0xE2, 0x9B, 0x33, 0x14, 0x01, 0x85 }; 
uint8_t sensor2[8] = { 0x28, 0xFF, 0xAA, 0xF1, 0x6B, 0x18, 0x01, 0x98 };

void setup(void)
{
  Serial.begin(9600);
  sensors.begin(); //Inicjalizacja czujników
}

void loop(void)
{
  sensors.requestTemperatures(); // Aktualizacja danych z sensorów
  Serial.print("DS18B20 1: ");
  printTemperature(sensor1);  
  Serial.print("DS18B20 2: ");
  printTemperature(sensor2);
  Serial.println("");
  delay(6000);
}

// Funkcja odczytująca i wysyłająca temperature 
void printTemperature(DeviceAddress deviceAddress) 
{
  float tempC = sensors.getTempC(deviceAddress); // Odczyt temperatury sensor
  Serial.print(tempC); // wysłanie temperatury do PC
  Serial.print("C\n");
}
Wynik w monitorze portu szeregowego:

wynik