Professional Documents
Culture Documents
Executive Summary
The new Whirlpool dispenser cup does not only differentiate between powder
and liquid detergent as well as liquid bleach and fabric softener, it also adds a new user
interface via LEDs. This makes the system not only user-friendly, but efficient. Telling
the difference in the cups contents allows the system to optimize energy, and water
usage. Our team, ECE 480 Design Team Eight will provide a prototype of this dispenser
cup design. The system interacts with three sensors, one for each cup, it is robust,
accurate and resistant to moisture, ambient light and vibration originating from the
washing process. The final manufacturing cost of the dispenser cup is less than $4.00.
Whirlpool is a company that has always strived for innovation and sustainability.
With the interaction between Whirlpool, Michigan State University and ECE 480 Design
Team Eight, Whirlpool continues to show that its primary concern is their customers, not
only will they provide a quality product, but they will make this product easy to use while
also being energy and water efficient.
Acknowledgements
On behalf of ECE 480 Design Team Eight, we would like to thank the following people
that have helped us in succeeding to achieve our goals for this project:
Our sponsors from Whirlpool Corporation, Jason Savage and Jeff Landrey for their
guidance, advice and support in the learning and development of our project as well as
the industry
Our facilitator, Dr. Dean Aslam, for his guidance, critique and creativeness that has
solved many issues that we have come across
MSU ECE Technical Services: Mr. Brian Wright and Mrs. Roxanne Peacock, for
supplying and ordering parts along with providing testing equipment
Table of Contents:
Chapter 1 - Introduction ..6
1.1
Whirlpool Project - Dispenser Cup 6
1.2
Whirlpool Corporation .6
1.3
2.2
2.3
2.4
2.5
3.1.1 R e d G r e e n B l u e ( R G B ) L E D 1 8
3.1.2 S u p e r B r i g h t R e d L E D . . 1 9
3.2
3.2.1 E Z 4 3 0 - R F 2 5 0 0 . . 2 0
3.2.2 C C 2 5 0 0 T r a n s c e i v e r w i t h M S P 4 3 0 2 1
3.2.3 A t m e g a 1 2 8 R F A 1 m i c r o c o n t r o l l e r 2 2
3.2.4 A t m e l S t u d i o . . . 2 3
3.3
3.3.1 S i e m e n s N X 9 . 0 . 2 4
3.3.2 Testing Dispenser Cup Model .24
3.3.3 First Design Prototype ..30
3.3.4 F i n a l 3 D C u p D e s i g n . 3 4
3.4
3.4.1 E l e c t r i c a l O p t i c a l S e n s o r . . 3 8
3.4.2 C h e m i r e s i s t o r s . . . 3 9
3.4.3 P h o t o r e s i s t o r s 4 1
3.5
3.5.1 S o l a r C e l l a n d R e c h a r g e a b l e B a t t e r y . . 4 4
3.6
Data Communication 45
3.6.1 U S B . 4 5
3.6.2 W i - F i . . . 4 6
Chapter 4 - Data Tests 47
4.1
4.2
Photoresistor Testing 47
4.3
Summary .49
5.2
5.3
6.2
6.3
6.4
6.5
6.6
Ref erences .. 57
8.2
8.3
8.4
Chapter 1 - Introduction
1.1 Whirlpool Project - Dispenser Cup
Dispenser Cup Contents Detection is the project that Whirlpool has given to
design team eight. Through this project, the team needs to create a dispenser cup that
is able to power itself and also communicate with the appliance without any contact
pads or harnesses. The cup must also support six LEDS, a microcontroller, dispenser
cup sensors and any communication device that the team uses. The cup also has to be
robust to high humidity, temperature (99% humidity with condescension) and vibration.
The entire system should not cost over $4 in manufacturing cost. These are the
requirements proposed by Whirlpool.
1.2 Whirlpool Corporation
Whirlpool Corporation is one of the largest washing machine manufacturers. Its
headquartered is in Benton Charter which is a township in Michigan. The Company
was founded on November 11, 1911. At the very beginning, it was a small company
that produced electric, motor driven, wringer washers. With the science and technology
developing rapidly, most families chose to use a washing machine at home instead of
doing laundry outside washing by hand or driving to the laundromat. So the rigid
demand of having a household washing machine increased rapidly. Whirlpool growing
fast and becoming one of Fortune 500 company, having an annual revenue of about
19 billion dollars. They have more than 70 manufacturing and technology research
centers in the world. However a new problem also came up, which is how to use the
least energy to wash the clothes clean. Being energy efficient and to be
environmentally friendly are two big problems for the manufacturer. In addition, with
the fossil energy being scarce, the government and many environmental protection
organizations are pressing this issue. Energy Star is an international standard for
energy efficient consumer, it was created in 1992 by the Environmental Protection
Agency and the Department of Energy. It aims to encourage the manufacturer to
design the most energy efficient product. We can see the Energy Star label on most of
whirlpool products on the market.The label shows how much energy and money it can
6
save a customer every year. For the customer, they take this into their consideration
when they choose the product. Now, many companies like whirlpool are willing to fund
the research to find a more economically feasible way to reduce energy cost.
Team eight uses mainly three components for this project: mechanical, electrical
and software. The mechanical devices includes the dispenser cup itself and all the other
materials that the team used for testing. The electrical devices includes the
microcontrollers, LEDs and the photoresistors. The software devices include the
programming of the microcontroller and an interface which user can select certain
cycles to test the program. These are the concepts that team eight is able to prove at
the end of this project.
10
11
The house of quality analysis has prioritized our customer wants in this order (highest to
lowest):
Accurate Sensor
Detecting liquid detergent
Detecting powered detergent
Detecting Fabric Softener
Low Cost System
Time for Wireless Communication
Robust and Compact Size
2.3 LED/Sensor/Cup Design
Design team eight has designed the cup to be robust to vibrations and
temperatures and have met the requirements for dispenser cup. The team decided to
put three LEDs on the top layer of the dispenser cup to notify the user that which
content they should be pouring in. The other three LEDs will be implanted within the
dispenser cup and will only light up when materials have been poured in. These LEDs
will serve as a light source for the photoresistor to read. The team is basing this
technology on the thought that the LEDs light will emit different strengths through the
different materials. For example, more light will go through the detergent instead of the
softener. Therefore having difference in those values would help determine what are the
materials that were poured in. After the dispenser cup determines that it is the right
material that has been poured in, then the light would shut off and the cycle would
begin. Therefore with three different cups there will be three different photoresistors on
the cap of each cup. The team has selected to place the LED on the bottom of the cup
and the photoresistor on top implanted in the cap. This is because the team is scared
that photoresistors are not chemical proof and therefore cannot be submerged within
materials. We would want to, however, have them on two sides of the cup to enable
correct readings regardless of the amount of material the user has poured in.
12
Components
Quantity
Cost
Shipping
Total
$4.22
$0.0
$4.22
Solar Cell
$6.95
$0.0
$6.95
$2.98
$5.95
$8.93
$9.95
$0.0
$9.95
TI eZ430-RF2500
$116.28
$0.0
$116.28
$9.94
$0.0
$9.94
$7.98
$0.0
$7.98
Photoresistor
4000
softener
13
$13.99
$5.99
$19.98
TI CC2500
$4.03
$4.09
$12.14
$12.19
$0.0
$12.19
$1.0
$0.0
$1.0
3D print Cup
$23.79
$0.0
$23.79
$40.00
$0.0
$40.00
SparkFun ATmega128RFA1
$171.780
$7.98
$179.76
AA Rechargeable batteries
DECS 3D print of a battery
case
micro-controller
$453.11
Total
14
15
16
17
18
19
3.2.1 EZ430-RF2500
One of the possibility that the team proposes is using the EZ430-RF2500
microcontroller. The purchase of EZ430-RF2500 comes with two boards and a tutorial
manual. These two boards are identical and have 20 pins and a microcontroller. It has
built in wireless communication which allows one board to communicate with the other.
If one board is the main inserted as the main system, the other board will be placed
within our circuit. This microcontroller is selected due to the wireless communication
built within. Although this microcontroller is costly, the team decided to use it for the
testing stage of the project. With this microcontroller the team is able to light up the
LEDS for the cup with the three different colors. However the main issue with this
20
microcontroller that it is hard to program and very expensive. Therefore the team began
to explore other options that might be a better fit to this project.
21
Figure 3.2.2.1/2 MSP430G2553 Microcontroller (1) along with CC2500 Transceiver (2)
Figure 3.2.3.1
22
Figure 3.2.3.2
23
24
25
26
27
28
29
In the first layer, there are three cups for detergent, bleach and softener
respectively. Also, there are three LEDs besides each cup. The application of the LEDs
is to tell the customer which cup needs to be filled and what should be put in the cup.
For example, when the detergent cup needs to be filled, the LED besides the cup will
turn to blue. When the cup is filled with the correct material and amount, the LED will
turn to green, otherwise the LED will be red.
30
Figure 3.3.2-11 Top View of the Second Layer of the Dispenser Cup
31
Figure 3.3.2-12 Bottom View of the Second Layer of the Dispenser Cup
The bottom layer is to store the microcontroller, battery and other circuits. There
is also a common path for detergent/bleach/softener to go through to main part of the
washer.
To stabilize the dispenser cup, bars have been design in the second and bottom
layer. There are rectangular shaped bar holes at the bottom of the first and second layer
for bars to insert in.
32
Figure 3.3.2-13 Top View of the Bottom Layer of the Dispenser Cup
The storage place is to store the microcontroller, power supply circuit and
battery. The LEDs of the first layer will be directly connected to the circuit from the
bottom layer. To keep the electrical circuit and microcontroller out of water, the storage
place and the detergent/bleach/softener path has been separated.
33
Figure 3.3.2-14 Side View of the Bottom Layer of the Dispenser Cup
34
35
36
37
38
is the electric trigger. The electric trigger is usually a separate device that you used to
measure current through the pull-up resistor. In our case, the microcontroller is the
electric trigger to constantly measure the current at the logic output of the sensor. The
current value depending on the amount of light will determine a logic high (1) or low (0).
3.4.2 Chemiresistors
This is one of the alternative solutions that the design team proposed. The way it
works is that it takes the chemicals that are within the detergents/softener and bleach.
Having these touching the base of the chemiresistor would then produce an electrical
39
current. Different materials create different electrical currents and the user gets to
monitor those currents. With this being said, the team then could determine what
material is currently being sensed through the chemiresistor and then the team could
determine what to do with the data given. For example the team could decide to light up
the LED into the red light to show that it is the wrong material. Another way is that the
LED could be turned into green to show that it is the right material that has been poured
in the cup. This is an alternative sensor that is suggested because it is also quite cheap
in cost. Refer to Figure 3.4.2 for the way that Chemiresistors work graphically.
40
3.4.3 Photoresistor
The light sensing concept consists of emitting light through the contents inside
the dispenser cup. In mind of keeping our design simple and cost effective, we decided
to go with a LED as our light source and a photoresistor as our light detector (figure
3.4.3.1). Using this design the only components needed are: two different resistors, a
photoresistor, a LED and a voltage supply. Only needing five total components can
keep the total cost to a minimum and also gives us the chance to experiment with
different parts and values for this design. With the design of this sensor being very
straight forwards it provides very accurate readings with minimal failure. A very accurate
sensor is detrimental to the customer since the washing machine is used in rough
condition. Violent vibrations, residual moisture, temperature flux and chemical corrosion
are the external factors that can possibly cause our sensor to fail. By using the
suggested design, these factors will have an insignificant effect on our light source and
photoresistor in detecting a change in the intensity of light.
The device sensing the light is the photoresistor. The light from the LED is
essentially what the photoresistor is constantly monitoring and is told to the user by the
41
changing value of its resistance. Well how and why is light effecting the resistor? The
answer to that is photoconductivity; this is the driving principle behind the photoresistor.
Photoconductivity is the electrical phenomenon in which a material becomes more
electrically conductive due to the absorption of electromagnetic radiation (light). The
next question may be what material of the resistor gives it the photoconductive
properties? The material that makes this possible is an inorganic chemical called
cadmium sulfide (CdS). This chemical is intrinsic when undoped, meaning that photons
excite the valence electrons across the band gap to become conductive electrons.
When light strikes the surface of the cadmium sulfide the electrons get a boost in
energy and they hop across the band gap of 2.4 volts and move freely (figure 3.4.3.2).
In the graph you can see the x-axis the electric potential and the y-axis is the energy of
the photons in cadmium sulfide. At 2.4 volts the photon's energy is excited and the
value of it increases rapidly. In addition to the electron roaming free, it also creates a
hole that is technically positively charged and wants to be filled by an electron making
the composition of the material impure and causes the conductivity to rise. In terms of
the resistor, current can flow easily through it, making a very low resistance in light and
a very high resistance in the dark. The cadmium sulfide is made into a thin track the
runs across the electrodes and then connects to the terminals of the resistor (figure
3.4.3.3). This makes the photoresistor a passive element meaning it doesn't have a P-N
junction.
42
43
44
45
communicate with the computer, X-CTU is a necessary tool for serial port to transceive
and receive data. With the help of hardware (USB port and microcontroller) and the
software (X-CTU), we can easily communicate between computer and microcontroller
3.6.2 Wireless communication
Since the computer is not wired with the microcontroller on the dispenser cup
directly, wireless communication between the two microcontroller is necessary. The
whole communication system will be implemented like this: 1. The user enters the cycle
number into the computer. 2. The computer will transfer the cycle number to the
microcontroller through USB port. 3. The microcontroller on USB will transfer the data
to the microcontroller on dispenser cup wirelessly. 4. The microcontroller on the
dispenser cup get the information and control everything directly. so the whole system
will be shown in figure 3.6.2
Figure 3.6.2
46
Photoresistor values
Light Intensity
Covered
Base (inside
unfilled dispenser
cup)
Ambient
Resistance (ohms)
160K
26.7K
16.7K
Table 4.2
47
RGB
Color
R
0.49
0.30
0.38
0.38
0.45
1.1
1.1
1.1
0.58
0.34
0.43
Base (V)
Table 4.3
48
49
50
51
photoresistor is very sensitive to light and readings could differentiate based on where
the cup is located at the time. Therefore the team strongly suggests a better sensor with
a more controlled environment could enhance the quality of the dispenser cup.
52
Chapter 6 - Appendix 1
Left to Right: Daniel Gomez, Connor Grossman, Gao Xin, Hongyi Shen, Daniel Sun
53
54
Along with these task, Mr. Grossman also took a lead role with phone conference
calls with Jason and Jeff that included speaking and explaining progress of team eight.
Connor was the main source of communication with Whirlpool and was in charge of
relaying information to them.
6.4 Daniel Gomez
Mr. Gomez technical role is the microcontroller programmer and presentation
manager. Mr. Gomez has investigated the optimal configuration of the microcontroller
for interfacing with the dispenser cup and how to implement the wireless communication
with the main system of the washing machine. The effects of sample-and-hold time and
reference voltage configurations of the Analog-to-Digital converter have been
extensively tested by him. Mr. Shen and Mr. Gomez have collaborated to establish the
best protocol for the wireless communications and the sensor interfacing. The
microcontroller programming for serial communication configuration and protocol were
researched and implemented by him.
The second role of Mr. Gomez is Lab Coordinator, Mr Gomez was in charge of
ordering all the parts necessary for the prototype. Mr Gomez was in charge of setting
meetings with the facilitator and he also help with the design of the sensor and power
supply.
6.5 Hong Yi Shen
Mr. Shens technical role is the microcontroller programmer. Based on Mr.
Shens previous working experience on programming the microcontroller for many
robot. Mr. Shen is familiar with the Atmega128rfa1 microcontroller. He configured
wireless communication, UART, Analog to Digital converter, LED control for
Atmega128rfa1. He work with other teammates closely, to make sure the the program
can be used by the configured code. In addition, Mr. Shen also in charge to weld the
brand new microcontroller with the chips. Due to the limitation of the microcontroller
port, for example, there are only 8 pin for Analog to Digital and some other pins have
limitation functions like transceive and receive so he arranged the pin for LEDs was also
done by Mr.Shen.
55
As the presentation preparer, Mr. Shen and Daniel Sun invited other members to
make powerpoints online and after everyone finish their own part, he make up the team
to do the practice and make sure the time is not too long or too short. If necessary, he
will discuss with the team to adjust some parts.
56
Chapter 7 - Appendix 2
7.1 References
http://www.johnloomis.org/ece445/topics/egginc/pt_app.html
http://www.radioelectronics.com/info/data/semicond/phototransistor/photo_transistor.php
http://en.wikipedia.org/wiki/Photodiode
http://www.teccogroup.com/LED-Rope-light-p404.html
http://en.wikipedia.org/wiki/LED_lamp
http://naturescreationsinc.com/alternative-systems/led-lighting/
http://en.wikipedia.org/wiki/Analog-to-digital_converter
http://www.radio-electronics.com/info/data/resistor/ldr/light_dependent_resistor.php
http://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter
http://kids.britannica.com/comptons/art-53789/Photoresistor
http://www.edn.com/design/analog/4368794/Simple-night-light-uses-a-photoresistor-todetect-dusk
http://www.education.rec.ri.cmu.edu/content/electronics/boe/light_sensor/1.html
http://nguyenmarysci4.tumblr.com/post/45739083253/what-the-led-how-it-does-it-work
Electro-optical Senor Wikipedia. Wikimedia Foundation Inc., 4 Feb. 2015. Web. 13
Mar. 2015.
What is an Optical Sensor? wiseGEEK. Conjecture Corperation, 12 Mar. 2015. Web.
13 Mar.
2015.
Ball, Stuart. Exploring optical and magnetic sensors. Embedded. 17 Jun. 2003. Web.
13 Mar. 2015.
Cadmium Sulfide Wikipedia. Wikimedia Foundation Inc., 22 Feb. 2015. Web. 24 Mar.
2015.
57
Chapter 8 - Appendix 3
8.1 Parts Identification
58
59
60
61
Figure 8.1-7 Materials From left to right (Bleach, Detergent, Softener, Detergent,
Bleach)
62
63
64
Author: ratmandu
*/
#ifndef RADIO_H_
#define RADIO_H_
#define TRX_MAX_FRAME_SIZE 127
#define TRX_FIFO_SIZE 128
#define TRX_WAIT_BEFORE
//#define TRX_WAIT_AFTER
#define SHORT_ADDR_L 0xFE
#define SHORT_ADDR_H 0xED
#define RADIO_CHANNEL 20
#define PAN_ADDR 0xACDC
#define MAC_ADDR_0 0x01
#define MAC_ADDR_1 0x23
#define MAC_ADDR_2 0x45
#define MAC_ADDR_3 0x67
#define MAC_ADDR_4 0x89
#define MAC_ADDR_5 0xab
#define MAC_ADDR_6 0xcd
#define MAC_ADDR_7 0xef
65
#define modifyReg(var, mask, value) (var = ((var & ~mask) | (value & mask)))
// Transceiver state status
#define TRX_STATUS_MASK
0x1f
enum
{
STATUS_BUSY_RX = 0x01,
STATUS_BUSY_TX = 0x02,
STATUS_RX_ON = 0x06,
STATUS_TRX_OFF = 0x08,
STATUS_PLL_ON = 0x09,
STATUS_SLEEP = 0x0f,
STATUS_BUSY_RX_AACK = 0x11,
STATUS_BUSY_TX_ARET = 0x12,
STATUS_RX_AACK_ON = 0x16,
STATUS_TX_ARET_ON = 0x19,
STATUS_STATE_TRANSITION_IN_PROGRESS = 0x1f
};
// Transceiver state change commands
enum
{
STATE_NOP = 0x00,
STATE_TX_START = 0x02,
STATE_FORCE_TRX_OFF = 0x03,
STATE_FORCE_PLL_ON = 0x04,
STATE_RX_ON = 0x06,
STATE_TRX_OFF = 0x08,
STATE_PLL_ON = 0x09,
66
STATE_RX_AACK_ON = 0x16,
STATE_TX_ARET_ON = 0x19
};
#define PHY_RSSI_MASK
#define PHY_RSSI_RANDOM_MASK
#define TRX_BUF(i)
0x1f
0x60
_SFR_MEM8(0x180 + i)
void trx_leaveTRXSleep();
void trx_setPANID(uint16_t panid);
void trx_setShortAddress(uint16_t shortaddr);
void trx_setExtAddress(uint8_t* extaddr);
void trx_waitWhile(uint8_t status);
void trx_getExtAddress(uint8_t* addr);
uint16_t trx_getShortAddress();
uint16_t trx_getPANID();
uint8_t trx_isSleeping();
uint8_t trx_getTRXState();
uint8_t trx_getRandomNumber();
uint8_t trx_getRSSI();
#endif /* RADIO_H_ */
2. head file serial.h (from sparkfun.com)
/*
* serial.h
*
* Created on: Jan 29, 2012
*
Author: ratmandu
*/
#ifndef SERIAL_H_
#define SERIAL_H_
#define SERIAL_0_RX_BUF_LEN
256
68
char serial0RxBuf[SERIAL_0_RX_BUF_LEN];
char serial1RxBuf[SERIAL_1_RX_BUF_LEN];
uint8_t bytesInSerial0RxBuf;
uint8_t bytesInSerial1RxBuf;
uint8_t buffer0ReadLoc, buffer0WriteLoc;
uint8_t buffer1ReadLoc, buffer1WriteLoc;
void initSerial0(uint32_t baud);
void initSerial1(uint32_t baud);
void serial0PutChar(unsigned char data);
void serial1PutChar(unsigned char data);
void serial0PutString(unsigned char *str);
void serial1PutString(unsigned char *str);
void initSerial0RxBuf(void);
void initSerial1RxBuf(void);
void writeToBuffer0(unsigned char data);
void writeToBuffer1(unsigned char data);
unsigned char readFromBuffer0(uint8_t *bufsize);
unsigned char readFromBuffer1(uint8_t *bufsize);
void buf0SkipTo(unsigned char data);
void buf1SkipTo(unsigned char data);
uint8_t buf0Size(void);
uint8_t buf1Size(void);
void USART0_RX_vect(void);
void USART1_RX_vect(void);
#endif /* SERIAL_H_ */
/*
this head file include most of basic function of wireless function
*/
#ifndef TRX_H_INCLUDED
#define TRX_H_INCLUDED
#define SERIAL_0_RX_BUF_LEN
256
70
71
#define TRX_STATUS_MASK
0x1f
enum
{
STATUS_BUSY_RX = 0x01,
STATUS_BUSY_TX = 0x02,
STATUS_RX_ON = 0x06,
STATUS_TRX_OFF = 0x08,
STATUS_PLL_ON = 0x09,
STATUS_SLEEP = 0x0f,
STATUS_BUSY_RX_AACK = 0x11,
STATUS_BUSY_TX_ARET = 0x12,
STATUS_RX_AACK_ON = 0x16,
STATUS_TX_ARET_ON = 0x19,
STATUS_STATE_TRANSITION_IN_PROGRESS = 0x1f
};
// Transceiver state change commands
enum
{
STATE_NOP = 0x00,
STATE_TX_START = 0x02,
STATE_FORCE_TRX_OFF = 0x03,
STATE_FORCE_PLL_ON = 0x04,
STATE_RX_ON = 0x06,
STATE_TRX_OFF = 0x08,
STATE_PLL_ON = 0x09,
STATE_RX_AACK_ON = 0x16,
STATE_TX_ARET_ON = 0x19
};
72
#define PHY_RSSI_MASK
#define PHY_RSSI_RANDOM_MASK
0x1f
0x60
#define TRX_BUF(i)
_SFR_MEM8(0x180 + i)
{
PHY_CC_CCA = ((PHY_CC_CCA & ~0x1F) | (channel & 0x1F));
}
void trx_calibrate()
//calibrate transceiver
{
FTN_CTRL |= (1 << FTN_START);
PLL_CF |= (1 << PLL_CF_START);
PLL_DCU |= (1 << PLL_DCU_START);
}
void trx_setTXPower(uint8_t power) // transmit power control
{
74
{
trx_setTRXState(STATE_TRX_OFF);
}
void trx_leaveTRXSleep()
{
trx_setTRXState(STATE_RX_ON);
}
void trx_setPANID(uint16_t panid) //set PANID for both low and high addresses
{
PAN_ID_0 = (panid & 0xFF);
PAN_ID_1 = ((panid >> 8) &0xFF);
}
void trx_setShortAddress(uint16_t shortaddr) //set the low and high short addresses
75
{
SHORT_ADDR_0 = (shortaddr & 0xFF);
SHORT_ADDR_1 = (shortaddr >>8) &0xFF;
}
void trx_setExtAddr(uint8_t* extaddr)
{
IEEE_ADDR_0 = extaddr[0];
IEEE_ADDR_1 = extaddr[1];
IEEE_ADDR_2 = extaddr[2];
IEEE_ADDR_3 = extaddr[3];
IEEE_ADDR_4 = extaddr[4];
IEEE_ADDR_5 = extaddr[5];
IEEE_ADDR_6 = extaddr[6];
IEEE_ADDR_7 = extaddr[7];
}
void trx_waitWhile(uint8_t status)
{
while (trx_getTRXState() == status)
{
;
}
}
uint16_t trx_getShortAddress()
{
uint16_t shortAddr;
shortAddr = (SHORT_ADDR_H << 8);
shortAddr |= SHORT_ADDR_L;
return shortAddr;
76
}
uint16_t trx_getPANID()
{
uint16_t panID;
panID = (PAN_ID_1 << 8);
panID |= PAN_ID_0;
return panID;
}
void trx_getExtAddr(uint8_t* addr)
{
addr[0] = IEEE_ADDR_0;
addr[1] = IEEE_ADDR_1;
addr[2] = IEEE_ADDR_2;
addr[3] = IEEE_ADDR_3;
addr[4] = IEEE_ADDR_4;
addr[5] = IEEE_ADDR_5;
addr[6] = IEEE_ADDR_6;
addr[7] = IEEE_ADDR_7;
}
uint8_t trx_isSleeping()
{
if (trx_getTRXState() == STATUS_SLEEP)
return 1;
else
return 0;
}
uint8_t trx_getTRXState()
77
{
return (TRX_STATUS & TRX_STATUS_MASK);
}
uint8_t trx_getRSSI()
// read PSSI
{
return PHY_RSSI & PHY_RSSI_MASK;
}
/*=================================================================
=================================*/
//function for data array transmit:
//write into frame buffer and transmit data from frame buffer
void trx_send_data(uint8_t command)
{
// make sure we aren't receiving anything, wait till RX_BUSY finished
trx_waitWhile(STATUS_BUSY_RX);
// turn on PLL and prepare for transmission ( change to PLL_O11N state)
trx_setTRXState(STATE_PLL_ON);
//write data into frame buffer
//Note: To send more than one byte data, write them into the rest byte of the
frame buffer (total 255)
TRX_FRAME_BUFFER(1)=command;
//TRX_BUF(i+1) = 't';
78
;
// start transmission
trx_setTRXState(STATE_TX_START);
}
#endif
4. code for the microcontroller on the usb port. C.file (edit by Hongyi Shen)
/*
* com.c
*
* Created: 4/20/2015 5:39:37 PM
* Author: shenhon2
*/
#include <avr/io.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/power.h>
#include <util/atomic.h>
#include <string.h>
#include "trx.h"
//h. file
communication
79
//=====================================
//uint8_t currentlyTransmitting;
void trx_radioInit();
//=======================================================
uint8_t command_recieved=0;
int main(void)
{
OSCCAL=0b10001100;
// set
calibration byte
//setup I/O port
//1 = output, 0 = input
DDRD = 0b11111011; //PORTD (RX on PD2)
clock_prescale_set(clock_div_1_rc);
initSerial1(921600);
//
initSerial1RxBuf();
trx_radioInit();
flag here
printf("Cycle 1: Detergent & Bleach\n");
printf("Cycle 2: Detergent & Softener\n");
80
interrupt coming
{
}
}
//RF function description
//=================================================================
===============//
void trx_radioInit() //initiate transceiver
{
cbi(SCCR0, SCCKSEL);
trx coming into sleep mode it will automatically set as 1. but we need it as 0 when it
wake up
uint8_t addr[8];
addr[0] = MAC_ADDR_0;
addr[1] = MAC_ADDR_1;
addr[2] = MAC_ADDR_2;
addr[3] = MAC_ADDR_3;
addr[4] = MAC_ADDR_4;
addr[5] = MAC_ADDR_5;
addr[6] = MAC_ADDR_6;
addr[7] = MAC_ADDR_7;
IRQ_STATUS |= (1 << TX_END) | (1 << RX_END) | (1 << RX_START);
//pending interrupt request
81
//select channel 20
//giving panid address
trx_setTRXState(STATE_RX_ON);
complete
trx_calibrate();
_delay_ms(500);
printf("RF transciever setup!!!\n");
}
//**************************************************************************************************
**//
//function for usart
//initial seiall which work for buad rate as 921600
void initSerial1(uint32_t baud)
{
uint32_t baudreg;
baudreg = (F_CPU/baud/8-1);
UBRR1H = (uint8_t)((baudreg >> 8) & 0xFF);
UBRR1L = (uint8_t)(baudreg & 0xFF);
//UCSR1A = 0x00;
82
sbi(UCSR1A,U2X1);
UCSR1B = (1<<TXEN1) | (1<<RXEN1)|(1<<RXCIE1); //activate RX interrupt
UCSR1C = 0x06; //asynchronous, no parity,
stdout = &mystdout; //Required for printf init
printf("Serial communication setup!!!\n");
}
static int uart_putchar(char c, FILE *stream)
{
if (c == '\n') uart_putchar('\r', stream);
loop_until_bit_is_set(UCSR1A, UDRE1);
UDR1 = c;
return 0;
}
uint8_t uart_getchar(void)
{
while( !(UCSR1A & (1<<RXC1)) );
return(UDR1);
}
//interrupt rountine
ISR(TRX24_TX_END_vect)
//RX_ON interrupt
{
trx_setTRXState(STATE_RX_ON);
}
83
ISR(TRX24_RX_END_vect)
{
if (ReadBit(PHY_RSSI, RX_CRC_VALID) == 0)
{
return;
}
command_recieved = TRX_FRAME_BUFFER(0);
//printf("data is %c\n",command_recieved);
}
ISR(TRX24_RX_START_vect)
{
rssi = PHY_RSSI;
}
5. code for the microcontroller embedded with dispenser cup. C.file (edit by Hongyi
Shen)
/*
* cup.c
*
* Created: 4/20/2015 5:35:16 PM
* Author: shenhon2
*/
//h. file
communication
//RF communication's function defined
//=====================================
//uint8_t currentlyTransmitting;
void trx_radioInit(); //initialize the RF transceiver
//=======================================================
//serial communication function
85
///sbi(PORTB,PORTB1);
clock_prescale_set(clock_div_1_rc); //set up the clock with division factor of 1
initSerial1(921600);
(serial communication)
DDRB |= 0b11111111;
DDRE |= 0b11111111;
DDRF |= 0b11110000;
DDRG |= 0b11100100;
initSerial1RxBuf();
86
trx_radioInit();
ADCSRB and bit 4:0 selects Analog Channel (single ended input ADC0)
ADCSRA=0b10000001;
Select Bits;
ADCSRC=0b00000111; //Bits 7:6 ADC Track-and-Hold Time (ADTHT);
Bits 4:0 C ADSUT4:0: ADC Start-up Time (ADSUT): startup time = 4(ADSUT+1),
minimum 20 s
cbi(ADCSRB,MUX5); //mux5 need to be 0, mux 5 is part of mux0:5
while(1)
{/*
ADCSRA = (1<<ADEN) + (1<<ADSC) + (2<<ADPS0); //enable adc
do
{} while( (ADCSRA & (1<<ADSC))); //wait adc complete
ADCSRA = 0x00;
TEMP1=ADCL;
TEMP2=ADCH;
TEMP = (ADCH << 8) + ADCL;
printf("\n %d ",TEMP1);
printf("\n %d ",TEMP2);
printf("\n %d ",TEMP);
*/
}
87
return 1;
}
//function of read data
uint16_t readd()
{
//initialize F0 as adc single read port
cbi(PRR0,PRADC);
cbi(DDRC,DDC0);
ADMUX=0b11000000;
ADCSRB and bit 4:0 selects Analog Channel (single ended input ADC0)
ADCSRA=0b10000001;
Select Bits;
ADCSRC=0b00000111; //Bits 7:6 ADC Track-and-Hold Time (ADTHT);
Bits 4:0 C ADSUT4:0: ADC Start-up Time (ADSUT): startup time = 4(ADSUT+1),
minimum 20 s
cbi(ADCSRB,MUX5); //mux5 need to be 0, mux 5 is part of mux0:5
//start read
ADCSRA = (1<<ADEN) + (1<<ADSC) + (2<<ADPS0); //enable adc
do
{} while( (ADCSRA & (1<<ADSC))); //wait adc complete
ADCSRA = 0x00;
TEMP1=ADCL;
TEMP2=ADCH;
TEMP = (ADCH << 8) + ADCL;
trx_send_data(TEMP);
printf("\n %d ",TEMP);
cbi(ADCSRA,ADEN);
88
sbi(PRR0,PRADC);
_delay_ms(20);
return TEMP;
}
uint16_t reads()
{
//initialize F1 as adc single read port
cbi(PRR0,PRADC);
cbi(DDRC,DDC0);
ADMUX=0b11000001;
ADCSRB and bit 4:0 selects Analog Channel (single ended input ADC0)
ADCSRA=0b10000001;
Select Bits;
ADCSRC=0b00000111; //Bits 7:6 ADC Track-and-Hold Time (ADTHT);
Bits 4:0 C ADSUT4:0: ADC Start-up Time (ADSUT): startup time = 4(ADSUT+1),
minimum 20 s
cbi(ADCSRB,MUX5); //mux5 need to be 0, mux 5 is part of mux0:5
//start read
ADCSRA = (1<<ADEN) + (1<<ADSC) + (2<<ADPS0); //enable adc
do
{} while( (ADCSRA & (1<<ADSC))); //wait adc complete
ADCSRA = 0x00;
TEMP1=ADCL;
TEMP2=ADCH;
TEMP = (ADCH << 8) + ADCL;
trx_send_data(TEMP);
printf("\n %d ",TEMP);
89
cbi(ADCSRA,ADEN);
sbi(PRR0,PRADC);
_delay_ms(20);
return TEMP;
}
uint16_t readb()
{
//initialize F2 as adc single read port
cbi(PRR0,PRADC);
cbi(DDRC,DDC0);
ADMUX=0b11000010;
ADCSRB and bit 4:0 selects Analog Channel (single ended input ADC0)
ADCSRA=0b10000001;
Select Bits;
ADCSRC=0b00000111; //Bits 7:6 ADC Track-and-Hold Time (ADTHT);
Bits 4:0 C ADSUT4:0: ADC Start-up Time (ADSUT): startup time = 4(ADSUT+1),
minimum 20 s
cbi(ADCSRB,MUX5); //mux5 need to be 0, mux 5 is part of mux0:5
//start read
ADCSRA = (1<<ADEN) + (1<<ADSC) + (2<<ADPS0); //enable adc
do
{} while( (ADCSRA & (1<<ADSC))); //wait adc complete
ADCSRA = 0x00;
TEMP1=ADCL;
TEMP2=ADCH;
TEMP = (ADCH << 8) + ADCL;
trx_send_data(TEMP);
90
printf("\n %d ",TEMP);
cbi(ADCSRA,ADEN);
sbi(PRR0,PRADC);
_delay_ms(20);
return TEMP;
}
addr[1] = MAC_ADDR_1;
addr[2] = MAC_ADDR_2;
addr[3] = MAC_ADDR_3;
addr[4] = MAC_ADDR_4;
addr[5] = MAC_ADDR_5;
addr[6] = MAC_ADDR_6;
addr[7] = MAC_ADDR_7;
IRQ_STATUS |= (1 << TX_END) | (1 << RX_END) | (1 << RX_START);
//pending interrupt request
IRQ_MASK |= (1 << TX_END_EN) | (1 << RX_END_EN) | (1 <<
RX_START_EN); //enable interrupt
trx_setTRXState(STATE_FORCE_TRX_OFF);
91
//select channel 20
//giving panid address
trx_setTRXState(STATE_RX_ON);
complete
trx_calibrate();
printf("RF transceiver initialization succeeds!\n");
}
void nolight()
{
PORTE &= 0b00000011;
PORTB &= 0b00011111;
PORTF &= 0b00011111;
}
//***********************************//
//function definition for serial communication
//initial seiall which work for buad rate as 921600
void initSerial1(uint32_t baud)
{
uint32_t baudreg;
baudreg = (F_CPU/baud/8-1);
UBRR1H = (uint8_t)((baudreg >> 8) & 0xFF);
UBRR1L = (uint8_t)(baudreg & 0xFF);
//UCSR1A = 0x00;
sbi(UCSR1A,U2X1);
92
//====================================================
static int uart_putchar(char c, FILE *stream)
{
if (c == '\n') uart_putchar('\r', stream);
loop_until_bit_is_set(UCSR1A, UDRE1);
UDR1 = c;
return 0;
}
uint8_t uart_getchar(void)
{
while( !(UCSR1A & (1<<RXC1)) );
return(UDR1);
}
//==========================================================
ISR(TRX24_TX_END_vect)
//RX_ON interrupt
93
{
trx_setTRXState(STATE_RX_ON);
}
ISR(TRX24_RX_END_vect)
{
if (ReadBit(PHY_RSSI, RX_CRC_VALID) == 0)
{
return;
}
uint8_t command_recieved;
command_recieved=TRX_FRAME_BUFFER(0);//read the data in frame buffer,
received by RF transmission
//following part is just an example: control the light.
//they can be edited on different port and pin or add different code to realize
different function
/* Determine the control command */
switch (command_recieved)
{
case 0x31:
nolight();
//Detergent
sbi(PORTE,PORTE7);
sbi(PORTF,PORTF5);
_delay_ms(10000);
94
cbi(PORTE,PORTE7);
output=readd();
if ((output<=195)&(output >=160))
{
sbi(PORTE,PORTE6);
}
else if((output<155)&(output>160))
{
output=readd();
if ((output<195)&(output >=160))
{
sbi(PORTE,PORTE6);
}
else
{
sbi(PORTE,PORTE5);
}
}
else
{
sbi(PORTE,PORTE5);
}
_delay_ms(2000);
nolight();
_delay_ms(2000);
//Bleach
sbi(PORTB,PORTB7);
sbi(PORTF,PORTF7);
_delay_ms(10000);
95
cbi(PORTB,PORTB7);
output=readb();
if ((output<=160)&(output >=140))
{
sbi(PORTB,PORTB6);
}
else if((output<140)&(output>120))
{
output=readb();
if ((output<140)&(output >=130))
{
sbi(PORTB,PORTB6);
}
else
{
sbi(PORTB,PORTB5);
}
}
else
{
sbi(PORTB,PORTB5);
}
_delay_ms(2000);
nolight();
_delay_ms(2000);
break;
case 0x32:
97
nolight();
_delay_ms(2000);
// softener
sbi(PORTE,PORTE4);
sbi(PORTF,PORTF6);
_delay_ms(10000);
cbi(PORTE,PORTE4);
output=reads();
if ((output<=195)&(output >=180))
{
sbi(PORTE,PORTE3);
}
else if((output<180)&(output>160))
{
output=reads();
if ((output<180)&(output >=170))
{
sbi(PORTE,PORTE3);
}
else
{
sbi(PORTE,PORTE2);
}
}
else
{
sbi(PORTE,PORTE2);
}
_delay_ms(2000);
98
nolight();
_delay_ms(2000);
break;
case 0x33:
99
else
{
sbi(PORTE,PORTE5);
}
_delay_ms(2000);
nolight();
_delay_ms(2000);
break;
case 0x34:
100
{
sbi(PORTE,PORTE5);
}
}
else
{
sbi(PORTE,PORTE5);
}
_delay_ms(2000);
nolight();
_delay_ms(2000);
// softener
sbi(PORTE,PORTE4);
sbi(PORTF,PORTF6);
_delay_ms(10000);
cbi(PORTE,PORTE4);
output=reads();
if ((output<=195)&(output >=180))
{
sbi(PORTE,PORTE3);
}
else if((output<180)&(output>160))
{
output=reads();
if ((output<180)&(output >=170))
{
sbi(PORTE,PORTE3);
}
else
{
101
sbi(PORTE,PORTE2);
}
}
else
{
sbi(PORTE,PORTE2);
}
_delay_ms(2000);
nolight();
_delay_ms(2000);
//Bleach
sbi(PORTB,PORTB7);
sbi(PORTF,PORTF7);
_delay_ms(10000);
cbi(PORTB,PORTB7);
output=readb();
if ((output<=160)&(output >=140))
{
sbi(PORTB,PORTB6);
}
else if((output<140)&(output>120))
{
output=readb();
if ((output<140)&(output >=130))
{
sbi(PORTB,PORTB6);
}
else
{
sbi(PORTB,PORTB5);
102
}
}
else
{
sbi(PORTB,PORTB5);
}
_delay_ms(2000);
nolight();
_delay_ms(2000);
break;
case 0x35:
103
readb();
break;
default:
break;
}
printf("get the char is %c\n",command_recieved);//
//trx_send_data(command_recieved);
}
ISR(TRX24_RX_START_vect)
{
rssi = PHY_RSSI;
}
104
Once the values were substituted the equation looked like this:
0.3 = 3.3
26
+ 26
Using basic algebraic principle, you can easily solve for R which is 260K. We opted to
use a resistor with the value of 270k because it could be provided for free through the
ECE 480 lab.
105