Weather Station
History
This project is one of many others I had made to control my house
with rules, web interface, logger and many more. This one is a
weather station that reports almost anything about the external
environment. I bought mechanical part of the wind sensor at
http://www.aag.com.mx/indexaag.html
I had to remove all the electronics that came with it and replace
them with my own. The lightning detector is very simple but it
works very well if you have a REAL ground, not your ground of your
electronic part, and don't worry about the 9v battery, after 2 years
it is still working. The humidity and temperature sensors are the
same ones I had used in the barometer project. I drilled a 3cm hole
in 5 soup bowls, mounted upside down. The top and bottom soup bowl
doesn't have holes. The sensors are place in the middle of those and
this way the sensors are protected from sun heat and the air could
pass through. The light sensor is done with a simple LDR and that
does a good job to tell my house to go into night mode. Rain fall
sensor is a simple tipping bucket that gives pulse to the MCU and
with a simple formula you can know how many millimeter of rain fell.
Features
|
|
All direct digital reading |
|
|
Temperature |
|
|
Humidity |
|
|
Light |
|
|
Lightning |
|
|
Humidex |
|
|
Wind chill |
|
|
Wind speed |
|
|
Wind speed max in the last hour |
|
|
Wind direction |
|
|
Rain fall |
Pictures
Click to enlarge
|
The weather station |
Lightning detector |
Wind speed & direction sensor |
|
Rain fall sensor |
Sun sheild tempereture/humidity sensor |
PCB in the wind sensor who manage all |
Sources codes & Schematics
-Schematic of the MCU Board in PDF format
-Schematic of the lightning detector in PDF format
//*****************************************************************************
// NetWind
// Version 10.0 Nov 2005
//
// 10.0 -> New code for 9bit protocol
//
// Sylvain Bissonnette
//*****************************************************************************
// Editor : UltraEdit32
//*****************************************************************************
//
//
R E T U R N S T A C K 6 4
//
X T A L 8 MHZ
//
BootLoader of 1024 word
//
//*****************************************************************************
//
//
F U S E B I T
//
//( )7 ( )6
(X)BL12 (X)BL11 ( )BL02 ( )BL01
( )Lock2 ( )Lock1
//( )7 ( )6
( ) ( ) ( )
( )M103C ( )WDTON ( )
//( )RSTDIS ( )WDON (X)SPIEN(X)CKOPT
(X)EESAVE ( )BOOTSZ1 (X)BOOTSZ0 (X)BOOTRST
//(X)BODLEV (X)BODEN ( )SUT1 ( )SUT0
( )CKSEL3 ( )CKSEL2 ( )CKSEL1 ( )CKSEL0
//
//*****************************************************************************
//
P I N U S A G E
//
// PA0 -> Wind Direction S
0 deg
// PA1 -> Wind Direction SE 45
deg
// PA2 -> Wind Direction E
90 deg
// PA3 -> Wind Direction NE 135
deg
// PA4 -> Wind Direction N
180 deg
// PA5 -> Wind Direction NO 225
deg
// PA6 -> Wind Direction O
270 deg
// PA7 -> Wind Direction SO 315
deg
//
// PB0 -> n/c
// PB1 -> n/c
// PB2 -> n/c
// PB3 -> n/c
// PB4 -> Light Sensor
// PB5 -> HUMIDITY_DATA
// PB6 -> HUMIDITY_SCK
// PB7 -> n/c
//
// PC0 -> n/c
// PC1 -> n/c
// PC2 -> n/c
// PC3 -> n/c
// PC4 -> n/c
// PC5 -> n/c
// PC6 -> n/c
// PC7 -> n/c
//
// PD0 -> Wind Speed
// PD1 -> RS485 TXE
// PD2 -> RS485 RX
// PD3 -> RS485 TX
// PD4 -> Wind Speed
// PD5 -> n/c
// PD6 -> n/c
// PD7 -> n/c
//
// PE0 -> n/c
// PE1 -> n/c
// PE2 -> n/c
// PE3 -> n/c
// PE4 -> n/c
// PE5 -> LED Monitor
// PE6 -> Lightning Sensor
// PE7 -> Rain Tip Sensor
//
// PF0 -> Light Sensor
// PF1 -> n/c
// PF2 -> n/c
// PF3 -> n/c
// PF4 -> n/c
// PF5 -> n/c
// PF6 -> n/c
// PF7 -> n/c
//
// PG0 -> n/c
// PG1 -> n/c
// PG2 -> n/c
// PG3 -> n/c
// PG4 -> n/c
//
//*****************************************************************************
//
T I M E R U S A G E
//
// Timer 0 is use by real time clock
// Timer 1 not use
// Timer 2 is use by TaskManager
// Timer 3 not use
//
//*****************************************************************************
// NetWork Function
//-----------------------------------------------------------------------------
// Command
// 0xff
-> Get 16 bit software version
// 0xf5,0x55,0xaa -> Reset MCU
// 0xf0,0x55,L,V -> Write eeprom at L
value V
// 0xf1,0x55,L -> Read
eeprom at L
// 0x20
-> Get 16 bit Temperature * 10
// 0x21
-> Get 16 bit Humidity * 10
// 0x22
-> Get 16 bit Wind Speed * 10
// 0x23
-> Get 16 bit Wind Speed Max * 10
// 0x24
-> Get 16 bit Rain Day * 10
// 0x25
-> Get 16 bit Rain HRS * 10
// 0x26
-> Get 16 bit Lightning Day * 10
// 0x27
-> Get 16 bit Lightning HRS * 10
// 0x28
-> Get 16 bit Wind Chill * 10
// 0x29
-> Get 16 bit Humidex * 10
// 0x2a
-> Get 16 bit Light * 10
// 0x2b
-> Get 16 bit Night * 10
// 0x2c
-> Get 16 bit Wind Dir * 10
// 0x60
-> Setup time at 0H00
//-----------------------------------------------------------------------------
// EEprom
// 00 -> Not for
use
// 01 -> Node
Address
// 02 -> Night Trig
// 03 -> Day Trig
// 04 -> Wind Dir
Ref
// 05@09 -> Free
// 10 -> Tip Qte
float
// 11 -> Tip Qte
float
// 12 -> Tip Qte
float
// 13 -> Tip Qte
float
// 14 -> Tip Qte
float
// 15 -> Tip Qte
float
// 16 -> Tip Qte
float
// 17 -> Tip Qte
float
// 18 -> Tip Qte
float
// 19 -> Tip Qte
float
// 20@xx -> Free
//*****************************************************************************
//
// Rain Tip = 0.18868
//
//*****************************************************************************
//
I N C L U D E
//*****************************************************************************
#include <iom64v.h>
#include <shortnametype.h>
#include <macros.h>
#include <stdlib.h>
#include <eeprom.h>
#include <math.h>
#include "TaskManager.h"
//*****************************************************************************
//
D E F I N E
//*****************************************************************************
#define VERSION
100
#define DEVICE
1280
#define TRUE
1
#define FALSE
0
#define XTAL
16000000
#define ACK
1
#define noACK
0
#define HUMIDITY_DDR
DDRB
#define HUMIDITY_PIN
PINB
#define HUMIDITY_PORT
PORTB
#define HUMIDITY_DATA
0x20
#define HUMIDITY_SCK
0x40
//adr command r/w
#define HUMIDITY_STATUS_REG_W 0x06
//000 0011
0
#define HUMIDITY_STATUS_REG_R 0x07
//000 0011
1
#define HUMIDITY_MEASURE_TEMP 0x03
//000 0001
1
#define HUMIDITY_MEASURE_HUMI 0x05
//000 0010
1
#define HUMIDITY_RESET
0x1e //000
1111 0
#define WIND_DDR
DDRA
#define WIND_PIN
PINA
#define WIND_PORT
PORTA
#define LED
0x20
#define NET_DDR
DDRD
#define NET_PIN
PIND
#define NET_PORT
PORTD
#define NET_RX
0x04
#define NET_TX
0x08
#define NET_TXE
0x02
#define NET_UBRRH
UBRR1H
#define NET_UBRRL
UBRR1L
#define NET_UCSRA
UCSR1A
#define NET_UCSRB
UCSR1B
#define NET_UCSRC
UCSR1C
#define NET_UDR
UDR1
#define NET_RXBUFFER
10
#define NET_TXBUFFER
10
#define NET_GET_ADDRESS
200
#define NET_SPEED
19200
#define BROADCASTDEVTYPE
0xf1
#define BROADCAST
0xff
#define TIPQTE
10
#define NIGHT
2
#define DAY
3
#define WINDREF
4
//*****************************************************************************
//
P R O T O T Y P E
//*****************************************************************************
void main(void);
void _StackOverflowed(char
c);
float CalcWindChill(float
Temperature,float WindSpeedMax);
float CalcHumidex(float
Temperature,float Humidity);
void Timer0Ovf(void);
void Int0(void);
void Int6(void);
void Int7(void);
void ADC_interrupt(void);
void HumidityInit(void);
void HumidityDelay(void);
void HumidityWriteByte(ushort
value);
ushort HumidityReadByte(ushort ack);
void HumidityTransStart(void);
void HumidityConnectionReset(void);
void HumiditySoftReset(void);
ushort HumidityReadStatus(void);
void HumidityWriteStatus(ushort
value);
uint HumidityMeasure(ushort mode);
void HumidityCalc(float
*p_humidity ,float *p_temperature);
void HumidityGet(float
*p_humidity ,float *p_temperature);
void NetInit(void);
void NetRxChar(void);
void NetAnalyseData(void);
void NetWrite(int
Value);
void NetTxByte(void);
void NetTxFinish(void);
void NetGetAddress(void);
//*****************************************************************************
//
G L O B A L V A R I A B L E
//*****************************************************************************
ushort NetAddress;
ushort NetRxData[NET_RXBUFFER];
ushort NetTxData[NET_TXBUFFER];
ushort *NetTxPtr;
short NetTxQte;
short NetBroadCast
= FALSE;
char TipQteStr[10];
float TipQte;
char WindRef;
ushort HumiError = FALSE;
uint Revolution,RevolutionMax,RainTip,LightningStrike;
ushort BounceInt6,BounceInt7;
ushort DayTrig,NightTrig;
float Temperature,
Humidity,
WindSpeed,
WindSpeedMax,
RainDay,
RainHRS,
WindChill,
Humidex,
Light,
Night;
uint TemperatureInt,
HumidityInt,
WindSpeedInt,
WindSpeedMaxInt,
RainDayInt,
RainHRSInt,
LightningDay,
LightningHRS,
LightningDayInt,
LightningHRSInt,
WindChillInt,
HumidexInt,
LightInt,
NightInt,
WindDirInt;
float WindSpeedHRSTable[12]
= {0,0,0,0,0,0,0,0,0,0,0,0};
float RainHRSTable[12]
= {0,0,0,0,0,0,0,0,0,0,0,0};
int LightningHRSTable[12]
= {0,0,0,0,0,0,0,0,0,0,0,0};
uint WindDir = 0;
typedef struct
{
ushort Second;
ushort Minute;
ushort Hour;
} TimeStruct;
TimeStruct Time;
//*****************************************************************************
//
M A I N
//*****************************************************************************
void main()
{
int i,j;
float Tmp;
int Quarter;
//Timer0 is real time clock
ASSR |= (1<<AS0);
//set async mode
TCCR0 = 0x05;
//start timer / 128
while ( ASSR &
0x07 ) WDR();
// Wait for Asynch mode
TIMSK |= (1<<TOIE0);
// Timer 1
// Not use
// Timer 2
// Use by TaskManager
// Timer 3
// Not use
// Port A
WIND_DDR = 0x00;
// PortA as input for wind direction
WIND_PORT = 0xff;
// Pull-up on PortA
// Port B
DDRB = 0x00;
// PortB as input
PORTB = 0xef;
// Pull-up on NC pin
// Port C
DDRC = 0x00;
// PortC as input NC
PORTC = 0xff;
// Pull-up on PortC
// Port D
DDRD = 0x00;
// PortD as input
PORTD = 0xff;
// Pull-up on PortD
// Port E
DDRE = 0x20;
// PORTE 5 as output for led, all other are
input
PORTE = 0xff;
// Led off and pullup for all other input
// PE6&7 are input for interrupt lightning and
rain
// Port F
DDRF = 0x00;
// PortF as input
PORTF = 0xfe;
// Pull-up on NC pin
// ADC
ADMUX = (1<<REFS0);
// select input 0 with REF at VCC with
external cap
TaskInit();
NetInit();
HumidityInit();
// External Int
EICRA |= (1<<ISC01);
// Falling edge on int 0
EICRB |= (1<<ISC61);
// Falling edge on int 6
EICRB |= (1<<ISC71);
// Falling edge on int 7
EIMSK |= (1<<INT7)+(1<<INT6)+(1<<INT0);
// Enable Int0,6,7
SEI();
// WatchDog
WDR();
WDTCR = 0x0f;
// Enable WatchDog at 2.2 sec
while (1)
{
PORTE ^= LED;
WDR();
_StackCheck();
NetGetAddress();
NightTrig = EEPROMread(NIGHT);
DayTrig = EEPROMread(DAY);
WindRef = EEPROMread(WINDREF);
EEPROMReadBytes(TIPQTE,&TipQteStr[0],10);
TipQte = atof(&TipQteStr[0]);
if (HumiError
== TRUE)
HumidityInit();
HumidityGet(&Humidity,&Temperature);
WDR();
// Wind Speed
WindSpeed = (float)(1.974
* RevolutionMax);
//(float)(3.9477 * RevolutionMax) / 2;
WDR();
// Wind Speed Max Hour
Quarter = Time.Minute
/ 5;
if (Quarter
< 11)
WindSpeedHRSTable[Quarter+1]
= 0;
else WindSpeedHRSTable[0]=
0;
if (WindSpeed
> WindSpeedHRSTable[Quarter])
WindSpeedHRSTable[Quarter]
= WindSpeed;
Tmp = 0;
for (i=0;i<12;i++)
if (Tmp <
WindSpeedHRSTable[i])
Tmp = WindSpeedHRSTable[i];
WindSpeedMax = Tmp;
WDR();
// Rain HRS
if (Quarter
< 11)
RainHRSTable[Quarter+1]
= 0;
else RainHRSTable[0]=
0;
RainHRSTable[Quarter]
+= RainTip;
Tmp = 0;
for (i=0;i<12;i++)
Tmp += RainHRSTable[i];
Tmp = Tmp
* TipQte;
RainHRS = Tmp;
WDR();
// Rain Day
RainDay += RainTip
* TipQte;
RainTip =
0;
WDR();
// Lightning HRS
if (Quarter
< 11)
LightningHRSTable[Quarter+1]
= 0;
else LightningHRSTable[0]=
0;
LightningHRSTable[Quarter]
+= LightningStrike;
j = 0;
for (i=0;i<12;i++)
j += LightningHRSTable[i];
LightningHRS = j;
WDR();
// Lightning Day
LightningDay += LightningStrike;
LightningStrike =
0;
WDR();
if (WIND_PIN
== ~0x01)
WindDir = 0;
if (WIND_PIN
== ~0x03)
WindDir = 225;
if (WIND_PIN
== ~0x02)
WindDir = 450;
if (WIND_PIN
== ~0x06)
WindDir = 675;
if (WIND_PIN
== ~0x04)
WindDir = 900;
if (WIND_PIN
== ~0x0c)
WindDir = 1125;
if (WIND_PIN
== ~0x08)
WindDir = 1350;
if (WIND_PIN
== ~0x18)
WindDir = 1575;
if (WIND_PIN
== ~0x10)
WindDir = 1800;
if (WIND_PIN
== ~0x30)
WindDir = 2025;
if (WIND_PIN
== ~0x20)
WindDir = 2250;
if (WIND_PIN
== ~0x60)
WindDir = 2475;
if (WIND_PIN
== ~0x40)
WindDir = 2700;
if (WIND_PIN
== ~0xc0)
WindDir = 2925;
if (WIND_PIN
== ~0x80)
WindDir = 3150;
if (WIND_PIN
== ~0x81)
WindDir = 3375;
WindDir += (WindRef*225);
if (WindDir
>= 3600)
WindDir = WindDir
- 3600;
WDR();
// Light
if (Light
> 100)
Light = 100;
WDR();
// Night
// Wind Chill
WindChill = CalcWindChill(Temperature,WindSpeedMax);
if (WindChill
> Temperature)
WindChill = Temperature;
WDR();
// Humidex
Humidex = CalcHumidex(Temperature,Humidity);
if (Humidex
< Temperature)
Humidex = Temperature;
WDR();
HumidityInt = Humidity
* 10;
WDR();
TemperatureInt = Temperature
* 10;
WDR();
WindSpeedInt = WindSpeed
* 10;
WDR();
WindSpeedMaxInt = WindSpeedMax
* 10;
WDR();
RainDayInt = RainDay
* 10;
WDR();
RainHRSInt = RainHRS
* 10;
WDR();
LightningDayInt = LightningDay
* 10;
WDR();
LightningHRSInt = LightningHRS
* 10;
WDR();
WindChillInt = WindChill
* 10;
WDR();
HumidexInt = Humidex
* 10;
WDR();
WindDirInt = WindDir;
WDR();
LightInt = Light
* 10;
if (Light
< NightTrig)
NightInt = 10;
if (Light
> DayTrig)
NightInt = 0;
WDR();
}
}
/******************************************************************************
Name:
void _StackOverflowed(char c)
Description: This function is
automaticaly called if
the stack crash, PE5 will be clear.
Input:
none
Output:
PE5
Misc:
******************************************************************************/
void _StackOverflowed(char
c)
{
CLI();
while(1);
}
/******************************************************************************
Name:
float CalcWindChill(float Temperature,float WindSpeedMax)
Description: Calculate wind chill
factor
Input:
float Temperature
float WindSpeedMax
Output:
float WindChill
Misc:
******************************************************************************/
float CalcWindChill(float
Temperature,float WindSpeedMax)
{
float WindChill,fTemp1,fTemp2;
if ((WindSpeedMax
> 0)
&& (WindSpeedMax <
100))
{
// WindChill = 13.12 + (0.6215 *
Temperature) - (11.37 * (pow(WindSpeedMax,0.16))) + (0.3965 *
Temperature * (pow(WindSpeedMax,0.16)));
fTemp1 = 0.3965
* Temperature * (pow(WindSpeedMax,0.16));
WDR();
fTemp2 = 11.37
* (pow(WindSpeedMax,0.16));
WDR();
WindChill =
0.6215 * Temperature;
WindChill +=
13.12;
WindChill -= fTemp2;
WindChill += fTemp1;
}
else WindChill
= Temperature;
return WindChill;
}
/******************************************************************************
Name:
float CalcHumidex(float Temperature,float Humidity)
Description: Calculate wind chill
factor
Input:
float Temperature
float Humidity
Output:
float Humidex
Misc:
******************************************************************************/
float CalcHumidex(float
Temperature,float Humidity)
{
float Humidex,TempK,DewK,e,h;
WDR();
TempK = Temperature +
273.15;
WDR();
DewK = (TempK / ((-0.0001846
* log(Humidity
/ 100)
* TempK) +
1.0));
WDR();
e = 6.11
* exp(5417.7530
* ((1
/ 273.16)
- (1 /
DewK)));
WDR();
h = (0.5555)
* (e -
10.0);
WDR();
Humidex = Temperature
+ h;
WDR();
return Humidex;
}
/******************************************************************************
Name:
void Timer0Ovf(void)
Description: This function is
automaticaly each second
Input:
none
Output:
none
Misc:
Drived by 32k xtal
******************************************************************************/
#pragma interrupt_handler Timer0Ovf:17
void Timer0Ovf(void)
{
if (++Time.Second
== 60)
{
Time.Second
= 0;
if (++Time.Minute
== 60)
{
Time.Minute
= 0;
if (++Time.Hour
== 24)
{
Time.Hour
= 0;
RainDay =
0;
LightningDayInt
= 0;
}
}
}
if (BounceInt6
!= 0)
{
BounceInt6--;
if (BounceInt6
== 0)
{
EIFR |= (1<<INTF6);
EIMSK |= (1<<INT6);
}
}
if (BounceInt7
!= 0)
{
BounceInt7--;
if (BounceInt7
== 0)
{
EIFR |= (1<<INTF7);
EIMSK |= (1<<INT7);
}
}
//if (RevolutionMax < Revolution) RevolutionMax
= Revolution;
//Revolution = 0;
RevolutionMax = Revolution;
Revolution = 0;
ADCSRA = 0xdf;
// Start AD convertion
}
/******************************************************************************
Name:
void Int0(void)
Description: This function is
automaticaly 2 time each wind speed
revolution
Input:
none
Output:
none
Misc:
******************************************************************************/
#pragma interrupt_handler Int0:2
void Int0(void)
{
Revolution++;
}
/******************************************************************************
Name:
void Int6(void)
Description: This function is
automaticaly called when lightning strike
Input:
none
Output:
none
Misc:
******************************************************************************/
#pragma interrupt_handler Int6:8
void Int6(void)
{
EIMSK &= ~(1<<INT6);
// Disable int 6 for 2 second
BounceInt6 = 2;
LightningStrike++;
}
/******************************************************************************
Name:
void Int7(void)
Description: This function is
automaticaly called when cup tip
Input:
none
Output:
none
Misc:
******************************************************************************/
#pragma interrupt_handler Int7:9
void Int7(void)
{
EIMSK &= ~(1<<INT7);
// Disable int 7 for 2 second
BounceInt7 = 2;
RainTip++;
}
/******************************************************************************
Name:
void ADC_interrupt(void)
Description: This function is
automaticaly called by the ADC interrupt
and read light value
Input:
none
Output:
none
Misc:
Setup value LightInt & NightInt
******************************************************************************/
#pragma interrupt_handler ADC_interrupt:22
void ADC_interrupt(void)
{
uint LightRaw;
float Tmp;
LightRaw = ADCL;
LightRaw |= (int)ADCH
<< 8;
// Sensor Max Output = Vcc - 1.15
Tmp = LightRaw;
Light = ((Tmp /
788) *
100);
}
//*****************************************************************************
// H U M I D I T Y
& T E M P F U N C T I O N
//*****************************************************************************
/******************************************************************************
Name:
void HumidityDelay(void)
Description: Delay for SCLK
Input:
none
Output:
none
Misc:
******************************************************************************/
void HumidityDelay(void)
{
int i;
for (i=0;i<(XTAL/400000);i++)
WDR();
}
/******************************************************************************
Name:
void HumidityInit(void)
Description: Initialise port and
constant used by
the Humidity & Temp hardware
Input:
none
Output:
none
Misc:
******************************************************************************/
void HumidityInit(void)
{
HUMIDITY_DDR |= HUMIDITY_DATA
+ HUMIDITY_SCK;
HUMIDITY_PORT |= HUMIDITY_DATA
+ HUMIDITY_SCK;
HumiditySoftReset();
}
/******************************************************************************
Name:
ushort HumidityWriteByte(ushort value)
Description: writes a byte on the
Sensibus and
checks the acknowledge
Input:
ushort value -> byte to write
Output:
none
Misc:
If the device don't ACK set HumiError to TRUE;
******************************************************************************/
void HumidityWriteByte(ushort
value)
{
ushort i;
HUMIDITY_DDR |= HUMIDITY_DATA;
//DATA-line in output
for (i=0x80;i>0;i/=2)
//shift bit for masking
{
HumidityDelay();
if (i
& value)
HUMIDITY_PORT |= HUMIDITY_DATA;
else HUMIDITY_PORT
&= ~HUMIDITY_DATA;
HumidityDelay();
HUMIDITY_PORT |= HUMIDITY_SCK;
HumidityDelay();
HUMIDITY_PORT &= ~HUMIDITY_SCK;
}
HUMIDITY_PORT |= HUMIDITY_DATA;
//release DATA-line
HUMIDITY_DDR &= ~HUMIDITY_DATA;
//DATA-line in input
HumidityDelay();
HUMIDITY_PORT |= HUMIDITY_SCK;
//clk #9 for ack
HumidityDelay();
if (HUMIDITY_PIN
& HUMIDITY_DATA)
HumiError = TRUE;
HUMIDITY_PORT &= ~HUMIDITY_SCK;
HumidityDelay();
}
/******************************************************************************
Name:
ushort HumidityReadByte(ushort ack)
Description: reads a byte form the
Sensibus and gives
an acknowledge in case of "ack=1"
Input:
ushort ack -> ack status
Output:
ushort value readed
Misc:
******************************************************************************/
ushort HumidityReadByte(ushort ack)
{
ushort i,val=0;
HUMIDITY_PORT |= HUMIDITY_DATA;
//release DATA-line
HUMIDITY_DDR &= ~HUMIDITY_DATA;
//DATA-line in input
for (i=0x80;i>0;i/=2)
//shift bit for masking
{
HumidityDelay();
HUMIDITY_PORT |= HUMIDITY_SCK;
//clk for SENSI-BUS
HumidityDelay();
if (HUMIDITY_PIN
& HUMIDITY_DATA)
val=(val |
i);
//read bit
HUMIDITY_PORT &= ~HUMIDITY_SCK;
}
if (ack ==
1)
{
HUMIDITY_DDR |=
HUMIDITY_DATA;
//DATA-line in output
HUMIDITY_PORT &= ~HUMIDITY_DATA;
//"ack==1" pull down DATA-Line
HumidityDelay();
HUMIDITY_PORT |= HUMIDITY_SCK;
HumidityDelay();
HUMIDITY_PORT &= ~HUMIDITY_SCK;
}
else
{
HumidityDelay();
HUMIDITY_PORT |= HUMIDITY_SCK;
HumidityDelay();
HUMIDITY_PORT &= ~HUMIDITY_SCK;
}
return val;
}
/******************************************************************************
Name:
ushort HumidityTransStart(void)
Description: Generates a transmission
start
Input:
none
Output:
none
Misc:
_____
________
DATA:
|_______|
___ ___
SCK : ___| |___|
|______
******************************************************************************/
void HumidityTransStart(void)
{
HUMIDITY_DDR |= HUMIDITY_DATA;
//DATA-line in output
HUMIDITY_PORT |= HUMIDITY_DATA;
//DATA=1
HUMIDITY_PORT &= ~HUMIDITY_SCK;
//SCK=0
HumidityDelay();
HUMIDITY_PORT |= HUMIDITY_SCK;
//SCK=1
HumidityDelay();
HUMIDITY_PORT &= ~HUMIDITY_DATA;
//DATA=0
HumidityDelay();
HUMIDITY_PORT &= ~HUMIDITY_SCK;
//SCK=0
HumidityDelay();
HUMIDITY_PORT |= HUMIDITY_SCK;
//SCK=1
HumidityDelay();
HUMIDITY_PORT |= HUMIDITY_DATA;
//DATA=1
HumidityDelay();
HUMIDITY_PORT &= ~HUMIDITY_SCK;
//SCK=0
HumidityDelay();
}
/******************************************************************************
Name:
void HumidityConnectionReset(void)
Description: communication Reset:
DATA-line=1 and at
least 9 SCK cycles followed by transstart
Input:
none
Output:
none
Misc:
_____________________________________________________
________
DATA:
|_______|
_ _ _ _
_ _ _ _
_ ___
___
SCK : __| |__| |__| |__| |__| |__| |__|
|__| |__| |______| |___| |______
******************************************************************************/
void HumidityConnectionReset(void)
{
ushort i;
HUMIDITY_DDR |= HUMIDITY_DATA;
//DATA-line in output
HUMIDITY_PORT |= HUMIDITY_DATA;
//DATA=1
HUMIDITY_PORT &= ~HUMIDITY_SCK;
//SCK=0
for (i=0;i<9;i++)
//9 SCK cycles
{
HumidityDelay();
HUMIDITY_PORT |= HUMIDITY_SCK;
//SCK=1
HumidityDelay();
HUMIDITY_PORT &= ~HUMIDITY_SCK;
//SCK=0
}
HumidityTransStart();
//transmission start
HumiError = FALSE;
}
/******************************************************************************
Name:
void HumiditySoftReset(void)
Description: Resets the sensor by a
softReset
Input:
none
Output:
none
Misc:
******************************************************************************/
void HumiditySoftReset(void)
{
int i;
HumidityConnectionReset();
//Reset communication
HumidityWriteByte(HUMIDITY_RESET);
//send Reset-command to sensor
for (i=0;i<100;i++)
HumidityDelay();
// 11ms delay
}
/******************************************************************************
Name:
ushort HumidityReadStatus(void)
Description: reads the status
register with checksum (8-bit)
Input:
none
Output:
ushort status byte
Misc:
******************************************************************************/
ushort HumidityReadStatus(void)
{
ushort value;
HumidityTransStart();
//transmission start
HumidityWriteByte(HUMIDITY_STATUS_REG_R);
//send command to sensor
value = HumidityReadByte(ACK);
//read status register (8-bit)
HumidityReadByte(noACK);
//dummy read checksum (8-bit)
return value;
}
/******************************************************************************
Name:
void HumidityWriteStatus(ushort value)
Description: writes the status
register with checksum (8-bit)
Input:
ushort value to write in the status register
Output:
none
Misc:
******************************************************************************/
void HumidityWriteStatus(ushort
value)
{
HumidityTransStart();
//transmission start
HumidityWriteByte(HUMIDITY_STATUS_REG_W);
//send command to sensor
HumidityWriteByte(value);
//send value of status register
}
/******************************************************************************
Name:
uint HumidityMeasure(ushort mode)
Description: makes a measurement
(humidity/temperature)
Input:
mode -> HUMI or TEMP
Output:
unsinged int Value mesured
Misc:
******************************************************************************/
uint HumidityMeasure(ushort mode)
{
ushort msb,lsb;
uint i,j;
HumidityTransStart();
//transmission start
switch (mode)
//send command to sensor
{
case
HUMIDITY_MEASURE_TEMP :
HumidityWriteByte(HUMIDITY_MEASURE_TEMP);
break;
case
HUMIDITY_MEASURE_HUMI :
HumidityWriteByte(HUMIDITY_MEASURE_HUMI);
break;
default
: break;
}
HUMIDITY_PORT |= HUMIDITY_DATA;
//release DATA-line
HUMIDITY_DDR &= ~HUMIDITY_DATA;
//DATA-line in input
for (i=0;i<=65530;i++)
{
for (j=0;j<10;j++)
WDR();
if((HUMIDITY_PIN
& HUMIDITY_DATA)
== 0)
break; //wait until sensor
} &n