Wednesday, May 4, 2011

Lab 4

Part A: Data-logging to non-volatile memory


EEPROM allows the user to save non-volatile data on the Arduino so that the information is not lost when the Arduino is powered down.  The user can save their non-volatile data in the 1024 bytes that the Arduino has available.    The main two functions used in data-logging are:

value = EEPROM.read(address);

EEPROM.write(address, value);



Basically, for the purpose of this lab, a value was stored for each byte less than or equal to 512.  Each value corresponded to the byte where the specific value was stored.  For instance the value "45" was stored in byte "45" in the non-volatile memory of the Arduino.  After the numbers were stored using EEPROM, the Arduino was powered down by unplugging the Arduino from the USB.  After plugging in the Arduino back into to the computer, the correct values were read from the EEPROM, proving that that the Arduino correctly stored the values in its non-volatile memory.  The code can be seen below:

#include <EEPROM.h>
int value;
int i=0;
int a;
void setup()
{
   Serial.begin(9600);
  
    EEPROM.write(a, a);
}

void loop()
{
  if (a <= 512);
  {
   a=i++;
   value = EEPROM.read(a);
  Serial.println(value);
  Serial.print("\n");
  delay(20);
  }

}

Part B: Mechatronics- build a rotational positioning device


The servo is controlled by sending a pulse to the device at least every 20 ms, so the servo is not moved out of position.  Basically the duration of the pulse determines the position that the servo moves to.  Although numbers vary slightly depending on the Arduino, a pulse width of 1 ms corresponds to a position of 0 degrees, a pulse width of 1.5 ms corresponds to 90 degrees, and a pulse width of 2 ms corresponds to a position of 180 degrees.  Similarly, the servo can be moved to any position within this range by selecting the appropriate pulse width between 1 to 2 ms.  The code for the first, most basic part of this lab can be seen below:


Code 1:

int buttonPin = 10;


void setup() {Serial.begin(9600);
pinMode(buttonPin, OUTPUT);

}

void loop()
{
 
      


     digitalWrite(buttonPin, HIGH);
     delayMicroseconds(2);
     digitalWrite(buttonPin, LOW);
     delayMicroseconds(1);
    
      
}


_________________________________________________________



Next, the servo was reversed back and forth.   This was done by uploading the following code to the Arduino:

Code 2:

int buttonPin = 10;
int i;

void setup() {Serial.begin(9600);
pinMode(buttonPin, OUTPUT);

}

