arduino bus steering gear + real-time serial communication control

arduino syntax

digitalWrite() function

digitalWrite(pin,value);  / / define the level of the pin
  • Pin *: * you want to set the pin numbers of the mode from 0 to 13

  • value: indicates high level or low level

digitalRead function

Pin level reading function

int digitalRead(pin)

The digital IO port reads the input level function and reads the value of the digital interface. For example, you can read the digital sensor. When it is sensed that the foot position is at HIGH potential, it will be sent back HIGH, otherwise it will be sent back LOW.

The digital IO port reads the input level function and reads the value of the digital interface. For example, you can read the digital sensor. When it is sensed that the foot position is at HIGH potential, it will be sent back HIGH, otherwise it will be sent back LOW.

example:

val = digitalRead (7); / / read the value of pin 7 and assign it to val

Analylogread() function

int analogRead(pin)

Pin the number of the analog input pin to be read (Arduino Diecimila is 0-5, Arduino nano is 0-7, and 0-15 on mega) the analog IO port reading function reads the value from the specified analog interface, and Arduino performs 10 bit digital conversion on the analog value. This function returns a number between 0 and 1023, representing a voltage between 0 and 5 volts. For example, if the voltage applied to the pin No. 0 is 2.5V, then the analogRead(0) returns 512.

By using the analysisread() function, we can read the voltage applied to one of the pins. For example, analog sensors can be read (10 bit AD, 0 ~ 5V represents 0 ~ 1023).

Analylogwrite function

analogWrite(pin, value);

Digital IO port PWM output function, write analog value (PWM wave) to an interface, change the output voltage value of PWM pin, which can be used for motor PWM speed regulation or music playback.

  • pin: for Arduino (including Mini or BT) of ATmega168 chip, this function can work on interfaces 3, 5, 6, 9, 10 and 11

  • value is expressed as 0 ~ 255

Delay (ms) delay function

delay (ms) ;
1

Delay (MS) delay function (unit: ms), delay for a period of time, how many milliseconds to pause the execution of the chip,

delay (1000) is one second.

Attachthrupt() function

attachInterrupt(interrupt,function,mode)

Interrupt: interrupt source (in Arduino, the optional value of interrupt source is 0 or 1, which generally corresponds to pins 2 and 3 respectively)

Function: the name of the function to be interrupted

mode:

LOW (LOW level trigger)

CHANGE (triggered when the pin level changes)

RISING (trigger from low level to high level)

FALLING (high level to low level trigger)

detachInterrupt() function

detachInterrupt(interrupt)

Interrupt switch function, interrupt=1 on, interrupt=0 off.

example:

detachInterrupt (1) / / open interrupt
 Interrupt enable function

Interrupts() / / enable interrupts

noInterrupts() / / disable interrupts

Serial port string

This function can convert the serial string data received by arduino into decimal shaping for later use and programming.

#define numdata_length 2
String comdata = "";
int numdata[numdata_length] = {0};
int flag = 0;
void setup() {
  Serial.begin(9600);
  }
void loop() {
int j = 0;
//Continuously cycle to detect the serial port cache and read the string one by one
while (Serial.available() > 0)
{
  comdata += char(Serial.read());
  delay(2);
  flag = 1;
}
//If the data is received, perform comdata analysis, otherwise do nothing
if(flag == 1) {
for(int i = 0; i < comdata.length() ; i++){
  if(comdata[i] == ','){
    j++;
    }
  else{
    numdata[j] = numdata[j] * 10 + (comdata[i] - '0');
    }
  }
comdata = String("");
flag = 0;
for(int i = 0; i < numdata_length; i++){
  Serial.println(numdata[i]);
  numdata[i] = 0;
  }
}
}

