I added
DirIn.setRange(476, 2518);
to my void setup() and there was no increase in servo response. Then I added:
Tur1.setRange(476, 2518);
Tur3.setRange(476, 2518);
And it would not compile. Here's the error method.
C:\Users\npboy\OneDrive\Documents\00 Alabama\SERVO\00_GFCS_r0\00_GFCS_r0.ino: In function 'void setup()':
C:\Users\npboy\OneDrive\Documents\00 Alabama\SERVO\00_GFCS_r0\00_GFCS_r0.ino:61:11: error: 'class MoToServo' has no member named 'setRange'
Tur1.setRange(476, 2518);
^~~~~~~~
C:\Users\npboy\OneDrive\Documents\00 Alabama\SERVO\00_GFCS_r0\00_GFCS_r0.ino:62:11: error: 'class MoToServo' has no member named 'setRange'
Tur3.setRange(476, 2518);
^~~~~~~~
exit status 1
Compilation error: 'class MoToServo' has no member named 'setRange'
Here's my code:
/* 1/96 Scale Model Ship
Gunfire Control System - USS Alabama
Neil Boyle
January 8, 2024
This program controls the turret rotation of a 3 gun battleship
with 3 RC channels on a DX-9 Spektrum Transmitter/Receiver.
Note: Code for Turret #3 (backward facing turret),has not been written yet.
There are 3 Modes of Operation, controlled on ModeSw pin<3>.
1. Centerline Mode: All turrets at centerline
2. Target Mode: All turrets point toward target. Dir can
still move independently.
3. Follow Mode: All turrets move in unison.
DirIn pin<2> is the gun Director input.
Dir pin<9> is the gun Director output.
Tur1 pin<10> is Turret 1 and 2 output.
The Mobatools library is included to servo rotation speed.
The ServoInput library is used for servo angle commands and servo control.
The Servo library is not included because I read that it may interfere
with Mobatools - I'm not sure, I'm just a beginner.
Some of the code my is prabably inefficient or non-professional, but keep in mind
that this is my first time programming in C++. I greatly appreciate all
the help I have been given and continue to receive.
*/
#include <MobaTools.h>
#include <ServoInput.h>
/* The signal pin for ServoInput MUST be an interrupt-capable pin!
Uno, Nano, Mini (328P): 2, 3
Mega, Mega2560: 2, 3, 18, 19, 20, 21
*/
ServoInputPin<2> DirIn; // Director input on pin 2. Rotatry knob on DX-9.
ServoInputPin<3> ModeSw; // Mode Switch on pin 3. 3 Position switch on DX-9.
MoToServo Dir; // I forget what this does, but it's needed,
MoToServo Tur1; // I forget what this does, but it's needed.
MoToServo Tur3; // I forget what this does, but it's needed.
float lastangle; // Last angle of the Director - Floating decimal variable
float Tol; // Tolerance (Tol) = lastangle - angle. Created to minimize servo hunting/jitter.
// It didn't seem to mitigate servo jitter, so I commented it out in the code below.
int position; // Position of Mode Switch (= 1,2 or 3)
void setup() {
Dir.attach(9); // Attaches servo on pin 9 to servo object "Dir"
Tur1.attach(10); // Attaches servo on pin 10 to servo obect "Tur1" T(Turrets 1 and 2)
Tur3.attach(11); // Attaches servo on pin 11 to servo obect "Tur3"
Dir.setSpeed(50); // Set servo rotation speed of Director (5 is final speed, 50 for testing)
Tur1.setSpeed(50); // Set servo rotation speed of Turret 1,2 (5 is final speed, 50 for testing)
Tur3.setSpeed(50); // Set servo rotation speed of Turret 1,2 (5 is final speed, 50 for testing)
DirIn.setRange(476, 2518);
Tur1.setRange(476, 2518);
Tur3.setRange(476, 2518);
Serial.begin(9600); // Serial port comu speed 9600 baud
// Serial.begin(115200);
lastangle = 90.0; // Initialize last angle to centerline = 90 degrees
Tol = 0.0; // Initialize Tol to 0.0
}
void loop() // Main loop
{
/* Read PWM angle on the 3 pos switch on the DX-9 and to decide what mode you desire:
1. Modeangle < 30 degrees (position 0 on switch): Move Turrets to Centerline
2. Modeangle > 120 degrees (position 2 on switch): Move Turrets using Follow Mode
3. All else, Modeangle (position 3 on switch): Move Turrets using Target Mode
Crude method, but it seems to work. I was unsuccessful with many attempts to use
case commands and other commands to make the switch reading an integer, etc.
*/
float angle = DirIn.getAngle(); // get angle of Director input from DX-9 (0 - 180)
Tol = lastangle - angle; // Don't do anything unless Tol is > than say 1.5 degrees: Tol = lastangle - angle
float Modeangle = ModeSw.getAngle(); // Determine angle of 3 pos switch on DX-9
if(Modeangle < 30.0)
{movecntrl();} // If < 30 degrees, run movecntrl (move turrets to centerline) function
else if(Modeangle > 120.0) // If < 120 degrees, run followmode (all turrets follow Director) function
{followmode();}
else // If neither above, run trgtmode (Director moves independently, turret remain at last positon)
{trgtmode();}
Serial.print("Modeangle: "); // Print to Serial Monitor for debuggimg
Serial.println(Modeangle);
Serial.println();
Serial.print("Director Input: ");
Serial.print(DirIn.getAngle());
Serial.println();
} // End of Main Loop
void movecntrl() // Function to Move turrets to centeline
{
//Dir.attach(9); // Reattach Dir and Tur1. Detached them at end of this
//Tur1.attach(10); // of this function to try to mitigate servo jitter.
//Dir.setSpeed(5); // Reset servo rotation speed of Director (5 is final speed, 50 for testing)
//Tur1.setSpeed(5); // RTest servo rotation speed of Turret 1,2 (5 is final speed, 50 for testing)
Dir.write(90);
Tur1.write(90);
Tur3.write(90);
//delay(20); // Delay 0.5 sec to complete write statements before
//Dir.detach(); // Detach to try to mitigate servo jitter.
//Tur1.detach();
}
void trgtmode() // Function to Move turrets to Director (DirIn) position
{
//Dir.attach(9); // Reattach Dir and Tur1. Detached them at end of this
//Tur1.attach(10); // of this function to try to mitigate servo jitter.
//Dir.setSpeed(50); // Reset servo rotation speed of Director (5 is final speed, 50 for testing)
//Tur1.setSpeed(50); // RTest servo rotation speed of Turret 1,2 (5 is final speed, 50 for testing)
float angle = DirIn.getAngle(); // get angle of Director input from DX-9 (0 - 180)
Tol = lastangle - angle; // Don't do anything unless Tol is > than say 1.5 degrees: Tol = lastangle - angle
if(abs(Tol > 10.0));
Dir.write(angle);
lastangle = angle;
//delay(20); // Delay 0.5 sec to complete write statements before
//Dir.detach(); // Detach to try to mitigate servo jitter.
//Tur1.detach();
//}
}
void followmode() // Function to have turrets follow Director
{
//Dir.attach(9); // Reattach Dir and Tur1. Detached them at end of this
//Tur1.attach(10); // of this function to try to mitigate servo jitter.
//Dir.setSpeed(5); // Reset servo rotation speed of Director (5 is final speed, 50 for testing)
//Tur1.setSpeed(5); // RTest servo rotation speed of Turret 1,2 (5 is final speed, 50 for testing)
float angle = DirIn.getAngle(); // get angle of Director input from DX-9 (0 - 180)
Tol = lastangle - angle; // Don't do anything unless Tol is > than say 1.5 degrees: Tol = lastangle - angle
if(abs(Tol > 10.0));
Dir.write(angle);
Tur1.write(angle);
moveTur3();
lastangle = angle;
//delay(20); // Delay 0.5 sec to complete write statements before
//Dir.detach(); // Detach to try to mitigate servo jitter.
//Tur1.detach();
}
/* Moving Turret #3
Backward facing Turret #3 is rotationally automated when the targeted position is in, or near, the port or
starboard "quadrants". With the DS3218mg Servos, the "quadrants" currently achieve 34 degrees of actual
rotation: 17 degrees on either side of the perpendicular, starting on the starboard side at 0 degrees
t0 34 degrees, then on the port side at 180 degrees to 214 degrees. Dead ahead, by servo instruction, is 107
degrees. So the DS3218 "270 Degree" servos only actually acheive 214 degrees, with the Spektrum DX-9 servo
travel set to 150%, and using the Arduino getAngle() function from 0 - 180 degrees.
Here is a calibration guide:
Switch "C" Command Actual Serial Mon Pulse Width Display Comment
0 0 -107 0 702 107 degrees stbd from dead ahead
1 90 0 90 1503 Dead ahead
2 180 234 180 2303 214 degrees, 107 port
Stbd Quad 0-34 Actual Degrees,
Port Quad 180-214 Actual Degrees. If Dir is leaving Port Quad leave Tur 3 as is until 120 degrees
*/
void moveTur3() // Function to move Turret 3
{
float angle = DirIn.getAngle(); // get angle of Director input from DX-9 (0 - 180)
if((angle >= 0) && (angle < 34)) // If Dir is in the Starboard quadrant then train Turret 3 to there
{Tur3.write((angle+146));}
else if((angle > 146) && (angle <= 180)) // If Dir is in the Port quadrant then train Turret 3 to there
{Tur3.write((angle-146));}
else if((angle <= 146) && (angle > 120 )) // If Dir is leaving the Port Quadrant, leave Turret 3 there until 120 degrees
{Tur3.write(0);}
else // If not then move Turret 3 back to it's centerline
{Tur3.write(90);}
lastangle = angle; // reset lastangle to most current angle
}