Introduction: Smart Watch Fan

This is my project for smart watch+ fan. And code in description.


Supplies

Step 1:

void setup() {

}

#include <OneWire.h>

#include <DallasTemperature.h>

#define ONE_WIRE_BUS 10

   

OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);

   

  int tempPin = ONE_WIRE_BUS; // выход LM35

  int fan = 11; // вывод на вентилятор

  int temp;

  int tempMin = 28; // температура начала вращения вентилятора

  int tempMax = 35; // максимальная температура, когда вентилятор вращается на 100%

  int fanSpeed;

  

   

  void setup() {

  pinMode(fan, OUTPUT);

  Serial.begin(9600);

  sensors.begin();

  pinMode(tempPin, INPUT);

  }

   

  void loop() {

  temp = readTemp(); // получаем температуру

  if(temp < tempMin) { // если temp меньше минимума

  fanSpeed = 0; // кулер не вращается

  digitalWrite(fan, LOW);

  }

  if((temp >= tempMin) && (temp <= tempMax)) { // если temp больше минимума

  fanSpeed = map(temp, tempMin, tempMax, 0, 255); // текущая скорость вентилятора

  analogWrite(fan, fanSpeed); // вращаем кулер со скоростью fanSpeed

  }

   

  Serial.print("TEMP: ");

  Serial.print(temp); // отображение температуры

  lcd.print("C ");

  delay(1000);

   

  }

   

  int readTemp() { // получить температуру и переконвертировать ее в цельсии

    sensors.requestTemperatures();

    temp = sensors.getTempCByIndex(0);

    return temp * 0.48828125;

  }void loop() {

}

/].

*/

/*

Retro Watch Arduino v1.0 - u8g (supports u8glib)


 Get the latest version, android host app at 

 ------> https://github.com/godstale/retrowatch

 ------> or http://www.hardcopyworld.com


Written by Suh Young Bae (godstale@hotmail.com)

All text above must be included in any redistribution

*/


#include <avr/pgmspace.h>

#include <SoftwareSerial.h>

#include <math.h>

#include "bitmap.h"


#include "U8glib.h"


///////////////////////////////////////////////////////////////////

//----- OLED instance


// IMPORTANT NOTE: The complete list of supported devices 

// with all constructor calls is here: http://code.google.com/p/u8glib/wiki/device


U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // I2C / TWI 

///////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////

//----- BT instance

SoftwareSerial BTSerial(2, 3); //Connect HC-06, RX, TX

///////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////

//----- Protocol


//----- Bluetooth transaction parsing

#define TR_MODE_IDLE 1

#define TR_MODE_WAIT_CMD 11

#define TR_MODE_WAIT_MESSAGE 101

#define TR_MODE_WAIT_TIME 111

#define TR_MODE_WAIT_ID 121

#define TR_MODE_WAIT_COMPLETE 201


#define TRANSACTION_START_BYTE 0xfc

#define TRANSACTION_END_BYTE 0xfd


#define CMD_TYPE_NONE 0x00

#define CMD_TYPE_RESET_EMERGENCY_OBJ 0x05

#define CMD_TYPE_RESET_NORMAL_OBJ 0x02

#define CMD_TYPE_RESET_USER_MESSAGE 0x03


#define CMD_TYPE_ADD_EMERGENCY_OBJ 0x11

#define CMD_TYPE_ADD_NORMAL_OBJ 0x12

#define CMD_TYPE_ADD_USER_MESSAGE 0x13


#define CMD_TYPE_DELETE_EMERGENCY_OBJ 0x21

#define CMD_TYPE_DELETE_NORMAL_OBJ 0x22

#define CMD_TYPE_DELETE_USER_MESSAGE 0x23


#define CMD_TYPE_SET_TIME 0x31

#define CMD_TYPE_REQUEST_MOVEMENT_HISTORY 0x32

#define CMD_TYPE_SET_CLOCK_STYLE 0x33

