Skip to content

Latest commit

 

History

History
462 lines (334 loc) · 24.1 KB

hardware-api.md

File metadata and controls

462 lines (334 loc) · 24.1 KB

Tessel API Documentation

Documentation for Tessel's hardware APIs. These are available for code running on Tessel, and is imported by require('tessel').

##Contents

##Tessel

Tessel is the root object for each of the different ports on the device.

var tessel = require('tessel'); // import tessel
var gpio = tessel.port['GPIO']; // select the GPIO port
gpio.digital[1].write(1);  // turn digital pin #1 high

# map<Port>  tessel.port = {}
A list of ports available on Tessel. Keys for this are "A", "B", "C", "D", or "GPIO".

# array<Pin>  tessel.led = []
An array of 4 LEDs available on the Tessel board. These are Pin objects. Their board order is different than their array index order; they're in rainbow order on the board. See below:

Index Position (from micro-USB) Color Name
0 3rd Green LED1
1 4th Blue LED2
2 1st Red Error
3 2nd Amber Conn
// Toggle an LED every 200ms
(function blink (value) {
  tessel.led[1].write(value);
  setTimeout(blink, 200, !value);
})(true)

##Pins

General purpose input-output (GPIO) provides access for digital and analog signal lines. Available pins are exposed through the .pin, .digital, .analog, and .pwm arrays.

By default, all of the pins are pulled high if not specifically set.

You may find it useful to cross-reference this section with the hardware documentation for Pins and Ports.

###GPIO bank Tessel's GPIO bank is designed to be breadboardable, so you can interact easily with sensors and actuators beyond our pre-built modules.

This example logs the value of each digital and analog pin from the GPIO bank:

var tessel = require('tessel'); // import tessel
var gpio = tessel.port['GPIO']; // select the GPIO port
gpio.digital.forEach(function (pin, i) {
  console.log('Value of digital pin', i, '=', pin.read());
});
gpio.analog.forEach(function (pin, i) {
  console.log('Value of analog pin', i, '=', pin.read() * pin.resolution, '/', pin.resolution);
});

Digital pins are either high (3.3V) or low (GND/0V).

Tessel has six digital pins on the GPIO bank, and three more on each of the four module ports.

This example shows the reading and writing of a digital pin:

var tessel = require('tessel'); // import tessel
var gpio = tessel.port['GPIO']; // select the GPIO port
var myPin = gpio.digital[0]; // on GPIO, can be gpio.digital[0] through 5 or gpio.pin['G3'] through ‘G6’
// Turn on the pin
myPin.output(1); // setting ‘true’ has the same effect
// Read the pin
console.log('Reading pin:', myPin.rawRead());
// Turn off the pin
myPin.output(0); // setting ‘false’ has the same effect. We could also call myPin.toggle() here.
// Read the pin
console.log('Reading pin:', myPin.rawRead());

Analog pins can be any value between 0 and 1 (GND/0V and 3.3V).

Tessel has six analog pins on the GPIO bank. All six can be used as inputs, but should not be used as outputs.

Here is an example of reading analog values.

var tessel = require('tessel'); // import tessel
var gpio = tessel.port['GPIO']; // select the GPIO port
var myPin = gpio.analog[0]; // can read on any of gpio.analog[0-5] or gpio.pin['A1'] through A6
// Read the pin
console.log('Reading pin:', myPin.read());

PWM pins are pulse-width modulated pins (wiki link). Essentially, PWM is a digital signal that spends between 0% and 100% of its time on (this is its "duty cycle"). You can set the PWM pins to any value between 0 and 1 to approximate an analog signal. PWM is often used to control servo speeds or LED brightness.

Tessel has three PWM pins: G4, G5, and G6 on the GPIO bank.

If you try to read a PWM pin, you will always get back 0 or 1, depending on which part of the duty cycle your .read() call happened to hit.

Here is an example of setting a PWM pin:

var tessel = require('tessel'); // import tessel
var gpio = tessel.port['GPIO']; // select the GPIO port
var myPin = gpio.pwm[0]; // can be gpio.pwm[0] through 3 or gpio.pin['G4'] through ‘G6’
// Tell the GPIO port that the frequency of its pwm pins is 980 Hz
gpio.pwmFrequency(980);
// Set duty cycle
myPin.pwmDutyCycle(0.6); // set the pin to be on 60% of the time

Tessel also has a pin that will allow you to read in the length of an incoming pulse.