void loop() 
{
  
       
for(i=0;i<2000;i=i+2)
{
     digitalWrite(buttonPin, HIGH);  
     delayMicroseconds(i);
     digitalWrite(buttonPin, LOW);
     delayMicroseconds(19000-i);
     
       
}



Next, the servo was controlled by entering an actual angle value rather than just a "time" pulse width in order to control the position.  Additionally, the speed of the servo motor was controlled.  Both of these were done by using the following code:

Code 3:


int buttonPin = 10;
int count=5;
int moveServo;
void setup() {Serial.begin(9600);
pinMode(buttonPin, OUTPUT);

}



void loop()  {
 if (Serial.available() > 0) 
{
  moveServo = Serial.read();
  if (moveServo == 49) {
  for (count = 5 ; count <= 50 ; count += 5)   // Count by 5 to gradually increase steps
  {
                 
        analogWrite(buttonPin, 180);           
                 
        delay(30);                             
  }
  for (count = 50 ; count >= 5 ; count -= 5)   // Count down by 5 to gradually decrease steps
  {   
               //higher count= slower speed
        analogWrite(buttonPin, 60);           
         
        delay(30); 
  }
  }
  if (moveServo == 50) {
  for (count = 5 ; count <= 150 ; count += 5)   // Count by 5 to gradually increase steps
  {
                 
        analogWrite(buttonPin, 180);           
                 
        delay(50);                             
  }
  for (count = 150 ; count >= 5 ; count -= 5)   // Count down by 5 to gradually decrease steps
  {   
               //higher count= slower speed
        analogWrite(buttonPin, 60);           
         
        delay(50); 
  }
  }
  if (moveServo == 51) {
  for (count = 5 ; count <= 250 ; count += 5)   // Count by 5 to gradually increase steps
  {
                 
        analogWrite(buttonPin, 180);           
                 
        delay(50);                             
  }
  for (count = 250 ; count >= 5 ; count -= 5)   // Count down by 5 to gradually decrease steps
  {   
               //higher count= slower speed
        analogWrite(buttonPin, 60);           
         
        delay(50); 
  }
  }
}
 }

Part C: Using a color LCD display

The LCD display can be used to display not only writing but also a variety of shapes, such as lines, dots, circles, and squares.  The user can also choose how to color each of these words or figures and where to position them exactly on the screen based on an x and y coordinate system.  For the first part of this section of the lab, the example code was downloaded from blackboard to see how the device worked.  Then, we created our own code to run on the Arduino to display various shapes, colors, and writing based on the example by simply using the LCD reference sheet to insert various shapes, writing, and colors.

However, our main goal was to make an interactive program that would test our reflex once a shape popped up on the screen.  For this specific experiment, we tested the user's reflex to a red rectangle popping up on the screen.  The test would be initiated by pressing one of the buttons.  Once the red rectangle popped up, the user would have to press that same button as fast they could repeatedly until the rectangle disappeared and the word, "STOP" appeared.  The serial monitor would count the number of button presses and hence determine both the user's reaction time as well as their speed in pressing the button.

Code 1:

// Included files
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "WProgram.h"
#include "HardwareSerial.h"
// External Component Libs
#include "LCD_driver.h"
int time;
int buttonPin = 5;    
int val; 
 int buttonState;
 int buttonPresses = 0;
void setup() {Serial.begin(9600);
ioinit(); //Initialize I/O
LCDInit(); //Initialize the LCD
LCDContrast(44);
              pinMode(buttonPin, INPUT);
              buttonState = digitalRead(buttonPin);

}

void loop() 
{
   
 
   int s2;
   s2 = !digitalRead(4);
   if (s2) {
    LCDClear(BLACK);
    delay(2000);
    LCDSetRect(1, 1, 100, 100, 1, RED);
    
  }
  val = digitalRead(buttonPin);
  time = millis();
  if (val != buttonState) {
    if(val == LOW) {
    if(time <= 10000) {
      buttonPresses++;
      Serial.println(buttonPresses);
      
     }
    }
  }
  buttonState = val; 
 if( time == 10000) {
   LCDClear(WHITE);
    LCDPutStr("STOP", 30, 30, BLACK, WHITE);
 }
 

      
  }

Tuesday, May 3, 2011

Final Project

NeoCrib Incubator
-produced by Paul Lee and Fabio Raman 

This is the prototype design of our product that can regulate the internal temperature and relative humidity.


Device Need



The Premature Newborn Cabinet is a device meant to regulate the temperature and humidity for infants born prematurely so that they can grow and be nourished in a completely regulated local environment. Premature, or preterm, births are usually associated with infants born before 37 weeks gestational period. Premature babies are more likely than babies born in the normal gestational period (37 to 41 weeks) to suffer long-term complications as well as face early morbidity, or even death (National Vital Statistics Reports, 2010). Within the normal term babies, statistics have shown that early-term infants (37 to 38 weeks) have a higher rate of morbidity than full term infants (39 to 41 weeks). Thus, this device is necessary to help premature and early-term infants survive until their bodies and organs have developed enough to withstand normal external environmental conditions.
Around 12.3% of all babies, or 518,322 infants, were born prematurely in the United States in 2008 according to the latest full report released by the National Center for Health Statistics (NCHS) (National Vital Statistics Reports, 2010). Of this number, 8.77% were born between 34 to 36 weeks (gestational period) and 3.56% under 34 weeks. This total number, 12.3%, is actual a gradual decrease in number of premature newborns from the previous 2 years as 12.68% were born prematurely in 2007 and 12.80% in 2006. However, the relatively large amount of premature infants in 2008 coupled with another 27.85% of babies born in the early-term period in 2008 shows that the target market is still large to current date. Although the usefulness of an incubator for babies born in the early-term period depends on a case-to-case basis, babies born prematurely would need some sort of incubator to greatly increase their chances of survival and minimize the chances of health complications.
Thus, the device should be targeted towards both early-term and pre-term newborns by selling the device to pediatricians in top-tier children’s hospitals in United States. This method would be more effective than targeting the parents of the newborns directly as hospitals need to be equipped with the technology before patients can even use the new device. Additionally, patients usually hear about breakthrough technology through their physicians. Implementation of a medical device in the mainstream market is usually based on a doctor’s acceptance and faith in the new technology. Thus, the premature newborn cabinet should first be targeted to doctors in the top three children’s hospitals, or the Children’s Hospital of Philadelphia (CHOP), the Children’s Hospital of Boston, and Texas Children’s Hospital. These “innovators” in the market are not only full of early adopters and leaders in their field but also the hospitals have beneficial connections to insurance companies, which will help make the product even more affordable to the buyers. Once the main hospitals adopt our Premature Newborn Cabinet, other hospitals will likely follow in adopting the same breakthrough technology.

Competitive Products
Most of the current neonatal incubators are doubled walled close type incubators that administer servo controlled oxygen, humidity, and air temperature to maintain the ambient temperature in the cabinet and to provide the desired humidity and oxygenation. The entire incubator unit utilizes microprocessor-based systems to create and maintain the ideal microclimate for the neonate. Skin senor is affixed to the abdomen part of the baby and sends information regarding skin temperature to the thermostat, which controls the output to the heat fan for cabinet temperature regulation. In addition to the skin sensor, other devices included are an AC-powered heater, a fan to circulate the warm air, a container for water to add humidity, a control valve through which oxygen may be added, and access ports for nursing care. When microclimate conditions are not maintained, built in audio alarm will sound to alert staff members.

One novel device is the Ohmeda Giraffe OmniBed that built by GE Healthcare. This device has the thermal advantages of a double-walled incubator with the access advantages of an open bed radiant warmer. By combing an incubator and a radiator into one, OmniBed reduces the necessity of transferring the patient during extensive procedures and during continual access to the infant. OmniBed operates in either the incubator or the radiant warmer mode, but never as both simultaneously. In incubator mode, it has air temperature and baby skin temperature control and integral humificiation. All control settings are integrated into a microprocessor, which allows users for easy settings control. Heating is uniform in cabinet regardless of baby position and mattress is evenly heated to minimize heat loss due to conduction. Humidity can be controlled between the ranges of 30% to 95% RH in 5% increments. Preset cabinet temperature maintains temperature between 35C to 37.5 C. Its general advantages are the combination of incubator and radiant warmer in one device and a swivel mattress for ease of access. A swivel mattress is designed for easier access and handling of neonates. It allows 360 degree rotation and can also be free tilted to any angle up to 12 degree in either the feet-up or head-up direction when inside the baby compartment. OmniBed’s main disadvantage is that it costs $35,000, and is relatively more expensive than other non-portable hospital incubators, which are around $20,000 per unit. However, even at a price of $20,000 per unit, hospital-grade incubators are too expensive to be purchased by third world country hospitals. Another disadvantage is that water reservoirs used for humidity control in these incubators are susceptible to bacterial growth. Lastly, incubator temperature can fluctuate when infant care is delivered.


Other Competitive Products in the Market


Product: Intensive Care Neonatal Transport Incubator, INC-100
Description of product: These neonatal incubators are designed to provide the safest and most stable environment for the neonate. Offered with a wide range of accessories, the neonatal incubators can be tailored to meet any critical situation arising in providing care.
Company: Phoenix Medical Systems
Summary of company: Company sells a lot of neonatal, maternal, and healthcare equipment. They offer the following products:

Advantages:
· Excellent access
· Safe and reliable operation
· Ease of cleaning
· Sturdy construction
· FDA approved
· Have been accredited with USFDA and CE certifications
Disadvantages
Relatively large device, intended primarily for hospitals


Product: Ohmeda Giraffe OmniBed (Neonatal Incubator/Infant Radiant Warmer)
Description of product: A novel device combining an incubator and a radiant warmer in one unit. The transformation from an incubator to a radiant warmer is activated by the touch of a switch. All the usual features of an incubator and radiant warmer are included. In addition the mattress swivels.
Company: Ohmeda Medical
Company description: sells all types of medical/healthcare equipment. A lot of their products are related to air control and anesthesia. They sell pulse oximiters, CO2 monitors, infant medical furniture, medical air and vacuum pumping systems, etc.
Advantages: Incubator and infant radiant warmer in one device. Relative humidity
option, swivel mattress, all around access, uniform central thermal environment.
Disadvantages: Care needed on raising canopy to avoid collisions with other equipment close by. Expensive. Water reservoir difficult to open.

Product: Neonatal incubators and Transport Incubators
Company: Ducray Lenoir Ltd
Description: They sell products in all of the following categories:
They sell all of this neonatal equipment:
Advantages: Offer a wider array of neonatal products, including both a transportable and non-transportable incubator.
Disadvantages: Incubator lacks some of the special amenities that other incubators have.


Product: Thermocare Vita Neonatal Incubator
Description: Intensive care of pre-term or sick babies should not only secure the survival. Also devotion and comfort must be given to the baby in order to make life possible.
The incubator - Vita, will help you to achieve this purpose.
It conjoins the stability of a closed ambience with the good access and contact possibilities offered by open care systems.

Company: Thermocare (sold by Central Medical Supplies)
Company description: sells products for vetininary purposes as well, such as animal intensive care units.
Advantages:

Ergonomic design
The perspex double-wall assembly has four ports. For quick access all walls can be folded down with one hand, the canopy can be removed easily. For passing tubes and cables sufficient grommets are provided. For taking x-ray it is not necessary to open the wall assembly, the tray for the cassette is inserted from the outside. Of course, for special procedures the bed can be pulled out completely. The incubator is also available with an integrated weighingscale. There is an electromotive bed tilt in both directions with automatic stop in weighing position. The desired working height can be adjusted by foot pedal.
Storage space and choice of accessories
A large shelf and two drawers are provided for storing material necessary for treatment. The accessories from the Thermocare and Variotherm devices are compatible and can be fixed at the rails and the spar assembly.
The control module
Innovative technology controls and monitors the selected values for air and patient temperature as well as for humidity and oxygen concentration. The selected parameters and measured values are indicated clearly structured with a graphic display of the development during the last three hours.
All values can be retraced and evaluated for the period of one week.

Reverse Engineering




The Dual Incubator Temperature Control System was developed by Ohmeda Healthcare in 1998 and was later acquired by G.E Healthcare. The details of this invention are described in patent #6036633. It is an infant incubator that provides a flow of heated air into the infant compartment and which exhausts air from the infant compartment. It consists of two thermometers that are placed in the inflow and outflow of the compartment to carry out the control and monitoring of the heating system that supplies the warm air to the infant compartment. By use of air temperature sensors in the two selected locations, information on air temperature within infant compartment and existence of fault in the fan or heater system can be detected.
Heating of the compartment consists of a conventional heater and a fan that induces the air past heater to heat the air which then enters the remaining part of the heater compartment. A fan is used to provide circulation of the heated air. The heated air then circulates the whole compartment and enters the air outlet. Air that enters the outlet would be slightly cooled than air that enters the inlet. Temperature sensors that measured the temperature difference of heated air in and out provide a sense of heat transferred to infant compartment to warm the infant. A CPU can then calculate and determine the air temperature within the compartment and can then use that derived temperature to regulate heater control or speed of fan to provide the desired amount of heat to the infant compartment. An abnormal condition can be detected as such the temperature in the inlet incases but the temperature in the outlet does not follow that increase in temperature, which can indicate that warm air is escaping outside the infant cabinet. When an abnormal condition such as the scenario previously described is sensed by the two temperature sensors, an alarm would sound and notify the user of such fault condition.

GE Healthcare is a unit of GE technology Infrastructure. It generates around 10% of G.E’s total revenue, which is approximately $17 billion dollars. Its major competitors include Hitachi Medical systems, Philips Healthcare, Siemens Healthcare, and Toshiba Medical Systems. It offers services in medical imaging, information technologies, medical diagnostics, patient monitoring systems, and biopharmaceutical manufacturing. Neonatal incubators are part of the patient monitoring segment. G. E Healthcare is also known to partake in many humanitarian missions in distributing medical equipment to third world country. In December 2010, G. E partnered with Embrace, a nonprofit based group to distribute low cost infant warming sleeping bag in an effort to promote awareness of infant mortality. The infant warming sleeping bag costs around $200 and are 100 times cheaper than hospital-grade incubators, are reusable and can maintain a consistence 98.6 degrees Fahrenheit for 4 hours without electricity.

Device Specifications



Conceptual Design of Device




If our device was up-scaled to the appropriate proportions to accommodate a premature infant, our device did meet the most basic specifications necessary to provide adequate environmental control and safety for a newborn child. The device in our demo effectively maintained a constant, consistent temperature between 27ºC and 29ºC as well as a relative humidity between 55% and 60%. Thus, both the code and hardware functioned effectively in regulating the local environment of our downscaled prenatal incubator. Furthermore, our device also displayed the temperature and humidity readouts on a serial monitor to allow the physician to perform quality control, ensuring that the temperature was being regulated effectively.
However, in order for our device to applied in a professional medical setting, several of the components would have to be up-scaled to meet proper medical safety standards. For instance, our device contained a heat/humidity source that ensured that the air within the compartment would never get too dry or cold. The hot water mug used in the demo would simply have to be replaced by an adequate humidifier and heat source. Similarly, the fan that worked effectively in the demo to cool the small compartment would have to be replaced by a more powerful, high-powered fan to cool a life-size baby incubator. The buzzer on the arduino should also be replaced by a louder alarm that could signal physicians farther away from the device. If each of these weakness were addressed, the device would be able to perform effectively in a medical setting.

In addition to the components provided in the device, we would make the incubator battery powered to make the device transportable. Thus, the device could be easily moved around the hospital. Additionally, the device could be transported in a vehicle to another hospital or a house if needed. In addition to the device being battery powered, the device could contain a blue-tooth device that could transmit the humidity and temperature readings to a cellular phone. Thus, the physician would could be alerted away from the room where the device was situated when the temperature or humidity rose above the threshold. Finally, an LCD readout could be present on the actual device itself, so the humidity and temperature could be read while the device is being transported.

Functional Block Diagram

The Arduino microcontroller is connected to both the humidity and temperature sensor as well as the fan and buzzer.




Proof of Concept/Functional Prototype of Device


The device functions by placing a continuous heat and humidity source within the chamber, which was built from a cardboard box. In the case of this project, a mug containing hot water was used this heat/humidity source. On the external sides of the box, two holes were cut: one for the fan and the other for the air exhaust, which was placed directly opposite the fan for maximum cooling efficiency. The arduino microcontroller, which contained both the humidity and temperature sensor as well as the buzzer, was placed inside the box. Basically, the temperature and humidity sensors would both receive input information and display readouts on the serial monitor of the PC connected to the arduino. A threshold value of (28ºC and 65% relative humidity) was set in the code within an if/else loop. If the temperature or relative humidity went above this threshold, the fan and buzzer would turn on. The buzzer would emit a series of short beeps continuously until the fan has cooled the device below this threshold. Then, both the fan and buzzer would turn off simultaneously. The buzzer was turned off by inserting a non-existent input pin number for the buzzer under the “else” part of the loop (the “else” part of the loop represented the temperature and relative humidity values below the threshold). The fan was turned off by simply switching the state from “HIGH” to “LOW.”
The DS1620 Digital Thermometer was used as our temperature sensor. The DS1620 had to be connected to the ground and 5V source on the arduino as well as three separate pins denoted as RST, CLK, and DQ, which were connected to pins 3, 4, and 5, respectively. All three of these pins were used to transmit data. RST referred to the “reset” input pin. Setting RST to high initiated all the data transfers for this part of the code. The DQ input/output pin was used to send/receive the 8-bit data commands. Meanwhile, the DQ could be jammed on high to be used as an input or set on low to be used as an output. The CLK input pin was used for clock pulses.
The HIH-430 Humidity Sensor was an analog humidity sensor connected to the ground and one of the analog inputs. The humidity sensor worked by continuously reading a voltage gradient on the analog input. The analogRead() function converted the voltage received through the humidity sensor to a digital value between 0 and 1023 where 0 represented 0 volts and 1023 represented the maximum 5 V of the arduino. Basically, the voltage would increase as resistance decreased in the humidity sensor. Increasing humidity would trigger lower resistance in the sensor. This would increase the voltage at the analog input. The analogRead() function then converted this value to a digital number. As relative humidity depends on the external temperature, a linear function was used to convert this value, based on the voltage, to the relative humidity, factoring in the temperature reading from the DS1620 Digital Thermometer Sensor. Due to the presence of this temperature sensor, an accurate reading of the relative humidity was able to be made using the sensor’s linear relationship of voltage to relative humidity.



These images show the fan switching between the “off”(left) and “on” (right) state.  The fan switches to the “on” state when the temperature or relative humidity threshold is reached.  The fan then turns off once the desired internal climate is reached.












Additional Information
 
If our device was up-scaled to the appropriate proportions to accommodate a premature infant, our device did meet the most basic specifications necessary to provide adequate environmental control and safety for a newborn child.  The device in our demo effectively maintained a constant, consistent temperature between 27ºC and 29ºC as well as a relative humidity between 55% and 60%.  Thus, both the code and hardware functioned effectively in regulating the local environment of our downscaled prenatal incubator.  Furthermore, our device also displayed the temperature and humidity readouts on a serial monitor to allow the physician to perform quality control, ensuring that the temperature was being regulated effectively.  Also, the alarm system helped to ensure the safety of the infant in the incubator as the pediatrician would be alerted each time that the device temperature or humidity went above the threshold.

However, in order for our device to applied in a professional medical setting, several of the components would have to be up-scaled to meet proper medical safety standards.  For instance, our device contained a heat/humidity source that ensured that the air within the compartment would never get too dry or cold.  The hot water mug used in the demo would simply have to be replaced by an adequate humidifier and heat source.  Similarly, the fan that worked effectively in the demo to cool the small compartment would have to be replaced by a more powerful, high-powered fan to cool a life-size baby incubator.  The buzzer on the arduino should also be replaced by a louder alarm that could signal physicians farther away from the device.  If each of these equipment-related weaknesses in the demo were addressed, the device would be able to perform effectively in a medical setting.

In addition to the components provided in the device, we would make the incubator battery-powered to make the device transportable. Thus, the device could be easily moved around the hospital.  Additionally, the device could be transported in a vehicle to another hospital or a house if needed.  In addition to the device being battery powered, the device could contain a blue-tooth device that could transmit the humidity and temperature readings to a cellular phone.  Thus, the physician could be alerted away from the room where the device was situated.  Finally, an LCD readout could be present on the actual device itself, so the humidity and temperature could be read while the device is being transported.

 This image displays the serial monitor that reads the temperature and relative humidity ever second.  Additionally, this image shows the glitch that occurs each time there is a rapid change in current due to the fan turning on and off.

Finally, the main weakness in the NeoCrib Incubator prototype that we would have to address is the rapid change in current when the fan turns on that causes a glitch in the serial monitor.  This phenomenon can be explained by the loading effect.  Basically, in order to achieve a stable output voltage, the output current should be a small fraction of the input current.  Basically, the gain should be small, meaning the ratio of current going into circuit should be small compared to current going to the fan as an output.  In the case of our prototype, the rapid change in current when the fan turned off and on  caused a glitch as the gain was really high as the output current was fairly high compared to the input current.  This problem can be fixed by amplifying the input current to make it much higher than the output current.  One specific technology that can do this are the L293 and L293D, which are quadruple high-current half-H drivers.  These devices amplify the input current and make the gain smaller.



Code:
#include <SoftwareSerial.h>

#define rxPin 0
#define txPin 1
#define ledPin 13
#define buttonPin 2

#define rstPin 3
#define clkPin 4
#define dqPin 5

int motorPin = 8;
float val = 3;
float RH = 3;
float my_room_temperature = 20; //in degrees C !
float max_voltage = 3.27;




// set up a new serial port
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
byte pinState = 0;

void setup() {
// define pin modes for tx, rx, led pins:
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
pinMode(rstPin, OUTPUT);
pinMode(clkPin, OUTPUT);
pinMode(dqPin, OUTPUT);
pinMode(motorPin, OUTPUT);
pinMode(11,OUTPUT);
digitalWrite(motorPin, LOW);

// set the data rate for the SoftwareSerial port
mySerial.begin(9600);
}


void loop() {

val = analogRead(3);
delay(500);

my_room_temperature = 20; // If you have temperature reading, put it here (centigrade!)
max_voltage = (3.27-(0.006706*my_room_temperature)) ; // The max voltage value drops down 0.006705882 for each degree C over 0C. The voltage at 0C is 3.27 (corrected for zero precent voltage)
RH = ((((val/1023)*5)-0.585)/max_voltage)*100;
Serial.println(RH);

int val = digitalRead(buttonPin);


rst_low();

clk_high();
rst_high(); //all data transfer are initiated by driving RST high
write_command(0x0c); // write config command
write_command(0x02); // cpu mode
rst_low();
delay(200); //wait until the configuration register is written

clk_high();
rst_high();
write_command(0xEE); //start conversion
rst_low();
delay(200);

clk_high();
rst_high();
write_command(0xAA);
int raw_data = read_raw_data();
rst_low();
int humidity = RH;
mySerial.print("temperature:");
mySerial.print(raw_data/2);
mySerial.println(" C");
mySerial.print("Humidity:");
mySerial.print(humidity);
mySerial.println(".");

if (RH > 65|| raw_data/2 > 28) {
digitalWrite(motorPin,HIGH);
tone(11,8000,100);



}
else {
digitalWrite(motorPin,LOW);
tone(12,8000,2000);
}
delay(100);


// toggle an LED just so you see the thing's alive.

toggle(13);

}


void toggle(int pinNum) {
// set the LED pin using the pinState variable:
digitalWrite(pinNum, pinState);
// if pinState = 0, set it to 1, and vice versa:
pinState = !pinState;
}

void write_command(int command)
/* sends 8 bit command on DQ output, least sig bit first */
{
int n, bit;

for(n=0;n<8;n++)
{
bit = ((command >> n) & (0x01));
out_bit(bit);
}
}

int read_raw_data(void)
{
int bit,n;
int raw_data=0;

pinMode(dqPin,INPUT);

/* jam the dq lead high to use as input */
for(n=0;n<9;n++)
{
clk_low();
bit=(digitalRead(dqPin));
clk_high();
raw_data = raw_data | (bit << n);
}
pinMode(dqPin, OUTPUT);
return(raw_data);
}

void out_bit(int bit)
{
digitalWrite(dqPin, bit); /* set up the data */
clk_low(); /* and then provide a clock pulse */
clk_high();
}

void clk_high(void)
{
digitalWrite(clkPin,HIGH);
}

void clk_low(void)
{
digitalWrite(clkPin,LOW);
}

void rst_high(void)
{
digitalWrite(rstPin,HIGH);
}

void rst_low(void)
{
digitalWrite(rstPin,LOW);
}



References
 
Hodge, C.G. (14 March, 2010). Dual Incubator Temperature Control System. United States Patent for Infant Incubator.
 
Martin, J. A., et. al. (December, 2010). National Vital Statistics Reports. National Center for Health Statistics: 59 (1).
 
TexasInstruments (2002). L293D Motor Driver Datasheet.

Thursday, March 31, 2011

Lab 3

 Use Serial.Read to Control the Arduino

Serial.read() allows the user to input information in the serial monitor so that the Arduino can receive signals or commands.  Basically, Serial.read allows  the user to send characters from the input line of the serial monitor to the Arduino.

Specific case: Using Serial.read to play tones on a buzzer on the arduino.  The buzzer was connected to pin 8 on the micro-controller.  Only two tones were set with the characters 'a' and 'b.'  Character 'a' was set at a frequency of 200 Hz and played for 2000 milliseconds.  On the other hand, character 'b' was played at 600 Hz and lasted 1000 milliseconds.  Basically, characters can be set for a series of tones and any song can be played as desired.  This would be especially useful if the letters represented the actual notes on a standard keyboard. Basically, just the frequencies of the notes have to be looked up for each character.  The code can be seen below:


Code:

int inputChar;

void setup()
{
  Serial.begin(9600);
  pinMode(8, OUTPUT);
}





void loop() {
  int inputChar;
  if (Serial.available()>0){
    inputChar = Serial.read();
    if (inputChar == 'a') {
      tone(8,200,2000);
    }
    if (inputChar == 'b') {
     tone(8,600,1000);
    }
  }
}


ColorPAL

First, we downloaded the example code for ColorPAL on blackboard to understand how the sensor functioned:

We noticed that the serial monitor read a specific color with 3 different number values for red, green, and blue.  A higher number for any of these specific values meant that there was more of that color.  For instance, a purely red object would have a high red value and low green and blue values.  Additionally, black objects would have very low values for all 3 numbers in the set while white had very high (300+) values.  After testing the device, we created a black and white reference in order to calibrate the ColorPAL.  We recorded the set of 3 values that the sensor read when putting a black sheet of paper directly in front of the sensor.  We named these values Kb, Kg, and Kr to designate the blue, green, and red reference values for the "black" background.  Similarly, we did the same for a "white" background and named these values Wb, Wg, and Wr.  After initializing these values, we inserted them into a code provided in the lab manual, which calibrated the ColorPAL for each color.  For instance, the green color was calibrated as follows:

Cg=(grn-Kg)/(Wg-Kg)

where
grn= green value read by device
Kg=black background value for green
Wg= white background value for green
Cg= final calibrated value for green

This procedure was repeated for the other two colors (blue and red).

The entire code is shown below:

/*====================================================
 / Connect ColorPAL SIG signal to Arduino pin 2 and 3
 / Add 2K pullup resistor from pins 2 & 3 to +5v
 / Baud Rate = 9600 kbps
 / Read signal on 9600 in HEX
 /====================================================*/

#include <SoftwareSerial.h>
SoftwareSerial Color90(2, 3);  // rx = 2, tx = 3

float red;
float grn;
float blu;
float Kr=6;
float Kb=8;
float Kg=6;
float Wr=312;
float Wg=315;
float Wb=420;
float Cr;
float Cg;
float Cb;


int gotcolor = 0;
int letter;


void setup()
{
  Serial.begin(9600); // Start communication with serial port read value
  Color90.begin(4800); // Send signal to led to read value

  pinMode(2,INPUT); // serial pin out from color pal
  pinMode(3,INPUT); // from same serial pin, signal pulls up, sends, pulls down, reads
  digitalWrite(2,HIGH); // Enable the pull-up resistor
  digitalWrite(3,HIGH); // Enable the pull-up resistor

  pinMode(2,OUTPUT); // send signal out
  pinMode(3,OUTPUT);
  digitalWrite(2,LOW); // turn pin off so pin 3 can go high
  digitalWrite(3,LOW);

  pinMode(2,INPUT); // Input signal to print
  pinMode(3,INPUT);

  Serial.println("Pass 1");
//  delay(20);

  while( digitalRead(2) != HIGH || digitalRead(3) != HIGH ) {
    Serial.println("In the loop");
    delay(50);
  }

  Serial.println("Pass 2");

  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  digitalWrite(2,LOW);
  digitalWrite(3,LOW);
  delay(100);     // spec is 80, but not all ColorPAL units work with 80

  pinMode(2,INPUT);
  pinMode(3,OUTPUT);
  delay(100);

}

// This oscillates back and forth on one wire to turn off led, send signal,
// turn on led, read signal. very fast strobe read - arduino is not capable of
// one wire signal communication over digital ports, so this is a way around
// that over 2 wires communicating with 1 pin on the sensor.
//---------------------------------

void loop()
{
  readcolor();

  Serial.print("R");
   Cr=((float)red-(float)Kr)/((float)Wr-(float)Kr);

  Serial.print(Cr);
  Serial.print("   G");
  Cg=(grn-Kg)/(Wg-Kg);
  Serial.print(Cg);
  Serial.print("   B");
  Cb=(blu-Kb)/(Wb-Kb);
  Serial.println(Cb);
  gotcolor = 0;
  delay(100);

}
void readcolor() {  // Reads ColorPAL, putting results in the red,grn,blu variables

  char rByte[9];
  char dummy[4];

  delay(20);
  Color90.begin(4800);
 Color90.print("= (00 $ m) !");  // set up loop to continuously send color data
  pinMode(3,INPUT);
  gotcolor = 0;
  while (gotcolor == 0) {
    rByte[0] = Color90.read();
    if( rByte[0] == '$' ) {
      gotcolor = 1;
      for(int i=0; i<9; i++) {
        rByte[i] = Color90.read();
//        Serial.print(rByte[i]);
      }
      Serial.println("");
      dummy[0] = rByte[0];
      dummy[1] = rByte[1];
      dummy[2] = rByte[2];
      dummy[3] = 0;

      red = strtol(dummy,NULL,16);


      dummy[0] = rByte[3];
      dummy[1] = rByte[4];
      dummy[2] = rByte[5];


      grn = strtol(dummy,NULL,16);

 


      dummy[0] = rByte[6];
      dummy[1] = rByte[7];
      dummy[2] = rByte[8];

      blu = strtol(dummy,NULL,16);
 

 

    }
  }
}