#define CMD_TYPE_SET_INDICATOR 0x34


#define CMD_TYPE_PING 0x51

#define CMD_TYPE_AWAKE 0x52

#define CMD_TYPE_SLEEP 0x53

#define CMD_TYPE_REBOOT 0x54


byte TRANSACTION_POINTER = TR_MODE_IDLE;

byte TR_COMMAND = CMD_TYPE_NONE;

///////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////

//----- Buffer, Parameters


//----- Message item buffer

#define MSG_COUNT_MAX 7

#define MSG_BUFFER_MAX 19

unsigned char msgBuffer[MSG_COUNT_MAX][MSG_BUFFER_MAX];

char msgParsingLine = 0;

char msgParsingChar = 0;

char msgCurDisp = 0;


//----- Emergency item buffer

#define EMG_COUNT_MAX 3

#define EMG_BUFFER_MAX 19

char emgBuffer[EMG_COUNT_MAX][EMG_BUFFER_MAX];

char emgParsingLine = 0;

char emgParsingChar = 0;

char emgCurDisp = 0;


//----- Time

#define UPDATE_TIME_INTERVAL 60000

byte iMonth = 1;

byte iDay = 1;

byte iWeek = 1;  // 1: SUN, MON, TUE, WED, THU, FRI,SAT

byte iAmPm = 0;  // 0:AM, 1:PM

byte iHour = 0;

byte iMinutes = 0;

byte iSecond = 0;


#define TIME_BUFFER_MAX 6

char timeParsingIndex = 0;

char timeBuffer[6] = {-1, -1, -1, -1, -1, -1};

