jgautier/firmata — pull request #48 by achingbrain (2013-11-08 08:39:50+00:00)
Title: adds 1-wire support via ConfigurableFirmata

I bought a [SparkFun DS18B20 based waterproof temperature sensor](http://proto-pic.co.uk/temperature-sensor-waterproof-ds18b20/), foolishly thinking it'd be as easy to use as the [TMP36](https://www.sparkfun.com/products/10988) sensor they include in their Inventors Kit.

Turns out it's a digital sensor that talks [1-Wire](http://en.wikipedia.org/wiki/1-Wire) - a bus protocol for connecting multiple sensors in series.

StandardFirmata does not support 1-Wire, but as luck would have it [ConfigurableFirmata](https://github.com/firmata/arduino/tree/configurable) does (see [the proposal](http://firmata.org/wiki/Proposals#OneWire_Proposal) and [the implementation](https://github.com/firmata/arduino/blob/configurable/utility/OneWireFirmata.cpp)).

This pull request adds support for 1-Wire, on the assumption that you've flashed your board with ConfigurableFirmata. If you haven't, it tries to detect this by printing out an error asking the user if they've done that if appropriate responses are not received from the attached device when searching for 1-Wire devices on the bus within a reasonable timeframe.

With the code in this pull request I can now use the DS18B20 like so:

```javascript
var board = new firmata.Board("/dev/my/device", function (error) {
if(error) {
console.error(error);
return;
}

// 1-wire devices are on pin 7
var pin = 7;

board.sendOneWireConfig(pin, true);
board.sendOneWireSearch(pin, function(error, devices) {
if(error) {
console.error(error);
return;
}

// only interested in the first device
var device = devices[0];

var readTemperature = function() {
// start transmission
board.sendOneWireReset(pin);

// a 1-wire select is done by ConfigurableFirmata
board.sendOneWireWrite(pin, device, 0x44);

// the delay gives the sensor time to do the calculation
board.sendOneWireDelay(pin, 1000);

// start transmission
board.sendOneWireReset(pin);

// tell the sensor we want the result and read it from the scratchpad
board.sendOneWireWriteAndRead(pin, device, 0xBE, 9, function(error, data) {
if(error) {
console.error(error);
return;
}

var raw = (data[1] << 8) | data[0];
var celsius = raw / 16.0;
var fahrenheit = celsius * 1.8 + 32.0;

console.info("celsius", celsius);
console.info("fahrenheit", fahrenheit);
});
};

// read the temperature now
readTemperature();

// and every five seconds
setInterval(readTemperature, 5000);
});
});
```

I've included tests for the new code introduced. Happy to discuss any aspect of the changes.

One problem I think is that 1-Wire is ConfigurableFirmata but not in StandardFirmata, but hopefully we can work something out.