Skip to menu

Robotics with Object Pascal

All New K2

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.

 

AllNewK02_basic_comm.png

 

===============================================

// 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.

 

AllNewK2_09_I2C_function_for_sending_data.png

 

AllNewK2_07_I2C_First_Sending.pngAllNewK2_08_I2C_Second_Sending.png

 

 

// 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.