Skip to content

Instantly share code, notes, and snippets.

@Links2004
Created October 6, 2018 09:55
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 Links2004/743ee62f2fcb682426f0276b8526d9e6 to your computer and use it in GitHub Desktop.
Save Links2004/743ee62f2fcb682426f0276b8526d9e6 to your computer and use it in GitHub Desktop.
Arduino async multi onewire 1wire bus
/*
*
* Created on: Jul 21, 2018
* Author: links
*/
#include <OneWire.h>
#include "dev_ids.h"
#ifdef ARDUINO_AVR_MEGA2560
#define BUSCOUNT (32)
#else
#define BUSCOUNT (11)
#endif
#define SHOW_RAW
//#define SHOW_SCAN
#ifdef ARDUINO_AVR_MEGA2560
#if BUSCOUNT == 32
OneWire * oneWireBus[BUSCOUNT] = { new OneWire(22), new OneWire(23), new OneWire(24), new OneWire(25), new OneWire(26), new OneWire(27), new OneWire(28), new OneWire(29), new OneWire(30), new OneWire(31), new OneWire(32), new OneWire(33), new OneWire(34), new OneWire(35), new OneWire(36), new OneWire(37), new OneWire(38), new OneWire(39), new OneWire(40), new OneWire(41), new OneWire(42), new OneWire(43), new OneWire(44), new OneWire(45), new OneWire(46), new OneWire(47), new OneWire(48), new OneWire(49), new OneWire(50), new OneWire(51), new OneWire(52), new OneWire(53) };
#else
#error BUS COUNT not matched
#endif
#else
#if BUSCOUNT == 6
OneWire * oneWireBus[BUSCOUNT] = { new OneWire(9), new OneWire(8), new OneWire(7), new OneWire(6), new OneWire(5), new OneWire(4) };
#elif BUSCOUNT == 11
OneWire * oneWireBus[BUSCOUNT] = { new OneWire(9), new OneWire(8), new OneWire(7), new OneWire(6), new OneWire(5), new OneWire(4), new OneWire(A2), new OneWire(A3), new OneWire(A4), new OneWire(A5), new OneWire(A1) };
#else
#error BUS COUNT not matched
#endif
#endif
char format[40] = { 0 };
void setup() {
Serial.begin(115200);
Serial.setTimeout(1000);
Serial.println("BOOT");
}
#define PRINT_BUS Serial.print("BUS:"); Serial.print(id); Serial.print('\t');
//Serial.print(" round:"); Serial.print(round);
bool busloop(uint8_t id, uint8_t round) {
OneWire * oneWire = oneWireBus[id];
uint8_t device_rom[8];
#ifdef SHOW_SCAN
PRINT_BUS
Serial.println("START");
#endif
//oneWire->depower();
oneWire->reset();
while(1) {
delay(20);
if(!oneWire->search(device_rom)) {
#ifdef SHOW_SCAN
PRINT_BUS
Serial.println("FIN");
#endif
oneWire->reset_search();
//oneWire->power();
return false;
}
w1IdType_t device_type = (w1IdType_t) device_rom[0];
snprintf(format, sizeof(format), "BUS:%d\tROM:%02x-%02x%02x%02x%02x%02x%02x\t", id, device_type, device_rom[6], device_rom[5], device_rom[4], device_rom[3], device_rom[2], device_rom[1]);
Serial.print(format);
if(device_rom[7] != oneWire->crc8(device_rom, 7)) {
Serial.println("ERROR:CRC not valid!");
return false;
}
bool device_is_present = oneWire->reset();
if(!device_is_present) {
Serial.println("ERROR:Device missing");
continue;
}
switch(device_type) {
case DS18S20:
case DS18B20:
case DS1822:
oneWire->select(device_rom);
if(round == 0) {
oneWire->write(0x44, 1); // start conversion, with parasite power on at the end
Serial.println("INFO:start conversion");
//delay(50);
} else {
/*
oneWire->write(0x44, 1); // start conversion, with parasite power on at the end
unsigned long now = millis();
while(oneWire->read_bit() != 1) {
delay(10);
}
Serial.print(" ms ");
Serial.print(millis() - now);
//delay(750); // maybe 750ms is enough, maybe not
// we might do a oneWire->depower() here, but the reset will take care of it.
device_is_present = oneWire->reset();
if(!device_is_present) {
continue;
}
oneWire->select(device_rom);
*/
oneWire->write(0xBE); // Read Scratchpad
uint8_t device_data[12];
oneWire->read(device_data, 9);
#ifdef SHOW_RAW
Serial.print("DATA:");
// we need 9 bytes
for(uint8_t index = 0; index < 9; index++) {
snprintf(format, sizeof(format), "%02X", device_data[index]);
Serial.print(format);
}
Serial.print('\t');
#endif
if(device_data[8] != oneWire->crc8(device_data, 8)) {
Serial.println("ERROR:CRC not valid!");
return false;
}
//Serial.println();
// Convert the device_data to actual temperature
// because the result is a 16 bit signed integer, it should
// be stored to an "int16_t" type, which is always 16 bits
// even when compiled on a 32 bit processor.
int16_t raw = (device_data[1] << 8) | device_data[0];
if(raw == 0x550) {
Serial.println("ERROR:default Value");
continue;
}
if(device_type == DS18S20) {
raw = raw << 3; // 9 bit resolution default
if(device_data[7] == 0x10) {
// "count remain" gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - device_data[6];
}
} else {
const uint8_t cfg = (device_data[4] & 0x60);
// at lower res, the low bits are undefined, so let's zero them
if(cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if(cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if(cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
//// default is 12 bit resolution, 750 ms conversion time
}
const float celsius = (float) raw / 16.0f;
Serial.print("TEMP:");
Serial.println(celsius, 3);
}
break;
case DS2406:
oneWire->select(device_rom);
uint8_t device_data[12];
uint16_t crcr;
device_data[0] = DS2406_ACCESS_READ;
device_data[1] = 0x4D;
device_data[2] = 0xFF;
oneWire->write(device_data, 3);
oneWire->read(&device_data[3], 2);
crcr = oneWire->read();
crcr |= ((unsigned int) (oneWire->read())) << 8;
#ifdef SHOW_RAW
Serial.print("DATA:");
for(uint8_t index = 3; index < 5; index++) {
snprintf(format, sizeof(format), "%02X", device_data[index]);
Serial.print(format);
}
Serial.print('\t');
#endif
if(crcr == 0xFFFF) {
Serial.println("ERROR:No Answer");
return false;
}
if(crcr != ~oneWire->crc16(device_data, 5)) {
Serial.println("ERROR:CRC not valid!");
return false;
}
oneWire->reset();
Serial.print("STATE:");
Serial.println(~(device_data[4]) & 0b11);
break;
default:
Serial.println("ERROR:Device not implemented");
break;
}
}
}
uint8_t readHEX(const char * str) {
const char in[3] = { str[0], str[1], 0x00 };
return strtoul(in, NULL, 16);
}
void loop() {
static uint8_t x = 0;
for(uint8_t i = 0; i < BUSCOUNT; i++) {
busloop(i, x);
}
x++;
if(x >= 2) {
x = 0;
}
if(Serial.available() > 0) {
String line = Serial.readStringUntil('\n');
// WRITE 04 12-00000023ec76 03
// WRITE 04 12-00000023ec76 02
// WRITE 04 12-00000023ec76 00
if(line.startsWith("WRITE ") && line.length() > (25)) {
line.remove(0, 6);
uint8_t device_rom[8] = { 0 };
const char * buf = line.c_str();
uint8_t id = readHEX(buf);
buf += 3;
if(id > (uint8_t) BUSCOUNT) {
Serial.println("WRITE\tERROR:BUS id wrong");
return;
}
OneWire * oneWire = oneWireBus[id];
device_rom[0] = readHEX(buf);
buf += 3;
device_rom[6] = readHEX(buf);
buf += 2;
device_rom[5] = readHEX(buf);
buf += 2;
device_rom[4] = readHEX(buf);
buf += 2;
device_rom[3] = readHEX(buf);
buf += 2;
device_rom[2] = readHEX(buf);
buf += 2;
device_rom[1] = readHEX(buf);
buf += 2;
// add CRC
device_rom[7] = oneWire->crc8(device_rom, 7);
w1IdType_t device_type = (w1IdType_t) device_rom[0];
snprintf(format, sizeof(format), "BUS:%d\tROM:%02x-%02x%02x%02x%02x%02x%02x\tWRITE\t", id, device_rom[0], device_rom[6], device_rom[5], device_rom[4], device_rom[3], device_rom[2], device_rom[1]);
Serial.print(format);
line.remove(0, 19);
buf = line.c_str();
switch(device_type) {
case DS2406:
if(line.length() >= 2) {
uint8_t data = readHEX(buf);
Serial.print("DATA:");
Serial.print(data, HEX);
Serial.print('\t');
uint8_t state = ((data & 0b11) << 5) | 0xf;
bool device_is_present = oneWire->reset();
if(!device_is_present) {
Serial.println("ERROR:Device missing");
return;
}
oneWire->select(device_rom);
uint8_t out[4];
uint16_t crcr;
out[0] = DS2406_WRITE_STATUS;
out[1] = 0x07;
out[2] = 0x00;
out[3] = state;
oneWire->write(out, 4);
crcr = oneWire->read();
crcr |= ((unsigned int) (oneWire->read())) << 8;
if(crcr == 0xFFFF) {
Serial.println("ERROR:No Answer");
return;
}
if(crcr != ~oneWire->crc16(out, 4)) {
Serial.println("ERROR:CRC not valid!");
return;
}
// Write the status back.
oneWire->write(0xFF, 1);
oneWire->read();
Serial.println("OK");
} else {
Serial.println("ERROR:To less data");
}
break;
default:
Serial.println("ERROR:Device not implemented");
break;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment