Sending complex data across I2C / Arduino

Hi All,

Setup: I am building a four motor rover, with a pan-tilt platform + SONAR. The motors are driven using a dedicated motor drive of appropriate voltage / amperage (2ch 30A drive w/ each channel driving 2 motors). The pan-tilt platform is bespoke with two S3003 servos driven through a servo driver. The SONAR is run of the mill HC-SR04 that feeds into the arduino.

Set up uses R-Pi as a Master and I aim to use the Arduino as a Slave through I2C. The Clock and Data Lines are connected through a logic converter; and a simple check of the I2C connection using "hello world" blinking program works. Everything is powered using a high capacity / high discharge 12V battery. The electro mechanical set up was earlier testing using just the Arduino (without RPi) and it works fine.

Why the Pi at all: I need to integrate both LiDAR and a visual camera besides creating a composite using all three positioning datasets (SONAR / LiDAR / VisCam). Moreover, the Pi will be used for PLAN / SLAM calculations too. Just the Arduino doesn't cut it for my needs.

Problem: I am trying to control the Motor Drive / SONAR / Pan-Tilt connected to the Arduino, from the RPi - through I2C. As mentioned above, I got the wire library to work successfully (thanks to many videos / articles on the net). I am however stuck in the next step.

I would like to send an array / dataframe / struct of information to the Arduino via I2C (for instance, imagine asking the pan-tilt system to move to angle 27* / 102*; I need to send a call to the function that moves these two servos, and provide this info. Or imagine moving the motors to make a turn, I need to provide differential speed info to the arduino about where I want to go (80,120) [motor control function].

How do I do this? Or is there no way to do this [can't believe this will be the case].

I understand I may not be the first one to ask this question: so, any pointers to previous solutions is also quite appreciated.

Thanks a ton.

Warm regards,

You can search for serial data transmission protocols.

But it will be much more efficient to use WiFi (TCP is more recommended than UDP) or SPI.

https://forum.arduino.cc/t/solved-sending-array-data-with-i2c/537012

https://community.st.com/s/question/0D50X0000ALud2SSQR/what-is-the-best-protocol-to-send-arrays-i2c-spi-

https://www.reddit.com/r/esp8266/comments/4s2q9q/esp8266_sending_large_array/

1 Like

The I2C bus is weak, because the high level is by pullup resistors. That will not go well with motors nearby. How close is the Arduino to the Raspberry Pi ? More than 20 cm ?
If you can use communication over Serial, that would be better. Then you can also use the buffer (64 byte) to send a few commands. Just plug the Arduino into a USB port and use Python to communicate with the Arduino.

You could define a 'struct' and send that 'struct' over I2C as a package. For example a byte for the type of command and a few more bytes for the data.
The onReceive handler puts the data in global memory and sets a flag. The loop() reads that flag and clears the flag and processes the data.

If you don't show it, then I have my doubts :grimacing:

1 Like

If you don't show it, then I have my doubts

:smiley: .. Here is the code I used for that

On the Arduino side:

#include <Wire.h>

int ledPin = 13;
void setup() {
  // put your setup code here, to run once:
  Wire.begin(0x8);

  Wire.onReceive(receiveEvent);

  pinMode(ledPin,OUTPUT);
  digitalWrite(ledPin,LOW);
}

void receiveEvent(int howMany) {
  // put your main code here, to run repeatedly:
  while(Wire.available())
  {
    char c = Wire.read();
    digitalWrite(ledPin, c);
  }
}

void loop()
{
  delay(100);
}

On the R-Pi side:

from smbus import SMBus
addr = 0x8
bus = SMBus(1)

numb = 1

numb = 1
print("Enter 1 or 0")

while numb == 1:
    
    ledState = input("  ")
    if ledState == "1":
        bus.write_byte(addr, 0x1)
    elif ledState == "0":
        bus.write_byte(addr, 0x0)
    else:
        numb = 0

Disclaimer - these snippets are closely adapted from code I found on the web. I can find a reference for credits ; but important thing is this is not my own. So I am not surprised the code worked.

To answer your other questions: The arduino is going to be placed less than 20cm from the Pi.

Serial Port as an option - thanks. I will definitely read up about it.

Last thing - about sending the struct as a series of bytes. Can you point me to an example that does it? That is really what I want to see - to learn how to do it. Thanks.

Warm regards,

Thank you for the links. I will go through them.

As for WiFi - I am afraid my arduino (Nano) isn't capable. Will look up SPI. As @Koepel pointed out, I will also look up USB Serial connection.

As for WiFi - I am afraid my arduino (Nano) isn't capable

Note that GitHub - jeelabs/esp-link: esp8266 wifi-serial bridge, outbound TCP, and arduino/AVR/LPC/NXP programmer is the original esp-link software which has notably been forked by arduino.org as Esp-Link and shipped with the initial Arduino Uno Wifi.

The esp-link firmware connects a micro-controller to the internet using an ESP8266 Wifi module. It implements a number of features:

  • Transparent bridge between Wifi and serial, useful for debugging or inputting into a uC
  • Flash-programming attached Arduino/AVR microcontrollers and LPC800-series and other ARM microcontrollers via Wifi

https://github.com/jeelabs/esp-link

Hardware configuration for normal operation

This firmware is designed for any esp8266 module. The recommended connections for an esp-01 module are:

  • URXD: connect to TX of microcontroller*
  • UTXD: connect to RX of microcontroller*
  • GPIO0: connect to RESET of microcontroller*
  • GPIO2: optionally connect green LED to 3.3V (indicates wifi status)*

https://github.com/jeelabs/esp-link/blob/master/FLASHING.md

1 Like

Thanks. That is a trove of info in your posts. I will spend the next few days at least reading up on those.

1 Like

This explains the basics: Arduino in Target mode · Koepel/How-to-use-the-Arduino-Wire-library Wiki · GitHub
I did not give a full example, because of all the trouble.

Robin2 made a full working example here: Use I2C for communication between Arduinos
I think my comments are valid, but he did not change it.

GolamMostafa also made a full working example, but I can't find it right now.

1 Like

Thanks much. I had accidentally stumbled upon your git page on common mistakes earlier. :slight_smile: Will also go through your Wiki. I think I saw GolamMostafa's article too (through googling). Thanks for all the resource links.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.