Go Down

Topic: 1-Wire Slave (Read 44123 times) previous topic - next topic

Adam84

Hi guys,
Can anyone give any guidance on using this library to make an Uno a 1-wire slave. I can get the "DS18B20_Slave_Interrupt_universal_analogread_fulllib.ino" example sketch to compile and upload fine by changing the  dsslavepin (does this number refer to the actual pin or the interrupt no.?) I have another arduino with another DS18B20 and using the wire library example to get the addresses of the devices on the bus i only find the actual DS18B20. Has anyone had it working on an Uno and knows where i'm going wrong?   

wongsm7

Hi Markus,

Does your library work with Arduino Uno?

Youen

#92
Aug 09, 2015, 10:44 am Last Edit: Aug 09, 2015, 10:46 am by Youen
I just released my library to make an Arduino board act as a 1-wire slave. You can download it here: https://github.com/neuoy/OneWireArduinoSlave

It's implemented using interrupts (everything is asynchronous, user code is notified by callbacks when bytes are received, etc.)

I've only tested it with an Arduino Uno and a DS9490R master (connected by USB to a laptop that acts as my home automation server). Works flawlessly so far in this setup, but let me know if you find bugs or can test it with other hardware setups (wether it works or not, I'm interested to know in both cases).

I was surprised how developing this kind of library is tricky, timings are sometimes as short as 3 microseconds or the master can miss bits, so debugging through Serial is not really an option, I acquired an USB oscilloscope for the occasion (very interesting project though).

/dev

Very nice!  It's great to see a real C++ design and clean implementation that's easy-to-read.  I've been helping someone over here, and had recently come to the conclusion that interrupts will have to be used for the exact reasons you state: 3us events.

As you said, this is definitely something that requires a 'scope or Logic Analyzer.  The nice thing about the 'scope is that you can distinguish between active highs, input mode and multiple devices driving low.  The user I am trying to help doesn't have either, and isn't very advanced in Arduino nor embedded techniques.  It has been slow going.

While I've been reluctant to dive in and implement this, I have started on something.  After looking at the timings and existing implementations, I was just starting to look at External Interrupts, Pin Change Interrupts and even the Input Capture.  So thanks a million for this very "timely" post.  ;)

Were you thinking about extending this to other types/numbers of 1-wire devices, or are you at the "good enough for me" stage?

BTW, have you seen Cosa?  There are a few stylistic similarities, and I mean that as a compliment.

Cheers,
/dev

Youen

Nice to see it can be useful to others :-)

Right now, it is indeed in a "good enough for me" stage. The goal was to provide a low level implementation only, because high level considerations (emulating specific devices such as temperature sensors or whatever) have a much larger scope, beyond what I can provide and support as a hobby, and also these are (somewhat) less difficult problems to solve. But it's open source, so anyone can expand on it. Also, that doesn't mean I won't try to fix the bugs that are reported, if any :-)

I didn't heard of Cosa, but it seems interesting, I'll take a look, thanks.

