The educational section of the temp display.....

One of the most useful functions of the Arduino is MAP. This allows taking any sensor information

in bits and converting it to a useful number in engineering units. Best used in data with linear

slope. However, most data is somewhat linear for short intervals. Multiple MAP functions can be

used for limited sections of a curve. The calibration data does not need to fully from end to end

of the data span. It will interpolate beyond that. If you have data for 167 counts and 689 counts

it will calculate the value for 101 counts or 778 counts.

The water tank temperature sensing uses a cheap $3 temperature control board that has a

resistive sensor that is pulled up to 5V by a 10K resistor. This is ideal for the A/D converter

input of a UNO and they can just be connected together at the same time. The display is a bonus

not requiring you to write any code or add additional electronics. Hard to replicate for $3.

Calibration is very easy. Just replace the sensor with a pot and adjust to any temperature desired

on the display. The A/D readings are then recorded for that temperature. This will require you

to have a diagnostic code to read these values. Quite easy using Serial Monitor in TOOLS. Here is

the sample code I used as part of the house program.

AI5 = analogRead (5); // Anolog In. Read temp board sensor

// PIN #A5 TANK #1 TEMP

The A/D converter produces a number with a maximum of 1K counts. I has a noise level of up

to six counts. With small numbers, this is a problem. Averaging produces a very stable number.

The following routine smothes out those variances and multiplies the raw A/D number by 16.

Unless declared as something else, a variable is a maximum of +- 16K. Going beyond that produces

strange results. Since maximum A/D reading is 1K and it is multiplied by 16, that 16K is never

violated. Always be careful not to exceed variable limits. Try to use binary numbers,2, 4, 8,

16,32 as they are faster in math multiplies and divides. That becomes only a shift left or right.

WH1avg = WH1avg - WH1avg / 16 ; // average temp raw data X16 to get rid of noise

WH1avg = WH1avg + AI5 ; // this is a times sixteen multiplier

The map function will convert any count to an engineering value. The bigger the input number

that is used, the more accurate it will be. In the tank temperature range that number can be

as low as 180 counts from the A/D. Therefore, the above multiplication is performed. Noise if

averaged can increase the accuracy of the reading. This routine does slow down the response

time. In this case it helps. other times it creates big problems. The output number is in

degrees C times 10. So, 45.3C is 453. I just like using integer numbers and again, the bigger

the better.

temp1 = map (WH1avg , 4730, 2590, 300, 490); // For TEMP SENSOR with 10K pullup to +5V X16

// format... DATA, LOW RAW, HIGH RAW, LOW OUT, HIGH OUT,

// Output is X10 in degrees C

// WATER HEATER #1 TEMP ANALOG OUT IN F

// Like who understands degrees C

temp1avg is the value in C of tank #1 times ten from MAP function. (503 = 50.3C)

A running average of that value is taken over 8 samples giving a multiplier of eight FOR

temp1avg. (4024) This additional average is done because in my other control logic I need

really stable numbers.

temp1avg = temp1avg - temp1avg / 8 ; // average temp to get rid of noise

temp1avg = temp1avg + temp1 ; // this is a times eight multiplier

// ANALOG METER PWM FOR CONVERSION F = C * 9 / 5 + 32

Math follows the MiDAS rule. Multiplications are done first, Divisions next, Additions follow

and Subtraction last. This math example is very simple. Others can be hard to get your head

around if you are not familiar with math. Perfectly fine to do one operation at a time to

avoid errors. This will also make it easier to detect when limits have been exceeded.

T1WH = temp1avg / 5; // reduce number first to prevent over run (804)

T1WH = T1WH * 9; // then multiply (7236)

T1WH = T1WH + 2560; // add in freezing X8 X10 =2560 (9796)

T1WH = T1WH / 44; // divide by whatever to get a nice 0-255 range (195)

// 25C 77F, would be (123) for reference

End up with a PWM value as close to 255 as possible to produce the highest voltage and give you as many bits of resolution as possible. The number chosen gives about 3.7V normally. A resistive voltage divider converts that to about 1.2V for the meter. If the decimal point is ignored or painted over, the reading is in in degrees F with a three digit 0-10V digital meter. Smoothing of the PWM pulses to give an average voltage is performed with a 5.1K resistorgoing to a 150uF capacitor, negative of capacitor connected to common. A voltage divider of about 100K is suitable for the meter.

if (blinktime == 10 || blinktime == 110) analogWrite (6,T1WH); // send out temp as analog

// value twice a cycle

I don't like updating every program loop. This updates the display about every 3 seconds. blinktime is a loop count and || is an OR function. Update is done at either 10 or 110.

Analog transmissions are old school but work well for long distances. This display is 30 feet from power shed. These meters only cost a little more than a buck and it is simple to use technology. This is the temp display in the shed.