//-----------------------------------------------------------------------------
// Programm zum Messen der Luftfeuchte mit dem Sensor HH10D
// und zum Messen des Luftdrucks u. Temperatur mit HP03S
// Bearbeiter: S. Taborek
// Beginn: 23.12.2010
// Stand: 29.12.2010
//
// Prozessor: ATMEGA8L
// Interface: UART1
//
//-----------------------------------------------------------------------------
program AVR_HP03S_HH10D;
{ Declarations section }
var cnt_0 : word;
w_h : word;
b_h : byte;
str2 : string[2];
uart_cmd : byte;
//-----------------------
ctc_1 : longint;
humidity : real;
pressure : real;
temperature : real;
//----------------------
hh10d_sens : word; // ROM-Constante für HH10D
hh10d_offs : word; // ROM-Constante für HH10D
hp03s_C1 : word;
hp03s_C2 : word;
hp03s_C3 : word;
hp03s_C4 : word;
hp03s_C5 : word;
hp03s_C6 : word;
hp03s_C7 : word;
hp03s_A : byte;
hp03s_B : byte;
hp03s_C : byte;
hp03s_D : byte;
hp03s_Pressure : word;
hp03s_Temperat : word;
hh10d_mess : word;
//-----------------------
h_txt : string[15];
send_txt : string[90];
cnt2 : word;
const
ROM_Adr_HH10D : byte = 0xA2; //Moduladr. read
ROM_Adr_HP03S : byte = 0xA0;
ADC_HP03S : byte = 0xEE; // ROM write
{==============================================================================}
procedure Counter0_ISR; org IVT_ADDR_TIMER0_OVF;
{==============================================================================}
var h1, h2 : longint;
// Zähler an F_Out des Humidity-Sensors
// Es werden jeweils 32512 steigende Flanken gezählt und anschließend mit
// einer festen Frequenz verglichen. Das entspricht einer Messzeit von 3-7 sec.
begin
//TCNT0 := 0; // Überlauf bei 256
inc(cnt_0);
if (cnt_0 > 127) then begin // 127*256 = 32512
h2 := ctc_1;
ctc_1 := 0;
PORTD.6 := not PORTD.6;
h1 := (h2 * 10000);
h2 := h1 div 327869; // siehe CTC
h1 := (32512000 div h2); // Ergebnis in Hz / Genauigkeit +/- 2Hz
hh10d_mess := h1;
cnt_0 := 0;
end;
end;
{==============================================================================}
procedure Counter1_ISR; org IVT_ADDR_INT0;
{==============================================================================}
// angekoppelt an externen Takt von CTC1 (Frequenz: 31,3725 KHz)
begin
inc(ctc_1);
end;
{------------------------------------------------------------------------------}
procedure SetError_LED(_a: byte);
{------------------------------------------------------------------------------}
var i : byte;
begin
for i := 1 to _a do begin
PORTD.6 := not PORTD.6;
delay_ms(100);
end;
end;
{------------------------------------------------------------------------------}
function Read_ROMC(device_adr, b_adr: byte;): word;
{------------------------------------------------------------------------------}
// Read one word from EEPROM (like 24C02)
var bl, bh, bdu : byte;
begin
result := 0;
if TWI_Start() = 0 then begin
PORTD.6 := 0; // LED on
PORTD.7 := 0; // LED on
TWI_Write(device_adr+0); // Device-Adr für write
TWI_Write(b_adr); // Adresse des 1.Bytes
//nun lesen
TWI_Start();
TWI_Write(device_adr+1); // Device-Adr für read
bh := TWI_Read(1);
bl := TWI_Read(0);
TWI_Stop();
result := bh*256 + bl;
//
delay_ms(40);
PORTD.6 := 1; // LED off
PORTD.7 := 1;
end
else begin
SetError_LED(10);
end;
delay_ms(40);
end;
{------------------------------------------------------------------------------}
function Test_ROM_HP03S_Constants: byte;
{------------------------------------------------------------------------------}
begin
result := 0;
if (hp03s_C1 < 256) then result := 1;
if (hp03s_C2 > 8197) then result := 2;
if (hp03s_C3 > 3000) then result := 3;
if (hp03s_C4 > 4096) then result := 4;
if (hp03s_C5 < 4096) then result := 5;
if (hp03s_C6 > 16384) then result := 6;
if (hp03s_C7 < 2400) or (hp03s_C7 > 2600) then result := 7;
if (hp03s_A = 0) or (hp03s_A > 63) then result := 8;
if (hp03s_B = 0) or (hp03s_B > 63) then result := 9;
if (hp03s_C = 0) or (hp03s_C > 15) then result := 10;
if (hp03s_D = 0) or (hp03s_D > 15) then result := 11;
if result > 0 then begin // constants not real
SREG.7 := 0; // Interrupts disabled
// Fehleranzeige mittels vorhandener LED s
w_h := 2* result;
PORTD.6 := 0;
PORTD.7 := 0;
delay_ms(2500);
repeat
PORTD.6 := not PORTD.6;
PORTD.7 := not PORTD.7;
delay_ms(500);
dec(w_h);
until w_h = 0;
PORTD.6 := 1;
PORTD.7 := 1;
SREG.7 := 1; // Interrupts enabled
end;
end;
{------------------------------------------------------------------------------}
procedure Read_ROM_Constants_HH10D;
{------------------------------------------------------------------------------}
// Read ROM-Constants from HH10D
begin
hh10d_sens := Read_ROMC(ROM_Adr_HH10D, 0x10);
hh10d_offs := Read_ROMC(ROM_Adr_HH10D, 0x12);
delay_ms(100);
end;
{------------------------------------------------------------------------------}
function Read_ROM_Constants_HP03S: byte;
{------------------------------------------------------------------------------}
begin
result := 0;
hp03s_C1 := Read_ROMC(ROM_Adr_HP03S, 0x10);
hp03s_C2 := Read_ROMC(ROM_Adr_HP03S, 0x12);
hp03s_C3 := Read_ROMC(ROM_Adr_HP03S, 0x14);
hp03s_C4 := Read_ROMC(ROM_Adr_HP03S, 0x16);
hp03s_C5 := Read_ROMC(ROM_Adr_HP03S, 0x18);
hp03s_C6 := Read_ROMC(ROM_Adr_HP03S, 0x1A);
hp03s_C7 := Read_ROMC(ROM_Adr_HP03S, 0x1C);
// and now the 4 Byte-Constants:
w_h := Read_ROMC(ROM_Adr_HP03S, 0x1E);
hp03s_A := hi(w_h);
hp03s_B := lo(w_h);
w_h := Read_ROMC(ROM_Adr_HP03S, 0x20);
hp03s_C := hi(w_h);
hp03s_D := lo(w_h);
//------------------------------------------
result := Test_ROM_HP03S_Constants; // Test the limits of values
end;
{------------------------------------------------------------------------------}
function Read_ADC_HP03S(_selector: byte;): word;
{------------------------------------------------------------------------------}
var bl, bh, bdu : byte;
const Awrite = 0;
Aread = 1;
// _selector for one of the both values:
begin
result := 1;
PORTD.7 := 1;
PORTB.2 := 1; // set XCLR an HP03S hi
delay_ms(10);
if TWI_Start() = 0 then begin
PORTD.7 := 0; // LED on
TWI_Write(ADC_HP03S + Awrite); // Device-Adr für write
TWI_Write(0xFF); //
TWI_Write(_selector); // Pressure/Temperature selector
TWI_Stop();
delay_ms(60);
TWI_Start();
TWI_Write(ADC_HP03S + Awrite); // Device-Adr für write
TWI_Write(0xFD); //
//now read
TWI_Start();
TWI_Write(ADC_HP03S + Aread); // Device-Adr für read
bh := TWI_Read(1);
bl := TWI_Read(0);
TWI_Stop();
result := bh*256 + bl;
PORTD.7 := 1;
//
end
else begin
SetError_LED(7);
end;
PORTB.2 := 0; // set XCLR an HP03S lo
end;
{------------------------------------------------------------------------------}
procedure Compute_Humidity(var hum1: real);
{------------------------------------------------------------------------------}
var HC1 : real;
begin
HC1 := hh10d_offs;
HC1 := HC1 - hh10d_mess;
HC1 := HC1 * hh10d_sens ; //
hum1 := HC1 / 4096;
end;
{------------------------------------------------------------------------------}
function Compute_P_T(var _pr, _te : real): boolean;
{------------------------------------------------------------------------------}
// Berechnungen erfolgen im Bereich der real-Zahlen:
var HC1, HC2, HC3 : real;
h_pow : longint;
dUT, OFF, SENS, X : real;
i : byte;
begin
result := 0;
_pr := 0;
_te := 0;
//
// if Test_ROM_HP03S_Constants = 0 then begin
HC1 := hp03s_Temperat;
HC1 := HC1 - hp03s_C5;
HC2 := HC1 / 128;
dUT := HC1;
h_pow := 1;
h_pow := h_pow shl hp03s_C;
if (hp03s_temperat >= hp03s_C5) then begin
HC1 := (HC2 * HC2 * hp03s_A);
end
else begin
HC1 := (HC2 * HC2 * hp03s_B);
end;
HC2 := HC1 / h_pow;
dUT := dUT - HC2;
//-------------------
HC1 := hp03s_C4;
HC1 := HC1 - 1024;
HC1 := HC1 * dUT;
HC1 := HC1 / 16384;
HC1 := HC1 + hp03s_C2;
OFF := HC1 * 4;
//-------------------
HC1 := hp03s_C3;
HC1 := HC1 * dUT;
HC1 := HC1 / 1024;
SENS := HC1 + hp03s_C1;
//-------------------
HC1 := hp03s_pressure;
HC1 := HC1 - 7168;
HC1 := HC1 * SENS;
HC1 := HC1 / 16384;
X := HC1 - OFF;
//--------------------
HC1 := X * 10;
HC1 := HC1 / 32;
_pr := HC1 + hp03s_C7; // result
_pr := _pr / 10;
//--------------------
HC1 := hp03s_C6;
HC1 := HC1 * dUT;
HC1 := HC1 / 65536;
h_pow := 1;
h_pow := h_pow shl hp03s_D;
HC3 := dUT / h_pow;
_te := HC1 - HC3 + 250; // result
_te := _te / 10;
//---------------------------
result := 1;
// end;
end;
{------------------------------------------------------------------------------}
function SendDateStr(): boolean;
{------------------------------------------------------------------------------}
var cnt : byte;
begin
result := false;
send_txt := send_txt + # +#0; //delimiter
UART1_Write_Text(send_txt);
cnt := 0;
repeat
inc(cnt);
if (UART1_Data_Ready() = 1) then begin
if (UART1_Read() = 0xA0) then result := true;
end;
delay_ms(1);
until (result = true)or(cnt > 25) ;
end;
{------------------------------------------------------------------------------}
procedure MCU_Init;
{------------------------------------------------------------------------------}
begin
TWI_Init(100000);
UART1_Init(9600);
// Initialisierung des Timer1 als Freuenzgenerator:
DDRB := DDRB or %00000010; // B1 = OC1A out
TCCR1A := %01000000; // Port B1 toggeln
TCCR1B := %00001001; // Timer1-Reset bei compare, no prescaling
OCR1AH := 0;
OCR1AL := 244; // 16000000/2/244 = 32,7869 KHz
//Initialisierung der LED-Ausgaben:
DDRD := DDRD or %11000000; // D7 = gn LED D6 = ye LED
//Initialisierung des XCLR-Ausgangs für HP03S-PIN:
DDRB := DDRB or %00000100; // B2 low für ROM-read sonst hight
PORTB.2 := 0; // XCLR an HP03S low
// Initialisierung für DCF-PON
DDRC := DDRC or %00000001; // C0 low = DCF on
PORTB.2 := 1; // DCF on
//Initialisierung des Timer0 als Counter:
DDRD := DDRD and %11101111; // D4 = XCK/T0 Eingang
PortD.4 := 1; // PullUp für D4 aktiv
TCCR0 := %00000110; // External clock on T0 pin falling edge.
TIMSK.TOIE0 := 1; // Timer0-Overflow ISR aktiv
TCNT0 := 0; // Counter0 voreinstellen
//Initialisierung des externen Interrupts an PIND2
DDRD := DDRD and %11111011; // D2 ist input <-- B1
PortD := PortD or %00000100; // PullUp für D2 aktiv
GICR := GICR or %01000000; // Int0 erlaubt
MCUCR := MCUCR or %00000010; // Int0 löst bei fallender Flanke aus
SREG.7 := 1; // Interrupts enabled
//------------------------------------------------------------------
PORTD.6 := 1;
PORTD.7 := 0;
end;
{==============================================================================}
begin
{ Main program ATMEGA8L}
MCU_Init;
//------------------------------------------------------------------
Read_ROM_Constants_HH10D;
//------------------------------------------------------------------
Read_ROM_Constants_HP03S;
//------------------------------------------------------------------
cnt2 := 250;
while true do begin
if (UART1_Data_Ready() = 1) then begin // stand by for request
uart_cmd := UART1_Read();
if (uart_cmd = 0xA1) then begin
Compute_Humidity(humidity);
FloatToStr(huminity, h_txt);
h_txt[5] := 0;
Send_txt := + h_txt + %/ ;
FloatToStr(temperature, h_txt);
if temperature > 0 then begin
h_txt[5] := 0;
str2 := ;
end
else begin
h_txt[6] := 0;
str2 := ;
end;
Send_txt := send_txt + str2 + h_txt + C/ ;
FloatToStr(pressure, h_txt);
if pressure < 1000 then begin
h_txt[6] := 0;
str2 := ;
end
else begin
h_txt[7] := 0;
str2 := ;
end;
Send_txt := send_txt + str2 + h_txt + p / / ;
//--- raw-values:
WordToStr(hh10d_mess, h_txt);
send_txt := send_txt + Hum + h_txt + / ;
WordToStr(hp03s_temperat, h_txt);
send_txt := send_txt + Tem + h_txt + / ;
WordToStr(hp03s_pressure, h_txt);
send_txt := send_txt + Pre + h_txt;
SendDateStr();
end;
//
if (uart_cmd = 0xA9) then begin // send HH10D-ROM-Constants
WordToStr(hp03s_C1, h_txt);
send_txt := h_txt + / ;
WordToStr(hp03s_C2, h_txt);
send_txt := send_txt + h_txt + / ;
WordToStr(hp03s_C3, h_txt);
send_txt := send_txt + h_txt + / ;
WordToStr(hp03s_C4, h_txt);
send_txt := send_txt + h_txt + / ;
WordToStr(hp03s_C5, h_txt);
send_txt := send_txt + h_txt + / ;
WordToStr(hp03s_C6, h_txt);
send_txt := send_txt + h_txt + / ;
WordToStr(hp03s_C7, h_txt);
send_txt := send_txt + h_txt;
if not SendDateStr() then begin // sendet send_txt
end;
end;
if (uart_cmd = 0xAA) then begin // send HH10D-ROM-Constants
ByteToStr(hp03s_A, h_txt);
send_txt := h_txt;
ByteToStr(hp03s_B, h_txt);
send_txt := send_txt + h_txt;
ByteToStr(hp03s_C, h_txt);
send_txt := send_txt + h_txt;
ByteToStr(hp03s_D, h_txt);
send_txt := send_txt + h_txt + / / ;
WordToStr(hh10d_offs, h_txt);
send_txt := send_txt + h_txt + / ;
WordToStr(hh10d_sens, h_txt);
send_txt := send_txt + h_txt;
if not SendDateStr() then begin // send send_txt
end;
end;
end;
//-------------------------------------------------
delay_ms(25);
PORTD.7 := not PORTD.7; // gn LED
inc(cnt2);
if cnt2 > 250 then begin // cyclic computing
cnt2 := 0;
hp03s_Pressure := Read_ADC_HP03S(0xF0);
hp03s_Temperat := Read_ADC_HP03S(0xE8);
Compute_P_T(pressure, temperature);
end;
end;
end.