Hi all,
I've been working on a project to allow my observatory dome to track my telescopes movements using ToF sensors. Basically if a sensor is blocked, the motor moves the dome until it is unblocked and if it is blocked for a set amount of time, the motor speeds up to catch up.
However, when I've tested the code, the motor moves in loads of tiny increments instead of a single smooth move. Other test code without the sensors works perfectly fine so the wiring is ok. I think its the sensors that are causing the issue.
I am using 4 Adafruit VL53LX1's connected to an Adafruit PCA9548 connected to a Leonardo board.
Does anyone have any ideas on the issue?
Thank you
#include <Wire.h>
#include "Adafruit_VL53L1X.h"
#define TCAADDR 0x70
void tcaselect(uint8_t i) {
if (i > 7) return;
Wire.beginTransmission(TCAADDR);
Wire.write(1 << i);
Wire.endTransmission();
}
Adafruit_VL53L1X vl[4];
bool sensorOK[4] = {false, false, false, false};
#define SENSOR_THRESHOLD_MM 200
#define DIR_PIN 5
#define PUL_PIN 6
bool motorRunning = false;
bool motorDirCW = true;
uint32_t currentDelay = 1500;
unsigned long lastStepTime = 0;
#define START_DELAY 2000
#define FAST_DELAY 800
#define ACCEL_TIME 5000000
unsigned long blockStart = 0;
void setup() {
pinMode(DIR_PIN, OUTPUT);
pinMode(PUL_PIN, OUTPUT);
digitalWrite(DIR_PIN, LOW);
digitalWrite(PUL_PIN, LOW);
Serial.begin(115200);
delay(1000);
Serial.println("=== Observatory Dome Automation ===");
Wire.begin();
for (int i = 0; i < 4; i++) {
tcaselect(i);
if (!vl[i].begin(0x29, &Wire)) {
Serial.print("Sensor "); Serial.print(i); Serial.println(" FAIL");
sensorOK[i] = false;
} else {
vl[i].startRanging();
sensorOK[i] = true;
Serial.print("Sensor "); Serial.print(i); Serial.println(" OK");
}
}
Serial.println("Commands: CW, CCW, STOP, SPDxxxx, TEST");
}
void loop() {
if (Serial.available()) {
String cmd = Serial.readStringUntil('\n');
handleSerialCommand(cmd);
}
if (manualMode()) {
runMotor();
return;
}
bool leftBlocked = false;
bool rightBlocked = false;
for (int i = 0; i < 4; i++) {
if (!sensorOK[i]) continue;
tcaselect(i);
if (vl[i].dataReady()) {
int dist = vl[i].distance();
vl[i].clearInterrupt();
if (dist > 0 && dist < SENSOR_THRESHOLD_MM) {
if (i < 2) leftBlocked = true;
else rightBlocked = true;
}
}
}
if (leftBlocked && !rightBlocked) {
startMotor(true);
} else if (rightBlocked && !leftBlocked) {
startMotor(false);
} else if (!leftBlocked && !rightBlocked) {
stopMotor();
}
if (motorRunning) {
if (blockStart == 0) blockStart = micros();
unsigned long elapsed = micros() - blockStart;
if (elapsed > ACCEL_TIME) {
currentDelay = FAST_DELAY;
} else {
currentDelay = START_DELAY - ( (START_DELAY - FAST_DELAY) * elapsed / ACCEL_TIME );
}
} else {
blockStart = 0;
}
runMotor();
}
bool manualModeFlag = false;
bool manualMode() {
return manualModeFlag;
}
void runMotor() {
if (motorRunning) {
unsigned long now = micros();
if (now - lastStepTime >= currentDelay) {
lastStepTime = now;
digitalWrite(PUL_PIN, HIGH);
delayMicroseconds(2);
digitalWrite(PUL_PIN, LOW);
}
}
}
void startMotor(bool cw) {
motorRunning = true;
manualModeFlag = false;
digitalWrite(DIR_PIN, cw ? HIGH : LOW);
}
void stopMotor() {
motorRunning = false;
}
void handleSerialCommand(String cmd) {
cmd.trim();
cmd.toUpperCase();
if (cmd == "CW") {
Serial.println("Manual CW");
manualModeFlag = true;
motorRunning = true;
digitalWrite(DIR_PIN, HIGH);
} else if (cmd == "CCW") {
Serial.println("Manual CCW");
manualModeFlag = true;
motorRunning = true;
digitalWrite(DIR_PIN, LOW);
} else if (cmd == "STOP") {
Serial.println("STOP");
motorRunning = false;
} else if (cmd.startsWith("SPD")) {
long spd = cmd.substring(3).toInt();
if (spd >= 100) {
currentDelay = spd;
Serial.print("Manual speed: ");
Serial.println(currentDelay);
} else {
Serial.println("Invalid SPD value");
}
} else if (cmd == "TEST") {
Serial.println("Test: 200 steps CW then CCW");
digitalWrite(DIR_PIN, HIGH);
for (int i = 0; i < 200; i++) {
digitalWrite(PUL_PIN, HIGH);
delayMicroseconds(800);
digitalWrite(PUL_PIN, LOW);
delayMicroseconds(800);
}
delay(500);
digitalWrite(DIR_PIN, LOW);
for (int i = 0; i < 200; i++) {
digitalWrite(PUL_PIN, HIGH);
delayMicroseconds(800);
digitalWrite(PUL_PIN, LOW);
delayMicroseconds(800);
}
Serial.println("Test complete.");
} else {
Serial.print("Unknown: ");
Serial.println(cmd);
}
}