ISP conflict on Raspberry Pi/Arduino SPI communication - arduino

I'm working on a communication between a Raspberry Pi 3+ and an Arduino Nano. The Raspberry uses ISP pins to program the Arduino. After, both should communicate in full-duplex via SPI protocol, using the WiringPi library under Qt environment. The problem is that SPI only returns 0 on both slave and master side.
Is it possible that the ISP programmer enter in conflict with the SPI protocol, even if not used at the same time?
Master code:
GpioMachine::GpioMachine(QObject *parent) :
QObject(parent){
wiringPiSetupGpio();
wiringPiSPISetup(0,1000000);
pinMode(CE0_PIN,OUTPUT);
}
void GpioMachine::sendSPI(int channel, int cmd,int arg)
{// send 2 bytes to slave
unsigned char buffer[2];
buffer[0]=cmd;
buffer[1]=arg;
wiringPiSPIDataRW(channel,buffer,2);
int val;
val=QChar(buffer[0]).toLatin1();
int val2;
val2=QChar(buffer[1]).toLatin1();
qDebug()<<"spi get:"<<val<<val2;
}
Slave code:
#include <SPI.h>
#include "pins_arduino.h"
// SPI interrupt routine
ISR (SPI_STC_vect)
{
byte c=SPDR;
Serial.println(c);
SPDR=5;// random testing value to send to master;
}
void setup()
{
Serial.begin(9600);
pinMode(MISO, OUTPUT);
pinMode(SS,INPUT);
// turn on SPI in slave mode
SPCR |= _BV(SPE);
SPI.attachInterrupt();
}
void loop()
{
delay(10);
}
Both codes gives only zeros. Any Idea?

Related

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.

SMS notification not working with Arduino Nano with a GSM module

I want to use an Arduino Nano to monitor SMS traffic of a GSM module. I'm able to read and send SMS but the notification system is not working: when I send an SMS (to the SIM card that is in the GSM module) no new data becomes available in the Serial port. Any idea why or how can I debug to find the problem?
The communication is done through pins 9 and 10 of Arduino and RX and TX for the GSM module, which is an Quectel EC25. The code I'm using:
#include <SoftwareSerial.h>
#define DEBUG Serial
SoftwareSerial EC25(10,9); // RX, TX - 9600 baud rate
// pin 8 of raspi -> pin 9 of arduino nano
// pin 10 of raspi -> pin 10 of arduino nano
#define AT_RESPONSE_LEN 100
#define TIMEOUT 1000
void setup() {
// put your setup code here, to run once:
EC25.begin(9600);
DEBUG.begin(9600);
// some AT commands just to see if the coms are ok
sendATComm("AT","OK\r\n");
sendATComm("AT+IPR?","OK\r\n");
sendATComm("AT+CGSN","OK\r\n");
sendATComm("AT+CNMI=2,1,0,0,0","OK\r\n");
DEBUG.println("listennig");
}
void loop() {
// put your main code here, to run repeatedly:
if (EC25.available()){
DEBUG.println("Notification received!");
}
}
// function for sending at command.
const char* sendATComm(const char *command, const char *desired_reponse)
{
uint32_t timer;
char response[AT_RESPONSE_LEN]; // module response for AT commands.
memset(response, 0 , AT_RESPONSE_LEN);
EC25.flush();
sendATCommOnce(command);
timer = millis();
while(true){
if(millis()-timer > TIMEOUT){
sendATCommOnce(command);
timer = millis();
}
char c;
int i = 0;
while(EC25.available()){
c = EC25.read();
DEBUG.write(c);
response[i++]=c;
delay(2);
}
if(strstr(response, desired_reponse)){
return response;
memset(response, 0 , strlen(response));
break;
}
}
}
// send at comamand to module
void sendATCommOnce(const char *comm)
{
EC25.print(comm);
EC25.print("\r");
delay(100);
}
So, it turns out that I had to define the output port of URC to use UART communication (not using it as default).
The default configuration was set to either usbat or usbmodem, meaning that the notification information I was waiting for was being sent to one of these serial ports. But I was listening to UART (through RX and TX pints) and therefore I was not getting any notification.
AT command QURCCFG can be used to set which port URC signals should be sent to. In this case I want them to be sent to UART:
AT+QURCCFG="urcport","uart1"

Android Things to Arduino using I2C - error 6: No such device or address