Here is an example of reading a pulse in from an external device

var tessel = require('tessel'); // import tessel
var gpio = tessel.port['GPIO']; // select the GPIO port
var pin_input = gpio.pin['G3']; // readPulse only works on gpio.pin['G3']
// read a low pulse in (--_--) and timeout if there's no pulse within 3 seconds
pin_input.readPulse('low', 3000, function (err,pulse_len) {
  // if there's an err object it means the SCT timed out or was already in use
  if (err) {
    console.log(err.message);
    return;
  }
  // Log the pulse length
  console.log('Pulse read length:',pulse_len,'ms');
});

Note that readPulse is similar to the arduino pulseIn function.

Other pins: For more details on addressing the other pins on the GPIO bank, see the sections on SPI, I2C, and UART.

###Module port pins

You can address each of the pins in the module ports.

Ports A, B, C, and D each have 3 digital pins which can be addressed in two ways:

Digital pins addressed as items in an array:

tessel.port['A'].digital[0];
tessel.port['A'].digital[1];
tessel.port['A'].digital[2];

Digital pins addressed by the silkscreen printed on Tessel:

tessel.port['A'].pin['G1']; // this is the same as digital[0]
tessel.port['A'].pin['G2']; // this is the same as digital[1]
tessel.port['A'].pin['G3']; // this is the same as digital[2]

For more details on addressing the other pins on the module ports, see the sections on SPI, I2C, and UART.

###Referring to Pins

The table below indexes the various ways of referring to pins.

Pin # is the number returned when you console.log the pin. Label is the silkscreened label. Type and index can be used together, e.g. pin #16 can be referred to as tessel.port['A'].pin['G1'] or tessel.port['A'].digital[0].

Pin # Port Label Type Index
16 A G1 Digital 0
17 A G2 Digital 1
18 A G3 Digital 2
19 B G1 Digital 0
20 B G2 Digital 1
21 B G3 Digital 2
22 C G1 Digital 0
23 C G2 Digital 1
24 C G3 Digital 2
25 D G1 Digital 0
26 D G2 Digital 1
27 D G3 Digital 2
28 GPIO A1 Analog 0
29 GPIO A2 Analog 1
30 GPIO A3 Analog 2
31 GPIO A4 Analog 3
32 GPIO A5 Analog 4
33 GPIO A6 Analog 5
34 GPIO G1 Digital 0
35 GPIO G2 Digital 1
36 GPIO G3 Digital 2
37 GPIO G4 Digital 3
37 GPIO G4 PWM 0
38 GPIO G5 Digital 4
38 GPIO G5 PWM 1
39 GPIO G6 Digital 5
39 GPIO G6 PWM 2

###Pin API

# string  port.id
The unique ID of this port. On Tessel, this would be one of "A", "B", "C", "D", or "GPIO".

# array<number>  port.digital = []
An array of which pins are digital inputs/outputs. Has 3 pins for ports A, B, C, and D and 6 pins for the GPIO port.

# array<number>  port.analog = []
An array of which pins are analog inputs. Is only available on the GPIO port.

# array<number>  port.pwm = []
An array of which pins are PWM outputs (may overlap analog array).

# port.pwmFrequency ( frequency )
Sets the frequency of PWM for a given port. Only the GPIO bank supports PWM pins on Tessel.

# array<number>  port.pin = []
An array of all pins on the port. You can differentiate them by their .type and .isPWM attributes.

# new  port.Pin ( pin )
Create and return pin object.

# string  pin.type
"digital" or "analog".

# number  pin.resolution
Digital pins: 1. Analog pins: ADC resolution of output pins ( e.g. 1023 for Tessel ).

# pin.input()
Set pin to be an input.

# pin.output ( value )
Set pin to be an output with value value. Note that the Analog pins cannot be outputs.

# pin.rawDirection( isOutput )
Set pin as input or output.

# pin.write ( value )
Behaves the same as pin.output. Sets pin as an output with value. Digital pins: output is set HIGH if value is truthy, otherwise LOW.

# pin.pwmDutyCycle ( dutyCycleFloat )
Creates a PWM signal with a duty cycle of dutyCycleFloat, the fraction of the PWM period in which the signal is high. Range is between [0-1] inclusive. Only works with pins with true property of isPWM.

# pin.rawWrite ( value )
Sets the pin to value. Does not change the direction of the pin.

# pin.read ()
Sets the pin as an input and reads a digital or analog value. For digital pins, 1 is returned if the value is HIGH, otherwise 0 if LOW. For analog pins the range is between [1-0] inclusive.

