Temp DS18b20 + Humidity + Ethernet

I am creating a project that will monitor humidity and 1 to 10 temperature sensors and have a simple ethernet interface.

I have the project working but I am not happy with the way I have implemeted it.

Basically I poll for DS18B20 devices in setup() and then in the loop

loop()
{
    Check Humidity();
    Check Temperature();
    Check Ethernet()
}

In the Humidity and Temperature function I only do a check if it has been at least 10 seconds since the last check.

The humidity is fine as it is quick. The problem is with the DS18B20 devices as the library I am using and generally most must issue a 1Wire command and then wait 750ms before looking for the answer.

Not too bad if you have 1 device, but if you have 10 then that alone is 7.5 seconds

If you make an ethernet lookup you my be waiting 7.5+ seconds for an answer due to the temperature lookups.

Is there a way that the temperature lookup can be done in the background? is there such a thing as real background processes?

Is using the Timer() and Timer2() really background processes? or does the loop() just stop while the code in the timer interrupt runs?

Should I be updating only 1 temperature probe every time through the loop if the right amount of time has passed?

Cheers

Chris

The amount of time needed for a DS18B20 conversion is dependent upon the resolution of the reading. By default this is 12 bits. If you use 9-bit resolution (half a degree precision) the delay is less than 100ms.

Pete

el_supremo:
The amount of time needed for a DS18B20 conversion is dependent upon the resolution of the reading. By default this is 12 bits. If you use 9-bit resolution (half a degree precision) the delay is less than 100ms.

Thanks Pete.

After posting this I have had two thoughts.

  1. Say I want to update every 10 seconds then if there is 4 sensors (10000 / 4) = 2500 so if the interval is >= 2500 process the next temperature - ie only do one at once and keep a counter of the last one I did.

  2. I like this better

Like #1 above but while waiting just set a flag to say I am waiting and then exit the function so the rest of the loop can process. Then next call to the function I check if the flag is set if so then has 750ms passed? if it has then process the value of the temperature clear the flag and continue with the method in #1.

I think I will try this out - I will post back my findings.

Chris

I went with my option #2

Here is the code I ended up with - it takes a while when the sketch starts up to read all the temperatures which could be handled in a better way but I am happy now as my ethernet web server response is instant (or close to it)

void checkTemperature()
{
        if (continueProcessingTemperatureMillis != 0) 
	{
		if (millis() >= continueProcessingTemperatureMillis)
		{
			byte i;
			byte present = 0;
			byte type_s;
			byte data[12];
			byte addr[8];
			float celsius;

			present = ds.reset();
			ds.select(sensor[temperatureSensorToProcess]);    
			ds.write(0xBE);         // Read Scratchpad

			for ( i = 0; i < 9; i++) {           // we need 9 bytes
				data[i] = ds.read();
			}
			//Serial.print(" CRC=");
			//Serial.print(OneWire::crc8(data, 8), HEX);
			//Serial.println();

			// convert the data to actual temperature

			unsigned int raw = (data[1] << 8) | data[0];
			if (type_s) {
				raw = raw << 3; // 9 bit resolution default
				if (data[7] == 0x10) {
					// count remain gives full 12 bit resolution
					raw = (raw & 0xFFF0) + 12 - data[6];
				}
			} else {
				byte cfg = (data[4] & 0x60);
				if (cfg == 0x00) raw = raw << 3;  // 9 bit resolution, 93.75 ms
				else if (cfg == 0x20) raw = raw << 2; // 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
			}
			celsius = (float)raw / 16.0;

			temperature[temperatureSensorToProcess] = celsius;

			temperatureSensorToProcess++;
			if (temperatureSensorToProcess >= temperatureSensorCount)
				temperatureSensorToProcess =0;

			nextTemperatureRead= millis() + MS_TEMPERATURE_DELAY;
			continueProcessingTemperatureMillis = 0;
		}
	}
	else{
		if (millis() >= nextTemperatureRead)
		{
			ds.reset();
			ds.select(sensor[temperatureSensorToProcess]);
			ds.write(0x44,1);         // start conversion, with parasite power on at the end
			
			continueProcessingTemperatureMillis = millis() + 750;
		}
	}
}

Chris