OF 062, Firmata 2.2, servos

Hi All, I’m currently trying to update some code and get my firmata2.2 and OF talking to each other nicely.

In previous versions, ( 060 I think) I was able to control the servos in OF using the advice and firmata version in this thread: http://forum.openframeworks.cc/t/ofarduino-and-servo/2950/4). However in 062, I can’t make my servos move, and get random crashes. However, when I don’t access the servo pins, it is stable.

Any advice?

have created an issue for this:

https://github.com/openframeworks/openF-…-issues/489

can’t think of nothing that changed from 0061 to 0062 for firmata, so i guess the problem is that the software was changed in the arduino side and we haven’t kept it up to date. About the crashes, can you debug your application and post in which line is it crashing?

I think that the servo code in oF is not in line with the latest firmata protocol. I recall having to change the oF code to get servos to work a while ago. I’ll look into it tonight. Need to do this anyway because I’m using the code in a class I’m teaching on HW/SW integration starting in a couple of weeks.

After some more testing I can say:

[All-OSX-10.6)–

(with-the-older-firmata)–
OF-0.060-±ofstandardfirmataplusservoplusshiftregister—works-reliably–
OF-0.061-±ofstandardfirmataplusservoplusshiftregister—causes-frequent-crashes.–
OF-0.062-±ofstandardfirmataplusservoplusshiftregister—frequent-crashes.–

with-the-newest-firmata:–
OF-0.062-±firmata-2.2—runs-but-servos-don’t-work.–


the-most-common-crash-I-get-is-a-EXC-BAD-ACESS-in-ofArduino::processSysExData()–

--
	//-act-on-reserved-sysEx-messages-(extended-commands)-or-trigger-SysEx-event...--
	switch(data.front())-{-//first-byte-in-buffer-is-command--
		case-FIRMATA-SYSEX-REPORT-FIRMWARE:--
			it-=-data.begin();--
			it++;-//-skip-the-first-byte,-which-is-the-firmware-version-command--
			-majorFirmwareVersion-=-*it;--
			it++;--
			-minorFirmwareVersion-=-*it;--
			it++;--
--
			while(-it-!=-data.end()-)-{--
					buffer-=-*it;--
					it++;--
					buffer-+=-*it-<<-7;--//line-where-most-crashes-happen--
					it++;--
					str+=buffer;--
			}--
			-firmwareName-=-str;--


I-also-think-that-the-newer-UNO-boards-will-only-accept-the-2.2-firmware-(the-other-won’t-even-compile-in-recent-arduino-builds)-so-that-will-be-an-issue-for-those-who-don’t-have-stockpiles-of-older-boards.–

I’ve-uploaded-a-little-test-app-to-http://happyfamilylife.net/ServoTests.zip

I’ve looked into this further and have a fix. The issue was as I suspected that the way servo is handled in firmata 2.2 is different than in ofArduino.

I have pasted a temporary fix below. Replace the following in ofArduino.cpp. Please note that this will break backwards compatibility so it should only be used as a temporary solution. I hope to have time this weekend to properly update the file in my oF fork and will submit a pull request at that time.

  
  
/*  
void ofArduino::sendServo(int pin, int value, bool force){  
	if(_digitalPinMode[pin]==ARD_SERVO && (_servoValue[pin]!=value || force)){  
		//sendByte(FIRMATA_START_SYSEX);  
		//sendByte(SYSEX_SERVO_WRITE);  
		//sendByte(pin);  
		//sendValueAsTwo7bitBytes(value);  
		//sendByte(FIRMATA_END_SYSEX);  
		_servoValue[pin]=value;  
	}  
}  
*/  
  
// update for firmata 2.2  
void ofArduino::sendServo(int pin, int value, bool force){  
	if(_digitalPinMode[pin]==ARD_SERVO && (_digitalPinValue[pin]!=value || force)){  
		sendByte(FIRMATA_ANALOG_MESSAGE+pin);  
		sendValueAsTwo7bitBytes(value);  
		_digitalPinValue[pin] = value;  
	}  
}  
  
void ofArduino::sendServoAttach(int pin, int minPulse, int maxPulse, int angle) {  
	sendByte(FIRMATA_START_SYSEX);  
	//sendByte(SYSEX_SERVO_ATTACH);  
	sendByte(FIRMATA_SYSEX_SERVO_CONFIG);  
	sendByte(pin);  
	sendValueAsTwo7bitBytes(minPulse);  
	sendValueAsTwo7bitBytes(maxPulse);  
	sendByte(FIRMATA_END_SYSEX);  
	_digitalPinMode[pin]=ARD_SERVO;  
}  
  

thanks for that, soundanalogous.

we also need to change the get method for the servo to use digitalPinValue instead of servoValue:

  
int ofArduino::getServo(int pin){  
	if(_digitalPinMode[pin]==ARD_SERVO)  
		//return _servoValue[pin];  
		return  _digitalPinValue[pin];  
	else  
		return -1;  
}  

so now the servos move, but I still get crashes on startup about 30% of the time.
and I can confirm this works with Uno boards now.

Latest update should be backwards compatible with older firmata versions with servo support:

https://github.com/soundanalogous/openF-…-0b5b119294

I’ve submitted a pull request so hopefully it will merged with the main oF repository soon.

Here’s an example usage: http://www.box.net/shared/32tfaon50q

Note the use of the EInitialized event in the setup() method of the example rather than polling isArduinoReady. You will need to use the event rather than polling for servo to work properly with Firmata 2.2. This is also better practice in general since isArduinoReady() was based on an arbitrary delay period rather than the actual initialization event.

Regarding the crash you’ve been experiencing. I have also noticed this and think it may be a timing issue either in firmata running on the arduino or somewhere in ofArduino. What’s happening is on startup an event indicating that firmata on the Arduino has acknowledged the connection to the oF application is sending incomplete data so during the read, the pointer increments and there is nothing stored at the address (this where you see the code stopping in the debugger). I intend to look into this.

-jeff