# pin.readPulse ( type, timeout, callback(err, pulsetime) )
Measures the length of an input pulse. The type of the pulse can either be 'high' or 'low'. The callback function is passed an err if no pulse was read within the timeout (in milliseconds) or if the SCT was in use by another process. If there was an error then pulsetime will be set to 0, otherwise it will be set to the measured pulse length. Note that reading a pulse is only possible on GPIO pin 'G3'.

# pin.rawRead ()
Reads from the pin *without first setting the direction as an input. Only available on digital pins.

# pin.pull ( mode )
Sets the pin as a pullup, pulldown, or neutral pin. Mode is one of pullup, pulldown or none. Passing in no argument is equivalent to none.

# pin.mode ()
Returns the mode of the pin.

External GPIO Interrupts can be used much like regular Node EventEmitters. There are seven external interrupts you can work with. You can read more in depth discussion about gpio interrupts in our External GPIO Walkthrough.

# pin.on ( type, callback(time, type) )
Sets a listener for a signal edge on pin. time is the milliseconds since boot up and type can be one of rise, fall, change. The high and low level triggers cannot be used with on because they would fire repeatedly and wreak havoc on the runtime.

# pin.once ( type, callback(time, type) )
Sets a listener for a a single event of the trigger type on the pin. time is the milliseconds since boot up and type can be one of rise, fall, change, high, or fall.

# pin.removeListener ( type, listener )
Removes the listener callback for a given type of trigger (eg. 'rise' or 'high') on a pin.

# pin.removeAllListeners ( type )
Removes all of the listeners for a given trigger type on a pin.

##Buttons

Tessel has two buttons. The reset button (nearer to the edge of the board) will stop running any program that is currently executing and restart the microcontroller (erasing any memory in RAM).

The config button will eventually be used for other purposes but is currently a simple way to get user feedback into a script:

var tessel = require('tessel');

tessel.button.on('press', function(time) {
  console.log('the button was pressed!', time);
});

tessel.button.on('release', function(time) {
  console.log('button was released', time);
});

Please note that the button press and release events will use one of the seven External GPIO Interrupts (for one or both events).

The buttons can also be used to put the board into DFU Mode which can be understood as the stage just prior to reprogramming the board. This is useful if the board is no longer able to communicate like typical with a host computer. To activate DFU mode, hold down the config button while pressing and releasing the reset button so that the config button is pressed down when the board comes out of a reset. Then release the config button.

##SPI

A SPI channel. For details on connecting the hardware to Tessel see the Pins and Ports section of the Hardware documentation.

var port = tessel.port['A'];
var spi = new port.SPI({
  clockSpeed: 4*1000*1000, // 4MHz
  cpol: 1, // polarity
  cpha: 0, // clock phase
});

spi.transfer(new Buffer([0xde, 0xad, 0xbe, 0xef]), function (err, rx) {
  console.log('buffer returned by SPI slave:', rx);
});

spi.transferBatch(new Buffer([0xc0, 0xd0, 0xc1, 0xd1]), {chunkSize:2}, function (err, rx) {
// Equivalent to
//    spi.transfer(new Buffer[0xc0, 0xd0]);
//    spi.transfer(new Buffer[0xc1, 0xd1]);
// Faster than doing separate transfers because only 1 JS call is made
});

# new  port.SPI ( [options] )
Creates a SPI object. Options is an object specifying any of the following:

  • channel (optional) — An optional numeric index for selecting a SPI channel. Defaults to the first (or only) SPI channel.
  • clockSpeed (default 100000) — SPI clock speed in Hz.
  • cpol (default 0) — Clock polarity. Options are 0 or 1, or 'low' and 'high'.
  • cpha (default 0) — Clock phase. Options are 0 or 1, or 'first' and 'second'.
  • dataMode (default 0) — An alternative to defining cpol and cpha explicitly, you can use mode numbers.
  • bitOrder (default "msb") — Bit order, most significant bit first or least. Options are 'msb' or 'lsb'.
  • frameMode (default "normal") — SPI frame format. Only one format is supported at the moment, "normal".
  • chipSelect (default null) — Pin to use as a default chip select pin. If a pin is specified, this pin is toggled in master mode whenever data is to be sent/received on the bus.
  • chipSelectActive (default "low") — If a chipSelect pin is specified, this defines the polarity of the CS line when active.
  • role (default master) — Determines the role the SPI channel plays, either "master" or "slave". (Currently not supported.)

