Johan4668 Posted March 16, 2023 Author Share Posted March 16, 2023 17 hours ago, Vinc_Vega said: Hi Johan, try another Nano, maybe there is something broken within the communication chipset. Regards, Vinc Done a test.. the 0 km - 13 is working the other way how can I reverse that? And I need some code to make the 0 - 1000 meter work.. with 0 position.. Then I need to calibrating the whole thing... I upload what it is doing now.. Link to comment Share on other sites More sharing options...
Johan4668 Posted March 16, 2023 Author Share Posted March 16, 2023 and it is not always on the same number... it shifts.. Link to comment Share on other sites More sharing options...
Johan4668 Posted March 17, 2023 Author Share Posted March 17, 2023 On 3/12/2023 at 9:14 PM, Vinc_Vega said: No, for the standard USB mode just leave it as it is. For the RS485 option (later) delete the first two slashes. As you may see, I connected the encoder to pins D3 and D4 and the stepper for the km-disk to pins D5 to D8. Regards, Vinc How can you change the direction of the stepper? Link to comment Share on other sites More sharing options...
Vinc_Vega Posted March 17, 2023 Share Posted March 17, 2023 1 hour ago, Johan4668 said: How can you change the direction of the stepper? I'll give you a tested answer when I'm home tonight. Regards, Vinc 1 Regards, Vinc real life: Royal Bavarian Airforce online: VJS-GermanKnights.de [sIGPIC][/sIGPIC] Link to comment Share on other sites More sharing options...
Johan4668 Posted March 17, 2023 Author Share Posted March 17, 2023 nullThis is more than 360... 410 degrees.. i solved it like this... then it has a 0 point.. but do you also need a end point? Link to comment Share on other sites More sharing options...
No1sonuk Posted March 17, 2023 Share Posted March 17, 2023 This is an option: 1:2.66 gearing (24:9 teeth) means a 180 degree servo can make a needle go 478 degrees. Link to comment Share on other sites More sharing options...
Vinc_Vega Posted March 17, 2023 Share Posted March 17, 2023 (edited) 23 hours ago, Johan4668 said: How can you change the direction of the stepper? Hi Johan I reproduced the behavior of your stepper. It has been working good with the A-10C gauges but moves strange with the Bf-109. No idea what happens, but I'll do further investigation at the weekend. The Stepper direction may be chagend in different ways: 1) Quick and dirty by flipping the mapping interval. just change the last two values from int stepperPosition = map(newValue, 0, 65535, 0, 1260); to int stepperPosition = map(newValue, 0, 65535, 1260, 0); 2) Changing the pin order by software just change the pins pairwise from AccelStepper stepper0(AccelStepper::HALF4WIRE , 5, 6, 8, 7); to AccelStepper stepper0(AccelStepper::HALF4WIRE , 8, 7, 5, 6); 3) Changing the physical pin order As two pins are connected to each coil (see below picture) the pins may be flipped at the stepper or the Arduino connections. Just flip them coil wise like the pin order in the above AccelStepper object declaration. Regards, Vinc Edited March 18, 2023 by Vinc_Vega Regards, Vinc real life: Royal Bavarian Airforce online: VJS-GermanKnights.de [sIGPIC][/sIGPIC] Link to comment Share on other sites More sharing options...
Vinc_Vega Posted March 17, 2023 Share Posted March 17, 2023 2 hours ago, Johan4668 said: nullThis is more than 360... 410 degrees.. i solved it like this... then it has a 0 point.. but do you also need a end point? Yes, you need a lower stop and an end stop. If the stepper has 630 steps for a 315 degree turn you may go 820 steps for your 410 degrees spiral. (630 * 410 / 315 = 820) A reduction gear may also be used. Otherwise you need some zero detection like you planned for the second stepper of the altimeter. Regards, Vinc Regards, Vinc real life: Royal Bavarian Airforce online: VJS-GermanKnights.de [sIGPIC][/sIGPIC] Link to comment Share on other sites More sharing options...
Johan4668 Posted March 18, 2023 Author Share Posted March 18, 2023 9 hours ago, Vinc_Vega said: Yes, you need a lower stop and an end stop. If the stepper has 630 steps for a 315 degree turn you may go 820 steps for your 410 degrees spiral. (630 * 410 / 315 = 820) A reduction gear may also be used. Otherwise you need some zero detection like you planned for the second stepper of the altimeter. Regards, Vinc Thanks... then iam going to experiment on that.. and to set 0 with a ir sensor.. what do I need to add? And thanks for explaining and testing this is so helpful.. here i just started a discord for the 109 for people who likes to build it also.. and will also get the code on there so they don't have to go this journey I did... https://discord.gg/YGdhFuH2 If you like check it out.. and you can give advice.. Everything is going to be free and downloadeble and gauge by gauge.. I give you the result this weekend. Thanks again.. 9 hours ago, No1sonuk said: This is an option: 1:2.66 gearing (24:9 teeth) means a 180 degree servo can make a needle go 478 degrees. I have this also.. the mw50 and feul for example 1 Link to comment Share on other sites More sharing options...
Vinc_Vega Posted March 18, 2023 Share Posted March 18, 2023 (edited) Hi Johan, I've found the issue! Don't know why, but I mixed up the adresses. After updating the plugins, the altimeter stepper worked fine with standard values. Sorry for that! I updated all the old postings with the corrected adresses. For the kilometer gauge you may use the following code, adress is 0x424a // Altimeter kilometer disk (0-13.000 m) void onAltimeterCoarseptrChange(unsigned int newValue) { stepper0.runToNewPosition(map(newValue, 0, 56535, 0, 1260)); } DcsBios::IntegerBuffer altimeterCoarseptrBuffer(0x424a, 0xffff, 0, onAltimeterCoarseptrChange); Would you tell me the kind of IR sensor you intend to use? Is there already an Arduino library or some code for that sensor available? Regards, Vinc Edited March 18, 2023 by Vinc_Vega Regards, Vinc real life: Royal Bavarian Airforce online: VJS-GermanKnights.de [sIGPIC][/sIGPIC] Link to comment Share on other sites More sharing options...
Johan4668 Posted March 18, 2023 Author Share Posted March 18, 2023 3 hours ago, Vinc_Vega said: Hi Johan, I've found the issue! Don't know why, but I mixed up the adresses. After updating the plugins, the altimeter stepper worked fine with standard values. Sorry for that! I updated all the old postings with the corrected adresses. For the kilometer gauge you may use the following code, adress is 0x424a // Altimeter kilometer disk (0-13.000 m) void onAltimeterCoarseptrChange(unsigned int newValue) { stepper0.runToNewPosition(map(newValue, 0, 56535, 0, 1260)); } DcsBios::IntegerBuffer altimeterCoarseptrBuffer(0x424a, 0xffff, 0, onAltimeterCoarseptrChange); Would you tell me the kind of IR sensor you intend to use? Is there already an Arduino library or some code for that sensor available? Regards, Vinc Youmile 5-delige snelheidsmeetsensor IR-infrarood sleuven optische optocoupler-module Foto-onderbrekersensor voor motorsnelheidsdetectie of Arduino met encoders https://amzn.eu/d/bLbJ0FE This one.. Link to comment Share on other sites More sharing options...
Vinc_Vega Posted March 19, 2023 Share Posted March 19, 2023 (edited) On 3/18/2023 at 7:47 AM, Johan4668 said: Thanks... then iam going to experiment on that.. and to set 0 with a ir sensor.. what do I need to add? Hi Johan, I merged Ian's code from that forum here (see page 1 for reference) for the 1000m pointer - including the zero detection - with that of the kilometer disk. As I don't have an IR sensor yet, I simply used a push button at pin 11 to simulate the signal. The 1000m pointer (AltimeterFineptr) is connected to pins 9, 10, 12 and 13, while the kilometer disk stepper (AltimeterCoarseptr) remains at pins 5 to 8. So the rotary encoder still has pins 3 and 4 available and pins 0 to 2 are reserved for the RS485 option. Maybe you have to tweak the values for maxSpeed and MaxAcceleration. You also may adjust the mapped values to the needs of your kilometer disk as 1260 steps are good for a 315 degree motion. But at least you should have a sketch to start from. Spoiler #define DCSBIOS_IRQ_SERIAL #include <AccelStepper.h> #include "DcsBios.h" 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(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 = { 1440, // maxSteps 8000, // maxSpeed 16000 // acceleration }; // define AccelStepper instance AccelStepper stepper1(AccelStepper::HALF4WIRE , 13, 12, 9, 10); // define Vid60Stepper class that uses the AccelStepper instance defined in the line above // v-- arbitrary name Vid60Stepper AltimeterFineptr(0x4248, // address of stepper data stepper1, // name of AccelStepper instance stepperConfig, // StepperConfig struct instance 11, // 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); }); AccelStepper stepper0(AccelStepper::HALF4WIRE , 8, 7, 5, 6); // Altimeter kilometer disk (0-13.000 m) void onAltimeterCoarseptrChange(unsigned int newValue) { stepper0.runToNewPosition(map(newValue, 0, 56535, 0, (1260-1))); } DcsBios::IntegerBuffer altimeterCoarseptrBuffer(0x424a, 0xffff, 0, onAltimeterCoarseptrChange); // sea level knob DcsBios::RotaryEncoder altPressSet("ALT_PRESS_SET", "-6400", "+6400", 3, 4); void setup() { DcsBios::setup(); pinMode(13, OUTPUT); zero_stepper0(); } void loop() { PORTB |= (1<<5); PORTB &= ~(1<<5); DcsBios::loop(); } void zero_stepper0(){ stepper0.setMaxSpeed(16000); // 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(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); stepper0.setCurrentPosition(0); // set steps to zero } Regards, Vinc Edited March 19, 2023 by Vinc_Vega Regards, Vinc real life: Royal Bavarian Airforce online: VJS-GermanKnights.de [sIGPIC][/sIGPIC] Link to comment Share on other sites More sharing options...
Johan4668 Posted March 19, 2023 Author Share Posted March 19, 2023 4 hours ago, Vinc_Vega said: Hi Johan, I merged Ian's code from that forum here (see page 1 for reference) for the 1000m pointer - including the zero detection - with that of the kilometer disk. As I don't have an IR sensor yet, I simply used a push button at pin 11 to simulate the signal. The 1000m pointer (AltimeterFineptr) is connected to pins 9, 10, 12 and 13, while the kilometer disk stepper (AltimeterCoarseptr) remains at pins 5 to 8. So the rotary encoder still has pins 3 and 4 available and pins 0 to 2 are reserved for the RS485 option. Maybe you have to tweak the values for maxSpeed and MaxAcceleration. You also may adjust the mapped values to the needs of your kilometer disk as 1260 steps are good for a 315 degree motion. But at least you should have a sketch to start from. Hide contents #define DCSBIOS_IRQ_SERIAL #include <AccelStepper.h> #include "DcsBios.h" 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(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 = { 1440, // maxSteps 8000, // maxSpeed 16000 // acceleration }; // define AccelStepper instance AccelStepper stepper1(AccelStepper::HALF4WIRE , 13, 12, 9, 10); // define Vid60Stepper class that uses the AccelStepper instance defined in the line above // v-- arbitrary name Vid60Stepper AltimeterFineptr(0x4248, // address of stepper data stepper1, // name of AccelStepper instance stepperConfig, // StepperConfig struct instance 11, // 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); }); AccelStepper stepper0(AccelStepper::HALF4WIRE , 8, 7, 5, 6); // Altimeter kilometer disk (0-13.000 m) void onAltimeterCoarseptrChange(unsigned int newValue) { stepper0.runToNewPosition(map(newValue, 0, 56535, 0, (1260-1))); } DcsBios::IntegerBuffer altimeterCoarseptrBuffer(0x424a, 0xffff, 0, onAltimeterCoarseptrChange); // sea level knob DcsBios::RotaryEncoder altPressSet("ALT_PRESS_SET", "-6400", "+6400", 3, 4); void setup() { DcsBios::setup(); pinMode(13, OUTPUT); zero_stepper0(); } void loop() { PORTB |= (1<<5); PORTB &= ~(1<<5); DcsBios::loop(); } void zero_stepper0(){ stepper0.setMaxSpeed(16000); // 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(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); stepper0.setCurrentPosition(0); // set steps to zero } Regards, Vinc Your the best this is also done.. Link to comment Share on other sites More sharing options...
Vinc_Vega Posted March 19, 2023 Share Posted March 19, 2023 Did you manage to bring the speedometer to 410 degrees and back? Regards, Vinc Regards, Vinc real life: Royal Bavarian Airforce online: VJS-GermanKnights.de [sIGPIC][/sIGPIC] Link to comment Share on other sites More sharing options...
Johan4668 Posted March 20, 2023 Author Share Posted March 20, 2023 17 hours ago, Vinc_Vega said: Did you manage to bring the speedometer to 410 degrees and back? Regards, Vinc i did not connect it yet but with hand it goes perfect... the new nano is in.. so iam going to connect the alt gauge first Link to comment Share on other sites More sharing options...
lesthegrngo Posted March 22, 2023 Share Posted March 22, 2023 On 3/11/2023 at 11:18 PM, Vinc_Vega said: No, unfortunately only Megas will work as masters. But each Mega can support up to 3 RS485 buses. Edit: As a slave, the Mega, Uno and Nano boards do work. Regards, Vinc On the 3 buses for each mega, I have tried it and it works fine, it helped me simplify my wiring a lot Cheers Les Link to comment Share on other sites More sharing options...
Johan4668 Posted March 22, 2023 Author Share Posted March 22, 2023 (edited) On 3/19/2023 at 4:39 PM, Vinc_Vega said: Did you manage to bring the speedometer to 410 degrees and back? Regards, Vinc 20230322_114216.mp4 20230322_114057.mp4 It stops that is good.. I see the meter needle not moving and the km is and fast.. And on encoder the km disk moves.. Do we mis something here? Edited March 22, 2023 by Johan4668 Link to comment Share on other sites More sharing options...
Johan4668 Posted March 22, 2023 Author Share Posted March 22, 2023 null Link to comment Share on other sites More sharing options...
Vinc_Vega Posted March 22, 2023 Share Posted March 22, 2023 (edited) Hi Johan, the lower movie shows the starting sequence. The 1000m needle moves slow and stops at zero. The km disk goes to the upper stop and back to zero. It's intended to do so. If you want to slow down the km disk at startup you have to lower the MaxSpeed within the Zero_Stepper0 routine at the end of the sketch let's say to 1000 and acceleration to 2000. Furthermore, I think that the direction of the 1000m needle has to be inverted. Change the pins to 9, 10, 13, 12 within the AccelStepper declaration. But what is shown in the upper movie? The km disk should not move when turning the encoder (or at least only from 0 to 1. Regards, Vinc Edited March 22, 2023 by Vinc_Vega Regards, Vinc real life: Royal Bavarian Airforce online: VJS-GermanKnights.de [sIGPIC][/sIGPIC] Link to comment Share on other sites More sharing options...
Johan4668 Posted March 22, 2023 Author Share Posted March 22, 2023 4 minutes ago, Vinc_Vega said: Hi Johan, the lower movie shows the starting sequence. The 1000m needle moves slow and stops at zero. The km disk goes to the upper stop and back to zero. It's intended to do so. If you want to slow down the km disk at startup you have to lower the MaxSpeed within the Zero_Stepper0 routine at the end of the sketch let's say to 1000 and acceleration to 2000. But what is shown in the upper movie? The km disk should not move when turning the encoder (or at least only from 0 to 1. Regards, Vinc the lower is ok.. the startup.. the upper is in DCS flight.. the 0 - 1000 meter needle is not moving and the km disk is moving fast.. on climbing 500 meters Link to comment Share on other sites More sharing options...
Vinc_Vega Posted March 22, 2023 Share Posted March 22, 2023 Would you post your sketch pls? Regards, Vinc Regards, Vinc real life: Royal Bavarian Airforce online: VJS-GermanKnights.de [sIGPIC][/sIGPIC] Link to comment Share on other sites More sharing options...
Johan4668 Posted March 22, 2023 Author Share Posted March 22, 2023 On 3/19/2023 at 3:30 PM, Johan4668 said: #define DCSBIOS_IRQ_SERIAL #include <AccelStepper.h> #include "DcsBios.h" 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(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 = { 1440, // maxSteps 8000, // maxSpeed 16000 // acceleration }; // define AccelStepper instance AccelStepper stepper1(AccelStepper::HALF4WIRE , 13, 12, 9, 10); // define Vid60Stepper class that uses the AccelStepper instance defined in the line above // v-- arbitrary name Vid60Stepper AltimeterFineptr(0x4248, // address of stepper data stepper1, // name of AccelStepper instance stepperConfig, // StepperConfig struct instance 11, // 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); }); AccelStepper stepper0(AccelStepper::HALF4WIRE , 8, 7, 5, 6); // Altimeter kilometer disk (0-13.000 m) void onAltimeterCoarseptrChange(unsigned int newValue) { stepper0.runToNewPosition(map(newValue, 0, 56535, 0, (1260-1))); } DcsBios::IntegerBuffer altimeterCoarseptrBuffer(0x424a, 0xffff, 0, onAltimeterCoarseptrChange); // sea level knob DcsBios::RotaryEncoder altPressSet("ALT_PRESS_SET", "-6400", "+6400", 3, 4); void setup() { DcsBios::setup(); pinMode(13, OUTPUT); zero_stepper0(); } void loop() { PORTB |= (1<<5); PORTB &= ~(1<<5); DcsBios::loop(); } void zero_stepper0(){ stepper0.setMaxSpeed(16000); // 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(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); stepper0.setCurrentPosition(0); // set steps to zero } It's the code you send me.. Link to comment Share on other sites More sharing options...
Vinc_Vega Posted March 22, 2023 Share Posted March 22, 2023 (edited) Can somebody please confirm the addresses for the altimeter of the BF-109? I have read out the Bf-109K-4.json file from the "AppData\Roaming\DCS-BIOS\control-reference-json" folder. But as I don't use the Flightpanels fork, the file may be outdated. Altimeter_FinePtr (1000m needle) 0x4248 (decimal 16.968) Altimeter_CoarsePtr (km disk) 0x424a (decimal 16.970) Altimeter_Pressure (pressure disk ) 0x424c (decimal 16.972) Johan, What happen to your gauge if you change the address of the 1000m needle and the km disk according to values read out of the Flightpanel's Bf-109K-4.jsonp file? try to change the hexadecimal addresses in line 165 DcsBios::IntegerBuffer altimeterCoarseptrBuffer(0x424a, 0xffff, 0, onAltimeterCoarseptrChange); into DcsBios::IntegerBuffer altimeterCoarseptrBuffer(0x424c, 0xffff, 0, onAltimeterCoarseptrChange); and that of line 149 Vid60Stepper AltimeterFineptr(0x4248, // address of stepper data into Vid60Stepper AltimeterFineptr(0x424a, // address of stepper data Regards, Vinc Edited March 22, 2023 by Vinc_Vega Regards, Vinc real life: Royal Bavarian Airforce online: VJS-GermanKnights.de [sIGPIC][/sIGPIC] Link to comment Share on other sites More sharing options...
No1sonuk Posted March 22, 2023 Share Posted March 22, 2023 31 minutes ago, Vinc_Vega said: Can somebody please confirm the addresses for the altimeter of the BF-109? I have read out the Bf-109K-4.json file from the "AppData\Roaming\DCS-BIOS\control-reference-json" folder. But as I don't use the Flightpanels fork, the file may be outdated. Altimeter_FinePtr (1000m needle) 0x4248 (decimal 16.968) Altimeter_CoarsePtr (km disk) 0x424a (decimal 16.970) Altimeter_Pressure (pressure disk ) 0x424c (decimal 16.972) From the latest I have: Altimeter_CoarsePtrBf-109K-4/ALTIMETER_COARSEPTR DcsBios::ServoOutput altimeterCoarseptr(0x424c, PIN, 544, 2400); Altimeter_FinePtrBf-109K-4/ALTIMETER_FINEPTR DcsBios::ServoOutput altimeterFineptr(0x424a, PIN, 544, 2400); Altimeter_PressureBf-109K-4/ALTIMETER_PRESSURE DcsBios::ServoOutput altimeterPressure(0x424e, PIN, 544, 2400); 1 Link to comment Share on other sites More sharing options...
Vinc_Vega Posted March 22, 2023 Share Posted March 22, 2023 (edited) Thank you No1sonuk, so the issue can be explained. Johan, please change the hexadecimal values for both steppers like proposed above. adjusted code below Spoiler #define DCSBIOS_IRQ_SERIAL #include <AccelStepper.h> #include "DcsBios.h" 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(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 = { 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 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); }); AccelStepper stepper0(AccelStepper::HALF4WIRE , 8, 7, 5, 6); // Altimeter kilometer disk (0-13.000 m) void onAltimeterCoarseptrChange(unsigned int newValue) { stepper0.runToNewPosition(map(newValue, 0, 56535, 0, (1260-1))); } DcsBios::IntegerBuffer altimeterCoarseptrBuffer(0x424c, 0xffff, 0, onAltimeterCoarseptrChange); // sea level knob DcsBios::RotaryEncoder altPressSet("ALT_PRESS_SET", "-3200", "+3200", 3, 4); void setup() { DcsBios::setup(); pinMode(13, OUTPUT); zero_stepper0(); } void loop() { PORTB |= (1<<5); PORTB &= ~(1<<5); DcsBios::loop(); } void zero_stepper0(){ stepper0.setMaxSpeed(8000); // maximum speed in steps per second. Must be > 0. stepper0.setAcceleration(4000); // desired acceleration in steps per second per second. Must be > 0.0 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); stepper0.setCurrentPosition(0); // set steps to zero } Regards, Vinc Edited March 22, 2023 by Vinc_Vega 1 Regards, Vinc real life: Royal Bavarian Airforce online: VJS-GermanKnights.de [sIGPIC][/sIGPIC] Link to comment Share on other sites More sharing options...
Recommended Posts