I didn't try that, but made it show the Room-temperature.
The MOD-TC interface uses MAX6675 IC and uses a pseudo SPI-interface. With pseudo I mean that it is using a wiring scheme that allows it to be used in a real SPI setup, but does need it's own software driver.
As this is UEXT plugin compatible, after studying the schematic I came up with the following:
Code: Select all
MODULE MAX6675;
(* The primary use of the library is to easily interface with a MAX6675 chip via it's
PSEUDO-SPI interface. Use the following code to initialize the library.
units is one of the following:
0 = raw 0-4095 value
1 = temp in °C
2 = temp in °F
Following this you can use the ReadTemp() function to return the temperature
as a REAL.
temperature := MAX6675.readTemp();
*)
IMPORT SYSTEM, Out, LPC := LPC2378, Timer;
PROCEDURE ToggleCS(high : BOOLEAN);
BEGIN
IF high THEN
SYSTEM.PUT(LPC.FIO0SET, {6}); (* Set P0.6 high *)
ELSE
SYSTEM.PUT(LPC.FIO0CLR, {6}); (* Set P0.6 low *)
END
END ToggleCS;
PROCEDURE ToggleClock(high : BOOLEAN);
BEGIN
IF high THEN
SYSTEM.PUT(LPC.FIO0SET, {7}); (* Set P0.7 high *)
ELSE
SYSTEM.PUT(LPC.FIO0CLR, {7}); (* Set P0.7 low *)
END
END ToggleClock;
(* returns 1 or 0 for p0[8]=input data *)
PROCEDURE ReadDataBit() : INTEGER;
VAR
val : INTEGER;
BEGIN
IF SYSTEM.BIT(LPC.FIO0PIN, 8) THEN
val := 1
ELSE
val := 0
END;
RETURN val
END ReadDataBit;
(* out : FALSE means error, so value is not meaningful.
TRUE means ok, it looks like the TC is hooked up *)
PROCEDURE RawRead(VAR value : INTEGER) : BOOLEAN;
CONST
dly = 1000; (* unit= microseconds *)
VAR
i, v : INTEGER;
iserror : BOOLEAN;
BEGIN
(*
Initiate a temperature conversion. According to MAX's tech notes FAQ's
for the chip, Line going high initiates a conversion, which means, we
need to clock the chip low to high to initiate the conversion, then wait
for the conversion to be complete before trying to read the data from
the chip.
*)
ToggleCS(FALSE); (* start conversion *)
Timer.uSecDelay(2*dly); (* delay a bit *)
value := 0; i := 16;
WHILE i > 0 DO
DEC(i);
ToggleClock(FALSE); (* read data on falling edge *)
IF i IN {0,1,15} THEN (* Ignore these bits *)
v := ReadDataBit()
ELSIF i = 2 THEN (* is a TC connected? *)
iserror := ReadDataBit()=1
ELSE (* read the value-bit *)
value := LSL(value,1) + ReadDataBit();
END;
Timer.uSecDelay(dly); (* delay a bit *)
ToggleClock(TRUE); (* Reading on the falling edge of the clock *)
Timer.uSecDelay(dly) (* delay a bit *)
END;
ToggleCS(TRUE);
RETURN iserror
END RawRead;
(* Binary display of 12 lsb bits of value 'v' *)
PROCEDURE DumpBits(v : INTEGER);
VAR
idx : INTEGER;
sbits : SET;
BEGIN
sbits := SYSTEM.VAL(SET, v);
FOR idx := 11 TO 0 BY -1 DO
IF idx IN sbits THEN
Out.Char("1")
ELSE
Out.Char("0")
END
END;
Out.Ln;
END DumpBits;
PROCEDURE ReadTemp*() : REAL;
CONST
units = 1; (* Units to readout temp (0 = raw, 1 = °C, 2 = °F)*)
VAR
value : INTEGER;
temp : REAL;
BEGIN
IF ~RawRead(value) THEN
DumpBits(value);
(*
Keep in mind that the temp that was just read is on the digital scale
from 0°C to 1023.75°C at a resolution of 2^12. We now need to convert
to an actual readable temperature. Now multiply by 0.25. = divide by 4
2 = temp in deg F
1 = temp in deg C
0 = raw chip value 0-4095
*)
temp := FLT(value);
IF units = 2 THEN
temp := temp * 0.25 * 9.0 / 5.0 + 32.0
ELSIF units = 1 THEN
temp := temp * 0.25
(* else no further conversion needed *)
END;
ELSE
temp := -1.0
END;
(* Output negative if there is a TC error, otherwise return 'temp' *)
RETURN temp
END ReadTemp;
(* Configured for use/test with LPC2378-STK *)
PROCEDURE Init*;
VAR
mbits : SET;
BEGIN
(* MISO1 = P0[8] = input = reading data from MOD-TC
SCK1 = P0[7] = output = pseudo clock
SSEL = P0[6] = output = Select *)
SYSTEM.GET(LPC.SCS, mbits);
IF ~(0 IN mbits) THEN
SYSTEM.PUT(LPC.SCS, mbits +{0}); (* Although we're not in a hurry, select FastIO *)
END;
SYSTEM.GET(LPC.PINSEL0, mbits);
SYSTEM.PUT(LPC.PINSEL0, mbits - {12..17}); (* P0[6,7,8] = is GPIO*)
SYSTEM.GET(LPC.PINMODE0, mbits);
SYSTEM.PUT(LPC.PINMODE0, mbits + {13,15,17} - {12,14,16}); (* No pulls, already wired *)
SYSTEM.GET(LPC.FIO0DIR, mbits);
SYSTEM.PUT(LPC.FIO0DIR, mbits - {8} + {6,7}); (* P0[6,7] output, P0[8] = input *)
ToggleCS(TRUE); (* CS HIGH *)
ToggleClock(FALSE); (* Clock Low *)
END Init;
END MAX6675.
Creating a final demo program:
Code: Select all
MODULE DemoReader;
(*
Example using the MAX6675 Module.
*)
IMPORT MAX6675, Timer, Reals, Out, Main;
(* MAX6675 Module already sets pin modes for MAX6675 chip! *)
PROCEDURE run;
VAR
temperature : REAL; (* Temperature output variable *)
buf : ARRAY 10 OF CHAR;
BEGIN
Timer.Init(Timer.uSecs); (* Initialize and use microseconds as unit of delay *)
MAX6675.Init;
REPEAT
(* Read the temp from the MAX6675 *)
temperature := MAX6675.ReadTemp();
IF temperature < 0.0 THEN
(* If there is an error with the TC, temperature will be < 0 *)
Out.String("Thermocouple Error on CS")
ELSE
Out.String("Current Temperature=")
END;
Reals.RealToStrF(temperature, 5, buf);
Out.String(buf); Out.Ln;
(* Wait 15 seconds before reading again *)
Timer.uSecDelay(15000000)
UNTIL FALSE
END run;
BEGIN
run
END DemoReader.
- Apart from the module, you need to connect the thermocouple wire, which is an additional buy.
- Connect the thermocouple wire correct to get accurate results,
- Carefully arrange electricity , moisture and heat!
Cheers.