# spi.transfer ( txbuf, callback(err, rxbuf) )
Transfers a Buffer txbuf to the slave and receives a response in rxbuf.

# spi.transferBatch ( txbuf, [options], callback(err, rxbuf) )
Transfers a series of commands stored in a Buffer txbuf by splitting txbuf into chunks of a specified size. Sends each command in txbuf to the slave and receives a response in rxbuf. Options is an object specifying any of the following:

  • chunkSize (optional) — An optional value specifying the interval size. Defaults to txbuf.length.
  • repeat (optional) — An optional value specifying how many times the txbuf will be transmitted. Used for transmitting the same buffer multiple times. Defaults to 1.

# spi.receive ( len, callback(err, rxbuf) )
Reads len bytes from a slave. Returns a buffer.

# spi.send ( txbuf, callback(err) )
Sends a Buffer txbuf to the slave.

# spi.sendBatch ( txbuf, [options], callback(err) )
Sends a series of commands stored in a Buffer txbuf by splitting txbuf into chunks of a specified size. Sends each command in txbuf to the slave. Options is an object specifying any of the following:

  • chunkSize (optional) — An optional value specifying the interval size. Defaults to txbuf.length.
  • repeat (optional) — An optional value specifying how many times the txbuf will be transmitted. Used for transmitting the same buffer multiple times. Defaults to 1.

# spi.setClockSpeed ( clockspeed )
Sets the clockspeed.

# spi.setDataMode ( mode )
Sets the data mode.

# spi.setFrameMode ( mode )
Sets the frame mode.

# spi.setRole ( role )
Sets the role.

# spi.setChipSelectMode ( mode )
Sets the chip select settings.

# spi.lock ( callback )
Locks SPI so that only one SPI port is communicating at a time. To read more about SPI Bus Locking, check out our discussion about the Bus Locking and Raw Transfers API.

##I2C

An I2C channel. For details on connecting the hardware to Tessel see the Pins and Ports section of the Hardware documentation.

var port = tessel.port['A'];
var slaveAddress = 0xDE;
var i2c = new port.I2C(slaveAddress)
i2c.transfer(new Buffer([0xde, 0xad, 0xbe, 0xef]), function (err, rx) {
  console.log('buffer returned by I2C slave ('+slaveAddress.toString(16)+'):', rx);
})

# new  port.I2C ( address, [idx] )
Creates an I2C channel for a device of a specific address. Multiple I2C channels can be used in parallel.

# i2c.transfer ( txbuf, rxbuf_len, callback(err, rxbuf) )
Transfers a Buffer txbuf to the client and receives a response of length rxbuf_len.

# i2c.receive ( rxbuf_len, callback(err, rxbuf) )
Reads rxbuf_len bytes from a client.

# i2c.send ( txbuf, callback(err) )
Sends a Buffer txbuf to the client.

##UART

A UART channel. For details on connecting the hardware to Tessel see the Pins and Ports section of the Hardware documentation.

var port = tessel.port['A'];
var uart = new port.UART({
  baudrate: 115200
});

uart.write('ahoy hoy\n')
uart.on('data', function (data) {
  console.log('received:', data);
})

// UART objects are streams!
// pipe all incoming data to stdout:
uart.pipe(process.stdout);

# new  port.UART ( [idx[, options]] )
implements DuplexStream
Creates a UART channel. Defaults: {"baudrate": 9600, "dataBits": 8, "parity": "none", "stopBits": 1}

# array<number>  uart.baudRates = []
An array of valid baud rates supported by the system.

# uart.setBaudRate ( rate )
Sets the baud rate to a valid rate in baudRates.

# uart.setDataBits ( bits )
Sets the number of data bits to the number 5, 6, 7, or 8.

# uart.setStopBits ( bits )
Sets the number of data bits to the number 1 or 2.

# uart.setParity ( parity )
Sets the parity to the value "none", "odd", or "even".

# uart.write ( buf )
Writes a buffer to the UART connection.

# uart → emits "data"
Data that arrives over the UART channel is sent as a Node.js stream.

##System

# process.sendfile ( filename, buffer )
A buffer can be sent over USB to a file named filename on a host computer's file system. You must start the script with -u and the argument of which directory to save the folder. For example, tessel run test.js -u ./recordings will save the file in the recordings directory.

# tessel.deviceId ()
Get the Unique ID of your Tessel.