Search code examples
arduinoraspberry-pii2cwindows-10-iot-core

Sending a JSON String via I2C between Arduino and RPi IOT C#


I'm trying to send a JSON String via I2C from an Arduino Uno to a RaspPi running Win IOT Core.

The connection works fine, I've registered an event handler on the Arduino side which is called fine when the master (rpi) requests data.

void I2CRequest()
{
  Serial.println("I2C Request received");
 /*Send data to WinIoT */

 int bt = Wire.write(lastJSON.c_str());
 Serial.println(lastJSON);
 Serial.print("Send bytes: ");
 Serial.println(bt);
}

The output on the Serial Monitor looks also fine...

I2C Request received
{"Sensor":"OneWire","data":["28ffc8675216451",23.9375,"28ff9feb521645e",24.0625]}
Send bytes: 81

The C# method on the RPi looks like this:

public static async Task<byte[]> GetI2CTemperatures()
    {
        var ReceivedData = new byte[1024];

        /* Arduino Nano's I2C SLAVE address */
        int SlaveAddress = 64;              // 0x40

        try
        {
            // Initialize I2C
            var Settings = new I2cConnectionSettings(SlaveAddress);
            Settings.BusSpeed = I2cBusSpeed.StandardMode;

            if (AQS == null || DIS == null)
            {
                AQS = I2cDevice.GetDeviceSelector("I2C1");
                DIS = await DeviceInformation.FindAllAsync(AQS);
            }


            using (I2cDevice Device = await I2cDevice.FromIdAsync(DIS[0].Id, Settings))
            {
                if (Device==null)
                {
                    Debug.Write("No access to I2C Device");
                }


                /* Read from Arduino  */
                Device.Read(ReceivedData);
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine("Exception occurred on reading I2C",ex);
            // SUPPRESS ANY ERROR
        }

        /* Return received data or ZERO on error */
        return ReceivedData;
    }
}

Unfortunately whatever I do, I just get as a result in ReceivedData a 00 as the first byte followed by FFs.
I've tried also Device.ReadPartial() instead of Device.Read() with the same result.

Can anybody point me into the right direction what I'm doing wrong?


Solution

  • The write() command on the Arduino platform only writes a single byte. You are attempting to write the entire string in a single command. You will need to loop through the array and send each byte separately.

    However, as soon as you do this, you will run into the 32-byte buffer limitation. It is possible to increase the buffer to 64 bytes, but this is the limit on the Uno (Atmel 328).

    I put some code together to show how to setup a relationship between the Uno and the Raspberry Pi that can transfer a JSON string of varying sizes. The code is in GitHub at https://github.com/porrey/i2c.

    If you want to see more ways to use I2C to communicate between an Arduino and a Raspberry Pi running Windows IoT Core see my Hackster projects at https://www.hackster.io/porrey:

    • Bridging the Raspberry Pi and the Arduino
    • DHT Tiny Breakout for the Raspberry Pi
    • Discover i2c Devices on the Raspberry Pi