Communicate with secondary chip

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
SwimDude0614
Posts: 32
Joined: Mon Mar 10, 2014 1:32 am

Communicate with secondary chip

Post by SwimDude0614 » Tue Jul 18, 2017 4:26 am

I'd like to have two-way communication between my ESP8266 and a secondary chip (Parallax Propeller) which will be in charge of real-time work. I've been having a lot of fun with the ESP so far and testing various features, but the one thing I'm struggling to figure out is how my two chips will communicate. I was going under the assumption for a long time that I'd have a UART connection between the two, but that's looking unlikely given this enhancement request. So what is everyone else doing for this time of thing? Software UART? Some other protocol? The Propeller doesn't do synchronous slave protocols well which is why I was hoping for UART, but I'm open to other ideas.

I do have an I2C slave driver for the Propeller, so that might be one option.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Communicate with secondary chip

Post by pythoncoder » Tue Jul 18, 2017 5:13 am

SwimDude0614 wrote:...The Propeller doesn't do synchronous slave protocols well...

I do have an I2C slave driver for the Propeller, so that might be one option.
Those statements seem mutually incompatible: does the I2C slave mode driver work well in practice?

I encountered the same issue here https://github.com/peterhinch/micropython-mqtt.git. This uses an ESP8266 as a peripheral to bring MQTT to the Pyboard. I wanted the code on the Pyboard to be asynchronous and needed a communication link between the two boards. A UART was out for the usual ESP8266 reasons, and on the Pyboard slave mode protocols are blocking.

So I designed my own bit-banged protocol which is synchronous at the hardware level but uses asynchronous (non-blocking) code at each end. This works well, but inevitably it's not particularly fast. It is designed to be portable to any device running MicroPython so if you can cope with its speed and are happy with asynchronous programming see https://github.com/peterhinch/micropython-async.git. There is scope for speeding it up but my solution prioritises portability over speed.
Peter Hinch
Index to my micropython libraries.

SwimDude0614
Posts: 32
Joined: Mon Mar 10, 2014 1:32 am

Re: Communicate with secondary chip

Post by SwimDude0614 » Wed Jul 19, 2017 12:38 pm

Propeller only has 32kB of shared program/data storage, so micropython on that end is a no-go. I guess what I meant by "does not do ... well" was "can't handle high speed". But I guess, like all things related to performance, I should probably start with what's easy (using that I2C driver I have) and handle the problem of speed later, if and only if it actually arises. Thanks for your link to the micropython-mqtt library though. Looks cool :)

SwimDude0614
Posts: 32
Joined: Mon Mar 10, 2014 1:32 am

Re: Communicate with secondary chip

Post by SwimDude0614 » Mon Aug 07, 2017 2:42 am

Okay... this has been an interesting day of messing around with I2C. I'm guessing the problem is that I have two bit-banged I2C routines, neither one matches specifications perfectly, and together they're doing terrible things to each other.

Setup

Broken:
Parallax Propeller running a bit-banged I2C slave @ address = 42
ESP8266 running machine.I2C @ 100 kHz with this code in main.py:

Code: Select all

def send(bus, address, message):
    ret = 0
    tries = 0
    while ret != len(message):
        try:
            tries += 1
            ret = bus.writeto(address, message.encode())
        except:
            pass
    return tries
    

if '__main__' == __name__:
    i2c = machine.I2C(scl=machine.Pin(13), sda=machine.Pin(12), freq=100000)
    # send(i2c, 42, 'Hello, world!') is invoked from WebREPL
Less broken:
Parallax Propeller running a bit-banged I2C slave @ address = 42
Arduino Leonardo running "Wire" class with this software:

Code: Select all

#include <Wire.h>
 
 
void setup()
{
  Wire.begin();
 
  Serial.begin(9600);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}


unsigned int send () {
  byte error;
  unsigned int attempts = 0;

  do {
    Wire.beginTransmission(42);
    Wire.write("Hello, world!");
    error = Wire.endTransmission();
    ++attempts;
  } while (error);

  return attempts;
}
 
void loop()
{
  byte error, address;
  int nDevices;
  char c;
 
  Serial.print(send());
  Serial.println(" number of tries required.");

  delay(1);
}
Problem

The ESP8266 seems to be having some trouble writing the address once in a while. When that happens, the whole comm chain breaks down into chaos. Here's the beginning of a large capture:
esp8266_to_prop.png
esp8266_to_prop.png (128.48 KiB) Viewed 4705 times
You can see it starts out doing well until the Propeller hiccups and throws a NAK, but then something really bad happens in the second attempt. The address is all screwy, with one of the bits being just a blip instead of a full period.
Here's a snippet from the middle of the capture:
esp8266_to_prop_super_busted.png
esp8266_to_prop_super_busted.png (124.99 KiB) Viewed 4705 times
So the stop bit is missing, causing the whole protocol to degrade and now my logic analyzer has no idea what's going on. Who knows if the Propeller and ESP8266 are interpreting SDA in the same way as the LA at this point.

The Propeller's slave software clearly is not perfect, as evidenced by the first NAK in the first picture. However, it gives that same behavior when controlled by the Arduino, but without the eratic behavior. For instance, here's the first few lines of output from the Arduino serial terminal:

Code: Select all

I2C Scanner
2 number of tries required.
1 number of tries required.
11 number of tries required.
1 number of tries required.
2 number of tries required.
6 number of tries required.
1 number of tries required.
8 number of tries required.
8 number of tries required.
6 number of tries required.
Okay, clearly the Prop software isn't perfect. But here's what part of the capture looks like:
arduino_to_prop.png
arduino_to_prop.png (109.87 KiB) Viewed 4705 times
We can see the Prop still throwing NAKs for no good reason, but behavior is reasonable. The master retries the write routine again (correctly) and eventually succeeds.


So where do I go from here? Has anyone else seen this kind of behavior from the ESP8266?

I've given up on high-speed comms. I'd be satisfied if I could just get 9600 baud unidirectional serial working at this point!

SwimDude0614
Posts: 32
Joined: Mon Mar 10, 2014 1:32 am

Re: Communicate with secondary chip

Post by SwimDude0614 » Mon Aug 07, 2017 2:44 am

Trying to figure out how to get full-res copies of the photos... I'll try attaching them non inline.

Edit...
That doesn't seem to have worked either. Here they are on my website:

https://david.zemon.name/downloads/esp8266_to_prop.png
https://david.zemon.name/downloads/esp8 ... busted.png
https://david.zemon.name/downloads/arduino_to_prop.png
Attachments
esp8266_to_prop_super_busted.png
esp8266_to_prop_super_busted.png (124.99 KiB) Viewed 4705 times
esp8266_to_prop.png
esp8266_to_prop.png (128.48 KiB) Viewed 4705 times
arduino_to_prop.png
arduino_to_prop.png (109.87 KiB) Viewed 4705 times

Post Reply