Skip to content

Instantly share code, notes, and snippets.

@smittytone
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smittytone/97e57909105c9e0d31aa to your computer and use it in GitHub Desktop.
Save smittytone/97e57909105c9e0d31aa to your computer and use it in GitHub Desktop.
Electric Imp Squirrel class for handling 1-Wire devices over a UART bus
// Squirrel Class for accessing 1-Wire devices, eg.
// Maxim Integrated DS18B20 temperature sensor
// [http://www.maximintegrated.com/datasheet/index.mvp/id/2812]
// via two-wire UART. The imp does not support 1-Wire natively
// Bus: UART
// Code by Tony Smith (@smittytone) June 2014
// Version 1.0
class ONEWIRE
{
ow = null
current_id = null
slaves = null
next_device = 0
constructor (imp_uart_bus)
{
ow = imp_uart_bus
slaves = []
current_id = []
}
function init()
{
// Convenience initialization routine that simply calls
// the class' own function to find all bus slaves
getslavelist()
}
function reset()
{
// Configure UART for 1-Wire RESET timing
ow.configure(9600, 8, PARITY_NONE, 1, NO_CTSRTS);
ow.write(0xF0);
ow.flush();
if (ow.read() == 0xF0)
{
// UART TX will read TX if there's no device connected
return false;
}
else
{
// Switch UART to 1-Wire data speed timing
ow.configure(115200, 8, PARITY_NONE, 1, NO_CTSRTS);
return true;
}
}
function writebyte(byte)
{
for (local i = 0; i < 8; i++, byte = byte >> 1)
{
// Run through the bits in the byte, extracting the
// LSB (bit 0) and sending it to the bus
readwritebit(byte & 0x01);
}
}
function readbyte()
{
local byte = 0;
for (local b=0; b<8; b++)
{
// Build up byte bit by bit, LSB first
byte = (byte >> 1) + 0x80 * readwritebit(1);
}
return byte;
}
function readwritebit(bit)
{
bit = bit ? 0xFF : 0x00;
ow.write(bit);
ow.flush();
local return_value = ow.read() == 0xFF ? 1 : 0;
return return_value;
}
function skiprom()
{
// Ignore device ID(s) (issues standard 1-Wire command)
writebyte(0xCC)
}
function readom()
{
// Read a device’s ID (issues standard 1-Wire command)
writebyte(0x33)
}
function searchrom()
{
// Begin enumerating IDs (issues standard 1-Wire command)
writebyte(0xF0)
}
function matchrom()
{
// Select a device with a specific ID
// Next 64 bits to be written will be the known ID
writebyte(0x55)
}
function search(next_node)
{
local last_fork_point = 0 // last found fork point
// Reset the bus and exit if no device found
if (reset())
{
// If there are 1-Wire device(s) on the bus - for which one_wire_reset()
// checks - this function readies them by issuing the 1-Wire SEARCH command (0xF0)
searchrom()
// Work along the 64-bit ROM code, bit by bit, from LSB to MSB
for (local i = 64 ; i > 0 ; i--)
{
local byte = (i-1)/8
// Read bit from bus
local bit = readwritebit(1)
// Read the next bit, the first's complement
if (readwritebit(1))
{
if (bit)
{
// If first bit is 1 too, this indicates no further devices
// so put pointer back to the start and break out of the loop
last_fork_point = 0
break;
}
}
else if (!bit)
{
// First and second bits are both 0
if (next_node > i || ((next_node != i) && (current_id[byte] & 1)))
{
// Take the '1' direction on this point
bit = 1
last_fork_point = i
}
}
// Write the 'direction' bit. If it's, say, 1, then all further
// devices with a 0 at the current ID bit location will go offline
readwritebit(bit)
// Shift out the previous path bits, add on the msb side the new choosen path bit
current_id[byte] = (current_id[byte] >> 1) + 0x80 * bit
}
}
// return the last fork point for next search
return last_fork_point
}
function getslavelist()
{
slaves = []
current_id = [0,0,0,0,0,0,0,0]
next_device = 65;
while(next_device)
{
next_device = search(next_device);
slaves.push(clone(current_id));
}
}
function getdevicecount()
{
return slaves.len()
}
function getdevice(device_index)
{
// Returns the device ID array out of the slaves array
return slaves[device_index]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment