Hello, I am fairly new to arduino, and I have a project I'm working on with an Arduino Uno R3, a laser distance sensor, an accelerometer, and an lcd display. It will be a golf rangefinder, where I point the laser at the hole, and it tells me the lateral distance to the hole, which is calculated using the distance measured by the laser, combined with the angle relative to the horizon that the accelerometer measures.
Everything I have done so far works in isolation, the laser measures the distance very accurately, and the accelerometer gives the correct angle. The problem is when I have both going at the same time. It seems the serial data being sent is being interfered with. When the laser sends its distance measurement, the accelerometer measures less than 1 degrees no matter the orientation, but if I disconnect the laser or move it around quickly so it can't get a measurement, then the accelerometer displays the correct angle for the orientation. I have tried many different solutions, including AltSoftSerial, and NeoSWSerial plus using the built-in hardware serial connection. With AltSoftSerial, I tried the laser in pins 8, 9, accelerometer in 2, 3, same issue, with NeoSWSerial, I tried the laser in pins 8, 9, and the accelerometer in 0, 1, again with the same issue.
Again, I'm not very experienced, so maybe there is a combination that I've overlooked that could fix this using these different software serial libraries, so I would be willing to try suggestions for this. I had hoped that by staggering the laser and accelerometer, as well as using the listen command, that I could avoid the interference that can occur between multiple software serial connections. If it doesn't seem like this can be done on an Uno, I'm assuming a Mega would be able to work with two hardware serial connections, therefore avoiding interference?
The code is shown below. If you would like me to add the code I used when testing out the AltSoftSerial or NeoSWSerial combinations, I can, but I didn't want to make this too long of a post.
#include <SoftwareSerial.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <math.h>
SoftwareSerial laserSerial(10,11); // Laser Serial Connection, (10, 11)
SoftwareSerial angleSerial(12,13); // Accelerometer Serial Connection, (12, 13)
LiquidCrystal_I2C lcd(0x27, 20, 4); // I2C Setup for LCD Display
char distanceStr[8];
double distance;
double verticalDist;
double lateralDist;
short pitch;
byte rollL;
byte rollH;
byte pitchL;
byte pitchH;
byte yawL;
byte yawH;
byte command[] = {0x80, 0x06, 0x03, 0x77};
float pitchAngle;
void setup() {
// Arduino Serial Monitor Setup
Serial.begin(57600);
// Laser Serial Setup
laserSerial.begin(9600);
// Accelerometer Serial Setup
angleSerial.begin(115200);
// LCD Setup
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
// Send the command to start continuous measurement
laserSerial.write(command, sizeof(command));
laserSerial.flush();
Serial.println("Setup Complete");
}
void loop() {
// Set the listening port to the accelerometer
angleSerial.listen();
delay(50);
// Clear Buffer
while(angleSerial.available()){
angleSerial.read();
}
delay(125);
// Read the incoming angle data
while (angleSerial.available()) {
byte incomingByte = angleSerial.read();
// Look for the angle output header 0x55 0x53
if (incomingByte == 0x55 && angleSerial.peek() == 0x53) {
angleSerial.read(); // Read the 0x53 byte
// Read angle data
rollL = angleSerial.read();
rollH = angleSerial.read();
pitchL = angleSerial.read();
pitchH = angleSerial.read();
yawL = angleSerial.read();
yawH = angleSerial.read();
break;
}
}
// Set the listening port to the laser
laserSerial.listen();
delay(50);
// Clear Buffer
while(laserSerial.available()) {
laserSerial.read();
}
delay(125);
// Wait for the sensor to take the measurement and send the data
while(laserSerial.available()) {
if (laserSerial.read() == 0x80) {
// Read the incoming data
byte data[10];
for (int i = 0; i < 10; i++) {
data[i] = laserSerial.read();
}
// Convert the distance data from ASCII to a string
for (int i = 0; i < 7; i++) {
distanceStr[i] = char(data[i + 2]);
}
distanceStr[8] = '\0';
break;
}
}
// CALCULATIONS
// Convert the string to a float
distance = atof(distanceStr);
distance=distance*3.28084;
// Convert data to angle
short pitch = (short)((pitchH << 8) | pitchL);
// Calculate actual angle
pitchAngle = pitch / 32768.0 * 180.0;
// Calculate Vertical Distance
verticalDist = distance*sin((2*3.1415/360)*pitchAngle);
// Calculate Lateral Distance
lateralDist = sqrt((distance*distance)-(verticalDist*verticalDist));
// RESULTS
lcd.clear();
// Display the distance on LCD
lcd.setCursor(5,1);
lcd.print(distance);
lcd.printstr(" feet");
// Display the lateral distance on LCD
lcd.setCursor(5,2);
lcd.print(lateralDist);
lcd.printstr(" feet");
// Display the vertical on LCD
lcd.setCursor(3,3);
lcd.print(verticalDist);
lcd.printstr(" feet");
// Print angle to serial monitor
Serial.print(" Pitch: ");
Serial.print(pitchAngle);
Serial.println();
Serial.flush();
// Delay for 50ms before next loop iteration
delay(50);
}