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:

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:

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:

