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 */
2633EncoderFirmata::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
3738void 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
5656void 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
162159void 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
170189boolean 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
187194void 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
196203void 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)
209216void 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
241240bool EncoderFirmata::isReportingEnabled ()
242241{
243- return autoReport;
242+ return autoReport > 0 ;
244243}
245244
245+
0 commit comments