Go Down

Topic: Extending StandardFirmata instruction to do 2 things (Read 135 times) previous topic - next topic


Jan 13, 2021, 06:27 am Last Edit: Jan 13, 2021, 02:03 pm by linzmeister
Hi All,

I am new to Arduino programming (c++), but very familiar with other languages.  I have a basic grasp on the .h and .cpp files...

I have video switching/streaming software (VMix), installed on a computer, that I do not have access to the source code.  I have interfaced a UNO to VMix using StandardFirmata as directed by the VMix help file.  VMix is currently controlling some TTL output pins on the Uno (Tally lights for Cameras) and it has been working correctly for several years.

I want to add some functionality to the Arduino, so that as well as controlling the digital pins, it sends 4~6 bytes of RS232 command via an altSoftSerial port on the Uno to an RGB presentation switcher.

Computer (running Vmix - video switching software)                              Sends StandardFirmata commands
  |  USB
  >   Uno with StandardFirmata (tally light interface)                              Receives the StandardFirmata commands
        |             |                   |                      |                   |
        |             |  TTL 1        |   TTL 2           |  TTL 3        | TTL 4
        |             |                   |                       |                   |
        |       >   4x Sony Camera Control Units  (TTL Receivers)                  Receives the TTL Pin signal from Uno (Currently working)
        |            |                 |                   |                   | 
        |            |  RGB1      |  RGB2       |  RGB3       |  RGB4
        |            |                 |                   |                   | 
         >       RGB Video signal switcher with RS232 remote control         Receives 4-6 bytes of RS232 data from Uno (Want to add)
                     |                                                                                                       Will send RS232 responses which I will simply purge and ignore
                     |  RGB Output 1
                     >   Tecktronix 1780R Waveform/Vector Scope Monitor

Basically I need to hack around somewhere to add the additional RS232 output.
Obviously the incoming data can only be read from the Firmata Serial port buffer once, so I need to insert code to send my RS232 bytes either:
A)      between the data being read from the serial buffer and being processed or
B)      at the end of the default digital pin processing

Where should I insert my code?
The sketch doesn't have low level access, but I can't follow the function calls deep into Firmata.cpp/FirmataParser.cpp etc .files.


I have not looked in detail but the VMix is using standard firmata sketch according to this setup guide.

You need to confirm the firmata message format being sent from VMix. My guess is DIGITAL_MESSAGE but it could be SET_DIGITAL_PIN_VALUE or one of the other message types.
Once you know the message format being sent then just add your code to the relevant callback in the sketch, no need to dive into the core .h & .cpp files of firmata.

If I was doing this project I would probably switch from the UNO to using either the Leonardo or Mega board as both would have a spare Serial port available for connecting to your switcher and remove the need of using software serial.
The standardfirmata.ino's digitalWriteCallback function (below) seems to mask for Serial ports so this removes the need/worry of sending firmata messages to configure software serial pins.

Code: [Select]
void digitalWriteCallback(byte port, int value)
  byte pin, lastPin, pinValue, mask = 1, pinWriteMask = 0;

  if (port < TOTAL_PORTS) {
    // create a mask of the pins on this port that are writable.
    lastPin = port * 8 + 8;
    if (lastPin > TOTAL_PINS) lastPin = TOTAL_PINS;
    for (pin = port * 8; pin < lastPin; pin++) {
      // do not disturb non-digital pins (eg, Rx & Tx)
      if (IS_PIN_DIGITAL(pin)) {
        // do not touch pins in PWM, ANALOG, SERVO or other modes
        if (Firmata.getPinMode(pin) == OUTPUT || Firmata.getPinMode(pin) == INPUT) {
          pinValue = ((byte)value & mask) ? 1 : 0;
          if (Firmata.getPinMode(pin) == OUTPUT) {
            pinWriteMask |= mask;
          } else if (Firmata.getPinMode(pin) == INPUT && pinValue == 1 && Firmata.getPinState(pin) != 1) {
            // only handle INPUT here for backwards compatibility
#if ARDUINO > 100
            pinMode(pin, INPUT_PULLUP);
            // only write to the INPUT pin to enable pullups if Arduino v1.0.0 or earlier
            pinWriteMask |= mask;
          Firmata.setPinState(pin, pinValue);
      mask = mask << 1;
    writePort(port, (byte)value, pinWriteMask);
Don't PM me for help as I will ignore it.


Thank You.  You've provided enough information to direct my thinking.

Oh.. Are the Callbacks in the sketch overriding the Firmata.cpp functions?  I couldn't see where they were being called from.
  different language object model structures...

Yes that link is the VMix/Arduino config I have implemented successfully.

Ok, I'll try to sniff out what VMix is sending by looping back to a comm port.... assuming VMix doesn't timeout waiting for a response from a nonexistent firmata..

I've found the firmata protocol docs so I can translate the hex into function calls.

As I said, the system has been operating fine for a couple of years on the Uno, so I'll just add a MAX232 and associated caps to the existing prototyping shield rather than buy a bigger controller.  Integrating the altSoftSerial on some unused pins seems easy enough and the docs say it doesn't interfere with the hardware port timing.

I'll just configure the soft serial in the setup() of the sketch and leave it hard coded. No additional firmata messages are possible anyway, as I don't have the source code for VMix.


The callbacks are to functions in your sketch from the firmata library so you can hook in your own code.

To find out what callback is being used by VMix just have a simple print statement to your software serial port in each callback function. As an example put sserial.print("DIGITAL_MESSAGE"); in the digitalWriteCallback (assuming your software serial port is called sserial).

I suggested to use a board with hardware serial instead of software serial as looking at the example callback I posted, it masks for serial and other non digital pins like PWM, ANALOG and SERVO that have been defined as such using firmata controller (VMix).
*After having a deeper look it might be the setPinValueCallback that VMix calls and this will make life easier for using software serial if this is the case as you don't need to worry about port masking.
Don't PM me for help as I will ignore it.


Jan 14, 2021, 01:56 pm Last Edit: Jan 14, 2021, 11:22 pm by linzmeister

I've had a more thorough read through the standardfirmata code today and loaded it into eclipse.

I like the idea of basically inserting debug print statements in the callbacks to identify what VMix is sending.. That should simply the task heaps.  After identifying which callback is being used I can even print the parameter values VMix sent to assist final programming..

Go Up