Windows IOT 和 Arduino Nano 之间使用 C# 的 I2C 连接 [英] I2C connection between Windows IOT and Arduino Nano using C#

查看:21
本文介绍了Windows IOT 和 Arduino Nano 之间使用 C# 的 I2C 连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 Raspberry 和 Arduino 的世界还很陌生(尤其是与 Windows IoT 一起使用).我的计划是,用 Arduino 读出不同的传感器(温度和压力),然后将值发送到我的 RP2,我可以在 GUI 上使用它们.

I'm pretty new in the world of Raspberry and Arduino (especially together with Windows IoT). My plan is, to readout different sensors (temp and pressure) with the Arduino and then sending the values to my RP2 where I can use them on a GUI.

因此,读出传感器不是问题.我收到正确的值.之后我将它们发送到 I²C 总线(基于 Wire.h 库的要求).

So, it's not a problem to readout the sensors. I receive the correct values. Afterwards I'm sending them to the I²C bus (based on the requirements of the Wire.h lib).

对于我的 RP2,我发现了两个类似的项目,我的 C# 代码基于这些项目.

For my RP2 I found two similar projects and my code in C# is based on those.

到目前为止,一切都很好,但是当我启动两个设备时,我的 RP 上没有任何数据.我的 RP 找到了 Arduino.

So far, so good, but when I start both devices I don't get any data on my RP. My RP finds the Arduino.

为了定位问题,我使用 Wire.h 示例草图向我的 RP 发送随机值.但是还是有同样的问题,所以我猜我的C#代码有问题.我还在我的 RP 应该将值写入数组的地方设置了一个断点.但看起来,没有传入值.

To localize the problem I'm using a Wire.h sample sketch for sending random values to my RP. But there is still the same problem, so I guess there is a problem with my C# code. Also I set a breakpoint at place where my RP should write the values into a array. But it looks like, there are no incoming values.

我附上了两个代码.希望有人可以帮助我.我被困得很糟糕...

I attached both codes. Hope somebody can help me. I'm stuck pretty bad...

非常感谢!蒂莫

Arduino 代码:

Arduino code:

#include <Wire.h>
  #define SLAVE_ADDRESS 0x40


byte val = 0;
byte val_2 = 100;

void setup()
{
  Wire.begin(SLAVE_ADDRESS); // join i2c bus
  Serial.begin(9600);
}

void loop()
{
  Wire.beginTransmission(SLAVE_ADDRESS); // transmit to master device
                              // device address is specified in datasheet
  Wire.write(val);             // sends value byte  
  Wire.write (val_2);
 // Serial.write(val);
//  Serial.write(val_2);
  Wire.endTransmission();     // stop transmitting

  val++;        // increment value
  val_2++;
  if(val == 64) // if reached 64th position (max)
  {
    val = 0;    // start over from lowest value
  }

  if (val_2 == 164)
  {
    val = 100;  
  }
  delay(500);
}

C# 代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// i2c Libs
using Windows.Devices.Enumeration;
using Windows.Devices.I2c;
using System.Diagnostics;
using System.Threading;


// Die Vorlage "Leere Seite" ist unter http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 dokumentiert.

namespace _007_Test7_I2C
{
    /// <summary>
    /// Eine leere Seite, die eigenständig verwendet werden kann oder auf die innerhalb eines Rahmens navigiert werden kann.
    /// </summary>

    public sealed partial class MainPage : Page
    {

        private I2cDevice Device;
        private Timer periodicTimer;


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

        private async void initcomunica()

        {

            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);
            periodicTimer = new Timer(this.TimerCallback, null, 0, 1000); // Create a timer

        }

