0

first StackOverflow question so hopefully its a decent one. I'm in the process of making a sensor network using RPi's and Arduino boards. I have done this in the past using Raspbian but now have to do it using Windows IOT.

The Arduino Uno boards are connected to the Raspberry Pi using I2C communication. The problem is that my C# code produces a "Slave address is not recognized" error.

The RPi is configured as a master and the Arduino as a slave. There is no logic voltage converter, but it should work fine in this configuration as per:

https://create.arduino.cc/projecthub/phantom_override/arduino-i2c-ommunication-with-raspi-2-wiot-63d599?ref=user&ref_id=11763&offset=0

Will use a bidirectional voltage converter when I can get my hands on one.

I have tried the following:

1.) I2C connection between Windows IOT and Arduino Nano using C# 2.) Checking the connections between the RPi and the Arduino (SDA to SDA and SCL to SCL 3.) Adding 3.3V pullup resistors 4) Raspberry pi 2 and BMP280 : Slave address was not acknowledged 5.) Changing the slave address of the Arduino 6.) Swapping the both the Arduino and RPi out in case the pins were blown 7.) Digitally writing the Arduino pins low in case they were interfering with the i2c commmunication

Here is the corresponding Arduino Code:

//**********************Libraries**********************
#include <Wire.h>

//*********************Definitions*********************
 #define SERIAL Serial
#define SLAVE_ADDRESS 0x40 

//********************Global Variables*******************
float humidity, temperature, temp, motion;

byte      ReceivedData[4];
byte      Response[4]; 
bool      DataReceived;


//Analoge Pin setup 
int clockFrequency = 100000;

//***********************************Setup******************************

void setup(){
      //digitalWrite(SCL, 0);
      //digitalWrite(SDA, 0);

      //i2c communication setup

      Wire.begin(SLAVE_ADDRESS);
      Wire.onReceive(receiveData);
      Wire.onRequest(sendData);
      //Wire.setClock(clockFrequency);

      //Baud rate
      Serial.begin(9600);

      dht.begin();  
}



//*********************************Loop*********************************
void loop()
{

  getSensors();  
  delay(100);

}

void getSensors() 
{

     //sensors data retrieved 

      Response[0]=(byte)humidity;
      Response[1]=(byte)temperature;
      Response[2]=(byte)proximity;
      Response[3]=(byte)motion;

}  

void sendData()
{

      Wire.beginTransmission(SLAVE_ADDRESS);

      //Loop to iterate i2c transmissions

      for (int i = 0; i <= 3; i++) { 
      Wire.write((uint8_t *)Response[i], sizeof(Response));
      }  

      Wire.endTransmission();
}

And here is the corresponding C# methods for the RPi

private async Task InitI2C()
        {
            var settings = new I2cConnectionSettings(0x40); // Arduino address
            settings.BusSpeed = I2cBusSpeed.StandardMode;
            string aqs = I2cDevice.GetDeviceSelector("I2C1");
            var dis = await DeviceInformation.FindAllAsync(aqs);
            _device = await I2cDevice.FromIdAsync(dis[0].Id, settings);

        } 

 private async Task GetArduino()
        {
            try
            {
                byte[] ReadBuf = new byte[32];
                _device.Read(ReadBuf);

                //convert buffer into floats here

            }

Any help would be greatly appreciated as WIOT resources are quite scarce compared to other IOT OS's.

Per Salmi
  • 1,398
  • 1
  • 14
  • 28
  • I would start by checking device manager to see if a USB device is installed. This will indicate if the issue is on the Adrino or the c# code. Make sure you are setup for USB and the device is Adrino is powered. – jdweng Dec 07 '19 at 14:15
  • Thank you for your reply. I have checked the Arduino by using Serial.print statements in my Arduino code and have received the sensor values – Michael Noyce Dec 07 '19 at 17:29
  • Is it working? You need to make sure the Window IOT recognizes the Arduino outside the c# code before you can determine if the code is bad. – jdweng Dec 08 '19 at 13:56
  • Which build of Window IoT Core did you test the code on? @MichaelNoyce – Michael Xu Dec 09 '19 at 03:31
  • @jdweng It still isn't working. I don't think it is recognizing the Arduino outside the code as I have tried to check through the online device portal. How would you check that the WIOT recognizes the Arduino outside of the code? – Michael Noyce Dec 09 '19 at 05:44
  • @MichaelXu-MSFT Thanks for joining. I am using Windows IOT core version 10.0.17763.107 and the target version on the Visual Studio is Windows 10 version 1809 (Build 17763). – Michael Noyce Dec 09 '19 at 06:00
  • See if this helps : http://watsoniotplatform-bitsnpieces.blogspot.com/2016/07/device-management-using-ibm-watson-iot.html – jdweng Dec 09 '19 at 06:18
  • @jdweng the link is interesting, but unfortunately the code is tied to Microsoft services – Michael Noyce Dec 09 '19 at 06:35
  • @MichaelNoyce, have you add lowLevelDevice capability(https://learn.microsoft.com/en-us/windows/uwp/packaging/app-capability-declarations) in your manifest? The lowLevelDevices Capability allows apps to access custom devices when a number of additional requirements are met. This capability should not be confused with the lowLevel device capability, which allows access to GPIO, I2C, SPI, and PWM devices. – Michael Xu Dec 09 '19 at 08:58
  • @MichaelXu-MSFT, I had the lowlevel device enabled in my manifest, I changed it to the lowlevelDevice capability and briefly had a clock stretching error instead of a 'slave address not acknowledged' error but I have not been able to replicate it since. I have tried swapping between the two and even deploying the code with both enabled and still get a 'slave address not acknowledged' error – Michael Noyce Dec 09 '19 at 09:36
  • You may try to refer to this topci(https://stackoverflow.com/questions/35368372/raspberry-pi-2-and-bmp280-slave-address-was-not-acknowledged). – Michael Xu Dec 10 '19 at 02:43

1 Answers1

0

@MichaelXu-MSFT and @jdweng Thank you for your help. I worked out the problem. The Arduino code had unnecessary wire.beginTransmission and wire.endTransmission statements, which seem to be for sending data from master to slave on i2c, whereas I had a configuration of the master device requesting data from the slave. Just using the wire.write(data, length) length function in the sendData() ISR did the trick. I highly recommend http://www.gammon.com.au/i2c, as he has excellent i2c resources on his site.

The correction is as follows:

void sendData()
{

      //Wire.beginTransmission(SLAVE_ADDRESS); remove this statement

      Wire.write(Response, sizeof(Response));

      //Wire.endTransmission(); remove this statement as well
}
  • It is normal. You don't start the transmission. You will answer to an open transmission. Just remember that you have to be fast when you reply to the RPi... If your ISR need too much time, the ATMega will stretch the clock and this is fatal for the most RPi (1 to 3) as the library can't handle it. – Adriano Dec 10 '19 at 16:59