Jump to content

Nearly finished...... but....


Recommended Posts

Posted (edited)

Hi All, I can't believe I am actually saying this, but I am nearly finished* building the rig! I do have to go back and find out why Helios isn't working but that's not really building it.

I have converted most of my sketches and panels successfully to RS485 but there is one issue I can't solve. My Altimeter will work in USB mode but defies all my attempts to make it run under RS485. Now, I could just keep it as a USB sketch but I did intend it to be run on RS485 to reduce the number of USB connections.

I have tried it on its own, with nothing else connected and it just jitters around. I have replace the nano, Max487 chip, tested the IR sensor (as I said, it works in USB mode. The other three nanos on the same PCB run RS485 flawlessly, so it can't be that, or at least not the basic PCB. I have checked it and rechecked it for shorts or open circuits, but can't find any issues with it, although I accept that there may be issues with the design.

Is there anything about the sketch below that would interfere with RS485?

*for a given value of 'finished'.... I know it will never really be finished as I will always find something to improve

//#define DCSBIOS_IRQ_SERIAL

#define DCSBIOS_RS485_SLAVE 49
#define TXENABLE_PIN 2

#include <AccelStepper.h>
#include "DcsBios.h"

#include <Wire.h>




struct StepperConfig {
  unsigned int maxSteps;
  unsigned int acceleration;
  unsigned int maxSpeed;
};


class Vid29Stepper : public DcsBios::Int16Buffer {
  private:
    AccelStepper& stepper;
    StepperConfig& stepperConfig;
    inline bool zeroDetected() {
      return digitalRead(irDetectorPin) == 1;
    }
    unsigned int (*map_function)(unsigned int);
    unsigned char initState;
    long currentStepperPosition;
    long lastAccelStepperPosition;
    unsigned char irDetectorPin;
    long zeroOffset;
    bool movingForward;
    bool lastZeroDetectState;

    long normalizeStepperPosition(long pos) {
      if (pos < 0) return pos + stepperConfig.maxSteps;
      if (pos >= stepperConfig.maxSteps) return pos - stepperConfig.maxSteps;
      return pos;
    }

    void updateCurrentStepperPosition() {
      // adjust currentStepperPosition to include the distance our stepper motor
      // was moved since we last updated it
      long movementSinceLastUpdate = stepper.currentPosition() - lastAccelStepperPosition;
      currentStepperPosition = normalizeStepperPosition(currentStepperPosition + movementSinceLastUpdate);
      lastAccelStepperPosition = stepper.currentPosition();
    }
  public:
    Vid29Stepper(unsigned int address,
                 AccelStepper& stepper,
                 StepperConfig& stepperConfig,
                 unsigned char irDetectorPin,
                 long zeroOffset, unsigned int (*map_function)(unsigned int)): Int16Buffer(address),
      stepper(stepper),
      stepperConfig(stepperConfig),
      irDetectorPin(irDetectorPin),
      zeroOffset(zeroOffset),
      map_function(map_function),
      initState(0),
      currentStepperPosition(0),
      lastAccelStepperPosition(0)
    {
    }

    virtual void loop() {

      if (initState == 0) { // not initialized yet
        pinMode(irDetectorPin, INPUT);
        stepper.setMaxSpeed(stepperConfig.maxSpeed);
        stepper.setSpeed(1000);

        initState = 1;
      }
      if (initState == 1) {
        // move off zero if already there so we always get movement on reset
        // (to verify that the stepper is working)
        if (zeroDetected()) {
          stepper.runSpeed();
        } else {
          initState = 2;
        }
      }
      if (initState == 2) { // zeroing
        if (!zeroDetected()) {
          stepper.runSpeed();
        } else {
          stepper.setAcceleration(stepperConfig.acceleration);
          stepper.runToNewPosition(stepper.currentPosition() + zeroOffset);
          // tell the AccelStepper library that we are at position zero
          stepper.setCurrentPosition(0);
          lastAccelStepperPosition = 0;
          // set stepper acceleration in steps per second per second
          // (default is zero)
          stepper.setAcceleration(stepperConfig.acceleration);

          lastZeroDetectState = true;
          initState = 3;
        }
      }
      if (initState == 3) { // running normally

        // recalibrate when passing through zero position
        bool currentZeroDetectState = zeroDetected();
        if (!lastZeroDetectState && currentZeroDetectState && movingForward) {
          // we have moved from left to right into the 'zero detect window'
          // and are now at position 0
          lastAccelStepperPosition = stepper.currentPosition();
          currentStepperPosition = normalizeStepperPosition(zeroOffset);
        } else if (lastZeroDetectState && !currentZeroDetectState && !movingForward) {
          // we have moved from right to left out of the 'zero detect window'
          // and are now at position (maxSteps-1)
          lastAccelStepperPosition = stepper.currentPosition();
          currentStepperPosition = normalizeStepperPosition(stepperConfig.maxSteps + zeroOffset);
        }
        lastZeroDetectState = currentZeroDetectState;


        if (hasUpdatedData()) {
          // convert data from DCS to a target position expressed as a number of steps
          long targetPosition = (long)map_function(getData());

          updateCurrentStepperPosition();

          long delta = targetPosition - currentStepperPosition;

          // if we would move more than 180 degree counterclockwise, move clockwise instead
          if (delta < -((long)(stepperConfig.maxSteps / 2))) delta += stepperConfig.maxSteps;
          // if we would move more than 180 degree clockwise, move counterclockwise instead
          if (delta > (stepperConfig.maxSteps / 2)) delta -= (long)stepperConfig.maxSteps;

          movingForward = (delta >= 0);

          // tell AccelStepper to move relative to the current position
          stepper.move(delta);

        }
        stepper.run();
      }
    }
};

/* modify below this line */

/* define stepper parameters
   multiple Vid60Stepper instances can share the same StepperConfig object */
struct StepperConfig stepperConfig =
{
  730,  // maxSteps
  2200, // maxSpeed
  1000 // acceleration
};


// define AccelStepper instance
AccelStepper stepper(AccelStepper::DRIVER, 4, 5);  //was 11, 10
// define Vid29Stepper class that uses the AccelStepper instance defined in the line above
//           v-- arbitrary name
Vid29Stepper alt100ftPointer(0x107e,          // address of stepper data
                             stepper,         // name of AccelStepper instance
                             stepperConfig,   // StepperConfig struct instance
                             6,              // IR Detector Pin (must be HIGH in zero position)
                             0,               // zero offset
[](unsigned int newValue) -> unsigned int {
  /* this function needs to map newValue to the correct number of steps */
  return map(newValue, 65535, 0, 0, stepperConfig.maxSteps - 1);
});

void setup() {

  DcsBios::setup();

}

void loop() {

  DcsBios::loop();
  
}

 

 

 

Edited by lesthegrngo
  • Like 1
Posted (edited)

Hi Les,

Congratulations to see the finish line!

If USB is working fine and the glitches come when wiring to the other bus, so did you check if RS485 slave address 49 is already in use with an other device?

Regards, Vinc

Edited by Vinc_Vega

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Posted

Hi Vinc, yeah, I checked the slave number. I set up an Excel spreadsheet to track them that automatically highlights if the number is duplicated, after falling foul of that. Having said that, I can change it and see if it makes a difference

Cheers

 

Les

 

Posted

I'm going to make a new PCB with decoupled circuitry for the IR sensor and nano. I suspect that there is interference or at least interaction between the different nanos, and maybe the stepper driver (A4899) as well, and have them powered separately. I'm not certain it will cure it but I will certainly try it to test.

You can see my sketch above for the Altimeter, and while it works I have always had reservations about it as I don't think that the motion is as smooth as it could be. I'm willing to try different setups, if someone has a sketch that works well plus a schematic of the hardware I would be willing to give it a go. If possible I would prefer not to have to use a stepper driver (and definitely not an EasyDriver!) but as my setup already has 5v and 12v feeds it won't be a problem.

Another change I am going to make is to ditch the USB HDMI devices I am using to drive the 5 small monitors that are used with Helios and MonitorSetup. I have to confess that I have been burying my head in the sand a little on this one, ignoring the obvious issues that I now am facing up to. They work, they are neat and simple to install but the bald fact of the matter is that they are not reliable, and Windows doesn't play very nicely with them for setups like ours.

It is a lottery as to whether Windows will remember the desktop setup that you make, and to have half a chance of this you can't disconnect the USB connection. If you do, even if the PC is powered down, the chances are that when you power up the desktop will default to all the monitors in a horizontal line. This wouldn't be so bad if it was always the same order, but that isn't happening. As a result, all the carefully selected MonitorSetup.lua work goes straight out of the window and you have to mess around with it to reset at least 30% of the time. It also means Helios has to be reset virtually every time you start it, and sometimes the displays simply don't display. Maybe I'm expecting too much from it, but it is not a fit and forget plug and play setup.

I have an old GTX660 that I removed after Windows stopped recognising it as a secondary GPU, I will try and resurrect that.  I also have the GTX1070Ti in my son's desktop I can try, I'm sure he won't complain if I end up replacing that with something better 'cos I stole it. I never really investigated why I couldn't get the second GPU to work (it used to, then a Windows update came along and messed it up) so maybe a bit of sleuthing is in order. Of course, it also means going back to 6 DisplayPort/ HDMI cables, one of the reasons I turned to the USB setup in the first place.

However I don't really think I have much of a choice if I want a good solid reliable setup. There's no doubt that the USB setup packages really nicely, it really did help simplify the whole lot, but it means I can't just jump on the rig and fly, I have to spend 15 to 20 minutes first making sure the configuration is OK. Not workable in the long run

Les

  • Like 1
Posted

Im still trying to convince my Raspberry safely talking to DcsBios for the HSI display. If that works (sometime) the plan is to let another Raspbi reproduce the ADI. So two USB ports would be sucrified in favour to free HDMI ports.

Than only the two head down displays and the radar warner have to be connected to the graphic card.

Regards, Vinc

  • Like 1

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Posted

I, erm, 'borrowed' the GTX 1070Ti from my son's desktop and I'm pleased to say that it is working fine, so I have all six monitors working reliably with an extended desktop that doesn't keep changing. By chance I found a local supermarket selling cheap DisplayPort to HDMI cables, and I was surprised to find they worked absolutely perfectly, so I had ended up with a bit of a plate of spaghetti at the back but a much more reliable setup.

Additionally I managed to export the CDU screen, which I have to say looks really good. 

So that leaves me still trying to get the RWR indicators on the viewport (separate thread), and to try to set up Helios for the HSI, ADI and ASI. I'm working with the Discord channel, who say that it can be done by using CTRL-C and CTRL-V from one of Capt Zeens profiles, so if that works I will let everyone know how I did it

Les 

  • Like 1
Posted (edited)

Right, the Helios thing is done. For those who wish to know how I did it, it was surprisingly easy, if a little bit laborious. A big shout out to MadKreator37 over on the Helios Discord channel, without whose help I would still be struggling

To summarise, the process is as follows.

Firstly, go to your User/saved games/scripts folder and back up your copy of the Export.lua file (call it Exportbak.lua or something like that)

Go to the Capt Zeen website and get one of Capt Zeen's predone profiles, in my case the A10C version, open it in the Helios editor and do the 'reset monitors' thing, setting everything on the main monitor. In my case, opening up the profile showed two monitors, 1 (main monitor) and a second one with a load of stuff on it. Resetting the monitors allows you to tell Helios to move the contents of monitor X to monitor Y. Your monitor setup will be different to mine, but you will almost certainly have a monitor that you view the main game on; make Helios move everything to that one. Do not open two instances of Helios editor as you need to work with everything in one instance of Helios

Please note that when you do this initial work on a main panel called 'Interface status; you may see a load of errors generated. This is normal, and by expanding each section, if there are issues clicking on the little cogwheel setting icon will generally shop you what needs to be done automatically and by accepting it it will fix it for you, although there are some that are a bit more manual (for example where it says you must save the profile before it can be used)

Once you have everything on that monitor, you need to decide what you want and on what monitor to set it on. In my case it was the RWR bezel, the entire HSI, the entire ASI and the entire ADI including the slip ball indicator. The problem is that if you try and look for these they may actually be on sub panels on the main display. On the right hand side you will see a list of all the components being shown in the Layers tab - except it isn't a full list. So, be careful not to delete stuff without knowing what it is.

The other thing that may occur is that the images all come up as red boxes with black crosses through them. That is because the images being used by the profile are in a sub folder you downloaded with the profile in it. To correct this you need to copy the image files and subfolders from the download location into the Helios installation images folder. When you save the copy of the profile you are making it should automatically show the correct images.

Now you have to start deleting things. If you click on the item in the right hand Layers list it will highlight it on the monitor screen (if you double click on the monitor in the top left preview screen it will open in the main panel - be sure to click on the actual number in the middle of the preview as if you don't sometimes it won't open the screen). When you can see that the highlighted item is something you don't need / want, you can delete it.

Continue that process to declutter as much as possible. Eventually you will get to a point where you have a lot less that includes the ones you want, and they may actually be in a sub layer (for instance mine were in a sub-layer called 'main panel'. On the main screen you can double click on these and they will appear in a new screen and all the sub parts will be listed in the Layers tab to the right. Depending on the instrument, clicking on it will open yet another with the sub components of that instrument. Unfortunately that doesn't seem to be very consistent, but it doesn't seem to matter.

So assuming you now have a condensed list with just the items you want (possibly with some unwanted extras) not it is time to put the desired instruments in their correct location. To do this you will copy and paste, using either ctrl-c and ctrl-v or the edit-copy and edit-paste commands. Select say the HSI from the layer list; you will see it highlighted on the main screen. Copy it, then open up the screen you want to put it on, and paste it. Doing this has now copied all the subcomponents and layers, and more importantly all the bindings that let it interact with the DCS info.

Follow the same procedure for all the desired items, placing a copy of each on the appropriate monitor. Obviously save as you go in case of mistakes or issues. When saving, you may get some other errors generated in the 'interface status' tab, just repeat the actions you did earlier and it should all come good. Some errors might remain but are ones that don't affect the workings.

Now you should start the profile using the Helios Control app, and hopefully it will start without errors. If there are any problems it generally will be easy to address, as there is information given. Hopefully it will start OK and so what you will see are two sets of instruments, the original ones on the main screen, and the new ones on the screens you chose.

Start DCS and if all went well, your instruments should all show the game generated data, and work with it. If that is the case, congrats, you can move on the next stage. If not you will need to verify the Interface status, and that the Saved Games Export.lua is referencing Helios, which should have automatically happened when you went through the initial Interface Setup error correction

Now you have to go through the laborious reiterative process of stopping the profile, dragging the individual instruments to the correct size and positions, then restarting the profile to check it. Bear in mind that while the instruments will snap to the borders, this can easily be overridden by simply typing in the desired position in the top right panel. A lot of mine are set at like -5 from the top so the top of the instrument is off the top of the monitor, so that it displays in the exact location to match my laser cut bezel. The same goes for the left position, height and width. You will have to keep starting the profile, checking it for position and aspect ratio and then correcting as necessary.

Once all the positions are correct restart DCS to check that it all works, save it one more time  and then save as another filename so that the working one is still there in case you have issues. 

Once you have done that, go back to the original instruments that are in the wrong place and delete them, leaving only the instruments that you want, and save. If all went well, you new should have a fully working Helios profile.

One other thing that I had to do once I was finished with Helios was to ensure that any viewports I had created were correctly aligned with the Helios instruments. For example, the RWR symbols were way off center, being too far to the left and down. In the Monitor Setup.lua file I then had to adjust the start position (x, y) and once I had that correct I had to make sure that the height and width of the viewport matched the Helios version. Again, this is a reiterative process, where you have to change the numbers, see how it looks, and then change it again until you are happy. 

I would say it took me most of an afternoon to get it all right, but the finished setup looks really great. The thing is that with patience you can do it

One last point - you may have to copy the DCS Bios line (something like dofile blah blah DCS Bios) from the Export.lua you backed up at the beginning in order to get DCS Bios working with it.

I hope that this helps, I am not an expert on Helios but this worked reasonably easily for me

Cheers

Les

Edited by lesthegrngo
  • Like 1
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...