alvesjc:
I' had it running with other timers, but would have failures from time to time, some of them were very spaced in time.
I can believe that. Several of the code fragments above have the interrupt disable removed. If an interrupt occurs during a bit read or write, it will lengthen the timing. On ARM, the problem is probably less, because the process is so much faster, especially with interrupt overhead (the context is saved by hardware, utilizing a separate bus, rather than by code in the interrupt routine). This was one of the 2 major bugs before I made version 2.0.
I've been running the OneWire code that I posted in the ZIP file in a previous post for over 12 hours with no errors pulling data from three DS18B20's.
I have not been able to incorporate mantoui's updated read_bit function but I will do that later tonight when I'm home.
ROM = 28 A0 CE 49 3 0 0 55
Chip = DS18B20
Data = 1 A3 1 4B 46 7F FF D 10 CE CRC=CE
Temperature = 26.19 Celsius, 79.14 Fahrenheit
ROM = 28 F6 C3 49 3 0 0 25
Chip = DS18B20
Data = 1 A2 1 4B 46 7F FF E 10 D8 CRC=D8
Temperature = 26.12 Celsius, 79.03 Fahrenheit
ROM = 28 6B C7 49 3 0 0 C1
Chip = DS18B20
Data = 1 A3 1 4B 46 7F FF D 10 CE CRC=CE
Temperature = 26.19 Celsius, 79.14 Fahrenheit
No more addresses.
I noticed in the Examples folder there is also a sketch for a DS2408 which is an 8 channel addressable switch. I have a number of those lying around so I may be able to test the sketch later against one and let you know the results.
[quote author=Paul Stoffregen link=topic=141030.msg1067752#msg1067752 date=1357937038]
Does Due have a tone() function yet? If so, please output an infinite duration 15 kHz tone on a pin during the test.
I believe the tone functions are still not ported.
[/quote]
I'm not sure what this has to do with onewire thread, but I have a proof-of-concept tone(), see tone1.ino in
I've been working with OneWire today. I included the #defines for Due.
It seems to work on a couple sensors, but most of my 10 test sensors them do not work. They all respond with a presence pulse, but then return 0xFF for every byte including the checksum.
So I started troubleshooting. I believe I've tracked the problem to a possible bug in delayMicroseconds(). I'm using Arduino IDE 1.5.1.
Here is a very simple test program, which does a reset and then sends a single byte (skip is 0xCC).
#include <OneWire.h>
OneWire ds(10); // on pin 10
void setup() {
}
void loop() {
ds.reset();
ds.skip();
delay(10);
}
Here is the actual waveform:
On the top trace you can see the entire sequence. On the bottom is a zoomed in view of the first 4 bits after the reset. The time scale is 30 us/div. OneWire sends LSB first, so this is two 0s followed by two 1s.
The first 0 bit is incorrect. OneWire called delayMicroseconds(65), but as you can see on the trace, the time was only 30 us. The next zero bit is generated by the exact same code, where the delay actually is 65 us. Well, it's actually closer to 67 us, but a 2 us error is ok. But the first pulse being less than 60 us is not ok. The datasheet says the chip will sample the voltage between 15 to 60 us after the falling edge, so a 30 us pulse works with some chips, but not others (most my 10 test samples apparently sample after 30 us).
Here is the same code, with the same sensor and same oscilloscope setup, running on a Teensy 3.0 board.
Both of the zero bits have a 65 us wide low pulse.
I'm having problems reading from multiple DS18B20's with your 2.2 preview library.
Fresh copy of arduino-1.5.1r2-windows, and downloaded just your 2.2 preview library, and I run the DS18x20_Temperature sketch with three of the DS18B20's attached to Due pin 54 (Analog line 0) and I get the following:
No more addresses.
No more addresses.
No more addresses.
If I pull two of the sensors out it starts returning results although sometimes it returns results like the following:
I'm using the ADK2012 device (with the google-provided IDE), which is very similar to an Arduino Due. When I include the pre-release 2.2 version linked above into a project and compile, I get errors like this:
OneWire.cpp: In constructor 'OneWire::OneWire(uint8_t)':
OneWire.cpp:123: error: base operand of '->' has non-pointer type 'const PinDescription'
OneWire.cpp:124: error: base operand of '->' has non-pointer type 'const PinDescription'
Removing the 2 lines it's complaining about allows it to compile, but unsurprisingly, it doesn't actually work.
I'm new enough to all this that I don't have a good handle on how to get started debugging this. Any ideas?
PaulMcMillan:
I'm using the ADK2012 device (with the google-provided IDE), which is very similar to an Arduino Due. When I include the pre-release 2.2 version linked above into a project and compile, I get errors like this:
Did you try compiling on Arduino 1.5.1?
Maybe you can copy whatever's ADK2012 is missing from Arduino 1.5.1?
Of course, without fixing delayMicroseconds(), it's unlikely to work reliably.
Is there any way to fix to the delayMicroseconds() issue? or is this something we have to hope the folks at arduino will fix for us? I am using the Ds18b20's for a brewery system and have moved to the due recently and don't want to backtrack to change the sensors
I tried the the OneWire 2.2 with IDE 1.5.1r2. Two of four DS1820 sensors give me no readings ("No more addresses" in the DS18x20 Example sketch), the other two produce no valid temperature readings:
I just finished diff-and-try session with the library version OneWire_preview22_17jan13.zip and the version from this thread (with changes by alvesjc and mantoui).
The critical point seems to be the write_bit() function and the interrupt handling combined with delayMicroseconds() calls in this function (both have been mentioned in this thread already).
As soon as I excluded delayMicroseconds calls from noInterrupts()/interrupts() sections in the write_bit() function, the library worked.
I'm running a test with all the sensors installed in my house heating control, I have 9 DS1820 for temperature sensing and some DS2408 and DS2413 for relay switching.
All of them are working (so far) as they usually do with my old Arduino Mega. I'll post test results tomorrow.
Interrupts are disabled for a very good reason. There's absolutely no way OneWire will return to the buggy pre-2.0 days where interrupts could lengthen the timing and cause random communication errors.
Ok, I understand that (I do know what are interrupts for and why they are disabled in time critical sections). I do not understand why delayMicroseconds acts differently depending on interrupts being disabled or enabled. Declaration of delayMicrosections for SAM is quite simple (from wiring.c):
void delayMicroseconds( uint32_t us )
{
uint32_t start = micros();
while ((micros() - start) < us)
;
}
[quote author=Paul Stoffregen link=topic=141030.msg1115802#msg1115802 date=1360682994]
Interrupts are disabled for a very good reason. There's absolutely no way OneWire will return to the buggy pre-2.0 days where interrupts could lengthen the timing and cause random communication errors.
Ok, I understand that (I do know what are interrupts for and why they are disabled in time critical sections). I do not understand why delayMicroseconds acts differently depending on interrupts being disabled or enabled. Declaration of delayMicrosections for SAM is quite simple (from wiring.c):
void delayMicroseconds( uint32_t us )
{
uint32_t start = micros();
while ((micros() - start) < us)
;
}
It did not change since 1.5.1r2.
Do you have an idea, what the solution could be?
Leo
PS if I can contribute in any way, let me know.
[/quote]
So the problem must be somewhere behind the micros the function delayMicroseconds is realy open so the problem musst be somewhere there
Markus_L811:
So the problem must be somewhere behind the micros the function delayMicroseconds is realy open so the problem musst be somewhere there
Right, micros() must have a problem with noInterrupts().
I tried to change delayMicroseconds() to make it independent from micros(). Here is the code:
#define CYCLES_PER_USEC 84 // Arduino Due has 84 MHz clock
#define CYCLES_PER_LOOP 6 // one iteration of the loop takes 6 cycles
#define OVERHEAD_CONST 18 // could someone with an osci please verify this constant?
void delayMicroseconds( uint32_t us )
{
if(us==1) return;
int j;
//one iteration of this loop takes 6 cycles on Arduino Due compiled with IDE 1.5.2
for(j=0;j<us*(CYCLES_PER_USEC/CYCLES_PER_LOOP)-OVERHEAD_CONST;j++)
{
asm volatile("mov r0, r0"); // just NOP
asm volatile("mov r0, r0");
}
}
This change worked with the original version of OneWire (OneWire_preview22_17jan13.zip)
This patch is not pretty but it proves that the problem is in the micros().
Tomorrow I'll try to understand, why micros() has a problem with noIterrupts().