Seeed-Studio / OSHW-XIAO-Series

The Seeed Studio XIAO Series is a collection of thumb-sized, powerful microcontroller units (MCUs) tailor-made for space-conscious projects requiring high performance and wireless connectivity.
MIT License
14 stars 0 forks source link

Any XIAO SPI to any other XIAO #10

Open hpssjellis opened 2 months ago

hpssjellis commented 2 months ago

Any XIAO SPI to any other XIAO

Presently data is not moving between the boards.

@LynnL4

Background: The XIAO only has 10 pins most other boards have 20-40 pins. Many large projects need more pins, and a multiplexer is just another layer of confusion. Solution: Connect 2 or more XIAO together.

I have I2C and UART XIAO to XIAO communication working here

XIAO SPI works fine with other boards that need SPI like a XIAO to OLED etc, so the issue should not be with the receiver (Master) the issue is probably with the Transmitter (Slave).

Here is my semi-working code: I typically make code as simple as possible but have tried several ideas here to make things work. It is likely that I have missed some simple thing.

Slave (transmitter)

/*
Connect all wires the same on both XIAO's

GND      to GND
3V3      to 3V3
MOSI D10 to MOSI D10
MISO D9  to MISO D9
SCK  D8  to SCK  D8
SS  D0   to SS   D0

*/

#include <SPI.h>

// Note: XIAO-ESP32C3  SS is D7

#define SS D0         // Needed for XIAO-SAMD
const int mySS = SS;  // SS is D7 on XIAO-ESP

void setup() {
  pinMode(mySS, OUTPUT);
  digitalWrite(mySS, HIGH);
  SPI.begin();
  //SPI.setDataMode(SPI_MODE3); // Set the SPI mode to match the transmitter
  SPI.setClockDivider(SPI_CLOCK_DIV128); // Adjust the clock divider if necessary

}

void loop() {
  digitalWrite(mySS, LOW);
  // SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE0));
  SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0)); 
  SPI.transfer(200);
  SPI.endTransaction();
  digitalWrite(mySS, HIGH);
  delay(1000);
}

and the much longer Master (receiver) code:

/*
Connect all wires the same on both XIAO's

GND      to GND
3V3      to 3V3
MOSI D10 to MOSI D10
MISO D9  to MISO D9
SCK  D8  to SCK  D8
SS  D0   to SS   D0

*/

#include <SPI.h>

#define SS D0         // Needed for XIAO-SAMD
const int mySS = SS;  // SS is D7 on XIAO-ESP

volatile byte myReceivedData;

void setup() {
  pinMode(mySS, INPUT_PULLUP);
  SPI.begin();
  //SPI.setDataMode(SPI_MODE0); // Set the SPI mode to match the transmitter
  // SPI.setDataMode(SPI_MODE3); // Set the SPI mode to match the transmitter
  //SPI.setClockDivider(SPI_CLOCK_DIV8); // Adjust the clock divider if necessary
  SPI.setClockDivider(SPI_CLOCK_DIV128); // Adjust the clock divider if necessary
  Serial.begin(115200);
}

void loop() {

  if (digitalRead(mySS) == LOW) {
    delay(1);
    // SPI.beginTransaction(SPISettings(1000000, LSBFIRST, SPI_MODE0));
    SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0)); 
    myReceivedData = SPI.transfer(0); // Read data from the transmitter

    SPI.endTransaction();
    Serial.print("myReceivedData:");    
    Serial.println(myReceivedData);
    Serial.print("MOSI:"+String(MOSI) + ", MISO:"+String(MISO));
    Serial.println(", SCK:"+String(SCK)+", SS:"+String(SS));
    Serial.println("mySS:"+String(mySS) +", D0:"+String(D0) + ", D2:" + String(D2) + ", D4:" + String(D4) + ", D7:"+String(D7));
    Serial.println("SPI_MODE0:"+String(SPI_MODE0)+", SPI_CLOCK_DIV8:"+String(SPI_CLOCK_DIV8));
    Serial.println("----------------");
    delay(1);
  }
}