I try to connect an NXP i.MX7D running Android Things to a Arduino UNO using I2C. The slave code is fairly simple :
#include <Wire.h>
void setup() {
Wire.begin(0x08); // 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("hello "); // respond with message of 6 bytes
// as expected by master
}
The two devices are connected like this:
NPX SDA Pin ---> 3.3v level converter 5v ----> Arduino PIN A4
NPX SCL Pin ---> 3.3v level converter 5v ----> Arduino PIN A5
When I use the PIO tool I can't seem to connect or read the Arduino slave. There is two BUS (I2C1, I2C2) on the NPX I tried both with the same result:
imx7d_pico:/ $ pio i2c I2C1 0x08 read-reg-byte 0x00
[WARNING:client_errors.cc(35)] error 6: No such device or address
6|imx7d_pico:/ $ pio i2c I2C2 0x08 read-reg-byte 0x00
[WARNING:client_errors.cc(35)] error 6: No such device or address
I assume the level converter work properly I did have limited success with UART connection (Arduino was able to emit to NPX but not NPX to Arduino, will investigate this after)
Here are some pictures of the connection.
Try to add on Wire.onReceive callback(together with onRequest) to your arduino code.
Like this:
#include <Wire.h>
void setup() {
Wire.begin(8); // join i2c bus with address #8
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600); // start serial for output
}
void loop() {
delay(100);
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
while (1 < Wire.available()) { // loop through all but the last
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
int x = Wire.read(); // receive byte as an integer
Serial.println(x); // print the integer
}

ESP8266 to ESP8266 i2C Communication

I am trying to get my ESP8266's connect and send messages over an i2c bus. I am using a NodeMcu Development Board. Pins D1,D2 and GND are connected to each other.
The code on my master is :
#include <Wire.h>
void setup() {
Wire.begin(D1,D2); // join i2c bus (address optional for master)
Serial.begin(115200);
}
byte x = 0;
void loop() {
Wire.beginTransmission(8);
Wire.write(x); // sends one byte
Wire.endTransmission(); // stop transmitting
Serial.println("Transmitted");
x++;
delay(500);
}
And the code on my slave ESP is:
#include <Wire.h>
void setup() {
Wire.begin(8); // join i2c bus with address #8
Wire.onReceive(receiveEvent); // register event
Serial.begin(115200); // start serial for output
}
void loop() {
delay(100);
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
Serial.println("Received..");
/*
while (1 < Wire.available()) { // loop through all but the last
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
*/
int x = Wire.read(); // receive byte as an integer
Serial.println(x); // print the integer
}
Running this gives no output on the receiver chip.
As mentioned in the comments it doesn't look like I2C is supported, but you could use PJON
You just need to connect a single wire to enable communication between the two devices
I'm not sure but I would expect the Wire library from Arduino to use the hardware I2C controller for ATMega. The I2C driver in the firmware from Espressif seems to be doing I2C over GPIO, that would hint there is no hw controller on ESP (what are the odds they would be the same anyway). So you need to use something else than Wire.h, thus I would suggest - try downloading something that fakes I2C over GPIO for your Arduino IDE. Like this .. maybe, I haven't tried that out. I know not a complete solution, but maybe at least this helps.. good luck!
ESP8266(I2C Master) to ESP8266(I2C Slave) works from version 2.5.0. Check out my comments on the ESP8266 GitHub

Arduino Master - Slave setup

The master board is a Arduino Uno and the slave is a Arduino Yun. I have them both wired up using A4 & A5 of one board to attach to the A4 & A5 pin on the other. They are both powered separately but share the same ground like the diagram below.
The code for both master and slave are below. If the slave board is not powered the master knows it can not talk to the slave and won't print out Loop until the slave is powered. This suggests that the master knows of the slave.
However the slave never receives this signal from the master. receiveEvent is never called.
I am doing this as I have ran out of pins on the master and want the slave to control a LCD display that takes up several pins as I'm sure you all know.
Any help would be great, thanks.
Master
#include <Wire.h>
#define SLAVE_ADDRESS 0x9
void setup() {
Serial.begin(9600);
Wire.begin();
delay(1000);
}
void loop() {
Wire.beginTransmission(SLAVE_ADDRESS);
Wire.write('T');
Wire.endTransmission();
Serial.println("Loop");
delay(1000);
}
Slave
#include <Wire.h>
#define SLAVE_ADDRESS 0x9
void setup() {
Serial.begin(9600);
delay(1000);
Wire.begin(SLAVE_ADDRESS);
Wire.onReceive(receiveEvent);
Serial.println("Setup");
}
void loop() {
// Serial.println("Loop");
}
void receiveEvent(int howMany){
Serial.println("Receive event");
while (Wire.available() > 0)
{
char c = Wire.read();
Serial.println(c);
}
}
Maybe you should think about the wiring.
Your Yun is using a different layout see: http://forum.arduino.cc/index.php?topic=191974.0
If the UNO is a R3 layout you can use the pins above AREF as far as I know. Check the exact pin-out of your Arduino(s).

Resources