Search code examples
c#arduinoraspberry-pii2cwindowsiot

Write data using I2C windows iot and Arduino


So I have a Arduino and Raspberry pi 3 with windows IoT connected as show in the image below: [enter image description here][1

I want to read from, and write to, the Arduino slave using the RPI as master with I2C. I have the following code so far:

C# Master:

private I2cDevice arduio; // Used to Connect to Arduino
private DispatcherTimer timer = new DispatcherTimer();

public MainPage()
{
    this.InitializeComponent();
    Initialiasecom();
}

public async void Initialiasecom()
{
    var settings = new I2cConnectionSettings(0x40); // Slave Address of Arduino Uno 
    settings.BusSpeed = I2cBusSpeed.FastMode; // this bus has 400Khz speed

    string aqs = I2cDevice.GetDeviceSelector("I2C1"); // This will return Advanced Query String which is used to select i2c device
    var dis = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(aqs);
    arduio = await I2cDevice.FromIdAsync(dis[0].Id, settings);

    timer.Tick += Timer_Tick; // We will create an event handler 
    timer.Interval = new TimeSpan(0, 0, 0, 0, 500); // Timer_Tick is executed every 500 milli second
    timer.Start();
}

private async void Timer_Tick(object sender, object e)
{
    byte[] response = new byte[2];
    byte[] request = new byte[] { 0x40, 0x40 };

    try
    {
        arduio.Read(response); // this funtion will request data from Arduino and read it
        arduio.Write(request); // this function will send data to Arduino
    }
    catch (Exception p)
    {
        //Windows.UI.Popups.MessageDialog msg = new Windows.UI.Popups.MessageDialog(p.Message);

        Debug.WriteLine(p.Message);

        //await msg.ShowAsync(); // this will show error message(if Any)
    }

    text.Text = response[0].ToString();
}

Slave Arduino:

include <Wire.h>
#define SLAVE_ADDRESS 0x40

byte response[1]; // this data is sent to PI

void setup() {
    Wire.begin(SLAVE_ADDRESS);                // join i2c bus with address slaveAddress
    Wire.onReceive(I2CReceived);
    Wire.onRequest(I2CRequest);
}

void loop() {
    delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void I2CRequest() {

    response[0] = (byte)17;
    Wire.write(response, 2); // return data to PI
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void I2CReceived(int howMany) {
    Serial.println("test");

    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
}

I can successfully read data from the Arduino and print them to the textblock on windows IoT. But I also want to write text to the Arduino. I tried something but it isn't working. Can someone please explain how to write data.

I really need some help and I'm no professional programmer so please keep it as simple as possible. If something is wrong with my current code please comment so I can try to improve my code.


Solution

  • I think the issue is due to the missing of Serial.begin,in fact the data sent from master to slaver has been received,just not printed.Please try again with the following code on slaver.

    #include <Wire.h>
    #define SLAVE_ADDRESS 0x40
    
    byte response[1]; // this data is sent to PI
    static int index = 0;
    
    void setup() {
        Serial.begin(9600); 
        Wire.begin(SLAVE_ADDRESS);                // join i2c bus with address         slaveAddress
        Wire.onReceive(I2CReceived);
        Wire.onRequest(I2CRequest);    
    }
    
    void loop() {
        delay(100);
    }
    
    // function that executes whenever data is requested by master
    // this function is registered as an event, see setup()
    void I2CRequest() {
        Serial.println("I2C-Request");
        response[0] = (byte) index ++ ;
        Wire.write(response, 2); // return data to PI
    }
    
    // function that executes whenever data is received from master
    // this function is registered as an event, see setup()
    void I2CReceived(int howMany) {
        Serial.println("I2C-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
    }
    

    I tested with my Arduino UNO,it works.The received data could be shown in serial monitor.

    enter image description here