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

查看:93
本文介绍了使用C#在Windows IOT和Arduino Nano之间进行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 lib的要求).

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从设备,只能根据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素描(I2C从设备),其响应主机请求按字节发送:

#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主代码段?

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

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

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

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

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