Strange behavior on the Onewireslave library

Markus_L811

Well-known member
I worked on an Onewire-Slave lib first thinks worked good but after I try to move the attachinterrupt-routine in the library it goes strange.

Here a the exiting parts:

I try to move the double definition of the Slave Pin and the Interrupt Pin inside the lib to make it easy to set it up and make some define's to sort out for some Arduinoboards and ARM Boards (T3 Due as far) I attached 2 Sketches ..._fulllib is the one under construction the other is the "normal" one with seperate Pin discription for the lib and in sketch function.

The constution is:
in the h for wrapping out of the static trap of the attachinterrupt-routine
(an good friend helped me with that)
Code:
class OneWireSlave {
  ...
  public:
    ...
    void init2(unsigned char rom[8], uint8_t pin);
    void MasterResetPulseDetection();
    static void ISRPIN();

...
static OneWireSlave* static_OWS_instance;

#endif

move this stuff from the sketch

Code:
//Interrupt
volatile long previousmicros = 0;
volatile long old_previousmicros = 0;
volatile long difference = 0;

void setup() {
  ...
  attachInterrupt(dsslaveassignedint, DS18B20, CHANGE);
  ...
}

void DS18B20() {
  old_previousmicros = previousmicros;
  previousmicros = micros();
  difference = previousmicros - old_previousmicros;
  if (difference >= lowmark && difference <= highmark) {
    ds.waitForRequestInterrupt(false);
  }
}
in the cpp for the MasterResetPulseDetection.
Code:
...
void OneWireSlave::ISRPIN() {
  (*static_OWS_instance).MasterResetPulseDetection();
}

void OneWireSlave::MasterResetPulseDetection() {
  old_previous = previous;
  previous = micros();
  diff = previous - old_previous;
  if (diff >= lowmark && diff <= highmark) {
    waitForRequestInterrupt(false);
  }
}
...
void OneWireSlave::init2(unsigned char rom[8], uint8_t pin) {
	for (int i=0; i<7; i++)
    this->rom[i] = rom[i];
  this->rom[7] = crc8(this->rom, 7);
  
  attachInterrupt(pin, &ISRPIN, CHANGE);
}

And now to the problem:
In the old version all works fine just, but in new one it seems there is an issue with this functions if some of this is called

#define DIRECT_READ(base, mask) (*((base)+512))
#define DIRECT_MODE_INPUT(base, mask) (*((base)+640) = 0)
#define DIRECT_MODE_OUTPUT(base, mask) (*((base)+640) = 1)
#define DIRECT_WRITE_LOW(base, mask) (*((base)+256) = 1)
#define DIRECT_WRITE_HIGH(base, mask) (*((base)+128) = 1)

My T3 get broken and the T3 stopped working. I don't think it's on the functions above I reckon it's more a Problem how they called inside the wrapped interrupt function, but I have no answer.

I don't know why it don't work in this way, can someone help me please.
 

Attachments

  • DS18B20_Slave_Interrupt_universal_analogread.ino
    2.4 KB · Views: 1,251
  • DS18B20_Slave_Interrupt_universal_analogread_fulllib.ino
    2 KB · Views: 1,101
  • OneWireSlave.cpp
    20.1 KB · Views: 1,442
  • OneWireSlave.h
    7.1 KB · Views: 8,653
Last edited:
Changing this to this helps I don't know why:

//volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;
volatile IO_REG_TYPE *reg IO_REG_ASM = PIN_TO_BASEREG(_pin);

And making this works quit fine
Code:
uint8_t _pin;

OneWireSlave::OneWireSlave(uint8_t pin) {
	_pin = pin;
	pinMode(_pin, INPUT);
	pin_bitmask = PIN_TO_BITMASK(_pin);
	baseReg = PIN_TO_BASEREG(_pin);
	
	#define dsslavepin _pin
        attachInterrupt(dsslaveassignedint, &ISRPIN, CHANGE);
}

volatile uint8_t errno = 0;                //neccessery to bring errno direct in.

but this brings it down:

Inside the presence function
Code:
  uint8_t retries = 25;
  while (!DIRECT_READ(reg, mask));
  do {
	if ( retries-- == 0)
		//return FALSE;
	delayMicroseconds(2); 
  } while(!DIRECT_READ(reg, mask));
  /*
 
Last edited:
An new cleaner sketch and some integrations for Teensyboards

Hey guys,

I integrated some #defined to let the lib to choose between the differend Teensy Boards and to distinguish between T2.0 and the Arduino Leonardo, and an new Sketch there. Not high integrated (because I don't know how) but nicer I think.

Rest below.

Code:
#define dsslavepin 12

#include <OneWireSlave.h>

//                     {Family , <---, ----, ----, ID--, ----, --->,  CRC} 
unsigned char rom[8] = {DS18B20, 0xAD, 0xDA, 0xCE, 0x0F, 0x00, 0x11, 0x00};
//                            {TLSB, TMSB, THRH, TLRL, Conf, 0xFF, Rese, 0x10,  CRC}
unsigned char scratchpad[9] = {0x00, 0x00, 0x4B, 0x46, 0x7F, 0xFF, 0x00, 0x10, 0x00};
//                             {TLSB, TMSB}
unsigned char temperature[2] = {0x7F, 0x09};

OneWireSlave ds(dsslavepin);

//Blinking
const int ledPin = 13;
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated
long interval = 250;            // interval at which to blink (milliseconds)

float value, oldvalue;
boolean expose = true;

void setup() {
  attachInterrupt(dsslaveassignedint, slave, CHANGE);
  Serial.begin(9600);
//  while (!Serial) {
//    ; // wait for serial port to connect. Needed for Leonardo only
//  }
  pinMode(ledPin, OUTPUT);
  ds.init(rom);
  ds.setScratchpad(scratchpad);
  ds.setPower(PARASITE);
  ds.setResolution(9);
  value = -55;
  ds.attach44h(temper);
}

void slave() {
  ds.MasterResetPulseDetection();
}

void loop() {
  blinking();
  
  readfromanalog();
}

void temper() {
  int16_t degree = value * 16;
  temperature[0] = degree & 0xFF;
  temperature[1] = degree >> 8;
  ds.setTemperature(temperature);
}

void blinking() {
  unsigned long currentMillis = millis(); 
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    ledState = !ledState;
    digitalWrite(ledPin, ledState);
  }
}

void readfromanalog() {
  if (expose) {
    Serial.println("Vorgabe Temperatur: ");
    expose = false;
  }
  
  int analog = analogRead(A5);
  analog = map(analog, 1, 1023, -1023, 1023);  
  
  value = (float)analog/10;
  
  if (value != oldvalue){
    Serial.print(value);
    Serial.println(" C");
    oldvalue = value;
  }
}

Sorry guys, I did not include CRC in all changes, now included. So it works better.
 

Attachments

  • OneWireSlave.h
    9 KB · Views: 1,390
  • OneWireSlave.cpp
    21.1 KB · Views: 1,258
Last edited:
Upgrade

New cpp with integration for the ALARM SEARCH function.

Now you get responce for the AlarmHandler Sketch from Miles Burton.
 

Attachments

  • OneWireSlave.cpp
    21.4 KB · Views: 1,420
Seems to work pretty well. This may be useful for my TeensyPi project, as I am interested in placing other devices (thermocouples, humidity sensors, etc) on the 1-wire bus. Nice Job.

Update:

I may have spoken too soon...

I've got two Unos, one running as a 1-wire master and one as a 1-wire slave, running on a very short (< 10") 1-wire mini-lan. It works for a while, then the slave appears to give up the ghost. Since I don't have a scope or logic analyzer available it's kind of hard to see what's dying...

Oh well...
 
Last edited:
Seems to work pretty well. This may be useful for my TeensyPi project, as I am interested in placing other devices (thermocouples, humidity sensors, etc) on the 1-wire bus. Nice Job.

Update:

I may have spoken too soon...

I've got two Unos, one running as a 1-wire master and one as a 1-wire slave, running on a very short (< 10") 1-wire mini-lan. It works for a while, then the slave appears to give up the ghost. Since I don't have a scope or logic analyzer available it's kind of hard to see what's dying...

Oh well...

Oh sorry to hear that I worked on some strange behaviors I post my latest files. ATM I worked with 2 Teensy 3.0 to test it and there I had tests for several hours working fine.

My latest files there.

There are some issues I working on, I think the Uno is fast enough, I can't remember that an Slave disappear in the latest ones can you test it with this files again and show my your sketch so I know that you do.
 

Attachments

  • OneWireSlave.cpp
    21.8 KB · Views: 21,666
  • OneWireSlave.h
    9.1 KB · Views: 25,103
  • DS18B20_Slave_Interrupt_universal_analogread.ino
    2.3 KB · Views: 18,129
Changed the slave to a Teensy 3.0, and now the slave is responding just fine, apparently the Uno just doesn't have enough "oomph"...
 
Changed the slave to a Teensy 3.0, and now the slave is responding just fine, apparently the Uno just doesn't have enough "oomph"...

"oomph" sounds nice, there is somewhere an problem with the timing, I don't know why, think it's time to get an scope...

And yes the Teensy 3.0 works really fine.
 
Odd problem...

I've made a couple of boards that use the Teensy 3.0 and MAX31855K as a 1-wire Thermocouple.

When I address the boards with 1-wire addresses that are close together, ie 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 and 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, the ds.search() function of the 1-wire library fails to detect either of them.

When I address the boards with 1-wire addresses that are farther apart, ie 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00 and 0xAA, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, the ds.search() function of the 1-wire library can fined them both just fine.

Just thought I'd throw that out there...
 
I've made a couple of boards that use the Teensy 3.0 and MAX31855K as a 1-wire Thermocouple.

When I address the boards with 1-wire addresses that are close together, ie 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 and 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, the ds.search() function of the 1-wire library fails to detect either of them.

When I address the boards with 1-wire addresses that are farther apart, ie 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00 and 0xAA, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, the ds.search() function of the 1-wire library can fined them both just fine.

Just thought I'd throw that out there...

Think There is something wrong with the response for the search algorithm I will investigate it soon.
 
Have a question - would it be possible to instantiate multiple instances of a one-wire slave with a specific address on a single Teensy? I ask because I have a one-wire datalogger in my home that can't use anything other than one-wire as an input. There are some distant sensors that would benefit from a wireless link. If I could transfer the data to a 'sample and hold' teensy 3 one-wire slave that pretends being multiple DS18B20 or DS2408, etc. , I would be a happy camper indeed. Each pin would masquerade as a separate one-wire device..
 
Have a question - would it be possible to instantiate multiple instances of a one-wire slave with a specific address on a single Teensy? I ask because I have a one-wire datalogger in my home that can't use anything other than one-wire as an input. There are some distant sensors that would benefit from a wireless link. If I could transfer the data to a 'sample and hold' teensy 3 one-wire slave that pretends being multiple DS18B20 or DS2408, etc. , I would be a happy camper indeed. Each pin would masquerade as a separate one-wire device..

Interesting question! I didn't test i yet.

May in several intanceses, but I think I wouldn't work because it will drop if the rom id don't match so in an few days I have some more time so I can write/rewrite an function that supports more rom id's with more actions for different 44h.
 
A generous German user figured out a way to emulate the now-discontinued DS2434 with a ATTiny25 (!!!), which is a great way around the DS2423 shortage ($10.20 a chip!). The underlying software may provide some hints re: how to emulate a DS2423, etc.

I bet the folk at OWFS would be tickled pink if more one-wire input options became available. Given the sheer number of inputs on a Teensy 2 or 3, one could create very cost-competitive, flexible, and easy-to-configure front ends for data collection, holding, and later transmission of remote as well as local sensor data. The only caveat is being able to emulate the various 1-wire device flavors as a slave.

Likely, the Teensy 2 series would be a better candidate for this project, however, as 5V compatibility is likely important. But I could be wrong!
 
A generous German user figured out a way to emulate the now-discontinued DS2423 with a ATTiny25 (!!!), which is a great way around the DS2423 shortage ($10.20 a chip!). The underlying software may provide some hints re: how to emulate a DS2423, etc.
I know this page and see how he made it. It's brain-fucking!

Jumps with Timer and pcint from stage to stage inside the communication tree of the 1-Wire Protocol. I think it would be nice to implement the DS2423 functions.
I bet the folk at OWFS would be tickled pink if more one-wire input options became available. Given the sheer number of inputs on a Teensy 2 or 3, one could create very cost-competitive, flexible, and easy-to-configure front ends for data collection, holding, and later transmission of remote as well as local sensor data. The only caveat is being able to emulate the various 1-wire device flavors as a slave.

Likely, the Teensy 2 series would be a better candidate for this project, however, as 5V compatibility is likely important. But I could be wrong!

Yes this can be really nice btw. the Teensy 3.1 servs 5V the Ports are 5V resistent
 
Last edited:
This was a while back...

I've made a couple of boards that use the Teensy 3.0 and MAX31855K as a 1-wire Thermocouple.

I started playing with the board and code again, and one of the things that I really wanted was an automagic way to have a unique 1-wire address for each board without futzing with the code and uploading a re-compiled program for each new board.

I've been messing around with the WIZ820io and when I found this thread, I realized that I could use the 6-byte MAC address of the Teensy 3.0 as the unique address for each board.

I'm using AA as the family code, the Teensy MAC address as the unique address, and letting the OneWireSlave code compute the CRC. I've added a "showID()" function to the OneWireSlave library to allow me to make sure that each address is unique.

I've got three boards happily communicating on the 1-wire mini-lan, and will add some additional devices as time allows.

This is probably moot, as Maxim recently released a 1-wire thermocouple chip, but it may have some other applications.

Here's a copy of my BasicOneWireSlave.ino

Code:
/********************

Basic1WireSlave.ino

Version 0.0.1
Last Modified 12/20/2013
By Jim Mayhugh

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

This software uses multiple libraries that are subject to additional
licenses as defined by the author of that software. It is the user's
and developer's responsibility to determine and adhere to any additional
requirements that may arise.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


*********************/

#define dsslavepin 2

#include <OneWireSlave.h>
#include <MAX31855.h>
#include <t3mac.h>

//                     {Family , <---, ----, ----, ID--, ----, --->,  CRC} 
uint8_t rom[8] = {0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
//                            {TLSB, TMSB, THRH, TLRL, Conf, 0xFF, Rese, 0x10,  CRC}
uint8_t scratchpad[9] = {0x00, 0x00, 0x4B, 0x46, 0x7F, 0xFF, 0x00, 0x10, 0x00};
//                             {TLSB, TMSB}
uint8_t temperature[2] = {0x7F, 0x09};

OneWireSlave ds(dsslavepin);

const int mxDO  = 3;
const int mxCLK = 5;
const int mxCS = 4;

// Initialize the Thermocouple
MAX31855 eMX(mxCLK, mxCS, mxDO);

//Blinking
const int ledPin = 13;
int ledState = LOW;             // ledState used to set the LED
//long previousMillis = 0;        // will store last time LED was updated
elapsedMillis interval;
uint32_t interval_cnt = 250;
//long interval = 250;            // interval at which to blink (milliseconds)
uint8_t setDebug = 0x0;         // set to 0 to disable serial debug


void setup() {
  if(setDebug)
  {
    delay(5000);
    Serial.begin(115200);
    delay(3000);
    Serial.println(F("Serial Debug started at 115200 baud"));
  }
  read_mac();
  memcpy( (uint8_t *) &rom[1], (uint8_t *) &mac, 6 );
  rom[7]=ds.crc8(rom, rom[7]); 
  
  attachInterrupt(dsslaveassignedint, slave, CHANGE);
//  Serial.begin(115200);
//  while (!Serial) {
//    ; // wait for serial port to connect. Needed for Leonardo only
//  }
  pinMode(ledPin, OUTPUT);
  ds.init(rom);

  if(setDebug)
  {
    Serial.print(F("MAC Address is "));
    print_mac();
    Serial.println();
  }

  ds.setScratchpad(scratchpad);
  ds.setPower(EXTERNAL);
//  ds.setResolution(9);
//  value = -55;
  ds.attach44h(temper);
}

void slave() {
  ds.MasterResetPulseDetection();
}

void loop() {
  blinking();
}

void temper() {
  int16_t degree = eMX.readCelsius();
  temperature[0] = degree & 0xff;
  temperature[1] = (degree & 0xff00) >> 8;
  ds.setTemperature(temperature);
}

void blinking() {
  if(interval >= interval_cnt) {
    ledState = !ledState;
    digitalWrite(ledPin, ledState);
    interval = 0;
    if(setDebug)
    {
      ds.showID();
    }
  }
}

And the two libraries:
 

Attachments

  • OneWireSlave.zip
    10.4 KB · Views: 4,285
  • MAX31855.zip
    1.8 KB · Views: 2,098
Last edited:
Back here again...

It seems that the 1-Wire Slave library is working with Arduino 1.0.6 and Teensyduino 1.20, but will not work with any newer combination of Arduino/Teensyduino.

I was hoping to use the Teensy-LC as a lower-cost replacement for some 1-wire slave boards I've made, but until I can figure out what's going on, I'll have to stay with the 1.06/1.20 combination.
 
Back here again...

It seems that the 1-Wire Slave library is working with Arduino 1.0.6 and Teensyduino 1.20, but will not work with any newer combination of Arduino/Teensyduino.

I was hoping to use the Teensy-LC as a lower-cost replacement for some 1-wire slave boards I've made, but until I can figure out what's going on, I'll have to stay with the 1.06/1.20 combination.

Hi jimmayhugh, oh yes it's on my list didn't have ported it yet nor added the Teensy-LC I will order an LC the next days and then I will bring it on the way, sorry...
 
Hi jimmayhugh, oh yes it's on my list didn't have ported it yet nor added the Teensy-LC I will order an LC the next days and then I will bring it on the way, sorry...

Not a problem, I was just surprised that it would compile, but then would bring down the entire mini-lan. I'm not going to be able to look at it before next weekend anyway.
 
Looks like OneWireSlave needs at least an update for the direct I/O macros. The normal OneWire library has them for Teensy-LC. The section about which pins support interrupts will also need some definitions for Teensy-LC, since most but not all pins support interrupts.

Is there a GitHub repository for OneWireSlave? I could send a pull request, if there is.
 
Looks like OneWireSlave needs at least an update for the direct I/O macros. The normal OneWire library has them for Teensy-LC. The section about which pins support interrupts will also need some definitions for Teensy-LC, since most but not all pins support interrupts.

Is there a GitHub repository for OneWireSlave? I could send a pull request, if there is.

https://github.com/MarkusLange/OneWireSlave

Thanks, Paul.
 
Last edited:
You can try View attachment 4070 if it works I will upload it, added the direct I/O macros grabbed from the OneWire lib

I used your DS18B20_Slave_Interrupt_T3 example using a Teensy3.0 as a base. I'm using pin 9 as the dsslavepin.
With the 1.0.6/1.20 IDE, the code compiles and communicates just fine.
OneWireSlave-1.0.6-1.20.png
With the 1.6.3/1.22 IDE the code compiles, but seems to get stuck sending a stream of presence pulses.
OneWireSlave-1.6.3-1.22.png
 
Last edited:
Need a scope. Did the other example also didn't work?

Lookd like DS18B20_Slave_Interrupt_universal_analogread works atm don't know why the other not
 
Last edited:
Back
Top