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.