PROGMEM const char* const weekString[] = {"", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

PROGMEM const char* const ampmString[] = {"AM", "PM"};

///////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////

//----- Display features

#define DISPLAY_MODE_START_UP 0

#define DISPLAY_MODE_CLOCK 1

#define DISPLAY_MODE_EMERGENCY_MSG 2

#define DISPLAY_MODE_NORMAL_MSG 3

#define DISPLAY_MODE_IDLE 11

byte displayMode = DISPLAY_MODE_START_UP;


#define CLOCK_STYLE_SIMPLE_ANALOG 0x01

#define CLOCK_STYLE_SIMPLE_DIGIT 0x02

#define CLOCK_STYLE_SIMPLE_MIX 0x03

byte clockStyle = CLOCK_STYLE_SIMPLE_MIX;


#define INDICATOR_ENABLE 0x01

boolean updateIndicator = true;


byte centerX = 64;

byte centerY = 32;

byte iRadius = 28;


#define IDLE_DISP_INTERVAL 60000

#define CLOCK_DISP_INTERVAL 60000

#define EMERGENCY_DISP_INTERVAL 5000

#define MESSAGE_DISP_INTERVAL 3000

unsigned long prevClockTime = 0;

unsigned long prevDisplayTime = 0;


unsigned long next_display_interval = 0;

unsigned long mode_change_timer = 0;

#define CLOCK_DISPLAY_TIME 300000

#define EMER_DISPLAY_TIME 10000

#define MSG_DISPLAY_TIME 5000


PROGMEM const char* const strIntro[] = {"Retro", "Watch", "Arduino v1.0"};

///////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////

//----- Button control

int buttonPin = 5;

boolean isClicked = HIGH;

///////////////////////////////////////////////////////////////////



void setup()  {

 //Serial.begin(9600);  // WARNING: Do not enable this if there is not enough memory

 //Serial.println(F("RetroWatch v1.0 u8g"));


 //----- Set button

 pinMode(buttonPin, INPUT); // Defines button pin

  

 //----- Initialize message buffer

 init_emg_array();

 init_msg_array();

  

 //----- Set display features

 centerX = u8g.getWidth() / 2;

 centerY = u8g.getHeight() / 2;

 iRadius = centerY - 2;


 //----- Setup serial connection with BT

 BTSerial.begin(9600); // set the data rate for the BT port

  

 //----- Show logo

 drawStartUp();  // Show RetroWatch Logo

 delay(3000);

}



void loop() {

 boolean isReceived = false;

 unsigned long current_time = 0;

  

 // Get button input

 if(digitalRead(buttonPin) == LOW) isClicked = LOW;

  

 // Receive data from remote and parse

 isReceived = receiveBluetoothData();

  

 // Update clock time

 current_time = millis();

 updateTime(current_time);

  

 // Display routine

 onDraw(current_time);

  

 // If data doesn't arrive, wait for a while to save battery

 if(!isReceived)

  delay(300);

}





///////////////////////////////////

//----- Utils

///////////////////////////////////

void init_msg_array() {

 for(int i=0; i<MSG_COUNT_MAX; i++) {

  for(int j=0; j<MSG_BUFFER_MAX; j++) {

   msgBuffer[i][j] = 0x00;

  }

 }

 msgParsingLine = 0;

 msgParsingChar = 0;  // First 2 byte is management byte

 msgCurDisp = 0;

}


void init_emg_array() {

 for(int i=0; i<EMG_COUNT_MAX; i++) {

  for(int j=0; j<EMG_BUFFER_MAX; j++) {

   emgBuffer[i][j] = 0x00;

  }

 }

 emgParsingLine = 0;

 emgParsingChar = 0;  // First 2 byte is management byte

 emgCurDisp = 0;

}


///////////////////////////////////

//----- Time functions

///////////////////////////////////

void setTimeValue() {

 iMonth = timeBuffer[0];

 iDay = timeBuffer[1];

 iWeek = timeBuffer[2];  // 1: SUN, MON, TUE, WED, THU, FRI,SAT

 iAmPm = timeBuffer[3];  // 0:AM, 1:PM

 iHour = timeBuffer[4];

 iMinutes = timeBuffer[5];

}


void updateTime(unsigned long current_time) {

 if(iMinutes >= 0) {

  if(current_time - prevClockTime > UPDATE_TIME_INTERVAL) {

   // Increase time

   iMinutes++;

   if(iMinutes >= 60) {

    iMinutes = 0;

    iHour++;

    if(iHour > 12) {

     iHour = 1;

     (iAmPm == 0) ? iAmPm=1 : iAmPm=0;

     if(iAmPm == 0) {

      iWeek++;

      if(iWeek > 7)

       iWeek = 1;

      iDay++;

      if(iDay > 30) // Yes. day is not exact.

       iDay = 1;

     }

    }

   }

   prevClockTime = current_time;

  }

 }

 else {

  displayMode = DISPLAY_MODE_START_UP;

 }

}


///////////////////////////////////

//----- BT, Data parsing functions

///////////////////////////////////


// Parsing packet according to current mode

boolean receiveBluetoothData() {

 int isTransactionEnded = false;

 while(!isTransactionEnded) {

  if(BTSerial.available()) {

   byte c = BTSerial.read();

    

   //if(c == 0xFE && TRANSACTION_POINTER != TR_MODE_WAIT_MESSAGE) return false;

    

   if(TRANSACTION_POINTER == TR_MODE_IDLE) {

    parseStartSignal(c);

   }

   else if(TRANSACTION_POINTER == TR_MODE_WAIT_CMD) {

    parseCommand(c);

   }

   else if(TRANSACTION_POINTER == TR_MODE_WAIT_MESSAGE) {

    parseMessage(c);

   }

   else if(TRANSACTION_POINTER == TR_MODE_WAIT_TIME) {

    parseTime(c);

   }

   else if(TRANSACTION_POINTER == TR_MODE_WAIT_ID) {

    parseId(c);

   }

   else if(TRANSACTION_POINTER == TR_MODE_WAIT_COMPLETE) {

    isTransactionEnded = parseEndSignal(c);

   }

    

  } // End of if(BTSerial.available())

  else {

   isTransactionEnded = true;

  }

 } // End of while()

 return true;

} // End of receiveBluetoothData()


void parseStartSignal(byte c) {

 //drawLogChar(c);

 if(c == TRANSACTION_START_BYTE) {

  TRANSACTION_POINTER = TR_MODE_WAIT_CMD;

  TR_COMMAND = CMD_TYPE_NONE;

 }

}


void parseCommand(byte c) {

 if(c == CMD_TYPE_RESET_EMERGENCY_OBJ || c == CMD_TYPE_RESET_NORMAL_OBJ || c == CMD_TYPE_RESET_USER_MESSAGE) {

  TRANSACTION_POINTER = TR_MODE_WAIT_COMPLETE;

  TR_COMMAND = c;

  processTransaction();

 }

 else if(c == CMD_TYPE_ADD_EMERGENCY_OBJ || c == CMD_TYPE_ADD_NORMAL_OBJ || c == CMD_TYPE_ADD_USER_MESSAGE) {

  TRANSACTION_POINTER = TR_MODE_WAIT_MESSAGE;

  TR_COMMAND = c;

  if(c == CMD_TYPE_ADD_EMERGENCY_OBJ) {

   //Serial.println("# start - ADD_EMERGENCY_OBJ");

   emgParsingChar = 0;

   if(emgParsingLine >= MSG_COUNT_MAX || emgParsingLine < 0)

    emgParsingLine = 0;

   for(int i=3; i<EMG_BUFFER_MAX; i++)

    emgBuffer[emgParsingLine][i] = 0x00;

  }

  else if(c == CMD_TYPE_ADD_NORMAL_OBJ) {

   //Serial.println("# start - ADD_NORMAL_OBJ");

   msgParsingChar = 0;

   if(msgParsingLine >= MSG_COUNT_MAX || msgParsingLine < 0)

    msgParsingLine = 0;

   for(int i=3; i<MSG_BUFFER_MAX; i++)

    msgBuffer[msgParsingLine][i] = 0x00;

  }

 }

 else if(c == CMD_TYPE_DELETE_EMERGENCY_OBJ || c == CMD_TYPE_DELETE_NORMAL_OBJ || c == CMD_TYPE_DELETE_USER_MESSAGE) {

  TRANSACTION_POINTER = TR_MODE_WAIT_COMPLETE;

  TR_COMMAND = c;

 }

 else if(c == CMD_TYPE_SET_TIME) {

  TRANSACTION_POINTER = TR_MODE_WAIT_TIME;

  TR_COMMAND = c;

 }

 else if(c == CMD_TYPE_SET_CLOCK_STYLE || c == CMD_TYPE_SET_INDICATOR) {

  TRANSACTION_POINTER = TR_MODE_WAIT_ID;

  TR_COMMAND = c;

 }

 else {

  TRANSACTION_POINTER = TR_MODE_IDLE;

  TR_COMMAND = CMD_TYPE_NONE;

 }

}


void parseMessage(byte c) {

 if(c == TRANSACTION_END_BYTE) {

  processTransaction();

  TRANSACTION_POINTER = TR_MODE_IDLE;

 }

  

 if(TR_COMMAND == CMD_TYPE_ADD_EMERGENCY_OBJ) {

  if(emgParsingChar < EMG_BUFFER_MAX - 1) {

   if(emgParsingChar > 1) {

    emgBuffer[emgParsingLine][emgParsingChar] = c;

   }

   emgParsingChar++;

  }

  else {

   TRANSACTION_POINTER = TR_MODE_IDLE;

   processTransaction();

  }

 }

 else if(TR_COMMAND == CMD_TYPE_ADD_NORMAL_OBJ) {

  if(msgParsingChar < MSG_BUFFER_MAX - 1) {

   if(msgParsingChar > 1) {

    msgBuffer[msgParsingLine][msgParsingChar] = c;

   }

   msgParsingChar++;

  }

  else {

   TRANSACTION_POINTER = TR_MODE_IDLE;

   processTransaction();

  }

 }

 else if(TR_COMMAND == CMD_TYPE_ADD_USER_MESSAGE) {

  // Not available yet.

  TRANSACTION_POINTER = TR_MODE_WAIT_COMPLETE;

 }

}


void parseTime(byte c) {

 if(TR_COMMAND == CMD_TYPE_SET_TIME) {

  if(timeParsingIndex >= 0 && timeParsingIndex < TIME_BUFFER_MAX) {

   timeBuffer[timeParsingIndex] = (int)c;

   timeParsingIndex++;

  }

  else {

   processTransaction();

   TRANSACTION_POINTER = TR_MODE_WAIT_COMPLETE;

  }

 }

}


void parseId(byte c) {

 if(TR_COMMAND == CMD_TYPE_SET_CLOCK_STYLE) {

  clockStyle = c;

  processTransaction();

 }

 else if(TR_COMMAND == CMD_TYPE_SET_INDICATOR) {

  if(c == INDICATOR_ENABLE)

   updateIndicator = true;

  else

   updateIndicator = false;

  processTransaction();

 }

 TRANSACTION_POINTER = TR_MODE_WAIT_COMPLETE;

}


boolean parseEndSignal(byte c) {

 if(c == TRANSACTION_END_BYTE) {

  TRANSACTION_POINTER = TR_MODE_IDLE;

  return true;

 }

 return false;

}


void processTransaction() {

 if(TR_COMMAND == CMD_TYPE_RESET_EMERGENCY_OBJ) {

  init_emg_array();//init_msg_array();

 }

 else if(TR_COMMAND == CMD_TYPE_RESET_NORMAL_OBJ) {

  init_msg_array();//init_emg_array();

 }

 else if(TR_COMMAND == CMD_TYPE_RESET_USER_MESSAGE) {

  // Not available yet.

 }

 else if(TR_COMMAND == CMD_TYPE_ADD_NORMAL_OBJ) {

  //Serial.println("# processTransaction() - ADD_NORMAL_OBJ");

  msgBuffer[msgParsingLine][0] = 0x01;

  msgBuffer[msgParsingLine][MSG_BUFFER_MAX-1] = 0x00;

  msgParsingChar = 0;

  msgParsingLine++;

  if(msgParsingLine >= MSG_COUNT_MAX)

   msgParsingLine = 0;

  setNextDisplayTime(millis(), 0); // update screen immediately

 }

 else if(TR_COMMAND == CMD_TYPE_ADD_EMERGENCY_OBJ) {

  //Serial.println("# processTransaction() - ADD_EMERGENCY_OBJ");

  emgBuffer[emgParsingLine][0] = 0x01;

  emgBuffer[emgParsingLine][EMG_BUFFER_MAX - 1] = 0x00;

  emgParsingChar = 0;

  emgParsingLine++;

  if(emgParsingLine >= EMG_COUNT_MAX)

   emgParsingLine = 0;

  startEmergencyMode();

  setNextDisplayTime(millis(), 2000);

 }

 else if(TR_COMMAND == CMD_TYPE_ADD_USER_MESSAGE) {

 }

 else if(TR_COMMAND == CMD_TYPE_DELETE_EMERGENCY_OBJ || TR_COMMAND == CMD_TYPE_DELETE_NORMAL_OBJ || TR_COMMAND == CMD_TYPE_DELETE_USER_MESSAGE) {

  // Not available yet.

 }

 else if(TR_COMMAND == CMD_TYPE_SET_TIME) {

  setTimeValue();

  timeParsingIndex = 0;

  setNextDisplayTime(millis(), 0); // update screen immediately

 }

 if(TR_COMMAND == CMD_TYPE_SET_CLOCK_STYLE || CMD_TYPE_SET_INDICATOR) {

  setNextDisplayTime(millis(), 0); // update screen immediately

 }

}


///////////////////////////////////

//----- Drawing methods

///////////////////////////////////


// Main drawing routine