Jump to content

Stepper x27 and DCS Bios request


Johan4668

Recommended Posts

Hi, trying to learn and to get to understand the script... so i came up with some questions.

Can you help me through the script above.

line 33 --------------------------------------------------------------------

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();
   }

---------------------------------------------------------------------

What can i do here? is this to set the offset of like,.

void updateCurrentStepperPosition(100)

and where does i see what stepper it is..

or..

Line 78 --------------------------------------------------------------------

 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;

-----------------------------------------------------------------------------

can we do something here...

133 -------------------------------------------------------------------------------

/* modify below this line */

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


// define AccelStepper instance
AccelStepper stepper1(AccelStepper::HALF4WIRE , 10, 11, 13, 12);
// define Vid60Stepper class that uses the AccelStepper instance defined in the line above
//           v-- arbitrary name
Vid60Stepper AltimeterFineptr(0x424a,          // address of stepper data DCS
                            stepper1,         // name of AccelStepper instance
                            stepperConfig,   // StepperConfig struct instance
                            9,              // 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, 0, 65535, 0, stepperConfig.maxSteps-1);
});

-------------------------------------------------------------------------------------------------

This is for stepper 1 0-1000..

Max steps.. is there a calculation for that?

Max speed.. speed what range? 4000 is ok in this case.. 

Acceleration..  dont know how to see that..

 

185-------------------------------------------------------------------------------

stepper0.runToNewPosition(1260); // go to the upper end stop
    delay(250);
    stepper0.setCurrentPosition(1260); // set max steps
    stepper0.runToNewPosition(0);    // go to the lower end stop
    delay(250);

-------------------------------------------------------------------------------------

What can we do here?

sorry for all those questions.. i really interested.

 

Johan

 

 

Link to comment
Share on other sites

this is for the nano..
 
#ifdef RS485
  #define DCSBIOS_RS485_SLAVE 1 // change according your slave number (1 to 128)
  #define TXENABLE_PIN 2
#endif
------------------------------------
What can i use for the Mega?
 

20230323_143821.jpg


Edited by Johan4668
Link to comment
Share on other sites

1 hour ago, Johan4668 said:
this is for the nano..
 
#ifdef RS485
  #define DCSBIOS_RS485_SLAVE 1 // change according your slave number (1 to 128)
  #define TXENABLE_PIN 2
#endif
------------------------------------
What can i use for the Mega?
 

20230323_143821.jpg

 

For the Mega please use the RS485Master.ino sketch from the dcs-bios-arduino-library example folder.

Regards, Vinc


Edited by Vinc_Vega

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

1 hour ago, Johan4668 said:

this is sometime confusing.. just to be sure...

this code says 

stepper1(AccelStepper::HALF4WIRE , 10, 11, 13, 12)
 
that means the stepper must connected like this to the nano?
 

Screenshot 2023-03-23 151616.png

Connections look good to me.

Regards, Vinc

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

On 3/23/2023 at 12:07 PM, Johan4668 said:

Hi, trying to learn and to get to understand the script... so i came up with some questions.

Can you help me through the script above.

line 33 --------------------------------------------------------------------

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();
   }

---------------------------------------------------------------------

What can i do here? is this to set the offset of like,.

void updateCurrentStepperPosition(100)

and where does i see what stepper it is..

or..

Line 78 --------------------------------------------------------------------

 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;

-----------------------------------------------------------------------------

can we do something here...

133 -------------------------------------------------------------------------------

/* modify below this line */

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


// define AccelStepper instance
AccelStepper stepper1(AccelStepper::HALF4WIRE , 10, 11, 13, 12);
// define Vid60Stepper class that uses the AccelStepper instance defined in the line above
//           v-- arbitrary name
Vid60Stepper AltimeterFineptr(0x424a,          // address of stepper data DCS
                            stepper1,         // name of AccelStepper instance
                            stepperConfig,   // StepperConfig struct instance
                            9,              // 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, 0, 65535, 0, stepperConfig.maxSteps-1);
});

-------------------------------------------------------------------------------------------------

This is for stepper 1 0-1000..

Max steps.. is there a calculation for that?

Max speed.. speed what range? 4000 is ok in this case.. 

