Basic Communication between ZERO 3W <==> Pro Mini via I2C
2025.03.13 21:09
Basic Communication between ZERO 3W <==> Pro Mini via I2C
The only reason why using Pro Mini is that RADXA ZERO 3W has serious problem that PWM does NOT work as expected.
If PWM was working properly on RADXA ZERO 3W, I could have omitted Arduino Pro Mini.
===============================================
// All Servo Testing on Pro Mini
// Arduino Pro Mini will get command from Radxa ZERO 3W via I2C port
// to control 3 servos for now.
#include <Wire.h>
#include <Servo.h> // Pin7 : For Lidar 20kg torque with frame
// Pin8 : Left Wheel (Continous Servo)
// Pin9 : Right Wheel (Continous Servo)
#include "parse.h"
#define BUFFER_SIZE 100
char packetBuffer[255];
const int ThisMachine = 2;
Servo LidarAngle;
Servo WheelL;
Servo WheelR;
int LSpos = 0; // variable to store the servo position
int WLval = 0; // variable for Left Wheel Servo Speed / Direction
int WRval = 0; // variable for Right Wheel Servo Speed / Direction
void Test_All_Servos() {
Serial.println("Lidar Servo Testing Begins");
// Lidar Servo Test
LSpos = 60; // -45 degree (Heading high position of 45 degree angle)
LidarAngle.write(LSpos);
for (LSpos = 60; LSpos <= 120; LSpos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
LidarAngle.write(LSpos); // tell servo to go to position in variable 'pos'
delay(150); // waits 15 ms for the servo to reach the position
}
LSpos = 90; // Move back to flat direction
LidarAngle.write(LSpos);
Serial.println("1. Lidar Servo Test Done");
delay(500);
Serial.println("Left Wheel Servo Testing Begins");
// Left Wheel Servo Test
for (WLval = 90; WLval <= 120; WLval += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
WheelL.write(WLval); // tell servo to go to position in variable 'pos'
delay(150); // waits 15 ms for the servo to reach the position
}
for (WLval = 120; WLval <= 60; WLval -= 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
WheelL.write(WLval); // tell servo to go to position in variable 'pos'
delay(150); // waits 15 ms for the servo to reach the position
}
for (WLval = 60; WLval <= 87; WLval += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
WheelL.write(WLval); // tell servo to go to position in variable 'pos'
delay(150); // waits 15 ms for the servo to reach the position
}
Serial.println("2. Left Wheel Servo Test Done");
Serial.println("Right Wheel Servo Testing Begins");
// Left Wheel Servo Test
for (WRval = 90; WRval <= 120; WRval += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
WheelR.write(WRval); // tell servo to go to position in variable 'pos'
delay(150); // waits 15 ms for the servo to reach the position
}
for (WRval = 120; WRval <= 60; WRval -= 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
WheelR.write(WRval); // tell servo to go to position in variable 'pos'
delay(150); // waits 15 ms for the servo to reach the position
}
for (WRval = 60; WRval <= 87; WRval += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
WheelR.write(WRval); // tell servo to go to position in variable 'pos'
delay(150); // waits 15 ms for the servo to reach the position
}
Serial.println("3. Right Wheel Servo Test Done");
}
void setup() {
Wire.begin(8); // join i2c bus with address #8
Wire.onReceive(receiveEvent); // register event
// For debugging the message received from Radxa ZERO 3W vid I2C
Serial.begin(115200); // Initialize serial and wait for port to open:
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("Serial initialized");
// Servos (LidarAngle, WheelL, WheelR)
LidarAngle.attach(7); // Servo for Lidar Angle
WheelL.attach(8); // Continous Servo for Left Wheel
WheelR.attach(9); // Continous Servo for Right Wheel
Serial.println("Servo initialized");
delay(500);
LidarAngle.write(90); // Center
WheelL.write(87);
WheelR.write(90);
Serial.println("All Servo Centered");
delay(500);
Test_All_Servos();
}
void loop() {
delay(100);
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
while (1 < Wire.available()) { // loop through all but the last
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
int x = Wire.read(); // receive byte as an integer
Serial.println(x); // print the integer
}
=========================================
// From Object Pascal from Radxa ZERO 3W
// I must utilize pascalio library's i2c_dev.pas unit.
// SAMPLE CODING ABOVE
unit K2GuiMain;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
baseUnix, i2c_dev, fpi2c;
type
RegArray = array [0..64] of byte;
pRegArray = ^RegArray;
{ TGuiMain }
TGuiMain = class(TForm)
bTest: TButton;
Label1: TLabel;
Label2: TLabel;
lblfdI2cValue: TLabel;
lblfpIOCtlValue: TLabel;
lblStatus: TLabel;
procedure bTestClick(Sender: TObject);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormCreate(Sender: TObject);
private
public
end;
const
// I have attached Arduino Pro Mini on I2C-4 w/ address 08
I2C_Pro_Mini_Path : string = '/dev/i2c-4';
Address_Pro_Mini = $08;
var
GuiMain: TGuiMain;
fdI2C : cint;
fdIOCtl : cint;
i : integer;
rval : LongInt; // result value
implementation
{$R *.lfm}
{ TGuiMain }
procedure TGuiMain.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
fpclose(fdI2C);
end;
procedure TGuiMain.bTestClick(Sender: TObject);
begin
fdI2C := fpOpen(I2C_Pro_Mini_Path, O_RDWR);
lblfdI2cValue.caption := inttostr(fdI2C);
if fdI2C >= 0 then begin
fdIOCtl := fpIOCtl(fdI2C, I2C_SLAVE, Pointer(Address_Pro_Mini));
lblfpIOCtlValue.caption := inttostr(fdIOCtl);
if (fdIOCtl >= 0) then begin
lblStatus.caption := 'Connection Succedded';
// Test sending a byte
// rval := i2c_smbus_write_byte_data(fdI2C, $00, ord('A'));
rval := i2c_smbus_write_byte(fdI2C, ord('B'))
end;
end;
end;
procedure TGuiMain.FormCreate(Sender: TObject);
begin
fdI2C := -1;
fdIOCtl := -1;
end;
end.
Comment 0
No. | Subject | Author | Date | Views |
---|---|---|---|---|
10 | I asked Google's Gemini for parsing code. | me | 2025.04.17 | 82 |
9 |
ESP-NOW without Long Range & External Antenna is terrible!
![]() | me | 2025.04.16 | 81 |
8 |
ESP-NOW with ESP8266 - Two way communication test done
![]() | me | 2025.04.11 | 86 |
7 |
Retry on PWM from Radxa ZERO 3W for servo control
![]() | me | 2025.03.25 | 124 |
6 | Problems found on I2C communication | me | 2025.03.22 | 132 |
5 | radxa zero 3w running an app on booting | me | 2025.03.13 | 142 |
» |
Basic Communication between ZERO 3W <==> Pro Mini via I2C
![]() | me | 2025.03.13 | 144 |
3 | Important Links | me | 2025.03.12 | 164 |
2 | To-Do List as of Mar. 12, 2025 | me | 2025.03.12 | 159 |
1 |
Mar. 12, 2025 Status
![]() | me | 2025.03.12 | 159 |