/* This file is part of Waag's BioHack Academy Code. Waag's BioHack Academy Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Waag's BioHack Academy Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Waag's BioHack Academy Code. If not, see . */ /* Attribution MOSFET code derived from: http://bildr.org/2012/03/rfp30n06le-arduino/ 4 digit 7 segment code derived from: http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Components/LED/_7Seg_Example.pde button code derived from: http://arduino.cc/en/tutorial/button Thermistor code derived from: http://computers.tutsplus.com/tutorials/how-to-read-temperatures-with-arduino--mac-53714 NOTICE for first time users: - Try to build the circuits and run the sketches in the above examples prior to using this code */ // Include libraries #include // loads a library with more advanced math functions // Define pins #define fanPin 3 // The mosfet that drives the 80mm fan is connected to pin 3 #define relayPin 2 // Pin for the relay that controls the 100W light #define buttonPin1 7 // Pin for the push button left of the screen #define buttonPin2 8 // Pin for the push button right of the screen #define ledPin 13 // Arduino nboard LED pin used as indicator // Display pins //int digit1 = 11; //PWM Display pin 1 int digit2 = 10; //PWM Display pin 2 int digit3 = 9; //PWM Display pin 6 //int digit4 = 6; //PWM Display pin 8 int segA = A1; //Display pin 14 int segB = 12; //Display pin 16 int segC = 4; //Display pin 13 int segD = 5; //Display pin 3 int segE = A0; //Display pin 5 int segF = 6; //Display pin 11 int segG = 11; //Display pin 15 // Connected to ground // Display pin 7: dots // Display pin 4 & 12: semi colon // Display pin 9 & 10: degree // Display pin 1 & 8: digit 1 & 4 // Define variables int targetTemp = 18; // Initial target temperature int button1State = 0; // variable for reading the pushbutton status int button2State = 0; // variable for reading the pushbutton status // User interaction vairables boolean set_mode = false; long set_time = 5000; // max set mode time long begin_set_time = 0; long switch_time = 3000; long begin_switch_time = 0; long temp_time = 2000; long begin_temp_time = 0; // Vars int val; //Create an integer variable double temp; //Variable to hold a temperature value void setup() { //This function gets called when the Arduino starts Serial.begin(115200); //This code sets up the Serial port at 115200 baud rate // Set pin modes pinMode(fanPin, OUTPUT); // Fanpin pinMode(ledPin, OUTPUT); // initialize the LED pin as an output: pinMode(buttonPin1, INPUT); // initialize the pushbutton pin as an input: pinMode(buttonPin2, INPUT); // initialize the pushbutton pin as an input: pinMode(relayPin, OUTPUT); // 4 Digit display pinMode(segA, OUTPUT); pinMode(segB, OUTPUT); pinMode(segC, OUTPUT); pinMode(segD, OUTPUT); pinMode(segE, OUTPUT); pinMode(segF, OUTPUT); pinMode(segG, OUTPUT); // pinMode(digit1, OUTPUT); pinMode(digit2, OUTPUT); pinMode(digit3, OUTPUT); // pinMode(digit4, OUTPUT); // Set time begin_set_time = millis(); begin_switch_time = millis(); } // Thermistor function double Thermister(int RawADC) { //Function to perform the fancy math of the Steinhart-Hart equation double Temp; Temp = log(((10240000/RawADC) - 10000)); Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp ); Temp = Temp - 273.15; // Convert Kelvin to Celsius //Temp = (Temp * 9.0)/ 5.0 + 32.0; // Celsius to Fahrenheit - comment out this line if you need Celsius return Temp; } void loop() { //This function loops while the arduino is powered if((millis() - begin_temp_time) > temp_time) { val=analogRead(5); //Read the analog port 0 and store the value in val temp=Thermister(val); //Runs the fancy math on the raw analog value Serial.println(temp); //Print the value to the serial port begin_temp_time = millis(); } if((millis() - begin_switch_time) > switch_time) { // Turn the 100W infrared light on or of depending on temperature if (temp < targetTemp) { digitalWrite(relayPin, HIGH); begin_switch_time = millis(); } else { digitalWrite(relayPin, LOW); begin_switch_time = millis(); } } // Keep spinning the fan digitalWrite(fanPin, HIGH); // Read the state of the pushbutton value: button1State = digitalRead(buttonPin1); button2State = digitalRead(buttonPin2); // Check if the pushbutton is pressed. // If it is, the buttonState is HIGH: if (button1State == HIGH) { // turn LED on: digitalWrite(ledPin, HIGH); ++targetTemp; begin_set_time = millis(); // Reset set mode counter if(targetTemp > 50) targetTemp = 50; // Sanity check, do not allow temperatures higher than 50 delay(500); } else if (button2State == HIGH) { digitalWrite(ledPin, HIGH); --targetTemp; begin_set_time = millis(); // Reset set mode counter if(targetTemp < 0) targetTemp = 0; // Sanity check, do not allow temperatures higher than 50 delay(500); } else { // turn LED off: digitalWrite(ledPin, LOW); } button1State = 0; button2State = 0; // Print the new target temperature to the Serial port Serial.println(targetTemp); // Decide what temperature to display if((millis() - begin_set_time) < set_time) { // Display set time displayNumber(constrain(targetTemp,0,99)*10); } else { // Display current temperature displayNumber(constrain(temp,0,99)*10); } } // Functions for controlling the LCD display //Let's define a variable called brightness that varies from: //5000 blindingly bright (15.7mA current draw per digit) //2000 shockingly bright (11.4mA current draw per digit) //1000 pretty bright (5.9mA) //500 normal (3mA) //200 dim but readable (1.4mA) //50 dim but readable (0.56mA) //5 dim but readable (0.31mA) //1 dim but readable in dark (0.28mA) void displayNumber(int toDisplay) { #define DISPLAY_BRIGHTNESS 500 #define DIGIT_ON HIGH #define DIGIT_OFF LOW long beginTime = millis(); for(int digit = 4 ; digit > 0 ; digit--) { //Turn on a digit for a short amount of time switch(digit) { case 1: //digitalWrite(digit1, DIGIT_ON); break; case 2: digitalWrite(digit2, DIGIT_ON); break; case 3: digitalWrite(digit3, DIGIT_ON); break; case 4: //digitalWrite(digit4, DIGIT_ON); break; } //Turn on the right segments for this digit lightNumber(toDisplay % 10); toDisplay /= 10; delayMicroseconds(DISPLAY_BRIGHTNESS); //Display this digit for a fraction of a second (between 1us and 5000us, 500 is pretty good) //Turn off all segments lightNumber(10); //Turn off all digits //digitalWrite(digit1, DIGIT_OFF); digitalWrite(digit2, DIGIT_OFF); digitalWrite(digit3, DIGIT_OFF); //digitalWrite(digit4, DIGIT_OFF); } while( (millis() - beginTime) < 10) ; //Wait for 20ms to pass before we paint the display again } //Given a number, turns on those segments //If number == 10, then turn off number void lightNumber(int numberToDisplay) { #define SEGMENT_ON LOW #define SEGMENT_OFF HIGH switch (numberToDisplay){ case 0: digitalWrite(segA, SEGMENT_ON); digitalWrite(segB, SEGMENT_ON); digitalWrite(segC, SEGMENT_ON); digitalWrite(segD, SEGMENT_ON); digitalWrite(segE, SEGMENT_ON); digitalWrite(segF, SEGMENT_ON); digitalWrite(segG, SEGMENT_OFF); break; case 1: digitalWrite(segA, SEGMENT_OFF); digitalWrite(segB, SEGMENT_ON); digitalWrite(segC, SEGMENT_ON); digitalWrite(segD, SEGMENT_OFF); digitalWrite(segE, SEGMENT_OFF); digitalWrite(segF, SEGMENT_OFF); digitalWrite(segG, SEGMENT_OFF); break; case 2: digitalWrite(segA, SEGMENT_ON); digitalWrite(segB, SEGMENT_ON); digitalWrite(segC, SEGMENT_OFF); digitalWrite(segD, SEGMENT_ON); digitalWrite(segE, SEGMENT_ON); digitalWrite(segF, SEGMENT_OFF); digitalWrite(segG, SEGMENT_ON); break; case 3: digitalWrite(segA, SEGMENT_ON); digitalWrite(segB, SEGMENT_ON); digitalWrite(segC, SEGMENT_ON); digitalWrite(segD, SEGMENT_ON); digitalWrite(segE, SEGMENT_OFF); digitalWrite(segF, SEGMENT_OFF); digitalWrite(segG, SEGMENT_ON); break; case 4: digitalWrite(segA, SEGMENT_OFF); digitalWrite(segB, SEGMENT_ON); digitalWrite(segC, SEGMENT_ON); digitalWrite(segD, SEGMENT_OFF); digitalWrite(segE, SEGMENT_OFF); digitalWrite(segF, SEGMENT_ON); digitalWrite(segG, SEGMENT_ON); break; case 5: digitalWrite(segA, SEGMENT_ON); digitalWrite(segB, SEGMENT_OFF); digitalWrite(segC, SEGMENT_ON); digitalWrite(segD, SEGMENT_ON); digitalWrite(segE, SEGMENT_OFF); digitalWrite(segF, SEGMENT_ON); digitalWrite(segG, SEGMENT_ON); break; case 6: digitalWrite(segA, SEGMENT_ON); digitalWrite(segB, SEGMENT_OFF); digitalWrite(segC, SEGMENT_ON); digitalWrite(segD, SEGMENT_ON); digitalWrite(segE, SEGMENT_ON); digitalWrite(segF, SEGMENT_ON); digitalWrite(segG, SEGMENT_ON); break; case 7: digitalWrite(segA, SEGMENT_ON); digitalWrite(segB, SEGMENT_ON); digitalWrite(segC, SEGMENT_ON); digitalWrite(segD, SEGMENT_OFF); digitalWrite(segE, SEGMENT_OFF); digitalWrite(segF, SEGMENT_OFF); digitalWrite(segG, SEGMENT_OFF); break; case 8: digitalWrite(segA, SEGMENT_ON); digitalWrite(segB, SEGMENT_ON); digitalWrite(segC, SEGMENT_ON); digitalWrite(segD, SEGMENT_ON); digitalWrite(segE, SEGMENT_ON); digitalWrite(segF, SEGMENT_ON); digitalWrite(segG, SEGMENT_ON); break; case 9: digitalWrite(segA, SEGMENT_ON); digitalWrite(segB, SEGMENT_ON); digitalWrite(segC, SEGMENT_ON); digitalWrite(segD, SEGMENT_ON); digitalWrite(segE, SEGMENT_OFF); digitalWrite(segF, SEGMENT_ON); digitalWrite(segG, SEGMENT_ON); break; case 10: digitalWrite(segA, SEGMENT_OFF); digitalWrite(segB, SEGMENT_OFF); digitalWrite(segC, SEGMENT_OFF); digitalWrite(segD, SEGMENT_OFF); digitalWrite(segE, SEGMENT_OFF); digitalWrite(segF, SEGMENT_OFF); digitalWrite(segG, SEGMENT_OFF); break; } }