From 7a3be851fa54e177e8d6b911b76df937a9daa295 Mon Sep 17 00:00:00 2001 From: Norman Gray Date: Sun, 27 May 2018 12:29:50 +0100 Subject: [PATCH] Let pins float when writing (cf data sheet section 'write time slots') --- OneWire.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/OneWire.cpp b/OneWire.cpp index 38bf4ee..805fa4f 100644 --- a/OneWire.cpp +++ b/OneWire.cpp @@ -184,7 +184,7 @@ uint8_t OneWire::reset(void) delayMicroseconds(480); noInterrupts(); DIRECT_MODE_INPUT(reg, mask); // allow it to float - delayMicroseconds(70); + delayMicroseconds(70); // must be more than 60us, and less than (15+60)us r = !DIRECT_READ(reg, mask); interrupts(); delayMicroseconds(410); @@ -201,19 +201,28 @@ void OneWire::write_bit(uint8_t v) volatile IO_REG_TYPE *reg IO_REG_BASE_ATTR = baseReg; if (v & 1) { + // Data sheet: To generate a Write 1 time slot, after + // pulling the 1-Wire bus low, the bus master must + // release the 1-Wire bus within 15us. When the bus is + // released, the 5kOhm pullup resistor will pull the + // bus high. noInterrupts(); DIRECT_WRITE_LOW(reg, mask); DIRECT_MODE_OUTPUT(reg, mask); // drive output low delayMicroseconds(10); - DIRECT_WRITE_HIGH(reg, mask); // drive output high + DIRECT_MODE_INPUT(reg, mask); // release interrupts(); delayMicroseconds(55); } else { + // To generate a Write 0 time slot, after pulling the + // 1-Wire bus low, the bus master must continue to + // hold the bus low for the duration of the time slot + // (at least 60us). noInterrupts(); DIRECT_WRITE_LOW(reg, mask); DIRECT_MODE_OUTPUT(reg, mask); // drive output low delayMicroseconds(65); - DIRECT_WRITE_HIGH(reg, mask); // drive output high + DIRECT_MODE_INPUT(reg, mask); // release interrupts(); delayMicroseconds(5); } @@ -232,8 +241,10 @@ uint8_t OneWire::read_bit(void) noInterrupts(); DIRECT_MODE_OUTPUT(reg, mask); DIRECT_WRITE_LOW(reg, mask); + // must be low for minimum of 1us delayMicroseconds(3); DIRECT_MODE_INPUT(reg, mask); // let pin float, pull up will raise + // DS18B20 data is valid for 15us after falling edge delayMicroseconds(10); r = DIRECT_READ(reg, mask); interrupts();