21
21
#include < Firmata.h>
22
22
#include " EncoderFirmata.h"
23
23
#include " Encoder.h"
24
+ #include < String.h>
25
+
26
+ #define isAttached (encoderNum ) (encoderNum < MAX_ENCODERS && encoders[encoderNum])
27
+
28
+ static Encoder *encoders[MAX_ENCODERS];
29
+ static int32_t positions[MAX_ENCODERS];
30
+ static byte autoReport = 0x02 ;
24
31
25
32
/* Constructor */
26
33
EncoderFirmata::EncoderFirmata ()
27
34
{
28
- byte encoder;
29
- for (encoder=0 ; encoder<MAX_ENCODERS; encoder++)
30
- {
31
- encoders[encoder]=NULL ;
32
- }
33
- autoReport = false ;
34
- numEncoders = 0 ;
35
+ memset (encoders,0 ,sizeof (Encoder*)*MAX_ENCODERS);
35
36
}
36
37
37
38
void EncoderFirmata::attachEncoder (byte encoderNum, byte pinANum, byte pinBNum)
38
39
{
39
- if (isEncoderAttached (encoderNum))
40
+ if (isAttached (encoderNum))
40
41
{
41
42
// Firmata.sendString("Encoder Warning: encoder is already attached. Operation cancelled.");
42
43
return ;
@@ -49,17 +50,15 @@ void EncoderFirmata::attachEncoder(byte encoderNum, byte pinANum, byte pinBNum)
49
50
Firmata.setPinMode (pinANum, ENCODER);
50
51
Firmata.setPinMode (pinBNum, ENCODER);
51
52
encoders[encoderNum] = new Encoder (pinANum, pinBNum);
52
- numEncoders++;
53
53
reportPosition (encoderNum);
54
54
}
55
55
56
56
void EncoderFirmata::detachEncoder (byte encoderNum)
57
57
{
58
- if (isEncoderAttached (encoderNum))
58
+ if (isAttached (encoderNum))
59
59
{
60
60
free (encoders[encoderNum]);
61
61
encoders[encoderNum] = NULL ;
62
- numEncoders--;
63
62
}
64
63
}
65
64
@@ -131,8 +130,7 @@ boolean EncoderFirmata::handleSysex(byte command, byte argc, byte *argv)
131
130
}
132
131
if (encoderCommand == ENCODER_REPORT_AUTO)
133
132
{
134
- enableReports = argv[1 ];
135
- toggleAutoReport (enableReports == 0x00 ? false : true );
133
+ autoReport = argv[1 ];
136
134
return true ;
137
135
}
138
136
@@ -155,38 +153,47 @@ void EncoderFirmata::reset()
155
153
{
156
154
detachEncoder (encoder);
157
155
}
158
- autoReport = false ;
159
- numEncoders= 0 ;
156
+ autoReport = 0x02 ;
160
157
}
161
158
162
159
void EncoderFirmata::report ()
163
160
{
164
- if (autoReport && numEncoders> 0 )
161
+ if (autoReport > 0 )
165
162
{
166
- reportPositions ();
163
+ bool report = false ;
164
+ for (uint8_t encoderNum=0 ; encoderNum < MAX_ENCODERS; encoderNum++)
165
+ {
166
+ if (isAttached (encoderNum))
167
+ {
168
+ int32_t position = encoders[encoderNum]->read ();
169
+ if ( autoReport == 1 || positions[encoderNum] != position )
170
+ {
171
+ if (!report)
172
+ {
173
+ Firmata.write (START_SYSEX);
174
+ Firmata.write (ENCODER_DATA);
175
+ report = true ;
176
+ }
177
+ positions[encoderNum] = position;
178
+ _reportEncoderPosition (encoderNum,position);
179
+ }
180
+ }
181
+ }
182
+ if (report)
183
+ {
184
+ Firmata.write (END_SYSEX);
185
+ }
167
186
}
168
187
}
169
188
170
189
boolean EncoderFirmata::isEncoderAttached (byte encoderNum)
171
190
{
172
- if (encoderNum>=MAX_ENCODERS)
173
- {
174
- // Firmata.sendString("Encoder Error: encoder number should be less than 5. Operation cancelled.");
175
- return false ;
176
- }
177
- if (encoders[encoderNum])
178
- {
179
- return true ;
180
- }
181
- else
182
- {
183
- return false ;
184
- }
191
+ return isAttached (encoderNum);
185
192
}
186
193
187
194
void EncoderFirmata::resetPosition (byte encoderNum)
188
195
{
189
- if (isEncoderAttached (encoderNum))
196
+ if (isAttached (encoderNum))
190
197
{
191
198
encoders[encoderNum]->write (0 );
192
199
}
@@ -195,51 +202,44 @@ void EncoderFirmata::resetPosition(byte encoderNum)
195
202
// Report specify encoder postion using midi protocol
196
203
void EncoderFirmata::reportPosition (byte encoder)
197
204
{
198
- if (isEncoderAttached (encoder))
205
+ if (isAttached (encoder))
199
206
{
200
207
Firmata.write (START_SYSEX);
201
208
Firmata.write (ENCODER_DATA);
202
209
203
- _reportEncoderPosition (encoder);
210
+ _reportEncoderPosition (encoder,encoders[encoder]-> read () );
204
211
205
212
Firmata.write (END_SYSEX);
206
213
}
207
214
}
208
215
// Report all attached encoders positions (one message for all encoders)
209
216
void EncoderFirmata::reportPositions ()
210
217
{
211
- Firmata.write (START_SYSEX);
212
- Firmata.write (ENCODER_DATA);
213
- byte encoder;
214
- for (encoder=0 ; encoder<MAX_ENCODERS; encoder++)
215
- {
216
- _reportEncoderPosition (encoder);
217
- }
218
- Firmata.write (END_SYSEX);
218
+ byte tmpReport = autoReport;
219
+ autoReport = 1 ;
220
+ report ();
221
+ autoReport = tmpReport;
219
222
}
220
- void EncoderFirmata::_reportEncoderPosition (byte encoder)
223
+
224
+ void EncoderFirmata::_reportEncoderPosition (byte encoder, int32_t position)
221
225
{
222
- if (isEncoderAttached (encoder))
223
- {
224
- signed long position = encoders[encoder]->read ();
225
- long absValue = abs (position);
226
- byte direction = position >= 0 ? 0x00 : 0x01 ;
227
- Firmata.write ((direction << 6 ) | (encoder));
228
- Firmata.write ((byte)absValue & 0x7F );
229
- Firmata.write ((byte)(absValue >> 7 ) & 0x7F );
230
- Firmata.write ((byte)(absValue >> 14 ) & 0x7F );
231
- Firmata.write ((byte)(absValue >> 21 ) & 0x7F );
232
- }
226
+ long absValue = abs (position);
227
+ byte direction = position >= 0 ? 0x00 : 0x01 ;
228
+ Firmata.write ((direction << 6 ) | (encoder));
229
+ Firmata.write ((byte)absValue & 0x7F );
230
+ Firmata.write ((byte)(absValue >> 7 ) & 0x7F );
231
+ Firmata.write ((byte)(absValue >> 14 ) & 0x7F );
232
+ Firmata.write ((byte)(absValue >> 21 ) & 0x7F );
233
233
}
234
234
235
-
236
- void EncoderFirmata::toggleAutoReport (bool report)
235
+ void EncoderFirmata::toggleAutoReport (byte report)
237
236
{
238
237
autoReport = report;
239
238
}
240
239
241
240
bool EncoderFirmata::isReportingEnabled ()
242
241
{
243
- return autoReport;
242
+ return autoReport > 0 ;
244
243
}
245
244
245
+
0 commit comments