Using a Parallex 360° with Arduino

MatMax:
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

Matmax

You have a basic programming mistake ; The Variables Declaration !

Here I see that dc is not and integer ;

dc=(dutyScale*tHigh)/(tHigh+tLow);

But you have chosen the dc as int ;

int dc,...

You need to declare proper type for your dc variable, for example float could work here.

Hadi