Skip to content

Commit 4604d33

Browse files
Merge pull request #16 from talbotmcinnis/SyncingSwitch
Syncing switches and RotarySyncingPotentiometer
2 parents 594c41d + 7888040 commit 4604d33

File tree

6 files changed

+212
-4
lines changed

6 files changed

+212
-4
lines changed

examples/Synchronization/Synchronization.ino

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,6 @@ void onModTimeChange(char* newValue) {
7070
}
7171
}
7272
DcsBios::StringBuffer<5> modTimeBuffer(0x043e, onModTimeChange);
73+
74+
// Yet another option, some controls can be synced to DCS by combining a switch control with a Syncing version of that control.
75+
DcsBios::SyncingSwitch3Pos ahcpMasterArm("AHCP_MASTER_ARM", 2, 3, 0x10e8, 0x000c, 2);

releasenotes.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
## v0.3.6 (VNext)
1+
## v0.3.6
22
- Replaced InvertedPotentiometer class with a reverse bool constructor option for the existing potentiometer.
33
- Added Synchronization example to layout different strategies for physical control <=> DCS synchronization on startup, periodic or on aircraft entry.
4-
- Created new synchronization option via ResettableInput/resetThisState()
5-
- Added RotarySwitch for cockpits with a rotary encoder in place of N-Position switches
4+
- Created new single control reset/synchronization option via ResettableInput::resetThisState()
5+
- Created new RotarySyncingPotentiometer for simpits with a potentiometer in place of a rotary control, and an example to document usage.
6+
- Added RotarySwitch for cockpits with a rotary encoder in place of N-Position switches.
7+
- Created new Syncing Switches which are both an output to DCS, but also an input from DCS and will automatically re-send their state to DCS if DCS reports a different value. Checkout Synchronization example for sample usage of SyncingSwitch3Pos.
68

79
## v0.3.5
810
- Switched all examples to DCSBIOS_DEFAULTSERIAL for compatibility.

src/DcsBios.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,10 @@ do not come with their own build system, we are just putting everything into the
118118

119119
#include "internal/Buttons.h"
120120
#include "internal/Switches.h"
121+
#include "internal/SyncingSwitches.h"
121122
#include "internal/Encoders.h"
122123
#include "internal/Potentiometers.h"
124+
#include "internal/RotarySyncingPotentiometer.h"
123125
#include "internal/Leds.h"
124126
#include "internal/Servos.h"
125127
#include "internal/Dimmer.h"

