【问题标题】:Sending Byte from Raspberry Pi to Arduino With I2c & IoT for PWM使用 I2c 和 IoT 将字节从 Raspberry Pi 发送到 Arduino 以实现 PWM
【发布时间】:2016-05-25 09:33:01
【问题描述】:

我对同时使用 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,不管 Pi 上的 sendpos 的值是多少(是的,当我移动滑块时它确实会改变)。

我遇到的第二个问题是第一次移动滑块时,我在 Arduino 串行上得到了输出,但之后就没有了。如果我重置或重新加载 Arduino,我会再次获得初始滑块更改的输出,之后什么都没有。

如果其中任何内容过于含糊或解释不佳,我们深表歉意,我们将非常感谢您在正确方向上的任何帮助或推动。

提前致谢。

【问题讨论】:

    标签: c# arduino raspberry-pi iot i2c


    【解决方案1】:

    您必须更改“Wire.onReceive(I2CReceived);”到循环,因为当它在设置中时,arduino 只执行它一个,(对不起我的英语)

    【讨论】:

    • 感谢 Med,如果我将 'Wire.onReceive(I2CReceived)' 或 'I2CReceived(pass)' 移动到循环中,我会在初始启动时将 'VMDPV_1|1ßõMDPV' 输出到串行的 Arduino,然后我只在 Arduino 崩溃/冻结之前得到第一个滑块运动的输出。
    【解决方案2】:

    我基于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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多