2015. 10. 8. 14:44ㆍ2018년 이전 관심사/개발관련
Remote Temperature/Humidity Checker & LED controller
앞에서 설명한 mbed RPC Library와 Python Interface를 활용한 예제를 만들어 보려고 하다 보니 제목이 거창해 진거 같다.
간단하게 말하자면, 본 예제는 아래와 같은 기능을 수행한다.
- mbed platform의 3색 LED 제어 ( On/Off )
- mbed platform의 현재 LED 상태 확인 ( Smartphone의 TTS 기능을 이용하여 Green,Blue,Red 인지 상태 확인 기능 )
- mbed platform으로 부터 온도, 습도 정보를 확인 ( Smartphone의 TTS 기능을 이용하여 온/습도 정보를 확인 가능)
본 예제에서는 mbed RPC를 이용하여 스마트폰에서 mbed platform을 제어하고 있으며, 스마트폰의 Application은 python 기반의 kivy 라이브러리를 사용하였다.
mbed HTTP RPC Server
본 장에서는 위에서 설명한 동작을 수행하기 위한 mbed code를 구현하는 방법에 대해 설명한다. 아래 코드는 mbed rpc와 HTTP Server 등을 구동하기 위한 코드이며, 사용된 라이브러리는 아래와 같다. mbed platform에 아래 코드를 컴파일해서 Upload 하면, 외부에서 HTTP Data를 이용하여 mbed platform을 제어 할 수 있다.
- DHT : 온/습도 센서를 제어 하기 위한 라이브러리
- HTTPServer : HTTP Server를 위한 라이브러리
- mbed-rpc : mbed RPC를 위한 라이브러리
- WIZnetInterface : 별도의 Software stack 없이 Ethernet을 사용하기 위한 라이브러리
Example Code는 아래 경로에서 다운로드 할 수 있다.
RPC_HTTP_WIZnetInterface
#include "mbed.h"
#include "EthernetInterface.h"
#include "HTTPServer.h"
#include "mbed_rpc.h"
#include "DHT.h"
RpcDigitalOut led1(D9,"led1");
RpcDigitalOut led2(D10,"led2");
RpcDigitalOut led3(D11,"led3");
//RPCVarialbe<float> RPCTemperature(&GetTemperature, "Temperature");
//RPCVarialbe<float> RPCHumidity(&GetHumidity, "Humidity");
void Get_Temp_and_Humidity(Arguments * input, Reply * output);
RPCFunction Temp_and_Humidity_Finder(&Get_Temp_and_Humidity, "Temp_and_Humidity_Finder");
EthernetInterface eth;
HTTPServer svr;
DHT sensor(D4, DHT11);
void Get_Temp_and_Humidity(Arguments * input, Reply *output){
int error = 0;
float h = 0.0f, c = 0.0f;
char arg[100];
error = sensor.readData();
if (0 == error) {
c = sensor.ReadTemperature(CELCIUS);
h = sensor.ReadHumidity();
sprintf(arg,"Temperature in Celcius: %4.2f, Humidity is %4.2f",c, h);
output->putData(arg);
}
}
int main() {
//Turn the LEDs off
uint8_t mac_addr[6] = {0x00, 0x08, 0xDC, 0x32, 0x23, 0x42};
led1.write(0);
led2.write(0);
led3.write(0);
RPC::add_rpc_class<RpcDigitalOut>();
printf("Setting up...\n");
eth.init(mac_addr);
int ethErr = eth.connect();
if(ethErr < 0)
{
printf("Error %d in setup.\n", ethErr);
return -1;
}
svr.addHandler<HTTPRpcRequestHandler>("/rpc");
//attach server to port 80
printf("Listening...\n");
svr.start(80, ð);
Timer tm;
tm.start();
//Listen indefinitely
while(true)
{
svr.poll();
if(tm.read()>.5)
{
tm.start();
}
}
}
- 7~8 : 3색 LED를 위한 GPIO를 RPC에 등록
- 15 : 온/습도를 얻어 오기 위한 Custom 함수를 RPC에 등록
- 22~35 : Custom 함수의 구현 부
- mbed RPC client로 부터 요청이 들어오면 온/습도를 추출한 후, Temperature in Celcius : … “ 데이터를 RPC client에게 송신 한다.
- 54 : HTTPRPC Request 등록
Smartphone Simple Application
본 장에서는 Smartphone에서 mbed device를 제어하기 위한 간단한 Application을 만드는 방법을 설명한다. 본 예제는 python으로 구현 하였으며, UI를 위해 kivy 라이브러리를 사용하였다. 본 예제를 구현 및 구동하기 위해서는 아래와 같은 절차를 수행 해야 한다.
Download Qpython
Android 폰에서 python을 구동하기 위해서는 Qpython 이라는 프로그램이 필요 하며, 다운로드 경로는 아래와 같다.
QPython Download
앞에서 설명한 것과 같이 python으로 UI를 만들기 위해서는 kivy 라이브러리가 필요하며, 스마트폰의 TTS(Text to Speach) 기능을 사용하기 위해서는 AndroidHelper 라이브러리가 있어야 한다. 각각의 라이브러리는 아래 그림과 같은 절차를 수행하면 설치 할 수 있다.
Edit Source Code
스마트폰 앱으로 소스코드를 작성하는 일은 매우 불편하다. 다행히도 QPython은 미리 작성한 코드를 FTP로 핸드폰에 저장하는 기능을 지원하고 있다.
나는 이 기능을 이용해서 PC에서 미리 구현해 놓은 프로그램을 스마트폰에 복사 한 후 실행하는 절차로 코드를 구현 및 디버깅 했다. ( 이 또한 매우 불편 하였다. )
Setting for FTP
아래 그림과 같은 절차를 수행하면 Qpython의 FTP 기능을 사용 할 수 있다.
Upload Source Code to Smartphone
아래 그림들은 PC에서 QPython의 FTP Server에 접속해서 미리 작성한 코드를 업로드 하는 방법을 나타낸다.
FTP 접속에 성공하면 아래와 같이 Qpython의 폴더 트리를 볼 수 있다. 폴더 트리에 나오는 폴더를 하나 선택하여 미리 작성한 코드를 업로드 하면 된다.
나는 project3/RPC_TTS 폴더를 만들고 kivy.py와 mbedRPC.py를 복사 해서 사용한다.
mbedRPC.py는 앞에서 설명한 mbed python RPC library이며, kivy.py는 Application의 UI 및 동작을 구현한 파일이다.
Source code of kivy.py
#-*-coding:utf8;-*-
#qpy:2
#qpy:kivy
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from mbedRPC import *
import androidhelper
class CommandScreen(GridLayout):
def __init__(self, **kwargs):
super(CommandScreen, self).__init__(**kwargs)
self.cols = 2
self.row = 2
self.row_force_default=True
self.row_default_height=200
self.add_widget(Label(text='Device IP'))
self.m_text_device_ip = TextInput(multiline=False,text="192.168.18.121")
self.add_widget(self.m_text_device_ip)
self.m_button_init = Button(text="Init")
self.m_button_init.bind(on_press=self.mbedInit)
self.add_widget(self.m_button_init)
self.m_button_GetTemp = Button(text="Get Temp")
self.m_button_GetTemp.bind(on_press=self.GetTemp)
self.add_widget(self.m_button_GetTemp)
self.btn_onLed1 = Button(text="Turn On",background_color=(1,0,0,1))
self.btn_onLed1.bind(on_press=self.TurnOnLed1)
self.add_widget(self.btn_onLed1)
self.btn_offLed1 = Button(text="Turn Off",background_color=(1,0,0,1))
self.btn_offLed1.bind(on_press=self.TurnOffLed1)
self.add_widget(self.btn_offLed1)
self.btn_onLed2 = Button(text="Turn On",background_color=(0,1,0,1))
self.btn_onLed2.bind(on_press=self.TurnOnLed2)
self.add_widget(self.btn_onLed2)
self.btn_offLed2 = Button(text="Turn Off",background_color=(0,1,0,1))
self.btn_offLed2.bind(on_press=self.TurnOffLed2)
self.add_widget(self.btn_offLed2)
self.btn_onLed3 = Button(text="Turn On",background_color=(0,0,1,1))
self.btn_onLed3.bind(on_press=self.TurnOnLed3)
self.add_widget(self.btn_onLed3)
self.btn_offLed3 = Button(text="Turn Off",background_color=(0,0,1,1))
self.btn_offLed3.bind(on_press=self.TurnOffLed3)
self.add_widget(self.btn_offLed3)
self.btn_getLedStatus = Button(text="LED Status")
self.btn_getLedStatus.bind(on_press=self.GetLedStatus)
self.add_widget(self.btn_getLedStatus)
self.btn_getA0Status = Button(text="Get A0 Status")
self.btn_getA0Status.bind(on_press=self.GetA0Status)
self.add_widget(self.btn_getA0Status)
def mbedInit(self,event):
self.droid = androidhelper.Android()
self.mbed = HTTPRPC(self.m_text_device_ip.text)
self.led1 = DigitalOut(self.mbed,"led1")
self.led2 = DigitalOut(self.mbed,"led2")
self.led3 = DigitalOut(self.mbed,"led3")
self.temp_humidity = RPCFunction(self.mbed,"Temp_and_Humidity_Finder")
box = BoxLayout(orientation='vertical')
box.add_widget(Label(text='Init Complete'))
button_close = Button(text='Close me!')
box.add_widget(button_close)
popup = Popup(title='message', content=box,
size_hint=(None,None),size=(400,400), auto_dismiss=False)
button_close.bind(on_press=popup.dismiss)
popup.open()
def GetTemp(self,event):
resp = self.temp_humidity.run("")
self.droid.ttsSpeak(resp)
def TurnOnLed1(self,event):
self.led1.write(1)
def TurnOffLed1(self,event):
self.led1.write(0)
def TurnOnLed2(self,event):
self.led2.write(1)
def TurnOffLed2(self,event):
self.led2.write(0)
def TurnOnLed3(self,event):
self.led3.write(1)
def TurnOffLed3(self,event):
self.led3.write(0)
def GetLedStatus(self,event):
if( self.led1.read()[0] == '1' ): self.droid.ttsSpeak("Turn on red.")
if( self.led2.read()[0] == '1' ): self.droid.ttsSpeak("Turn on green.")
if( self.led3.read()[0] == '1' ): self.droid.ttsSpeak("Turn on blue.")
def GetA0Status(self,event):
print ''
class MyApp(App):
def build(self):
return CommandScreen()
if __name__ == '__main__':
MyApp().run()
- 15 ~ 65 : App Button 및 UI 초기화
- 68 ~ 86 : mbed RPC library 초기화
- 89 : mbed platform으로 부터 온/습도 데이터를 수신 후 TTS로 출력
- 93 ~ 109 : LED1/2/3 On/Off
- 111 ~ 114 : 현재 mbed platform의 LED 색깔을 확인 후 TTS로 출력
Result after run
Demo Video
'2018년 이전 관심사 > 개발관련' 카테고리의 다른 글
How to make Geo-location Watch (0) | 2015.10.08 |
---|---|
How to make Wi-Fi oil checker using Axeda (0) | 2015.10.08 |
DIY 캐논 카메라 리모컨 및 수신기 만들기 (1) | 2014.11.26 |
SNS을 이용한 개인용 화재 경보 시스템 만들기 (0) | 2014.10.15 |
[Arduino]WizFi250 Twitter Example (0) | 2014.09.23 |