src/internal/Potentiometers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ namespace DcsBios {
5858
{
5959
msg_ = msg;
6060
}
61-
61+
6262
void resetThisState()
6363
{
6464
this->resetState();
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#ifndef __DCSBIOS_ROTARYPOTS_H
2+
#define __DCSBIOS_ROTARYPOTS_H
3+
4+
#include <math.h>
5+
#include "Arduino.h"
6+
#include "PollingInput.h"
7+
8+
namespace DcsBios {
9+
template <unsigned long pollIntervalMs = POLL_EVERY_TIME, bool invert = false>
10+
class RotarySyncingPotentiometerEWMA : PollingInput, Int16Buffer, public ResettableInput {
11+
private:
12+
void resetState()
13+
{
14+
lastState_ = (lastState_==0)?-1:0;
15+
}
16+
void pollInput() {
17+
lastState_ = readState();
18+
}
19+
20+
inline unsigned int readState()
21+
{
22+
return map(analogRead(pin_), invert?1023:0, invert?0:1023, 0, 65535);
23+
}
24+
25+
const char* msg_;
26+
char pin_;
27+
unsigned int lastState_;
28+
29+
unsigned int mask;
30+
unsigned char shift;
31+
32+
unsigned long lastSendTime;
33+
34+
int (*mapperCallback)(unsigned int, unsigned int);
35+
36+
public:
37+
RotarySyncingPotentiometerEWMA(const char* msg, char pin,
38+
unsigned int syncToAddress, unsigned int syncToMask, unsigned char syncToShift,
39+
int (*mapperCallback)(unsigned int, unsigned int)) :
40+
PollingInput(pollIntervalMs), Int16Buffer(syncToAddress) {
41+
msg_ = msg;
42+
pin_ = pin;
43+
pinMode(pin_, INPUT);
44+
lastState_ = (float)readState();
45+
46+
this->mask = syncToMask;
47+
this->shift = syncToShift;
48+
lastSendTime = millis();
49+
50+
this->mapperCallback = mapperCallback;
51+
}
52+
53+
void SetControl( const char* msg )
54+
{
55+
msg_ = msg;
56+
}
57+
58+
void resetThisState()
59+
{
60+
this->resetState();
61+
}
62+
63+
unsigned int getData() {
64+
return ((this->Int16Buffer::getData()) & mask) >> shift;
65+
}
66+
67+
virtual void loop() {
68+
unsigned int dcsData = getData();
69+
70+
int requiredAdjustment = mapperCallback(lastState_, dcsData);
71+
72+
//Serial.println("**************");
73+
//Serial.write("lastState_:");Serial.println(lastState_);
74+
//Serial.write("dcsData:");Serial.println(dcsData);
75+
//Serial.write("requiredAdjustment:");Serial.println(requiredAdjustment);
76+
77+
// Send the adjustment to DCS
78+
if( requiredAdjustment != 0 )
79+
{
80+
if( millis() - lastSendTime > 100)
81+
{
82+
char buff[7];
83+
sprintf(buff, "%+d", requiredAdjustment);
84+
tryToSendDcsBiosMessage(msg_, buff);
85+
lastSendTime = millis();
86+
}
87+
}
88+
}
89+
};
90+
typedef RotarySyncingPotentiometerEWMA<> RotarySyncingPotentiometer;
91+
typedef RotarySyncingPotentiometerEWMA<POLL_EVERY_TIME, true> InvertedRotarySyncingPotentiometer;
92+
}
93+
94+
#endif

src/internal/SyncingSwitches.h

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#ifndef __DCSBIOS_SYNCING_SWITCHES_H
2+
#define __DCSBIOS_SYNCING_SWITCHES_H
3+
4+
#include <math.h>
5+
#include "Arduino.h"
6+
7+
namespace DcsBios {
8+
template <unsigned long pollIntervalMs = POLL_EVERY_TIME>
9+
class SyncingSwitch3PosT : PollingInput, public ResettableInput, Int16Buffer
10+
{
11+
private:
12+
const char* msg_;
13+
char pinA_;
14+
char pinB_;
15+
char lastState_;
16+
char steadyState_;
17+
unsigned long debounceDelay_;
18+
unsigned long lastDebounceTime = 0;
19+
20+
unsigned int mask;
21+
unsigned char shift;
22+
23+
char readState() {
24+
if (digitalRead(pinA_) == LOW) return 0;
25+
if (digitalRead(pinB_) == LOW) return 2;
26+
return 1;
27+
}
28+
void resetState()
29+
{
30+
lastState_ = (lastState_==0)?-1:0;
31+
steadyState_ = lastState_;
32+
}
33+
void pollInput() {
34+
char state = readState();
35+
if (state != lastState_) {
36+
lastDebounceTime = millis();
37+
}
38+
39+
if ((millis() - lastDebounceTime) > debounceDelay_)
40+
{
41+
if (state != steadyState_) {
42+
if (state == 0)
43+
{
44+
if (tryToSendDcsBiosMessage(msg_, "0"))
45+
steadyState_ = state;
46+
}
47+
else if (state == 1)
48+
{
49+
if (tryToSendDcsBiosMessage(msg_, "1"))
50+
steadyState_ = state;
51+
}
52+
else if (state == 2)
53+
{
54+
if(tryToSendDcsBiosMessage(msg_, "2"))
55+
steadyState_ = state;
56+
}
57+
}
58+
}
59+
60+
lastState_ = state;
61+
}
62+
public:
63+
SyncingSwitch3PosT(const char* msg, char pinA, char pinB,
64+
unsigned int syncToAddress, unsigned int syncToMask, unsigned char syncToShift,
65+
unsigned long debounceDelay = 50) :
66+
PollingInput(pollIntervalMs), Int16Buffer(syncToAddress)
67+
{
68+
msg_ = msg;
69+
pinA_ = pinA;
70+
pinB_ = pinB;
71+
pinMode(pinA_, INPUT_PULLUP);
72+
pinMode(pinB_, INPUT_PULLUP);
73+
lastState_ = readState();
74+
steadyState_ = lastState_;
75+
debounceDelay_ = debounceDelay;
76+
77+
this->mask = syncToMask;
78+
this->shift = syncToShift;
79+
}
80+
81+
void SetControl( const char* msg )
82+
{
83+
msg_ = msg;
84+
}
85+
86+
void resetThisState()
87+
{
88+
this->resetState();
89+
}
90+
91+
unsigned int getData() {
92+
return ((this->Int16Buffer::getData()) & mask) >> shift;
93+
}
94+
95+
virtual void loop() {
96+
if (hasUpdatedData()) {
97+
unsigned int dcsData = getData();
98+
// What DCS says is most important, so latch it as our last known state. If the switch differs,
99+
// it will be caught on the next pollInput
100+
lastState_ = dcsData;
101+
}
102+
}
103+
};
104+
typedef SyncingSwitch3PosT<> SyncingSwitch3Pos;
105+
}
106+
107+
#endif

0 commit comments

Comments
 (0)