tfirmata

tfirmata is a Tcl host implementation of Firmata 2.3. Firmata is a communications protocol that can be used for controlling hardware interfaced to an Arduino through the Arduino's serial port.

tfirmata can most easily be used by making use of the StandardFirmata project that's included with the Arduino IDE software. StandardFirmata implements Firmata, and by programming an Arduino with StandardFirmata, hardware interfaced to the Arduino can then be controlled directly from a PC using Tcl and tfirmata. Below is an example showing a script for flashing an LED on an Arduino Uno.

source tfirmata.tcl

set bd [tfirmata::open /dev/ttyACM0]
$bd mode 13 out

while {1} {
    $bd dset 13 1
    tfirmata::sleep 250
    $bd dset 13 0
    tfirmata::sleep 250
}

For more examples, see the examples page.

tfirmata is a complete implementation of Firmata, including board capability querying. As a result tfirmata should work with all boards supported by Firmata.

Commands and Subcommands

tfirmata provides the following two commands:

The open command opens a connection to an Arduino. It takes an argument specifying a serial port an Arduino is connected on. open returns a reference command that is used for calling subcommands listed below.

The sleep command delays a script for a number of milliseconds. sleep is the recommended way of delaying a script, because it passes control to the Tcl event loop, allowing tfirmata to continue to service open connections.

Reference command subcommands are as follows:

The mode subcommand is used to configure the mode of operation of Arduino pins. The mode can be any of in, out, analog, pwm, or servo (to put TWI capable pins in TWI mode, use twiconfig). The mode subcommand may be used to set the mode of a single pin, or to set the mode for several pins.

$bd mode 13 out
$bd mode 4 5 6 7 in 9 pwm 10 11 12 13 out

The dget subcommand gets the digital value of input pins, retrieving values from a local cache. Before the dget subcommand is used, the dstream subcommand should be called to set up an Arduino, so that when a digital input changes, its new value is sent for the local tfirmata cache. dget may be used to get the value of one pin or multiple pins. When getting values for multiple pins, values are returned as a list.

puts [$bd dget 13]
puts [$bd dget 4 5 6 7]

The dset subcommand sets the value of digital output pins. dset may be used to set the value of a single pin or to set the value of multiple pins.

$bd dset 13 1
$bd dset 10 0 11 0 12 1

The aget subcommand gets the analog value of analog input channels, retrieving values from a local cache. Before the aget subcommand is used, the astream subcommand should be called to set up an Arduino so that it reports analog values at regular intervals for storing in the local tfirmata cache. The interval between updates can be set with the period subcommand. aget may be used to get the analog value of one pin or multiple pins. When requesting values for multiple pins, values are returned as a list.

puts [$bd aget 0]
puts [$bd aget 0 1 2 3]

The aset subcommand sets the value of pwm or servo configured output pins. aset may be used to set the value of a single pin, or to set the value of multiple pins.

$bd aset 11 1
$bd aset 9 128 10 0 11 255

The dstream subcommand configures an Arduino to send digital port values when a port value changes. Firmata considers 8 pins to make up a port so, for example, enabling streaming on port 0 will result in a port message being sent if any of pins 0 to 7 change value. dstream can be used to turn streaming on or off, for a single port or for multiple ports.

$bd dstream 0 on
$bd dstream 0 1 on 2 off

The astream subcommand configures an Arduino to send analog channel values at regular intervals set by the period subcommand. astream can be used to turn streaming on or off, for a single analog channel or for multiple analog channels.

$bd astream 0 on
$bd astream 1 2 3 on 4 5 off

The dcommand subcommand is used to set code that's run when tfirmata receives a message after a port, that has been configured for streaming with dstream, has changed value. The port number and port value that are part of a port message can be substituted into a code block by using '%P' and '%V'.

$bd dcommand {puts "digital port update"}
$bd dcommand {puts "digital port update, port: %P, value: %V"}

The acommand subcommand is used to set code that's run when tfirmata receives a message for an analog channel that's been configured for streaming with astream. The analog channel and analog value that are part of an analog channel message can be substituted into a code block by using '%C' and '%V'.

$bd acommand {puts "analog channel update"}
$bd acommand {puts "analog channel update, channel: %C, value: %V"}

The servolimits subcommand sets the lower and upper limits for servo outputs in microseconds. Limits are provided as a two element list. Limits can be set for a single pin or for multiple pins.

$bd servolimits 12 {850 2250}
$bd servolimits 10 11 {900 2100} 12 {850 2250}

The amapping subcommand returns pin numbers that analog channel numbers map to. Mappings for a single analog channel or multiple analog channels can be retreived.

puts [$bd amapping 0]
puts [$bd amapping 0 1 2]

The twiconfig subcommand configures an Arduino's TWI capable pins to TWI mode. A delay in microseconds may be specified for reads. The delay is inserted between TWI messages that request data from a TWI device and TWI messages that read out the data. Most TWI devices do not require a delay, and if not specified, the delay will default to 0us.

$bd twiconfig 
$bd twiconfig 5000

The twiget subcommand can be used to retreive data from a TWI device, and also to stop repeated TWI reads. For reading from a TWI device the address of the TWI device, any command bytes to send to the device before reading, and the number of bytes to read are supplied as arguments. The subcommand will block if a -command argument isn't provided, and read bytes will be returned. If -command is provided, the subcommand will not block, and once data has been retrieved the code specified by -command is run. Data bytes read from a TWI device may be substituted into a code block with '%D'. If -repeat is specified, the read message to the TWI device is repeated at regular intervals set by the period subcommand. To stop repeated reads, -stop is specified along with device address.

puts [$bd twiget 0x50 0 1] 
$bd twiget 0x50 1 -command {puts "Data: %D"}
$bd twiget -repeat 0x50 1 -command {myTwiCallback %D}
$bd twiget -stop 0x50

The twiset subcommand is used to initiate a TWI write message. The subcommand takes an address for a target TWI device, followed by the bytes to send to it.

$bd twiset 0x50 0 0 0x55

The period subcommand sets the number of milliseconds between messages sent from an Arduino for analog channels and for repeated TWI reads.

$bd period 500

The state subcommand returns the current configuration state of Arduino pins. The state is returned as a dictionary, where dictionary keys are the requested pin numbers, and values are a list of state values. Configuration state can be retrieved for a single pin, multiple pins, or for all pins.

puts [$bd state 13]
puts [$bd state 10 11 12 13]
puts [$bd state all]

The firmware subcommand returns the name and version of firmware programmed into an Arduino.

puts [$bd firmware]

The errors subcommand returns a count of the errors detected by tfirmata as it parses received messages.

puts [$bd errors]

The close subcommand closes a connection to an Arduino.

$bd close

TuxFamily