The purpose of this project is to upgrade the existing sound boom system in the Miraco sound laboratory to enable sound measurements using the Direct Method, in accordance with the requirements of ISO 3741.
In this method we measure the sound power & pressure in different 6 positions, we used Stepper motor to control this positions.
First step in design was to take dimension from the current boom
Then I move away everything I didn't need. and drew the chassis in fusion
Then I mounting electrical components
The following part is to hold the two proximity sensors exactly above the gears
After that I moved to the 2nd part of this design which is the controller which will control the stepper motor and show if its moving or it's settled.
I used sheet metal in fusion in order to cut it in the sheet metal workshop
Folded view
Unfolded View
Then I drew the top part of this controller which will hold the electrical components, some component I get their dimensions by measuring directly using Digital Caliper.
Components List
PSN17-8DP Autonics Proximity Sensor
Expansion Board for A4988/Drv8825
Wiring Diagram
I used Voltage Regulator connected between the Proximity Sensor & Arduino nano, because the Proximity Sensor take and give 12 volts, so I needed to decrease the output volt from 12 volts to 5 volts in order to be suitable for Arduino nano.
#include <AccelStepper.h>
// === Stepper setup ===
const int dirPin = 9;
const int stepPin = 8;
const int motorInterfaceType = 1; // Using DRIVER mode (A4988)
AccelStepper stepper(motorInterfaceType, stepPin, dirPin);
const int stepsPerRevolution = 6400;
const float degreesPerStep = 360.0 / stepsPerRevolution;
// === IR sensors (blind area detection) ===
const int sensor1Pin = 11; // 0° sensor
const int sensor2Pin = 12; // 30° sensor
// === Motion parameters ===
const int maxSpeed = 400; // steps/second
const int accel = 100; // steps/second^2
const int red_led = 2;
const int green_led = 3;
const int homing_btn = 4;
// === Variables ===
int switchPins[6] = {A0, A1, A2, A3, A4, A5};
int switchValue[6];
int positionAngles[7] = {0, 30, 90, 160, 230, 290, 340};
// 0 = auto-home reference (30° sensor)
// 1-6 = safe positions
long targetPosition = 0; // in steps
bool homed = false;
int currentPosition;
int prevPosition;
int iterate = 0; // this variable is to detect if there is more one reading from switch for long time then it's autohome position
void setup() {
Serial.begin(9600);
// define switch pins
for (int i=0; i<6; i++) {
pinMode(switchPins[i], INPUT_PULLUP);
}
pinMode(sensor1Pin, INPUT);
pinMode(sensor2Pin, INPUT);
pinMode(green_led, INPUT);
pinMode(red_led, INPUT);
pinMode(homing_btn, INPUT_PULLUP);
stepper.setMaxSpeed(maxSpeed);
stepper.setAcceleration(accel);
}
void loop() {
// === Test switch ===
for (int i=0; i<6; i++) {
switchValue[i] = digitalRead(switchPins[i]);
}
// check if all pin are HIGH for 200 millis then autohome
int pinCounter = 0;
int actualSwitchPos = NULL;
// set previous position
if(actualSwitchPos != currentPosition){
prevPosition = currentPosition;
}
for (int i=0; i<6; i++) {
if(switchValue[i] == LOW){
pinCounter ++;
actualSwitchPos = i+1;
}
}
if(pinCounter == 1 && homed && actualSwitchPos != currentPosition){
moveToPosition(actualSwitchPos);
iterate = 0;
}
else if (pinCounter == 1 && !homed && actualSwitchPos != currentPosition) {
autoHome();
moveToPosition(actualSwitchPos);
iterate = 0;
}
else if (pinCounter == 0) {
iterate ++;
}
// if the button pressed then autohome
if(digitalRead(homing_btn) == LOW){
autoHome();
}
// if a number bigger than 6 is selected in the switch then autohome
if(iterate >= 10 && !homed){
iterate = 0;
autoHome();
}
// === Keep running stepper motion if moving as long as no sensor reading ===
if(checkSensors() == 0)
stepper.run();
}
// ===============================================
// Move to selected safe position
// ===============================================
void moveToPosition(int posNum) {
currentPosition = posNum;
int angle = positionAngles[posNum];
targetPosition = angleToSteps(angle);
Serial.print("Moving to position ");
Serial.print(posNum);
Serial.print(" (");
Serial.print(angle);
Serial.println("°)");
stepper.setSpeed(500);
stepper.moveTo(targetPosition);
while (stepper.distanceToGo() != 0) {
stepper.run(); // uses acceleration & target position
// power green LED & turn off red led
digitalWrite(red_led, LOW);
digitalWrite(green_led, HIGH);
int sensors = checkSensors();
if (sensors == 1 || sensors == 2 && currentPosition-prevPosition < 0) { // any sensor active → stop
Serial.println("⚠️ Blind zone detected! Stopping...");
stepper.stop();
autoHome();
break;
}
}
// power green LED & turn off red led
digitalWrite(red_led, HIGH);
digitalWrite(green_led, LOW);
homed == false;
Serial.println("✅ Position reached.");
}
// ===============================================
// Auto-home routine (move until sensor2 triggers)
// ===============================================
void autoHome() {
Serial.println("🏠 Auto-homing...");
// power green LED & turn off red led
digitalWrite(red_led, LOW);
digitalWrite(green_led, HIGH);
// if it's already infront of the sensor go away then return back to the sensor
if (checkSensors() == 2){
// go away the sensor
stepper.setSpeed(100);
while (checkSensors() == 2) {
stepper.runSpeed();
}
// then return back
autoHome();
}
else{
stepper.setSpeed(-400);
while (checkSensors() != 2) {
stepper.runSpeed();
if(checkSensors() == 2){
break;
}
}
}
stepper.stop();
// delay(100);
// Set current position = 30° reference (home)
stepper.setCurrentPosition(angleToSteps(30));
currentPosition = 1;
homed = true;
// power green LED & turn off red led
digitalWrite(red_led, HIGH);
digitalWrite(green_led, LOW);
Serial.println("✅ Homing complete. Home = 30°");
}
// ===============================================
// Convert angle to steps
// ===============================================
int angleToSteps(int angle) {
return angle / degreesPerStep;
}
int checkSensors(){
// === Safety check: stop if IR sensors detect the blind zone ===
if (digitalRead(sensor1Pin) == HIGH && digitalRead(sensor2Pin) == HIGH) {
return 3;
}
if (digitalRead(sensor2Pin) == HIGH) {
return 2;
}
if (digitalRead(sensor1Pin) == HIGH) {
return 1;
}
return 0;
}
Integrating Boom
Preparing Cables
Integrating Controller