Thursday, December 12, 2013

Video of final project and how it works!

Final Code

int buttonPin = 3; //Variable for button pin
int ledPin[] = {11, 12, 13}; //Variables for the led pins that indicate fan speed
int ledPin1 = 6; //Variable for indicating whether motor can be controlled by potentiometer
int buttonState1 = 0; //Button state variable
int buttonState2 = 0; //Second button state
int buttonState = 0; //Another button state variable
int buttonCount = 0; //Variable to store number times button is pushed
boolean lastButton = HIGH; //Intial state for button using boolean "true" or "false"
int potPin = A0; //Pin that potentiometer is connected to
int motorPin = 9; //Pin the motor is connected to
int potValue; //Value for the potentiometer from 0 to 1023
int motorValue = 0; //Intial motor value from o to 255
int x;
void setup() {
for (x = 0; x < 3; x++) { //Configure the led pins that indicate fan speed as for loops and outputs
pinMode (ledPin[x], OUTPUT);}
pinMode(motorPin, OUTPUT); //Configure motor pin as output
pinMode(buttonPin, INPUT); //Configure button as input pin
}
void loop() {
buttonState1 = digitalRead(buttonPin); //reads the state of the button and stores the variable
delay(50); //delay 50 milliseconds for debounce
buttonState2 = digitalRead(buttonPin); //aids in debounce
if (buttonState1 == buttonState2){ //if statement (buttonState1 is equal to buttonState2)
buttonState = buttonState2; //buttonState will equal buttonState2
if (buttonState != lastButton) { //if buttonState is not lastButton and buttonState is equal to low then add 1 to buttonCount
if (buttonState == LOW){
buttonCount++;
}
}
lastButton = buttonState; //Varaible used to store value
}
if ( (buttonCount % 2) == 0) { //if buttonCount is even then enable the potentiometer to control the motor speed
potValue = analogRead(potPin); //read the pot value
motorValue = map(potValue, 0, 1023, 0, 255); //maps the value from 0 to 1023 to 0 to 255 (digital to analog)
analogWrite(motorPin, motorValue); //tells the motor pin to turn on in accordance to the value read by the pot pin
delay(2);
}
if ( (buttonCount % 2) != 0) { //if buttonCount is odd then do not allow the potentiometer to control the motor speed
analogWrite (motorPin, 0);
}
{
potValue = analogRead(potPin); //make the leds indicating fan speed to turn on indacting states of "high medium or low",
for (int i = 0; i < 3; i++) { //high = 3 red leds on, medium = 2 red leds on and low = 1 red led on
if( (i * 341) < potValue) { digitalWrite(ledPin[i], HIGH);}
else
{ digitalWrite(ledPin[i], LOW);}
if ( (buttonCount % 2) != 0) {
digitalWrite (ledPin[i], LOW);
}
}
}
if ( (buttonCount % 2) == 0) { //if buttonCount is even then turn on the led indicating whether you can control motor with potentiometer
digitalWrite (ledPin1, HIGH);
}
else {
digitalWrite (ledPin1, LOW);
}
}
view raw gistfile1.txt hosted with ❤ by GitHub

Monday, December 2, 2013

We have slightly modified the design of our fan so that the LCD displays the current and desired temperature as well as the RPM of the fan.  The following is a basic bread board setup and code for our fan.

Schematic for fan controller

*/
#include <OneWire.h>
#include <DallasTemperature.h>
#include <PID_v1.h>
#include <LiquidCrystal.h>

//Definitions
#define FAN 9           // Output pin for fan
#define ONE_WIRE_BUS 8  // Temperature Input is on Pin 2
#define click 3        //Rotary Encoder Click
#define encoder0PinA  2 //Rotary Encoder Pin A
#define encoder0PinB  4 //Rotary Encoder Pin B
#define CRITICAL 50.00  //Critical temperature to ignore PID and turn on fans

volatile unsigned int encoder0Pos = 0;  //Encoder value for ISR

