Also working on making a compass for flight simulator.
Hopefully the following code will help answer the question.
This is a working code that I have tested using serial monitor...
Note: For Flight Sim use, I did find that to get enough speed and smooth movement for the X27-168 gauge motor you need to use a stepper driver with microstepping rather than driving the X27-168 directly from the Nano I/O pins. You will have to adjust Max speed & acceleration and also edit the firmware for micro-stepping with using a stepper driver. Note: When using a stepper driver chip, you need to use the correct type for 6 step coil energising that the X27-168 stepper uses eg. AX1201728SG. Polulu (A4988) type stepper drivers use 8 steps coil energisation which will not move the gauge motor correctly - while it will move the gauge motor it creates a lot of noise and is not ideal.
I did have to add the following to get both left and right movements through North.
I used Movement rather than delta -
if(Movement( < -180){Movement = Movement + 360;}
A single movement of 180 degrees defaults to CCW direction. however with Flight simulator data extraction, you shouldn't get a single movement of that amount.
/*Analog Compass Gauge.**
This uses an Arduino Nano processor that has four of its I/O's directly connected to an X27-168 geared stepper motor(Gauge indicator motor).
While it works, there should really be four sets of protection diodes across each of the I/O pins - diode to +5V & diode to 0V to eliminate spikes over 5v and below 0v on each I/O pin.
The X27-168 geared stepper motor has had the internal stop cut off on the main output shaft gear to allow full 360 degree movement.
A 55mm dia plastic round plate has been fitted to the X27-168 geared stepper motor 1mm diameter drive shaft and a printed label attached to the plate to show compass direction.
The plastic plate has a small Neodymium magnet (1mm dia x 2mm long) which can pass near a Hall Effect sensor (A3144)to provide a homing reference signal.
+5v,0v and I/O signal pin is connected directly to the Hall Effect sensor. The Nano internal I/O resistor is used to provide a pullup voltage for the Hall effect sensor signal. The firmware uses the AccelStepper library.
PC Serial Monitor is used to enter new compass headings.
The X27-168 geared stepper motor is referred to as "stepper1" in the firmware.
*/
#include "AccelStepper.h"
AccelStepper Stepper1(AccelStepper::FULL4WIRE, 3, 4, 5, 6); // Define stepper I/O pins (Using I/O pins connected directly to X27-168 Geared Stepper Motor)
//AccelStepper Stepper1(AccelStepper::DRIVER, 2, 5); // Defines I/O pins when using a stepper driver e.g. AX1201728SG Quad driver chip - Dir pin - Stepper pin
#define Home_Sensor 2 // Pin 2 - Connected to Home Sensor - Hall Effect A3144- (0v when sensed)
int Offset = -67; // ****** Adjust this setting to ensure North facing when at Home Position(0) ******
int MaxSpeed = 80; // ****** Adjust this setting for Max Speed of Stepper as to not miss steps ******
int Acceleration = 25 // ****** Adjust this setting for Acceleration of Stepper as to not miss steps ******
int Move_finished = 1; // Used to check if move is completed
long Initial_Homing = -1; // Used to Home Stepper at startup
String InputString = ""; // String to hold incoming data from serial monitor
bool StringComplete = false; // Whether the string is complete
int LastHeading = 0; // Register for Last heading
int NewHeading = 0; // Register for New heading
int Movement; // Register for difference between Last and New heading
void setup() {
Serial.begin(9600); // Start the Serial monitor at 9600 Baud
pinMode(Home_Sensor, INPUT_PULLUP); // Using internal pullup for Hall Effect sensor
delay(5); // Wait for stepper Driver wake up (if used)
Stepper1.setMaxSpeed(MaxSpeed); // Intial Homing Max Speed of Stepper (Slower to get better accuracy)
Stepper1.setAcceleration(Acceleration ); // Intial Homing Acceleration of Stepper
Serial.println("........ Homing Stepper ........");
while (digitalRead(Home_Sensor)) { // Make the Stepper1 move CW until the sensor is activated
Stepper1.moveTo(Initial_Homing); // Set the position to move to
Initial_Homing--; // Decrease by 1 for next move if needed
Stepper1.run(); // Start moving stepper1
delay(5);
}
Stepper1.setCurrentPosition(0); // Set the current position as zero for now
Initial_Homing=1;
while (!digitalRead(Home_Sensor)) { // Make the Stepper1 move CCW until the sensor is deactivated
Stepper1.moveTo(Initial_Homing);
Stepper1.run();
Initial_Homing++;
}
//**** Should now be Homed to Magnet position which may not be North as per label. Below allows tuning to correct position of label ****
Stepper1.setCurrentPosition(0);
Stepper1.setMaxSpeed(MaxSpeed); // Intial Homing Correction Max Speed of Stepper1
Stepper1.setAcceleration(Acceleration ); // Intial Homing Correction Acceleration of Stepper1
Stepper1.moveTo(Offset); // To correct to have North as Home position
while(Stepper1.distanceToGo() != 0){Stepper1.run();} // Step to adjusted home position
Stepper1.setCurrentPosition(0); // Set Home position that will be used for all further movements..
Serial.println("........ Homing Completed ........");
Serial.println(" *** Enter Compass Heading 0 - 259 Degrees ***");
// --------- End of intial Homing Setup ------------
}
void loop() {
while (Serial.available() > 0) { // Read serial input:
int InChar = Serial.read();
if (isDigit(InChar)) {InputString += (char)InChar;} // Convert the incoming byte to a char and add it to the string
if (InChar == '\n') { // If you get a newline,
NewHeading = (InputString.toInt()); // Convert input heading string to int value heading
NewHeading = (NewHeading/2)*2; // Eliminates 1 degree movements. Reduces movement errors with small movements
Serial.print(NewHeading);
if(NewHeading > 359 ||NewHeading < 0) { // Displays error message if input is out of range
NewHeading = LastHeading; // No change due to incorrect data entered
Serial.println("Input Error. Enter value between 0 - 259 Degrees ");
}
else { Serial.print("Heading "); Serial.print(NewHeading); Serial.println("... Enter New Heading");
}
InputString = ""; // Clear the string for new input:
Movement = ((NewHeading + 180 - LastHeading) % 360) - 180; // Allows movement from North East to North West
if(Movement < -180){Movement = Movement + 360;} // Allows movement from North West to North East
Stepper1.setCurrentPosition(0); // Zero the motor.
Stepper1.setMaxSpeed(MaxSpeed); // Set Max Speed of Stepper1
Stepper1.setAcceleration(Acceleration ); // Set Acceleration of Stepper1
Stepper1.move(Movement*2); // Set new move to position of Stepper1
LastHeading = NewHeading; // New heading now becomes last heading
}
}
while(Stepper1.distanceToGo() != 0){Stepper1.run(); // Keep updating AccelStepper for current movement
int XInChar = Serial.read();XInChar = Serial.read();} // Keep clearing serial buffer- Only allow new heading input once movement finished.
}