/*
 * SPI Data Mode: Determines the clock polarity (CPOL) and clock phase (CPHA). There are four possible modes:

SPI_MODE0 (CPOL = 0, CPHA = 0)
SPI_MODE1 (CPOL = 0, CPHA = 1)
SPI_MODE2 (CPOL = 1, CPHA = 0)
SPI_MODE3 (CPOL = 1, CPHA = 1)
Example: SPI.setDataMode(SPI_MODE0);

Clock Divider: Sets the SPI clock frequency relative to the system clock frequency. Possible dividers are:

SPI_CLOCK_DIV2
SPI_CLOCK_DIV4
SPI_CLOCK_DIV8
SPI_CLOCK_DIV16
SPI_CLOCK_DIV32
SPI_CLOCK_DIV64
SPI_CLOCK_DIV128
Example: SPI.setClockDivider(SPI_CLOCK_DIV8);

Bit Order: Defines whether the most significant bit (MSB) or least significant bit (LSB) is sent first.

MSBFIRST
LSBFIRST
Example: SPI.setBitOrder(MSBFIRST);

Clock Speed: Specifies the desired SPI clock frequency in Hz. This setting is used when more fine-grained control of the SPI clock frequency is required.

Example: SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0)); (where 1000000 is the clock speed in Hz)

DATA:

XIAO-ESP32C3
myReceivedData:255
MOSI:10, MISO:9, SCK:8, SS:2
mySS:2, D0:2, D2:4, D4:6, D7:20
SPI_MODE0:0, SPI_CLOCK_DIV8:4984833
----------------

XIAO-ESP32S3-Sense
myReceivedData:0
MOSI:9, MISO:8, SCK:7, SS:1
mySS:1, D0:1, D2:3, D4:5, D7:44
SPI_MODE0:0, SPI_CLOCK_DIV8:4984833
----------------

XIAO-SAMD

myReceivedData:255
MOSI:10, MISO:9, SCK:8, SS:0
mySS:0, D0:0, D2:2, D4:4, D7:7
SPI_MODE0:2, SPI_CLOCK_DIV8:12
----------------

From SPI.h
  // Default speed set to 4MHz, SPI mode set to MODE 0 and Bit order set to MSB first.
  SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); }

*/
hpssjellis commented 2 months ago

I found the esp32spiSlave library, which makes sense that the slave is not configured to send, but presently dont have it running.

limengdu commented 2 months ago

The idea of pin expansion via spi in series with multiple xiao is quite interesting. Maybe we'll verify it for you and export it as a wiki.

hpssjellis commented 2 months ago

The idea of pin expansion via spi in series with multiple xiao is quite interesting. Maybe we'll verify it for you and export it as a wiki.

@limengdu

On MBED an entire library is used for the SpiSlave https://os.mbed.com/docs/mbed-os/v6.16/apis/spislave.html It makes sense that MISO, MOSI, SCK will need to be set differently for the slave, and perhaps the spi.transfer function needs to work differently. I will continue to work on it, but if you can give me some suggestions that would be great.

I think Eric Pan knows that you are welcome to use any of my open source XIAO-ESP32S3-sense maker100-eco code on your wiki. Just credit both Jeremy Ellis and the TinyML4D community.

hpssjellis commented 2 months ago

@limengdu The following SPI slave code is different than my original and compiled and sent some data but still is not working. It is based on the idea that the SPIClass has functionality to work as a slave device, but it really needs to be an easier, better system.

I did find out that I need to plug the main usb device into the usb plug a few times before both XIAO's start properly. Kind of strange but might explain some earlier frustrations.


#define SS_PIN D0      // Slave Select pin
#define MOSI_PIN D10   // Master Out Slave In
#define MISO_PIN D9    // Master In Slave Out
#define SCK_PIN D8     // Serial Clock

//volatile byte myReceivedData;
volatile byte mySendingData;

void setup() {
  pinMode(SS_PIN, INPUT_PULLUP);  // Set SS pin as input with pull-up resistor
  SPI.begin(SCK_PIN, MISO_PIN, MOSI_PIN);  // Initialize as SPI slave

  // Attach interrupt to the SPI slave select pin
  attachInterrupt(digitalPinToInterrupt(SS_PIN), onReceive, FALLING);

  Serial.begin(115200); // Initialize serial communication for debugging
}

void loop() {

  Serial.print("Slave Sent: ");
  Serial.println(mySendingData, HEX);

  delay(1000);
}

void onReceive() {
  SPIClass *spi = &SPI;
  mySendingData = 3
  spi->transfer(mySendingData);
}
hpssjellis commented 2 months ago

Unless I learn something new, I am stuck. Nothing is consistent, even the library esp32spiSlave does not seem to work with the XIAO boards. Most Arduino systems only work for an old AVR method, the new MBED boards also don't seem to work. As far as I can tell putting the SPIClass into slave mode is the only issue, but I can't seem to get it working. Hopefully someone can have a look at this and make some suggestions.

limengdu commented 2 months ago

