Jump to content

Recommended Posts

Posted (edited)

All, as I am unable to make an RS485 network function for me, I have written this sketch to allow you to connect multiple stepper motors to one Arduino Mega2560 and connect via 1 USB connection. It will allow up to 23 stepper drivers to be driven, and as of today I have had 16 gauges running simultaneously (all 10 engine gauges, both APU gauges, both hydraulic gauges and both fuel quantity gauges) without any significant lag or slow down during the game. You will notice that the initial gauge self calibration part is significantly slower, but once that is finished the operation is good.

 

I have found it to connect reliably and function reliably and repeatably. Each gauge can be individually calibrated (you can add additional gauges and stepperConfifg instances as required up to the max of 23)

 

When used with EasyDriver stepper drivers it only requires 2 wires for each stepper driver, one for step and one for direction, as from my tests there is no need to connect the arduino 5v and GND, although a common GND may be desirable. The problem I find with EasyDriver boards is that in my experience they are fragile and don't handle loose connections , and they also tend to run worryingly hot, even with low power stepper motors like the X27-68's I used. Obviously you need a power supply for the stepper drivers, I used a 12v supply.

 

For use with A4988 drivers, you will have to connect the Mega 5v and GND as well as the step and direction pins. You will also have to reduce the maxsteps value in the calibration down to something like 200 instead of circa 4000 for the EasyDriver boards. However the A4988s seem to be more reliable, come with heatsinks that keep them at a reasonable temperature and subjectively seem to deliver smoother control of the stepper motor. As with the EasyDrivers you will require a 12v power supply a well

 

The code is below, and please note that I am no expert on this - I just kept at this until I got it working. However it does work

 

#define DCSBIOS_IRQ_SERIAL

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

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


class Vid29Stepper : public DcsBios::Int16Buffer {
 private:
   AccelStepper& stepper;
   StepperConfig& stepperConfig;
   unsigned int (*map_function)(unsigned int);
   unsigned char initState;
 public:
   Vid29Stepper(unsigned int address, AccelStepper& stepper, StepperConfig& stepperConfig, unsigned int (*map_function)(unsigned int))
   : Int16Buffer(address), stepper(stepper), stepperConfig(stepperConfig), map_function(map_function), initState(0) {
   }

   virtual void loop() {
     if (initState == 0) { // not initialized yet
       stepper.setMaxSpeed(stepperConfig.maxSpeed);
       stepper.setAcceleration(stepperConfig.acceleration);
       stepper.moveTo(-((long)stepperConfig.maxSteps));
       initState = 1;
     }
     if (initState == 1) { // zeroing
       stepper.run();
       if (stepper.currentPosition() <= -((long)stepperConfig.maxSteps)) {
         stepper.setCurrentPosition(0);
         initState = 2;
         stepper.moveTo(stepperConfig.maxSteps/2);
       }
     }
     if (initState == 2) { // running normally
       if (hasUpdatedData()) {
         unsigned int newPosition = map_function(getData());
         newPosition = constrain(newPosition, 0, stepperConfig.maxSteps);
         stepper.moveTo(newPosition);
       }
       stepper.run();
     }
   }
};


/* define stepper parameters for each guage, calculate maxSteps number to suit gauge then call out rekevant stepperConfig instance against particular gauge
   */


struct StepperConfig stepperConfig01 = {
 3900,  // maxSteps
 1000, // maxSpeed
 1000 // acceleration
 };
 
 struct StepperConfig stepperConfig02 = {
 5000,  // maxSteps
 1000, // maxSpeed
 1000 // acceleration
 };
 
 struct StepperConfig stepperConfig03 = {
 4350,  // maxSteps
 1000, // maxSpeed
 1000 // acceleration
 };
 
 struct StepperConfig stepperConfig04 = {
 4790,  // maxSteps
 1000, // maxSpeed
 1000 // acceleration
 };
 
 struct StepperConfig stepperConfig05 = {
 4240,  // maxSteps
 1000, // maxSpeed
 1000 // acceleration
 };
 
 struct StepperConfig stepperConfig06 = {
 3900,  // maxSteps
 1000, // maxSpeed
 1000 // acceleration
 };
 
 struct StepperConfig stepperConfig07 = {
 4194,  // maxSteps
 1000, // maxSpeed
 1000 // acceleration
 };
 

// first named number is step and the second is direction 
// for standard Mega 2560 board I have tested pins 2 to 13 and 2 to 35, giving a total of 23 pin pairs

AccelStepper stepper01(AccelStepper::DRIVER, 13, 12);
AccelStepper stepper02(AccelStepper::DRIVER, 11, 10);
AccelStepper stepper03(AccelStepper::DRIVER, 9, 8);
AccelStepper stepper04(AccelStepper::DRIVER, 52, 50);
AccelStepper stepper05(AccelStepper::DRIVER, 3, 2);
AccelStepper stepper06(AccelStepper::DRIVER, 48, 46);
AccelStepper stepper07(AccelStepper::DRIVER, 7, 6);
AccelStepper stepper08(AccelStepper::DRIVER, 5, 4);
AccelStepper stepper09(AccelStepper::DRIVER, 44, 42);
AccelStepper stepper10(AccelStepper::DRIVER, 40, 38);
AccelStepper stepper11(AccelStepper::DRIVER, 36, 34);
AccelStepper stepper12(AccelStepper::DRIVER, 32, 30);

Vid29Stepper lEngTempBuffer(0x10b4, stepper01, stepperConfig01, [](unsigned int newValue) -> unsigned int {

 return map(newValue, 0, 65535, 0, stepperConfig01.maxSteps);
});

Vid29Stepper apuRpmBuffer(0x10be, stepper02, stepperConfig06, [](unsigned int newValue) -> unsigned int {

 return map(newValue, 0, 65535, 0, stepperConfig06.maxSteps);
});

Vid29Stepper apuTempBuffer(0x10c0, stepper03, stepperConfig07, [](unsigned int newValue) -> unsigned int {

 return map(newValue, 0, 65535, 0, stepperConfig07.maxSteps);
}); 

Vid29Stepper lEngCoreBuffer(0x10a8, stepper04, stepperConfig03, [](unsigned int newValue) -> unsigned int {

 return map(newValue, 0, 65535, 0, stepperConfig03.maxSteps);
}); 

Vid29Stepper rEngCoreBuffer(0x10ac, stepper05, stepperConfig03, [](unsigned int newValue) -> unsigned int {

 return map(newValue, 0, 65535, 0, stepperConfig03.maxSteps);
}); 

Vid29Stepper rEngTempBuffer(0x10b8, stepper06, stepperConfig01, [](unsigned int newValue) -> unsigned int {

 return map(newValue, 0, 65535, 0, stepperConfig01.maxSteps);
}); 

Vid29Stepper lEngFanBuffer(0x10a2, stepper07, stepperConfig02, [](unsigned int newValue) -> unsigned int {

 return map(newValue, 0, 65535, 0, stepperConfig02.maxSteps);
}); 

Vid29Stepper lEngFuelFlowBuffer(0x10ae, stepper08, stepperConfig04, [](unsigned int newValue) -> unsigned int {

 return map(newValue, 0, 65535, 0, stepperConfig04.maxSteps);
}); 

Vid29Stepper lOilPressBuffer(0x10c6, stepper09, stepperConfig05, [](unsigned int newValue) -> unsigned int {

 return map(newValue, 0, 65535, 0, stepperConfig05.maxSteps);
}); 

Vid29Stepper rEngFanBuffer(0x10a4, stepper10, stepperConfig02, [](unsigned int newValue) -> unsigned int {

 return map(newValue, 0, 65535, 0, stepperConfig02.maxSteps);
});

Vid29Stepper rEngFuelFlowBuffer(0x10b0, stepper11, stepperConfig04, [](unsigned int newValue) -> unsigned int {

 return map(newValue, 0, 65535, 0, stepperConfig04.maxSteps);
});

Vid29Stepper rOilPressBuffer(0x10c8, stepper12, stepperConfig05, [](unsigned int newValue) -> unsigned int {

 return map(newValue, 0, 65535, 0, stepperConfig05.maxSteps);
});

void setup() {
 DcsBios::setup();
}

void loop() {
 DcsBios::loop();
}

 

The code could probably do with someone who knows what they are doing having a look at it to tidy it up. In the form above it is set up for EasyDrivers driving the 10 basic engine gauges plus the two APU gauges, with seven steperConfig calibrations.

 

You can also connect I2C devices to the SDA and SCL pins, I had an LCD an an OLED display working on it (individually, not together). I do not recommend that you use a scrolling OLED display like the altimeter one with stepper drivers though, I note that it hugely slows response time, smoothness and speed of the steppers.

 

This is complementary to the RS485 system, and you may find that for some devices RS485 does a better job, but this at least will reduce the USB connections.

 

I hope this helps someone

 

Cheers

 

Les

Edited by lesthegrngo
  • Recently Browsing   0 members

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