I'm working on a project where we use 2 mg996 servo and tfmini plus lidar to map a room. But when we wrote a code the vertical servo is shaking. When lidar is not connected there is no shaking. I heard that the shaking is because the vertical servo is idle for a long time while collecting the lidar value and can be avoided by providing the angle value as a 20ms period pwm to the vertical servo(Not sure if that's what they meant).But i dont understand how to create a pwm such that there is no stopping in the code execution in collecting value from the lidar. Here's the code snippet of both servo writing and lidar reading. Can someone tell me what to do.
Thanks in advance.
void loop() {
for(theta=0 ; theta<=180; theta++){
analogWrite(SERVO_theta,
delay(100);
if(theta%2==0){
for(phi=1;phi<=180;phi++){
servoX.write(phi);
delay(12);//delay for each servo angle
reading();//function to obtain the lidar value
}
delay(100);
}
else{
for(phi=180; phi>0;phi--){
servoX.write(phi);
delay(12);
reading();
}
delay(100);
}
}
}
void reading()
{
if (Serial1.available()) { //check if serial port has data input
if(Serial1.read() == HEADER) { //assess data package frame header 0x59
uart[0]=HEADER;
if (Serial1.read() == HEADER) { //assess data package frame header 0x59
uart[1] = HEADER;
for (i = 2; i < 9; i++) { //save data in array
uart[i] = Serial1.read();
}
check = uart[0] + uart[1] + uart[2] + uart[3] + uart[4] + uart[5] + uart[6] + uart[7];
if (uart[8] == (check & 0xff)){ //verify the received data as per protocol
dist = uart[2] + uart[3] * 256; //calculate distance value
//output measure distance value of LiDAR
x=dist*cos(theta* PI / 180.0)*cos(phi* PI / 180.0);//converting spherical to cartesian
y=dist*cos(theta* PI / 180.0)*sin(phi* PI / 180.0);
z=dist*sin(theta* PI / 180.0);
printOutput(x, y, z);
}
}
}
}
}
#include <SoftwareSerial.h> //header file of software serial port
#include <Servo.h>
void reading();
void printOutput(float ,float ,float);
Servo servoX;
Servo servoY;
SoftwareSerial Serial1(2,3); //define software serial port name as Serial1 and define pin2 as RX and
#define SERVO_theta 9 // Pin connected to servo motor
#define SERVO_phi 10
#define PI 3.14159
int phi;
int theta;
float x,z,y;
/* For Arduinoboards with multiple serial ports like DUEboard, interpret above two pieces of code and directly use Serial1 serial port*/
int dist; //actual distance measurements of LiDAR
int check; //save check value
int i;
int uart[9]; //save data measured by LiDAR
const int HEADER=0x59; //frame header of data package
void setup() {
Serial.begin(9600); //set bit rate of serial port connecting Arduino with computer
Serial1.begin(115200); //set bit rate of serial port connecting LiDAR with Arduino
servoY.attach(SERVO_theta);
servoX.attach(SERVO_phi);
}
void loop() {
for(theta=0 ; theta<=180; theta++){
servoY.write(theta);
delay(100);
if(theta%2==0){
for(phi=1;phi<=180;phi++){
servoX.write(phi);
delay(12);//delay for each servo angle
reading();//function to obtain the lidar value
}
delay(100);
}
else{
for(phi=180; phi>0;phi--){
servoX.write(phi);
delay(12);
reading();
}
delay(100);
}
}
}
void reading()
{
if (Serial1.available()) { //check if serial port has data input
if(Serial1.read() == HEADER) { //assess data package frame header 0x59
uart[0]=HEADER;
if (Serial1.read() == HEADER) { //assess data package frame header 0x59
uart[1] = HEADER;
for (i = 2; i < 9; i++) { //save data in array
uart[i] = Serial1.read();
}
check = uart[0] + uart[1] + uart[2] + uart[3] + uart[4] + uart[5] + uart[6] + uart[7];
if (uart[8] == (check & 0xff)){ //verify the received data as per protocol
dist = uart[2] + uart[3] * 256; //calculate distance value
//output measure distance value of LiDAR
x=dist*cos(theta* PI / 180.0)*cos(phi* PI / 180.0);
y=dist*cos(theta* PI / 180.0)*sin(phi* PI / 180.0);
z=dist*sin(theta* PI / 180.0);
printOutput(x, y, z);
}
}
}
}
}
void printOutput(float x1, float y1, float z1)
{
Serial.print(x1);
Serial.print(" ");
Serial.print(y1);
Serial.print(" ");
Serial.println(z1);
}
edit::: i didn't used analogWrite command....I was just trying it out
i think if there is a way i can maintain the theta angle by using a pwm ( by using a timer) may help....not so sure....if it does can someone help with that code....I'm new to arduino timer....our servo uses a 20ms period pulse
The problem is with software serial. It can disable interupts for long periods so it will also disable the servo outputs.
Your diagram is wrong if you are actually using software serial and not hardware serial.
You might try altsoftserial but you must go slower than 115200
but we want the values to appear on serial monitor cause then only we can save these values to a txt file right?? we need to plot these coordinates. And i guess the hardware serial can't print that values in the serial monitor right?? correct me if I'm wrong
That's the problem when you only have one hardware serial port.
If you connect the LIDAR to it then anything you send to the serial monitor will also go to the LIDAR.
Can you make the LIDAR ignore incomming data?
Have you tried the Altsoftserial?
I will check if the lidar can ignore incomming data.
I haven't tried the altsoftserial....can it by any means support 115200 baud rate....cause reducing the lidar baud rate is bit difficult and might affect the performance I think. And does any other board have more hardware serial port...We are using uno