Skip to content

Commit 355bdf1

Browse files
committed
Merge pull request firmata#120 from ntruchsess/encoder_report_changedonly
implement reporting for changed positions only
2 parents cd1f295 + 3d7ec6c commit 355bdf1

File tree

4 files changed

+68
-68
lines changed

4 files changed

+68
-68
lines changed

Firmata.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* software can test whether it will be compatible with the currently
2121
* installed firmware. */
2222
#define FIRMATA_MAJOR_VERSION 2 // for non-compatible changes
23-
#define FIRMATA_MINOR_VERSION 5 // for backwards compatible changes
23+
#define FIRMATA_MINOR_VERSION 6 // for backwards compatible changes
2424
#define FIRMATA_BUGFIX_VERSION 0 // for bugfix releases
2525

2626
#define MAX_DATA_BYTES 64 // max number of data bytes in incoming messages

test/encoder_test/encoder_test.ino

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,16 +150,19 @@ test(handleReportEncodersPositionsMessage)
150150
test(enableAutomaticReports)
151151
{
152152
EncoderFirmata encoder;
153-
assertFalse(encoder.isReportingEnabled());
154-
encoder.toggleAutoReport(true);
155153
assertTrue(encoder.isReportingEnabled());
156-
encoder.toggleAutoReport(false);
154+
encoder.toggleAutoReport(1);
155+
assertTrue(encoder.isReportingEnabled());
156+
encoder.toggleAutoReport(2);
157+
assertTrue(encoder.isReportingEnabled());
158+
encoder.toggleAutoReport(0);
157159
assertFalse(encoder.isReportingEnabled());
158160
}
159161

160162
test(handleEnableAutomaticReportsMessage)
161163
{
162164
EncoderFirmata encoder;
165+
encoder.toggleAutoReport(0);
163166
assertFalse(encoder.isReportingEnabled());
164167

165168
byte enableMessage[]={ENCODER_REPORT_AUTO, 0x01};
@@ -183,7 +186,7 @@ test(fullReport)
183186
encoder.report();
184187
assertEqual(stream.bytesWritten().length(), 0); // reports disable
185188

186-
encoder.toggleAutoReport(true);
189+
encoder.toggleAutoReport(1);
187190

188191
stream.reset();
189192
encoder.report();

utility/EncoderFirmata.cpp

Lines changed: 56 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,23 @@
2121
#include <Firmata.h>
2222
#include "EncoderFirmata.h"
2323
#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;
2431

2532
/* Constructor */
2633
EncoderFirmata::EncoderFirmata()
2734
{
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);
3536
}
3637

3738
void EncoderFirmata::attachEncoder(byte encoderNum, byte pinANum, byte pinBNum)
3839
{
39-
if (isEncoderAttached(encoderNum))
40+
if (isAttached(encoderNum))
4041
{
4142
//Firmata.sendString("Encoder Warning: encoder is already attached. Operation cancelled.");
4243
return;
@@ -49,17 +50,15 @@ void EncoderFirmata::attachEncoder(byte encoderNum, byte pinANum, byte pinBNum)
4950
Firmata.setPinMode(pinANum, ENCODER);
5051
Firmata.setPinMode(pinBNum, ENCODER);
5152
encoders[encoderNum] = new Encoder(pinANum, pinBNum);
52-
numEncoders++;
5353
reportPosition(encoderNum);
5454
}
5555

5656
void EncoderFirmata::detachEncoder(byte encoderNum)
5757
{
58-
if (isEncoderAttached(encoderNum))
58+
if (isAttached(encoderNum))
5959
{
6060
free(encoders[encoderNum]);
6161
encoders[encoderNum] = NULL;
62-
numEncoders--;
6362
}
6463
}
6564

@@ -131,8 +130,7 @@ boolean EncoderFirmata::handleSysex(byte command, byte argc, byte *argv)
131130
}
132131
if (encoderCommand == ENCODER_REPORT_AUTO)
133132
{
134-
enableReports = argv[1];
135-
toggleAutoReport(enableReports == 0x00 ? false : true);
133+
autoReport = argv[1];
136134
return true;
137135
}
138136

@@ -155,38 +153,47 @@ void EncoderFirmata::reset()
155153
{
156154
detachEncoder(encoder);
157155
}
158-
autoReport = false;
159-
numEncoders= 0;
156+
autoReport = 0x02;
160157
}
161158

162159
void EncoderFirmata::report()
163160
{
164-
if (autoReport && numEncoders>0)
161+
if (autoReport > 0)
165162
{
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+
}
167186
}
168187
}
169188

170189
boolean EncoderFirmata::isEncoderAttached(byte encoderNum)
171190
{
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);
185192
}
186193

187194
void EncoderFirmata::resetPosition(byte encoderNum)
188195
{
189-
if (isEncoderAttached(encoderNum))
196+
if (isAttached(encoderNum))
190197
{
191198
encoders[encoderNum]->write(0);
192199
}
@@ -195,51 +202,44 @@ void EncoderFirmata::resetPosition(byte encoderNum)
195202
// Report specify encoder postion using midi protocol
196203
void EncoderFirmata::reportPosition(byte encoder)
197204
{
198-
if (isEncoderAttached(encoder))
205+
if (isAttached(encoder))
199206
{
200207
Firmata.write(START_SYSEX);
201208
Firmata.write(ENCODER_DATA);
202209

203-
_reportEncoderPosition(encoder);
210+
_reportEncoderPosition(encoder,encoders[encoder]->read());
204211

205212
Firmata.write(END_SYSEX);
206213
}
207214
}
208215
// Report all attached encoders positions (one message for all encoders)
209216
void EncoderFirmata::reportPositions()
210217
{
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;
219222
}
220-
void EncoderFirmata::_reportEncoderPosition(byte encoder)
223+
224+
void EncoderFirmata::_reportEncoderPosition(byte encoder, int32_t position)
221225
{
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);
233233
}
234234

235-
236-
void EncoderFirmata::toggleAutoReport(bool report)
235+
void EncoderFirmata::toggleAutoReport(byte report)
237236
{
238237
autoReport = report;
239238
}
240239

241240
bool EncoderFirmata::isReportingEnabled()
242241
{
243-
return autoReport;
242+
return autoReport > 0;
244243
}
245244

245+

utility/EncoderFirmata.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#include "FirmataFeature.h"
3030

3131
// This optional setting causes Encoder to use more optimized code
32-
// safe iif 'attachInterrupt' is never used in the same time
32+
// safe if 'attachInterrupt' is never used in the same time
3333
//#define ENCODER_OPTIMIZE_INTERRUPTS // => not compiling
3434
#include "Encoder.h"
3535

@@ -61,14 +61,11 @@ class EncoderFirmata:public FirmataFeature
6161
void reportPosition(byte encoderNum);
6262
void reportPositions();
6363
void resetPosition(byte encoderNum);
64-
void toggleAutoReport(bool report);
64+
void toggleAutoReport(byte report);
6565
bool isReportingEnabled();
6666

6767
private:
68-
Encoder *encoders[MAX_ENCODERS];
69-
void _reportEncoderPosition(byte encoder);
70-
volatile bool autoReport;
71-
byte numEncoders;
68+
static void _reportEncoderPosition(byte encoder, int32_t position);
7269
};
7370

74-
#endif
71+
#endif

0 commit comments

Comments
 (0)