1

私は Raspberry と Arduino の世界ではかなり新しいものです (特に Windows IoT と一緒に)。私の計画は、Arduino でさまざまなセンサー (温度と圧力) を読み取り、その値を RP2 に送信して、GUI で使用できるようにすることです。

したがって、センサーを読み取ることは問題ではありません。正しい値を受け取ります。その後、I²C バスに送信します (Wire.h ライブラリの要件に基づく)。

私の RP2 では、2 つの同様のプロジェクトが見つかりました。C# のコードはそれらに基づいています。

ここまでは順調ですが、両方のデバイスを起動しても RP にデータがありません。私のRPはArduinoを見つけます。

問題を特定するために、ランダムな値を RP に送信するために Wire.h サンプル スケッチを使用しています。しかし、まだ同じ問題があるので、私の C# コードに問題があると思います。また、RP が値を配列に書き込む場所にブレークポイントを設定します。しかし、入ってくる値がないように見えます。

両方のコードを添付しました。誰かが私を助けてくれることを願っています。私はかなりひどい立ち往生しています...

どうもありがとうございました!ティエモ

Arduino コード:

#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; });

        }

    }
}
4

1 に答える 1

3

コードは両側で同期する必要があります。Arduino は I2C スレーブであり、RPi2 (Windows IoT) であるマスターからの要求に応じてのみバイトを送信できます。

Arduino スケッチに次のエラーがあります。

  • スレーブ デバイスはバス上で書き込み要求を開始できません (それに対するマスター要求を除く)
  • Windows IoT 側で有効な文字または文字列を解析するには、Arduino は有効な ASCII 形式でバイトを送信する必要があります。

基本的な Arduino スケッチと RPi2 UWP コードを添付します。

マスターから要求されたバイトで応答する 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 間のマスター/スレーブ通信について明確に理解してください。

さらに深く掘り下げるには、次のプロジェクトを参照してください。
Raspi 2 との Arduino I2C 通信 WIOT
Windows IoT (RPi2) - I2C 加速度計

于 2015-12-15T14:24:10.943 に答える