//Define a comdata string variable and assign the initial value to null
    String comdata = "";
    //numdata is an array of numbers after splitting
    int numdata[6] = {0}, PWMPin[6] = {3, 5, 6, 9, 10, 11}, mark = 0;
    void setup()
    {
    //Define 0 ~ 6 pins as output
      for(int i = 0; i < 6; i++) pinMode(PWMPin[i], OUTPUT);
      Serial.begin(9600);
    }
     
    void loop()
    {
    //j is the position count of the number array after splitting
      int j = 0;
     
      //Continuously cycle to detect the serial port cache and read in strings one by one,
      while (Serial.available() > 0)
      {
      //After reading in, connect the string to comdata.
        comdata += char(Serial.read());
          //Delay for a while to make the serial port cache ready for the next number. No delay will lead to data loss,
        delay(2);
        //Mark that the serial port has read data. If there is no data, this while will not be executed directly.
        mark = 1;
      }
     
      if(mark == 1) / / if data is received, perform comdata analysis. Otherwise, do nothing.
      {
      //Display the string just entered (optional statement)
        Serial.println(comdata);
          //Display the length of the string just entered (optional statement)
        Serial.println(comdata.length());
     
    /*******************Here are the key points*******************/
    //Read the string length cycle through the serial port,
        for(int i = 0; i < comdata.length() ; i++)
        {
        //Analyze the text of comdata[i] string one by one. If the text is a separator (comma separation is selected here), move the position of the result array down one bit
        //That is, for example, 11 starting from 11, 22, 33 and 55 is recorded in numdata[0]; If you encounter a comma, j equals 1,
        //Then convert to numdata[1]; If you encounter a comma again, write it down to numdata[2]; And so on until the end of the string
          if(comdata[i] == ',')
          {
            j++;
          }
          else
          {
             //If there is no comma, add the read number * 10 to the previously read number,
             //And (comdata [i] - [0 ') is to convert the ASCII code of the character' 0 'into the number 0 (this problem will not be described below, but directly regarded as the number 0).
             //For example, if the input number is 12345, this statement will be executed five times without encountering a comma five times.
             //Because the number on the left is obtained first, and numdata[0] is equal to 0,
             //So the first cycle is numdata[0] = 0*10+1 = 1
             //The second time numdata[0] is equal to 1, and the cycle is numdata[0] = 1*10+2 = 12
             //The third time is that numdata[0] is equal to 12, and the cycle is numdata[0] = 12*10+3 = 123
             //The fourth time is numdata[0] equal to 123, and the cycle is numdata[0] = 123*10+4 = 1234
             //And so on, the string will be changed to the number 0.
            numdata[j] = numdata[j] * 10 + (comdata[i] - '0');
          }
        }
        //All comdata strings have been converted to numdata. Clear comdata for next use,
        //If you don't leave it blank, this result is likely to interfere with the next one.
        comdata = String("");
     
     
        //The contents of numdata are output circularly and written to the PWM pin
        for(int i = 0; i < 6; i++)
        {
          Serial.print("Pin ");
          Serial.print(PWMPin[i]);
          Serial.print(" = ");
          Serial.println(numdata[i]);
          analogWrite(PWMPin[i], numdata[i]);
          numdata[i] = 0;
        }
        //After output, the mark of the read data must be set to 0. If it is not set to 0, it cannot be used in the next cycle.
        mark = 0;
      }
    }

arduino code

#include "LobotServoController.h"
#include <Servo.h>
/*~~~~~~~~~~~~~~~~~~~~~~~~~~Gorgeous dividing line~~~~~~~~~~~~~~~~~~~~~~~~~~ */
#define L1 75
#define L2 125
#define pi 3.1415926
#define up  200
#define down 800
LobotServoController myse(Serial);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~Gorgeous dividing line~~~~~~~~~~~~~~~~~~~~~~~~~~ */
int User_receive_buffer_flag = 0;
int lift_flag = 0;//0 is falling
double s_1,s_2;
double  s_1_pre,s_2_pre;
int lift = 300;
int recv_size = 0;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~Gorgeous dividing line~~~~~~~~~~~~~~~~~~~~~~~~~~ */
Servo myservo;  //Create a steering gear control object
Servo myservo1; // The Servo class can control up to 8 steering engines
Servo myservo2;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~Gorgeous dividing line~~~~~~~~~~~~~~~~~~~~~~~~~~ */

