简体   繁体   中英

Sending Byte from Raspberry Pi to Arduino With I2c & IoT for PWM

I am very new to the using both I2C and C#/Windows IoT so apologies up front if any of this is a dumb question. I have a Raspberry Pi 3 master and Arduino slave. I am trying to send a value from a slider on my UI form over I2C to the Arduino which I will use to adjust my PWM duty cycle. There a couple of issues I am having and can't work out if its the Pi, Arduino or both.

Here is my Arduino Slave code:

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

}

And my Pi Master:

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;

        }
    }
}

The first issue I am having is that my ReceivedData on the Arduino is always 0 not matter what the value of sendpos is on the Pi (yes, it does change when I move the slider).

The second issue I am having is the first time the slider is moved I get the output on the Arduino serial but then nothing after. If I either reset or reload the Arduino I then get the output of the initial slider change again and nothing after.

Apologies if any of this is too vague or explained poorly, any help or nudge in the right direction would be greatly appreciated.

Thanks in advance.

you have to change the "Wire.onReceive(I2CReceived);" to the loop because when it's in the setup the arduino exute it only one, (sorry for my english)

I wrote an I2C slave for Arduino UNO based on Nick Gammon Web Site . It worked but I could not get more than 10 K byte /second. You have some missing part in your own code.

Here is stripped down version of the Arduino Code

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM