|

Click picture to enlarge
ecoTHERMO
Design
Documentation
Introduction
The ecoTHERMO is an intelligent residential/commercial
HVAC controller. It is designed to provide you with reliable and precise
temperature/humidity control. This thermostat is not only
attractive and accurate, but its ease of use can't be beat. Setting the
desired temperature is as easy as pushing the up or down button.
Additionally, two separate temperatures, day and night, can be
configured so that your house can be quickly set to any of these
temperatures with the press of a single button. The thermostat can be
powered by regular household power supply or by two AA batteries (sold
separately).
Behind this simple interface lies state-of-the art features:
adjustable cycle times to maximize comfort or system life, proportional
adaptive regulation which analyzes how long it takes your system to heat
your house. Additionally, this thermostat is easily controlled by most
home automation systems. This thermostat also include a remote device,
which can be placed in a remote area (with in 100 ft (30 m) indoor or
with in 300 ft (100 m) outdoor). With this user can check the remote
temperature and humidity while they are in comfort of their bed.
Features:
7-day models are best if
your daily schedule tends to change, say, if children are at home
earlier on some days. They give you the most flexibility, and let you
set different programs for different days usually with two possible
temperature periods per day.
This thermostat also
comes with following features:
Displays updated temperature every second.
Displays updated humidity every second.
Clock display
User friendly key-pad. With the help of key-pad
- User can change
and update the clock
- Set different
temperature for day and night
- Set different
humidity for day and night
Digital, backlit displays
Adaptive Recovery/ Smart Recovery features - control
features that senses the amount of time it will take to reach the next
set-point temperature, and reach desired temperatures by the set time
+/- 2 degree accuracy to keep the temperature at an even
level, keeping you comfortable
Two default program periods per day, allowing you to save
money while you're away or sleeping
Specification
|
|
|
Power
Requirements |
|
|
MIN |
MAX |
|
Supply Voltage |
4.7 V |
5.4 V |
|
|
|
|
|
Performance |
|
|
MIN |
MAX |
|
Indoor/Urban
Range |
Up to 100 ft.
(30 m) |
Up to 300 ft.
(100 m) |
|
RF data rate |
|
250,000 bps |
|
Receiver
Sensitivity |
|
-92 dBm
|
|
|
|
|
|
General |
|
Operating
frequency |
|
ISM 2.4 GHz |
|
Operating
Temperature |
|
-40 to 85 ฐC |
|
Antenna Option |
|
Integrated |
|
|
|
|
|
Network and
Security |
|
|
|
Supported
Network Topologies |
Point-to-point,
Point-to-multipoint & Peer-to-peer |
|
Number of Channels |
16 Direct sequence channel |
|
Addressing Options |
PAN ID, Channel and address |
|
|
|
System Description:
ecoTHERMO
works with the help of sensors, clock and user keypads. The ATmega 128
is a 8-bit Microcontroller with 128K Bytes In-System Programmable Flash,
which acts a brain of the systems. It is responsible of all the
processing, which involve, getting the input from the user, getting the
temperature and humidity reading from a temperature sensor, and
displaying the results on a OPTREX 16 x 2 LCD display. The system is
using a ZMD CHIP CAP, which is a Fully Calibrated Humidity Sensor IC.
CHIP CAP provides an accurate temperature and humidity reading every
second. MAXIM 1306 is used to provide an accurate clock to the ecoTHERMO.
ATMEGA 128
MICROCONTROLLER
General Overview
The
ATmega128 is a low-power CMOS 8-bit microcontroller based on the AVR
enhanced RISC architecture. By executing powerful instructions in a
single clock cycle, the ATmega128 achieves throughputs approaching 1
MIPS per MHz allowing the system designer to optimize power consumption
versus processing speed.
The
AVR core combines a rich instruction set with 32 general purpose working
registers. All the 32 registers are directly connected to the Arithmetic
Logic Unit (ALU), allowing two independent registers to be accessed in
one single instruction executed in one clock cycle. The resulting
architecture is more code efficient while achieving throughputs up to
ten times faster than conventional CISC microcontrollers.
The
ATmega128 provides the following features: 128K bytes of In-System
Programmable Flash with Read-While-Write capabilities, 4K bytes EEPROM,
4K bytes SRAM, 53 general purpose I/O lines, 32 general purpose working
registers, Real Time Counter (RTC), four flexible Timer/Counters with
compare modes and PWM, 2 USARTs, a byte oriented Two-wire Serial
Interface, an 8-channel, 10-bit ADC with optional differential input
stage with programmable gain, programmable Watchdog Timer with Internal
Oscillator, an SPI serial port, IEEE std. 1149.1 compliant JTAG test
interface, also used for accessing the On-chip Debug system and
programming and six software selectable power saving modes. The Idle
mode stops the CPU while allowing the SRAM, Timer/Counters, SPI port,
and interrupt system to continue functioning.
The Power-down mode
saves the register contents but freezes the Oscillator, disabling all
other chip functions
until the next interrupt or Hardware Reset. In Power-save mode, the
asynchronous timer continues to run, allowing the user to maintain a
timer base while the rest of the device is sleeping. The ADC Noise
Reduction mode stops the CPU and all I/O modules except Asynchronous
Timer and ADC, to minimize switching noise during ADC conversions. In
Standby mode, the Crystal/Resonator Oscillator is running while the rest
of the device is sleeping. This
allows very fast
start-up combined with low power consumption. In Extended Standby mode,
both the main Oscillator and the Asynchronous Timer continue to run.
The
device is manufactured using Atmels high-density nonvolatile memory
technology. The Onchip ISP Flash allows the program memory to be
reprogrammed in-system through an SPI serial interface, by a
conventional nonvolatile memory programmer, or by an On-chip Boot
program running on the AVR core. The boot program can use any interface
to download the application program in the application Flash memory.
Software in the Boot Flash section will continue to run
while the Application
Flash section is updated, providing true Read-While-Write operation. By
combining an 8-bit RISC CPU with In-System Self-Programmable Flash on a
monolithic chip, the Atmel ATmega128 is a powerful microcontroller that
provides a highly flexible and cost effective solution to many embedded
control applications.
The ATmega128 AVR is
supported with a full suite of program and system development tools
including: C compilers, macro assemblers, program debugger/simulators,
in-circuit emulators, and evaluation kits.
Features
High-performance, Low-power
AVRฎ 8-bit Microcontroller
Advanced RISC Architecture
133 Powerful Instructions Most Single Clock Cycle Execution
32 x 8 General Purpose Working Registers + Peripheral Control
Registers
Fully Static Operation
Up to 16 MIPS Throughput at 16 MHz
On-chip 2-cycle Multiplier
High Endurance Non-volatile
Memory segments
128K Bytes of In-System Self-programmable Flash program memory
4K Bytes EEPROM
4K Bytes Internal SRAM
Write/Erase cycles: 10,000 Flash/100,000 EEPROM
Data retention: 20 years at
85ฐC/100 years at 25ฐC
Optional Boot Code Section with Independent Lock Bits
In-System Programming by On-chip Boot Program
True Read-While-Write Operation
Up to 64K Bytes Optional External Memory Space
Programming Lock for Software Security
SPI Interface for In-System Programming
JTAG (IEEE std. 1149.1
Compliant) Interface
Boundary-scan Capabilities According to the JTAG Standard
Extensive On-chip Debug Support
Programming of Flash, EEPROM, Fuses and Lock Bits through the
JTAG Interface
Peripheral Features
Two 8-bit Timer/Counters with Separate Prescalers and Compare
Modes
Two Expanded 16-bit Timer/Counters with Separate Prescaler,
Compare Mode and Capture Mode
Real Time Counter with Separate Oscillator
Two 8-bit PWM Channels
6 PWM Channels with Programmable Resolution from 2 to 16 Bits
Output Compare Modulator
8-channel, 10-bit ADC
8 Single-ended Channels
7 Differential Channels
2 Differential Channels with Programmable Gain at 1x, 10x, or
200x
Byte-oriented Two-wire Serial Interface
Dual Programmable Serial USARTs
Master/Slave SPI Serial Interface
Programmable Watchdog Timer with On-chip Oscillator
On-chip Analog Comparator
Special Microcontroller
Features
Power-on Reset and Programmable Brown-out Detection
Internal Calibrated RC Oscillator
External and Internal Interrupt Sources
Six Sleep Modes: Idle, ADC Noise Reduction, Power-save,
Power-down, Standby, and Extended Standby
Software Selectable Clock Frequency
ATmega103 Compatibility Mode Selected by a Fuse
Global Pull-up Disable
I/O and Packages
53 Programmable I/O Lines
64-lead TQFP and 64-pad QFN/MLF
Operating Voltages
4.5 - 5.5V for ATmega128
Speed Grades
0 - 16 MHz for ATmega128
OPTREX DOT MATRIX
LCD MODULE
General Overview
DMC
series is the name given to the dot matrix character LCD display modules
that have been developed by OPTREX CORPORATION. The modules consist of
high contrast and large viewing angle TN and STN type LC (liquid
crystal) panels. Each module contains a CMOS controller and all
necessary drivers which have low power consumption. The controller is
equipped with an internal character generator ROM, RAM and RAM for
display data. All display functions are controllable by instructions
making interfacing practical.
Both
display data RAM and character generator RAM can be read making it
possible to use any part not used for display as general data RAM. The
products of this series therefore have wide application possibilities in
the field of terminal display or display for measuring devices.
Characteristics
5 x 7 dots plus cursor, 5 x 8 dots or 5 x 11 dots, dot
matrix LCD (TN and STN mode.)
4 bit or 8 bit interface with MPU is possible.
Display data RAM 80 x bit (max. 80 characters)
Character generator ROM 160 5 x 7 Character fonts.
32 5 x 10 Character fonts.
Custom ROM codes available.
Character generator RAM Program write (64 x 8 bit)
o
8 5 x 7 character fonts.
o
4 5 x 10 character fonts.
Both display data RAM and Character generator RAM can be
read from MPU.
Duty ratio 1 Line Display: 1/8 duty 5 x 7 dots plus
cursor, 5 x 8 dots.
o
1/11 duty 5 x 11 dots.
o
1/16 duty 5 x 7 dots plus cursor, 5 x 8 dots.
o
2 Line Display: 1/16 duty 5 x 7 dots plus cursor, 5 x 8
dots.
o
4 Line Display: 1/16 duty 5 x 8 dots.
Wide variety of operating instructions:
Display clear, Cursor home, Display ON/OFF, Display cursor
blink, Cursor shift, Display shift.
Internal automatic reset circuit upon power up.
Internal oscillator circuit.
CMOS circuitry.
Logic power source: Single (+5 V) for normal temperature.
o
Dual voltage for extended temperature.
Operating temperature range: 0 to +50ฐC (Standard type)
-20 to +70ฐC (H type)
CHIP CAP ZACwire
General Overview
ZACwire is a single wire bi-directional communication protocol. The bit
encoding is similar to Manchester in that clocking information is
embedded into the signal (falling edges of the signal happen at regular
periods). This allows the protocol to be largely insensitive to baud
rate differences between the two ICs communicating. In end-user
applications, the ChipCap will be transmitting humidity and temperature
information and another IC in the system (most likely a μController)
will be reading the data over the ZACwireTM.
Temperature
Transmission Packet from a ChipCap
The
ChipCap transmits 1-byte or 2-byte data packets. 1-byte packets consist
of a start bit, 8 data bits, and a parity bit. The nominal baud rate is
8kHz (125μsec bit window). The signal is normally high. When a
transmission occurs, the start bit occurs first followed by the data
bits (MSB first, LSB last). The packet ends with an even parity bit.
On
the temperature channel, the ChipCap provides temperature data with
10-bit resolution, which cannot be conveyed in a single byte. A complete
temperature transmission from the ChipCap consists of two bytes. The
first byte contains the most significant 2 bits of temperature
information, and the second byte contains the least significant 8 bits
of temperature information. There is a single bit window of high signal
(stop bit) between the two bytes.
16-KEY ENCODER
General Overview
The
MM74C922 and MM74C923 CMOS key encoders provide all the necessary logic
to fully encode an array of SPST switches. The keyboard scan can be
implemented by either an external clock or external capacitor. These
encoders also have on-chip pull-up devices which permit switches with up
to 50 kΩ on resistance to be used. No diodes in the switch array are
needed to eliminate ghost switches. The internal debounce circuit needs
only a single external capacitor and can be defeated by omitting the
capacitor. A Data Available output goes to a high level when a valid
keyboard entry has been made. The Data Available output returns to a low
level when the entered key is released, even if another key is
depressed. The Data Available will return high to indicate acceptance of
the new key after a normal debounce period; this two-key roll-over is
provided between any two switches. An internal register remembers the
last key pressed even after the key is released. The 3-STATE outputs
provide for easy expansion and bus operation and are LPTTL compatible.
Features
50 kΩ maximum switch on resistance
On or off chip clock
On-chip row pull-up devices
2 key roll-over
Keybounce elimination with single capacitor
Last key register at outputs
3-STATE output LPTTL compatible
Wide supply range: 3V to 15V
Low power consumption
X-BEE
RF MODULES
General Overview
The XBee OEM RF
Modules were engineered to meet IEEE 802.15.4 standards and support the
unique needs of low-cost, low-power wireless sensor networks. The
modules require minimal power and provide reliable delivery of data
between devices. The modules operate within the ISM 2.4 GHz frequency
band and are pin-for-pin compatible with each other.
Features
Long Range Data
Integrity
Indoor/Urban: up to 100 (30 m)
Outdoor line-of-sight: up to 300 (100 m)
Transmit Power: 1 mW (0 dBm)
Receiver Sensitivity: -92 dBmXBee-PRO
Networking &
Security
Retries and Acknowledgements
DSSS (Direct Sequence Spread Spectrum)
Each direct sequence channels has over 65,000 unique network addresses
available
Source/Destination Addressing
Unicast & Broadcast Communications
Point-to-point, point-to-multipoint and peer-to-peer topologies
supported
Coordinator/End Device operations
Low Power
TX
Current: 45 mA (@3.3 V)
RX
Current: 50 mA (@3.3 V)
Power-down Current: < 10 μAXBee-PRO
TX
Current: 215 mA (@3.3 V)
RX
Current: 55 mA (@3.3 V)
Power-down Current: < 10 μAADC and I/O line support
Analog-to-digital conversion, Digital I/OI/O Line Passing
Easy-to-Use
No configuration
necessary for out-of box RF communications Free X-CTU Software (Testing
and configuration software). AT and API Command Modes for configuring
module parameters. Extensive command set small form factor
Serial Alarm Real-Time Clock
The DS1306 serial alarm
real-time clock (RTC) provides a full binary coded decimal (BCD) clock
calendar that is accessed by a simple serial interface. The
clock/calendar provides seconds, minutes, hours, day, date, month, and
year information. The end of the month date is automatically adjusted
for months with fewer than 31 days, including corrections for leap year.
The clock operates in either the 24 - hour or 12-hour format with AM/PM
indicator. In addition, 96 bytes of NV RAM are provided for data
storage.
An interface logic-power
supply input pin (VCCIF) allows the DS1306 to drive SDO and 32kHz pins
to a level that is compatible with the interface logic. This allows an
easy interface to 3V logic in mixed supply systems. The DS1306 offers
dual-power supplies as well as a battery-input pin. The dual-power
supplies support a programmable trickle charge circuit that allows a
rechargeable energy source (such as a super cap or rechargeable battery)
to be used for a backup supply. The VBAT pin allows the device to be
backed up by a non-rechargeable battery. The DS1306 is fully operational
from 2.0V to 5.5V.
Two programmable time-of-day
alarms are provided by the DS1306. Each alarm can generate an interrupt
on a programmable combination of seconds, minutes, hours, and day.
Dont care states can be inserted into one or more fields if it is
desired for them to be ignored for the alarm condition. A 1Hz and a
32kHz clock output are also available.
The DS1306 supports a direct
interface to SPI serial data ports or standard 3-wire interface. An
easy-to use address and data format is implemented in which data
transfers can occur 1 byte at a time or in multiple-byte burst mode.
Features
Real-Time Clock
(RTC) Counts Seconds, Minutes, Hours, Date of the Month, Month, Day of
the Week, and Year with Leap-Year Compensation Valid Up to 2100
96-Byte,
Battery-Backed NV RAM for Data Storage
Two Time-of-Day
Alarms, Programmable on combination of Seconds, Minutes, Hours, and Day
of the Week
1Hz and
32.768kHz Clock Outputs
Supports
Motorola SPI
(Serial Peripheral
Interface) Modes
1 and 3 or Standard 3-Wire Interface
Burst Mode for
Reading/Writing Successive Addresses in Clock/RAM
Dual-Power
Supply Pins for Primary and Backup Power Supplies
Optional Trickle
Charge Output to Backup Supply
2.0V to 5.5V
Operation
Optional
Industrial Temperature Range: -40ฐC to +85ฐC
Available in
Space-Efficient, 20-Pin TSSOP Package
/***********************************************************************************************************
* Table Driven FSM Keypad Parsing
*
* Purpose:
* This program implements a table driven FSM that
process key-press events from a keypad.
*
* Author: Muhammad Sajjad Aman
*
* Copyright: 2008 by Kenneth L. Short
*
* Filename: table_driven_fsm.c
*
* Device: ATmega128 @ 1MHz
*
*
***********************************************************************************************************/
//File with register addresses for ATmega128
#include <iom128.h>
#include <intrinsics.h>
#include <stdio.h>
//LCD header file. Used to display character on LCD
#include "lcd.h"
#define CLOCK 0
#define ALRM0 1
#define ALRM1 2
#define CLOCK_NOT_SET 4
#define CLOCK_SET 5
#define DISP_SET_CLOCK 6
// ********************************************
OTHER VARIABLES *******************************************
char keycode = '1';
char keyPress = 1;
unsigned char status_of_clk = CLOCK_NOT_SET;
unsigned char set_time = CLOCK;
// *********************************************
CLOCK VARIABLES *****************************************
unsigned int fsm_hr = 1;
unsigned int fsm_min = 0;
unsigned int fsm_sec = 0;
unsigned int fsm_date = 1;
unsigned int fsm_month = 1;
unsigned int fsm_yr = 8;
unsigned int fsm_pm = 1;
// **********************************************
ALARM 0 VARIABLES *************************************
unsigned int fsm_alrm0_hr = 1;
unsigned int fsm_alrm0_min = 0;
unsigned int fsm_alrm0_sec = 0;
unsigned int fsm_alrm0_pm = 1;
// ***********************************************
ALARM 1 VARIABLES ************************************
unsigned int fsm_alrm1_hr = 1;
unsigned int fsm_alrm1_min = 0;
unsigned int fsm_alrm1_sec = 0;
unsigned int fsm_alrm1_pm = 1;
// ******************************************** NEW
VARIABLES *********************************************
int temp_set_day = 70;
int temp_set_night = 60;
int hum_set_day = 70;
int hum_set_night = 50;
// states in the FSM
typedef enum {disp_clk, set_clk, set_hr, set_min,
set_sec, set_ampm, set_day, set_date, set_month, set_yr, disp_alrm0,
set_alrm0, disp_alrm1, set_alrm1, disp_temp, disp_hum, set_day_temp,
set_night_temp, set_day_hum, set_night_hum} state;
state present_state; // Globle variable for
present state of FSM
// keys on the keypad
// eol is a psuedo key used as a default in the
state table
// Key : Functions
// A : temp
// B : hum
// C : enter
// D : set
// E : down
// F : up
typedef enum {clk, temp, hum, alrm0, alrm1, cancel,
enter, set, down, up, eol} key;
// Day ENUM
typedef enum {sun, mon, tue, wed, thurs, fri, sat}
day;
day day_table[7] = {sun, mon, tue, wed, thurs, fri,
sat};
int day_array = 0;
int alrm0_day_array = 0;
int alrm1_day_array = 0;
day fsm_day;
day fsm_alrm0_day;
day fsm_alrm1_day;
// functions to implement the task(s) associated
with a state transition
// all functions must have the same signature
(parameters and return type)
extern void disp_clk_fn();
extern void set_clk_fn();
extern void set_hr_fn();
extern void set_min_fn();
extern void set_sec_fn();
extern void set_ampm_fn();
extern void set_day_fn();
extern void set_date_fn();
extern void set_month_fn();
extern void set_yr_fn();
extern void disp_alrm0_fn();
extern void set_alrm0_fn();
extern void disp_alrm1_fn();
extern void set_alrm1_fn();
extern void disp_temp_fn();
extern void disp_hum_fn();
extern void set_day_temp_fn();
extern void set_night_temp_fn();
extern void set_day_hum_fn();
extern void set_night_hum_fn();
extern void incr_fn();
extern void decr_fn();
extern void ld_fn();
extern void error_fn();
extern void null_fn();
extern void display_clk(char to_ds_hr, char
to_ds_min, char to_ds_sec, char to_ds_pm, char to_ds_day, char
to_ds_date, char to_ds_month, char to_ds_yr);
extern void display_set_clock();
extern void set_ds_alrm0(char to_ds_alrm0_hr, char
to_ds_alrm0_min, char to_ds_alrm0_sec, char to_ds_alrm0_pm, char
to_ds_alrm0_day);
extern void set_ds_alrm1(char to_ds_alrm1_hr, char
to_ds_alrm1_min, char to_ds_alrm1_sec, char to_ds_alrm1_pm, char
to_ds_alrm1_day);
extern void display_temp(int to_dsp_temp_day, int
to_dsp_temp_night);
extern void display_hum(int to_dsp_hum_day, int
to_dsp_hum_night);
extern void keyPressed(void);
// global variables for measured values and
settings
int loc_temp_meas = 72, rem_temp_meas = 0, temp_set
= 70;
int loc_dhum_meas = 50, rem_dhum_meas = 0, dhum_set
= 50;
int loc_hum_meas = 35, rem_hum_meas = 0, hum_set =
80;
int temp_temp = 70, temp_hum = 40;
// declare type task_fn_ptr as a pointer to a task
function
typedef void (* task_fn_ptr) ();
// A structure transition represents one row of a
state transition table
// it has a field for the input key value, the next
state, and a pointer
// to the task function.
// Declare type transition as a structure with
fields for input key value,
// next state value, and pointer to the task
function
typedef struct {
key keyval;
state next_state;
task_fn_ptr tf_ptr;
} transition;
// The state transition table consists of an array
of arrays of structures.
// Each array of structures corresponds to a
particular present state value.
// Each structure in such an array corresponds to a
transition from the
// state for a given input value and the task
function associated with the
// transition. Accordingly, each structure in an
array has fields
// corresponding to an input value, the next state
for this input value,
// and a pointer to the function task for this
input value.
// The last transition structure in each array has
a keyval field value
// of eol. This is a default value meaning any key
value that has not
// been explcitly listed in a previous transition
structure in the array.
const transition disp_clk_transitions [] = //
subtable for disp_clk state
{
// INPUT NEXT_STATE
TASK
{clk,
disp_clk, disp_clk_fn},
{alrm0, disp_alrm0,
disp_alrm0_fn},
{alrm1, disp_alrm1,
disp_alrm1_fn},
{temp, disp_temp,
disp_temp_fn},
{hum,
disp_hum, disp_hum_fn},
{set,
set_clk,
set_clk_fn},
{eol , disp_clk,
error_fn}
};
const transition set_clk_transitions [] = //
subtable for set_clk state
{
// INPUT NEXT_STATE
TASK
{enter, set_hr,
set_hr_fn},
{cancel, disp_clk,
disp_clk_fn},
{eol, disp_clk,
error_fn}
};
const transition set_hr_transitions [] = //
subtable for set_clk state
{
// INPUT NEXT_STATE
TASK
{up, set_hr,
incr_fn},
{down, set_hr,
decr_fn},
{enter, set_min,
set_min_fn},
{eol,
set_hr, error_fn}
};
const transition set_min_transitions [] = //
subtable for set_clk state
{
// INPUT NEXT_STATE
TASK
{up, set_min,
incr_fn},
{down, set_min,
decr_fn},
{enter, set_sec,
set_sec_fn},
{eol, set_min,
error_fn}
};
const transition set_sec_transitions [] = //
subtable for set_clk state
{
// INPUT NEXT_STATE
TASK
{up, set_sec,
incr_fn},
{down, set_sec,
decr_fn},
{enter, set_ampm,
set_ampm_fn},
{eol,
set_sec, error_fn}
};
const transition set_ampm_transitions [] = //
subtable for set_clk state
{
// INPUT NEXT_STATE
TASK
{up, set_ampm,
incr_fn},
{down, set_ampm,
decr_fn},
{enter, set_day,
set_day_fn},
{eol, set_ampm,
error_fn}
};
const transition set_day_transitions [] =
{
// INPUT NEXT_STATE
TASK
{up, set_day,
incr_fn},
{down, set_day,
decr_fn},
{enter, set_date,
set_date_fn},
{eol, set_day,
error_fn}
};
const transition set_date_transitions [] = //
subtable for set_clk state
{
// INPUT NEXT_STATE
TASK
{up, set_date,
incr_fn},
{down, set_date,
decr_fn},
{enter, set_month,
set_month_fn},
{eol, set_date,
error_fn}
};
const transition set_month_transitions [] = //
subtable for set_clk state
{
// INPUT NEXT_STATE
TASK
{up, set_month,
incr_fn},
{down, set_month,
decr_fn},
{enter, set_yr,
set_yr_fn},
{eol, set_month,
error_fn}
};
const transition set_yr_transitions [] = //
subtable for set_clk state
{
// INPUT NEXT_STATE
TASK
{up, set_yr,
incr_fn},
{down, set_yr,
decr_fn},
{enter, disp_clk,
disp_clk_fn},
{eol,
set_yr, error_fn}
};
const transition disp_alrm0_transitions [] = //
subtable for disp_clk state
{
// INPUT NEXT_STATE
TASK
{clk, disp_clk,
disp_clk_fn},
{alrm1, disp_alrm1,
disp_alrm1_fn},
{temp, disp_temp,
disp_temp_fn},
{hum,
disp_hum, disp_hum_fn},
{set,
set_alrm0,
set_alrm0_fn},
{eol, disp_clk,
error_fn}
};
const transition set_alrm0_transitions [] = //
subtable for set_clk state
{
// INPUT NEXT_STATE
TASK
{enter, set_hr,
set_hr_fn},
{cancel, disp_alrm0,
disp_alrm0_fn},
{eol, disp_clk,
error_fn}
};
const transition disp_alrm1_transitions [] = //
subtable for disp_clk state
{
// INPUT NEXT_STATE
TASK
{clk,
disp_clk, disp_clk_fn},
{alrm0, disp_alrm0,
disp_alrm0_fn},
{temp, disp_temp,
disp_temp_fn},
{hum,
disp_hum, disp_hum_fn},
{set,
set_alrm1, set_alrm1_fn},
{eol,
disp_clk, error_fn}
};
const transition set_alrm1_transitions [] = //
subtable for set_clk state
{
// INPUT NEXT_STATE
TASK
{enter, set_hr,
set_hr_fn},
{cancel, disp_alrm1,
disp_alrm1_fn},
{eol, disp_clk,
error_fn}
};
const transition disp_temp_transitions [] = //
subtable for set_clk state
{
// INPUT NEXT_STATE
TASK
{clk,
disp_clk, disp_clk_fn},
{alrm0, disp_alrm0,
disp_alrm0_fn},
{alrm1, disp_alrm1,
disp_alrm1_fn},
{temp, disp_temp,
disp_temp_fn},
{hum,
disp_hum, disp_hum_fn},
{set,
set_day_temp,
set_day_temp_fn},
{eol, disp_temp,
error_fn}
};
const transition disp_hum_transitions [] = //
subtable for set_clk state
{
// INPUT NEXT_STATE
TASK
{clk,
disp_clk, disp_clk_fn},
{alrm0, disp_alrm0,
disp_alrm0_fn},
{alrm1, disp_alrm1,
disp_alrm1_fn},
{temp, disp_temp,
disp_temp_fn},
{hum,
disp_hum, disp_hum_fn},
{set,
set_day_hum,
set_day_hum_fn},
{eol,
disp_hum, error_fn}
};
const transition set_day_temp_transitions [] =
// subtable for set_clk state
{
// INPUT NEXT_STATE
TASK
{up, set_day_temp,
incr_fn},
{down, set_day_temp,
decr_fn},
{enter,
set_night_temp, set_night_temp_fn},
{eol, set_day_temp,
error_fn}
};
const transition set_night_temp_transitions []
= // subtable for set_clk state
{
// INPUT NEXT_STATE
TASK
{up, set_night_temp,
incr_fn},
{down, set_night_temp,
decr_fn},
{enter, disp_temp,
ld_fn},
{eol,
set_night_temp, error_fn}
};
const transition set_day_hum_transitions [] =
// subtable for set_clk state
{
// INPUT NEXT_STATE
TASK
{up, set_day_hum,
incr_fn},
{down, set_day_hum,
decr_fn},
{enter,
set_night_hum, set_night_hum_fn},
{eol, set_day_hum,
error_fn}
};
const transition set_night_hum_transitions [] =
// subtable for set_clk state
{
// INPUT NEXT_STATE
TASK
{up,
set_night_hum, incr_fn},
{down,
set_night_hum, decr_fn},
{enter,
disp_hum, ld_fn},
{eol,
set_night_hum, error_fn}
};
// The outer array is an array of pointers to an
array of transition
// structures for each present state.
const transition * ps_transitions_ptr[20] =
{
disp_clk_transitions,
set_clk_transitions,
set_hr_transitions,
set_min_transitions,
set_sec_transitions,
set_ampm_transitions,
set_day_transitions,
set_date_transitions,
set_month_transitions,
set_yr_transitions,
disp_alrm0_transitions,
set_alrm0_transitions,
disp_alrm1_transitions,
set_alrm1_transitions,
disp_temp_transitions,
disp_hum_transitions,
set_day_temp_transitions,
set_night_temp_transitions,
set_day_hum_transitions,
set_night_hum_transitions
};
// The finite state machine is implemented as a
fumction with parameters
// corresponding to the present state and key value
that has been input.
void fsm (state ps, key keyval)
{
// Search the array of transition structures
corresponding to the
// present state for the transition structure that
has has keyvalue
// field value that is equal to current input key
value or equal
// to eol.
int i;
for (i = 0; (ps_transitions_ptr[ps][i].keyval !=
keyval)
&& (ps_transitions_ptr[ps][i].keyval != eol);
i++);
// i now has the value of the index of the
transition structure
// corresponding to the current intput key value.
// Invoke the task function pointed to by the task
function pointer
// of the current transition structure.
ps_transitions_ptr[ps][i].tf_ptr();
// Make present state equal to the next state value
of the current
// transition structure.
present_state =
ps_transitions_ptr[ps][i].next_state;
}
int main( void )
{
DDRD = 0xFE;
//Initialize PORTD.
PORTD =
0x07; //Enable INT0
DDRF =
0xFF; // PORTF as Input
PORTF =
0xFF; // PULL-UP
DDRC =
0xF0; //Initialize PORTB.
PORTC = 0x0F;
EIMSK =
0x01; //Enable interrupt masks.
__enable_interrupt(); //Enable global interrupts.
init_dsp(); //ASM call to init_dsp()
clear_dsp(); //C call to clear_dsp()
update_dsp();
present_state = disp_clk;
fsm(present_state,
clk);
while (1)
{
if(keycode == '0')
{
clear_dsp();
printf("KEY NOT SET");
update_dsp();
}
else if(keycode == '1')
{
if(keyPress == 1)
fsm(present_state, clk);
keyPress = 0;
}
else if(keycode == '2')
{
if(keyPress == 1)
fsm(present_state, alrm0);
keyPress = 0;
}
else if(keycode == '3')
{
if(keyPress == 1)
fsm(present_state, alrm1);
keyPress = 0;
}
else if(keycode == '4')
{
if(keyPress == 1)
fsm(present_state, cancel);
keyPress = 0;
}
else if(keycode == '5')
{
clear_dsp();
printf("KEY NOT SET");
update_dsp();
}
else if(keycode == '6')
{
clear_dsp();
printf("KEY NOT SET");
update_dsp();
}
else if(keycode == '7')
{
clear_dsp();
printf("KEY NOT SET");
update_dsp();
}
else if(keycode == '8')
{
clear_dsp();
printf("KEY NOT SET");
update_dsp();
}
else if(keycode == '9')
{
clear_dsp();
printf("KEY NOT SET");
update_dsp();
}
else if(keycode == 'A')
{
if(keyPress ==
1)
fsm(present_state, temp);
keyPress = 0;
}
else if(keycode == 'B')
{
if(keyPress ==
1)
fsm(present_state, hum);
keyPress = 0;
}
else if(keycode == 'C')
{
if(keyPress ==
1)
fsm(present_state, enter);
keyPress = 0;
}
else if(keycode == 'D')
{
if(keyPress ==
1)
fsm(present_state, set);
keyPress = 0;
}
else if(keycode == 'E')
{
if(keyPress ==
1)
fsm(present_state, down);
keyPress = 0;
}
else
{
if(keyPress ==
1)
fsm(present_state, up);
keyPress = 0;
}
update_dsp();
//Update display.
};
}
void disp_clk_fn()
{
display_clk(fsm_hr, fsm_min, fsm_sec,
fsm_pm, fsm_day, fsm_date, fsm_month, fsm_yr);
}
void set_clk_fn()
{
clear_dsp();
printf("Press enter to set clock");
update_dsp();
set_time = CLOCK;
}
void set_hr_fn()
{
if(set_time == CLOCK)
{
clear_dsp();
printf("%d:00:00 PM",
fsm_hr);
update_dsp();
}
else if(set_time == ALRM0)
{
clear_dsp();
printf("Alrm0:%d:00:00 PM",
fsm_alrm0_hr);
update_dsp();
}
else if(set_time == ALRM1)
{
clear_dsp();
printf("Alrm1:%d:00:00 PM",
fsm_alrm1_hr);
update_dsp();
}
}
void set_min_fn()
{
if(set_time == CLOCK)
{
clear_dsp();
printf("%d:%d:00 PM",
fsm_hr, fsm_min);
update_dsp();
}
else if(set_time == ALRM0)
{
clear_dsp();
printf("Alrm0:%d:%d:00 PM",
fsm_alrm0_hr, fsm_alrm0_min);
update_dsp();
}
else if(set_time == ALRM1)
{
clear_dsp();
printf("Alrm1:%d:%d:00 PM",
fsm_alrm1_hr, fsm_alrm1_min);
update_dsp();
}
}
void set_sec_fn()
{
if(set_time == CLOCK)
{
clear_dsp();
printf("%d:%d:%d PM",
fsm_hr, fsm_min, fsm_sec);
update_dsp();
}
else if(set_time == ALRM0)
{
clear_dsp();
printf("Alrm0:%d:%d:%d PM",
fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
update_dsp();
}
else if(set_time == ALRM1)
{
clear_dsp();
printf("Alrm1:%d:%d:%d PM",
fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
update_dsp();
}
}
void set_ampm_fn()
{
if(set_time == CLOCK)
{
if(fsm_pm == 1)
{
clear_dsp();
printf("%d:%d:%d PM", fsm_hr, fsm_min, fsm_sec);
update_dsp();
}
else
{
clear_dsp();
printf("%d:%d:%d AM", fsm_hr, fsm_min, fsm_sec);
update_dsp();
}
}
if(set_time == ALRM0)
{
if(fsm_alrm0_pm == 1)
{
clear_dsp();
printf("Alrm0:%d:%d:%d PM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
update_dsp();
}
else
{
clear_dsp();
printf("Alrm0:%d:%d:%d AM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
update_dsp();
}
}
if(set_time == ALRM1)
{
if(fsm_alrm1_pm == 1)
{
clear_dsp();
printf("Alrm1:%d:%d:%d PM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
update_dsp();
}
else
{
clear_dsp();
printf("Alrm1:%d:%d:%d AM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
update_dsp();
}
}
}
void set_day_fn()
{
if(set_time == CLOCK)
{
fsm_day =
day_table[day_array];
switch(fsm_day)
{
case sun:
clear_dsp();
printf("Day :
Sunday");
update_dsp();
break;
case mon:
clear_dsp();
printf("Day :
Monday");
update_dsp();
break;
case tue:
clear_dsp();
printf("Day :
Tuesday");
update_dsp();
break;
case wed:
clear_dsp();
printf("Day :
Wednesday");
update_dsp();
break;
case thurs:
clear_dsp();
printf("Day :
Thursday");
update_dsp();
break;
case fri:
clear_dsp();
printf("Day :
Friday");
update_dsp();
break;
default:
clear_dsp();
printf("Day :
Saturday");
update_dsp();
}
}
else if(set_time == ALRM0)
{
fsm_alrm0_day =
day_table[alrm0_day_array];
switch(fsm_alrm0_day)
{
case sun:
clear_dsp();
printf("Day :
Sunday");
update_dsp();
break;
case mon:
clear_dsp();
printf("Day :
Monday");
update_dsp();
break;
case tue:
clear_dsp();
printf("Day :
Tuesday");
update_dsp();
break;
case wed:
clear_dsp();
printf("Day :
Wednesday");
update_dsp();
break;
case thurs:
clear_dsp();
printf("Day :
Thursday");
update_dsp();
break;
case fri:
clear_dsp();
printf("Day :
Friday");
update_dsp();
break;
default:
clear_dsp();
printf("Day :
Saturday");
update_dsp();
}
}
else if(set_time == ALRM1)
{
fsm_alrm1_day =
day_table[alrm1_day_array];
switch(fsm_alrm1_day)
{
case sun:
clear_dsp();
printf("Day :
Sunday");
update_dsp();
break;
case mon:
clear_dsp();
printf("Day :
Monday");
update_dsp();
break;
case tue:
clear_dsp();
printf("Day :
Tuesday");
update_dsp();
break;
case wed:
clear_dsp();
printf("Day :
Wednesday");
update_dsp();
break;
case thurs:
clear_dsp();
printf("Day :
Thursday");
update_dsp();
break;
case fri:
clear_dsp();
printf("Day :
Friday");
update_dsp();
break;
default:
clear_dsp();
printf("Day :
Saturday");
update_dsp();
}
}
}
void set_date_fn()
{
if(set_time == CLOCK)
{
clear_dsp();
printf("DATE : %d",
fsm_date);
update_dsp();
}
else if(set_time == ALRM0)
{
set_alrm0(char alrm0_hr,
char alrm0_min, char alrm0_sec, char alrm0_pm, char alrm0_day);
clear_dsp();
printf("ALRM0 SET");
update_dsp();
__delay_cycles(2500000);
present_state = disp_clk;
fsm(present_state, clk);
}
else if(set_time == ALRM1)
{
set_alrm1(char alrm1_hr,
char alrm1_min, char alrm1_sec, char alrm1_pm, char alrm1_day);
clear_dsp();
printf("ALRM1 SET");
update_dsp();
__delay_cycles(2500000);
present_state = disp_clk;
fsm(present_state, clk);
}
}
void set_month_fn()
{
clear_dsp();
printf("MONTH : %d", fsm_month);
update_dsp();
}
void set_yr_fn()
{
clear_dsp();
printf("YEAR : %d", fsm_yr);
update_dsp();
}
void disp_alrm0_fn()
{
if(fsm_alrm0_pm == 1)
{
fsm_alrm0_day =
day_table[alrm0_day_array];
switch(fsm_alrm0_day)
{
case sun:
clear_dsp();
printf("Alrm0 :
%d%d%d PM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
printf(" Day : Sunday");
update_dsp();
break;
case mon:
clear_dsp();
printf("Alrm0 :
%d%d%d PM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
printf(" Day : Monday");
update_dsp();
break;
case tue:
clear_dsp();
printf("Alrm0 :
%d%d%d PM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
printf(" Day : Tuesday");
update_dsp();
break;
case wed:
clear_dsp();
printf("Alrm0 :
%d%d%d PM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
printf(" Day : Wednesday");
update_dsp();
break;
case thurs:
clear_dsp();
printf("Alrm0 :
%d%d%d PM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
printf(" Day : Thursday");
update_dsp();
break;
case fri:
clear_dsp();
printf("Alrm0 :
%d%d%d PM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
printf(" Day : Friday");
update_dsp();
break;
default:
clear_dsp();
printf("Alrm0 :
%d%d%d PM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
printf("
Day : Saturday");
update_dsp();
}
}
else if(fsm_alrm0_pm == 0)
{
fsm_alrm0_day =
day_table[alrm0_day_array];
switch(fsm_alrm0_day)
{
case sun:
clear_dsp();
printf("Alrm0 :
%d%d%d AM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
printf(" Day : Sunday");
update_dsp();
break;
case mon:
clear_dsp();
printf("Alrm0 :
%d%d%d AM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
printf(" Day : Monday");
update_dsp();
break;
case tue:
clear_dsp();
printf("Alrm0 :
%d%d%d AM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
printf(" Day : Tuesday");
update_dsp();
break;
case wed:
clear_dsp();
printf("Alrm0 :
%d%d%d AM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
printf(" Day : Wednesday");
update_dsp();
break;
case thurs:
clear_dsp();
printf("Alrm0 :
%d%d%d AM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
printf(" Day : Thursday");
update_dsp();
break;
case fri:
clear_dsp();
printf("Alrm0 :
%d%d%d AM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
printf(" Day : Friday");
update_dsp();
break;
default:
clear_dsp();
printf("Alrm0 :
%d%d%d AM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
printf(" Day : Saturday");
update_dsp();
}
}
}
void set_alrm0_fn()
{
clear_dsp();
printf("Press enter to set alarm0");
update_dsp();
set_time = ALRM0;
}
void disp_alrm1_fn()
{
if(fsm_alrm1_pm == 1)
{
fsm_alrm1_day =
day_table[alrm1_day_array];
switch(fsm_alrm1_day)
{
case sun:
clear_dsp();
printf("Alrm1 :
%d%d%d PM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
printf(" Day : Sunday");
update_dsp();
break;
case mon:
clear_dsp();
printf("Alrm1 :
%d%d%d PM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
printf(" Day : Monday");
update_dsp();
break;
case tue:
clear_dsp();
printf("Alrm1 :
%d%d%d PM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
printf(" Day : Tuesday");
update_dsp();
break;
case wed:
clear_dsp();
printf("Alrm1 :
%d%d%d PM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
printf(" Day : Wednesday");
update_dsp();
break;
case thurs:
clear_dsp();
printf("Alrm1 :
%d%d%d PM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
printf(" Day : Thursday");
update_dsp();
break;
case fri:
clear_dsp();
printf("Alrm1 :
%d%d%d PM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
printf(" Day : Friday");
update_dsp();
break;
default:
clear_dsp();
printf("Alrm1 :
%d%d%d PM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
printf(" Day : Saturday");
update_dsp();
}
}
else if(fsm_alrm1_pm == 0)
{
fsm_alrm1_day =
day_table[alrm1_day_array];
switch(fsm_alrm1_day)
{
case sun:
clear_dsp();
printf("Alrm1 :
%d%d%d AM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
printf(" Day : Sunday");
update_dsp();
break;
case mon:
clear_dsp();
printf("Alrm1 :
%d%d%d AM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
printf(" Day : Monday");
update_dsp();
break;
case tue:
clear_dsp();
printf("Alrm1 :
%d%d%d AM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
printf(" Day : Tuesday");
update_dsp();
break;
case wed:
clear_dsp();
printf("Alrm1 :
%d%d%d AM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
printf(" Day : Wednesday");
update_dsp();
break;
case thurs:
clear_dsp();
printf("Alrm1 :
%d%d%d AM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
printf(" Day : Thursday");
update_dsp();
break;
case fri:
clear_dsp();
printf("Alrm1 :
%d%d%d AM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
printf(" Day : Friday");
update_dsp();
break;
default:
clear_dsp();
printf("Alrm1 :
%d%d%d AM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
printf(" Day : Saturday");
update_dsp();
}
}
}
void set_alrm1_fn()
{
clear_dsp();
printf("Press enter to set alarm1");
update_dsp();
set_time = ALRM1;
}
void disp_temp_fn()
{
display_temp(temp_set_day,
temp_set_night);
}
void disp_hum_fn()
{
display_hum(hum_set_day,
hum_set_night);
}
void set_day_temp_fn()
{
clear_dsp();
printf("Set day temp : %d",
temp_set_day);
update_dsp();
}
void set_night_temp_fn()
{
clear_dsp();
printf("Set night temp : %d",
temp_set_night);
update_dsp();
}
void set_day_hum_fn()
{
clear_dsp();
printf("Set day hum : %d",
hum_set_day);
update_dsp();
}
void set_night_hum_fn()
{
clear_dsp();
printf("Set night hum : %d",
hum_set_night);
update_dsp();
}
void incr_fn()
{
if(present_state == set_hr)
{
if(set_time == CLOCK)
{
fsm_hr++;
fsm_hr = fsm_hr
% 13;
if(fsm_hr == 0)
{
fsm_hr = 1;
}
clear_dsp();
printf("%d:00:00 PM", fsm_hr);
update_dsp();
}
else if(set_time == ALRM0)
{
fsm_alrm0_hr++;
fsm_alrm0_hr =
fsm_alrm0_hr % 13;
if(fsm_alrm0_hr
== 0)
{
fsm_alrm0_hr = 1;
}
clear_dsp();
printf("%d:00:00 PM", fsm_alrm0_hr);
update_dsp();
}
else if(set_time == ALRM1)
{
fsm_alrm1_hr++;
fsm_alrm1_hr =
fsm_alrm1_hr % 13;
if(fsm_alrm1_hr
== 0)
{
fsm_alrm1_hr = 1;
}
clear_dsp();
printf("%d:00:00 PM", fsm_alrm1_hr);
update_dsp();
}
}
else if(present_state == set_min)
{
if(set_time == CLOCK)
{
fsm_min++;
fsm_min =
fsm_min % 60;
clear_dsp();
printf("%d:%d:00 PM", fsm_hr, fsm_min);
update_dsp();
}
else if(set_time == ALRM0)
{
fsm_alrm0_min++;
fsm_alrm0_min =
fsm_alrm0_min % 60;
clear_dsp();
printf("%d:%d:00 PM", fsm_alrm0_hr, fsm_alrm0_min);
update_dsp();
}
else if(set_time == ALRM1)
{
fsm_alrm1_min++;
fsm_alrm1_min =
fsm_alrm1_min % 60;
clear_dsp();
printf("%d:%d:00 PM", fsm_alrm1_hr, fsm_alrm1_min);
update_dsp();
}
}
else if(present_state == set_sec)
{
if(set_time == CLOCK)
{
fsm_sec++;
fsm_sec =
fsm_sec % 60;
clear_dsp();
printf("%d:%d:%d PM", fsm_hr, fsm_min, fsm_sec);
update_dsp();
}
else if(set_time == ALRM0)
{
fsm_alrm0_sec++;
fsm_alrm0_sec =
fsm_alrm0_sec % 60;
clear_dsp();
printf("%d:%d:%d PM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
update_dsp();
}
else if(set_time == ALRM1)
{
fsm_alrm1_sec++;
fsm_alrm1_sec =
fsm_alrm1_sec % 60;
clear_dsp();
printf("%d:%d:%d PM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
update_dsp();
}
}
else if(present_state == set_ampm)
{
if(set_time == CLOCK)
{
if(fsm_pm == 1)
{
clear_dsp();
printf("%d:%d:%d AM", fsm_hr, fsm_min, fsm_sec);
update_dsp();
fsm_pm = 0;
}
else if(fsm_pm
== 0)
{
clear_dsp();
printf("%d:%d:%d PM", fsm_hr, fsm_min, fsm_sec);
update_dsp();
fsm_pm = 1;
}
}
else if(set_time == ALRM0)
{
if(fsm_alrm0_pm
== 1)
{
clear_dsp();
printf("A0:%d:%d:%d AM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
update_dsp();
fsm_alrm0_pm = 0;
}
else
if(fsm_alrm0_pm == 0)
{
clear_dsp();
printf("A0:%d:%d:%d PM", fsm_alrm0_hr, fsm_alrm0_min, fsm_alrm0_sec);
update_dsp();
fsm_alrm0_pm = 1;
}
}
else if(set_time == ALRM1)
{
if(fsm_alrm1_pm
== 1)
{
clear_dsp();
printf("A1:%d:%d:%d AM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
update_dsp();
fsm_alrm1_pm = 0;
}
else
if(fsm_alrm1_pm == 0)
{
clear_dsp();
printf("A1%d:%d:%d PM", fsm_alrm1_hr, fsm_alrm1_min, fsm_alrm1_sec);
update_dsp();
fsm_alrm1_pm = 1;
}
}
}
else if(present_state == set_day)
{
if(set_time == CLOCK)
{
day_array++;
day_array =
day_array % 7;
fsm_day =
day_table[day_array];
switch(fsm_day)
{
case sun:
clear_dsp();
printf("Day : Sunday");
update_dsp();
break;
case mon:
clear_dsp();
printf("Day : Monday");
update_dsp();
break;
case tue:
clear_dsp();
printf("Day : Tuesday");
update_dsp();
break;
case wed:
clear_dsp();
printf("Day : Wednesday");
update_dsp();
break;
case thurs:
clear_dsp();
printf("Day : Thursday");
update_dsp();
break;
case fri:
clear_dsp();
printf("Day : Friday");
update_dsp();
break;
default:
clear_dsp();
printf("Day : Saturday");
update_dsp();
}
}
else if(set_time == ALRM0)
{
alrm0_day_array++;
alrm0_day_array
= alrm0_day_array % 7;
fsm_alrm0_day =
day_table[alrm0_day_array];
switch(fsm_alrm0_day)
{
case sun:
clear_dsp();
printf("Day : Sunday");
update_dsp();
break;
case mon:
clear_dsp();
printf("Day : Monday");
update_dsp();
break;
case tue:
clear_dsp();
printf("Day : Tuesday");
update_dsp();
break;
case wed:
clear_dsp();
printf("Day : Wednesday");
update_dsp();
break;
case thurs:
clear_dsp();
printf("Day : Thursday");
update_dsp();
break;
case fri:
clear_dsp();
printf("Day : Friday");
update_dsp();
break;
default:
clear_dsp();
printf("Day : Saturday");
update_dsp();
}
}
else if(set_time == ALRM1)
{
alrm1_day_array++;
alrm1_day_array
= alrm1_day_array % 7;
fsm_alrm1_day =
day_table[alrm1_day_array];
switch(fsm_alrm1_day)
{
case sun:
clear_dsp();
printf("Day : Sunday");
update_dsp();
break;
case mon:
clear_dsp();
printf("Day : Monday");
update_dsp();
break;
case tue:
clear_dsp();
printf("Day : Tuesday");
update_dsp();
break;
case wed:
clear_dsp();
printf("Day : Wednesday");
update_dsp();
break;
case thurs:
clear_dsp();
printf("Day : Thursday");
update_dsp();
break;
case fri:
clear_dsp();
printf("Day : Friday");
update_dsp();
break;
default:
clear_dsp();
printf("Day : Saturday");
update_dsp();
}
}
}
else if(present_state == set_date)
{
fsm_date++;
fsm_date = fsm_date % 32;
if(fsm_date == 0)
{
fsm_date = 1;
}
clear_dsp();
printf("Date : %d",
fsm_date);
update_dsp();
}
else if(present_state == set_month)
{
fsm_month++;
fsm_month = fsm_month % 13;
if(fsm_month == 0)
{
fsm_month = 1;
}
clear_dsp();
printf("Month : %d",
fsm_month);
update_dsp();
}
else if(present_state == set_yr)
{
fsm_yr++;
fsm_yr = fsm_yr % 100;
clear_dsp();
printf("Year : %d",
fsm_yr);
update_dsp();
}
else if(present_state == set_day_temp)
{
temp_set_day++;
clear_dsp();
printf("Set day temp
: %d", temp_set_day);
update_dsp();
}
else if(present_state ==
set_night_temp)
{
temp_set_night++;
clear_dsp();
printf("Set night temp :
%d", temp_set_night);
update_dsp();
}
else if(present_state == set_day_hum)
{
hum_set_day++;
clear_dsp();
printf("Set day hum :
%d", hum_set_day);
update_dsp();
}
else if(present_state == set_night_hum)
{
hum_set_night++;
clear_dsp();
printf("Set night hum
: %d", hum_set_night);
update_dsp();
}
}
void decr_fn()
{
if(present_state == set_hr)
{
fsm_hr--;
if(fsm_hr == 0)
{
fsm_hr = 12;
}
clear_dsp();
printf("%d:00:00 PM",
fsm_hr);
update_dsp();
}
else if(present_state == set_min)
{
fsm_min--;
if(fsm_min == -1)
{
fsm_min = 59;
}
clear_dsp();
printf("%d:%d:00 PM",
fsm_hr, fsm_min);
update_dsp();
}
else if(present_state == set_sec)
{
fsm_sec--;
if(fsm_sec == -1)
{
fsm_sec = 59;
}
clear_dsp();
printf("%d:%d:%d PM",
fsm_hr, fsm_min, fsm_sec);
update_dsp();
}
else if(present_state == set_ampm)
{
if(fsm_pm == 1)
{
clear_dsp();
printf("%d:%d:%d AM", fsm_hr, fsm_min, fsm_sec);
update_dsp();
fsm_pm = 0;
}
else if(fsm_pm == 0)
{
clear_dsp();
printf("%d:%d:%d PM", fsm_hr, fsm_min, fsm_sec);
update_dsp();
fsm_pm = 1;
}
}
else if(present_state == set_day)
{
day_array--;
if(day_array == -1)
{
day_array = 6;
}
fsm_day =
day_table[day_array];
switch(fsm_day)
{
case sun:
clear_dsp();
printf("Day :
Sunday");
update_dsp();
break;
case mon:
clear_dsp();
printf("Day :
Monday");
update_dsp();
break;
case tue:
clear_dsp();
printf("Day :
Tuesday");
update_dsp();
break;
case wed:
clear_dsp();
printf("Day :
Wednesday");
update_dsp();
break;
case thurs:
clear_dsp();
printf("Day :
Thursday");
update_dsp();
break;
case fri:
clear_dsp();
printf("Day :
Friday");
update_dsp();
break;
default:
clear_dsp();
printf("Day :
Saturday");
update_dsp();
}
}
else if(present_state == set_date)
{
fsm_date--;
if(fsm_date == 0)
{
fsm_date = 31;
}
clear_dsp();
printf("Date : %d",
fsm_date);
update_dsp();
}
else if(present_state == set_month)
{
fsm_month--;
if(fsm_month == 0)
{
fsm_month = 12;
}
clear_dsp();
printf("Month : %d",
fsm_month);
update_dsp();
}
else if(present_state == set_yr)
{
fsm_yr--;
fsm_yr = fsm_yr % 100;
clear_dsp();
printf("Year : %d",
fsm_yr);
update_dsp();
}
else if(present_state == set_day_temp)
{
temp_set_day--;
clear_dsp();
printf("Set day temp : %d",
temp_set_day);
update_dsp();
}
else if(present_state ==
set_night_temp)
{
temp_set_night--;
clear_dsp();
printf("Set night temp :
%d", temp_set_night);
update_dsp();
}
else if(present_state == set_day_hum)
{
hum_set_day--;
clear_dsp();
printf("Set day hum : %d",
hum_set_day);
update_dsp();
}
else if(present_state == set_night_hum)
{
hum_set_night--;
clear_dsp();
printf("Set night hum :
%d", hum_set_night);
update_dsp();
}
}
void ld_fn()
{
clear_dsp();
printf("Setting saved");
update_dsp();
__delay_cycles(2500000);
if(present_state == set_night_temp)
{
disp_temp_fn();
}
else if(present_state == set_night_hum)
{
disp_hum_fn();
}
}
void error_fn()
{
printf("ERROR");
}
void null_fn()
{
printf("NULL");
}
void keyPressed()
{
keyPress = 1;
}
/***********************************************************************************************************
* USART SPI Interface
*
* Purpose:
* This program implements a USART that process
remote temperature and humidity readings.
*
* Author: Muhammad Sajjad Aman
*
* Copyright: 2008 by Muhammad Sajjad Aman
*
* Filename: USART.c
*
* Device: ATmega128 @ 1MHz
*
*
***********************************************************************************************************/
/* Includes */
#include <iom128.h>
#include <intrinsics.h>
#include <stdio.h>
#include <string.h>
#include "lcd.h"
#include <ina90.h>
/* UART Buffer Defines */
#define USART_RX_BUFFER_SIZE 128 /*
2,4,8,16,32,64,128 or 256 bytes */
#define USART_TX_BUFFER_SIZE 128 /*
2,4,8,16,32,64,128 or 256 bytes */
#define USART_RX_BUFFER_MASK ( USART_RX_BUFFER_SIZE
- 1 )
#define USART_TX_BUFFER_MASK ( USART_TX_BUFFER_SIZE
- 1 )
#if ( USART_RX_BUFFER_SIZE & USART_RX_BUFFER_MASK )
#error RX buffer size is not a power of
2
#endif
#if ( USART_TX_BUFFER_SIZE & USART_TX_BUFFER_MASK )
#error TX buffer size is not a power of
2
#endif
/* Static Variables */
static unsigned char
USART_RxBuf[USART_RX_BUFFER_SIZE];
static volatile unsigned char USART_RxHead;
static volatile unsigned char USART_RxTail;
static unsigned char
USART_TxBuf[USART_TX_BUFFER_SIZE];
static volatile unsigned char USART_TxHead;
static volatile unsigned char USART_TxTail;
unsigned char disp_data = 0;
/* States in FSM (Get remote data) */
typedef enum {eMark, Temp2, Temp1, Temp0, Hum2,
Hum1, Hum0, pMark, data} remoteState;
/* Input Data */
typedef enum {rec_eMark, rec_Temp2, rec_Temp1,
rec_Temp0, rec_Hum2, rec_Hum1, rec_Hum0, rec_pMark, rec_eot} remoteData;
/* Global variable for present remote state of FSM
*/
remoteState present_remoteState;
/* Declare type task_rem_fnptr as a pointer to a
task function */
typedef void (*task_rem_fnptr) ();
/* Prototypes */
void USART0_Init( unsigned int baudrate );
unsigned char USART0_Receive( void );
void USART0_Transmit( unsigned char data );
unsigned char ch[8] = {0,0,0,0,0,0,0,0};
unsigned char getData = 0;
unsigned char getTemp, getHum;
typedef struct
{
remoteData remData;
remoteState
remNxtState;
}trans;
const trans eMark_trans [] =
{
// INPUT NEXT_STATE
{ rec_eMark, Temp2},
{ rec_Temp2, Temp1},
{ rec_Temp1, Temp0},
{ rec_Temp0, Hum2},
{ rec_Hum2, Hum1},
{ rec_Hum1, Hum0},
{ rec_Hum0, pMark},
{ rec_pMark, data},
{ rec_eot, eMark}
};
const trans Temp2_trans [] =
{
// INPUT NEXT_STATE
{ rec_eMark, Temp2},
{ rec_Temp2, Temp1},
{ rec_Temp1, Temp0},
{ rec_Temp0, Hum2},
{ rec_Hum2, Hum1},
{ rec_Hum1, Hum0},
{ rec_Hum0, pMark},
{ rec_pMark, data},
{ rec_eot, eMark}
};
const trans Temp1_trans [] =
{
// INPUT NEXT_STATE
{ rec_eMark, Temp2},
{ rec_Temp2, Temp1},
{ rec_Temp1, Temp0},
{ rec_Temp0, Hum2},
{ rec_Hum2, Hum1},
{ rec_Hum1, Hum0},
{ rec_Hum0, pMark},
{ rec_pMark, data},
{ rec_eot, eMark}
};
const trans Temp0_trans [] =
{
// INPUT NEXT_STATE
{ rec_eMark, Temp2},
{ rec_Temp2, Temp1},
{ rec_Temp1, Temp0},
{ rec_Temp0, Hum2},
{ rec_Hum2, Hum1},
{ rec_Hum1, Hum0},
{ rec_Hum0, pMark},
{ rec_pMark, data},
{ rec_eot, eMark}
};
const trans Hum2_trans [] =
{
// INPUT NEXT_STATE
{ rec_eMark, Temp2},
{ rec_Temp2, Temp1},
{ rec_Temp1, Temp0},
{ rec_Temp0, Hum2},
{ rec_Hum2, Hum1},
{ rec_Hum1, Hum0},
{ rec_Hum0, pMark},
{ rec_pMark, data},
{ rec_eot, eMark}
};
const trans Hum1_trans [] =
{
// INPUT NEXT_STATE
{ rec_eMark, Temp2},
{ rec_Temp2, Temp1},
{ rec_Temp1, Temp0},
{ rec_Temp0, Hum2},
{ rec_Hum2, Hum1},
{ rec_Hum1, Hum0},
{ rec_Hum0, pMark},
{ rec_pMark, data},
{ rec_eot, eMark}
};
const trans Hum0_trans [] =
{
// INPUT NEXT_STATE
{ rec_eMark, Temp2},
{ rec_Temp2, Temp1},
{ rec_Temp1, Temp0},
{ rec_Temp0, Hum2},
{ rec_Hum2, Hum1},
{ rec_Hum1, Hum0},
{ rec_Hum0, pMark},
{ rec_pMark, data},
{ rec_eot, eMark}
};
const trans pMark_trans [] =
{
// INPUT NEXT_STATE
{ rec_eMark, Temp2},
{ rec_Temp2, Temp1},
{ rec_Temp1, Temp0},
{ rec_Temp0, Hum2},
{ rec_Hum2, Hum1},
{ rec_Hum1, Hum0},
{ rec_Hum0, pMark},
{ rec_pMark, data},
{ rec_eot, eMark}
};
const trans * ps_trans_ptr[8] =
{
eMark_trans,
Temp2_trans,
Temp1_trans,
Temp0_trans,
Hum2_trans,
Hum1_trans,
Hum0_trans,
pMark_trans
};
void remData_fsm(remoteState rPrsntState,
remoteData remData)
{
int i;
for(i = 0; (ps_trans_ptr[rPrsntState][i].remData
!= remData)
&& (ps_trans_ptr[rPrsntState][i].remData !=
rec_eot); i++);
present_remoteState =
ps_trans_ptr[rPrsntState][i].remNxtState;
}
char getRemoteData( int result )
{
USART0_Init( 12 ); /* Set the baudrate to
19,200 bps using a 3.6864MHz crystal */
_SEI(); /* Enable interrupts => enable
UART interrupts */
present_remoteState = eMark;
getTemp = 0x00;
getHum = 0x00;
for( ; ; ) /* Forever */
{
ch[0] = USART0_Receive();
if(ch[0] == '!' && getData == 0)
{
remData_fsm(present_remoteState, rec_eMark);
ch[1] = USART0_Receive();
if(ch[1] == '0' || ch[1] == '1' || ch[1] ==
'2' || ch[1] == '3' || ch[1] == '4' || ch[1] == '5' || ch[1] == '6' ||
ch[1] == '7' || ch[1] == '8' || ch[1] == '9')
remData_fsm(present_remoteState, rec_Temp2);
ch[2] = USART0_Receive();
if(ch[2] == '0' || ch[2] == '1' || ch[2] ==
'2' || ch[2] == '3' || ch[2] == '4' || ch[2] == '5' || ch[2] == '6' ||
ch[2] == '7' || ch[2] == '8' || ch[2] == '9')
remData_fsm(present_remoteState, rec_Temp1);
ch[3] = USART0_Receive();
if(ch[3] == '0' || ch[3] == '1' || ch[3] ==
'2' || ch[3] == '3' || ch[3] == '4' || ch[3] == '5' || ch[3] == '6' ||
ch[3] == '7' || ch[3] == '8' || ch[3] == '9')
remData_fsm(present_remoteState, rec_Temp0);
ch[4] = USART0_Receive();
if(ch[4] == '0' || ch[4] == '1' || ch[4] ==
'2' || ch[4] == '3' || ch[4] == '4' || ch[4] == '5' || ch[4] == '6' ||
ch[4] == '7' || ch[4] == '8' || ch[4] == '9')
remData_fsm(present_remoteState, rec_Hum2);
ch[5] = USART0_Receive();
if(ch[5] == '0' || ch[5] == '1' || ch[5] ==
'2' || ch[5] == '3' || ch[5] == '4' || ch[5] == '5' || ch[5] == '6' ||
ch[5] == '7' || ch[5] == '8' || ch[5] == '9')
remData_fsm(present_remoteState, rec_Hum1);
ch[6] = USART0_Receive();
if(ch[6] == '0' || ch[6] == '1' || ch[6] ==
'2' || ch[6] == '3' || ch[6] == '4' || ch[6] == '5' || ch[6] == '6' ||
ch[6] == '7' || ch[6] == '8' || ch[6] == '9')
remData_fsm(present_remoteState, rec_Hum0);
ch[7] = USART0_Receive();
if(ch[7] == '#')
remData_fsm(present_remoteState, rec_pMark);
if(present_remoteState == data)
{
present_remoteState = eMark;
if(result == 0)
{
getTemp |= ch[1] | (ch[2] <<= 1) | (ch[3]
<<= 2); // getTemp OR ch[1] OR (left shifted) ch[2] OR (left shifted)
ch[3]
return getTemp;
}
else if(result == 1)
{
getHum |= ch[4] | (ch[5] <<= 1) | (ch[6]
<<= 2); // getTemp OR ch[4] OR (left shifted) ch[5] OR (left shifted)
ch[6]
return getHum;
}
}
}
}
}
/* Initialize USART */
void USART0_Init( unsigned int baudrate )
{
unsigned char x;
/* Set the baud rate */
UBRR0H = (unsigned char) (baudrate >>
8);
UBRR0L = (unsigned char) baudrate;
/* Enable UART receiver and transmitter
*/
UCSR0B = ( ( 1 << RXCIE0 ) | ( 1 <<
RXEN0 ) | ( 1 << TXEN0 ) );
/* Set frame format: 8 data 2stop */
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
// Set to 8-bit data, no parity, 1 stop bit (for devices with Extended
IO)
/* Flush receive buffer */
x = 0;
USART_RxTail = x;
USART_RxHead = x;
USART_TxTail = x;
USART_TxHead = x;
}
/* Interrupt handlers */
#pragma vector=USART0_RXC_vect
__interrupt void USART0_RX_interrupt( void )
{
unsigned char data;
unsigned char tmphead;
/* Read the received data */
data = UDR0;
/* Calculate buffer index */
tmphead = ( USART_RxHead + 1 ) &
USART_RX_BUFFER_MASK;
USART_RxHead = tmphead; /* Store
new index */
if ( tmphead == USART_RxTail )
{
/* ERROR! Receive buffer
overflow */
}
USART_RxBuf[tmphead] = data; /* Store
received data in buffer */
}
#pragma vector=USART0_UDRE_vect
__interrupt void USART0_TX_interrupt( void )
{
unsigned char tmptail;
/* Check if all data is transmitted */
if ( USART_TxHead != USART_TxTail )
{
/* Calculate buffer index
*/
tmptail = ( USART_TxTail +
1 ) & USART_TX_BUFFER_MASK;
USART_TxTail =
tmptail; /* Store new index */
UDR0 =
USART_TxBuf[tmptail]; /* Start transmition */
}
else
{
UCSR0B &=
~(1<<UDRIE0); /* Disable UDRE interrupt */
}
}
/* Read and write functions */
unsigned char USART0_Receive( void )
{
unsigned char tmptail;
while ( USART_RxHead == USART_RxTail
); /* Wait for incomming data */
tmptail = ( USART_RxTail + 1 ) &
USART_RX_BUFFER_MASK;/* Calculate buffer index */
USART_RxTail = tmptail;
/* Store new index */
return USART_RxBuf[tmptail];
/* Return data */
}
void USART0_Transmit( unsigned char data )
{
unsigned char tmphead;
/* Calculate buffer index */
tmphead = ( USART_TxHead + 1 ) &
USART_TX_BUFFER_MASK; /* Wait for free space in buffer */
while ( tmphead == USART_TxTail );
USART_TxBuf[tmphead] = data;
/* Store data in buffer */
USART_TxHead = tmphead;
/* Store new index */
UCSR0B |= (1<<UDRIE0);
/* Enable UDRE interrupt */
}
unsigned char DataInReceiveBuffer( void )
{
return ( USART_RxHead != USART_RxTail
); /* Return 0 (FALSE) if the receive buffer is empty */
}
/***********************************************************************************************************
* Display the current local and remote temperature
in Centigrade and Fahrenheit
*
* Purpose:
* This program displays the local and remote
temperature in Centigrade and Fahrenheit
*
* Author: Muhammad Sajjad Aman
*
* Copyright: 2008 by Muhammad Sajjad Aman
*
* Filename: dsp_hum.c
*
* Device: ATmega128 @ 1MHz
*
*
***********************************************************************************************************/
#include <iom128.h> //File with register addresses
for ATmega128
#include <intrinsics.h>
#include <stdio.h>
#include <avr_macros.h>
#include "lcd.h"
#define GET_HUMIDITY 1
extern unsigned char ch[8];
extern int getLocalHum();
extern char getRemoteData(int toUSART);
extern void dispHum_keyPressed();
unsigned int localHum;
unsigned char remoteHum;
extern unsigned char dispHum_keypress = 1;
void display_hum(int dsp_hum_day, int
dsp_hum_night)
{
dispHum_keypress = 1;
while(dispHum_keypress == 1)
{
__disable_interrupt();
EIFR = 0x00;
EIMSK = 0x07;
__enable_interrupt();
localHum = getLocalHum();
remoteHum = getRemoteData(GET_HUMIDITY);
if(ch[4] == '0')
{
clear_dsp();
printf("HLOC:%d REM:%c%c%% DSET:%d NSET:%d",
localHum, ch[5], ch[6], dsp_hum_day, dsp_hum_night);
update_dsp();
}
else if(ch[4] != '0')
{
clear_dsp();
printf("HLOC:%d REM:%c%c%c%% DSET:%d
NSET:%d", localHum, ch[4], ch[5], ch[6], dsp_hum_day, dsp_hum_night);
update_dsp();
}
if(localHum < dsp_hum_day)
{
SETBIT(PORTF,3);
CLEARBIT(PORTF,2);
}
else if(localHum > dsp_hum_day)
{
SETBIT(PORTF,2);
CLEARBIT(PORTF,3);
}
}
}
void dispHum_keyPressed()
{
dispHum_keypress = 0;
}
/***********************************************************************************************************
* Display the current local and remote humidity in
Centigrade and Fahrenheit
*
* Purpose:
* This program displays the local and remote
humidity in Centigrade and Fahrenheit
*
* Author: Muhammad Sajjad Aman
*
* Copyright: 2008 by Muhammad Sajjad Aman
*
* Filename: dsp_temp.c
*
* Device: ATmega128 @ 1MHz
*
*
***********************************************************************************************************/
#include <iom128.h> //File with register addresses
for ATmega128
#include <intrinsics.h>
#include <stdio.h>
#include <avr_macros.h>
#include "lcd.h"
#define GET_TEMPRATURE 0
extern char getLocalTemp();
extern char getRemoteData(int toUSART);
extern void dispTemp_keyPressed();
extern unsigned char ch[8];
unsigned int localTemp;
unsigned char remoteTemp;
unsigned char dispTemp_keypress = 1;
void display_temp(int dsp_temp_day, int
dsp_temp_night)
{
dispTemp_keypress = 1;
while(dispTemp_keypress == 1)
{
__disable_interrupt();
EIFR = 0x00;
EIMSK = 0x03;
__enable_interrupt();
localTemp = getLocalTemp();
remoteTemp = getRemoteData(GET_TEMPRATURE);
if(ch[1] == '0')
{
clear_dsp();
printf("TLOC:%d REM:%c%c DSET:%d NSET:%d",
localTemp, ch[2], ch[3], dsp_temp_day, dsp_temp_night);
update_dsp();
}
else if(ch[1] != '0')
{
clear_dsp();
printf("TLOC:%d REM:%c%c%c D_SET:%d
N_SET:%d", localTemp, ch[1], ch[2], ch update_dsp();
}
if(localTemp < dsp_temp_day)
{
SETBIT(PORTF,1);
CLEARBIT(PORTF,0);
}
else if(localTemp > dsp_temp_day)
{
SETBIT(PORTF,0);
CLEARBIT(PORTF,1);
}
}
}
void dispTemp_keyPressed()
{
dispTemp_keypress = 0;
}
/***********************************************************************************************************
* Calculates the current local temperature
*
* Purpose:
* This program displays the temperature
*
* Author: Muhammad Sajjad Aman
*
* Copyright: 2008 by Muhammad Sajjad Aman
*
* Filename: dsp_local_temp.c
*
* Device: ATmega128 @ 1MHz
*
*
***********************************************************************************************************/
#include <iom128.h>
#include <intrinsics.h>
#include <stdio.h>
#include <string.h>
#include "lcd.h"
//void check_temprature();
unsigned char start;
unsigned char tempReady = 0;
unsigned char counter0=0, counter1=0;
unsigned char temp = 0x00, temp_value1=0x00,
temp_value2=0x00;
unsigned int litemp_value=0x0000;
char count0=0, count1=0;
//int loop;
#pragma vector = INT1_vect //Declare Vector
location.
__interrupt void ISR_INT1(void) //Declare
Interrupt Function
{
start = 0;
litemp_value = 0x0000;
while(start == 0)
{
counter0 = 0;
counter1 = 0;
while(PING_PING0 == 0)
{
counter0++;
}
while(PING_PING0 == 1)
{
counter1++;
}
if(counter0 == counter1-1)
start = 1;
}
__delay_cycles(35); // Wait for 125ms
if(PING_PING0)
{
temp_value2 <<= 1;
temp_value2 |= 0x01;
}
else
{
temp_value2 <<= 1;
temp_value2 |= 0x00;
}
__delay_cycles(120); // Wait for 125ms
if(PING_PING0)
{
temp_value2 <<= 1;
temp_value2 |= 0x01;
}
else
{
temp_value2 <<= 1;
temp_value2 |= 0x00;
}
__delay_cycles(120); // Wait for 125ms
if(PING_PING0)
{
temp_value2 <<= 1;
temp_value2 |= 0x01;
}
else
{
temp_value2 <<= 1;
temp_value2 |= 0x00;
}
__delay_cycles(120); // Wait for 125ms
if(PING_PING0)
{
temp_value2 <<= 1;
temp_value2 |= 0x01;
}
else
{
temp_value2 <<= 1;
temp_value2 |= 0x00;
}
__delay_cycles(120); // Wait for 125ms
if(PING_PING0)
{
temp_value2 <<= 1;
temp_value2 |= 0x01;
}
else
{
temp_value2 <<= 1;
temp_value2 |= 0x00;
}
__delay_cycles(120); // Wait for 125ms
if(PING_PING0)
{
temp_value2 <<= 1;
temp_value2 |= 0x01;
}
else
{
temp_value2 <<= 1;
temp_value2 |= 0x00;
}
__delay_cycles(120); // Wait for 125ms
if(PING_PING0)
{
temp_value2 <<= 1;
temp_value2 |= 0x01;
}
else
{
temp_value2 <<= 1;
temp_value2 |= 0x00;
}
__delay_cycles(120); // Wait for 125ms
if(PING_PING0)
{
temp_value2 <<= 1;
temp_value2 |= 0x01;
}
else
{
temp_value2 <<= 1;
temp_value2 |= 0x00;
}
__delay_cycles(120); // Wait for 125ms
while(PING_PING0 == 1);
while(PING_PING0 == 0);
while(PING_PING0 == 1);
__delay_cycles(35); // Wait for 125ms
if(PING_PING0)
{
temp_value1 <<= 1;
temp_value1 |= 0x01;
}
else
{
temp_value1 <<= 1;
temp_value1 |= 0x00;
}
__delay_cycles(120); // Wait for 125ms
if(PING_PING0)
{
temp_value1 <<= 1;
temp_value1 |= 0x01;
}
else
{
temp_value1 <<= 1;
temp_value1 |= 0x00;
}
__delay_cycles(120); // Wait for 125ms
if(PING_PING0)
{
temp_value1 <<= 1;
temp_value1 |= 0x01;
}
else
{
temp_value1 <<= 1;
temp_value1 |= 0x00;
}
__delay_cycles(120); // Wait for 125ms
if(PING_PING0)
{
temp_value1 <<= 1;
temp_value1 |= 0x01;
}
else
{
temp_value1 <<= 1;
temp_value1 |= 0x00;
}
__delay_cycles(120); // Wait for 125ms
if(PING_PING0)
{
temp_value1 <<= 1;
temp_value1 |= 0x01;
}
else
{
temp_value1 <<= 1;
temp_value1 |= 0x00;
}
__delay_cycles(120); // Wait for 125ms
if(PING_PING0)
{
temp_value1 <<= 1;
temp_value1 |= 0x01;
}
else
{
temp_value1 <<= 1;
temp_value1 |= 0x00;
}
__delay_cycles(120); // Wait for 125ms
if(PING_PING0)
{
temp_value1 <<= 1;
temp_value1 |= 0x01;
}
else
{
temp_value1 <<= 1;
temp_value1 |= 0x00;
}
__delay_cycles(120); // Wait for 125ms
if(PING_PING0)
{
temp_value1 <<= 1;
temp_value1 |= 0x01;
}
else
{
temp_value1 <<= 1;
temp_value1 |= 0x00;
}
if(temp_value2 > 0x01)
{
temp = temp_value2;
temp_value2 = temp_value1;
temp_value1 = temp;
}
litemp_value = temp_value2;
|