Welcome to Cockpitbuilders.com. Please login or sign up.

April 23, 2024, 08:44:55 AM

Login with username, password and session length

PROUDLY ENDORSING


Fly Elise-ng
151 Guests, 0 Users
Members
  • Total Members: 4,154
  • Latest: xyligo
Stats
  • Total Posts: 59,641
  • Total Topics: 7,853
  • Online today: 174
  • Online ever: 582
  • (January 22, 2020, 08:44:01 AM)
Users Online
Users: 0
Guests: 151
Total: 151

COUNTDOWN TO WF2022


WORLDFLIGHT TEAM USA

Will Depart in...

Recent

Welcome

Real 737 RMI interface

Started by 727737Nut, October 19, 2015, 04:07:54 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

727737Nut

Well I can call this project complete now. In the pic below you will see my RMI interface which I use to drive my real RMI's and also my compass card on my HSI.  Specs, Teensy 3.2, 6ea Pololu drv8825 stepper drivers set for 1/32 micro stepping. Servo city gears and hardware, ebay special 1.8deg 12-24v NEMA14 steppers.  Optical sensors for setting home/0 position at start up. 26vac 400hz synchros which output the angle signal used by the RMI  I have a few flights on it now and works great so i'm happy as a flying pig. :D


737 Junkie

mickc

Awesome Rob!

I'm glad i didn't have to use synchros for mine, i'd have no hair left.  ::)

Interested in seeing how you coded this if you are willing to share

727737Nut

Quote from: mickc on October 19, 2015, 04:16:51 PM
Awesome Rob!

I'm glad i didn't have to use synchros for mine, i'd have no hair left.  ::)

Interested in seeing how you coded this if you are willing to share

It was actually pretty easy, never opened the RMI up.  Key is getting the wire diagram to know which pin is which.   Code is below with one caveat, the stepper4 part of code is for my compass card. it is dead on with the sim except when passing the dreaded 359/0 degree line. It ones to turn a complete turn the opposite way to line back up with the heading instead going step per step across that line.
Rob

Quote//StepperTest
#include <AccelStepper.h>

const int homeButton = 0;
const int homeButton2 = 1;
const int homeButton3 = 2;
const int homeButton4 = 3;

byte hBval;
byte hB2val;
byte hB3val;
byte hB4val;

AccelStepper stepper(1, 21, 20);  //21=Step 20=Dir #31
AccelStepper stepper2(1, 19, 18); //19=Step 18=Dir #32
AccelStepper stepper3(1, 17, 16); //17=Step 16=Dir #33
AccelStepper stepper4(1, 15, 14); //15=Step 14=Dir #34

FlightSimFloat nav1;
FlightSimFloat nav2;
FlightSimFloat adf1;
FlightSimFloat magHdg;

float cur_pos;
float cur_pos2;
float cur_pos3;
float cur_pos4;

void setup() {
  stepper.setMaxSpeed(3000);
  stepper.setAcceleration(3000);
  stepper2.setMaxSpeed(3000);
  stepper2.setAcceleration(3000);
  stepper3.setMaxSpeed(3000);
  stepper3.setAcceleration(3000);
  stepper4.setMaxSpeed(2500);
  stepper4.setAcceleration(3000);
 
  nav1    = XPlaneRef("sim/cockpit2/radios/indicators/nav1_relative_bearing_deg");
  nav2    = XPlaneRef("sim/cockpit2/radios/indicators/nav2_relative_bearing_deg");
  adf1    = XPlaneRef("sim/cockpit2/radios/indicators/adf1_relative_bearing_deg");
  magHdg  = XPlaneRef("sim/cockpit2/gauges/indicators/heading_electric_deg_mag_pilot");
 
  pinMode(homeButton, INPUT_PULLUP);
  pinMode(homeButton2, INPUT_PULLUP);
  pinMode(homeButton3, INPUT_PULLUP);
  pinMode(homeButton4, INPUT_PULLUP);
 
  stepperHome(); //runs routine to home motors
}

void loop() {
  FlightSim.update();

  cur_pos = nav1 * 88.889;
  stepper.moveTo(cur_pos);
  stepper.run();  //ToPosition
 
  cur_pos2 = nav2 * 88.889;
  stepper2.moveTo(cur_pos2);
  stepper2.run();  //ToPosition
 
  cur_pos3 = adf1 * -88.889;
  stepper3.moveTo(cur_pos3);
  stepper3.run();  //ToPosition
 
  if (magHdg < 360) {
  cur_pos4 = magHdg * 88.889;
  }
  else
  cur_pos4 = magHdg * -88.889; //- 360;

  stepper4.moveTo(cur_pos4);
  stepper4.run();  //ToPosition
}

void stepperHome() { //this routine should run the motor
  //stepper1.moveTo(300);
  //stepper1.run();
  delay(100);
  hBval = digitalRead(homeButton);
  while (hBval == LOW)
  {
    //backwards slowly till it hits the switch and stops
    stepper.moveTo(33000);
    stepper.run();
    hBval = digitalRead(homeButton);
  }
  stepper.setCurrentPosition(0); //should set motor position to zero and go back to main routine

delay(50);
hB2val = digitalRead(homeButton2);
while (hB2val == LOW)
{
  //backwards slowly till it hits the switch and stops
  stepper2.moveTo(33000);
  stepper2.run();
  hB2val = digitalRead(homeButton2);

}
stepper2.setCurrentPosition(0); //should set motor position to zero and go back to main routine

delay(50);
hB3val = digitalRead(homeButton3);
while (hB3val == LOW)
{
  //backwards slowly till it hits the switch and stops
  stepper3.moveTo(33000);
  stepper3.run();
  hB3val = digitalRead(homeButton3);

}
stepper3.setCurrentPosition(0); //should set motor position to zero and go back to main routine

delay(50);
hB4val = digitalRead(homeButton4);
while (hB4val == LOW)
{
  //backwards slowly till it hits the switch and stops
  stepper4.moveTo(33000);
  stepper4.run();
  hB4val = digitalRead(homeButton4);

}
stepper4.setCurrentPosition(0); //should set motor position to zero and go back to main routine
}
737 Junkie

matta757

Quote from: mickc on October 19, 2015, 04:16:51 PM
Awesome Rob!

I'm glad i didn't have to use synchros for mine, i'd have no hair left.  ::)

Interested in seeing how you coded this if you are willing to share

Mick,

How did you interface your gauges?

Thanks,
Matt

mickc

Quote from: matta757 on October 21, 2015, 11:23:05 AM
Mick,

How did you interface your gauges?

Thanks,
Matt

Hi Matt.

My RMI is a genuine unit out of a -800 NG and does not use any Synchros like the earlier ones. It uses ARINC 429 decoders and 3 servo motor drives, one for each needle and one for the heading card.

I ditched the ARINC side of it, and converted the servo motor drives to micro stepper motor operation, and added home position sensors. 

Running through SIOC and OC stepper drivers at the moment, but I am in the process of changing over to Arduino as the OC stepper boards aren't quite up to the job.

You can take a look here for more details https://www.facebook.com/media/set/?set=a.747866858655983.1073741838.727065570736112&type=3

mickc

Quote from: 727737Nut on October 19, 2015, 04:35:27 PM

It was actually pretty easy, never opened the RMI up.  Key is getting the wire diagram to know which pin is which.   Code is below with one caveat, the stepper4 part of code is for my compass card. it is dead on with the sim except when passing the dreaded 359/0 degree line. It ones to turn a complete turn the opposite way to line back up with the heading instead going step per step across that line.
Rob

Cheers Rob, thats great

My existing code in SIOC works fine for the wet compass and the heading card on the RMI, no issues with the 359/0 line.  Maybe you can try adapting the section in italics and see if it helps?

QuoteVar 0985, name CMP_HDG
{
  &CMP_STEPPER = &CMP_HDG * 100
}

Var 0990, name MAG_VAR


Var 0981, name FS_MAGVAR, Link FSUIPC_IN, Offset $02A0, Length 2
{
  L0 = &FS_MAGVAR * 0.005493164
  L0 = 360 - L0
  &MAG_VAR = L0   
}

Var 0988, name FS_HDG, Link FSUIPC_IN, Offset $0580, Length 4
{
  L0 = &FS_HDG * 8.3819E-008
  L0 = ROUND L0
  IF L0 < 1
  {
    L0 = L0 + 360
  }
  L1 = L0 + &MAG_VAR
  IF L1 > 360
  {
    L1 = L1 - 360
  }
  &CMP_HDG = L1   
}


Var 1001, name CMP_STEPPER, Link USB_STEPPER, Device 2, Output 1, PosL 3, PosC 0, PosR 7, Type H


727737Nut

QuoteMy existing code in SIOC works fine for the wet compass and the heading card on the RMI, no issues with the 359/0 line.  Maybe you can try adapting the section in italics and see if it helps?

As you will soon learn when going to arduino from sioc, SIOC did allot behind the scenes that with arduino we have to put in.  The code although both C do not interchange.  Below is the new perfectly working code thanks to a generous teacher in Brasil. No more 0-359 issues .

Quote#include <AccelStepper.h>


const int homeButton = 0;
const int homeButton2 = 1;
const int homeButton3 = 2;
const int homeButton4 = 3;


byte hBval;
byte hB2val;
byte hB3val;
byte hB4val;


AccelStepper stepper(1, 21, 20);  //21=Step 20=Dir #31
AccelStepper stepper2(1, 19, 18); //19=Step 18=Dir #32
AccelStepper stepper3(1, 17, 16); //17=Step 16=Dir #33
AccelStepper stepper4(1, 15, 14); //15=Step 14=Dir #34


