JiriBilek / WiFiSpi

SPI library for Arduino AVR and STM32F1 to connect to ESP8266
GNU Lesser General Public License v3.0
62 stars 13 forks source link

Possible to run this on Arduino Due? #18

Closed fredlcore closed 3 years ago

fredlcore commented 3 years ago

This library looks like the perfect addition to our project, thanks for all the effort! Is it possible to run the code on the Arduino Due as well? Has anyone figured out the wiring for it yet? MISO, MOSI and SCK should be clear (SPI-4, SPI-1 and SPI-3 respectively), but for SS Master, there are three pins available (4, 10 and 52), which of the three should be used and how should I configure this? If someone already has figured out the (best) way to wire it, maybe the Due could also be added to the list on the main README.md? Thanks a lot again!

JiriBilek commented 3 years ago

Hi, I am convinced the library will run on Arduino Due. I have never tested the board but from the source (https://github.com/arduino/ArduinoCore-sam/blob/790ff2c852bf159787a9966bddee4d9f55352d15/variants/arduino_due_x/variant.h#L130), I think that the default SS is pin 10.

#define PIN_SPI_MOSI         (75u)
#define PIN_SPI_MISO         (74u)
#define PIN_SPI_SCK          (76u)
#define BOARD_SPI_SS0        (10u)
#define BOARD_SPI_SS1        (4u)
#define BOARD_SPI_SS2        (52u)
#define BOARD_SPI_SS3        PIN_SPI_SS3
#define BOARD_SPI_DEFAULT_SS BOARD_SPI_SS3

... ... ...

static const uint8_t SS   = BOARD_SPI_SS0;
static const uint8_t SS1  = BOARD_SPI_SS1;
static const uint8_t SS2  = BOARD_SPI_SS2;
static const uint8_t SS3  = BOARD_SPI_SS3;
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK  = PIN_SPI_SCK;

However, you can always initialize the SPI explicitly and then pass the SPI object to the initialization routine of WiFiSPIClass object. The initialization routine allows you to assign any free pin to the SS signal:

https://github.com/JiriBilek/WiFiSpi/blob/ec4a9d43e90cf87619a6242540a09baed13ea194/src/WiFiSpi.cpp#L49

Please let me know if the library is working for you.

fredlcore commented 3 years ago

Thanks, will do! One more question: Is this library only implementing the client side or is it also possible to use it as a server as well (similar to EthernetServer)? Since the Arduino is running as a webserver in my current project, I could only use it if the latter is also implemented. Or would I have to use a different library for that?

JiriBilek commented 3 years ago

The library implements server functions but you will have to use polling, no callbacks implemented.

fredlcore commented 3 years ago

Great, I only use .available(), so that should be fine! Will let you know my experiences here, hopefully soon!

fredlcore commented 3 years ago

Just to report back: At least the examples work fine on the Due :)! Tested with an orignal Due and a LoLin NodeMCU v3. The Due only provides SPI signals on the 6-pin header where other shields are also plugged in, so you have to make sure that any other shield routes these pins through. Furthermore, the power pin on the SPI header of the Due exports 5V and not 3.3V as one may think since the Due runs on 3.3V. So since the LoLin only accepts either 3.3V on the designated pins or more than 7V on VIN, you have to take the 3.3V from the designated pin on the Due, not the SPI pins. If you use a Wemos D1 mini which accepts 5V, this will be easier to handle.

Other than that, it's pretty straightforward, just connect the pins accordingly:

SPI-Due NodeMCU
1   D6
(2) (for boards that accept 5V input)
3   D5
4   D7
6   GND

Finally, just connect pin 10 (or whatever pin for SS you use) to D8 on the NodeMCU and you're done :)!

Thanks a lot again for this great library!

fredlcore commented 3 years ago

One last question: Is the D8<->SS connection always necessary? I just tried it without connecting the cable and it seems to work. In case the NodeMCU is the only SPI device, it would make designing a small adapter board much easier, as for example with the Wemos D1 mini, all necessary pins could be taken from the SPI header and one would not have to go all the way to the outer pin headers of the Arduino to connect to pin 10.

JiriBilek commented 3 years ago

Hi, thanks for the good news. As far as I can recall, I had troubles running without SS in high speeds of the SPI bus.

fredlcore commented 3 years ago

Ok, thanks! One (hopefully last) question: When I call WiFiSpi.localIP() right after the connection is established, I get the DHCP-assigned IP and can print it on the Serial port. If I call it a few lines later, I get these errors:

[espspi_proxy.h:300] W: Slave rx is not ready, status 0                         
[espspi_proxy.h:300] W: Slave rx is not ready, status 0                         
[espspi_proxy.h:329] W: Slave tx is not ready, status 0                         
[wifispi_drv.cpp:79] W: Error waitResponse   

and WiFiSpi.localIP() returns 0.0.0.0. Despite these errors, the WiFi works fine (and fast!) afterwards.

Note: I'm using pin 13 for SS as in WiFiSpi.init(13) because I also use the Ethernet shield still for its SD card functionality. The Ethernet Shield uses pin 10 for SS and is set up between the two localIP() calls, just in case that this would make any difference.

EDIT: The behaviour is not exactly reproducible, because sometimes after resetting or unplugging power of the Arduino, it's working fine. Sometimes the error also persists during runtime and prevents connecting to the Arduino/ESP via WiFi.

JiriBilek commented 3 years ago

This may be timing problem. The ESP8266 SPI implementation has issues. Try big delay (e.g. 40 us) here: https://github.com/JiriBilek/WiFiSpi/blob/ec4a9d43e90cf87619a6242540a09baed13ea194/src/utility/espspi_proxy.h#L107

fredlcore commented 3 years ago

It seemed to be a bit better, but not fixed. I then just added some seconds of delay after the WiFiSpi.begin() sequence and now it seems to run fine. Thanks a lot again!