Thanks for the detailed description, I'll come back and look into your scenario after I've been busy with my latest business. We can discuss and study the details of it together.

hpssjellis commented 2 months ago

Found this repository that looks promising. I will try to test it later.

https://github.com/ramiss/SeeeduinoXIAO_SPISlave

limengdu commented 1 month ago

Already on the to-do list, following up.

hpssjellis commented 1 month ago

I have something kind of working from any XIAO to the XIAO-SAMD21 which has a good com module.

limengdu commented 1 month ago

I think my colleague will use two ESP32's XIAO to do SPI communication.

Jasionf commented 3 weeks ago

ESPSPI.zip this file is sample SPI communcation

hpssjellis commented 3 weeks ago

ESPSPI.zip this file is sample SPI communcation

@Jasionf which XIAO are you testing this on? Presently testing on XIAO-SAMD21 and not seeing the desired responses. I will try XIAO-esp32S3, but I am also interested in two way communication not just master to slave.

P.S. Pasting code here is a bit easier for us to discuss the code than attaching a .zip file.

Master

#include <SPI.h>

#define MISO D9
#define MOSI D10
#define SCK D8
#define chipSelectPin D2

void setup() {
  Serial.begin(115200);
  pinMode(chipSelectPin, OUTPUT);
  digitalWrite(chipSelectPin, HIGH); 

  SPI.begin();
}

void loop() {
  digitalWrite(chipSelectPin, LOW); 
  byte response = SPI.transfer(0x42); 
  digitalWrite(chipSelectPin, HIGH); 

  Serial.print("Response from slave: ");
  Serial.println(response, HEX);

  delay(1000);
}

slave

#include <SPI.h>

#define MISO D9
#define MOSI D10
#define SCK D8
#define chipSelectPin D2

void setup() {
  Serial.begin(115200);
  pinMode(chipSelectPin, INPUT_PULLUP); // Set CS pin as input

  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV16); // Set clock divider
  SPI.setDataMode(SPI_MODE0); // Set SPI mode
}

void loop() {
  if (digitalRead(chipSelectPin) == LOW) { // Check if selected
    byte received = SPI.transfer(0x00); // Dummy transfer to read data
    Serial.print("Received: ");
    Serial.println(received, HEX);
  }
}
Jasionf commented 2 weeks ago

ok , In the zip file , i write readme.txt in here , I have explained which Xiao series I am using for communication and what message I am sending , and i use D9 and D10 communcation , All the XIAO Series have the same SPI Pin ,D9 and D10 ,The sending and receiving functions provided inside can be used to implement device reading and writing ,

include

define MISO D9

define MOSI D10

define SCK D8

define chipSelectPin D2

void setup() { Serial.begin(115200); pinMode(chipSelectPin, OUTPUT); digitalWrite(chipSelectPin, HIGH);

SPI.begin(); }

void loop() {

/****send information part****/ digitalWrite(chipSelectPin, LOW); byte response = SPI.transfer(0x42); digitalWrite(chipSelectPin, HIGH);

Serial.print("Response from slave: "); Serial.println(response, HEX); /****send information part****/

delay(1000); }

include

define MISO D9

define MOSI D10

define SCK D8

define chipSelectPin D2

void setup() { Serial.begin(115200); pinMode(chipSelectPin, INPUT_PULLUP); // Set CS pin as input

SPI.begin(); SPI.setClockDivider(SPI_CLOCK_DIV16); // Set clock divider SPI.setDataMode(SPI_MODE0); // Set SPI mode }

void loop() {

/****receive information part****/ if (digitalRead(chipSelectPin) == LOW) { // Check if selected byte received = SPI.transfer(0x00); // Dummy transfer to read data Serial.print("Received: "); Serial.println(received, HEX); } /****receive information part****/ }

these code you can pack a function to use

hpssjellis commented 2 weeks ago

@Jasionf sorry about that I did not read your README.txt file in the zipped folder. It says

XIAO ESP32C6 as Master send information FF in Serial monitor
XIAO ESP32C3 as Slave receive information FF from Master in Serial monitor
I will check if I have the above boards. What I have found is this very simple code does not working for me with:

XIAO SAMD21 as Master send information FF in Serial monitor
XIAO SAMD21 as Slave receive information FF from Master in Serial monitor

XIAO ESP32S3 as Master send information FF in Serial monitor
XIAO ESP32S3 as Slave receive information FF from Master in Serial monitor

@Jasionf can you please post what your results look like from both serial monitors?

Jasionf commented 1 week ago

of course , here is slave receive informations 屏幕截图 2024-08-29 111550