About timing issues, I also tried with an active wait, and it was just a little bit slower, but I think it can work too. However, you really have to use 100% of the CPU to do just that, poll the pin state in a loop, and pull low as soon as you detect the edge (so you need to know if you're going to pull low before starting the loop, to avoid too many instructions in between). So in my experience, interrupts are indeed more adequate to the task (a bit faster, and also less risk to miss an edge since the edge detection is hardware). Not sure how all these things will work (or not) on other boards though.

milimilo

Hello Youen

Thank you very much for your lib.

My project is this one, and of course doesn't work:
I have an home automation zwave device that can read DS18B20 1Wire sensors. I would like to use my Arduino UNO to send some value through this zwave module.

May you give me a simple example of code that sends a value when pressing a simple button?

I'm blocked trying to give your library a value to send (using your demo .ino ...).

Sorry for my completely noob question (i am really new to Arduino and totally off the computing universe) and thank you very much for your help!

ColinR

The example does not seem to compile for ATTiny85:

In file included from ATTiny1WireSlave.ino:2:0:
E:\Docs\code\avr\arduino projects\libraries\OneWireArduinoSlave/LowLevel.h: In member function 'void Pin::attachInterrupt(void (*)(), int)':
E:\Docs\code\avr\arduino projects\libraries\OneWireArduinoSlave/LowLevel.h:113:3: error: 'EIFR' was not declared in this scope
   EIFR |= (1 << INTF0); // clear any pending interrupt (we want to call the handler only for interrupts happending after it is attached)
   ^

ColinR

I've gone through and replaced the offending items using the ATTiny85 and ATMega328 datasheets, namely:

EIFR --> GIFR
TCCR1B --> TCCR0B
WGM12 --> WGM02
TIMSK1 --> TIMSK

There may have been one more.

I don't know enough about the register functions to know where I have not gotten this right, but I definitely do not have a functioning example at the moment. The Tiny doesn't take down the bus, and have another device on there for a sanity check, so the bus and adapter are up. Just no ATTiny slave.

Colin

ColinR

I have finally got ATTiny85's working as 1-wire slaves but not using Markus' library, I used a modified version of the one wire library from Alexander Gordeev . I finally succeeded once I discovered I could run the ATTiny85 at 16Mhz, that was the big breakthrough. 

I now have ATTiny85s as slaves for a rain gauge and another for a humidity sensor. I am using the  PinChange Interrupt Library so that the slaves only process one-wire commands once a One Wire Reset is detected. An LED flashes to provide visual feedback when the slave sends sensor data. Like the DS18B20 I use 0x44 as a request to calculate the sensor data and 0xBE to return the results.

<<snip>>

I could not get this to work. I had to all sorts of library moving, and eventually a type definition conflict with 'boolean'. I renamed all instances in the libraries to 'myboolean' and resolved the conflict, but still no device on the bus.

You did not mention how you set the clock to internal 16MHz. The typical ATTiny board profiles for the Arduino IDE do not have a 16MHz internal option. Instead, I set up the Adafruit Trinket 16MHz definition and enabled as described here: https://learn.adafruit.com/introducing-trinket/16mhz-vs-8mhz-clock

Still, no love.

Colin

milimilo

Would this project be possible? :

- a keypad identifies a user with a code
- the accepted user code is send through 1Wire (as a DS18B20) to a 1Wire receiver that can only read a DS18B20

All of this on an Arduino UNO.

Thank you for your help

Youen

Hello Youen

Thank you very much for your lib.

My project is this one, and of course doesn't work:
I have an home automation zwave device that can read DS18B20 1Wire sensors. I would like to use my Arduino UNO to send some value through this zwave module.

May you give me a simple example of code that sends a value when pressing a simple button?

I'm blocked trying to give your library a value to send (using your demo .ino ...).

Sorry for my completely noob question (i am really new to Arduino and totally off the computing universe) and thank you very much for your help!
If I understand correctly, the zwave thing does not matter here, things would be exactly the same if you wanted to talk to a classical 1-wire master?

So what you want to do is emulate a DS18B20 sensor. For that, you need to understand the specific protocol of this device, you can look at this document for example : http://www.adafruit.com/datasheets/DS18B20.pdf, check the section "DS18B20 FUNCTION COMMANDS"

For a very basic operation, you'll need to understand the temperature conversion command, and how to send the response (which happens after the "read scratchpad" command, two bytes of the scratchpad are used to transmit the temperature). However, if your zwave device, which acts as a master, always sends configuration, or performs other operations, you might need to implement that part of the protocol as well.

Once you understand the protocol, implementing it with my library should be straightforward : as in the sample, you initialize the library with the device ROM (which may or may not be an official ROM number, but must have the correct family code), and register the event callback. This callback is a function that you write yourself, and will be called each time something happens (a byte is received, an error occurs, etc.). Then you'll need to react to the various commands that can be sent to a DS18B20 ("begin temperature conversion" and "read scratchpad" being the most important).

Communicating with your development PC using the serial port of the Arduino should help you in the process of understanding what happens in your program (so that you can see what command you have received, etc.)

Go Up