LiquidCrystal lcd(12, 11, 13, 5,6,7);  //set up LCD

//Setup Temperature Sensor
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

//Setup PID
double Setpoint, Input, Output;                                          //I/O for PID
double aggKp=40, aggKi=2, aggKd=10;                                     //original: aggKp=4, aggKi=0.2, aggKd=1, Aggressive Turning,50,20,20
double consKp=20, consKi=1, consKd=5;                                  //original consKp=1, consKi=0.05, consKd=0.25, Conservative Turning,20,10,10
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, REVERSE);  //Initialize PID

//interface
int timeCounter;
void setup()

  // start serial port for temperature readings
  Serial.begin(9600);
  Serial.println("Start");

  //Temperature Setup
  sensors.begin();                    //Start Library
  sensors.requestTemperatures();      // Send the command to get temperatures
  Input = sensors.getTempCByIndex(0); //Set Input to Current Temperature
  Setpoint = 28;                      //Inintialize desired Temperature in Deg C
  encoder0Pos=28;

  //PID Setup
  myPID.SetMode(AUTOMATIC);
  //TCCR2B = TCCR2B & 0b11111000 | 0x01; //adjust the PWM Frequency, note: this changes timing like delay()

  //Setup Pins
  pinMode(FAN, OUTPUT);                   // Output for fan speed, 0 to 255
  pinMode(click, INPUT);                  // Click button is an input
  pinMode(encoder0PinA, INPUT);
  digitalWrite(encoder0PinA, HIGH);       // Turn on pullup resistor
  pinMode(encoder0PinB, INPUT);
  digitalWrite(encoder0PinB, HIGH);       // Turn on pullup resistor

  //Set up Interupts
  attachInterrupt(1, clicked, RISING);    // Click button on interrupt 1 - pin 3
  attachInterrupt(0, doEncoder, CHANGE);  // Encoder pin on interrupt 0 - pin 2

  //interface

  timeCounter=0;

  //Setup LCD 16x2 and display startup message
  lcd.begin(16, 2);
  lcd.print(" Smart Fan");
  lcd.setCursor(0,1);
  lcd.print(" Starting Up");
  delay(1000);
  lcd.clear();
}
void loop()
{
   timeCounter++;

   //Get temperature and give it to the PID input
   sensors.requestTemperatures();
   Input=sensors.getTempCByIndex(0);

  //print out info to LCD
  lcd.setCursor(1,0);
  lcd.print("Temp:");
  lcd.print((int)Input);
  lcd.setCursor(9,0);
  lcd.print("RPM:");
  lcd.print((int)Output*4.7059);
  lcd.setCursor(1,1);
  lcd.print("Set:");
  lcd.print((int)Setpoint);

  //Compute PID value
  double gap = abs(Setpoint-Input); //distance away from setpoint
  if(gap<1)
  { 
    //Close to Setpoint, be conservative
    myPID.SetTunings(consKp, consKi, consKd);
  }
  else
  {
     //Far from Setpoint, be aggresive
     myPID.SetTunings(aggKp, aggKi, aggKd);
  }
  myPID.Compute();
  Serial.print(timeCounter);
  Serial.print(" ");
  Serial.print(Input);
  Serial.print(" ");
  Serial.println(Output);
  analogWrite(FAN,255);
  //Write PID output to fan if not critical
  if (Input<CRITICAL)
    analogWrite(FAN,Output);
  else
    analogWrite(FAN,255);
}

void doEncoder()
{
  //pinA and pinB are both high or both low, spinning forward, otherwise it's spinning backwards
  if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB))
  {
    encoder0Pos++;
  }
  else
  {
    encoder0Pos--;
  }
  Serial.println (encoder0Pos, DEC);  //Print out encoder value to Serial
  Setpoint=encoder0Pos;
}
void clicked()
{
  //For interface
  lcd.clear();
  lcd.print("clicked!");
  delay(1000);
}