robert-hh / Onewire_DS18X20

Classes for driving the DS18x20 sensor with the onewire protocol for Pycom MicroPython
11 stars 6 forks source link

Can this library detect when DS18X20 finishes temperature conversion? #21

Open MarioPL98 opened 11 months ago

MarioPL98 commented 11 months ago

Hi. According to pdf docs (https://www.analog.com/media/en/technical-documentation/data-sheets/DS18B20.pdf)

If the DS18B20 is powered by an external supply, the master can issue read time slots after the Convert T command and the DS18B20 will respond by transmitting a 0 while the temperature conversion is in progress and a 1 when the conversion is done.

Can this library detect it and get temperature without using any sleep functions to wait predetermined amount of time? Can this be done with reading scratchpad without losing too much time?

What about this part of the docs?: image

robert-hh commented 11 months ago

This scan method is not implemented, but it is useful. It has to be implemented in the onewire module. Do you use the version onewire.py from this lib or the onewire module of MicroPython in micropython/drivers/bus/onewire?

MarioPL98 commented 11 months ago

I haven't tried using either yet. I'm also quite beginner when it comes to python on microcontrollers. I can try adding support for this if you can help me a bit. I remember implementing it for stm32 using interrupts and timers (C/C++) few years ago and I would like to try it here. What do you think?

If possible, I would like to implement whole onewire based on your code so that it works in non-blocking way. When I was programming it for stm32, I used timer for 0s and 1s in onewire communication and another timer with interrupts for all other stuff.

Do you think micropython on pi pico would be fast enough to allow using timers for onewire communication? On stm32 my method was fast enough that there was almost no performance penalty for using this while performing heavy math in main loop. I want to try using PIO in near future too but I have yet to understand it better.

I'm trying to use micropython since I'm starting with pi pico and I want to see if it's actually easier to do similar stuff.

robert-hh commented 11 months ago

The Pico has by default the MicroPython driver built-in. The basic communication there is C code, which works even on small & slow MCUs. You should be able to use that with asyncio, and at also in the second thread of the Pico. For the DS18B20 it's only the bit read part which has to be blocking. But that's short. For the read after x ms you can of course use a timer.

MarioPL98 commented 11 months ago

Do you think micropython is fast enough so that using non-blocking bits transfer (60 us delay) is worth it? Or should I rather use PIO? I want avoid disabling irq when transmitting with onewire.

robert-hh commented 11 months ago

Do you think micropython is fast enough so that using non-blocking bits transfer (60 us delay)

I have my doubts. Task switching takes it's time. For a single bit transfer, IRQ should be disabled, like it's done in extmod/modonwire.c

MarioPL98 commented 11 months ago

Can't it be done by a timer? With stuff like stm32 you could just set a timer in PWM mode with output on some GPIO pin. I think that way it won't be necessary to disable irq, since it takes no cpu instructions.

robert-hh commented 11 months ago

You could implement bit write and bit read with the PIO, which also does not take CPU cycles.

MarioPL98 commented 11 months ago

Yes, that's the other alternative but it wouldn't be compatible with other microcontrollers. Do you think this method might work with micropython? Do you happen to know how long does setting up timer take in micropython? By that I mean the time from calling a function that sets up timer to the timer actually starting.

I've found this: https://github.com/microentropie/DS18B20 But I have yet to read it and I don't have that time now, will do it later.

robert-hh commented 11 months ago

The MicroPython timer has ms granularity, and only a few board can get to a timer callback event every 1 ms. So that's by far too slow for DS18B20, which requires µs timing, with switching to 1 latest after 15µs when writing a 1, and reading the value latest after 15µs. It is only a single bit which has this rigid timing demands. The time between bits can be longer.

The code you linked achieves short read times by reversing the order between the start sampling command and reading the value. I did similar once in a ADS1115 driver to get more time for other code to run. It does not increase the average sample rate, but avoids waiting for a result. Obviously that is not a good method if you sample very rarely, since the temperature can have changed between taking a measurement and reading the value. So that's good only for short sample intervals, like <1 minute.

MarioPL98 commented 11 months ago

You are right about the code, I've read it just now. There is one missing feature that my solution would need in order to work with rp2040. I can't find any info about using gpio for timer's clock or about chaining timers with hardware. Or using timer compare mode. I assume rp2040 doesn't support this. It seems that PIO is my only solution.