Acceleration..  dont know how to see that..

 

185-------------------------------------------------------------------------------

stepper0.runToNewPosition(1260); // go to the upper end stop
    delay(250);
    stepper0.setCurrentPosition(1260); // set max steps
    stepper0.runToNewPosition(0);    // go to the lower end stop
    delay(250);

-------------------------------------------------------------------------------------

What can we do here?

sorry for all those questions.. i really interested.

 

Johan

 

 

Vinc can you help me understand the above?

Link to comment
Share on other sites

On 3/23/2023 at 5:13 PM, Vinc_Vega said:

Connections look good to me.

Regards, Vinc

Something is not right in the code.. the stepper of the needle is going with noise and not smooth and the disk is going fast and smooth no noise.. when i exchange the stepper connection numbers in the Sketch it si the other way around..  so it looks that the needle code is something not right

Link to comment
Share on other sites

and the rs485

This in the Master.. and pin 2

----------------------------------------------------------------------------
/*
  The following #define tells DCS-BIOS that this is a RS-485 slave device.
  It also sets the address of this slave device. The slave address should be
  between 1 and 126 and must be unique among all devices on the same bus.
*/
#define DCSBIOS_RS485_SLAVE 1
 
/*
  The Arduino pin that is connected to the
  /RE and DE pins on the RS-485 transceiver.
*/
#define TXENABLE_PIN 2
 
#include "DcsBios.h"
 
/* paste code snippets from the reference documentation here */
 
void setup() {
  DcsBios::setup();
}
 
void loop() {
  DcsBios::loop();
}
--------------------------------------------------------------------------------
this in the slave also on pin2.. 
------------------------------------------------------------------------
#define RS485  // default is USB mode, uncomment for using at the RS485 bus
 
#ifndef RS485
  #define DCSBIOS_IRQ_SERIAL  // use for Arduino UNO, NANO and MEGA
  // #define DCSBIOS_DEFAULT_SERIAL  // use for other boards like ESP32 or Raspberry Pi Pico
#endif
 
#ifdef RS485
  #define DCSBIOS_RS485_SLAVE 1 // change according your slave number (1 to 128)
  #define TXENABLE_PIN 2
#endif
 
#include <AccelStepper.h>
#include "DcsBios.h"
 
// sea level knob
DcsBios::RotaryEncoder altPressSet("ALT_PRESS_SET", "-3200", "+3200", A1, A2);
 
-------------------------------------------------------------------------
 
 
do i miss something that it is not working?
 
Link to comment
Share on other sites

Hi Johan,

I am not the author of the altimeter code and therefore have les ideas what it does. I only merged the lines for the needle with that of the km disk.

It is possible, that the code for the km disk blocks the needle code, but I have no idea how to use the stepper class for a motor without IR sensor (that of the km disk).

A way to verify blocking is to connect only one stepper to the arduino and going airborne. Use the same pin configuration for that test (e.g. 5,6,7,8). You therefore have to exclude the coding for the other stepper.

If both stepper behaves good when standalone than you probably have to use several Nanos to drive the two motors.

Furthermore it is a good idea first to get rid of all problems in the USB configuration. If all works fine you may go the RS458 way and have a look if the behavior is still good.

 

If you want to reduce the turn angle of the km disk, you have to look into the map function

int stepperPosition = map(newValue, 0, 65535, 0, 1260);

1260 steps are for a 315 degree angle (that is between both endstops) with 4 steps per degree (315 * 4 = 1260).

If you want to turn only 270degrees you have to change the value accordingly (270 * 4 = 1080).

This is half step mode (HALF4WIRE ) and probably may be changed into full step mode (3 steps per degree ??? depending on your stepper type) FULL4WIRE.

You than have to find the correct number of steps for a turn of your motor.

 

For the RS485 Master you have to use an Arduino MEGA and the RS485Master.ino sketch that is in your dcs-bios-arduino-library/Examples folder.

 

Regards, Vinc


Edited by Vinc_Vega

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

16 hours ago, Vinc_Vega said:

Hi Johan,

I am not the author of the altimeter code and therefore have les ideas what it does. I only merged the lines for the needle with that of the km disk.

