Chat freely about anything...

User avatar
By KasaiMist
#76625 Hi!

I'm having a great deal of trouble getting the SPISlave example for ESP8266 on Arduino IDE to work with the Adafruit Feather HUZZAH ESP8266 board and a host microcontroller. I'm a newbie with SPI communication and low level hardware so I am completely lost with how to dig deeper and debug the problem.

My goal is to eventually send data quickly and consistently via SPI between a STM32F446RE master and a ESP-12S slave. But first, I simply want to get the example code working with an Arduino Due master and the HUZZAH, which features a ESP-12S embedded module.

-- HARDWARE --
Having made the following basic connections,
(DUE -> HUZZAH)
    MISO -> MISO
    MOSI -> MOSI
    SCK -> SCK
    Pin 10 -> Pin 15 (chip select)

(the spec sheet for the HUZZAH board is here)

-- SOFTWARE --
I am uploading the "SPISlave_Test.ino" provided example to the HUZZAH and the "SPISlave_SafeMaster" example to the Arduino Due. In accordance with previous forum suggestions, I have also added the following patch to setup() in "SPISlave_Test.ino":
Code: Select all// Additional setting to have MISO change on falling edge
    SPI1C2 |= 1 << SPIC2MISODM_S;


With the patch above, my master is receiving data correctly from the slave. However, that is not the case the other way around. More specifically:

In "SPISlave_SafeMaster.ino", the following is being sent:
Code: Select allvoid loop() {
  delay(1000);
  send("Are you alive?", 1);
}


The following variations (non-exclusive) are being received at the slave (as seen on Serial monitor):
Code: Select allQuestion: Are yo
or
Code: Select allQuestion: Are you
or
Code: Select allQuestion: Are
or
Code: Select allQuestion: A
or
Code: Select allQuestion: €
etc.

I tried printing both the data sent from the master and the data received at the slave in HEX.
From the master, I am sending the following 32 byte message:
Code: Select all41 72 65 20 79 6F 75 20 61 6C 69 76 65 3F 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

At the slave, that is not what is being received. For example for "Question: Are you", I am receiving:
Code: Select all41 72 65 20 79 6F 75 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 46 4C DD 64 D0 88 3C AD 19

It seems that the latter portion (an arbitrary number of 0s, followed by '46 4C DD 64 D0 88 3C AD 19') is always present. The first portion is never complete, and sometimes complete gibberish.

--
As mentioned earlier, I'm a complete newbie with this, and so I'm completely lost as to what next steps to take, particularly as it seems that this is the only example provided.

Where does the problem lie? And how can I fix it?

Any help would be greatly appreciated :)
User avatar
By KasaiMist
#76862 Since no one is replying, here is a follow up:

I implemented 2 separate SPI settings:
Code: Select all// For master -> slave
SPISettings settingsOUT(20000000, MSBFIRST, SPI_MODE1);
// For slave -> master
SPISettings settingsIN(20000000, MSBFIRST, SPI_MODE0);

With these settings, I then wrap all the "SPI.transfer()"s with the corresponding "SPI.beginTransaction(setting)" and "SPI.endTransaction()". This surprisingly fixes much of the problem.

However, one prominent issue with simply having a set of long male-to-male wire connections is the presence of signal reflection. I have set both clocks to 20MHz, and the accuracy of the data packet being sent is only around 40%. The slower the clock rate, the more accurate it is.

To improve this, I have added a pull-down resistor to the SCLK (i.e. SCLK -> high resistance resistor -> GND). SPI is now working at an accuracy of ~90%.

I am going to start transitioning to working with STM32F446RE instead of Arduino Mega. If anyone has any other suggestions or comments, please do update this thread. Cheers!
User avatar
By KasaiMist
#77000 -Further update-

So after further analysis, I've found the solution I gave in the previous reply is invalid. The main problem actually lies in two crucial problems: one in the hardware setup, and one in the firmware.

1. Both the host MCU and the ESP8266 slave MUST HAVE A COMMON GROUND. This is crucial, and something I foolishly did not do. Make sure there is a GND->GND connection.

2. Do NOT use 'sprintf()' as provided in the SPISlave_Test.ino example. Replace this with a simple for-loop to copy data byte by byte to the variable you desire (whether local or global). Though this may seem to run fine, it interferes with the execution of other WiFi functions for some reason (causing an Exception (9) and making the module randomly reset). I had encountered serious issues with configuring SPISlave with UDP (as demonstrated at http://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/udp-examples.html). This fixed the reset problems, and drastically increased the accuracy of SPI communication as well.

Hope this helps!

Cheers