3

Except hardware UART. Main requirements are reliability and simplicity of use. Speed isn't as important.

Details:

I have an Arduino Pro Mini (ATmega328P 5V) controlled via UART.
I wish to connect an ESP8266 with stripped-down NodeMCU to offer a web interface for the same functionalities, sending <=122 character strings to Arduino and possibly getting a short response.
I do not want to use Arduino for processing the interface (too little memory) or use the ESP only (need a stable clock and multiple analog inputs).

My research shows that:

  • ESP8266 has obvious timing issues, having been designed for a different purpose.
  • Controlling the ESP8266 from Arduino via hardware serial works fine, but I need it the other way around, too. Also, NodeMCU is rather chatty and I don't know how to suppress it, and I'd rather keep the hardware serial ports for programming.
  • The same via SoftwareSerial is unreliable
  • Personal experience shows OneWire works poorly on ESP8266 (though it may have been fixed)

I have no experience with I2C and SPI beyond polling a slave, and don't know about reliability on ESP8266.
The Arduino already works as an I2C master.
I'm assuming I2C is the way to go, but wanted to ask for opinions first.

[EDIT] Seems I have once again neglected to set up the proper context. The reason I'm asking is that ESP8266 can't do very precise timing, leading to communication problems. Hardware UART to hardware UART is shown to be reliable. For most other protocols, at least one side does bit-banging. I have not done or found extensive reliability tests for those options, and hope instead that the community can offer some insights. Can you?

  • I need it the other way around, too - can you clarify what that means? I'd rather keep the hardware serial ports for programming - maybe, but unplugging two wires every time you need to program isn't that bad, if it makes the whole setup work reliably. – Nick Gammon Jan 22 '16 at 9:52
  • I would suggest my ICSC library - I use it for communication between a NodeMCU and a PIC32 board. github.com/MajenkoLibraries/ICSC – Majenko Jan 22 '16 at 11:19
  • @nick-gammon Controlling the Arduino by sending serial commands from ESP8266. Would be fine if the latter didn't talk so much - errors and boot message... And programming: 2 jumpers are tolerable but won't help when I'm monitoring/debugging the whole setup. – kaay Jan 22 '16 at 15:29
  • @majenko Useful, so thanks, but I'm not seeing much relevance to the question itself. First arg in constructor is a serial interface, which means the choice I'm asking about had already been made. – kaay Jan 22 '16 at 15:34
  • I have a page about debugging with I2C and SPI which shows how you can debug if the serial ports are in use for other purposes. I also have pages about I2C and SPI if that helps. I'm not seeing much relevance to the question itself - I don't see a question, frankly. – Nick Gammon Jan 22 '16 at 19:06
2

So you are asking how to use an Arduino Pro Mini as a smart peripheral connected to a NodeMCU master, without making use of the hardware serial port on the latter.

In general, this is either going to operate slowly enough that you can guarantee reception, or you will need to use some kind of flow control or acknowledgement.

One question is whether the APM can always receive at any time, or whether it has to do things which would cause it to not respond for some while and possibly lose data.

Hardware I2c or SPI, with a software flow control protocol using additional pins, are probably your best bets if you cannot use async serial. For example the APM sets OK2SEND high when it's ready to receive (this is an APM output pin connected to a NodeMCU input pin). When NodeMCU detects this high, it writes to I2C and then sets HAVESENT high. When the APM detects & processes incoming data as I2C slave, it sets OK2SEND low. NodeMCU sees OK2SEND low (ack'ing the byte) and sets HAVESENT low. APM detects HAVESENT low which completes the handshake. When APM is ready for another byte, it sets OK2SEND high again. etc. Variants could send more than one byte per handshake, if performance needs that; APM asserting OK2SEND would be contracting to handle that number of bytes.

If you can guarantee that the APM will respond quickly enough to interrupts, you could use an interrupt driven I2C slave system on it, and simplify the above. The APM could be like a dedicated I2C peripheral, albeit a slow one.

  • APM uses Wire.onReceive() and onRequest() - works well. Thank you, for reminding me that other kinds of communication can take place aside from i2c - it was a D'OH! moment for me. – kaay Feb 27 '16 at 19:19
  • Just to clarify, though: I wrote the Arduino was already the i2c MASTER. I only switched it to slave later because afaik NodeMCU can't work as a slave. But I'd really like to keep the Arduino as master so I'd have direct access to the RTC module. – kaay Mar 4 '16 at 14:12
1

While possibly not "the best", I have found I2C to be sufficient for my needs.

Simple to use, if a bit different conceptually (master-slave).

My tests have shown it to be reliable thus far, zero errors over 20 minutes (sending & receiving 20 bytes each time), as long as there were sufficient pauses between calls.

I am going to make the Arduino switch its i2c master/slave role based on the state of other pins. Master most of the time (to use a DS1307 RTC, etc), switching to slave whenever NodeMCU (which can only work as master) has something to say. Thanks to Zeph for the idea.

  • Side note: You now that on i2c you can have multiple masters talking to each other? – Offler Jul 5 '16 at 6:50
  • @offler Yes, I do recall that. Haven't gotten the hang of it, though, especially with NodeMCU. I don't trust examples that make it look easy, got burned too many times. – kaay Jul 5 '16 at 10:14

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.