简体   繁体   中英

How to connect 2 SPI devices to Arduino MkrZero

I am having a problem where I am unable to connect 2 SPI devices to my MkrZero. One device is a CAN shield and the other is an Ethernet Shield .

Both work fine on their own without the other connected but don't seem to work when both connected at the same time. This makes me think that my wiring and code is correct but something is still missing.

The CAN section initializes no matter what, execution seems to stop at the Ethernet code. But the Ethernet code works fine when the CAN wires are disconnected.

I have tried manually setting the CS pins, this doesn't do much. Even with both pins held high CAN starts up. This implies that the libraries take control of the pins.

I have read various tutorials on how to connect multiple devices with SPI but most times the devices are duplicates. My devices are different. I have connected the SPI pins exactly as I should with different CS pins for each device but the problem persists.

Here is my code

#include <CAN.h>              //https://github.com/sandeepmistry/arduino-CAN
#include <MCP2515.h>          //https://github.com/sandeepmistry/arduino-CAN Changes CS and Int pins from Uno to MkrZero configuration
#include <Ethernet.h>
#include <ArduinoJson.hpp>
#include <ArduinoJson.h>
#include <PubSubClient.h>
#include <Losant.h>
#include <SPI.h>

//Ethernet setup
#define MQTT_MAX_TRANSFER_SIZE 80  //this was done as a result of troubleshooting
byte mac[] = {  0x2C, 0xF7, 0xF1, 0x08, 0x19, 0x2C };
IPAddress ip (192, 168, 0, 1);
EthernetClient client;

// ** Configure the Losant credentials to enable comms over mqtt **
const char* LOSANT_DEVICE_ID = "";
const char* LOSANT_ACCESS_KEY = "";
const char* LOSANT_ACCESS_SECRET = "";
LosantDevice device(LOSANT_DEVICE_ID);

// The setup() function runs once each time the micro-controller starts
void setup()
{
  Serial.begin(9600);
  while(!Serial) {  }
  Serial.println("started UART");
  //pinMode(BUTTON_PIN, INPUT); 

  // disable SD SPI
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  //starting ethernet
  Ethernet.init(6); //changing Ethernet shield software select pin to 6 since default is an SPI transfer pin
  Serial.println("ethernet about to start");
  while(!Ethernet.begin(mac))  {}
  Serial.println("ethernet started");

  while (!CAN.begin(200E3)) {
    Serial.println("Starting CAN failed! ");
    delay(250);
  }
  Serial.println("CAN started");
  delay(100);   

Does anybody have any ideas on how to troubleshoot this or what the problem is?

There have been a few answers that involve not assuming the SPI bus has been kept the same from the last transaction. I need to reset SPI parameters each time I send a transaction. After going though the libraries I have seen that SPI.begintransaction() is called before every SPI communication, which according to my knowledge, resets the parameters. This implies that I don't need to manually change the SPI bus parameters before each transaction. Am I wrong in this regard?

SPI bus is really simple, and there should be no problem in connecting multiple slaves, as long as, at any time, only one of them has CS_ asserted (low). It can be expected that a library takes control of the CS_ pin, but it also should deassert it after the job is done. If not, then the library would be a very bad one.

You should check hardware and software.

Hardware: use a scope with memory, and look at what happens during initialization. May be that the CS_ pins need a pull-up resistor (the library, if it takes control of its CS_ pin, could choose to put it in high-impedance instead of driving it high). If you don't have a scope you can perhaps monitor the pins by software.

Software: may be the libraries use interrupts? In that case, the program can do things you are unaware of, for example a library can poll a device in background and mess with your code or one from another library. You have to dive deep in the libraries documentation and code. Again, a scope would help a lot.

You didn't specify much about your setup, and your tentative to "manually deselect the CS_ pins) is really worrying. You should check twice that point - if the CS_ pin is high, there is no reason the other SPI device does not work.

Problem was with the level shifter. I connected the OE enable pin to CAN CS, which puts the chip in high impedance when it isn't being used and enables it when I want to send data.

I used my scope to connect to the SPI pins and recorded what was happening. All was working well till I got to MISO. The level shifter was messing with it and pulling it to ground. Basically silencing output from one of the shields.

The learning here is when using level shifters with SPI devices connect the CS to OE.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM