framework2

Форк
0
1826 строк · 45.6 Кб
1
/*
2
 * 11/5/15:
3
 *   - updated for arduino 2.5.0 and configurable firmata
4
 *
5
 * 1/9/13:
6
 *   - Fixed issue where digitalPinchange
7
 *
8
 * 9/28/11:
9
 *   - updated to be Firmata 2.3/Arduino 1.0 compatible
10
 *   - fixed ability to use analog pins as digital inputs
11
 *
12
 * 3/5/11:
13
 *   - added servo support for firmata 2.2 and greater (should be
14
 *     backwards compatible with Erik Sjodin's older firmata servo
15
 *     implementation)
16
 *
17
 *
18
 * Copyright 2007-2008 (c) Erik Sjodin, eriksjodin.net
19
 * Wiring version 2011 (c) Carlos Mario Rodriguez and Hernando Barragan
20
 * Updates 2015 (c) Dom Amato
21
 *
22
 * Devloped at: The Interactive Institutet / Art and Technology,
23
 * OF Lab / Ars Electronica
24
 *
25
 * Permission is hereby granted, free of charge, to any person
26
 * obtaining a copy of this software and associated documentation
27
 * files (the "Software"), to deal in the Software without
28
 * restriction, including without limitation the rights to use,
29
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
30
 * copies of the Software, and to permit persons to whom the
31
 * Software is furnished to do so, subject to the following
32
 * conditions:
33
 *
34
 * The above copyright notice and this permission notice shall be
35
 * included in all copies or substantial _portions of the Software.
36
 *
37
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
38
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
39
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
40
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
41
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
42
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
43
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
44
 * OTHER DEALINGS IN THE SOFTWARE.
45
 */
46

47
#include "ofArduino.h"
48
#include "ofUtils.h"
49
#include "ofMath.h"
50
#include "ofLog.h"
51
#include <climits>
52

53
using std::vector;
54
using std::string;
55
using std::list;
56
using std::pair;
57

58

59
 // TODO thread it?
60
 // TODO throw event or exception if the serial port goes down...
61
 //---------------------------------------------------------------------------
62
ofArduino::ofArduino() {
63
	_portStatus = -1;
64
	_waitForData = 0;
65
	_analogHistoryLength = 2;
66
	_digitalHistoryLength = 2;
67
	_stringHistoryLength = 1;
68
	_sysExHistoryLength = 1;
69
	_initialized = false;
70
	_totalDigitalPins = 0;
71
	_executeMultiByteCommand = 0x00; // 0x00 a pin mode (input), not a command in Firmata -> fail hard
72
	_multiByteChannel = 0;
73
	_firstAnalogPin = -1;
74

75
	for (unsigned char & e : _storedInputData) {
76
		e = UCHAR_MAX;
77
	}
78
	for (int & e : _digitalPinMode) {
79
		e = INT_MAX;
80
	}
81
	for (int & e : _digitalPinValue) {
82
		e = INT_MAX;
83
	}
84
	for (int & e : _digitalPortValue) {
85
		e = INT_MAX;
86
	}
87
	for (int & e : _digitalPortReporting) {
88
		e = INT_MAX;
89
	}
90
	for (int & e : _digitalPinReporting) {
91
		e = INT_MAX;
92
	}
93
	for (int & e : _analogPinReporting) {
94
		e = INT_MAX;
95
	}
96
	for (int & e : _servoValue) {
97
		e = INT_MAX;
98
	}
99
	connected = false;
100
	connectTime = 0.0f;
101

102
	_majorFirmwareVersion = 0;
103
	_minorFirmwareVersion = 0;
104
	_firmwareName = "Unknown";
105

106
	bUseDelay = true;
107
}
108

109
ofArduino::~ofArduino() {
110
	_port.close();
111
}
112

113
// initialize pins once we get the Firmata version back from the Arduino board
114
// the version is sent automatically by the Arduino board on startup
115
void ofArduino::initPins() {
116

117
	if (_initialized) {
118
		return;                 // already initialized
119
	}
120

121
	_digitalHistory.resize(_totalDigitalPins + 1);
122
	_digitalPinMode.resize(_totalDigitalPins + 1);
123
	_digitalPinValue.resize(_totalDigitalPins + 1);
124
	_digitalPinReporting.resize(_totalDigitalPins + 1);
125
	_servoValue.resize(_totalDigitalPins + 1);
126

127
	_analogHistory.resize(_totalDigitalPins - _firstAnalogPin + 1);
128
	_analogPinReporting.resize(_totalDigitalPins - _firstAnalogPin + 1);
129

130
	// ports
131
	for (int i = 0; i < ARD_TOTAL_PORTS; ++i) {
132
		_digitalPortValue[i] = 0;
133
		_digitalPortReporting[i] = ARD_OFF;
134
	}
135

136
	// digital pins
137
	for (int i = 0; i < _firstAnalogPin; ++i) {
138
		_digitalPinValue[i] = -1;
139
		_digitalPinMode[i] = ARD_OUTPUT;
140
		_digitalPinReporting[i] = ARD_OFF;
141
	}
142

143
	// analog in pins
144
	for (int i = _firstAnalogPin; i < _totalDigitalPins; ++i) {
145
		_analogPinReporting[i - _firstAnalogPin] = ARD_OFF;
146
		// analog pins used as digital
147
		_digitalPinMode[i] = ARD_ANALOG;
148
		_digitalPinValue[i] = -1;
149
	}
150

151
	for (int i = 0; i < _totalDigitalPins; ++i) {
152
		_servoValue[i] = -1;
153
	}
154

155
	_initialized = true;
156
	ofNotifyEvent(EInitialized, _majorFirmwareVersion, this);
157
}
158

159
bool ofArduino::connect(const std::string & device, int baud) {
160
	connectTime = ofGetElapsedTimef();
161
	_initialized = false;
162
	connected = _port.setup(device.c_str(), baud);
163
	sendFirmwareVersionRequest();
164
	return connected;
165
}
166

167
// this method is not recommended
168
// the preferred method is to listen for the EInitialized event in your application
169
bool ofArduino::isArduinoReady() {
170
	if (bUseDelay) {
171
		if (!_initialized && (ofGetElapsedTimef() - connectTime) > OF_ARDUINO_DELAY_LENGTH) {
172
			sendPinCapabilityRequest();
173
			connected = true;
174
		}
175
	}
176
	return connected;
177
}
178

179
void ofArduino::setUseDelay(bool bDelay) {
180
	bUseDelay = bDelay;
181
}
182

183
void ofArduino::setDigitalHistoryLength(int length) {
184
	if (length >= 2) {
185
		_digitalHistoryLength = length;
186
	}
187
}
188

189
void ofArduino::setAnalogHistoryLength(int length) {
190
	if (length >= 2) {
191
		_analogHistoryLength = length;
192
	}
193
}
194

195
void ofArduino::setSysExHistoryLength(int length) {
196
	if (length >= 1) {
197
		_sysExHistoryLength = length;
198
	}
199
}
200

201
void ofArduino::setStringHistoryLength(int length) {
202
	if (length >= 1) {
203
		_stringHistoryLength = length;
204
	}
205
}
206

207
void ofArduino::disconnect() {
208
	_port.close();
209
}
210

211
void ofArduino::update() {
212
	vector <unsigned char> bytesToProcess;
213
	int bytesToRead = _port.available();
214
	if (bytesToRead > 0) {
215
		bytesToProcess.resize(bytesToRead);
216
		//its possible we dont get all the bytes
217
		int bytesRead = _port.readBytes(&bytesToProcess[0], bytesToRead);
218
		for (int i = 0; i < bytesRead; i++) {
219
			processData((char)(bytesToProcess[i]));
220
		}
221
	}
222
}
223

224
int ofArduino::getAnalog(int pin) const {
225
	if (!isAnalogPin(pin)) {
226
		return -1;
227
	}
228
	if (_digitalPinMode[convertAnalogPinToDigital(pin)] != ARD_ANALOG) {
229
		ofLogError("ofArduino") << "Analog Input has not been configured for pin " << pin;
230
		return -1;
231
	}
232
	pin = convertDigitalPinToAnalog(pin);
233
	if (_analogHistory[pin].size() > 0) {
234
		return _analogHistory[pin].front();
235
	}
236
	else {
237
		return -1;
238
	}
239
}
240

241
int ofArduino::getDigital(int pin) const {
242
	if (!isPin(pin)) {
243
		return -1;
244
	}
245
	if ((_digitalPinMode[pin] == ARD_INPUT || _digitalPinMode[pin] == ARD_INPUT_PULLUP) && _digitalHistory[pin].size() > 0) {
246
		return _digitalHistory[pin].front();
247
	}
248
	else if (_digitalPinMode[pin] == ARD_OUTPUT) {
249
		return _digitalPinValue[pin];
250
	}
251
	else {
252
		return -1;
253
	}
254
}
255

256
int ofArduino::getPwm(int pin) const {
257
	if (!isPin(pin)) {
258
		return -1;
259
	}
260
	if (!pinCapabilities[pin].pwmSupported) {
261
		ofLogError("ofArduino") << "PWM is not supported for pin " << pin;
262
		return -1;
263
	}
264
	if (_digitalPinMode[pin] == ARD_PWM) {
265
		return _digitalPinValue[pin];
266
	}
267
	else {
268
		return -1;
269
	}
270
}
271

272
vector <unsigned char> ofArduino::getSysEx() const {
273
	return _sysExHistory.front();
274
}
275

276
string ofArduino::getString() const {
277
	return _stringHistory.front();
278
}
279

280
int ofArduino::getDigitalPinMode(int pin) const {
281
	if (!isPin(pin)) {
282
		return -1;
283
	}
284
	return _digitalPinMode[pin];
285
}
286

287
void ofArduino::sendDigital(int pin, int value, bool force) {
288
	if (!isPin(pin)) {
289
		return;
290
	}
291
	if ((_digitalPinMode[pin] == ARD_INPUT || _digitalPinMode[pin] == ARD_INPUT_PULLUP || _digitalPinMode[pin] == ARD_OUTPUT) && (_digitalPinValue[pin] != value || force)) {
292

293
		_digitalPinValue[pin] = value;
294

295
		// set the bit
296
		int port = (pin >> 3) & 0x0F;
297

298
		if (value == 1)
299
			_digitalPortValue[port] |= (1 << (pin & 0x07));
300

301
		// clear the bit
302
		if (value == 0)
303
			_digitalPortValue[port] &= ~(1 << (pin & 0x07));
304

305
		sendByte(DIGITAL_MESSAGE | port);
306
		sendValueAsTwo7bitBytes(_digitalPortValue[port]);
307

308
	}
309
}
310

311
void ofArduino::sendPwm(int pin, int value, bool force) {
312
	if (!isPin(pin)) {
313
		return;
314
	}
315
	if (!pinCapabilities[pin].pwmSupported) {
316
		ofLogError("ofArduino") << "PWM is not supported for pin " << pin;
317
		return;
318
	}
319
	if (_digitalPinMode[pin] == ARD_PWM && (_digitalPinValue[pin] != value || force)) {
320
		sendByte(ANALOG_MESSAGE | pin);
321
		sendValueAsTwo7bitBytes(value);
322
		_digitalPinValue[pin] = value;
323
	}
324
}
325

326
void ofArduino::sendSysEx(int command, vector <unsigned char> data) {
327
	sendByte(START_SYSEX);
328
	sendByte(command);
329
	vector <unsigned char>::iterator it = data.begin();
330
	while (it != data.end()) {
331
		sendValueAsTwo7bitBytes(*it);
332
		it++;
333
	}
334
	sendByte(END_SYSEX);
335
}
336

337
void ofArduino::sendSysExBegin() {
338
	sendByte(START_SYSEX);
339
}
340

341
void ofArduino::sendSysExEnd() {
342
	sendByte(END_SYSEX);
343
}
344

345
void ofArduino::sendString(string str) {
346
	sendByte(START_SYSEX);
347
	sendByte(STRING_DATA);
348
	string::iterator it = str.begin();
349
	while (it != str.end()) {
350
		sendValueAsTwo7bitBytes(*it);
351
		it++;
352
	}
353
	sendByte(END_SYSEX);
354
}
355

356
void ofArduino::sendProtocolVersionRequest() {
357
	sendByte(REPORT_VERSION);
358
}
359

360
void ofArduino::sendFirmwareVersionRequest() {
361
	sendByte(START_SYSEX);
362
	sendByte(REPORT_FIRMWARE);
363
	sendByte(END_SYSEX);
364
}
365

366
//this currently isn't supported as the resonse is not mapped
367
void ofArduino::sendPinCofigurationRequest() {
368
	sendByte(START_SYSEX);
369
	sendByte(PIN_STATE_QUERY);
370
	sendByte(END_SYSEX);
371
}
372

373
void ofArduino::sendPinCapabilityRequest() {
374
	sendByte(START_SYSEX);
375
	sendByte(CAPABILITY_QUERY);
376
	sendByte(END_SYSEX);
377
}
378

379
void ofArduino::sendAnalogMappingRequest()
380
{
381
	sendByte(START_SYSEX);
382
	sendByte(ANALOG_MAPPING_QUERY);
383
	sendByte(END_SYSEX);
384
}
385

386
void ofArduino::sendPinStateQuery(int pin)
387
{
388
	sendByte(START_SYSEX);
389
	sendByte(PIN_STATE_QUERY);
390
	sendByte(pin & 0x7f);
391
	sendByte(END_SYSEX);
392
}
393

394
void ofArduino::sendReset() {
395
	sendByte(SYSTEM_RESET);
396
}
397

398
void ofArduino::sendAnalogPinReporting(int pin, int mode) {
399
	if (!isAnalogPin(pin)) {
400
		return;
401
	}
402

403
	//the digital pin mode needs the digital pin #
404
	_digitalPinMode[convertAnalogPinToDigital(pin)] = ARD_ANALOG;
405

406
	//the sent message needs the analog pin #
407
	sendByte(REPORT_ANALOG | convertDigitalPinToAnalog(pin));
408
	sendByte(mode);
409
	_analogPinReporting[convertDigitalPinToAnalog(pin)] = mode;
410
}
411

412
void ofArduino::sendDigitalPinMode(int pin, int mode) {
413
	if (!isPin(pin)) {
414
		return;
415
	}
416
	switch (mode) {
417
	case ARD_INPUT:
418
	case ARD_INPUT_PULLUP:
419
		if (!pinCapabilities[pin].inputSupported) {
420
			ofLogError("ofArduino") << "Input is not supported for pin " << pin;
421
			return;
422
		}
423
		break;
424
	case ARD_OUTPUT:
425
		if (!pinCapabilities[pin].outputSupported) {
426
			ofLogError("ofArduino") << "Output is not supported for pin " << pin;
427
			return;
428
		}
429
		break;
430
	case ARD_ANALOG:
431
		if (!pinCapabilities[pin].analogSupported) {
432
			ofLogError("ofArduino") << "Analog is not supported for pin " << pin;
433
			return;
434
		}
435
		break;
436
	case ARD_PWM:
437
		if (!pinCapabilities[pin].pwmSupported) {
438
			ofLogError("ofArduino") << "PWM is not supported for pin " << pin;
439
			return;
440
		}
441
		break;
442
	case ARD_SERVO:
443
		if (!pinCapabilities[pin].servoSupported) {
444
			ofLogError("ofArduino") << "Servo Control is not supported for pin " << pin;
445
			return;
446
		}
447
		break;
448
	case ARD_I2C:
449
		if (!pinCapabilities[pin].i2cSupported) {
450
			ofLogError("ofArduino") << "I2C is not supported for pin " << pin;
451
			return;
452
		}
453
		break;
454
	case ARD_ONEWIRE:
455
		if (!pinCapabilities[pin].onewireSupported) {
456
			ofLogError("ofArduino") << "Onewire is not supported for pin " << pin;
457
			return;
458
		}
459
		break;
460
	case ARD_STEPPER:
461
		if (!pinCapabilities[pin].stepperSupported) {
462
			ofLogError("ofArduino") << "Stepper Control is not supported for pin " << pin;
463
			return;
464
		}
465
		break;
466
	case ARD_ENCODER:
467
		if (!pinCapabilities[pin].encoderSupported) {
468
			ofLogError("ofArduino") << "Encoder Control is not supported for pin " << pin;
469
			return;
470
		}
471
		break;
472
	case ARD_SERIAL:
473
		if (!pinCapabilities[pin].serialSupported) {
474
			ofLogError("ofArduino") << "Serial is not supported for pin" + ofToString(pin);
475
			return;
476
		}
477
		break;
478
	default:
479
		ofLogError("ofArduino") << "Mode is not supported";
480
		return;
481
		break;
482
	}
483
	sendByte(SET_PIN_MODE);
484
	sendByte(pin); // Tx pins 0-6
485
	sendByte(mode);
486
	_digitalPinMode[pin] = mode;
487

488
	// turn on or off reporting on the port
489

490
	if (mode == ARD_INPUT || mode == ARD_INPUT_PULLUP) {
491
		sendDigitalPinReporting(pin, ARD_ON);
492
	}
493
	else {
494
		sendDigitalPinReporting(pin, ARD_OFF);
495
	}
496

497
}
498

499
int ofArduino::getAnalogPinReporting(int pin) const {
500
	if (!isAnalogPin(pin)) {
501
		return -1;
502
	}
503
	if (_digitalPinMode[convertAnalogPinToDigital(pin)] != ARD_ANALOG) {
504
		ofLogError("ofArduino") << "Analog Input has not been configured for pin " << pin;
505
		return -1;
506
	}
507
	//these are just safety checks
508
	pin = convertDigitalPinToAnalog(pin);
509
	return _analogPinReporting[pin];
510
}
511

512
list <int> * ofArduino::getAnalogHistory(int pin) {
513
	if (!isAnalogPin(pin)) {
514
		return NULL;
515
	}
516
	if (_digitalPinMode[convertAnalogPinToDigital(pin)] != ARD_ANALOG) {
517
		ofLogError("ofArduino") << "Analog Input has not been configured for pin " << pin;
518
		return NULL;
519
	}
520
	pin = convertDigitalPinToAnalog(pin);
521
	return &_analogHistory[pin];
522
}
523

524
list <int> * ofArduino::getDigitalHistory(int pin) {
525
	if (!isPin(pin)) {
526
		return NULL;
527
	}
528
	return &_digitalHistory[pin];
529
}
530

531
list <vector <unsigned char> > * ofArduino::getSysExHistory() {
532
	return &_sysExHistory;
533
}
534

535
list <string> * ofArduino::getStringHistory() {
536
	return &_stringHistory;
537
}
538

539
int ofArduino::getMajorFirmwareVersion() const {
540
	return _majorFirmwareVersion;
541
}
542

543
int ofArduino::getMinorFirmwareVersion() const {
544
	return _minorFirmwareVersion;
545
}
546

547
string ofArduino::getFirmwareName() const {
548
	return _firmwareName;
549
}
550

551
bool ofArduino::isInitialized() const {
552
	return _initialized;
553
}
554

555
bool ofArduino::isAttached() {
556
	//should return false if there is a serial error thus the arduino is not attached
557
	return _port.writeByte(static_cast<unsigned char>(END_SYSEX));
558
}
559

560
// ------------------------------ private functions
561

562
void ofArduino::processData(unsigned char inputData) {
563
	ofLog() << "Received Byte: " << inputData;
564

565
	// we have command data
566
	if (_waitForData > 0 && inputData < 128) {
567
		_waitForData--;
568

569
		// collect the data
570
		_storedInputData[_waitForData] = inputData;
571

572
		// we have all data executeMultiByteCommand
573
		if (_waitForData == 0) {
574
			switch (_executeMultiByteCommand) {
575
			case DIGITAL_MESSAGE:
576
				processDigitalPort(_multiByteChannel, (_storedInputData[0] << 7) | _storedInputData[1]);
577
				break;
578

579
			case REPORT_VERSION:    // report version
580
				_majorFirmwareVersion = _storedInputData[1];
581
				_minorFirmwareVersion = _storedInputData[0];
582
				ofNotifyEvent(EFirmwareVersionReceived, _majorFirmwareVersion, this);
583
				break;
584

585
			case ANALOG_MESSAGE:
586
				if (_initialized) {
587
					if (_analogHistory[_multiByteChannel].size() > 0) {
588
						int previous = _analogHistory[_multiByteChannel].front();
589

590
						_analogHistory[_multiByteChannel].push_front((_storedInputData[0] << 7) | _storedInputData[1]);
591
						if ((int)_analogHistory[_multiByteChannel].size() > _analogHistoryLength) {
592
							_analogHistory[_multiByteChannel].pop_back();
593
						}
594

595
						// trigger an event if the pin has changed value
596
						if (_analogHistory[_multiByteChannel].front() != previous) {
597
							ofNotifyEvent(EAnalogPinChanged, _multiByteChannel, this);
598
						}
599
					}
600
					else {
601
						_analogHistory[_multiByteChannel].push_front((_storedInputData[0] << 7) | _storedInputData[1]);
602
						if ((int)_analogHistory[_multiByteChannel].size() > _analogHistoryLength) {
603
							_analogHistory[_multiByteChannel].pop_back();
604
						}
605
					}
606
				}
607
				break;
608
			}
609

610
		}
611
	}
612
	// we have SysEx command data
613
	else if (_waitForData < 0) {
614

615
		// we have all sysex data
616
		if (inputData == END_SYSEX) {
617
			_waitForData = 0;
618
			processSysExData(_sysExData);
619
			_sysExData.clear();
620
		}
621
		// still have data, collect it
622
		else {
623
			_sysExData.push_back((unsigned char)inputData);
624
		}
625
	}
626
	// we have a command
627
	else {
628

629
		int command;
630

631
		// extract the command and channel info from a byte if it is less than 0xF0
632
		if (inputData < 0xF0) {
633
			command = inputData & 0xF0;
634
			_multiByteChannel = inputData & 0x0F;
635
		}
636
		else {
637
			// commands in the 0xF* range don't use channel data
638
			command = inputData;
639
		}
640

641
		switch (command) {
642
		case REPORT_VERSION:
643
		case DIGITAL_MESSAGE:
644
		case ANALOG_MESSAGE:
645
			_waitForData = 2;     // 2 bytes needed
646
			_executeMultiByteCommand = command;
647
			break;
648

649
		case START_SYSEX:
650
			_sysExData.clear();
651
			_waitForData = -1;     // n bytes needed, -1 is used to indicate sysex message
652
			_executeMultiByteCommand = command;
653
			break;
654
		}
655

656
	}
657
}
658

659
// sysex data is assumed to be 8-bit bytes split into two 7-bit bytes.
660
void ofArduino::processSysExData(vector <unsigned char> data) {
661

662
	string str;
663

664
	vector <unsigned char>::iterator it;
665
	unsigned char buffer;
666
	//int i = 1;
667

668
	// act on reserved sysEx messages (extended commands) or trigger SysEx event...
669
	switch (data.front()) {  //first byte in buffer is command
670
	case REPORT_FIRMWARE:
671
		ofLogVerbose("ofArduino") << "Recieved Firmware Report";
672
		it = data.begin();
673
		it++;    // skip the first byte, which is the firmware version command
674
		_majorFirmwareVersion = *it;
675
		it++;
676
		_minorFirmwareVersion = *it;
677
		it++;
678

679
		while (it != data.end()) {
680
			buffer = *it;
681
			it++;
682
			buffer += *it << 7;
683
			it++;
684
			str += buffer;
685
		}
686
		_firmwareName = str;
687

688
		ofNotifyEvent(EFirmwareVersionReceived, _majorFirmwareVersion, this);
689

690
		// trigger the initialization event
691
		if (!_initialized) {
692
			sendPinCapabilityRequest();
693
		}
694

695
		break;
696

697
	case STRING_DATA:
698
		ofLogVerbose("ofArduino") << "Recieved Firamta String";
699
		it = data.begin();
700
		it++;    // skip the first byte, which is the string command
701
		while (it != data.end()) {
702
			buffer = *it;
703
			it++;
704
			buffer += *it << 7;
705
			it++;
706
			str += buffer;
707
		}
708

709
		_stringHistory.push_front(str);
710
		if ((int)_stringHistory.size() > _stringHistoryLength) {
711
			_stringHistory.pop_back();
712
		}
713

714
		ofNotifyEvent(EStringReceived, str, this);
715
		break;
716
	case I2C_REPLY:
717
		ofLogVerbose("ofArduino") << "Recieved I2C Reply";
718
		if (data.size() > 7 && (data.size() - 5) % 2 == 0) {
719
			Firmata_I2C_Data i2creply;
720
			it = data.begin();
721

722
			i2creply.address = *++it | (*++it << 7);
723
			i2creply.reg = *++it | (*++it << 7);
724

725
			it++;
726
			while (it != data.end()) {
727
				str += *it | (*++it << 7);
728
				it++;
729
			}
730
			i2creply.data = str;
731
			ofNotifyEvent(EI2CDataRecieved, i2creply, this);
732
		}
733
		else {
734
			ofLogError("Arduino I2C") << "Incorrect Number of Bytes recieved, possible buffer overflow";
735
			purge();
736
		}
737
		break;
738
	case ENCODER_DATA:
739
		ofLogVerbose("ofArduino") << "Recieved Encoder Data";
740
		if (data.size() % 5 == 1) {
741

742
			vector<Firmata_Encoder_Data> encoderReply;
743
			Firmata_Encoder_Data tempEncoderReply;
744
			int encoderPos = 0;
745
			unsigned char encBuffer[4];
746

747
			it = data.begin();
748
			it++; // skip the first byte, which is the string command
749

750
			while (it != data.end()) {
751
				tempEncoderReply.ID = (*it & ENCODER_CHANNEL_MASK);
752
				tempEncoderReply.direction = (*it & ENCODER_DIRECTION_MASK);
753

754
				it++;
755

756
				encBuffer[0] = *it++ & 0x7F;
757
				encBuffer[1] = *it++ & 0x7F;
758
				encBuffer[2] = *it++ & 0x7F;
759
				encBuffer[3] = *it++ & 0x7F;
760

761
				encoderPos = encBuffer[3];
762
				encoderPos <<= 7;
763
				encoderPos |= encBuffer[2];
764
				encoderPos <<= 7;
765
				encoderPos |= encBuffer[1];
766
				encoderPos <<= 7;
767
				encoderPos |= encBuffer[0];
768

769
				tempEncoderReply.position = encoderPos;
770
				encoderReply.push_back(tempEncoderReply);
771
			}
772
			ofNotifyEvent(EEncoderDataReceived, encoderReply, this);
773
		}
774
		else {
775
			ofLogError("Arduino Encoder") << "Incorrect Number of Bytes recieved, possible buffer overflow";
776
			purge();
777
		}
778

779
		break;
780
	case SERIAL_MESSAGE:
781
	{
782
		ofLogVerbose("ofArduino") << "Recieved Serial Message";
783
		Firmata_Serial_Data reply;
784

785
		it = data.begin();
786
		//unsigned char command = *it & 0xF0;
787
		unsigned char portId = *it & 0x0F;
788
		it++;    // skip the first byte, which is the command and port
789

790
		while (it != data.end()) {
791
			buffer = *it;
792
			it++;
793
			buffer += *it << 7;
794
			it++;
795
			str += buffer;
796
		}
797
		switch (portId) {
798
		case HW_SERIAL0:
799
			reply.portID = HW_SERIAL0;
800
			break;
801
		case HW_SERIAL1:
802
			reply.portID = HW_SERIAL1;
803
			break;
804
		case HW_SERIAL2:
805
			reply.portID = HW_SERIAL2;
806
			break;
807
		case HW_SERIAL3:
808
			reply.portID = HW_SERIAL3;
809
			break;
810
		case SW_SERIAL0:
811
			reply.portID = SW_SERIAL0;
812
			break;
813
		case SW_SERIAL1:
814
			reply.portID = SW_SERIAL1;
815
			break;
816
		case SW_SERIAL2:
817
			reply.portID = SW_SERIAL2;
818
			break;
819
		case SW_SERIAL3:
820
			reply.portID = SW_SERIAL3;
821
			break;
822
		default:
823
			ofLogError("Arduino Serial") << "Port does not exist or is not defined";
824
		}
825
		reply.data = str;
826
		ofNotifyEvent(ESerialDataReceived, reply, this);
827
	}
828
	break;
829
	case CAPABILITY_RESPONSE:
830
	{
831
		ofLogVerbose("ofArduino") << "Recieved Capability Response";
832
		it = data.begin();
833
		it += 2; // skip the first byte, which is the string command
834

835
		int pin = 1;
836

837
		firmataInputSupported = false;
838
		firmataOutputSupported = false;
839
		firmataAnalogSupported = false;
840
		firmataPwmSupported = false;
841
		firmataServoSupported = false;
842
		firmataI2cSupported = false;
843
		firmataSerialSupported = false;
844
		firmataOnewireSupported = false;
845
		firmataStepperSupported = false;
846
		firmataEncoderSupported = false;
847

848
		while (it != data.end()) {
849
			switch (*it) {
850
			case ARD_INPUT:
851
				pinCapabilities[pin].inputSupported = true;
852
				pinCapabilities[pin].outputSupported = true;
853
				firmataInputSupported = true;
854
				firmataOutputSupported = true;
855
				it += 6;
856
				break;
857
			case ARD_ANALOG:
858
				pinCapabilities[pin].analogSupported = true;
859
				it += 2;
860
				if (!firmataAnalogSupported)
861
					_firstAnalogPin = pin;
862
				firmataAnalogSupported = true;
863
				break;
864
			case ARD_PWM:
865
				pinCapabilities[pin].pwmSupported = true;
866
				firmataPwmSupported = true;
867
				it += 2;
868
				break;
869
			case ARD_SERVO:
870
				pinCapabilities[pin].servoSupported = true;
871
				firmataServoSupported = true;
872
				it += 2;
873
				break;
874
			case ARD_I2C:
875
				pinCapabilities[pin].i2cSupported = true;
876
				firmataI2cSupported = true;
877
				it += 2;
878
				break;
879
			case ARD_SERIAL:
880
				pinCapabilities[pin].serialSupported = true;
881
				firmataI2cSupported = true;
882
				it += 2;
883
				break;
884
			case ARD_ONEWIRE:
885
				pinCapabilities[pin].onewireSupported = true;
886
				firmataOnewireSupported = true;
887
				it += 2;
888
				break;
889
			case ARD_STEPPER:
890
				pinCapabilities[pin].stepperSupported = true;
891
				firmataStepperSupported = true;
892
				it += 2;
893
				break;
894
			case ARD_ENCODER:
895
				pinCapabilities[pin].encoderSupported = true;
896
				firmataEncoderSupported = true;
897
				it += 2;
898
				break;
899
			default:
900
				it++;
901
				if (it != data.end()) {
902
					supportedPinTypes temp;
903
					pinCapabilities.emplace(++pin, temp);
904
				}
905
				break;
906
			}
907
		}
908
		_totalDigitalPins = pin;
909
		if (!_initialized) {
910
			sendAnalogMappingRequest();
911
		}
912
	}
913
	break;
914
	case ANALOG_MAPPING_RESPONSE:
915
	{
916
		ofLogVerbose("ofArduino") << "Recieved Analog Map Query Response";
917
		it = data.begin();
918
		int pin = 0;
919
		bool fAPin = false;
920
		it++;    // skip the first byte, which is the string command
921
		_totalAnalogPins = 0;
922
		while (it != data.end()) {
923
			//from the firmata protocol
924
			//analog channel corresponding to pin x, or 127 if pin x does not support analog
925
			if (*it != 127) {
926
				analogPinMap.emplace(int(*it), pin);
927
				_totalAnalogPins++;
928
				//these should be set by the capability query but just incase
929
				pinCapabilities[pin].analogSupported = true;
930
				if (!firmataAnalogSupported)
931
					firmataAnalogSupported = true;
932

933
				//lets also make sure that the capability response and this match up
934
				if (!fAPin) {
935
					if (pin != _firstAnalogPin)
936
						ofLogNotice("ofArduino") << "Capabaility Query and Analog Map don't match up";
937
					_firstAnalogPin = pin;
938
					fAPin = true;
939
				}
940
			}
941
			pin++;
942
			*it++;
943
		}
944
		if (!_initialized) {
945
			initPins();
946
		}
947
	}
948
	break;
949
	case PIN_STATE_RESPONSE:
950
	{
951
		ofLogVerbose("ofArduino") << "Recieved Pin State Query Response";
952
		it = data.begin();
953
		it++;    // skip the first byte, which is the string command
954
		int pin = *it++;
955
		Firmata_Pin_Modes mode{Firmata_Pin_Modes::MODE_INPUT};
956
		switch (*it++) {
957
		case ARD_INPUT:
958
			mode = Firmata_Pin_Modes::MODE_INPUT;
959
			break;
960
		case ARD_INPUT_PULLUP:
961
			mode = Firmata_Pin_Modes::MODE_INPUT_PULLUP;
962
			break;
963
		case ARD_OUTPUT:
964
			mode = Firmata_Pin_Modes::MODE_OUTPUT;
965
			break;
966
		case ARD_ANALOG:
967
			mode = Firmata_Pin_Modes::MODE_ANALOG;
968
			break;
969
		case ARD_PWM:
970
			mode = Firmata_Pin_Modes::MODE_PWM;
971
			break;
972
		case ARD_SERVO:
973
			mode = Firmata_Pin_Modes::MODE_SERVO;
974
			break;
975
		case ARD_I2C:
976
			mode = Firmata_Pin_Modes::MODE_I2C;
977
			break;
978
		case ARD_SERIAL:
979
			mode = Firmata_Pin_Modes::MODE_SERIAL;
980
			break;
981
		case ARD_ONEWIRE:
982
			mode = Firmata_Pin_Modes::MODE_ONEWIRE;
983
			break;
984
		case ARD_STEPPER:
985
			mode = Firmata_Pin_Modes::MODE_STEPPER;
986
			break;
987
		case ARD_ENCODER:
988
			mode = Firmata_Pin_Modes::MODE_ENCODER;
989
			break;
990
		}
991

992
		pair<int, Firmata_Pin_Modes> reply(pin, mode);
993
		ofNotifyEvent(EPinStateResponseReceived, reply, this);
994
	}
995
	break;
996
	default:    // the message isn't in Firmatas extended command set
997
		ofLogVerbose("ofArduino") << "This message isn't in Firmatas extended command set";
998
		_sysExHistory.push_front(data);
999
		if ((int)_sysExHistory.size() > _sysExHistoryLength) {
1000
			_sysExHistory.pop_back();
1001
		}
1002
		ofNotifyEvent(ESysExReceived, data, this);
1003
		break;
1004

1005
	}
1006
}
1007

1008
void ofArduino::processDigitalPort(int port, unsigned char value) {
1009

1010
	if (!_initialized)
1011
		return;
1012
	unsigned char mask;
1013
	int previous;
1014
	int pin;
1015

1016
	for (int i = 0; i < 8; ++i) {
1017
		pin = i + (port * 8);
1018
		if (pin <= _totalDigitalPins && (_digitalPinMode[pin] == ARD_INPUT || _digitalPinMode[pin] == ARD_INPUT_PULLUP)) {
1019
			if (!_digitalHistory[pin].empty())
1020
				previous = _digitalHistory[pin].front();
1021
			else previous = 0;
1022

1023
			mask = 1 << i;
1024
			_digitalHistory[pin].push_front((value & mask) >> i);
1025

1026
			if ((int)_digitalHistory[pin].size() > _digitalHistoryLength)
1027
				_digitalHistory[pin].pop_back();
1028

1029
			// trigger an event if the pin has changed value
1030
			if (_digitalHistory[pin].front() != previous) {
1031
				ofNotifyEvent(EDigitalPinChanged, pin, this);
1032
			}
1033
		}
1034
	}
1035
}
1036

1037
void ofArduino::sendDigitalPortReporting(int port, int mode) {
1038
	sendByte(REPORT_DIGITAL | port);
1039
	sendByte(mode);
1040
	_digitalPortReporting[port] = mode;
1041
}
1042

1043
void ofArduino::sendDigitalPinReporting(int pin, int mode) {
1044

1045
	int port = floor(pin / 8);
1046
	if (mode == ARD_OFF || mode == ARD_ON) {
1047
		_digitalPinReporting[pin] = mode;
1048
		sendDigitalPortReporting(port, mode);
1049
	}
1050
}
1051

1052
void ofArduino::sendByte(unsigned char byte) {
1053
	_port.writeByte(byte);
1054
}
1055

1056
// in Firmata (and MIDI) data bytes are 7-bits. The 8th bit serves as a flag to mark a byte as either command or data.
1057
// therefore you need two data bytes to send 8-bits (a char).
1058
void ofArduino::sendValueAsTwo7bitBytes(int value) {
1059
	sendByte(value & 127); // LSB
1060
	sendByte(value >> 7 & 127); // MSB
1061
}
1062

1063
// SysEx data is sent as 8-bit bytes split into two 7-bit bytes, this function merges two 7-bit bytes back into one 8-bit byte.
1064
int ofArduino::getValueFromTwo7bitBytes(unsigned char lsb, unsigned char msb) {
1065
	return (msb << 7) | lsb;
1066
}
1067

1068
int ofArduino::getInvertedValueFromTwo7bitBytes(unsigned char lsb, unsigned char msb) {
1069
	return msb | (lsb << 7);
1070
}
1071

1072
/********************************************
1073
*
1074
*
1075
*				Servo Functions
1076
*
1077
*
1078
********************************************/
1079

1080
void ofArduino::sendServoAttach(int pin, int minPulse, int maxPulse) {
1081
	if (!isPin(pin)) {
1082
		return;
1083
	}
1084
	if (!pinCapabilities[pin].servoSupported) {
1085
		ofLogError("ofArduino") << "Servo Control is not supported for pin" + ofToString(pin);
1086
		return;
1087
	}
1088
	sendByte(START_SYSEX);
1089
	sendByte(SERVO_CONFIG);
1090
	sendByte(pin);
1091
	sendValueAsTwo7bitBytes(minPulse);
1092
	sendValueAsTwo7bitBytes(maxPulse);
1093
	sendByte(END_SYSEX);
1094
	_digitalPinMode[pin] = ARD_SERVO;
1095
}
1096

1097
void ofArduino::sendServo(int pin, int value, bool force) {
1098
	if (!isPin(pin)) {
1099
		return;
1100
	}
1101
	if (!pinCapabilities[pin].servoSupported) {
1102
		ofLogError("ofArduino") << "Servo Control is not supported for pin " + ofToString(pin);
1103
		return;
1104
	}
1105
	if (_digitalPinMode[pin] != ARD_SERVO) {
1106
		ofLogError("ofArduino") << "Servo Control is not configured for pin " + ofToString(pin) + ". Did you send a servo attach message?";
1107
		return;
1108
	}
1109
	if (_digitalPinValue[pin] != value || force) {
1110
		if (pin > 15) {
1111
			sendByte(START_SYSEX);
1112
			sendByte(EXTENDED_ANALOG);
1113
			sendByte(pin);
1114
			sendValueAsTwo7bitBytes(value);
1115
			sendByte(END_SYSEX);
1116

1117
		}
1118
		else {
1119
			sendByte(ANALOG_MESSAGE | pin);
1120
			sendValueAsTwo7bitBytes(value);
1121
			_digitalPinValue[pin] = value;
1122
		}
1123
	}
1124
}
1125

1126
int ofArduino::getServo(int pin) const {
1127
	if (!isPin(pin)) {
1128
		return -1;
1129
	}
1130
	if (!pinCapabilities[pin].servoSupported) {
1131
		ofLogError("ofArduino") << "Servo Control is not supported for pin" + ofToString(pin);
1132
		return -1;
1133
	}
1134
	if (_digitalPinMode[pin] == ARD_SERVO) {
1135
		return _digitalPinValue[pin];
1136
	}
1137
	else {
1138
		return -1;
1139
	}
1140
}
1141

1142
/********************************************
1143
*
1144
*
1145
*				Stepper Functions
1146
*
1147
*
1148
********************************************/
1149

1150
void  ofArduino::sendStepper2Wire(int dirPin, int stepPin, int stepsPerRev) {
1151
	if (!isPin(dirPin)) {
1152
		return;
1153
	}
1154
	if (!isPin(stepPin)) {
1155
		return;
1156
	}
1157
	if (!pinCapabilities[dirPin].stepperSupported) {
1158
		ofLogError("ofArduino") << "Stepper Control is not supported for pin" + ofToString(dirPin);
1159
		return;
1160
	}
1161
	if (!pinCapabilities[stepPin].stepperSupported) {
1162
		ofLogError("ofArduino") << "Stepper Control is not supported for pin" + ofToString(stepPin);
1163
		return;
1164
	}
1165
	if (_numSteppers < MAX_STEPPERS) {
1166
		sendByte(START_SYSEX);
1167
		sendByte(STEPPER_DATA);
1168
		sendByte(STEPPER_CONFIG);
1169
		sendByte(_numSteppers);
1170
		sendByte(FIRMATA_STEPPER_DRIVER);
1171
		sendValueAsTwo7bitBytes(stepsPerRev);
1172
		sendByte(dirPin);
1173
		sendByte(stepPin);
1174
		sendByte(END_SYSEX);
1175
		_digitalPinMode[dirPin] = ARD_STEPPER;
1176
		_digitalPinMode[stepPin] = ARD_STEPPER;
1177
		_numSteppers++;
1178
	}
1179
	else {
1180
		ofLogNotice("Arduino") << "Reached max number of steppers";
1181
	}
1182
}
1183

1184
void  ofArduino::sendStepper4Wire(int pin1, int pin2, int pin3, int pin4, int stepsPerRev) {
1185
	if (!isPin(pin1)) {
1186
		return;
1187
	}
1188
	if (!isPin(pin2)) {
1189
		return;
1190
	}
1191
	if (!isPin(pin3)) {
1192
		return;
1193
	}
1194
	if (!isPin(pin4)) {
1195
		return;
1196
	}
1197
	if (!pinCapabilities[pin1].stepperSupported) {
1198
		ofLogError("ofArduino") << "Stepper Control is not supported for pin" + ofToString(pin1);
1199
		return;
1200
	}
1201
	if (!pinCapabilities[pin2].stepperSupported) {
1202
		ofLogError("ofArduino") << "Stepper Control is not supported for pin" + ofToString(pin2);
1203
		return;
1204
	}
1205
	if (!pinCapabilities[pin3].stepperSupported) {
1206
		ofLogError("ofArduino") << "Stepper Control is not supported for pin" + ofToString(pin3);
1207
		return;
1208
	}
1209
	if (!pinCapabilities[pin4].stepperSupported) {
1210
		ofLogError("ofArduino") << "Stepper Control is not supported for pin" + ofToString(pin4);
1211
		return;
1212
	}
1213
	if (_numSteppers < MAX_STEPPERS) {
1214
		sendByte(START_SYSEX);
1215
		sendByte(STEPPER_DATA);
1216
		sendByte(STEPPER_CONFIG);
1217
		sendByte(_numSteppers);
1218
		sendByte(FIRMATA_STEPPER_FOUR_WIRE);
1219
		sendValueAsTwo7bitBytes(stepsPerRev);
1220
		sendByte(pin1);
1221
		sendByte(pin2);
1222
		sendByte(pin3);
1223
		sendByte(pin4);
1224
		sendByte(END_SYSEX);
1225

1226
		_digitalPinMode[pin1] = ARD_STEPPER;
1227
		_digitalPinMode[pin2] = ARD_STEPPER;
1228
		_digitalPinMode[pin3] = ARD_STEPPER;
1229
		_digitalPinMode[pin4] = ARD_STEPPER;
1230
		_numSteppers++;
1231
	}
1232
	else {
1233
		ofLogNotice("Arduino") << "Reached max number of steppers";
1234
	}
1235

1236
}
1237

1238
void ofArduino::sendStepperMove(int stepperID, int direction, int numSteps, int speed, float acceleration, float deceleration) {
1239

1240
	if (stepperID <= _numSteppers && stepperID >= 0) {
1241
		unsigned char steps[3] = { static_cast<unsigned char>(abs(numSteps) & 0x0000007F), static_cast<unsigned char>((abs(numSteps) >> 7) & 0x0000007F), static_cast<unsigned char>((abs(numSteps) >> 14) & 0x0000007F) };
1242

1243
		// the stepper interface expects decimal expressed an an integer
1244
		if (acceleration != 0 && deceleration != 0) {
1245
			int accel = floor(acceleration * 100);
1246
			int decel = floor(deceleration * 100);
1247

1248
			sendByte(START_SYSEX);
1249
			sendByte(STEPPER_DATA);
1250
			sendByte(STEPPER_STEP);
1251
			sendByte(stepperID);
1252
			sendByte(direction);
1253
			sendByte(steps[0]);
1254
			sendByte(steps[1]);
1255
			sendByte(steps[2]);
1256
			sendValueAsTwo7bitBytes(speed);
1257
			sendValueAsTwo7bitBytes(accel);
1258
			sendValueAsTwo7bitBytes(decel);
1259
			sendByte(END_SYSEX);
1260

1261
		}
1262
		else {
1263
			sendByte(START_SYSEX);
1264
			sendByte(STEPPER_DATA);
1265
			sendByte(STEPPER_STEP);
1266
			sendByte(stepperID);
1267
			sendByte(direction);
1268
			sendByte(steps[0]);
1269
			sendByte(steps[1]);
1270
			sendByte(steps[2]);
1271
			sendValueAsTwo7bitBytes(speed);
1272
			sendByte(END_SYSEX);
1273
		}
1274
	}
1275
}
1276

1277

1278
/********************************************
1279
*
1280
*
1281
*				I2C Functions
1282
*
1283
*
1284
********************************************/
1285

1286
void  ofArduino::sendI2CConfig(int delay) {
1287
	sendByte(START_SYSEX);
1288
	sendByte(I2C_CONFIG);
1289
	sendByte(delay & 0xFF);
1290
	sendByte((delay >> 8) & 0xFF);
1291
	sendByte(END_SYSEX);
1292

1293
	_i2cConfigured = true;
1294
}
1295

1296
void  ofArduino::sendI2CWriteRequest(char slaveAddress, unsigned char * bytes, int numOfBytes, int reg) {
1297

1298
	if (_i2cConfigured) {
1299
		sendByte(START_SYSEX);
1300
		sendByte(I2C_REQUEST);
1301
		sendByte(slaveAddress);
1302
		sendByte(FIRMATA_I2C_WRITE << 3);
1303
		if (reg >= 0) {
1304
			sendValueAsTwo7bitBytes(reg);
1305
		}
1306
		for (int i = 0, length = numOfBytes; i < length; i++) {
1307
			sendValueAsTwo7bitBytes(bytes[i]);
1308
		}
1309

1310
		sendByte(END_SYSEX);
1311
	}
1312
	else {
1313
		ofLogError("Arduino") << "I2C was not configured, did you send an I2C config request?";
1314
	}
1315
}
1316

1317
void  ofArduino::sendI2CWriteRequest(char slaveAddress, char * bytes, int numOfBytes, int reg) {
1318
	if (_i2cConfigured) {
1319
		sendByte(START_SYSEX);
1320
		sendByte(I2C_REQUEST);
1321
		sendByte(slaveAddress);
1322
		sendByte(FIRMATA_I2C_WRITE << 3);
1323
		if (reg >= 0) {
1324
			sendValueAsTwo7bitBytes(reg);
1325
		}
1326
		for (int i = 0, length = numOfBytes; i < length; i++) {
1327
			sendValueAsTwo7bitBytes(bytes[i]);
1328
		}
1329

1330
		sendByte(END_SYSEX);
1331
	}
1332
	else {
1333
		ofLogError("Arduino") << "I2C was not configured, did you send an I2C config request?";
1334
	}
1335
}
1336

1337
void  ofArduino::sendI2CWriteRequest(char slaveAddress, const char * bytes, int numOfBytes, int reg) {
1338
	if (_i2cConfigured) {
1339
		sendByte(START_SYSEX);
1340
		sendByte(I2C_REQUEST);
1341
		sendByte(slaveAddress);
1342
		sendByte(FIRMATA_I2C_WRITE << 3);
1343
		if (reg >= 0) {
1344
			sendValueAsTwo7bitBytes(reg);
1345
		}
1346
		for (int i = 0, length = numOfBytes; i < length; i++) {
1347
			sendValueAsTwo7bitBytes(bytes[i]);
1348
		}
1349

1350
		sendByte(END_SYSEX);
1351
	}
1352
	else {
1353
		ofLogError("Arduino") << "I2C was not configured, did you send an I2C config request?";
1354
	}
1355
}
1356

1357
void  ofArduino::sendI2CWriteRequest(char slaveAddress, vector<char> bytes, int reg) {
1358

1359
	if (_i2cConfigured) {
1360
		sendByte(START_SYSEX);
1361
		sendByte(I2C_REQUEST);
1362
		sendByte(slaveAddress);
1363
		sendByte(FIRMATA_I2C_WRITE << 3);
1364
		if (reg >= 0) {
1365
			sendValueAsTwo7bitBytes(reg);
1366
		}
1367
		for (int i = 0, length = bytes.size(); i < length; i++) {
1368
			sendValueAsTwo7bitBytes(bytes[i]);
1369
		}
1370

1371
		sendByte(END_SYSEX);
1372
	}
1373
	else {
1374
		ofLogError("Arduino") << "I2C was not configured, did you send an I2C config request?";
1375
	}
1376
}
1377

1378
void  ofArduino::sendI2CReadRequest(char address, int numBytes, int reg) {
1379

1380
	if (_i2cConfigured) {
1381
		sendByte(START_SYSEX);
1382
		sendByte(I2C_REQUEST);
1383
		sendByte(address);
1384
		sendByte(FIRMATA_I2C_READ << 3);
1385
		if (reg >= 0) {
1386
			sendValueAsTwo7bitBytes(reg);
1387
		}
1388
		sendValueAsTwo7bitBytes(numBytes);
1389
		sendByte(END_SYSEX);
1390
	}
1391
	else {
1392
		ofLogError("Arduino") << "I2C was not configured, did you send an I2C config request?";
1393
	}
1394
}
1395

1396
void  ofArduino::sendI2ContinuousReadRequest(char address, int numBytes, int reg) {
1397
	if (_i2cConfigured) {
1398
		sendByte(START_SYSEX);
1399
		sendByte(I2C_REQUEST);
1400
		sendByte(address);
1401
		sendByte(FIRMATA_I2C_CONTINUOUS_READ << 3);
1402
		if (reg >= 0) {
1403
			sendValueAsTwo7bitBytes(reg);
1404
		}
1405
		sendValueAsTwo7bitBytes(numBytes);
1406
		sendByte(END_SYSEX);
1407
	}
1408
	else {
1409
		ofLogError("Arduino") << "I2C was not configured, did you send an I2C config request?";
1410
	}
1411
}
1412

1413
bool ofArduino::isI2CConfigured() {
1414
	return  _i2cConfigured;
1415
}
1416

1417
// CONTINUOUS_READ
1418

1419
/********************************************
1420
*
1421
*
1422
*				One Wire Functions
1423
*
1424
*
1425
********************************************/
1426

1427
void  ofArduino::sendOneWireConfig(int pin, bool enableParasiticPower) {
1428
	if (!isPin(pin)) {
1429
		return;
1430
	}
1431
	if (!pinCapabilities[pin].onewireSupported) {
1432
		ofLogError("ofArduino") << "Onewire is not supported for pin " << pin;
1433
		return;
1434
	}
1435
	sendByte(START_SYSEX);
1436
	sendByte(ONEWIRE_DATA);
1437
	sendByte(ONEWIRE_CONFIG_REQUEST);
1438
	sendByte(pin);
1439
	sendByte(enableParasiticPower ? 0x01 : 0x00);
1440
	sendByte(END_SYSEX);
1441
};
1442

1443
void  ofArduino::sendOneWireSearch(int pin) {
1444
	sendOneWireSearch(ONEWIRE_SEARCH_REQUEST, pin);
1445
};
1446

1447
void  ofArduino::sendOneWireAlarmsSearch(int pin) {
1448
	sendOneWireSearch(ONEWIRE_SEARCH_ALARMS_REQUEST, pin);
1449
};
1450

1451
//needs to notify event handler
1452
void  ofArduino::sendOneWireSearch(char type, int pin) {
1453
	if (!isPin(pin)) {
1454
		return;
1455
	}
1456
	if (!pinCapabilities[pin].onewireSupported) {
1457
		ofLogError("ofArduino") << "Onewire is not supported for pin " << pin;
1458
		return;
1459
	}
1460
	sendByte(START_SYSEX);
1461
	sendByte(ONEWIRE_DATA);
1462
	sendByte(type);
1463
	sendByte(pin);
1464
	sendByte(END_SYSEX);
1465
}
1466

1467
void  ofArduino::sendOneWireRead(int pin, vector<unsigned char> devices, int numBytesToRead) {
1468
	int correlationId = floor(ofRandomuf() * 255);
1469
	vector<unsigned char> b;
1470
	sendOneWireRequest(pin, ONEWIRE_READ_REQUEST_BIT, devices, numBytesToRead, correlationId, 0, b);
1471
}
1472

1473
void  ofArduino::sendOneWireReset(int pin) {
1474
	vector<unsigned char> a, b;
1475
	sendOneWireRequest(pin, ONEWIRE_RESET_REQUEST_BIT, a, 0, 0, 0, b);
1476
};
1477

1478
void  ofArduino::sendOneWireWrite(int pin, vector<unsigned char> devices, vector<unsigned char> data) {
1479
	sendOneWireRequest(pin, ONEWIRE_WRITE_REQUEST_BIT, devices, 0, 0, 0, data);
1480
};
1481

1482
void  ofArduino::sendOneWireDelay(int pin, unsigned int delay) {
1483
	vector<unsigned char> a, b;
1484
	sendOneWireRequest(pin, ONEWIRE_DELAY_REQUEST_BIT, a, 0, 0, delay, b);
1485
};
1486

1487
void  ofArduino::sendOneWireWriteAndRead(int pin, vector<unsigned char> devices, vector<unsigned char> data, int numBytesToRead) {
1488
	int correlationId = floor(ofRandomuf() * 255);
1489
	sendOneWireRequest(pin, ONEWIRE_WRITE_REQUEST_BIT | ONEWIRE_READ_REQUEST_BIT, devices, numBytesToRead, correlationId, 0, data);
1490
}
1491

1492
//// see http://firmata.org/wiki/Proposals#OneWire_Proposal
1493
void  ofArduino::sendOneWireRequest(int pin, unsigned char subcommand, vector<unsigned char> devices, int numBytesToRead, unsigned char correlationId, unsigned int delay, vector<unsigned char> dataToWrite) {
1494
	if (!isPin(pin)) {
1495
		return;
1496
	}
1497
	if (!pinCapabilities[pin].onewireSupported) {
1498
		ofLogError("ofArduino") << "Onewire is not supported for pin " << pin;
1499
		return;
1500
	}
1501
	vector<unsigned char> bytes;
1502
	bytes.resize(16);
1503

1504
	if (devices.size() > 0 || numBytesToRead > 0 || correlationId || delay > 0 || dataToWrite.size() > 0) {
1505
		subcommand = subcommand | ONEWIRE_WITHDATA_REQUEST_BITS;
1506
	}
1507

1508
	if (devices.size() > 0) {
1509
		for (size_t i = 0; i < devices.size(); i++) {
1510
			bytes[i] = devices[i];
1511
		}
1512
	}
1513

1514
	if (numBytesToRead > 0) {
1515
		bytes[8] = numBytesToRead & 0xFF;
1516
		bytes[9] = (numBytesToRead >> 8) & 0xFF;
1517
	}
1518

1519
	if (correlationId) {
1520
		bytes[10] = correlationId & 0xFF;
1521
		bytes[11] = (correlationId >> 8) & 0xFF;
1522
	}
1523

1524
	if (delay > 0) {
1525
		bytes[12] = delay & 0xFF;
1526
		bytes[13] = (delay >> 8) & 0xFF;
1527
		bytes[14] = (delay >> 16) & 0xFF;
1528
		bytes[15] = (delay >> 24) & 0xFF;
1529
	}
1530

1531
	if (dataToWrite.size() > 0) {
1532
		for (size_t i = 0; i < dataToWrite.size(); i++) {
1533
			bytes.push_back(dataToWrite[i]);
1534
		}
1535
	}
1536

1537
	sendByte(START_SYSEX);
1538
	sendByte(ONEWIRE_DATA);
1539
	sendByte(subcommand);
1540
	sendByte(pin);
1541
	int shift = 0;
1542
	int previous = 0;
1543
	//i dont think this is safe
1544
	for (size_t i = 0; i < bytes.size(); i++) {
1545
		if (shift == 0) {
1546
			sendByte(bytes[i] & 0x7f);
1547
			shift++;
1548
			previous = bytes[i] >> 7;
1549
		}
1550
		else {
1551
			sendByte(((bytes[i] << shift) & 0x7f) | previous);
1552
			if (shift == 6) {
1553
				sendByte(bytes[i] >> 1);
1554
				shift = 0;
1555
			}
1556
			else {
1557
				shift++;
1558
				previous = bytes[i] >> (8 - shift);
1559
			}
1560
		}
1561
	}
1562
	if (shift > 0) {
1563
		sendByte(previous);
1564
	}
1565

1566
	sendByte(END_SYSEX);
1567
}
1568

1569
/********************************************
1570
*
1571
*
1572
*				Encoder Functions
1573
*
1574
*
1575
********************************************/
1576

1577
void ofArduino::attachEncoder(int pinA, int pinB) {
1578
	if (!isPin(pinA)) {
1579
		return;
1580
	}
1581
	if (!isPin(pinB)) {
1582
		return;
1583
	}
1584
	if (!pinCapabilities[pinA].encoderSupported) {
1585
		ofLogError("ofArduino") << "Encoder Control is not supported for pin " + ofToString(pinA);
1586
		return;
1587
	}
1588
	if (!pinCapabilities[pinB].encoderSupported) {
1589
		ofLogError("ofArduino") << "Encoder Control is not supported for pin " + ofToString(pinB);
1590
		return;
1591
	}
1592
	if (_encoderID < MAX_ENCODERS) {
1593
		sendByte(START_SYSEX);
1594
		sendByte(ENCODER_DATA);
1595
		sendByte(ENCODER_ATTACH);
1596
		sendByte(_encoderID);
1597
		sendByte(pinA);
1598
		sendByte(pinB);
1599
		sendByte(END_SYSEX);
1600
		_encoderID++;
1601
	}
1602

1603
}
1604
void ofArduino::getEncoderPosition(int encoderID) {
1605
	if (encoderID <= _encoderID && encoderID >= 0) {
1606
		sendByte(START_SYSEX);
1607
		sendByte(ENCODER_DATA);
1608
		sendByte(ENCODER_REPORT_POSITION);
1609
		sendByte(encoderID);
1610
		sendByte(END_SYSEX);
1611
	}
1612
}
1613
void ofArduino::getAllEncoderPositions() {
1614
	sendByte(START_SYSEX);
1615
	sendByte(ENCODER_DATA);
1616
	sendByte(ENCODER_REPORT_POSITIONS);
1617
	sendByte(END_SYSEX);
1618
}
1619
void ofArduino::resetEncoderPosition(int encoderID) {
1620
	if (encoderID <= _encoderID && encoderID >= 0) {
1621
		sendByte(START_SYSEX);
1622
		sendByte(ENCODER_DATA);
1623
		sendByte(ENCODER_RESET_POSITION);
1624
		sendByte(encoderID);
1625
		sendByte(END_SYSEX);
1626
	}
1627
}
1628
void ofArduino::enableEncoderReporting() {
1629
	sendByte(START_SYSEX);
1630
	sendByte(ENCODER_DATA);
1631
	sendByte(ENCODER_REPORT_AUTO);
1632
	sendByte(1);
1633
	sendByte(END_SYSEX);
1634
}
1635
void ofArduino::disableEncoderReporting() {
1636
	sendByte(START_SYSEX);
1637
	sendByte(ENCODER_DATA);
1638
	sendByte(ENCODER_REPORT_AUTO);
1639
	sendByte(0);
1640
	sendByte(END_SYSEX);
1641
}
1642
void ofArduino::detachEncoder(int encoderID) {
1643
	if (encoderID <= _encoderID && encoderID >= 0) {
1644
		sendByte(START_SYSEX);
1645
		sendByte(ENCODER_DATA);
1646
		sendByte(ENCODER_DETACH);
1647
		sendByte(encoderID);
1648
		sendByte(END_SYSEX);
1649
		_encoderID--;
1650
	}
1651
}
1652

1653
//if the buffer gets out of sync we have to purge everything to get back on track
1654
void ofArduino::purge() {
1655
	while (_port.readByte() != -1);
1656
	for (int i = 0; i < 5; i++)
1657
		sendByte(END_SYSEX);
1658
}
1659

1660
/********************************************
1661
*
1662
*
1663
*				Serial Functions
1664
*
1665
*
1666
********************************************/
1667

1668
void ofArduino::sendSerialConfig(Firmata_Serial_Ports portID, int baud, int rxPin, int txPin) {
1669

1670
	if (portID > 7 && rxPin < 0 && txPin < 0) {
1671
		ofLogError("ofArduino") << "Both RX and TX pins must be defined when using Software Serial.";
1672
		return;
1673
	}
1674

1675
	sendByte(START_SYSEX);
1676
	sendByte(SERIAL_MESSAGE);
1677
	sendByte(SERIAL_CONFIG | portID);
1678
	sendByte(baud & 0x007F);
1679
	sendByte((baud >> 7) & 0x007F);
1680
	sendByte((baud >> 14) & 0x007F);
1681

1682
	if (portID > 7 && rxPin >= 0 && txPin >= 0) {
1683
		sendByte(rxPin);
1684
		sendByte(txPin);
1685
	}
1686
	else if (portID > 7) {
1687
		ofLogError("ofArduino") << "Both RX and TX pins must be defined when using Software Serial.";
1688
	}
1689

1690
	sendByte(END_SYSEX);
1691
};
1692

1693
void ofArduino::serialWrite(Firmata_Serial_Ports portID, unsigned char * bytes, int numOfBytes) {
1694
	sendByte(START_SYSEX);
1695
	sendByte(SERIAL_MESSAGE);
1696
	sendByte(SERIAL_WRITE | portID);
1697
	for (int i = 0; i < numOfBytes; i++) {
1698
		sendValueAsTwo7bitBytes(bytes[i]);
1699
	}
1700
	sendByte(END_SYSEX);
1701
};
1702

1703
void ofArduino::serialRead(Firmata_Serial_Ports portID, int maxBytesToRead) {
1704
	sendByte(START_SYSEX);
1705
	sendByte(SERIAL_MESSAGE);
1706
	sendByte(SERIAL_READ | portID);
1707
	sendByte(FIRMATA_SERIAL_READ_CONTINUOUS);
1708

1709
	if (maxBytesToRead > 0) {
1710
		sendValueAsTwo7bitBytes(maxBytesToRead);
1711
	}
1712

1713
	sendByte(END_SYSEX);
1714
};
1715

1716
void ofArduino::serialStop(Firmata_Serial_Ports portID) {
1717
	sendByte(START_SYSEX);
1718
	sendByte(SERIAL_MESSAGE);
1719
	sendByte(SERIAL_READ | portID);
1720
	sendByte(FIRMATA_SERIAL_STOP_READING);
1721
	sendByte(END_SYSEX);
1722
};
1723

1724
void ofArduino::serialClose(Firmata_Serial_Ports portID) {
1725
	sendByte(START_SYSEX);
1726
	sendByte(SERIAL_MESSAGE);
1727
	sendByte(SERIAL_CLOSE | portID);
1728
	sendByte(END_SYSEX);
1729
};
1730

1731
void ofArduino::serialFlush(Firmata_Serial_Ports portID) {
1732
	sendByte(START_SYSEX);
1733
	sendByte(SERIAL_MESSAGE);
1734
	sendByte(SERIAL_FLUSH | portID);
1735
	sendByte(END_SYSEX);
1736
};
1737

1738
void ofArduino::serialListen(Firmata_Serial_Ports portID) {
1739
	// listen only applies to software serial ports
1740
	if (portID < 8) {
1741
		return;
1742
	}
1743
	sendByte(START_SYSEX);
1744
	sendByte(SERIAL_MESSAGE);
1745
	sendByte(SERIAL_LISTEN | portID);
1746
	sendByte(END_SYSEX);
1747
};
1748

1749

1750

1751
//this is mostly safe except for the teensy 2.0, it has 12 analog outs starting at 22 going down to 11
1752
//the problem arises if they mean digital pin 11 or analog pin 11 which are not the same
1753
//digital pin 11 is analog pin 10 and analog pin 11 is digital pin 22
1754
bool ofArduino::isAnalogPin(int pin) const
1755
{
1756
	if (isPin(convertAnalogPinToDigital(pin))) {
1757
		if (pin < _firstAnalogPin) // this probably means they are using the Analog pin #
1758
		{
1759
			if (analogPinMap.count(pin) < 1) { //the pin doesnt exist in the analog pin mapping
1760
				ofLogError("ofArduino") << "Analog is not supported for pin " + ofToString(pin);
1761
				return false;
1762
			}
1763
			return true;
1764
		}
1765
		else //they are using the digital pin #
1766
		{
1767
			if (pinCapabilities.count(pin) < 1) {
1768
				ofLogError("ofArduino") << "Analog is not supported for pin " + ofToString(pin);
1769
				return false;
1770
			}
1771
			return true;
1772
		}
1773
	}
1774
	return false;
1775
}
1776

1777

1778
//this should only be false if the pin is negative or greater than the number of pins on the board
1779
//just incase we check against the pin capability map if for some reason a pin doesn't exist
1780
//pin 0 & 1 are outliers because they dont exist in the capability query but technically exist
1781
//we cant really use pin 0 & 1 though as it messes up the serial communication
1782
bool ofArduino::isPin(int pin) const
1783
{
1784
	if (pin < 0 || pin > _totalDigitalPins) {
1785
		ofLogError("ofArduino") << "Pin " + ofToString(pin) + " does not exist on the current board";
1786
		return false;
1787
	}
1788
	if (pinCapabilities.count(pin) < 1) {
1789
		ofLogError("ofArduino") << "Pin " + ofToString(pin) + " does not exist on the current board";
1790
		return false;
1791
	}
1792
	return true;
1793
}
1794

1795
//this returns the pin if its already not within the analog pin map
1796
//we need this to check between digital and analog pin mappings
1797
int ofArduino::convertAnalogPinToDigital(size_t pin) const
1798
{
1799
	if (pin < analogPinMap.size()) {
1800
		if (analogPinMap.count(pin) > 0) {
1801
			return analogPinMap[pin];
1802
		}
1803
		else {
1804
			ofLogError("ofArduino") << "Pin " + ofToString(pin) + " is not an Analog Pin";
1805
			return -1;
1806
		}
1807
	}
1808
	return pin;
1809
}
1810

1811
//this returns the pin if its already within the analog pin map
1812
//we need this to check between digital and analog pin mappings
1813
int ofArduino::convertDigitalPinToAnalog(size_t pin) const
1814
{
1815
	if (pin > analogPinMap.size()) {
1816
		for (auto aPin : analogPinMap)
1817
			if (aPin.second == (int)pin) {
1818
				return aPin.first;
1819
			}
1820
		ofLogError("ofArduino") << "Pin " + ofToString(pin) + " is not an Analog Pin";
1821
		return -1;
1822
	}
1823
	return pin; //this pin is already in the range of analog pins
1824
}
1825

1826
//these functions can't really account for user error 
1827

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.