使用I2c& amp;从Raspberry Pi向Arduino发送字节物联网用于PWM

时间:2016-05-25 09:33:02

标签: c# arduino raspberry-pi iot i2c

我对使用I2C和C#/ Windows IoT非常陌生,所以如果这是一个愚蠢的问题,请事先道歉。我有一个Raspberry Pi 3主和Arduino奴隶。我试图通过I2C从我的UI窗体上的滑块发送一个值到Arduino,我将用它来调整我的PWM占空比。我遇到了一些问题,如果它是Pi,Arduino或两者都可以解决。

这是我的Arduino Slave代码:

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

byte ReceivedData;
int pass;

void setup() {
    Wire.begin(MyAddress);
    Wire.onReceive(I2CReceived);
    Serial.begin(9600);
    //Wire.onRequest(I2CRequest);
}

void loop() {

    delay(100);
}

void I2CReceived(int NumberOfBytes)
{
    /* WinIoT have sent data byte; read it */
  byte ReceivedData = Wire.read();
  Serial.println(ReceivedData);
  if (ReceivedData <= 127){
      Serial.println("Equal or under");
      return;
  }else{
      Serial.println("over");
      return;
  }

}

我的Pi大师:

using System;
using Windows.Devices.Gpio;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Media;
using Windows.UI.Core;




using Windows.Devices.Enumeration;

using Windows.Devices.I2c;

using System.Diagnostics;

using System.Threading;

namespace I2COutput
{

    public sealed partial class MainPage : Page

    {


        private I2cDevice TransPump;

        private Timer periodicTimer;

        private const byte pump = 0x03;

        double pos;

        public MainPage()

        {

            InitializeComponent();

            initcomunica();

        }



        private async void initcomunica()

        {


            var pumpset = new I2cConnectionSettings(pump);


            pumpset.BusSpeed = I2cBusSpeed.StandardMode;

            string aqs = I2cDevice.GetDeviceSelector("I2C1");

            var dis = await DeviceInformation.FindAllAsync(aqs);


            TransPump = await I2cDevice.FromIdAsync(dis[0].Id, pumpset);


        }

        private async void SendChange()

        {
            byte[] sendpos;
            try
            {
               sendpos = BitConverter.GetBytes(pos);
                TransPump.Write(sendpos);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
            }

        }


        private void tempLbl_SelectionChanged(object sender, RoutedEventArgs e)
        {

        }

        private void slider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
        {

            pos = slider.Value;
            temp2Lbl.Text = pos.ToString();
            Convert.ToInt16(pos);
            SendChange();

            return;

        }
    }
}

我遇到的第一个问题是Arduino上的ReceivedData始终为0,无论sendpos在Pi上的值是什么(是的,当我移动滑块时它会改变)

我遇到的第二个问题是第一次移动滑块我得到了Arduino序列的输出,但之后没有任何内容。如果我重置或重新加载Arduino I,那么再次获得初始滑块的输出,之后没有任何内容。

道歉,如果其中任何一个过于模糊或解释不当,我们将非常感谢任何正确方向的帮助或推动。

提前致谢。

2 个答案:

答案 0 :(得分:0)

你必须改变&#34; Wire.onReceive(I2CReceived);&#34;循环,因为当它在设置中arduino exute只有一个,(对不起我的英语)

答案 1 :(得分:0)

我根据Nick Gammon Web Site为Arduino UNO编写了一个I2C从设备。 它工作但我不能超过10 K字节/秒。你自己的代码中有一些缺失部分。

这是Arduino代码的精简版

#include <Wire.h>

#define I2C_400K 1 // http://www.gammon.com.au/forum/?id=10896

bool receiveEventcommandReceived = false;
bool requestEventCommandReceived = false;

int _currentRequestInputParameterLen = 0;

void receiveEvent(int howMany) {

    receiveEventcommandReceived = true;
    while (Wire.available() > 0)
    {
        _cmd = Wire.read(); 

        if (_cmd == ArduinoCommand_EpromWrite) {
            // Some code
        }
        else if (_cmd == ArduinoCommand_EpromRead) {

            _addr0 = Wire.read();
            _addr1 = Wire.read();
            _addr  = (_addr0 * 256) + _addr1;
            _len   = Wire.read();
            _EEPROMBuffer = NusbioEx.EEPROMRead(_addr, _len);
            _r     = 128+1;
        }
        else {
            // Some code
        }
        _count++;
    }
}

void requestEvent()
{
    requestEventCommandReceived = true;

    if (_cmd == ArduinoCommand_EpromRead) {

        Wire.write(_EEPROMBuffer, strlen(_EEPROMBuffer));
    }
    else { // ArduinoCommand_EpromWrite or any other api

        int v1 = _r >> 8;
        int v2 = _r & 0xFF;

        char buffer[2];
        buffer[0] = v1;
        buffer[1] = v2;
        Wire.write(buffer, 2); // MUST BE SENT IN ONE BUFFER -> TO CREATE ONE I2C TRANSACTION
    }
}

void SetupI2C() {

    Wire.begin(I2C_SLAVE_ADDR);                // join i2c bus with address #4

    #if I2C_400K
        TWBR = 12; // http://www.gammon.com.au/forum/?id=10896
    #endif

    Wire.onReceive(receiveEvent); // register event
    Wire.onRequest(requestEvent); // register event
}

void setup() {
    SetupI2C();
}

void loop() {

    if (requestEventCommandReceived) 
    {
        requestEventCommandReceived = false;
    }
    #endif
}