Arduino / of0.9.0 / of0.8.4

I’m experimenting with of0.9.0 and an Arduino (uno). Results so far are a bit hit-and-miss, and I’m trying to figure out what could be causing that.

I’ve breadboarded a kind of ‘minimal arduino’ setup: 1 servo, 1 digital in, 1 analog in, 1 pwm out, and am using a v3 Arduino Uno (on Linux/F23)

Couple of questions:

  • Are there some limits in ofArduino/Firmata that I’m not aware of? For example, it seems that I cannot have a PWM out and a servo working at the same time.
    I’ve dropped the framerate as low as 20fps, but as soon as I enable a PWM pin, the servo stops responding.

  • I’ve pulled in the ‘new’ Arduino code from @DomAmato in my own of0.9.0 branch, but when I run the app, analog pin 0 is no longer recognized (‘Pin 0 does not exist on the current board’), and PWM mode cannot be set (‘PWM is not supported for this pin’). PWM+servo behaviour is otherwise the same: if I try to enable PWM (even though it fails), the servo stops responding.
    Without the new Arduino code the behaviour is the same as with of0.8.4

Any clues? I’m happy to help debug this, but am not sure where to start…

What version of Firmata are you running on the arduino? The most recent code I wrote was for 2.4.4 though really its 2.5 since those new features are part of the current upgrade.

I have a good idea whats causing the analog input problem and I will take a look at that shortly. For the PWM problem what pin are you trying to set as PWM? What pin is the servo?

Can you show me the code in the setupArduino phase or whatever function you have where you declare your pins?

I’m running 2.4.4 - the version that comes with Arduino 1.6.6

Just to make sure I’ve got your latest code: I’ve merged this commit

The servo is at pin 9, the PWM pin (with a LED) is pin 11
My setup function (called via the arduino.EInitialized event) looks like this:

void ofApp::setupArduino(const int & version) {
    ofRemoveListener(arduino.EInitialized, this, &ofApp::setupArduino);

    ofLogNotice() << arduino.getFirmwareName();
    ofLogNotice() << " v" << arduino.getMajorFirmwareVersion() << "." << arduino.getMinorFirmwareVersion();

    arduino.sendAnalogPinReporting(0, ARD_ANALOG);
    arduino.sendDigitalPinMode(2, ARD_INPUT);
    arduino.sendDigitalPinMode(13, ARD_OUTPUT);
    arduino.sendDigitalPinMode(11, ARD_PWM);

    // Listen for changes on the digital and analog pins
    ofAddListener(arduino.EDigitalPinChanged, this, &ofApp::digitalPinChanged);
    ofAddListener(arduino.EAnalogPinChanged, this, &ofApp::analogPinChanged);


Oh, not sure if it is relevant: after the arduino.connect(...) I have an explicit call to sendFirmareVersionRequest() like you suggested elsewhere.

Ok the analog problem im pretty sure is related to this:

at line 215 in ofArduino in the getAnalog function you need to replace to pin capabilities test with the following

if (pinCapabilities.count((firstAnalogPin + pin) < _totalDigitalPins ? (firstAnalogPin + pin) : pin) < 1) {
	ofLogError("ofArduino") << "Pin " + ofToString((firstAnalogPin + pin) < _totalDigitalPins ? (firstAnalogPin + pin) : pin) + " does not exist on the current board";
	return -1;
if (!pinCapabilities[(firstAnalogPin + pin) < _totalDigitalPins ? (firstAnalogPin + pin) : pin].analogSupported) {
	ofLogError("ofArduino") << "Analog is not supported for pin " + ofToString((firstAnalogPin + pin) < _totalDigitalPins ? (firstAnalogPin + pin) : pin);
	return -1;

The PWM and servo one isn’t quite clear as to the problem since the protocol for both are essentially the same. Unfortunately I don’t have a servo to test with but I can’t see any problems with the code.

Can you show the code that tells the servo to move and changes the PWM value?

I will update the code with the most recent changes but the only changes I made to the servo and pwm is I “or’d” the bits instead of added them and took in account for servos over pin 16

Also you no longer need to do a sendFirmareVersionRequest() if you are using my version as it handles that in the connection phase, though there is no harm in leaving that in.

That doesn’t help, unfortunately - the error appears to be triggered in ofArduino::sendAnalogPinReporting (and AFAICT that uses the right logic - or at least the same logic as in the snippet you posted)

Could the problem be somewhere in the init/board detection code? That might explain why the PWM/servo/analog stuff interfere?

Most of the code is directly from the OF Firmata example.

This is the code that moves the servo:

 void ofApp::keyPressed  (int key){
     switch (key) {
         case OF_KEY_RIGHT:
             arduino.sendServo(9, 180, false);
         case OF_KEY_LEFT:
             arduino.sendServo(9, 0, false);

And this is the code for the PWM:

void ofApp::update(){
    if (!arduino.isInitialized()) return;

    arduino.sendPwm(11, (int)(128 + 128 * sin(ofGetElapsedTimef())));

Can you put a breakpoint at the first part of sendAnalogPinReporting and tell me what the pin map says as well as what firstAnalogPin is?

firstAnalogPin should be 14 for an UNO

The pin map is a bit hard to post here but should have a size of 18 and slot 12 should be pin 14 that supports input, output, analog, and servos

Well, that doesn’t seem correct: firstAnalogPin is set to 0, and pin 14 (entry 12) has analogSupported set to false

I think thats unlikely to cause the interference but that might be related to the analog pin issue your are experiencing. I was trying to keep the paradigm that the firmware request means the handshake is completed but its possible your program is trying to setup the pins before the capability query is done and this the pin map hasnt been populated yet.

is the flag firmataAnalogSupported set to true? i have a hunch that firstAnalogPin is never initialized since it should never be 0

no, firmataAnalogSupported is false

btw - I’ve removed the superfluous version request, and the whole pin setup only starts once the EInitialized event gets fired.

strange I can’t replicate this on either windows or osx. Try uploading standardFirmataPlus to your board but the capability response seems to be working except for the analog part as the pins are properly mapped…

I’ll try that but I’ll need to set that up first.
Meanwhile, I added a breakpoint in the case ARD_ANALOG in the capability response handling code, and did notice that never fires.

Well, as luck would have it Firmata 2.5.0 has just been released 3 hrs ago :smile:
I’ve uploaded StandardFirmataPlus, and now I can get the PWM led, analog input and digital input working at the same time, but the servo doesn’t do anything :confused:

Ok, it seems to be a question of who comes first: if I move the sendServoAttach() line before the sendDigitalPinMode(11,ARD_PWM) line, the servo works, but the PWM doesn’t. If I reverse the order, the PWM works, but the servo doesn’t.
So far, reliably reproducable :persevere:

I am reworking some of the code regardless, adding a fallback feature using the analog pin mapping query to essentially double check things.

From the sounds of it, it seems they are competing for the same timer on the arduino but that shouldn’t be happening as the servo library should be mapped to a different timer than the PWM one. Try putting the servo on one of the analog pins, you can only use A0 (pin 14) or A1 (Pin 15) unless you have the most recent code I uploaded like an hour ago.

If that works its only a workaround not an actual solution.

Tried with the servo on A1/pin15, but that gave the same effect: whichever you configure first (servo or PWM), wins.
I’ve now updated to your latest code, and still have the same behaviour (with servo @ A1/p15 or p9), and also get the occasional coredump.

I’m not sure this is related to the client implementation since the old method didn’t change it, rather this might be more firmware/hardware related. I would recommend opening up an issue on the firmata github. Jeff, the maintainer of the repo, might have a suggestion but as far as I can tell the protocol is followed exactly as specified.

OK, I’ll do that! Thanks for your help sofar!

@bakercp Do you have any ideas regarding this? I know you aren’t super familiar with the changes I made to the code but maybe you have an idea whats causing it other than what I guessed was a fight over the same hardware timer.