mikaelpatel / Arduino-OWI

One Wire Interface (OWI) library for Arduino
https://mikaelpatel.github.io/Arduino-OWI/
61 stars 15 forks source link

Individually Controlling Multiple Slaves Example #7

Closed sebmorales closed 5 years ago

sebmorales commented 5 years ago

Hi, Thank you for the library, I haven't found any other that works like this one.

I am trying to control a couple (3-10) of attiny85s (slaves) with an arduino (master). So far I am able to read and write data of all slaves at the same time but I can't address them individually.

Do you know how to do this? Could you share an example?

Thank you so much! Sebastian

mikaelpatel commented 5 years ago

This issue list is normally used for reporting bugs and adding feature requests. Your issue unfortunately does not seem to fall into these categories. In any case...

What sketch(es) are you using? How are you setting the ROM address? Could you explain how you are able to read data from all slaves at the same time? Is that data correct? Do all the slaves have the same ROM address?

Cheers! Mikael

mikaelpatel commented 5 years ago

To run multiple slaves (e.g. several instances of the example sketches) you will have to give them individual ROM addresses. "Random generation" will not work if they use the same sketch.

As an example you can run several physical DS18B20 together with an emulated slave version. But again, if you want to have several emulated version you will have to modify the example sketch and give them individual ROM addresses.

Cheers! Mikael

sebmorales commented 5 years ago

Thanks for your quick response, I apologize if this is not the right place for this request, please let me know where might be more appropriate.

I am using the:

I modified the library (Slave/OWI.h) to take a ROM parameter when creating the slave device, that way I every time I program a ATtiny85 I can assign it a unique ROM.

On the arduino (ATtiny85) slave/DS1820 side:

static const uint8_t ROM[] = {0x28, 0x38, 0x00, 0x18, 0x18, 0x10, 0x00, 0x10};
// Slave device one wire access; use random rom code
Slave::OWI<BOARD::D0> owi(ROM);
//Slave::OWI<BOARD::D0> owi(FAMILY_CODE);

And on the Slave/OWI.h file:

OWI(const uint8_t rom[]) : 
   m_timestamp(0),
   m_label(255),
   m_alarm(false)
  {
   uint8_t crc = 0;
   for (size_t i = 0; i < ROM_MAX - 1; i++) {
      m_rom[i] = rom[i];
      crc = crc_update(crc, rom[i]);
   }
   m_rom[ROM_MAX - 1] = crc;
   m_pin.open_drain();
}

Then on the arduino DS18B20 master side, reading will list the slaves (sometimes only one communicates back). If you change some value, fore example the triggers, then all slaves will update. image

I guess what I want to do next is able to select a slave to read/write to, while the rest of the slaves ignore the signals. Similar to the select method here. I found a match_rom function but I can't figure out how to use it.

Finally, I am using the DS18B20 examples as a base, but ultimately I just want to communicate form 1 arduino to multiple attinys using 1wire.

Any thoughts? Happy cybermonday!

Thanks! Sebastian

mikaelpatel commented 5 years ago

Thanks for including more information. That helped understand what you are asking about.

There is already a member function that allows assigning a ROM address. https://github.com/mikaelpatel/Arduino-OWI/blob/master/src/Slave/OWI.h#L47 The ROM address is stored in program memory. Below code in the slave sketch.

const uint8_t ROM[] PROGMEM = {DS18B20::FAMILY_CODE, ... }; 
Slave::OWI<BOARD::D7> owi(ROM);

By using the same ROM addresses in the master and the slaves you get what you are asking for. The example sketch you are using shows how to use the search function and enumerate the connected devices. Below code in the master sketch.

Software::OWI<BOARD::D7> owi;
const uint8_t ROM1[] PROGMEM = {DS18B20::FAMILY_CODE, ... }; 
DS18B20 sensor1(owi, ROM1);
const uint8_t ROM2[] PROGMEM = {DS18B20::FAMILY_CODE, ... }; 
DS18B20 sensor2(owi, ROM2);

The device instance (such as https://github.com/mikaelpatel/Arduino-OWI/blob/master/src/Driver/DS18B20.h#L56) will handle the access of the given physical device (aka slave).

If there is limited amount of dynamic memory (SRAM) you can use a single device instance and dynamically change the ROM address (see https://github.com/mikaelpatel/Arduino-OWI/blob/master/src/OWI.h#L303) to allow access of a set of physical devices with a single instance.

Software::OWI<BOARD::D7> owi;
const uint8_t ROM1[] PROGMEM = {DS18B20::FAMILY_CODE, ... }; 
const uint8_t ROM2[] PROGMEM = {DS18B20::FAMILY_CODE, ... }; 
DS18B20 sensor(owi);
...
sensor.rom_P(ROM1);
sensor.convert_request();
...
sensor.rom_P(ROM2);

Cheers! Mikael

sebmorales commented 5 years ago

ahh! thank you so much! This is exactly what I was looking for.