MW freezes with continuous sampling of Firmata channels

Hello,

I am trying to read encoder values using an Arduino UNO through MWorks. This works within Arduino (using a sketch that just counts the encoder values), but when I try to do this in MWorks, no values are updated and MWorks freezes. I also tried increasing the data_interval parameter to 20ms to see if slower sampling would help, but this did not make a difference. Do you have any ideas here? I’ve attached the simple protocol I’m using to test in case I’ve set something up incorrectly. Thank you!

Attachment: test_encoder.xml (3.13 KB)

Hi Juliana,

when I try to do this in MWorks, no values are updated

Have you installed the StandardFirmata firmware on your Arduino board? If not, see this guide for instructions on how to do so.

Also, when you’re done, be sure to quit the Arduino app and unplug/replug the board, just to make sure it’s in a clean state. (You only need to do this once.)

and MWorks freezes

MWServer and MWClient appear to freeze, because the state “Read values” transitions to itself unconditionally. This causes the state to be executed over and over as quickly as possible, burning up CPU cycles and generating tons of MWorks events, the load of which makes the applications unresponsive.

You need to either add a wait to that state (it can be short, e.g. 100ms), or set another timer and use a timer-expired transition.

I also tried increasing the data_interval parameter to 20ms to see if slower sampling would help, but this did not make a difference.

FYI, data_interval applies only to analog inputs. Digital inputs are updated whenever their state changes.

Cheers,
Chris Stawarz

Hi Chris,

Thanks for the reply. Adding the “wait” fixes the freezing problem. However, the encoder pins are still not being updated… I installed the StandardFirmata firmware to the board, as well. Trying to understand if there’s a difference in how Arduino reads the DI vs. MWorks… any ideas on this front? Not sure why the two would be different… Thanks!

Hi Chris,

I did a little more systematic debugging, and here’s what I’ve found – hopefully you can shed some light on this:

  1. When I upload any of my independent Arduino sketches for reading the encoder values, the input values are correctly read, both by Arduino and by an oscilloscope.
  2. When I upload the StandardFirmata firmware to the board, the oscilloscope no longer reads the expected 5V value from the pins. *However, if i explicitly define the encoder-related channels and modes at the top and in the setup, respectively (see StandardFirmata_encoder.ino sketch attached), the oscilloscope correctly reads out the pin values.
  3. If I then try to use this modified firmata sketch with MWorks (including shutting down Arduino and un-plugging and re-plugging the Arduino, as suggested), I again lose the values (nothing read by either the oscilloscope or on the MWorks side).

I am confused because I know I can get MWorks to interface with Arduino in specific instances. For example, I have not yet had a problem when MWorks is controlling things like solenoid pulses or simple digital reads off of an input pin controlled by another hardware device. Do you have any ideas as to why the interface is failing in this particular case?

Hope this info helps… Thanks in advance.

I was unable to upload the .ino file in the previous post – trying here.

Attachment: StandardFirmata_encoder.ino.zip (7.9 KB)

Hi Juliana,

Thanks for sharing the sketch code. There are two issues here:

  1. MWorks doesn’t (currently) support configuring digital pins as INPUT_PULLUP. However, the Firmata protocol does support this, so it’d just be a matter of making it accessible via MWorks.
  2. Even though you configure the pins as INPUT_PULLUP in setup, they’re set back to plain INPUT by MWorks when it configures the device.

Adding support for INPUT_PULLUP pins to MWorks shouldn’t be a big job. I can probably get that in the nightly build relatively soon.

In the meantime, try moving your custom setup to setPinModeCallback. Maybe do something like this:

void setPinModeCallback(byte pin, int mode)
{
  if (mode == INPUT &&
      (pin == c_EncoderPinA || pin == c_EncoderPinB || pin == c_EncoderPinZ))
  {
    mode = PIN_MODE_PULLUP;
  }

  // Remainder of function is unmodified
  ...
}

Cheers,
Chris

Hi Chris,

Thanks for the info – how quickly do you think this feature could be added to MWorks? I am currently using MW 0.8 which has been working well with my setup, except for this issue. Would the feature addition be on the latest MW release? If so, I should install the latest stable release and make sure things still function properly on my end.

I tried adding the code block you sent, and if I remove my custom pin in setup() with the above added to setPinModeCallback(), the oscilloscope goes back to not getting the proper values. Do I need to explicitly set this in the setup()? Is it a problem if I do?

Please let me know if and when I can try out the MWorks change you mentioned in your last post! Hopefully that will solve the problem (along with some combination of adjusting the StandardFirmata). Thanks, again, for your help.

Best,

Julie

Hi Julie,

how quickly do you think this feature could be added to MWorks?

I’m actually working on some other Firmata changes right now, so I’ll try to add this at the same time. I’m guessing I’ll be able to have it done late this week or early next.

Would the feature addition be on the latest MW release?

It will go in to the nightly build, which is built from the latest code.

I tried adding the code block you sent, and if I remove my custom pin in setup() with the above added to setPinModeCallback(), the oscilloscope goes back to not getting the proper values. Do I need to explicitly set this in the setup()? Is it a problem if I do?

The change I suggested depends on you creating digital input channels in your experiment for each of the three pins. I see that the XML file you sent me doesn’t create a channel for the Z pin. Maybe you need to add that?

Also, with the change I suggested, the device will only work with MWorks (or some other Firmata client that configures the three pins). It won’t work standalone any more.

Of course, it’s also possible I just got the change wrong. If you still can’t make it work, let me know, and we’ll figure out why.

Cheers,
Chris

Hi Julie,

The MWorks nightly build now supports Firmata digital input pullup channels. This channel type enables the built-in pullup resistor for its associated pin.

I’ve attached an example experiment (in both MWEL and XML format) that configures the pins in the same way as your modified StandardFirmata firmware. To use it, be sure that you have the standard, unmodified StandardFirmata on your device.

When you have a chance, please download the nightly build and give this a try, and let me know if you have any problems.

Cheers,
Chris

Attachments:

Hi Chris,

Thanks so much. The .xml you sent works as well as my own original .xml for reading the values on pins A and B. You set the value reporting within the variable declaration, and it looks like this action is triggered on change (as with data logging). Is there a way for me to trigger some action (e.g., increment some variable) on the rising or falling edge of a pin instead?

Thanks, again!

Best,

Juliana

Hi again,

Just wanted to let you know that I found a work-around for this by explicitly checking that the previous value of the pin is 0 and current value is 1 (“rising” edge), and updating values that way. I’ve attached this below, but let me know if there is a nicer way to do this.

Thanks!

Best,

Juliana

Attachment: test_encoder.xml (4.16 KB)

Just wanted to let you know that I found a work-around for this by explicitly checking that the previous value of the pin is 0 and current value is 1 (“rising” edge), and updating values that way.

That’s probably how I’d do it, too.

Chris

Hi Chris,

Great! Thanks so much for your help. So far, the updates seem to be working (and no crashes yet going from MW 0.8 to this nightly build). Thanks!

Best,

Juliana