SOLVED: Trying to read OneWire ds18b20 without disabling interrupts

As the subject says. I'm running a 328p without crystal @8mhz. I'm manually multiplexing a 4 digit 7-segment display using timer2 interrupt. Also, i,m trying to read the ds18b20 with the OneWire library and Dallas library for conversion. Problem is that the I/O with the temp sensor is disrupting the display routine. I tried removing the ’nointerrupts()’ and pairing 'interrupts()’ in the OneWire library but then it doesn't work anymore (display is good, but i/o fails).

Any suggestions?

Running two bit bashing algorithms simultaneously is a challenge, and the one-wire bus requires some fairly sensitive timing. It's likely that you will not be able to resolve the conflict. Best bet is to purposely blank the display during the one-wire bus activity.

Thanks gardner. I know it's a tricky thing. The i/o with the ds18b20 takes about 50 msec in total and that's too long not to notice. I'm sure theres a concurrency bug in there somewhere, my interrupt is only 5 lines of code, there must be a way.

A logic analyser (saleae knockoff) is on its way to find the real problem without too much hassle.

If you can use your logic analyzer to measure the actual timing of your display updates, then perhaps you could modify the timing in the one-wire bus protocol logic to use display updates as part of the timing. For example in OneQire:read_bit you could change

uint8_t OneWire::read_bit(void)
{
	IO_REG_TYPE mask=bitmask;
	volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;
	uint8_t r;

	noInterrupts();
	DIRECT_MODE_OUTPUT(reg, mask);
	DIRECT_WRITE_LOW(reg, mask);
	delayMicroseconds(3);
	DIRECT_MODE_INPUT(reg, mask);	// let pin float, pull up will raise
	delayMicroseconds(10);
	r = DIRECT_READ(reg, mask);
	interrupts();
	delayMicroseconds(53);
	return r;
}

to

	DIRECT_MODE_INPUT(reg, mask);	// let pin float, pull up will raise
	delayMicroseconds(10);
	r = DIRECT_READ(reg, mask);
	interrupts();

	// delayMicroseconds(53);
        displayUpdate();             // measured 22 microsecs with logic analyzer
        delayMicroseconds(53 - 22);  // shortened to allow display update

	return r;

Just as a for-instance.

Thanks to the analyser, i found out my interrupt was not firing when a 1-wire data was being written. As it turned out, the service vector enabled/disabled the interrupts as well, with the effect that the disable/enable pairing went out of sync.

I removed the enabling/disabling from my timer interrupt. This fixed the problem.