Can't use two SPI devices at the same time - arduino

I can use the MFRC522 using the following code:
#include <SPI.h>
#include <MFRC522.h>
MFRC522 mfrc522(10, 9);
void setup() {
SPI.begin();
mfrc522.PCD_Init();
}
void loop() {
if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial() ) {
// Do stuff
}
}
And it works great. I can also use the dot-matrix (8x8) using the following code:
#include "LedControl.h"
LedControl lc = LedControl(12,11,8,1);
void setup() {
lc.shutdown(0,false);
lc.setIntensity(0,3);
lc.clearDisplay(0);
lc.setLed(0,2,5,true);
lc.setLed(0,5,5,true);
lc.setLed(0,2,2,true);
lc.setLed(0,3,1,true);
lc.setLed(0,4,1,true);
lc.setLed(0,5,2,true);
}
void loop() {
}
And it works just fine as well. However, when I try to use both of them using the following code:
#include <SPI.h>
#include <MFRC522.h>
#include "LedControl.h"
LedControl lc = LedControl(12,11,8,1);
MFRC522 mfrc522(10, 9);
void setup() {
SPI.begin();
mfrc522.PCD_Init();
lc.shutdown(0,false);
lc.setIntensity(0,3);
lc.clearDisplay(0);
lc.setLed(0,2,5,true);
lc.setLed(0,5,5,true);
lc.setLed(0,2,2,true);
lc.setLed(0,3,1,true);
lc.setLed(0,4,1,true);
lc.setLed(0,5,2,true);
}
void loop() {
if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial() ) {
// Do stuff
}
}
In that case only one of them works (the MFRC522). I know that since they are connected in SPI mode they need to have different SS pins, so I used pin 10 for MFRC522 and pin 8 for dot-matrix. So, what's wrong? Why dot-matrix doesn't work at the same code with MFRC522??

Without the datasheets at hand, I'd first suspect that the two SPI devices have clock rates that are incompatible. You need to find the clock rates for each one and either clock them off two different timers, or switch timing on a single timer to provide the correct clock rate for the currently selected device. Incompatible clock rates has been the only problem I've ever had with SPI devices.

Related

How to connect MAX30100 pulse sensor to a different i2c pins of ESP32 and read data?

I'm using a ESP32 30 pin board, MAX30100 pulse sensor for my project.
I can interface this sensor to ESP32's different i2c pins i.e. not default pins(21,22).
But I don't know how to read data from the MAX30100 if it connected to different pins - (Let's say 32, 33)
This is the program I used for default i2c pins to read data from MAX30100
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#define BLYNK_PRINT Serial
#include <Blynk.h>
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#define REPORTING_PERIOD_MS 1000
char auth[] = "*******************"; // You should get Auth Token in the Blynk App.
// Connections : SCL PIN - D1 , SDA PIN - D2 , INT PIN - D0
PulseOximeter pox;
float BPM, SpO2;
uint32_t tsLastReport = 0;
void onBeatDetected()
{
Serial.println("Beat Detected!");
}
void setup()
{
Serial.begin(115200);
pinMode(19, OUTPUT);
Blynk.begin(auth,"************", "**********");
Serial.print("Initializing Pulse Oximeter..");
if (!pox.begin()) {
Serial.println("FAILED");
for(;;);
}
else
{
Serial.println("SUCCESS");
pox.setOnBeatDetectedCallback(onBeatDetected);
}
// The default current for the IR LED is 50mA and it could be changed by uncommenting the following line.
pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
}
void loop()
{
pox.update();
Blynk.run();
BPM = pox.getHeartRate();
SpO2 = pox.getSpO2();
if (millis() - tsLastReport > REPORTING_PERIOD_MS)
{
Serial.print("Heart rate:");
Serial.print(BPM);
Serial.print(" bpm / SpO2:");
Serial.print(SpO2);
Serial.println(" %");
Blynk.virtualWrite(V3, BPM);
Blynk.virtualWrite(V4, SpO2);
tsLastReport = millis();
}
}
How do I interface MAX30100 to other pins? What should be the instructions?
PulseOximeter pox;
What does this instruction mean?
You should change direction in library:
Link to library file in github
Line 29: change that for
Wire.begin(SDA_PIN, SCL_PIN);
Where SDA_PIN and SCL_PIN are defines of your own routing.
NOTE: if you change the library you will need always to use that pins for all of your developments so maybe is better if you import that library locally or even better if you change library so if you don't pass any pin at argument it default normally I2C pins but, if defined use the defined ones.

