Pages: [1]   Go Down
Author Topic: SOLVED: Trying to read OneWire ds18b20 without disabling interrupts  (Read 484 times)
0 Members and 1 Guest are viewing this topic.
The Netherlands
Offline Offline
Full Member
***
Karma: 2
Posts: 197
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
« Last Edit: November 29, 2013, 02:02:06 pm by RobvdVeer » Logged

Rob
Follow my progress on http://simplicate.weebly.com

Ontario
Offline Offline
God Member
*****
Karma: 25
Posts: 883
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

The Netherlands
Offline Offline
Full Member
***
Karma: 2
Posts: 197
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Rob
Follow my progress on http://simplicate.weebly.com

Ontario
Offline Offline
God Member
*****
Karma: 25
Posts: 883
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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

Code:
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.
Logged

The Netherlands
Offline Offline
Full Member
***
Karma: 2
Posts: 197
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Rob
Follow my progress on http://simplicate.weebly.com

Pages: [1]   Go Up
Jump to: