0

I recently got to code my own driver for the One-Wire-Bus specifically with the ubiquitous DS18B20 temperature sensor in mind for an application.

I am running that code on an Arduino Mega 2560. Programming is done in Atmel Studio 7 and an AVR ISP mk2.

In the version as-of yesterday see here I get missing binary digits while trying to send the 0x55 One-Wire-Command (i.e. Match-Rom-Code). It appears like it where the least significant two bits that are missing (Oscilloscope capture).

Today I tried to sort out that bug and "fixed" it by counting to 9 instead of 8 (even though I can't explain why this should work, it should rather break stuff [turns out it does]...) and subtracting 1 from my index variable. (See file "OneWire.c" line 83 and following for the old version). Todays version is here (compare file "OneWire.c" line 81 and following).

In the new version (as-of today) I am able to get the 0x33 opcode (i.e. Send-Rom-Command) transmitted as wanted and get the ID of my specific sensor on the bus (atleast my oscilloscope shows the correct waveform). In the newer version I do the following chain of operations:

  • get the ID of the single sensor I have connected at the moment
  • send the Match-Rom-Command (just because that is something actually meaningful to do)
  • send the 64-Bit Rom-Code after that (or atleast what ever the statemachine of the getID function did end up writing in the output parameter)
  • send the 0x44 opcode (i.e. start temperature conversion)

This scenario yields me no correct Rom-code being sent on the bus, one byte more on the bus and another single bit too much on the bus for the temperature-conversion opcode. The Match Rom Code command does get transfered as supposed to and does not yield any extraneous or missing bits (no scope capture for that since that would not be possible to get into one shot that shows it all [at a workable scaling]...).

I would highly apprechiate anyone looking at my code and trying to figure out what is going wrong here since I am completely in the dark right now.

Before anybody asks:

I specifically did not want to use the readily available One-Wire-Libraries as they tend to be bloated and heavily rely on the delay function, which is fine if you are doing little else with your chip but not else. Since I have multiple sensors to read out (not yet but as soon as I got the drivers working) have to do some post processing on the raw data (i.e. put some sort of math to it) and transmit that data on a usually slow interface (I2C, Serial, you name it), which all takes time (and all that [periodically and as fast as possible of-course] on a poor 8-Bit Micro that runs at a underwhelming 16MHz...), I decided to keep polling and delay()-uses to a minimum and rather rely (heavily?) on a timer interrupt and a series of Statemachines...

It is not at all obvious to me why the code does act in that way.

  • I can't say much about your specific problem as a don't have too much experience with 1-wire. Actually, I always avoided using it, because those software implementations usually are so slow and blocking. That's why I'm curious about what you are trying to achieve. From what I know, 1-wire needs very accurate timing. I guews, one does not want anything else to happen while communication with a 1-wire device is going on. I think, reading several sensors synchronously will not be trivial – Sim Son Dec 14 '19 at 0:28
  • yes they are slow and blocking (due to the use of the delay function and similar bad techniques (we are talking about 500us for the reset and presence pulse together alone so roughly 7500 clock cycles at a 16MHz uC…) this is exactly what i want to circumvent by writing my own code for the job and by relying on timers where-ever possible. reading several sensors syncronously is not neccesary and not possible (if they are on the same bus else it is possible but anywhy) i plan to read them sequentially as soon as i can get at least one sensor working. The problem it self is not 1-wire-specific... – der bender Dec 15 '19 at 13:32
  • what i am exactly trying to archive is to measure a bunch of temperatures for a engine test rig. My supervisor advocated for the one wire temperature sensors and gave me the Arduino mega to have it all running on. it is planned to make the test rig a distributed System so that there is not much else going on on the uC just reading many sensors one at a time and converting the raw data to natural units and send them over to a "master"-Controller. Maybe some statistical stuff as well (mean temperature, dTemp/dTime and the like). The 7500 cycles mentioned above should be suffice for the math. – der bender Dec 15 '19 at 13:42
  • thats why i dont want to waste them. the real issue is just that the bit pattern on the bus shows more (or less) bits than what it is supposed to and from the code i can not get why it behaves that why. though i think that who ever takes a look at the code should easily see that i am somewhat proficent in writing code so its not that that is a problem... – der bender Dec 15 '19 at 13:45
  • DS18B20 is not the sensor for you, it's to slow you had to find another sensor! – Carlmikael Dec 17 '19 at 5:15
0

I managed to find the bug and fix it. I was missing that after the reset pulse the master must be in RX mode for atleast 480us no matter what, even if the presence pulse did occur and even if it's rising Edge did appear already. This mistiming did lead to the missing bits that were corrected with sending more bits until now (which in turn lead to the extraneous bits later on in the transmission).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.