Skip to content

Instantly share code, notes, and snippets.

@ElectricImpSampleCode
Last active September 12, 2023 10:21
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 ElectricImpSampleCode/c6981fcb9e30683ead8b to your computer and use it in GitHub Desktop.
Save ElectricImpSampleCode/c6981fcb9e30683ead8b to your computer and use it in GitHub Desktop.
1-Wire Examples
// FUNCTIONS
function onewireReset() {
// Configure UART for 1-Wire RESET timing
ow.configure(9600, 8, PARITY_NONE, 1, NO_CTSRTS);
ow.write(0xF0);
ow.flush();
local read = ow.read();
if (read == -1) {
// No UART data at all
server.log("No circuit connected to UART.");
return false;
} else if (read == 0xF0) {
// UART RX will read TX if there's no device connected
server.log("No 1-Wire devices are present.");
return false;
} else {
// Switch UART to 1-Wire data speed timing
ow.configure(115200, 8, PARITY_NONE, 1, NO_CTSRTS);
return true;
}
}
function onewireWriteByte(byte) {
for (local i = 0 ; i < 8 ; i++) {
// Run through the bits in the byte, extracting the
// LSB (bit 0) and sending it to the bus
byte = byte >> 1;
onewireBit(byte & 0x01);
}
}
function onewireReadByte() {
local byte = 0;
for (local i = 0 ; i < 8 ; i++) {
// Build up byte bit by bit, LSB first
byte = (byte >> 1) + 0x80 * onewireBit(1);
}
return byte;
}
function onewireBit(bit) {
bit = bit ? 0xFF : 0x00;
ow.write(bit);
ow.flush();
local returnVal = ow.read() == 0xFF ? 1 : 0;
return returnVal;
}
function onewireSearch(nextNode) {
// 'lastForkPoint' records where the device tree last branched
local lastForkPoint = 0;
// Reset the bus and exit if no device found
if (onewireReset()) {
// There are 1-Wire device(s) on the bus, so issue the 1-Wire SEARCH command (0xF0)
onewireWriteByte(0xF0);
// 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 = onewireBit(1);
// Read the next bit
if (onewireBit(1)) {
if (bit) {
// Both bits are 1 which indicates that there are no further devices
// on the bus, so put pointer back to the start and break out of the loop
lastForkPoint = 0;
break;
}
} else if (!bit) {
// First and second bits are both 0: we're at a node
if (nextNode > i || (nextNode != i && (id[byte] & 1))) {
// Take the '1' direction on this point
bit = 1;
lastForkPoint = i;
}
}
// Write the 'direction' bit. For example, if it's 1 then all further
// devices with a 0 at the current ID bit location will go offline
onewireBit(bit);
// Write the bit to the current ID record
id[byte] = (id[byte] >> 1) + 0x80 * bit;
}
}
// Return the last fork point so it can form the start of the next search
return lastForkPoint
}
function onewireDevices() {
id <- [0,0,0,0,0,0,0,0];
nextDevice <- 65;
while (nextDevice) {
nextDevice = onewireSearch(nextDevice);
// Store the device ID discovered by one_wire_search() in an array
// Nb. We need to clone the array, id, so that we correctly save
// each one rather than the address of a single array
peripherals.push(clone(id));
}
}
function getTemp() {
local tempLSB = 0;
local tempMSB = 0;
local tempCelsius = 0;
// Wake up in five seconds for the next reading
imp.wakeup(5.0, getTemp);
// Reset the 1-Wire bus
local result = onewireReset();
if (result) {
// Issue 1-Wire Skip ROM command (0xCC) to select all devices on the bus
onewireWriteByte(0xCC);
// Issue DS18B20 Convert command (0x44) to tell all DS18B20s to get the temperature
// Even if other devices don't ignore this, we will not read them
onewireWriteByte(0x44);
// Wait 750ms for the temperature conversion to finish
imp.sleep(0.75);
foreach (device, peripheralId in peripherals) {
// Run through the list of discovered peripheral devices, getting the temperature
// if a given device is of the correct family number: 0x28 for BS18B20
if (peripheralId[7] == 0x28) {
onewireReset();
// Issue 1-Wire MATCH ROM command (0x55) to select device by ID
onewireWriteByte(0x55);
// Write out the 64-bit ID from the array's eight bytes
for (local i = 7 ; i >= 0 ; i--) {
onewireWriteByte(peripheralId[i]);
}
// Issue the DS18B20's READ SCRATCHPAD command (0xBE) to get temperature
onewireWriteByte(0xBE);
// Read the temperature value from the sensor's RAM
tempLSB = onewireReadByte();
tempMSB = onewireReadByte();
// Signal that we don't need any more data by resetting the bus
onewireReset();
// Calculate the temperature from LSB and MSB, making sure we
// sign-extend the signed 16-bit temperature readinf ('raw')
// to a Squirrel 32-bit signed integer ('tempCelsius')
local raw = (tempMSB << 8) + tempLSB;
tempCelsius = ((raw << 16) >> 16) * 0.0625;
server.log(format("Device: %02d Family: %02x Serial: %02x%02x%02x%02x%02x%02x Temp: %3.2f", (device + 1), peripheralId[7], peripheralId[1], peripheralId[2], peripheralId[3], peripheralId[4], peripheralId[5], peripheralId[6], tempCelsius));
}
}
}
}
// RUNTIME START
// Set up the 1-Wire UART. This is for an imp001 -
// change the UART object in the line below for other imps
ow <- hardware.uart12;
peripherals <- [];
// Enumerate the devices on the bus
onewireDevices();
// Start sampling temperature data
getTemp();
// FUNCTIONS
function onewireReset() {
// Configure UART for 1-Wire RESET timing
ow.configure(9600, 8, PARITY_NONE, 1, NO_CTSRTS);
ow.write(0xF0);
ow.flush();
local read = ow.read();
if (read == -1) {
// No UART data at all
server.log("No circuit connected to UART.");
return false;
} else if (read == 0xF0) {
// UART RX will read TX if there's no device connected
server.log("No 1-Wire devices are present.");
return false;
} else {
// Switch UART to 1-Wire data speed timing
ow.configure(115200, 8, PARITY_NONE, 1, NO_CTSRTS);
return true;
}
}
function onewireWriteByte(byte) {
for (local i = 0 ; i < 8 ; ++i) {
// Run through the bits in the byte, extracting the
// LSB (bit 0) and sending it to the bus
byte = byte >> 1;
onewireBit(byte & 0x01);
}
}
function onewireReadByte() {
local byte = 0;
for (local i = 0 ; i < 8 ; ++i) {
// Build up byte bit by bit, LSB first
byte = (byte >> 1) + 0x80 * onewireBit(1);
}
return byte;
}
function onewireBit(bit) {
bit = bit ? 0xFF : 0x00;
ow.write(bit);
ow.flush();
local returnValue = ow.read() == 0xFF ? 1 : 0;
return returnValue;
}
function awakeAndGetTemp() {
// Wake up every 30 seconds and write to the server
local tempLSB = 0;
local tempMSB = 0;
local tempCelsius = 0;
// Run loop again in 30 seconds
imp.wakeup(30.0, awakeAndGetTemp);
if (onewireReset()) {
onewireWriteByte(0xCC); // 1-Wire Skip ROM command
onewireWriteByte(0x44);
// Wait for at least 750ms for data to be collated
imp.sleep(0.8);
// Get the data
onewireReset();
onewireWriteByte(0xCC); // 1-Wire Skip ROM command
onewireWriteByte(0xBE); // Tell sensor to take a reading
tempLSB = onewireReadByte();
tempMSB = onewireReadByte();
// Reset bus to stop sensor sending unwanted data
onewireReset();
// Calculate the temperature from LSB and MSB, making sure we
// sign-extend the signed 16-bit temperature readinf ('raw')
// to a Squirrel 32-bit signed integer ('tempCelsius')
local raw = (tempMSB << 8) + tempLSB;
tempCelsius = ((raw << 16) >> 16) * 0.0625;
server.log(format("Temperature: %3.2f degrees C", tempCelsius));
}
}
// RUNTIME START
// Set up the 1-Wire UART. This is for an imp001 -
// change the UART object in the line below for other imps
ow <- hardware.uart12;
awakeAndGetTemp();
@karthickrajapetal
Copy link

karthickrajapetal commented Jul 29, 2023 via email

@karthickrajapetal
Copy link

karthickrajapetal commented Aug 4, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment