Driving a Air Core Aviation Heading Gauge
Hi,
based on a older solution from https://forum.arduino.cc/index.php/topic,22480.0.html i made my own version for a Collins HDG gauge. It is connected just with 2 resistors. No other hardware is required.
Hope it might be useful for someone.
/* Arduino controls AIRCORE Gauge. E.Staebler 0621
* based on:
* https://forum.arduino.cc/index.php/topic,22480.0.html
* https://www.youtube.com/watch?v=ut9GZJTI3iA
*
* In this version no floating sine calculation is used.
* A 90 degrees lookuptable in byte-resolution directly to feed the 8Bit PWM/DAC is used instead.
*
* Define the pins the meter is connected to. We need 1 PWM to vary the voltage in
* each coil, and one more to reverse the polarity in that coil. So a total of 4 pins.
*/
#include <avr/pgmspace.h>
___
#define SinDirPin 7 // --|___|-- 560R to Sub-D-5 this controls the polarity to the "sine" coil
___
#define CosDirPin 8 // --|___|-- 560R to Sub-D-1 this controls the polarity to the "cosine" coil
#define SinPin 9 // to Sub-D 2 this controls the voltage to the "sine" coil (PWM)
#define CosPin 10 // to Sub-D-4 this controls the voltage to the "cosine" coil (PWM)
// if scale is 180° shifted, wire: Arduino 7 to Sub-D 2
Arduino 8 to Sub-D 4
Arduino 9 to Sub-D 5
Arduino 10 to Sub-D 1
int delayTime = 50; // milliseconds between each angular step.
// Sinustabelle 1.Quadrant 90 Werte 0-89° in 8 Bit Auflösung
const PROGMEM uint8_t Sine_Lookup[90] = // DAC/PWM Lookuptable 0-89 degrees Sine in 8 bit resolution
{
0, 4, 9, 13, 18, 22, 27, 31, 35, 40, 44, 49, 53, 57, 62, 66,
70, 75, 79, 83, 87, 91, 96,100,104,108,112,116,120,124,127,131,
135,139,143,146,150,153,157,160,164,167,171,174,177,180,183,186,
190,192,195,198,201,204,206,209,211,214,216,219,221,223,225,227,
229,231,233,235,236,238,240,241,243,244,245,246,247,248,249,250,
251,252,253,253,254,254,254,255,255,255
};
void setup(){
Serial.begin(115200); // for debugging or remote-setting
pinMode(SinPin, OUTPUT); // Set the pins to OUTPUT
pinMode(CosPin, OUTPUT);
pinMode(SinDirPin, OUTPUT);
pinMode(CosDirPin, OUTPUT);
digitalWrite(SinDirPin, HIGH); // Set the initial direction. (forward).
digitalWrite(CosDirPin, HIGH); // Of course it could be "reverse" depending on which lead you connected :-).
// Vary the PWM-Frequency if noise is annoying (Pin D9+D10)
// TCCR1B = TCCR1B & B11111000 | B00000001; // set timer 1 divisor to 1 for PWM frequency of 31372.55 Hz
TCCR1B = TCCR1B & B11111000 | B00000010; // for PWM frequency of 3921.16 Hz
// TCCR1B = TCCR1B & B11111000 | B00000011; // for PWM frequency of 490.20 Hz (The DEFAULT)
// TCCR1B = TCCR1B & B11111000 | B00000100; // for PWM frequency of 122.55 Hz
// TCCR1B = TCCR1B & B11111000 | B00000101; // for PWM frequency of 30.64 Hz
}
void loop() { // Run over and over again
for(int y = 0; y < 360; y++){ // Rotate 0 through 360 degrees (in degrees!)
setMeterPosition(y);
delay(delayTime); // waits for delayTime milliseconds
}
}
void setMeterPosition(int pos){ // setMeterPosition() - put it at the angle in radians
int sinCoilValue;
int cosCoilValue;
/* PolarityPin and table-read-direction
* Sin Cos
* 0 - 89 + -> + <-
* 90 - 179 + <- - ->
* 180 - 269 - -> - <-
* 270 - 359 - <- + ->
*/
while (pos>359) pos-=360; // while pos>359 subtract 360. just in case ...
if (pos>=270) { // 4. Quadrant 270-359
digitalWrite(SinDirPin, HIGH); // reverse. SinDirPin
digitalWrite(CosDirPin, LOW); // neg. CosDirPin
sinCoilValue=255-pgm_read_byte(&(Sine_Lookup[359-pos])); // reverse SinPin, table-read-direction backwards
cosCoilValue=pgm_read_byte(&(Sine_Lookup[pos-270])); // non-reverse CosPin, table-read-direction forewards
}
else if (pos>=180) { // 3. Quadrant 180-269
digitalWrite(SinDirPin, HIGH); // reverse SinDirPin
digitalWrite(CosDirPin, HIGH); // reverse CosDirPin
sinCoilValue=255-pgm_read_byte(&(Sine_Lookup[pos-180])); // reverse SinPin, table-read-direction forewards
cosCoilValue=255-pgm_read_byte(&(Sine_Lookup[269-pos])); // reverse CosPin, table-read-direction backwards
}
else if (pos>=90) { // 2. Quadrant 90-179
digitalWrite(SinDirPin, LOW); // neg. SinDirPin
digitalWrite(CosDirPin, HIGH); // reverse CosDirPin
sinCoilValue=pgm_read_byte(&(Sine_Lookup[179-pos])); // non-reverse SinPin, table-read-direction backwards
cosCoilValue=255-pgm_read_byte(&(Sine_Lookup[pos-90])); // reverse CosPin, table-read-direction forewards
}
else { // 1. Quadrant 0-89
digitalWrite(SinDirPin, LOW); // neg. SinDirPin
digitalWrite(CosDirPin, LOW); // neg. CosDirPin
sinCoilValue=pgm_read_byte(&(Sine_Lookup[pos])); // non-reverse SinPin, table-read-direction forewards
cosCoilValue=pgm_read_byte(&(Sine_Lookup[89-pos])); // non-reverse CosPin, table-read-direction backwards
}
/*
Serial.print(pos);
Serial.print(": sinCoilValue: "); // Debug
Serial.print(sinCoilValue);
Serial.print(" cosCoilValue: ");
Serial.println(cosCoilValue);
*/
analogWrite(SinPin, sinCoilValue); // set the PWM-Values
analogWrite(CosPin, cosCoilValue);
}