#include <Adafruit_GFX.h> // Core graphics library
#include <SPI.h> // this is needed for display
#include <Adafruit_ILI9341.h>
#include <Wire.h> // this is needed for FT6206
#include <Adafruit_FT6206.h>
#include <M2M_LM75A.h>
// The display also uses hardware SPI, plus #9 & #10
#define PIR 3
#define IR_LED 4
#define TFT_CS 10
#define TFT_DC 2
#define TEMP_SENSOR A3
const float BETA = 3950; // should match the Beta Coefficient of the thermistor
// Size of the color selection boxes and the paintbrush size
#define BOXSIZE 50
#define PENRADIUS 3
#define BUTTON_ONOFF 1
#define NO_BUTTON 0
#define BUTTON_PLUS 2
#define BUTTON_MINUS 3
#define BUTTON_MODE 4
#define BUTTON_ONOFF_X 40
#define BUTTON_ONOFF_Y 120
#define BUTTON_PLUS_X 120
#define BUTTON_PLUS_Y 95
#define BUTTON_MINUS_X 120
#define BUTTON_MINUS_Y 145
#define BUTTON_MODE_X 200
#define BUTTON_MODE_Y 120
#define EMPTY_ROOM 60000
M2M_LM75A lm75a;
// The FT6206 uses hardware I2C (SCL/SDA)
Adafruit_FT6206 ctp = Adafruit_FT6206();
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
enum State {
WAITING,
MOTION_DETECTED,
AC_ON
};
State currentState = WAITING;
float Temperature, prev_temp=0;
float AC_temp=23, prev_AC_temp=0;
unsigned long lastMotionTime = 0;
unsigned long lastTempCheckTime = 0;
bool isAcOn = false;
bool isHeatMode = false;
int oldcolor, currentcolor;
bool movement_detected;
bool on_off=false;
int button;
bool someone_in_the_room;
void setup() {
init_PIR();
init_Serial();
init_IR_LED();
init_lcd();
init_temp();
draw_ac_screen();
}
void loop()
{
//test_all();
main_logic();
}
//main logic
void main_logic()
{
Temperature=get_temp();
button=get_button();
if(button!=NO_BUTTON)
{
Serial.print("button pressed: ");
Serial.println(button);
handle_button(button);
delay(100);
}
switch(currentState)
{
case WAITING:
if(is_movement())
{
currentState=MOTION_DETECTED;
Serial.println("state motion detected");
lastMotionTime=millis();
}
break;
case MOTION_DETECTED:
if(!isAcOn)
{
start_ac(AC_temp,isHeatMode);
Serial.println("state ac is on");
currentState=AC_ON;
}
break;
case AC_ON:
if(is_movement())
{
lastMotionTime=millis();
}
else if(millis()-lastMotionTime>EMPTY_ROOM)
{
Serial.println("state is waiting");
currentState=WAITING;
if(isAcOn)
turn_ac_off();
}
break;
}
if(room_temp_changed())
lcd_room_temp();
if(ac_temp_changed())
lcd_ac_temp();
delay (100);
}
void handle_button(int button)
{
switch (button) {
case BUTTON_ONOFF:
if(isAcOn)
{
turn_ac_off();
currentState=WAITING;
}
else
{
start_ac(AC_temp,isHeatMode);
currentState=AC_ON;
}
button=NO_BUTTON;
break;
case BUTTON_PLUS:
adjust_temp(true);
button=NO_BUTTON;
break;
case BUTTON_MINUS:
adjust_temp(false);
button=NO_BUTTON;
break;
case BUTTON_MODE:
isHeatMode=!isHeatMode;
start_ac(AC_temp,isHeatMode);
button=NO_BUTTON;
break;
default:
button=NO_BUTTON;
break;
}
}
bool room_temp_changed()
{
if(Temperature!=prev_temp)
{
prev_temp=Temperature;
return true;
}
return false;
}
bool ac_temp_changed()
{
if(AC_temp!=prev_AC_temp)
{
prev_AC_temp=AC_temp;
return true;
}
return false;
}
// Init
void init_temp()
{
lm75a.begin();
}
void init_PIR()
{
pinMode(PIR, INPUT);
}
void init_Serial()
{
Serial.begin(9600);
}
void init_IR_LED()
{
pinMode(IR_LED, OUTPUT);
}
void init_lcd()
{
Serial.println(F("Cap Touch Paint!"));
tft.begin();
if (! ctp.begin(40)) { // pass in 'sensitivity' coefficient
Serial.println("Couldn't start FT6206 touchscreen controller");
while (1);
}
Serial.println("Capacitive touchscreen started");
tft.fillScreen(ILI9341_BLACK);
//tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
tft.setRotation(1);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
}
//Test
void test_temp()
{
/*
Serial.print("Temperature in Celsius: ");
Temperature = lm75a.getTemperature();
//Bug fix in M2M library, below 0 temperatures are not printed correctly
uint16_t i_temperature = Temperature * 256.0f;
Temperature = float(int16_t(i_temperature)) / 256.0f;
Serial.print(Temperature);
Serial.println(F(" *C"));
delay(500);
*/
Serial.print("Temperature in Celsius: ");
Serial.print(get_temp());
Serial.println(F(" *C"));
}
void test_all()
{
//test_PIR();
//test_IR_LED();
test_lcd();
//test_temp();
//test_ac();
}
void test_lcd()
{
// Wait for a touch
int x,y;
if (! ctp.touched()) {
return;
}
//tft.fillScreen(ILI9341_BLACK);
// Retrieve a point
TS_Point p = ctp.getPoint();
x = map(p.y, 0, 320, 0, 320);
y = map(p.x, 0, 240, 240, 0);
Serial.print(x);
Serial.print(" , ");
Serial.println(y);
if (((y-PENRADIUS) > BOXSIZE) && ((y+PENRADIUS) < tft.height()))
{
tft.fillCircle(x, y, PENRADIUS, currentcolor);
tft.setCursor((x-40),(y));
tft.print(x);
tft.print(", ");
tft.print(y);
}
}
void test_PIR()
{
if (is_movement())
Serial.println("Movement detected");
else
Serial.println("No movment");
}
void test_IR_LED()
{
digitalWrite(IR_LED, HIGH);
delay(1000);
digitalWrite(IR_LED, LOW);
delay(1000);
}
void test_ac()
{
draw_ac_screen();
}
//PIR
bool is_movement()
{
bool movement_detected = digitalRead(PIR);
return movement_detected;
}
//lcd
void draw_ac_screen()
{
//ac temperature
tft.drawRect(0, 0, 280, 60, ILI9341_WHITE);
tft.setCursor(20,2);
tft.print("ac");
//room temperature
tft.drawLine(140, 0, 140, 60, ILI9341_WHITE);
tft.setCursor(160,2);
tft.print("room");
//on off button
tft.drawRect(BUTTON_ONOFF_X, BUTTON_ONOFF_Y, BOXSIZE, BOXSIZE, ILI9341_WHITE);
tft.drawCircle(65, 145, 15, ILI9341_WHITE);
tft.drawFastVLine(65, 130, 15, ILI9341_WHITE);
//+ button
tft.drawRect(BUTTON_PLUS_X, BUTTON_PLUS_Y, BOXSIZE, BOXSIZE, ILI9341_WHITE);
tft.setCursor(140,113);
tft.print("+");
//- button
tft.drawRect(BUTTON_MINUS_X, BUTTON_MINUS_Y, BOXSIZE, BOXSIZE, ILI9341_WHITE);
tft.setCursor(140,163);
tft.print("-");
//hc button
tft.drawRect(BUTTON_MODE_X, BUTTON_MODE_Y, BOXSIZE, BOXSIZE, ILI9341_WHITE);
tft.setCursor(208,138);
tft.print("H/C");
}
//temp
float get_temp()
{
//Serial.print("Temperature in Celsius: ");
float temp = lm75a.getTemperature();
//Bug fix in M2M library, below 0 temperatures are not printed correctly
uint16_t i_temperature = temp * 256.0f;
temp = float(int16_t(i_temperature)) / 256.0f;
//Serial.print(temp);
//Serial.println(F(" *C"));
return temp;
}
//lcd
void lcd_room_temp()
{
tft.fillRect(165,25,100,30,ILI9341_BLACK);
tft.setCursor(170,30);
tft.print(get_temp());
}
void lcd_ac_temp()
{
tft.fillRect(25,25,100,30,ILI9341_BLACK);
tft.setCursor(30,30);
tft.print(AC_temp);
}
int get_button()
{
int x,y;
if (! ctp.touched()) {
return NO_BUTTON;
}
//tft.fillScreen(ILI9341_BLACK);
// Retrieve a point
TS_Point p = ctp.getPoint();
x = map(p.y, 0, 320, 0, 320);
y = map(p.x, 0, 240, 240, 0);
if(x>BUTTON_ONOFF_X&&x<(BUTTON_ONOFF_X+BOXSIZE)&&y>BUTTON_ONOFF_Y&&y<(BUTTON_ONOFF_Y+BOXSIZE))
return BUTTON_ONOFF;
else if(x>BUTTON_PLUS_X&&x<(BUTTON_PLUS_X+BOXSIZE)&&y>BUTTON_PLUS_Y&&y<(BUTTON_PLUS_Y+BOXSIZE))
return BUTTON_PLUS;
else if(x>BUTTON_MINUS_X&&x<(BUTTON_MINUS_X+BOXSIZE)&&y>BUTTON_MINUS_Y&&y<(BUTTON_MINUS_Y+BOXSIZE))
return BUTTON_MINUS;
else if(x>BUTTON_MODE_X&&x<(BUTTON_MODE_X+BOXSIZE)&&y>BUTTON_MODE_Y&&y<(BUTTON_MODE_Y+BOXSIZE))
return BUTTON_MODE;
else
return NO_BUTTON;
}
//ir
void turn_ac_off()
{
isAcOn=false;
Serial.println("ac is off");
}
void start_ac(int temp,bool heat_mode)
{
Serial.print("start ac with temp: ");
Serial.print(temp);
Serial.print(" in mode ");
if(heat_mode)
Serial.println("heat");
else
Serial.println("cold");
isAcOn=true;
}
void adjust_temp(bool increase)
{
if(increase)
AC_temp++;
else
AC_temp--;
}