Commanders
Arduino buttons/bus library
DccCommander.cpp
1 /*************************************************************
2 project: <Commanders>
3 author: <Thierry PARIS>
4 description: <Dcc Commander>
5 *************************************************************/
6 
7 #include <Commanders.h>
8 
9 #ifdef NO_DCCCOMMANDER
10 #pragma message ("Commanders : No DCC commander !")
11 #else
12 #ifdef VISUALSTUDIO
13 DCC_Decoder DCC_Decoder::DCCInstance;
14 #endif
15 
16 DccAccDecoderPacket DccCommanderClass::func_AccPacket;
17 DccCommanderClass *DccCommanderClass::pDccCommander;
18 
20 //
21 // DCC accessory packet handler
22 //
23 void DccCommanderClass::DccAccessoryDecoderPacket(int address, boolean activate, uint8_t data)
24 {
25  int realAddress = address;
26 
27 #ifdef COMMANDERS_DEBUG_MODE
28 #ifdef COMMANDERS_DEBUG_VERBOSE_MODE
29  Serial.print(F("Dcc packet found : real data : "));
30  Serial.print(realAddress);
31  Serial.print(F(" / "));
32  Serial.print(data, DEC);
33  Serial.print(F(" / "));
34  Serial.print(activate, DEC);
35 #endif
36 #endif
37 
38  if (!DccCommander.UseRawDccAddresses)
39  {
40  realAddress -= 1;
41  realAddress *= 4;
42  realAddress += 1;
43  realAddress += (data & 0x06) >> 1;
44  data = data % 2;
45  }
46 
47 #ifdef COMMANDERS_DEBUG_MODE
48 #ifdef COMMANDERS_DEBUG_VERBOSE_MODE
49  Serial.print(F(" converted : "));
50  Serial.print(realAddress);
51  Serial.print(F(" / "));
52  Serial.print(data, DEC);
53  Serial.print(F(" / "));
54  Serial.println(activate, DEC);
55 #endif
56 #endif
57 
58  // Sent packets are (on my MS2 !) :
59  // id / data / 1
60  // id / data / 1
61  // id / data / 1
62  // id / data / 0
63  // The last byte is to activate for a while (three times at 1 !) and then deactivate the motor !
64  // DccCommander will react only on the deactivate flag to avoid double events.
65  if (activate == false)
66  {
67 #ifdef COMMANDERS_DEBUG_MODE
68  Serial.print(F("DccCommander packet received :"));
69  Serial.print(realAddress);
70  Serial.print(F(" / "));
71  Serial.println(data, DEC);
72 #endif
73  if (DccCommanderClass::func_AccPacket)
74  (DccCommanderClass::func_AccPacket)(realAddress, activate, data);
75  else
76  {
78 
79  DccCommander.LastDccId = DCCINT(realAddress, data);
80  }
81  }
82 }
83 
84 #ifdef COMMANDERS_DEBUG_MODE
85 #define CHECK(val, text) CheckIndex(val, F(text))
86 #else
87 #define CHECK(val, text)
88 #endif
89 
90 bool status = false;
91 void StatusBlink_handler()
92 {
93  digitalWrite2f(Commanders::StatusLedPin, status ? HIGH : LOW);
94  status = !status;
95 }
96 
97 void DccCommanderClass::begin(int i, int j, int k, boolean inInterruptMonitor, boolean inUseRawDccAddresses)
98 {
99  DCC.beginDecoder(i, j, k);
100  this->UseRawDccAddresses = inUseRawDccAddresses;
101 #ifdef VISUALSTUDIO
102  // In VS, the exception address is also the pin number.
103  // pinMode() is just here to declare the pin used for the emulator...
104  pinMode(k, OUTPUT_INTERRUPT);
105 #endif
106  this->LastDccId = UNDEFINED_ID;
107 
108  DCC.SetBasicAccessoryDecoderPacketHandler(DccAccessoryDecoderPacket, true);
109 
110  if (inInterruptMonitor)
111  DCC.SetInterruptMonitor(StatusBlink_handler);
112 
113 #ifdef COMMANDERS_PRINT_COMMANDERS
114  this->Interrupt = k;
115 #endif
116 }
117 
118 void DccCommanderClass::PriorityLoop()
119 {
120  DccCommanderClass::loop();
121 }
122 
123 #define MINTIME 2
124 #ifdef COMMANDERS_DEBUG_MODE
125 #ifdef COMMANDERS_DEBUG_VERBOSE_MODE
126 static int countLoop = 0;
127 #endif
128 #endif
129 
130 static unsigned long start = 0;
131 
132 #define ELAPSEDTIME ((unsigned long) -2)
133 
134 unsigned long DccCommanderClass::loop()
135 {
136  //if (start == 0)
137  //start = millis();
138 
139  DCC.loop();
140 #ifdef COMMANDERS_DEBUG_MODE
141 #ifdef COMMANDERS_DEBUG_VERBOSE_MODE
142  countLoop++;
143 #endif
144 #endif
145 
146  //if (millis() - start > MINTIME)
147  {
148  /*
149 #ifdef COMMANDERS_DEBUG_MODE
150 #ifdef COMMANDERS_DEBUG_VERBOSE_MODE
151  Serial.print(F("DCC commander loop : "));
152  Serial.println(countLoop, DEC);
153  countLoop = 0;
154 #endif
155 #endif
156 */
157  start = 0;
158  if (this->LastDccId != UNDEFINED_ID)
159  {
160  unsigned long last = this->LastDccId;
161  this->LastDccId = UNDEFINED_ID;
164  return last;
165  }
166  }
167 
168  return UNDEFINED_ID;
169 }
170 
171 //DccAccDecoderPacket DccCommanderClass::func_AccPacket = NULL;
172 
173 void DccCommanderClass::SetAccessoryDecoderPacketHandler(DccAccDecoderPacket func)
174 {
175  DccCommanderClass::func_AccPacket = func;
176 }
177 
178 #ifdef COMMANDERS_DEBUG_MODE
179 void DccCommanderClass::printEvent(unsigned long inId, COMMANDERS_EVENT_TYPE inEventType, int inEventData)
180 {
181  Serial.print(F("DCC Commander event : Address : "));
182  Serial.print(DCCID(inId), DEC);
183  Serial.print(F(" / "));
184  Serial.print(DCCACTIVATION(inId), DEC);
185  Serial.print(F(" / "));
186  switch (inEventType)
187  {
188  case COMMANDERS_EVENT_NONE: Serial.println(F("NONE")); break;
189  case COMMANDERS_EVENT_TOGGLE: Serial.println(F("TOGGLE")); break;
190  case COMMANDERS_EVENT_MOVE:
191  Serial.print(F("MOVE "));
192  switch ((COMMANDERS_MOVE_TYPE)inEventData)
193  {
194  case COMMANDERS_MOVE_MORE: Serial.println(F("MORE")); break;
195  case COMMANDERS_MOVE_LESS: Serial.println(F("LESS")); break;
196  case COMMANDERS_MOVE_STOP: Serial.println(F("STOP")); break;
197  case COMMANDERS_MOVE_LEFT: Serial.println(F("LEFT")); break;
198  case COMMANDERS_MOVE_RIGHT: Serial.println(F("RIGHT")); break;
199  case COMMANDERS_MOVE_CENTER: Serial.println(F("CENTER")); break;
200  case COMMANDERS_MOVE_TOP: Serial.println(F("TOP")); break;
201  case COMMANDERS_MOVE_BOTTOM: Serial.println(F("BOTTOM")); break;
202  case COMMANDERS_MOVE_STRAIGHT: Serial.println(F("STRAIGHT")); break;
203  case COMMANDERS_MOVE_DIVERGE: Serial.println(F("DIVERGE")); break;
204  case COMMANDERS_MOVE_ON: Serial.println(F("ON")); break;
205  case COMMANDERS_MOVE_OFF: Serial.println(F("OFF")); break;
206  }
207  break;
209  Serial.print(F("MOVEPOSITION : "));
210  Serial.println(inEventData, DEC);
211  break;
213  Serial.println(F("MOVEPOSITIONID"));
214  break;
216  Serial.print(F("MOVEPOSITIONINDEX : "));
217  Serial.println(inEventData, DEC);
218  break;
220  Serial.print(F("CONFIG : "));
221  Serial.print(COMMANDERSCONFIGADDRESS(inEventData), DEC);
222  Serial.print(F(" / "));
223  Serial.println(COMMANDERSCONFIGVALUE(inEventData), DEC);
224  break;
225  }
226 }
227 #endif
228 
229 #ifdef COMMANDERS_PRINT_COMMANDERS
230 void DccCommanderClass::printCommander()
231 {
232  Serial.print(F("Commander: DccCommander - Interrupt: "));
233  Serial.println(this->Interrupt);
234 }
235 #endif
236 
237 #endif
static void SetLastEventData(int inData)
Definition: Commanders.hpp:93
static void SetLastEventType(COMMANDERS_EVENT_TYPE inEvent)
Definition: Commanders.hpp:89
#define UNDEFINED_ID
Definition: Events.h:38
static GPIO_pin_t StatusLedPin
Definition: Commanders.hpp:33
COMMANDERS_EVENT_TYPE
Definition: Events.h:25
COMMANDERS_MOVE_TYPE
Definition: Events.h:8
static unsigned long RaiseEvent(unsigned long inId, COMMANDERS_EVENT_TYPE inEvent = COMMANDERS_EVENT_MOVEPOSITIONID, int inData = 0)
Definition: Commanders.cpp:27