G400 & 1-wire temps(DS18B20) effected by ambient

I have an issue, where I’m reading between 30-45 DS18B20’s per a single 1-wire line. I am using an extremely simple 3.3v to 5v pullup circuit as pictured below, connected to a G400 board.
I’ve several times, adjusted the values of the R1 & R2 resistors, and for a period of a month or so everything is stable, but while the temperatures of the DS18B20’s, don’t fluctuate significantly, the temperatures that the G400 / Pullup circuit, well see’s the ambient outside temperatures, and then I’m back to missing sensors, or error code readings…

Anybody any thoughts on what’s changing? Possibly the frequency of the crystal driving the micro?

I’ve played with some more advanced level shifting IC’s, but didn’t have a lot of luck, so went with simple to get operational, and waiting on some new boards that are professionally populated to try again…

@ michaelb: I have recently been fighting an issue with DS18B20 sensors where they would latch up. This appears to be a problem in the Microsoft.SPOT.Hardware.OneWire routines, and it appears to be caused when a asynchronous RS232 stream sends data generating an interrupt during a OneWire read or write. We are in the process of verifying this, but if I disable the RS232 interrupts the problems go away. Since this is timing related, in my case it can take hours to manifest the error…

@ rockybooth - Interesting, as I’ve spent more hours than I care to debugging an X-modem protocol while talking to these devices… I’m actually intentionally sending way more data back & forth repeatedly, as I was attempting to make sure that the ability existed to send large, intact CRC verified files back & forth, for in field updating of meshed networked devices… While, just on a pattern recognition feeling, don’t think it address’s the specific issue I posted, I think its very relevant in another area that I’ve had issue’s with… Thanks for the comment.

If interested, Microsoft explains the Interrupts here:

@ rockybooth - Not sure what 1-wire implementation your using, but I started out with StablePoints, and have grown it to approximately 7 different 1-wire devices. If I’m on a small network, (less than 10 devices), I’ve yet to have issues with it, with the exception of the below freezing bug, which is easy enough to correct for.
Also, that said, I’ve never seen a 1-wire device latch up, (Well, one exception was the DS18B20 B7 die, where my biggest oops was wiping the eeprom of approximately 2000 sensors in less than a second), unless you mean the Micro, and I’ve been recently digging into Interrupts at the Hal/Pal layer, to better understand whats going on, (originally driven from accidentally populating a board that only functions in Overdrive mode)…
There is a lot on this forum that I’m still learning, but the DS18B20, is a sensor I’m VERY familiar with…to the point where in some applications, because of what I’m using them for, I need to re calibrate them far beyond the 1/2 degree accuracy that is claimed from the factory.
Which board are you using?

@ michaelb: I am using a custom board with a STM 32F429. I have 2 DS18B20 sensors operating. I also use the Stablepoint code as the starting point. A commands that will sometimes hang is in Stablepoint.hardware.onewire.devices.ds18b20.GetTemperature at either of these lines:
_rawDevice.RawBus.WriteByte(Command.MatchRom);
WriteBytes(_rawDevice.Address);

I find that VS stops responding, and to get control of the micro a reset is required.
VS does not break, and a Try/Catch will not catch the fault.
This only happens if I have a separate serial port data stream generating interrupts, otherwise there are no issues.

@ rockybooth - Interesting, will look into my code a bit more, compared to you, but in the Wiki, the original author prefers update temps, vs get temps because of exceptions, and because of my application I’ve used, I’ve never used the get temps… Just a first thunk, but curious…

@ rockybooth - From what thread are you calling this from?
I have a hunch I know what’s going on, but 9 times out of 10, I’m wrong, but that 1 time, curious…

@ michaelb:
To read the temperature, I modified the StablePoint ReadTemperature function to break it into two parts: StartTemperatureRead, which starts each sensor reading, and GetTemperature which retrieves the temperature. This was done to avoid the sleep for the conversion.
As far as the thread, when the program starts I initialize all the devices I am using including displays, 24bit ADCs, etc, and then start a timer and enter a sleep(timeout.infinite).
The timer firing gets the latest reading, does other stuff,and starts a new temperature conversion before ending.
Before calling a GetTemperature I verify the time elapsed since the reading was started is sufficient for the reading to be available.

@ rockybooth - Any chance of finding out what happens if you simply disconnect the sensors while your program is running?
Also, given you have split the function up, does it always lock up on the second MatchRom / Address command, or does it sometimes lock up on on StartTemperatureRead at the same lines?

It latches up on these two commands (not sure which one):
_rawDevice.RawBus.WriteByte(Command.MatchRom);
WriteBytes(_rawDevice.Address);
This can be in either start or read temperature.

If I disconnect the sensors it will throw an error as it should:
HandleCriticalError(“No response from device.”, “Function ReadTemperature()”);

This is the code that is then called from those two commands,

SMALLINT owWriteByte(int portnum, SMALLINT sendbyte)
{
   if((portnum >= MAX_PORTNUM) || (portnum < 0) || (owPortPin[portnum] ==0)) return 0;
   
   return (owTouchByte(portnum,sendbyte) == sendbyte) ? TRUE : FALSE;
}

SMALLINT owTouchByte(int portnum, SMALLINT sendbyte)
{
   uchar i;
   uchar result = 0;

   if((portnum >= MAX_PORTNUM) || (portnum < 0) || (owPortPin[portnum] ==0)) return 0;

   for (i = 0; i < 8; i++)
   {
       result |= (owTouchBit(portnum,sendbyte & 1) << i);
       sendbyte >>= 1;
   }

   return result;
}

SMALLINT owTouchBit(int portnum, SMALLINT sendbit)
{
   unsigned char result=0;
   
   if((portnum >= MAX_PORTNUM) || (portnum < 0) || (owPortPin[portnum] ==0) ) return 0;
   
   UINT32 pin = (UINT32)owPortPin[portnum];  

   //timing critical, so I'll disable interrupts here
   GLOBAL_LOCK(irq); //EA = 0;

   // start timeslot.
   CPU_GPIO_EnableOutputPin( pin, false );

   usDelay(5);

   if (sendbit == 1)
   {
	   // send 1 bit out.
	   // sample result @ 15 us.
	   CPU_GPIO_EnableInputPin( pin, false, NULL, GPIO_INT_EDGE_HIGH, RESISTOR_PULLUP );
	   usDelay(5);
	   result = CPU_GPIO_GetPinState(pin); 	
	   usDelay(55);
   }
   else
   {
      // send 0 bit out.
     ::CPU_GPIO_SetPinState(pin, 0); 	
     usDelay(70);
   }
   // timeslot done. Set output high.
   CPU_GPIO_EnableOutputPin( pin, true );

   usDelay(5);

   //restore interrupts
   irq.Release();

   if (result != 0) 
   {
     result = 1;
   }
   else
   {
     result = 0;
   }
   
   return result;
}

My best guess, is that there is the odd time that after GlobalLock is set, the serial interrupt routine has already put a request in, and you end up in the serial routine without any way to get back… This is part of the response I got from Microsoft when I was digging into threading…

This is just a suggestion that explains the symptoms your having, although I suspect, (but not sure), A Jtag debugger might confirm/deny this.

1 Like

michaelb: Many thanks, I really appreciate the insight.
Fortunately, avoiding interrupts by serial does seen to solve the problem. And, physically disconnecting the sensor does trigger the error trapping built into the StablePoint routines.
Rocky