It is possible, that the code for the km disk blocks the needle code, but I have no idea how to use the stepper class for a motor without IR sensor (that of the km disk).

A way to verify blocking is to connect only one stepper to the arduino and going airborne. Use the same pin configuration for that test (e.g. 5,6,7,8). You therefore have to exclude the coding for the other stepper.

If both stepper behaves good when standalone than you probably have to use several Nanos to drive the two motors.

Furthermore it is a good idea first to get rid of all problems in the USB configuration. If all works fine you may go the RS458 way and have a look if the behavior is still good.

 

If you want to reduce the turn angle of the km disk, you have to look into the map function

int stepperPosition = map(newValue, 0, 65535, 0, 1260);

1260 steps are for a 315 degree angle (that is between both endstops) with 4 steps per degree (315 * 4 = 1260).

If you want to turn only 270degrees you have to change the value accordingly (270 * 4 = 1080).

This is half step mode (HALF4WIRE ) and probably may be changed into full step mode (3 steps per degree ??? depending on your stepper type) FULL4WIRE.

You than have to find the correct number of steps for a turn of your motor.

 

For the RS485 Master you have to use an Arduino MEGA and the RS485Master.ino sketch that is in your dcs-bios-arduino-library/Examples folder.

 

Regards, Vinc

 

Yes, I changed it to FULLWIRE and it went a little better.. then i changed the pins.. when i use pin 13 it goes rough and 9-10-11-12 it goes around smooth.. so that is 1 thing solved using only the script of the needle. )not tsted yet on DCS.

now iam going to do only the disk, and combine it when it works perfect..

and the rs458 i used the RS485Master.ino on the Mega but that is for later... 

 

keep you updated

 

Johan

 

 

 

Link to comment
Share on other sites

22 hours ago, Vinc_Vega said:

Hi Johan,

I am not the author of the altimeter code and therefore have les ideas what it does. I only merged the lines for the needle with that of the km disk.

It is possible, that the code for the km disk blocks the needle code, but I have no idea how to use the stepper class for a motor without IR sensor (that of the km disk).

A way to verify blocking is to connect only one stepper to the arduino and going airborne. Use the same pin configuration for that test (e.g. 5,6,7,8). You therefore have to exclude the coding for the other stepper.

If both stepper behaves good when standalone than you probably have to use several Nanos to drive the two motors.

Furthermore it is a good idea first to get rid of all problems in the USB configuration. If all works fine you may go the RS458 way and have a look if the behavior is still good.

 

If you want to reduce the turn angle of the km disk, you have to look into the map function

int stepperPosition = map(newValue, 0, 65535, 0, 1260);

1260 steps are for a 315 degree angle (that is between both endstops) with 4 steps per degree (315 * 4 = 1260).

If you want to turn only 270degrees you have to change the value accordingly (270 * 4 = 1080).

This is half step mode (HALF4WIRE ) and probably may be changed into full step mode (3 steps per degree ??? depending on your stepper type) FULL4WIRE.

You than have to find the correct number of steps for a turn of your motor.

 

For the RS485 Master you have to use an Arduino MEGA and the RS485Master.ino sketch that is in your dcs-bios-arduino-library/Examples folder.

 

Regards, Vinc

 

Callibrated, and works but see video.. it goes wacky on the 0 detection... 

Link to comment
Share on other sites

21 minutes ago, Vinc_Vega said:

Additionally it jumps from 1000 to 600 m. What values did you change within the code?

 

No, every time it passes 0 it goes everywhere. even with the RotaryEncoder up is ok.. then to 0 it goes everywhere 

Link to comment
Share on other sites

Hi Johan,

you made a mistake while calibrating the gauge by editing the map function.

As somwhere explained here, that function works like

map(newValue, Dcs value min, Dcs value max, your stepper min, your stepper max);

So the newValue is the actual value supplied from DcsBios.

Dcs value min and max can be read out from the respective control reference.

For a standard (unsigned) integer value that is the range from 0 to 65535 and cannot be changed by you.

The your stepper min and max values are the steps your motor has to go from scale minimum to maximum (e.g. 0 to 13 km).

 

Unfortunately the data sheet says that the X25 and X27 stepper have 3 steps per degree, but the AccelStepper library seems to use only 2 steps per degree in full step mode (FULL4WIRE) and 4 steps in half step mode (HALF4WIRE).

As your km disk uses a stepper with end stop it has a maximum of 1260 half steps or 630 in full step mode (equals 315 degrees).

If you are in full step mode and want to turn the motor only 225 degrees you may use 450 steps as the maximum to be mapped (equals 900 in half step mode).

The correct function than must be read

stepper0.runToNewPosition(map(newValue, 0, 65535, 0, 450));	// for the km disk in FULL4WIRE mode 

 

The stepper motor for the needle ist set to 0 steps at the IR sensor and to maxSteps at 1000 meter.

For a full turn the stepper has to go 1440 half steps or 720 in full step mode, while zero already is the first step (equals 360 degrees; maxSteps - 1).

The correct functions therefore must be read as follows

  return map(newValue, 0, 65535, 0, stepperConfig.maxSteps-1);	// for the 1000m needle

To declare the maxSteps you have to enter your values into the stepperConfig declaration (720 in full step mode)

/* modify below this line */

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

For you information, see here for error within the stepperConfig, I already corrected above.

 

If you don't use pin 13 anymore, you may delete the respective line

  pinMode(13, OUTPUT);

 

As 450 steps may be the end of your km disk, it is not the position of the stepper's end stop.

You therefore have to use the maximum steps for that motor to calibrate at the startup (go to the upper stop).

In full step mode the function to zero the km disk must read

void zero_stepper0(){
    stepper0.setMaxSpeed(4000);    //  maximum speed in steps per second. Must be > 0.
    stepper0.setAcceleration(8000);  //  desired acceleration in steps per second per second. Must be > 0.0
    stepper0.runToNewPosition(630); // go to the upper end stop
    delay(250);
    stepper0.setCurrentPosition(630); // set max steps
    stepper0.runToNewPosition(0);    // go to the lower end stop
    delay(250);
    stepper0.setCurrentPosition(0);  // set steps to zero
}

 

I attached a modified file, including the above corrections.

 

Regards, Vinc

Alititude_Gauge_mod.ino


Edited by Vinc_Vega

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

7 hours ago, Vinc_Vega said:

Hi Johan,

you made a mistake while calibrating the gauge by editing the map function.

As somwhere explained here, that function works like

map(newValue, Dcs value min, Dcs value max, your stepper min, your stepper max);

So the newValue is the actual value supplied from DcsBios.

Dcs value min and max can be read out from the respective control reference.

For a standard (unsigned) integer value that is the range from 0 to 65535 and cannot be changed by you.

The your stepper min and max values are the steps your motor has to go from scale minimum to maximum (e.g. 0 to 13 km).

 

Unfortunately the data sheet says that the X25 and X27 stepper have 3 steps per degree, but the AccelStepper library seems to use only 2 steps per degree in full step mode (FULL4WIRE) and 4 steps in half step mode (HALF4WIRE).

As your km disk uses a stepper with end stop it has a maximum of 1260 half steps or 630 in full step mode (equals 315 degrees).

If you are in full step mode and want to turn the motor only 225 degrees you may use 450 steps as the maximum to be mapped (equals 900 in half step mode).

The correct function than must be read

stepper0.runToNewPosition(map(newValue, 0, 65535, 0, 450));	// for the km disk in FULL4WIRE mode 

 

The stepper motor for the needle ist set to 0 steps at the IR sensor and to maxSteps at 1000 meter.

For a full turn the stepper has to go 1440 half steps or 720 in full step mode, while zero already is the first step (equals 360 degrees; maxSteps - 1).

The correct functions therefore must be read as follows

  return map(newValue, 0, 65535, 0, stepperConfig.maxSteps-1);	// for the 1000m needle

To declare the maxSteps you have to enter your values into the stepperConfig declaration (720 in full step mode)

/* modify below this line */

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

For you information, see here for error within the stepperConfig, I already corrected above.

 

If you don't use pin 13 anymore, you may delete the respective line

  pinMode(13, OUTPUT);

 

As 450 steps may be the end of your km disk, it is not the position of the stepper's end stop.

You therefore have to use the maximum steps for that motor to calibrate at the startup (go to the upper stop).

In full step mode the function to zero the km disk must read

void zero_stepper0(){
    stepper0.setMaxSpeed(4000);    //  maximum speed in steps per second. Must be > 0.
    stepper0.setAcceleration(8000);  //  desired acceleration in steps per second per second. Must be > 0.0
    stepper0.runToNewPosition(630); // go to the upper end stop
    delay(250);
    stepper0.setCurrentPosition(630); // set max steps
    stepper0.runToNewPosition(0);    // go to the lower end stop
    delay(250);
    stepper0.setCurrentPosition(0);  // set steps to zero
}

 

I attached a modified file, including the above corrections.

 

Regards, Vinc

Alititude_Gauge_mod.ino 6.93 kB · 0 downloads

 

Thanks for taking the time to explain.. it makes more sens now.. i was changing thins on trial and error.. and was getting to celebrating on the wrong site.. the angle of the disk is 145 degrees.. so it is on fullwire 290

stepper0.runToNewPosition(map(newValue, 0, 65535, 0, 290));    // for the km disk in FULL4WIRE mode 

void zero_stepper0(){
    stepper0.setMaxSpeed(4000);    //  maximum speed in steps per second. Must be > 0.
    stepper0.setAcceleration(8000);  //  desired acceleration in steps per second per second. Must be > 0.0
    stepper0.runToNewPosition(290); // go to the upper end stop
    delay(250);
    stepper0.setCurrentPosition(290); // set max steps
    stepper0.runToNewPosition(0);    // go to the lower end stop
    delay(250);
    stepper0.setCurrentPosition(0);  // set steps to zero
}

But the lower stop is not on the 0 mark (offset).. do i need to change this? to get it on 0?

stepper0.setCurrentPosition(0);  // set steps to zero

 

Link to comment
Share on other sites

Hi Johan,

as you did not have physically manipulated the inner stops of the stepper motor, you have to stay with 630 full steps between both stops (315°).

Otherwise there is no correct calibration possible.

 

The above change in the map function should be okay but may need an offset (0+offset to 290+offset).

Before that the offset has to be declared as an int variable!

int offset = 20;   // let's assume that the offset should be 20 steps

 

An other solution is to change the zero_stepper0() function to run the stepper against the lower end stop and back to the zero mark of the scale (offset). Than setCurrentPosition(0).

 

Should be read something like that (untested):

   stepper0.runToNewPosition(630); // go to the upper end stop
    delay(250);
    stepper0.setCurrentPosition(630); // set max steps
    stepper0.runToNewPosition(0);    // go to the lower end stop
    delay(250);

    stepper0.runToNewPosition(offset);    // go to the zero mark of the km disk
    delay(250);
    stepper0.setCurrentPosition(0);  // set steps to new zero

 

How far away is the zero marking of the disk from the lower end stop?

 

Regards, Vinc


Edited by Vinc_Vega

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

6 hours ago, Vinc_Vega said:

Hi Johan,

as you did not have physically manipulated the inner stops of the stepper motor, you have to stay with 630 full steps between both stops (315°).

Otherwise there is no correct calibration possible.

 

The above change in the map function should be okay but may need an offset (0+offset to 290+offset).

Before that the offset has to be declared as an int variable!

int offset = 20;   // let's assume that the offset should be 20 steps

 

An other solution is to change the zero_stepper0() function to run the stepper against the lower end stop and back to the zero mark of the scale (offset). Than setCurrentPosition(0).

 

Should be read something like that (untested):

   stepper0.runToNewPosition(630); // go to the upper end stop
    delay(250);
    stepper0.setCurrentPosition(630); // set max steps
    stepper0.runToNewPosition(0);    // go to the lower end stop
    delay(250);

    stepper0.runToNewPosition(offset);    // go to the zero mark of the km disk
    delay(250);
    stepper0.setCurrentPosition(0);  // set steps to new zero

 

How far away is the zero marking of the disk from the lower end stop?

 

Regards,

the disk has new end points... as you can see on the picture..

Off set is about 15 I think 

disk

Link to comment
Share on other sites

20 hours ago, Vinc_Vega said:

Hi Johan,