        private void TimerCallback(object state)
        {

            byte[] RegAddrBuf = new byte[] { 0x40 };
            byte[] ReadBuf = new byte[7];

            try
            {
                Device.Read(ReadBuf);
             //   Debug.WriteLine(ReadBuf);
            }
            catch (Exception f)
            {
                Debug.WriteLine(f.Message);
            }


            char[] cArray = System.Text.Encoding.UTF8.GetString(ReadBuf, 0, 7).ToCharArray();  // Converte  Byte to Char
            String c = new String(cArray);
            Debug.WriteLine(c);
            // refresh the screen, note Im using a textbock @ UI

            var task = this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            { Temp_2.Text = c; });

        }

    }
}

推荐答案

你的代码必须在两边同步.Arduino 是 I2C Slave,只能根据 RPi2 (Windows IoT) 主机的请求发送字节.

Your code must be synchronized on both side. Arduino is I2C Slave and can only send bytes on request by the master which is RPi2 (Windows IoT).

您的 Arduino Sketch 中存在以下错误:

There are following errors in your Arduino Sketch:

  • 从设备无法在总线上发起写请求(主设备除外)
  • 要在 Windows IoT 端解析有效的字符或字符串,Arduino 必须以有效的 ASCII 格式发送字节

我附上了基本的 Arduino Sketch 和 RPi2 UWP 代码:

I'm attaching basic Arduino Sketch and RPi2 UWP Code:

Arduino Sketch(I2C Slave)响应主机请求的一个字节:

#include <Wire.h>
#define MyAddress 0x40

byte DataToBeSend[1];
byte ReceivedData;

void setup()
{
    /* Initialize I2C Slave & assign call-back function 'onReceive' on 'I2CReceived'*/
    Wire.begin(MyAddress);
    Wire.onReceive(I2CReceived);
    Wire.onRequest(I2CRequest);
}

void loop()
{
    /* Increment DataToBeSend every second and make sure it ranges between 0 and 99 */
    DataToBeSend[0] = (DataToBeSend[0] >= 99) ? 0 : DataToBeSend[0] + 1;
    delay(1000);
}

/* This function will automatically be called when RPi2 sends data to this I2C slave */
void I2CReceived(int NumberOfBytes)
{
    /* WinIoT have sent data byte; read it */
    ReceivedData = Wire.read();
}

/* This function will automatically be called when RPi2 requests for data from this I2C slave */
void I2CRequest()
{
    /*Send data to WinIoT */
    Wire.write(DataToBeSend,1);
}

Windows IoT UWP - I2C 主代码片段:

using System;
using Windows.Devices.Enumeration;
using Windows.Devices.I2c;

namespace Windows_10_I2C_Demo
{
    public class I2cHelper
    {
        private static string AQS;
        private static DeviceInformationCollection DIS;

        public static async System.Threading.Tasks.Task<byte> WriteRead_OneByte(byte ByteToBeSend)
        {
            byte[] ReceivedData = new byte[1];

            /* 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))
                {
                    /* Send byte to Arduino Nano */
                    Device.Write(new byte[] { ByteToBeSend });

                    /* Read byte from Arduino Nano */
                    Device.Read(ReceivedData);
                }
            }
            catch (Exception)
            {
                // SUPPRESS ANY ERROR
            }

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

如何在 Windows IoT UWP - I2C Master Code Snippet 上面使用?

public async void TestFunction()
{
    byte DataToBeSend = 100;
    byte ReceivedData;
    ReceivedData = await I2cHelper.WriteRead_OneByte(DataToBeSend);
}


在继续之前,您应该对 I2C 通信有一个清晰的了解.请参阅以下文章以清楚了解 Arduino 之间的主从通信:http://www.instructables.com/id/I2C-between-Arduinos/?ALLSTEPS

要深入了解,请参考以下项目:
Arduino I2C 与 Raspi 2 WIOT 通信
Windows IoT (RPi2) - I2C 加速度计

To get into more deeper, refer following projects:
Arduino I2C communication with Raspi 2 WIOT
Windows IoT (RPi2) - I2C Accelerometer

这篇关于Windows IOT 和 Arduino Nano 之间使用 C# 的 I2C 连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