How to use SPI with ESP32 and Arduino

I'm trying to send out data from SPI, but can't get it to work. There appear no data on the SPI ports (D12, 13, 14; checked with an oscilloscope) and the ESP32 seems to hang. I would like to use the HSPI port.
I am also wondering whether I need a special driver for SPI to work on ESP32 and if so, how can I check if I already have that and how do I install it. When I look in the library manager, I see no special SPI driver.
I have tried using this program (copied from https://diyi0t.com/spi-tutorial-for-arduino-and-esp8266/). It's apparently intended for esp8266. Should it work out of the box also for ESP32?
#include "SPI.h"
char buff[]="Hello Slave\n";
void setup() {
SPI.begin();
}
void loop() {
for(int i=0; i<sizeof buff; i++)
{
SPI.transfer(buff[i]);
}
delay(1000);
}
and also with this program:
#include "SPI.h"
char buff[]="Hello Slave\n";
SPIClass SPI1(HSPI);
void setup() {
SPI1.begin();
SPI1.setClockDivider(80);
}
void loop() {
for(int i=0; i<sizeof buff; i++)
{
SPI1.transfer(buff[i]);
}
delay(1000);
}
I am using a 30 pin ESP32 dev board, Arduino version 1.8.13. In preferences-->more board managers, it says:
http://arduino.esp8266.com/stable/package_esp8266com_index.json, https://dl.espressif.com/dl/package_esp32_index.json
For ESP32, you need to declare which SPI instance you want to use, like so:
#include <SPI.h>
SPIClass SPI1(HSPI);
SPI1.begin();
// Optional
// SPI1.beginTransaction(SPISettings(3000000, MSBFIRST, SPI_MODE2));
The rest is the same as ESP8266
#include <SPI.h>
#define HSPI_MISO 12
#define HSPI_MOSI 13
#define HSPI_SCLK 14
#define HSPI_CS 15
static const int spiClk = 240000000; // 1 MHz
SPIClass * hspi = NULL;
char buff[]="Hello Slave\n";
//byte buff[] = {0xAA, 0xBB, 0xAA, 0x01,
0x89, 0xAB, 0xCD, 0xEF};
void setup() {
Serial.begin(9600);
hspi = new SPIClass(HSPI);
hspi->begin();
hspi->begin(HSPI_SCLK, HSPI_MISO, HSPI_MOSI, HSPI_CS); //SCLK, MISO, MOSI, SS
pinMode(HSPI_CS, OUTPUT); //HSPI SS
}
void loop() {
for(int i=0; i<sizeof buff; i++)
{
SPI.transfer(buff[i]);
Serial.println(buff[i]);
}
delay(1000);
}
Assuming that you use the ESP32 Arduino Core, under the docs it is written that SPI is has a suppported Arduino API implementation. Thus using the Arduino SPI API, it should work, like all other devices (the ESP32 Arduino Core implementation conforms to the API defined by Arduino, of course I would check if your board's pinout corresponds to the Espressif defined ESP32 pinout).
If you want to see some examples, you can find one here. All supported APIs have examples on the ESP32 Arduino Core repo on GitHub.
I also want to point out that in the Arduino IDE (or the VSCode plugin) you can find examples for SPI, I would take a look as well for that.

ROSSerial fails to sync with teensy device on ROS Noetic

I am using teensy with rosserial + ROS Noetic/Ubuntu 20.04 on RASPI4. The teensy code is implemented with ros_lib on platformio (https://platformio.org/lib/show/5526/...). The program compiles fine and uploads successfully on port /dev/ttyACM0. However, when I do rosrun rossserial_python serial_node.py _port:=/dev/ttyACM0 _baud:=500000 then I get the sync failed error.
[ERROR] [1612795964.166906]: Unable to sync with device; possible link
problem or link software version mismatch such as hydro
rosserial_python with groovy Arduino.
Things I have already tried:
a) Setting correct baudrate in Serial.begin(500000)
b) Disabling all Serial.begin and Serial.print statements
c) Setting baudrate of ros node nh.gethardware()->setbaud(500000) before nh.init()
d) Increasing the default buffer size to 1024 in ros.h of ros_lib
typedef NodeHandle_<arduinohardware, 10,="" 10,="" 1024,="" 1024=""> NodeHandle;
e) Tried the Arduino board instead of Teensy and the problem still remain.
However, nothing has worked so far.
The default baud rate for rosserial is 56700. For changing it you will need to do the following
Modify the include statement in the arduino code from
#include <ros.h>
to
#include "ros.h"
Add the following header files alongside the .ino/.pde file
ros.h
#ifndef _ROS_H_
#define _ROS_H_
#include "ros/node_handle.h"
#include "ArduinoHardware.h"
namespace ros
{
typedef NodeHandle_<ArduinoHardware> NodeHandle;
}
#endif
ArduinoHardware.h
#ifndef ROS_ARDUINO_HARDWARE_H_
#define ROS_ARDUINO_HARDWARE_H_
#if ARDUINO>=100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#include <HardwareSerial.h>
#define SERIAL_CLASS HardwareSerial
class ArduinoHardware
{
public:
ArduinoHardware()
{
iostream = &Serial;
baud_ = 500000;
}
void setBaud(long baud)
{
this->baud_= baud;
}
int getBaud()
{
return baud_;
}
void init()
{
iostream->begin(baud_);
}
int read()
{
return iostream->read();
};
void write(uint8_t* data, int length)
{
for(int i=0; i<length; i++)
{
iostream->write(data[i]);
}
}
unsigned long time()
{
return millis();
}
protected:
SERIAL_CLASS* iostream;
long baud_;
};
#endif
In the ArduinoHeader.h file we defined above the iostream & the baud rate to be used is set using the constructor as shown below
ArduinoHardware()
{
iostream = &Serial;
baud_ = 500000;
}
as you are using teensy with USB the iostream will be Serial. If you are using the pins and not the USB it will vary from Serial1 to Serial8 as mentioned here. The baud rate of the teensy can be varied by varying the baud_ here set to 500000.
This code is referenced from Advanced Configuration for NodeHandle and ArduinoHardware

