1
\$\begingroup\$

[edit: clarifying the question] Is it possible to see events on I2C slaves, or a functional equivalent?

I'm brainstorming a new project. I'm using an ESP-12F as a main logic board to control and receive input from various connected modules (e.g. pushbutton, beam sensor, solenoid valve, shutter trigger) Each module (slave) is PIC based, and communicates with the ESP-12 (master) using I2C. Sending commands for valves and triggers over I2C is straightforward. I'm not sure how to utilize I2C for slave-triggered momentary events though.

Should I just keep sending status requests to those modules and look for changes that way? I'm also considering using XOR logic to flip the level of another line, which I can detect via interrupt to trigger the status request.

My device is timing sensitive, I'd like to get a response to a trigger down to maybe 50-100 microseconds.

I'm new to all of this so feel free to correct me on anything fundamental I'm missing.

\$\endgroup\$
  • \$\begingroup\$ Please ask a question, people can't answer if they don't have a direct question to answer. electronics.stackexchange.com/help/how-to-answer This post seems mostly opinion based there are many ways to accomplish what you want to accomplish. Do you want the best way? \$\endgroup\$ – Voltage Spike May 3 '16 at 21:28
3
\$\begingroup\$

The terms of art here are Polling, i.e. repeatedly checking the sensor for changes, vs Interrupt, being alerted on demand of a change.

No, I2C does not provide an Interrupt protocol directly. A subset of I2C, called SMBUS, does. It has the SMBALERT#, which the Host device has a single Interrupt pin which all the slave devices can attach to, and when triggered, the Host will read from the special Alert Response Address (0001 100x), and any slave that has a pending alert will write it's specific address. The Host then reads directly from it. If more than one is pending an Alert, arbitration takes place, and the Host will need to read from the ARA multiple times.

Neat trick, you can skip the interrupt pin, and poll from the ARA anyway, and then only if you get a valid address do you try to read from the slave. This can cut down the number of times you try to poll, if you have multiple slave devices.

Of course, you can implement this on I2C quite easily, if you can program the slave devices and the host device.

Alternatively, you can make all the micro controllers masters and slaves, implementing an I2C Multi-Master setup. Have the modules become masters and write to your main device. Then your main device switches to master mode, to read back.

Or just leave your main device as a slave and have the modules as masters write to it on demand as needed.

\$\endgroup\$
  • \$\begingroup\$ Fantastic information, thank you! I'll take a good look into SMBUS. I had for a time considered using two I²C channels but the microcontrollers with two hardware I²C channels were more expensive, and I couldn't find much information on bit banging a slave device (just a lot of examples of master devices). I wasn't thinking about changing the device roles on a single channel though... Also, interesting idea on reversing the master/slave role. I don't think it will work in my requirements because my modules will be a mixture of input and output devices/sensors. \$\endgroup\$ – David Woods May 5 '16 at 1:29
3
\$\begingroup\$

The I2C bus per se doesn't have the ability for a slave to alert the master asynchronously.

You can poll the slave, if that fits your requirements (latency, for example).

You can add separate line(s) for slave devices to alert the master asynchronously. These lines would be out of band with respect to the I2C bus (not a part of the I2C bus itself). For an example, here's a bog-standard I2C I/O expander PCA9554, which has got an alert output.

\$\endgroup\$
  • \$\begingroup\$ Thanks, good to know my thinking was pretty much on track. Good link to the PCA9554 chip too. My modules will be connected serially via external contacts, so I'd like to get everything either through the I²C lines, or at most one other line that all modules can share. But now that I know about the parallel expanded that can definitely help me make some decisions, thanks! \$\endgroup\$ – David Woods May 5 '16 at 0:24
2
\$\begingroup\$

For a interrupt/request line, you wouldn't use XOR, as two simultaneous requests would cancel out. If you want to have a common interrupt/request line, use wired-OR: make the drivers open-drain with a pull-up (just like the I2C lines) fed to an active-low interrupt input on your MCU. This way, when any of your slaves pull this low, your master knows to poll everyone.

\$\endgroup\$
  • \$\begingroup\$ Good point! I hadn't thought about simultaneous events. Not that it's super likely, but it would have been painful to track down a hard-to-reproduce bug like that \$\endgroup\$ – David Woods May 5 '16 at 0:13
1
\$\begingroup\$

A chip like the PCF8575 provides I2C input and output expansion with built-in interrupt functionality.

\$\endgroup\$
  • \$\begingroup\$ Thanks, I haven't come across that one yet. I'll look into it! \$\endgroup\$ – David Woods May 5 '16 at 0:11

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.