9월 15일
라즈베리파이 5일차
과제
온도가 높으면 warning message를 LCD에 출력 + LED를 끄거나 깜빡거리게.
구조에 어긋나지 않게 코딩하고 싶었으나, 필요하다 생각돼 구조가 바뀜
//main.cpp
#include <iostream>
#include <wiringPi.h>
#include "Button.h"
#include "Led.h"
#include "Listener.h"
#include "Controller.h"
#include "View.h"
#include "LCD.h"
#include "ClockView.h"
#include "ClockService.h"
#include "ClockCheck.h"
#include "I2C.h"
#include "DHT11.h"
#include "DHT_Data.h"
#include "TempHumidService.h"
#include "TempHumidView.h"
#include <time.h>
int main()
{
std::cout << "Hello World!" << std::endl;
// time_t timeSec;
// struct tm *timeDate;
ClockCheck clockCheck;
Button modeButton(27);
Button powerButton(28);
Led led1(21);
Led led2(22);
Led led3(23);
Led led4(24);
Led led5(25);
DHT11 dht(7);
DHT_Data dhtData;
LCD lcd(new I2C("/dev/i2c-1", 0x27));
View view(&led1, &led2, &led3, &led4, &led5, &lcd);
ClockView clockView(&lcd);
TempHumidView tempHumidView(&lcd, &led1, &led2, &led3, &led4, &led5);
Service service(&view);
ClockService clockService(&clockView);
TempHumidService tempHumidService(&tempHumidView, &view);
Controller control(&service, &clockService, &tempHumidService);
Listener listener(&modeButton, &powerButton, &control, &clockCheck, &dht);
while (1)
{
// dhtData = dht.readData();
// if(!dhtData.error)
// {
// std::cout << "humidity : " << dhtData.RH
// << "." << dhtData.RHDec
// << "%, Temperature : " << dhtData.Temp <<
// "." << dhtData.TempDec << "C" << std::endl;
// }
listener.checkEvent();
view.lightView();
delay(50);
}
return 0;
}
DHT11 Service(TempHumidService)에서 DHT11 View 이외에 Light View도 상속된 것을 볼 수 있다.
(TempHumidService tempHumidService(&tempHumidView, &view);)
일단 기능 구현을 위해 생각한 대로 짠 건데, Service 객체에서 특정 온도 이상 이하를 구분하는 로직을 넣고 싶었다. 그런데 실행을 하니까 View 쪽 라인을 따라 초기값에 의해 Light Off가 출력되는 바람에 원하는 대로 warning 메세지가 LCD에서 출력되지 않았다. 그래서 특정 온도 이상일 때는 기존과 다른 state(Light Off가 아닌)를 부여하기 위해 Light View 객체도 상속받았다.
다른 사람들은 어디서 판단하나 했는데 DHT11 View 단에서 판단했다고 한다. lcd 상속은 Light View나 DHT11 View나 똑같아서 lcd에서 온도를 저장시키고 판단가능하도록 로직을 짰다고 하는데, 아직은 코드를 구상할 때 기능에 초점을 두고 architecture까지 눈이 닿지 않는 거 같다.
교수님의 코드를 보고 비교해보고자 모든 코드를 올리겠다.
//Listener.h
#ifndef __LISTENER_H__
#define __LISTENER_H__
#include "Button.h"
#include "Controller.h"
#include "ClockCheck.h"
#include "DHT11.h"
#include "DHT_Data.h"
class Listener
{
private :
Button *powerButton;
Button *modeButton;
Controller *controller;
ClockCheck *timeClock;
DHT11 *dht11;
public:
Listener(Button *button, Button *powerButton, Controller *control, ClockCheck *time, DHT11 *dht11);
~Listener();
void checkEvent();
};
#endif /* __LISTENER_H__ */
//Listener.cpp
#include "Listener.h"
#include <wiringPi.h>
Listener::Listener(Button *button, Button *powerButton, Controller *control, ClockCheck *time, DHT11 *dht11)
{
modeButton = button;
this->powerButton = powerButton;
controller = control;
timeClock = time;
this->dht11 = dht11;
}
Listener::~Listener()
{
}
void Listener::checkEvent()
{
if (modeButton->getState() == RELEASE_ACTIVE)
{
controller->updateEvent("modeButton");
}
if (powerButton->getState() == RELEASE_ACTIVE)
{
controller->updateEvent("powerButton");
}
if (timeClock->isUpdate())
{
controller->updateEvent("clockUpdate");
}
static unsigned int prevTempHumidTime = 0;
if(millis() - prevTempHumidTime > 2000)
{
prevTempHumidTime = millis();
DHT_Data dhtData = dht11->readData();
if(dhtData.error == 0)
{
controller->updateTempHumid(dhtData);
}
}
}
//Controller.h
#ifndef __CONTROLLER_H__
#define __CONTROLLER_H__
#include <string>
#include "Service.h"
#include "ClockService.h"
#include "DHT_Data.h"
#include "TempHumidService.h"
class Controller
{
private:
int lightState;
Service *service;
ClockService *clockService;
TempHumidService *tempHumidService;
public:
Controller(Service *serv, ClockService *clockServ, TempHumidService *tempHumidService);
virtual ~Controller();
void updateEvent(std::string strBtn);
void updateTempHumid(DHT_Data dhtData);
};
#endif /* __CONTROLLER_H__ */
//Controller.cpp
#include "Controller.h"
Controller::Controller(Service *serv, ClockService *clockServ, TempHumidService *tempHumidService)
{
service = serv;
clockService = clockServ;
lightState = LIGHT_OFF;
this->tempHumidService = tempHumidService;
}
Controller::~Controller()
{
}
void Controller::updateEvent(std::string strBtn)
{
if (strBtn == "modeButton")
{
service->updateState("modeButton");
}
if (strBtn == "powerButton")
{
service->updateState("powerButton");
}
if (strBtn == "clockUpdate")
{
clockService->updateEvent();
}
}
void Controller::updateTempHumid(DHT_Data dhtData)
{
tempHumidService->updateEvent(dhtData);
}
//LightState.h
#ifndef LIGHTSTATE_H
#define LIGHTSTATE_H
#pragma once
enum {LIGHT_OFF, LIGHT_1, LIGHT_2, LIGHT_3, LIGHT_4, LIGHT_5, WARNING};
#endif
//Service.h
#ifndef SERVICE_H
#define SERVICE_H
#include "LightState.h"
#include "View.h"
#pragma once
class Service
{
public:
Service(View *viewer);
virtual ~Service();
void updateState(std::string strState);
private:
int lightState;
View *view;
};
#endif
//Service.cpp
#include "Service.h"
Service::Service(View *viewer)
{
view = viewer;
lightState = LIGHT_OFF;
}
Service::~Service()
{
}
void Service::updateState(std::string strState)
{
switch (lightState)
{
case LIGHT_OFF:
if (strState == "modeButton")
{
lightState = LIGHT_1;
}
if (strState == "powerButton")
{
lightState = LIGHT_OFF;
}
view->setState(lightState);
break;
case LIGHT_1:
if (strState == "modeButton")
{
lightState = LIGHT_2;
}
if (strState == "powerButton")
{
lightState = LIGHT_OFF;
}
view->setState(lightState);
break;
case LIGHT_2:
if (strState == "modeButton")
{
lightState = LIGHT_3;
}
if (strState == "powerButton")
{
lightState = LIGHT_OFF;
}
view->setState(lightState);
break;
case LIGHT_3:
if (strState == "modeButton")
{
lightState = LIGHT_4;
}
if (strState == "powerButton")
{
lightState = LIGHT_OFF;
}
view->setState(lightState);
break;
case LIGHT_4:
if (strState == "modeButton")
{
lightState = LIGHT_5;
}
if (strState == "powerButton")
{
lightState = LIGHT_OFF;
}
view->setState(lightState);
break;
case LIGHT_5:
if (strState == "modeButton") {
lightState = LIGHT_OFF;
}
if (strState == "powerButton")
{
lightState = LIGHT_OFF;
}
view->setState(lightState);
break;
case WARNING:
if (strState == "modeButton") {
lightState = LIGHT_OFF;
}
if (strState == "powerButton")
{
lightState = LIGHT_OFF;
}
view->setState(lightState);
break;
}
}
//ClockService.h
#ifndef CLOCKSERVICE_H
#define CLOCKSERVICE_H
#include <time.h>
#include "ClockView.h"
#pragma once
class ClockService
{
public:
ClockService(ClockView *clockview);
virtual ~ClockService();
void updateEvent();
private:
time_t curTime;
ClockView *clockView; //clockView에게 메세지를 전달할 게 필요함
};
#endif
//ClockService.cpp
#include "ClockService.h"
ClockService::ClockService(ClockView *clockview)
{
curTime = 0;
clockView = clockview;
}
ClockService::~ClockService()
{
}
void ClockService::updateEvent()
{
curTime = time(NULL);
struct tm *timeDate = localtime(&curTime);
clockView->updateTime(timeDate);
}
//TempHumidService.h
#ifndef TEMPHUMIDSERVICE_H
#define TEMPHUMIDSERVICE_H
#pragma once
#include "DHT_Data.h"
#include "TempHumidView.h"
#include "View.h"
#include "LightState.h"
class TempHumidService
{
public:
TempHumidService(TempHumidView *tempHumidView, View *view);
virtual ~TempHumidService();
void updateEvent(DHT_Data dhtData);
void SafetyCheck(float temp, float humid);
private:
TempHumidView *tempHumidView;
View *viewer;
};
#endif
//TempHumidService.cpp
#include "TempHumidService.h"
TempHumidService::TempHumidService(TempHumidView *tempHumidView, View *view)
{
this->tempHumidView = tempHumidView;
viewer = view;
}
TempHumidService::~TempHumidService()
{
}
void TempHumidService::updateEvent(DHT_Data dhtData)
{
float temp, humid;
temp = (float)dhtData.Temp + (float)(dhtData.TempDec/10.0);
humid = (float)dhtData.RH + (float)(dhtData.RHDec/10.0);
SafetyCheck(temp, humid);
}
void TempHumidService::SafetyCheck(float temp, float humid)
{
if(temp >= 27)
{
tempHumidView->Warning();
viewer->setState(WARNING);
}
else
{
tempHumidView->setTempHumidData(temp, humid);
}
}
//View.h
#ifndef __VIEW_H__
#define __VIEW_H__
#include <string>
#include "Led.h"
#include "LCD.h"
class View
{
private:
LCD *lcd;
int lightState;
Led *light1;
Led *light2;
Led *light3;
Led *light4;
Led *light5;
public:
View(Led *led1, Led *led2, Led *led3, Led *led4, Led *led5, LCD *lcd);
virtual ~View();
void setState(int state);
void lightView();
void lightOn_1();
void lightOn_2();
void lightOn_3();
void lightOn_4();
void lightOn_5();
void lightOff();
};
#endif /* __VIEW_H__ */
//View.cpp
#include "View.h"
#include "LightState.h"
#include <wiringPi.h>
View::View(Led *led1, Led *led2, Led *led3, Led *led4, Led *led5, LCD *lcd)
{
// char buff[30];
// int state = 0;
// sprintf(buff, "state : %d", state);
// lcd->WriteStringXY(0,0,buff);
light1 = led1;
light2 = led2;
light3 = led3;
light4 = led4;
light5 = led5;
lightState = LIGHT_OFF;
this->lcd = lcd;
}
View::~View()
{
}
void View::setState(int state)
{
lightState = state;
// char buff[30];
// sprintf(buff, " ");
// lcd->WriteStringXY(0, 0, buff);
}
void View::lightView()
{
switch (lightState)
{
case LIGHT_OFF:
lightOff();
break;
case LIGHT_1:
lightOn_1();
break;
case LIGHT_2:
lightOn_2();
break;
case LIGHT_3:
lightOn_3();
break;
case LIGHT_4:
lightOn_4();
break;
case LIGHT_5:
lightOn_5();
break;
case WARNING:
break;
}
}
void View::lightOn_1()
{
char buff[30];
sprintf(buff, "Light 1 ");
lcd->WriteStringXY(0,0,buff);
lcd->backLightOn();
light1->On();
light2->Off();
light3->Off();
light4->Off();
light5->Off();
}
void View::lightOn_2()
{
char buff[30];
sprintf(buff, "Light 2 ");
lcd->WriteStringXY(0,0,buff);
lcd->backLightOn();
light1->On();
light2->On();
light3->Off();
light4->Off();
light5->Off();
}
void View::lightOn_3()
{
char buff[30];
sprintf(buff, "Light 3 ");
lcd->WriteStringXY(0,0,buff);
lcd->backLightOn();
light1->On();
light2->On();
light3->On();
light4->Off();
light5->Off();
}
void View::lightOn_4()
{
char buff[30];
sprintf(buff, "Light 4 ");
lcd->WriteStringXY(0,0,buff);
lcd->backLightOn();
light1->On();
light2->On();
light3->On();
light4->On();
light5->Off();
}
void View::lightOn_5()
{
char buff[30];
sprintf(buff, "Light 5 ");
lcd->WriteStringXY(0,0,buff);
lcd->backLightOn();
light1->On();
light2->On();
light3->On();
light4->On();
light5->On();
}
void View::lightOff()
{
char buff[30];
sprintf(buff, "Light Off ");
lcd->WriteStringXY(0,0,buff);
lcd->backLightOff();
light1->Off();
light2->Off();
light3->Off();
light4->Off();
light5->Off();
}
//ClockView.h
#ifndef CLOCKVIEW_H
#define CLOCKVIEW_H
#pragma once
#include <time.h>
#include "LCD.h"
class ClockView
{
private:
struct tm timeDate;
LCD *lcd;
public:
ClockView(LCD *lcd);
~ClockView();
void updateTime(tm *timeDate);
};
#endif
//ClockView.cpp
#include "ClockView.h"
ClockView::ClockView(LCD *lcd)
{
this->lcd = lcd;
// timeDate = 0;
}
ClockView::~ClockView()
{
}
void ClockView::updateTime(tm *timeDate)
{
char buff[30];
sprintf(buff, "%02d:%02d:%02d", timeDate->tm_hour, timeDate->tm_min, timeDate->tm_sec);
lcd->WriteStringXY(1, 0, buff);
}
//TempHumidView.h
#ifndef TEMPHUMIDVIEW_H
#define TEMPHUMIDVIEW_H
#pragma once
#include "LCD.h"
#include "Led.h"
#include <wiringPi.h>
class TempHumidView
{
public:
TempHumidView(LCD *lcd, Led *led1, Led *led2, Led *led3, Led *led4, Led *led5);
~TempHumidView();
void setTempHumidData(float temp, float humid);
void Warning();
void Warning_light();
private:
LCD *lcd;
Led *light1;
Led *light2;
Led *light3;
Led *light4;
Led *light5;
};
#endif
//TempHumidView.cpp
#include "TempHumidView.h"
TempHumidView::TempHumidView(LCD *lcd, Led *led1, Led *led2, Led *led3, Led *led4, Led *led5)
{
this->lcd = lcd;
light1=led1;
light2=led2;
light3=led3;
light4=led4;
light5=led5;
}
TempHumidView::~TempHumidView()
{
}
void TempHumidView::setTempHumidData(float temp, float humid)
{
char buff[30];
sprintf(buff, "%.1fC ", temp);
lcd->WriteStringXY(0, 10, buff);
printf("%s\n", buff);
sprintf(buff, "%.1f%% ", humid);
lcd->WriteStringXY(1, 10, buff);
printf("%s\n", buff);
}
void TempHumidView::Warning()
{
char buff[30];
sprintf(buff, "StopTooHighTemp!");
lcd->WriteStringXY(0, 0, buff);
Warning_light();
}
void TempHumidView::Warning_light()
{
static int warning_prevTime = 0;
std::cout << millis()-warning_prevTime << std::endl;
int warning_state = 0;
if(millis()-warning_prevTime >= 5000)
{
warning_prevTime = millis();
warning_state = !warning_state;
}
if(warning_state)
{
light1->On();
light2->On();
light3->On();
light4->On();
light5->On();
}
else
{
light1->Off();
light2->Off();
light3->Off();
light4->Off();
light5->Off();
}
}
App, HW 구분
//Button.h
#ifndef __BUTTON_H__
#define __BUTTON_H__
enum {NO_ACTIVE, PUSH_ACTIVE, RELEASE_ACTIVE};
class Button
{
private:
const int SET = 1;
const int RESET = 0;
const int PUSHED = RESET;
const int RELEASED = SET;
int pinNumber;
int prevState;
int readPin();
public:
Button(int pin);
virtual ~Button();
int getState();
};
#endif /* __BUTTON_H__ */
//Button.cpp
#include "Button.h"
#include "wiringPi.h"
Button::Button(int pin)
: pinNumber(pin), prevState(RELEASED)
{
wiringPiSetup();
pinMode(pinNumber, INPUT);
}
Button::~Button()
{
}
int Button::readPin()
{
return digitalRead(pinNumber);
}
int Button::getState()
{
int curState = readPin();
if (curState == PUSHED && prevState == RELEASED) {
prevState = PUSHED;
return PUSH_ACTIVE;
}
else if (curState == RELEASED && prevState == PUSHED) {
prevState = RELEASED;
return RELEASE_ACTIVE;
}
return NO_ACTIVE;
}
//Clock.h
#ifndef CLOCKCHECK_H
#define CLOCKCHECK_H
#include <time.h>
class ClockCheck
{
public:
ClockCheck();
~ClockCheck();
bool isUpdate();
private:
time_t prevSec;
};
#endif
//Clock.cpp
#include "ClockCheck.h"
ClockCheck::ClockCheck()
{
prevSec = 0;
}
ClockCheck::~ClockCheck()
{
}
bool ClockCheck::isUpdate()
{
time_t curSec = time(NULL);
if(curSec == prevSec)
{
return false;
}
else
{
prevSec = curSec;
return true;
}
return false;
}
//DHT_Data.h
#ifndef __DHT_Data_H__
#define __DHT_Data_H__
#include "DHT_Data.h"
class DHT_Data
{
public:
int RH;
int RHDec;
int Temp;
int TempDec;
int checksum;
int error;
};
#endif
//DHT11.h
#ifndef __DHT11_H__
#define __DHT11_H__
#include "DHT_Data.h"
class DHT11
{
private:
int pinNumber;
int data[5];
DHT_Data dhtData;
void startTrigger();
void waitResponse();
void clearData();
public:
DHT11(int pin);
virtual ~DHT11();
DHT_Data readData();
};
#endif /* __DHT11_H__ */
//DHT11.cpp
#include "DHT11.h"
#include <wiringPi.h>
#include <iostream>
DHT11::DHT11(int pin)
: pinNumber(pin)
{
clearData();
wiringPiSetup();
}
DHT11::~DHT11()
{
}
void DHT11::clearData()
{
for (int i=0; i<5; i++) {
data[i] = 0;
}
}
void DHT11::startTrigger()
{
// Start Trigger
pinMode(pinNumber, OUTPUT);
digitalWrite(pinNumber, LOW);
delay(18);
digitalWrite(pinNumber, HIGH);
pinMode(pinNumber, INPUT);
}
void DHT11::waitResponse()
{
// read response
int count = 0;
while (digitalRead(pinNumber))
{
delayMicroseconds(1);
count++;
if (count == 255)
break;
}
count = 0;
while (!digitalRead(pinNumber))
{
delayMicroseconds(1);
count++;
if (count == 255)
break;
}
count = 0;
while (digitalRead(pinNumber))
{
delayMicroseconds(1);
count++;
if (count == 255)
break;
}
}
DHT_Data DHT11::readData()
{
int count = 0;
clearData();
startTrigger();
waitResponse();
// read data
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 8; j++)
{
count = 0;
while (!digitalRead(pinNumber)) // low
{
delayMicroseconds(1);
count++;
if (count == 255)
break;
}
count = 0;
while (digitalRead(pinNumber)) // high
{
delayMicroseconds(1);
count++;
if (count == 255)
break;
}
if (count < 50)
data[i] &= ~(1 << (7 - j));
else
data[i] |= (1 << (7 - j));
}
//std::cout << "data[" << i << "] : " << data[i] << std::endl;
}
dhtData.RH = data[0];
dhtData.RHDec = data[1];
dhtData.Temp = data[2];
dhtData.TempDec = data[3];
dhtData.checksum = data[4];
dhtData.error = (data[4] == (data[0] + data[1] + data[2] + data[3])) ? 0 : 1;
//std::cout << "data[4] : " << data[4] << " parity " << ((data[0] + data[1] + data[2] + data[3])) << std::endl;
return dhtData;
}
//I2C.h
#ifndef __I2C_H__
#define __I2C_H__
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include <cstring>
class I2C
{
public:
I2C();
I2C(const char* i2cDev, int i2cAddr);
virtual ~I2C();
void start();
void stop();
void sendByteData(uint8_t data);
void sendStreamData(uint8_t* data, size_t size);
private:
int i2cFd;
int i2cAddr;
char i2cDev[20];
};
#endif /* __I2C_H__ */
//I2C.cpp
#include "I2C.h"
I2C::I2C()
{}
I2C::I2C(const char* i2cDev, int i2cAddr)
{
memset(this->i2cDev, 0, sizeof(this->i2cDev));
memcpy(this->i2cDev, i2cDev, strlen(i2cDev)); // "/dev/i2c-1"
this->i2cAddr = i2cAddr;
start();
}
I2C::~I2C()
{
stop();
}
void I2C::start()
{
if((i2cFd = open(i2cDev, O_RDWR)) < 0) {
printf("Error failed to open I2C bus [%s].\n", i2cDev);
exit(-1);
}
// set the I2C slave address for all subsequent I2C device transfers
if (ioctl(i2cFd, I2C_SLAVE, i2cAddr) < 0) {
printf("Error failed to set I2C address [0x%x].\n", i2cAddr);
exit(-1);
}
}
void I2C::stop()
{
close(i2cFd);
}
void I2C::sendByteData(uint8_t data)
{
write(i2cFd, &data, 1);
}
void I2C::sendStreamData(uint8_t* data, size_t size)
{
write(i2cFd, data, size);
}
//LCD.h
#ifndef __LCD_H__
#define __LCD_H__
#include <stdint.h>
#include "I2C.h"
#define LCD_RS 0
#define LCD_RW 1
#define LCD_E 2
#define LCD_BACKLIGHT 3
#define COMMAND_FUNCSET_4BIT_8BIT 0x33
#define COMMAND_FUNCSET_4BIT_4BIT 0x22
#define COMMAND_FUNCSET_4BIT 0x28
#define COMMAND_FUNCSET_8BIT 0x30
#define COMMAND_DISPLAY_OFF 0x08
#define COMMAND_DISPLAY_ON 0x0c
#define COMMAND_DISPLAY_CLEAR 0x01
#define COMMAND_ENTRY_MODE_SET 0x06
class LCD
{
private:
uint8_t lcdData;
I2C *i2c;
void init(void);
void sendDataToInterface(uint8_t data);
void cmdMode(void);
void dataMode(void);
void writeMode(void);
void sendData8bitMode(uint8_t data);
void sendData4bitMode(uint8_t data);
void sendData(uint8_t data);
void writeCommand(uint8_t cmdData);
void writeData(uint8_t charData);
public:
LCD();
LCD(I2C *i2c);
virtual ~LCD();
void writeString(const char *string);
void gotoXY(uint8_t row, uint8_t col);
void WriteStringXY(uint8_t row, uint8_t col, const char *string);
void backLightOn();
void backLightOff();
};
#endif /* __LCD_H__ */
//LCD.cpp
#include "LCD.h"
LCD::LCD()
{
}
LCD::~LCD()
{
delete i2c;
}
LCD::LCD(I2C *i2c)
: lcdData(0)
{
this->i2c = i2c;
init();
}
void LCD::sendDataToInterface(uint8_t data) // 8bit mode data 전송
{
// 3. 입력된 data를 전송
i2c->sendByteData(data);
}
void LCD::sendData8bitMode(uint8_t data)
{
}
void LCD::sendData4bitMode(uint8_t data)
{
lcdData = (lcdData & 0x0f) | (data & 0xf0); // data 상위 4bit 전송
lcdData |= (1 << LCD_E);
sendDataToInterface(lcdData);
lcdData &= ~(1 << LCD_E);
sendDataToInterface(lcdData);
usleep(1000);
lcdData = (lcdData & 0x0f) | ((data & 0x0f) << 4); // data 하위 4bit 전송
lcdData |= (1 << LCD_E);
sendDataToInterface(lcdData);
lcdData &= ~(1 << LCD_E);
sendDataToInterface(lcdData);
usleep(1000);
}
void LCD::sendData(uint8_t data)
{
sendData4bitMode(data);
}
void LCD::cmdMode(void)
{
// 1. cmd RS값을 0 으로 출력
lcdData &= ~(1 << LCD_RS);
}
void LCD::dataMode(void)
{
// 1. data RS값을 1 으로 출력
lcdData |= (1 << LCD_RS);
}
void LCD::writeMode(void)
{
// 2. R/W pin값을 0(write)으로 출력
lcdData &= ~(1 << LCD_RW);
}
void LCD::writeCommand(uint8_t cmdData)
{
cmdMode();
writeMode();
sendData(cmdData);
}
void LCD::writeData(uint8_t charData)
{
dataMode();
writeMode();
sendData(charData);
}
void LCD::backLightOn()
{
lcdData |= (1 << LCD_BACKLIGHT); // #define BACKLIGHT 3
// sendData(lcdData);
sendDataToInterface(lcdData);
}
void LCD::backLightOff()
{
lcdData &= ~(1 << LCD_BACKLIGHT);
// sendData(lcdData);
sendDataToInterface(lcdData);
}
void LCD::init(void)
{
usleep(40000);
sendDataToInterface(0b00110100); // 8bit Mode Enalbe:High
sendDataToInterface(0b00110000); // 8bit Mode Enalbe:Low
usleep(5000);
sendDataToInterface(0b00110100); // 8bit Mode Enalbe:High
sendDataToInterface(0b00110000); // 8bit Mode Enalbe:Low
usleep(1000);
sendDataToInterface(0b00110100); // 8bit Mode Enalbe:High
sendDataToInterface(0b00110000); // 8bit Mode Enalbe:Low
usleep(5000);
sendDataToInterface(0b00100100); // 4bit Mode Enalbe:High
sendDataToInterface(0b00100000); // 4bit Mode Enalbe:Low
usleep(5000);
writeCommand(COMMAND_FUNCSET_4BIT); // 4bit Mode, 2Line, 5x7
writeCommand(COMMAND_DISPLAY_OFF); // Display Off
writeCommand(COMMAND_DISPLAY_CLEAR); // Display Clear
writeCommand(COMMAND_ENTRY_MODE_SET); // Entry Mode Set
writeCommand(COMMAND_DISPLAY_ON); // Display Off
backLightOn();
}
void LCD::writeString(const char *string)
{
for (uint8_t i = 0; string[i]; i++)
{
writeData(string[i]);
}
}
void LCD::gotoXY(uint8_t row, uint8_t col)
{
col %= 16;
row %= 2;
uint8_t address = (0x40 * row) + col;
uint8_t command = 0x80 + address;
writeCommand(command);
}
void LCD::WriteStringXY(uint8_t row, uint8_t col, const char *string)
{
gotoXY(row, col);
writeString(string);
}
//Led.h
#ifndef __LED_H__
#define __LED_H__
class Led
{
private:
const bool ON = 1;
const bool OFF = 0;
int pinNumber;
bool ledState;
void writePin(bool pinState);
public:
Led(int pin);
virtual ~Led();
void On();
void Off();
void Toggle();
};
#endif /* __LED_H__ */
//Led.cpp
#include "Led.h"
#include "wiringPi.h"
Led::Led(int pin)
: pinNumber(pin), ledState(OFF)
{
wiringPiSetup();
pinMode(pinNumber, OUTPUT);
}
Led::~Led()
{
}
void Led::writePin(bool pinState)
{
digitalWrite(pinNumber, (int)pinState);
}
void Led::On()
{
ledState = ON;
writePin(ledState);
}
void Led::Off()
{
ledState = OFF;
writePin(ledState);
}
void Led::Toggle()
{
ledState ^= 1;
writePin(ledState);
}
//CMakeLists.txt
cmake_minimum_required(VERSION 3.0.0)
project(StandLight_Clock_Temperature)
add_executable(${PROJECT_NAME}
./src/main.cpp
./src/app/Service/TempHumidService.cpp
./src/app/Service/ClockService.cpp
./src/app/Service/Service.cpp
./src/app/Listener/Listener.cpp
./src/app/Controller/Controller.cpp
./src/app/View/TempHumidView.cpp
./src/app/View/View.cpp
./src/app/View/ClockView.cpp
./src/hw/DHT11/DHT11.cpp
./src/hw/Button/Button.cpp
./src/hw/Led/Led.cpp
./src/hw/ClockCheck/ClockCheck.cpp
./src/hw/LCD/LCD.cpp
./src/hw/I2C/I2C.cpp
)
target_include_directories(${PROJECT_NAME} PUBLIC
./src/app/Service
./src/app/Listener
./src/app/Controller
./src/app/View
./src/hw/DHT11
./src/hw/Button
./src/hw/Led
./src/hw/ClockCheck
./src/hw/LCD
./src/hw/I2C
)
target_link_libraries(${PROJECT_NAME} PUBLIC
-lwiringPi
)
target_compile_options(${PROJECT_NAME} PUBLIC
-Wall
)