making arduino receive data from nRF24 (SPI and nRF libraries) while reading the serial port waiting for a data request using serialcommand

I am able to transfer data from one arduino to another using nRF24L01 chips. However, I need the data to be sent ONLY when a specific command is sent on the serial port. I want to be able to write 'A' on the serial port, and for arduino to reply with the latest data. This is easy with the serialcommand library and works if I am directly plugged in. However, the moment I add the nRF24L01 module, serialcommand.h does not respond with the data anymore. I tried even removing the if (radio.available()) .. so no data would be received and just the fact that there is radio.begin() in setup makes the serialcommand 'A' not work. when I remove the radio stuff, the command 'A' does reply with three zeros (default data).
Here is my receiver code. I still consider myself a beginner and i never formally studied C/C++. Any help or ideas as to why this happens is very appreciated!
.
#include <SoftwareSerial.h>
#include <SerialCommand.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
SerialCommand sCmd;
RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";
int Array[3];
void setup() {
Serial.begin(9600);
sCmd.addCommand("A", serialdataPrint );
radio.begin();
radio.setRetries(15, 15);
radio.openReadingPipe(0,address);
radio.setPALevel(RF24_PA_MIN);
radio.startListening();
}
void loop() {
while (Serial.available() > 0){
sCmd.readSerial();
if (radio.available()) {
int Array_received[3];
radio.read(&Array_received, sizeof(Array_received));
Array[0] = Array_received[0];
Array[1] = Array_received[1];
Array[2] = Array_received[2];
}
}
}
void serialdataPrint ()
{
Serial.println(Array[0]);
Serial.println(Array[1]);
Serial.println(Array[2]);
}

Error connecting an arduino and esp 32 via i2c

I'm having trouble connecting a esp32 with arduino pro mini 3v3. my code is the same arduino tutorial example. I use atom to code and when I open terminal serial write null message
Master code(Run ESP32)
#include <Wire.h>
int i=0;
char c[20
];
#include <Wire.h>
#define I2C_SDA_PIN 21
#define I2C_SCL_PIN 22
void setup() {
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
}
void loop() {
Wire.requestFrom(8, 1); // request 6 bytes from slave device #8
while (Wire.available()>0) { // slave may send less than requested
c[i]=Wire.read(); // receive a byte as character
i++;
Serial.print(c); // print the character
}
}
Run Arduino pro mini
#include <Wire.h>
void setup() {
Wire.begin(8); // join i2c bus with address #8
Wire.onRequest(requestEvent); // register event
}
void loop() {
delay(100);
}
// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
Wire.write('h'); // respond with message of 6 bytes
// as expected by master
}
I did an i2c bus address test and recognized the arduino:screenshot
I do not find anything about it, if anyone can help
p.s sorry for my poor english.

Resources