Electron as Slave, Pi 3 As Master

I am looking to control the Electron as Slave, Pi 3 As Master

I have some very basic code to try to have the Electron be the slave and the Pi be the master
Here is the Electron code

#include OneWire.h
#define MyAddress 0x40

byte DataToBeSend[1];
byte ReceivedData;
bool MessageNeedsProcessing =false;
 char msg[255] = "";
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);
    if(MessageNeedsProcessing)
    {
        
    
         char myJSON[255] = "";
        snprintf(myJSON, 255, "{\"Data\":{\"DeviceID\":%d,\"item\":%d}}","\"I2CTEST\"", msg);
   
        // Trigger the integration
        Particle.publish("Data", myJSON, PRIVATE);
        MessageNeedsProcessing=false;
    }
}

/* 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 */
    while(Wire.available())
    {
       char ReceivedData = Wire.read();
       msg = ReceivedData;
        MessageNeedsProcessing=true;

    }
}

/* 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);
    
}

Here is the Master code i am using on the pi to try to locate the Electron

        public static async Task<IEnumerable<byte>> FindDevicesAsync()
        {
            IList<byte> returnValue = new List<byte>();
            // *** 
            // *** Get a selector string that will return all I2C controllers on the system 
            // *** 
            string aqs = I2cDevice.GetDeviceSelector();
            // *** 
            // *** Find the I2C bus controller device with our selector string 
            // *** 
            var dis = await DeviceInformation.FindAllAsync(aqs).AsTask();
            if (dis.Count > 0)
            {
                const int minimumAddress = 1;
                const int maximumAddress = 88;
                for (byte address = minimumAddress; address <= maximumAddress; address++)
                {
                    var settings = new I2cConnectionSettings(address);
                    settings.BusSpeed = I2cBusSpeed.FastMode;
                    settings.SharingMode = I2cSharingMode.Shared;
                    // *** 
                    // *** Create an I2cDevice with our selected bus controller and I2C settings 
                    // *** 
                    using (I2cDevice device = await I2cDevice.FromIdAsync(dis[0].Id, settings))
                    {
                        if (device != null)
                        {
                            try
                            {
                                byte[] writeBuffer = new byte[1] { 0 };
                                device.Write(writeBuffer);
                                // *** 
                                // *** If no exception is thrown, there is 
                                // *** a device at this address. 
                                // *** 
                                returnValue.Add(address);
                            }
                            catch
                            {
                                // *** 
                                // *** If the address is invalid, an exception will be thrown. 
                                // *** 
                            }
                        }
                    }
                }
            }
            return returnValue;
        }

It Does not seem like i am talking to the Electron. It should publish a command when i do…

I am new to the hardware side of things… Not sure if i have it hooked up correct I have the
PI_SDA(gpio02) to Electron_SDA(gpioD0) and PI_SCL(gpio03) to Electron_SCL(gpioD1)
Do i need to have some type of resistor in place to get this to work correct?

Any help would be great.

thanks

Chris

Hello,

Let me ping someone that might be able to help, @tylercpeacock are you able to help on this?

Kyle

As @rickkas7 pointed out in the previous post, this is a bit beyond what we can offer from a customer support standpoint. The project is definitely possible, though offhand I’m unable to tell where the problem may lie. Hopefully there are others in the forums who can provide some insight into this project.

@ChrisCalzaretta, I2C requires pull-up resistors for both the SDA and SCL lines. Using 4.7K or 10K ohm resistors to 3V3 (3.3volt pins on either the Electron or the RPi). You MUST also ensure that the grounds (GND) of the Electron and RPi are tied together. Remember that the default I2C clock speed is 400KHz. I'm not sure what I2cBusSpeed.FastMode on the RPi side set the clock to.

If possible, I would start with simple Serial.print() debug statements on the Electron so you can trace your program flow. Once satisfied, you can then add the publish code. You could run your code in SYSTEM_MODE(MANUAL) to avoid using data while you test the I2C connectivity.

2 Likes

@ChrisCalzaretta, I did mention in the PM that you sent me that you’d need resistors and that you should update this thread accordingly to save others the time on commenting on the same point.

2 Likes

Yes i have resistors and the ground already connected I will make sure to update the thread as i get more information… Still having issues tho :frowning:

Also i have done a bit of digging… Windows IOT I2cBusSpeed.FastMode = 400Khz

And the Pi i think it can use the max i2c speed… I have not been able to find documentation on this.
The speed grades that i have seen so far
standard mode: 100 kbit/s, full speed: 400 kbit/s, fast mode: 1 mbit/s, high speed: 3,2 Mbit/s

i am reading that the Raspberry pi has the resistors on board
The Pi’s SDA and SCL lines have physical resistors on the board to pull up to 3.3V.

I assume the Raspberry pi onboard resistors would work for what i am trying to do here

Yes, they should work.

I believe everything is hooked up correct, And it should seems like it should work… I have tried both scl and sda lines on the electron. But can you tell me when i call Wire.begin(MyAddress); does it open both sda and scl lines?
D0,D1
C5,C4

Thanks

Wire.begin() only acts on D0/D1.
For the other interface you'd use Wire1.begin()

https://docs.particle.io/reference/firmware/electron/#wire-i2c-

1 Like

Thanks Trying to use wire1 now… I did not have luck with wire… Dont think it will make any difference but we will see :slight_smile:

Still have issues however Just got my usb debugger cable :)… I hope to have some more information soon…

Ok I got the problem resolved. It seem to have something to do with the PI windows IOT version. I upgraded everything to build Winodws IOT build 16193 and everything seems to be working now :)…

Thanks for your help in trying to figure out this issue

2 Likes