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.
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.
#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.
Thanks much. I had accidentally stumbled upon your git page on common mistakes earlier. Will also go through your Wiki. I think I saw GolamMostafa's article too (through googling). Thanks for all the resource links.