as you did not have physically manipulated the inner stops of the stepper motor, you have to stay with 630 full steps between both stops (315°).

Otherwise there is no correct calibration possible.

 

The above change in the map function should be okay but may need an offset (0+offset to 290+offset).

Before that the offset has to be declared as an int variable!

int offset = 20;   // let's assume that the offset should be 20 steps

 

An other solution is to change the zero_stepper0() function to run the stepper against the lower end stop and back to the zero mark of the scale (offset). Than setCurrentPosition(0).

 

Should be read something like that (untested):

   stepper0.runToNewPosition(630); // go to the upper end stop
    delay(250);
    stepper0.setCurrentPosition(630); // set max steps
    stepper0.runToNewPosition(0);    // go to the lower end stop
    delay(250);

    stepper0.runToNewPosition(offset);    // go to the zero mark of the km disk
    delay(250);
    stepper0.setCurrentPosition(0);  // set steps to new zero

 

How far away is the zero marking of the disk from the lower end stop?

 

Regards, Vinc

 

It looks good.. no hops just a small glitch.. when you pass in flight or turning the knob and you passen up 0.05 the leedle hops.. and keeps a 0.05 offset and down it resets on 0.. see vid..

Thanks this is so helpfull and I learn a lot..

 

Link to comment
Share on other sites

#define DCSBIOS_IRQ_SERIAL

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

// sea level knob
DcsBios::RotaryEncoder altPressSet("ALT_PRESS_SET", "-3200", "+3200", A1, A2);

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


class Vid60Stepper : 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:
    Vid60Stepper(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(200);
        
        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 = {
  720,  // maxSteps
  8000, // acceleration
  4000 // maxSpeed
 };


// define AccelStepper instance
AccelStepper stepper1(AccelStepper::FULL4WIRE , 8, 7, 9, 10);
// define Vid60Stepper class that uses the AccelStepper instance defined in the line above
//           v-- arbitrary name
Vid60Stepper alt100ftPointer(0x424a,          // DCS Bios address For stepper data
                             stepper1,         // name of AccelStepper instance
                             stepperConfig,   // StepperConfig struct instance
                             12,              // 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, 0, 65535, 0, stepperConfig.maxSteps-1);
});

//Stepper 2
AccelStepper stepper0(AccelStepper::FULL4WIRE , 4, 3, 5, 6);

  // Altimeter kilometer disk (0-13.000 m)
void onAltimeterCoarseptrChange(unsigned int newValue) {
  stepper0.runToNewPosition(map(newValue, 0, 65535, 0, 460));
}
DcsBios::IntegerBuffer altimeterCoarseptrBuffer(0x424c, 0xffff, 0, onAltimeterCoarseptrChange);

void zero_stepper0(){
    stepper0.setMaxSpeed(4000);    //  maximum speed in steps per second. Must be > 0.
    stepper0.setAcceleration(8000);  //  desired acceleration in steps per second per second. Must be > 0.0
    stepper0.runToNewPosition(460); // go to the upper end stop
    delay(250);
    stepper0.setCurrentPosition(460); // set max steps
    stepper0.runToNewPosition(12);    // go to the lower end stop
    delay(250);
    stepper0.setCurrentPosition(0);  // set steps to zero
}

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

void loop() {
  PORTB |= (1<<5);
  PORTB &= ~(1<<5);
  DcsBios::loop();
}

this is my code now

Link to comment
Share on other sites

Hi Johan,

why don't you use the full range of the km disk stepper during calibration (630 steps)? Imagine, if your disk has moved more than 460 steps away from the lower stop (already should be the case for adding the offset to the 460 steps), it will only go 460 steps back to zero itself and than to the offset to set a new zero. In that case you don't have the zero mark at 0 step position after the next calibration cycle. Try to start the arduino for several times and wait for the zero function for stepper0. At least it should add 12 steps for each calibration circle to the zero mark.

 

The jumps around the zero position of the needle stepper may be caused by the disk's IR sensor detectable slot width. A smaller slot should reduce the jumps. As long as that jumps only are while zeroing the pressure and not when flying (going through the zero position), I wouldn't care about it.

Regards, Vinc


Edited by Vinc_Vega

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

  • Recently Browsing   0 members

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