오늘 소개하는 Accessory shield for bluno는 OLED 디스플레이 및 여러가지 센서들을 하나의 보드로 통합한 것으로, 다른 쉴드들처럼 아두이노 보드위에 삽입하여 쉽게 접근할 수 있습니다. 또한, 같은 DFRobot사에서 만든 Bluno(아두이노 bluetooth 통합 보드)와 연결하면, 블루투스 통신을 이용하여 스마트폰 등에서 원격으로 제어할 수 있고, 이를 테스트할 수 있는 스마트폰용 앱과 소스도 제공하고 있습니다.
쉴드는 이렇게 생겼습니다. 박스는 없고 정전기 방지 필름으로만 포장되어 있었습니다. 사진만 보더라도 어떤 기능들이 포함되었는지 쉽게 알 수 있을듯 합니다. 아래 리스트를 참고하세요!
128x64 OLED Screen:Display messages from your phone interface.
해당 디렉토리에 총 4개의 파일이 있습니다. BLUNO.ino는 블루노 보드 소스이므로 아두이노 IDE로 열어서 업로드합니다. 그리고, 아래 3개의 라이브러리를 미리 설치합니다. zip 압축파일로 받으면, 아두이노 IDE의 "Sketch/Include Library/Add .ZIP Library..." 메뉴를 통해 쉽게 설치할 수 있습니다. PlainProtocol은 스마트폰 앱과 통신하기 위한 전송 방식을 지정하고 있고, U8glib.zip은 OLED 디스플레이를 위한 라이브러리, 그리고 blunoAccessory.zip은 각 센서 및 모듈에 대한 예제와 작동 방식을 포함합니다.
3개의 라이브러리를 설치하고, BLUNO.ino 소스를 업로드 하면 바로 스마트폰 앱을 통해 쉴드의 모든 기능을 테스트할 수 있습니다.
#include "Arduino.h"
#include "PlainProtocol.h"
#include "U8glib.h"
#include "blunoAccessory.h"
#define RIGHT 1
#define UP 2
#define LEFT 3
#define DOWN 4
#define PUSH 5
#define MID 0
//PlainProtocol constructor, define the Serial port and the baudrate.
PlainProtocol myBLUNO(Serial,115200);
//blunoAccessory constructor, for setting the relay,buzzer, temperature, humidity, knob, joystick and RGBLED
blunoAccessory myAccessory;
//OLED constructor, for oled display
U8GLIB_SSD1306_128X64 myOled(U8G_I2C_OPT_NONE);
String oledDisplay=""; //the display string recieved from the mobile device
int humidity=0; //humidity read from DHT11
int temperature=0; //temperature read from DHT11
int ledRed=0; //RGBLED red value
int ledGreen=0; //RGBLED green value
int ledBlue=0; //RGBLED blue value
int knob=0; //knob(potentiometer) value read from analog pin
int joyStick=0; //joystick state
void setup() {
myAccessory.begin();
myBLUNO.init();
myAccessory.setRGBLed(0,0,0); //turn off the RGBLED
}
void draw (void)
{
myOled.setFont(u8g_font_unifont);
myOled.setPrintPos(10,16); //set the print position
myOled.print("H:");
myOled.print(humidity); //show the humidity on oled
myOled.print("%");
myOled.setPrintPos(10,32);
myOled.print("T:"); //show the temperature on oled
myOled.print(temperature);
myOled.print("C");
myOled.setPrintPos(88,16);
myOled.print("R:"); //show RGBLED red value
myOled.print(ledRed);
myOled.setPrintPos(88,32);
myOled.print("G:"); //show RGBLED green value
myOled.print(ledGreen);
myOled.setPrintPos(88,48);
myOled.print("B:"); //show RGBLED blue value
myOled.print(ledBlue);
myOled.setPrintPos(10,48);
myOled.print("Knob:");
myOled.print(knob); //show knob(potentiometer) value read from analog pin
myOled.setPrintPos(10,60);
if (oledDisplay.length()) {
myOled.print(oledDisplay); //if the display string recieved from the mobile device, show the string
}
else{
myOled.print("Joystick:"); //if string is null, show the state of joystick
switch (joyStick){
case MID:
myOled.print("Normal");
break;
case RIGHT:
myOled.print("Right");
break;
case UP:
myOled.print("Up");
break;
case LEFT:
myOled.print("Left");
break;
case DOWN:
myOled.print("Down");
break;
case PUSH:
myOled.print("Push");
break;
default:
break;
}
}
}
void loop()
{
if (myBLUNO.available()) { //receive valid command
if (myBLUNO.equals("BUZZER")) { //if the command name is "BUZZER"
myAccessory.setBuzzer(myBLUNO.read()); //read the content and set the buzzer
}
else if (myBLUNO.equals("RELAY")){ //if the command name is "RELAY"
myAccessory.setRelay(myBLUNO.read()); //read the content and set the relay
}
else if (myBLUNO.equals("DISP")){ //if the command name is "DISP"
oledDisplay=myBLUNO.readString(); //read the string to local value
}
else if(myBLUNO.equals("RGBLED")){ //if the command name is "RGBLED"
ledRed=myBLUNO.read(); //read the red value first
ledGreen=myBLUNO.read(); //read the green value then
ledBlue=myBLUNO.read(); //read the blue value at last
myAccessory.setRGBLed(ledRed, ledGreen, ledBlue); //set the color to the RGBLED
}
else if(myBLUNO.equals("TEMP")){ //if the command name is "TEMP"
myBLUNO.write("TEMP", temperature); //return the value of temperature to mobile device
}
else if(myBLUNO.equals("HUMID")){ //if the command name is "HUMID"
myBLUNO.write("HUMID", humidity); //return the value of humidity to mobile device
}
else if(myBLUNO.equals("KNOB")){ //if the command name is "KNOB"
myBLUNO.write("KNOB", myAccessory.readKnob()); //return the value of the knob(potentiometer) to mobile device
}
}
static unsigned long oledTimer=millis(); //every 200ms update the oled display
if (millis() - oledTimer >= 200) {
oledTimer=millis();
myOled.firstPage(); //for more information about the U8glib library, go to https://code.google.com/p/u8glib/
do{
draw();
}
while(myOled.nextPage());
}
static unsigned long DHT11Timer=millis(); //every 2s update the temperature and humidity from DHT11 sensor
if (millis() - DHT11Timer >= 2000) {
DHT11Timer=millis();
temperature=myAccessory.readTemperature();
humidity=myAccessory.readHumidity();
}
static unsigned long Timer500ms=millis(); //every 500ms update the knob(potentiometer) and the joystick
if (millis() - Timer500ms >= 500) {
Timer500ms=millis();
knob=myAccessory.readKnob();
joyStick=myAccessory.readJoystick();
}
if (myAccessory.joystickAvailable()) { //if the state of joystick is changed
joyStick=myAccessory.readJoystick(); //update the joystick
myBLUNO.write("ROCKER", joyStick); //send the command and value to mobile device
oledDisplay=""; //clear the oled display string to show the new state of joystick on oled
}
}
필요한 라이브러리를 모두 설치했다면, 위 소스를 블루노 보드에 업로드합니다.
소스를 업로드한 후 실행한 모습입니다. 온도, 습도, 조이스틱, 가변저항, 그리고 RGB LED의 상태를 OLED 디스플레이를 통해 출력하고 있습니다.
이제 스마트폰과 통신하기 위해, 앱스토어에서 "bluno"로 검색하여 위 앱을 설치합니다. Bluno와 Accessory shield의 모든 기능을 테스트할 수 있는 앱입니다.
왼쪽은 앱을 처음 실행하였을 때의 모습으로, 약간 불투명한 느낌으로 아직 기기와 연결되어 있지 않음을 나타내고 있습니다. 상단 오른쪽의 "Search" 버튼을 누르면 오른쪽과 같이 Bluno 보드를 찾아서 표시해 줍니다. 표시된 항목을 터치하면 바로 연결하고 메인 화면으로 복귀합니다. 그리고, Bluno 이외의 기기와는 연결이 되지 않습니다.
블루노 보드와 연결에 성공한 상태입니다. 기본적으로 LED는 off 상태이고, 온도와 습도를 표시하고 있습니다. Buzzer와 Relay를 제외한 간단한 테스트를 아래 동영상에서 확인할 수 있습니다.
위 동영상을 통해 제대로 연결되고 있음을 확인할 수 있습니다. 릴레이와 부저는 테스트를 생략했는데, 릴레이는 다음 기회에 다루도록 하겠습니다.
이상으로 Accessory Shield for Arduino(Bluno)에 대한 소개를 마치겠습니다. 필요한 소스와 스마트폰 앱을 제공하기 때문에 손쉬운 테스트도 가능하고 앱을 직접 만들어야하는 부담감도 덜 수 있을듯 합니다.