FlightSimFloat nav1;
FlightSimFloat nav2;
FlightSimFloat adf1;
FlightSimFloat magHdg;


float cur_pos;
float cur_pos2;
float cur_pos3;
float cur_pos4;


const long STEPS_PER_REVOLUTION = 32000;
const float STEPS_PER_DEGREE = ((float) STEPS_PER_REVOLUTION)/360.0;


void setup() {
  Serial.begin(38400);
  stepper.setMaxSpeed(3000);
  stepper.setAcceleration(3000);
  stepper2.setMaxSpeed(3000);
  stepper2.setAcceleration(3000);
  stepper3.setMaxSpeed(3000);
  stepper3.setAcceleration(3000);
  stepper4.setMaxSpeed(2500);
  stepper4.setAcceleration(3000);


  nav1    = XPlaneRef("sim/cockpit2/radios/indicators/nav1_relative_bearing_deg");
  nav2    = XPlaneRef("sim/cockpit2/radios/indicators/nav2_relative_bearing_deg");
  adf1    = XPlaneRef("sim/cockpit2/radios/indicators/adf1_relative_bearing_deg");
  magHdg  = XPlaneRef("sim/cockpit2/gauges/indicators/heading_electric_deg_mag_pilot");


  pinMode(homeButton, INPUT_PULLUP);
  pinMode(homeButton2, INPUT_PULLUP);
  pinMode(homeButton3, INPUT_PULLUP);
  pinMode(homeButton4, INPUT_PULLUP);


  stepperHome(); //runs routine to home motors
}


void loop() {
  FlightSim.update();


  cur_pos = nav1 * STEPS_PER_DEGREE;
  stepper.moveTo(cur_pos);
  stepper.run();  //ToPosition


  cur_pos2 = nav2 * STEPS_PER_DEGREE;
  stepper2.moveTo(cur_pos2);
  stepper2.run();  //ToPosition


  cur_pos3 = adf1 * -STEPS_PER_DEGREE;
  stepper3.moveTo(cur_pos3);
  stepper3.run();  //ToPosition


  long currentPosition = stepper4.currentPosition();
  currentPosition = (currentPosition % STEPS_PER_REVOLUTION + STEPS_PER_REVOLUTION) % STEPS_PER_REVOLUTION; // positive modulo
  long targetPosition = (long) (magHdg * STEPS_PER_DEGREE);


  long cwSteps;
  long ccwSteps;
  if (targetPosition > currentPosition) {
    cwSteps = targetPosition - currentPosition;
    ccwSteps = currentPosition - targetPosition + STEPS_PER_REVOLUTION;
  } else {
    ccwSteps = currentPosition - targetPosition;
    cwSteps = targetPosition - currentPosition + STEPS_PER_REVOLUTION;
  }
   if (cwSteps < ccwSteps) {
     stepper4.move(cwSteps);
  } else {
    stepper4.move(-ccwSteps);
  }
  stepper4.run(); 


}


void stepperHome() { //this routine should run the motor
  delay(100);
  hBval = digitalRead(homeButton);
  while (hBval == LOW)
  {
    //backwards slowly till it hits the switch and stops
    stepper.moveTo(33000);
    stepper.run();
    hBval = digitalRead(homeButton);
  }
  stepper.setCurrentPosition(0); //should set motor position to zero and go back to main routine


  delay(50);
  hB2val = digitalRead(homeButton2);
  while (hB2val == LOW)
  {
    //backwards slowly till it hits the switch and stops
    stepper2.moveTo(33000);
    stepper2.run();
    hB2val = digitalRead(homeButton2);


  }
  stepper2.setCurrentPosition(0); //should set motor position to zero and go back to main routine


  delay(50);
  hB3val = digitalRead(homeButton3);
  while (hB3val == LOW)
  {
    //backwards slowly till it hits the switch and stops
    stepper3.moveTo(33000);
    stepper3.run();
    hB3val = digitalRead(homeButton3);


  }
  stepper3.setCurrentPosition(0); //should set motor position to zero and go back to main routine


  delay(50);
  hB4val = digitalRead(homeButton4);
  while (hB4val == LOW)
  {
    //backwards slowly till it hits the switch and stops
    stepper4.moveTo(33000);
    stepper4.run();
    hB4val = digitalRead(homeButton4);
  }
  stepper4.setCurrentPosition(0); //should set motor position to zero and go back to main routine
}
737 Junkie

Bob Reed


matta757

Question regarding types of gauges... how does one know if a gauge is ARINC?

727737Nut

You need a schematic to be sure.  They can all look alike from the outside and have the exact same connector.  Usually, the the 737 classics and older with partial and full steam gauges are non ARINC. Allot of people confuse ARINC as there are several different ARINC standards.  429 is most common on newer stuff though.  My HSI and RMI use ARINC 561 for the DME, the rest of the pit is pure analog. 
Rob
737 Junkie

Like the Website ?
Support Cockpitbuilders.com and Click Below to Donate