boolean sendFlag = false; //Indicates whether data is allowed to be sent through the serial port
boolean readCompleted = false; //Indicates whether reading serial port data is completed
String serialString = ""; //Serial port data cache string
int a[10]= {-1,560,230,520,999,290,-1,260,860,999};
int b[10]= {-1,680,320,370,999,360,-1,340,860,999};
int readnum;
int c[100] = {0};
int d[100] = {0};
double recv_data[200]; 
String comdata = "";
int numdata[200] = {0};
int mark=0;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~Gorgeous dividing line~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void setup()
{
  pinMode(13, OUTPUT);
  myse.moveServo(1,500,1000);
  myse.moveServo(2,500,1000);
  myse.moveServo(3,500,1000);
  Serial.begin(9600);
  serialString.reserve(200);
  motorplay_1(a,b,10);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~Gorgeous dividing line~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void loop()
{
    read();
    delay(10);
}
void set_pen(double x_1,double y_1)
{
  double m;//Distance from point to origin
  double a1;
  double a2;
  double a3;//Calculate the required angle
  m=sqrt(x_1*x_1+y_1*y_1);
  a1=cos_angle(L1,L2,m);
  a1 = acos(a1);
  a2=atan2(y_1,x_1);
  a3=cos_angle(L1,m,L2);
  a3 = acos(a3);
  s_1=a2-a3;
  s_2=pi-a1;
  s_1 = (180/pi)*s_1+90;
  s_2 = (180/pi)*s_2;
}
int cos_angle(double q,double w,double e){
  double r;
  r=(q*q+w*w-e*e)/(2*q*w);
  return r;
}
void read()
{
  int p = 0;
  int j = 0;
  while (Serial.available() > 0)
  {
    comdata += char(Serial.read());
    delay(2);
    mark = 1;
  }
  Serial.flush();
  if(mark == 1)  
  {
    for(int i = 0; i < comdata.length() ; i++)
    {
      if(comdata[i] == ',')
      {
        j++;
      }
      else
      {
        numdata[j] = numdata[j] * 10 + (comdata[i] - '0');
      }
    }
    if(numdata[0]>30)
    {
      digitalWrite(13,HIGH); 
    }
    else 
    {
      digitalWrite(13,LOW);
    }
    comdata = String("");
 
    for (int k =0;k<j;k++)
    {
      if(k<(j+1)/2)
      {
        c[k] = numdata[k];
      }
      else
      {
        d[p] = numdata[k];
        p++;
      }
      Serial.println(c[k]);
      Serial.println(d[k]);
    }
    mark = 0;
  }
}

void motorplay_1(int *thea1,int *thea2,int num)
{
  for (int i = 0;i<num;i++)
  {
    if(thea1[i] == 999&&thea2[i] == 999)
    {
      myse.moveServo(3,up,1000);
      delay(1000);
    }
    else if(thea1[i] == -1&&thea2[i] == -1)
    {
      myse.moveServo(3,down,500);
      delay(1000);
    }
    else
    {
      myse.moveServo(1,thea1[i],1000);
      myse.moveServo(2,thea2[i],1000);
      delay(1000);
    }
  }
  myse.moveServo(1,500,1000);
  myse.moveServo(2,500,1000);
  myse.moveServo(3,500,1000);
  delay(1000);
}


void lift_down( int flag)
{
  if (flag ==1)
  {
    myse.moveServo(3,900,1000);
    
  }
  if(flag == 0)
  {
    myse.moveServo(3,100,1000);
  }
}


static void StrToInt(char *buffer, int size)
{
    int i = 0;
 
    char *p = NULL;
 
    p = strtok(buffer, " ");
 
    while((p = strtok(NULL, " ")) != NULL)
    {
        recv_data[i++] = atoi(p);
    }
    recv_size = i;
}

The whole arduino control module is mainly divided into three parts: initialization port, data processing and analysis, and steering gear motion control

Initialize port module

Firstly, for the initialization port, we use the way of serial communication to realize the control of the steering gear and the communication with the host computer system. For the control of the steering gear, we use the steering gear control function of the steering gear board, which can be called after adding a third-party library.

#include "LobotServoController.h"

This arduino is only equipped with a hardware serial port, which means that the data transmission and reception needs a specific way, otherwise the steering gear control will be disordered. We use the communication format of the bus steering gear to communicate, which skillfully avoids this problem. The purpose of no conflict between receiving data and sending steering gear control instructions is realized.

Data analysis module

We use string to communicate with the host computer, adopt utf-8 encoding format, take "\ n" as the sending or reading termination bit, and convert the string received by the serial port into corresponding decimal number through void read() function and store it in the form of one-dimensional matrix.

Then we inverse solve the received data to get the corresponding angle of the steering gear according to the position of the target, and then control the steering gear.

Real time control module

Our host computer uses python to transmit data and collect original information. We collect external images by connecting an external camera, extract edges and get the position matrix. After that, the string is sent to the serial port in utf-8 format. After arduino parses the data, the steering gear motion is controlled in real time.

Keywords: Single-Chip Microcomputer

Added by sweenyman on Sun, 19 Dec 2021 09:50:21 +0200