Demo entry 6333201

asd

   

Submitted by anonymous on Dec 03, 2016 at 11:03
Language: C. Code size: 4.9 kB.

#include <Wire.h>
#include <Keypad.h>
#include <TimerOne.h>

#define TEMP_SENSOR 0x90 >> 1

// Pause button pin
const byte PAUSE = 2;

// Fan pin
const byte FAN = 11;

// Keypad
const byte rows = 4; // Four rows
const byte cols = 3; // Three columns

// Keypad button layout
char keys[rows][cols] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

// Keypad pins (3 x 4)
byte colPins[cols] = {8, 9, 10};
byte rowPins[rows] = {4, 5, 6, 7};

// Set up keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);

// The current key being input
volatile char key;

// The states the keypad input
enum States {START, AST_0, AST_1, HASH_0};

// Whether or not the program is running
volatile boolean running = true;

// The current currentTemperature
volatile short currentTemp = 0;

// The target currentTemperature
volatile short targetTemp;

// The duty cycle of the fan
volatile int dutyCycle = 0;

// Whether or not fan is in manual mode
volatile bool isManual = false;

void setup() {

  // Start serial
  Serial.begin(9600);

  // Set up I2C communication with temperature sensor
  Wire.begin();
  Wire.beginTransmission(TEMP_SENSOR);
  Wire.write(0xAC);
  Wire.write(0x02);
  Wire.beginTransmission(TEMP_SENSOR);
  Wire.write(0xEE);
  Wire.endTransmission();

  // Set up keypad event listener
  keypad.addEventListener(keypadInput);

  // Set up fan pin mode
  pinMode(FAN, OUTPUT);

  // Set up pause button pin mode
  pinMode(PAUSE, INPUT_PULLUP);

  // Set up pause/unpause interrupt
  attachInterrupt(digitalPinToInterrupt(PAUSE), pause, FALLING);

  // Set up timer to send info to Python program
  Timer1.initialize();
  Timer1.attachInterrupt(sendInfo, 1000000);
}

// Sends fan speed and current temperature to Python program
void sendInfo() {
  if (running) {
    String data = "Fan speed: ";
    data += dutyCycle;
    data += "%\tCurrent temperature: ";
    data += currentTemp;
    data += "°C\n";
    Serial.print(data);
  }
}

// Updates input state when keypad receives input
// States:
// START: default state
// AST_0: automatic mode entered
// AST_1: received first digit of automatic mode
// HASH_0: manual mode entered
// AST_1 and HASH_0 return to START state upon receiving next input
void updateState(char key) {

  // Initial state is the start state
  static enum States currentState = START;

  // Holds temperature being input in automatic mode 
  static int ast_1;
  
  // Check for mode change
  switch (key) {

    // Manual input
    case '#':
      currentState = HASH_0;
      return;

    // Automatic input
    case '*':
      currentState = AST_0;
      isManual = false;
      return;
  }

  // Act upon current state accordingly
  switch (currentState) {

    // Received first digit of automatic mode
    case AST_0:
      ast_1 = key - '0';
      currentState = AST_1;
      return;

    // Received second digit of automatic mode
    case AST_1:
      currentState = START;
      targetTemp = ast_1 * 10 + key - '0';
      return;

    // Received input for manual mode
    case HASH_0:
      currentState = START;
      dutyCycle = key == '1' ? 0 : key == '0' ? 100 : (key - '0') * 10;
      isManual = true;
  }
}

// Manages keypad input
void keypadInput(KeypadEvent key) {

  // Update input state when key pressed
  if (keypad.getState() == PRESSED) {
    updateState(key);
  }
}

// Pause/unpause the program
void pause() {
  static const int DEBOUNCE_TIME = 200; // Debounce time in milliseconds
  static unsigned long lastInterruptTime = 0;
  unsigned long currentInterruptTime = millis();
  if (currentInterruptTime - lastInterruptTime > DEBOUNCE_TIME) {
    running = !running;
  }
  lastInterruptTime = currentInterruptTime;
}

// If program running, continually sample keypad for input and
// temperature sensor. Set fan speed accordingly.
void loop() {

  // Only run program if program is not paused
  if (running) {

    // Get keypad input
    key = keypad.getKey();

    // Read and interpret temperature
    int8_t firstByte;
    int8_t secondByte;
    Wire.beginTransmission(TEMP_SENSOR);
    Wire.write(0xAA);
    Wire.endTransmission();
    Wire.requestFrom(TEMP_SENSOR, 2);
    firstByte = Wire.read();
    secondByte = Wire.read();
    currentTemp = firstByte;

    // Set the duty cycle in automatic mode
    if (!isManual) {
      if (currentTemp >= targetTemp + 2) {
        dutyCycle = 100; // Fan runs at 100%
      } else if (currentTemp == targetTemp + 1) {
        dutyCycle = 30; // Fan runs at 30%
      } else {
        dutyCycle = 0; // Fan runs at 0%
      }
    }
  }

  // Set duty cycle of fan
  analogWrite(FAN, running ? map(dutyCycle, 0, 100, 0, 255) : 0);
}

This snippet took 0.01 seconds to highlight.

Back to the Entry List or Home.

Delete this entry (admin only).