Hi all
For a project where we need to simulate a moving head, we have to use a Parallex 360° High Speed. We need to find a way to control the position of the motor. The idea is that we fill in a certain angle and that the motor changes to that position and stays there until we give it another one. Sadly, both of us don't have a lot of experience with programming.
With the datasheet (https://www.mouser.com/pdfdocs/900-00360-Feedback-360-HS-Servo-v12.pdf) and some examples we found on the internet (including this Forum), we managed to have something that looks good, but doesn't work. (We work with an Arduino Uno)
#include <Servo.h>
Servo nek; //Name the Servo
int pinFeedback=9;
int pinControl=10;
int angle, targetAngle;
int unitsFC = 360; // Units in a full circle
int dutyScale = 1000; // Scale duty cycle to 1/1000ths
int dcMin = 29; // Minimum duty cycle
int dcMax = 971; // Maximum duty cycle
int q2min = unitsFC/4; // For checking if in 1st quadrant
int q3max = q2min * 3; // For checking if in 4th quadrant
int turns = 0; // For tracking turns
// dc is duty cycle, theta is 0 to 359 angle, thetaP is theta from previous
// loop repetition, tHigh and tLow are the high and low signal times for
// duty cycle calculations.
int dc, theta, thetaP, tHigh, tLow;
int errorAngle, output, offset; // Control system variables
void setup() {
pinMode(pinFeedback, INPUT);
pinMode(pinControl,OUTPUT);
unsigned long tHigh;
unsigned long tLow;
}
void loop() {
//feedback
tHigh=pulseIn(pinFeedback,HIGH);
tLow=pulseIn(pinFeedback,LOW);
//dutycycle berekenen
dc=(dutyScale*tHigh)/(tHigh+tLow);
theta = (unitsFC - 1) - ((dc - dcMin) * unitsFC) / (dcMax - dcMin + 1);
thetaP = theta;
//while(1){
int tCycle = 0; // Clear cycle time
while(1) // Keep checking
{
tHigh = pulseIn(pinFeedback, HIGH); // Measure time high
tLow = pulseIn(pinFeedback, LOW); // Measure time low
tCycle = tHigh + tLow;
if((tCycle > 1000) && (tCycle < 1200)) // If cycle time valid
break; // break from loop
}
dc = (dutyScale * tHigh) / tCycle; // Calculate duty cycle
// This gives a theta increasing int the
// counterclockwise direction.
theta = (unitsFC - 1) - // Calculate angle
((dc - dcMin) * unitsFC)
/ (dcMax - dcMin + 1);
if(theta < 0) // Keep theta valid
theta = 0;
else if(theta > (unitsFC - 1))
theta = unitsFC - 1;
// If transition from quadrant 4 to
// quadrant 1, increase turns count.
if((theta < q2min) && (thetaP > q3max))
turns++;
// If transition from quadrant 1 to
// quadrant 4, decrease turns count.
else if((thetaP < q2min) && (theta > q3max))
turns --;
// Construct the angle measurement from the turns count and
// current theta value.
if(turns >= 0)
angle = (turns * unitsFC) + theta;
else if(turns < 0)
angle = ((turns + 1) * unitsFC) - (unitsFC - theta);
thetaP = theta; // Theta previous for next rep
}
//}
//Controle van servobewegingen
// servo_speed(pinControl, 0);
errorAngle = targetAngle - angle; // Calculate error
output = errorAngle * Kp; // Calculate proportional
if(output > 200) output = 200; // Clamp output
if(output < -200) output = -200;
if(errorAngle > 0) // Add offset
offset = 30;
else if(errorAngle < 0)
offset = -30;
else
offset = 0;
//servo_speed(pinControl, output + offset); // Set output
delay(20); // Repeat after 20 ms
}
}
Is there someone here who has an idea how to implement this correctly? Or by any chance has a code that already works and that we could use?
It is part of a project we have at university, in which we have to calculate where a sound source is located based on scattering of sound waves on a sphere. To be able to do this, the 'head' (sphere) should be able to turn. Both of us are Engineering Physics students, so our programming skill is only minimal (and apparently not good enough for this task). It would be stupid that our project doesn't work because of an issue that isn't really something we can work on.
Thanks in advance!
Sincerely,
Matmax