아두이노와 푸시(MQTT)

1. 아두이노에서 푸시를 사용하기 위해서 MQTT 프로토콜을 구현한 클라이언트를 다운받는다.
– https://github.com/knolleary/pubsubclient

2. pubsubclient 라이브러리를 Import받고 아래와 같이 구현하면 된다.

#include "TemptClient.h"
#include 
#include 



void messageArrived(char* topic, byte* payload, unsigned int uIntLength);

PubSubClient gClsMqttClient(gpChrServer, 1883, messageArrived, gClsWfClient);

void messageArrived(char* topic, byte* payload, unsigned int uIntLength)
{
	int intIndex = 0;
	char pChrBuffer[uIntLength + 1];
	for (intIndex = 0; intIndex < uIntLength; intIndex++)
	{
	    pChrBuffer[intIndex] = payload[intIndex];
	}
	pChrBuffer[intIndex] = '\0';

	String strPayload = String(pChrBuffer);
	Serial.print("uIntLength:");
	Serial.println(uIntLength);

	Serial.print("strPayload:");
	Serial.println(strPayload);
}

void getMacAddress(char * pChrMacAddress)
{
	byte bytMacAddr[6];
	WiFi.macAddress(bytMacAddr);
	snprintf(pChrMacAddress, MAC_ADDRESS_LENGTH+1, "%02X%02X%02X%02X%02X%02X", bytMacAddr[0], bytMacAddr[1], bytMacAddr[2], bytMacAddr[3], bytMacAddr[4], bytMacAddr[5]);
}


void setup()
{
	char pChrClientId[MAC_ADDRESS_LENGTH + 1];
	char pChrTopic[TOPIC_LENGTH + 1];
	Serial.begin(9600);

	if (WiFi.status() == WL_NO_SHIELD)
	{
		Serial.println("WiFi shield not present");
		while (true);
	}

	String strFwVersion = WiFi.firmwareVersion();
	Serial.print("FirmWare:");
	Serial.println(strFwVersion);
	if (strFwVersion != "1.1.0" ) Serial.println("Please upgrade the firmware");

    // 와이파이 네트워크 연결 시도
	while (gIntWiFiStatus != WL_CONNECTED)
    {
        Serial.print("Attempting to connect to SSID: ");
        Serial.println(gpChrSsid);
        gIntWiFiStatus = WiFi.begin(gpChrSsid, gpChrPasswd);
        delay(1000);
    }

	getMacAddress(pChrClientId);

	if (gClsMqttClient.connect(pChrClientId))
	{
		sprintf(pChrTopic, "arduino/%s", pChrClientId);
                // 메시지를 수신받을수 있도록 토픽을 구독한다.
		gClsMqttClient.subscribe(pChrTopic);

                // 메시지 퍼블리시(송신)
		gClsMqttClient.publish("arduino/99B8020EC478", "{'test1':200,'test2':'{babo:xxxxxx,yahoo:bbbbb}'}");
	}
}

3. 개발시 유의사항
퍼블리쉬할수 있는 데이터의 크기가 작기 때문에 실제 사용할때는 JSON또는 XML형태로 전송하는것은 이롭지 않은것 같다.
또한 위 소스상에 있는 messageArrived와 같은 CallBack함수를 통해 받을수 있는 데이터의 길이도 작으므로 푸시서버에서
긴 데이터를 전송한다면 문제가 될것이다. (즉, 큰 데이터는 수신 못할 가능성이 많음)

아두이노 WiFiClient의 write 함수의 제약

tcp 소켓의 send 함수와 같은 함수인 write(데이터, 데이터 길이) 함수를 이용하여
통신서버로 데이터를 전송하려고 할때

size_t write(const char *buffer, size_t size);

아두이노에서는 데이터 길이가 90 bytes 를 초과하게 되면 에러가 발생하게 된다.
따라서 전송할 용량이 크다면, 버퍼를 여러건으로 나누어 전송할 필요가 있다.

wfClent.write(pCharBuffer1, 90);
wfClent.write(pCharBuffer2, 70);
....

이클립스 아두이노에서 WiFi 라이브러리 추가시 오류 발생시 처리

이클립스에서 WiFi 라이브러리를 Import 받았을때 아래와 같이 파일을 찾을수 없다고
나온다면 다음과 같이 처리하면 된다.

arduino_wifi01

09:39:27 **** Incremental Build of configuration Release for project TemptClient ****
make all 
'Building file: C:/Applications/arduino-1.0.6/libraries/WiFi/utility/server_drv.cpp'
'Invoking: AVR C++ Compiler'
avr-g++ -I"C:\Applications\arduino-1.0.6\hardware\arduino\cores\arduino" -I"C:\Applications\arduino-1.0.6\hardware\arduino\variants\standard" -I"C:\Projects\89.IOTSolutions\02.Solutions\TemptClient" -I"C:\Applications\arduino-1.0.6\libraries\WiFi" -D__IN_ECLIPSE__=1 -DUSB_VID= -DUSB_PID= -DARDUINO=106 -Wall -Os -ffunction-sections -fdata-sections -fno-exceptions -g -mmcu=atmega328p -DF_CPU=16000000UL -MMD -MP -MF"WiFi/utility/server_drv.d" -MT"WiFi/utility/server_drv.d"  -c -o "WiFi/utility/server_drv.o" -x c++ "C:/Applications/arduino-1.0.6/libraries/WiFi/utility/server_drv.cpp"
'Finished building: C:/Applications/arduino-1.0.6/libraries/WiFi/utility/server_drv.cpp'
' '
'Building file: C:/Applications/arduino-1.0.6/libraries/WiFi/utility/socket.c'
'Invoking: AVR Compiler'
avr-gcc -I"C:\Applications\arduino-1.0.6\hardware\arduino\cores\arduino" -I"C:\Applications\arduino-1.0.6\hardware\arduino\variants\standard" -I"C:\Projects\89.IOTSolutions\02.Solutions\TemptClient" -I"C:\Applications\arduino-1.0.6\libraries\WiFi" -D__IN_ECLIPSE__=1 -DARDUINO=106 -DUSB_PID= -DUSB_VID= -Wall -Os -g -mmcu=atmega328p -DF_CPU=16000000UL -MMD -MP -MF"WiFi/utility/socket.d" -MT"WiFi/utility/socket.d"  -c -o "WiFi/utility/socket.o" "C:/Applications/arduino-1.0.6/libraries/WiFi/utility/socket.c"
'Finished building: C:/Applications/arduino-1.0.6/libraries/WiFi/utility/socket.c'
' '
'Building file: C:/Applications/arduino-1.0.6/libraries/WiFi/utility/spi_drv.cpp'
'Invoking: AVR C++ Compiler'
avr-g++ -I"C:\Applications\arduino-1.0.6\hardware\arduino\cores\arduino" -I"C:\Applications\arduino-1.0.6\hardware\arduino\variants\standard" -I"C:\Projects\89.IOTSolutions\02.Solutions\TemptClient" -I"C:\Applications\arduino-1.0.6\libraries\WiFi" -D__IN_ECLIPSE__=1 -DUSB_VID= -DUSB_PID= -DARDUINO=106 -Wall -Os -ffunction-sections -fdata-sections -fno-exceptions -g -mmcu=atmega328p -DF_CPU=16000000UL -MMD -MP -MF"WiFi/utility/spi_drv.d" -MT"WiFi/utility/spi_drv.d"  -c -o "WiFi/utility/spi_drv.o" -x c++ "C:/Applications/arduino-1.0.6/libraries/WiFi/utility/spi_drv.cpp"
'Finished building: C:/Applications/arduino-1.0.6/libraries/WiFi/utility/spi_drv.cpp'
' '
'Building file: C:/Applications/arduino-1.0.6/libraries/WiFi/utility/wifi_drv.cpp'
'Invoking: AVR C++ Compiler'
avr-g++ -I"C:\Applications\arduino-1.0.6\hardware\arduino\cores\arduino" -I"C:\Applications\arduino-1.0.6\hardware\arduino\variants\standard" -I"C:\Projects\89.IOTSolutions\02.Solutions\TemptClient" -I"C:\Applications\arduino-1.0.6\libraries\WiFi" -D__IN_ECLIPSE__=1 -DUSB_VID= -DUSB_PID= -DARDUINO=106 -Wall -Os -ffunction-sections -fdata-sections -fno-exceptions -g -mmcu=atmega328p -DF_CPU=16000000UL -MMD -MP -MF"WiFi/utility/wifi_drv.d" -MT"WiFi/utility/wifi_drv.d"  -c -o "WiFi/utility/wifi_drv.o" -x c++ "C:/Applications/arduino-1.0.6/libraries/WiFi/utility/wifi_drv.cpp"
'Finished building: C:/Applications/arduino-1.0.6/libraries/WiFi/utility/wifi_drv.cpp'
' '
'Building file: C:/Applications/arduino-1.0.6/libraries/WiFi/WiFi.cpp'
'Invoking: AVR C++ Compiler'
avr-g++ -I"C:\Applications\arduino-1.0.6\hardware\arduino\cores\arduino" -I"C:\Applications\arduino-1.0.6\hardware\arduino\variants\standard" -I"C:\Projects\89.IOTSolutions\02.Solutions\TemptClient" -I"C:\Applications\arduino-1.0.6\libraries\WiFi" -D__IN_ECLIPSE__=1 -DUSB_VID= -DUSB_PID= -DARDUINO=106 -Wall -Os -ffunction-sections -fdata-sections -fno-exceptions -g -mmcu=atmega328p -DF_CPU=16000000UL -MMD -MP -MF"WiFi/WiFi.d" -MT"WiFi/WiFi.d"  -c -o "WiFi/WiFi.o" -x c++ "C:/Applications/arduino-1.0.6/libraries/WiFi/WiFi.cpp"
C:/Applications/arduino-1.0.6/libraries/WiFi/WiFi.cpp:20:22: error: wifi_drv.h: No such file or directory
C:/Applications/arduino-1.0.6/libraries/WiFi/WiFi.cpp:26:21: error: debug.h: No such file or directory
C:/Applications/arduino-1.0.6/libraries/WiFi/WiFi.cpp: In static member function 'static void WiFiClass::init()':
C:/Applications/arduino-1.0.6/libraries/WiFi/WiFi.cpp:41: error: 'WiFiDrv' has not been declared
C:/Applications/arduino-1.0.6/libraries/WiFi/WiFi.cpp: In static member function 'static uint8_t WiFiClass::getSocket()':
C:/Applications/arduino-1.0.6/libraries/WiFi/WiFi.cpp:53: error: 'NO_SOCKET_AVAIL' was not declared in this scope
C:/Applications/arduino-1.0.6/libraries/WiFi/WiFi.cpp: In static member function 'static char* WiFiClass::firmwareVersion()':
C:/Applications/arduino-1.0.6/libraries/WiFi/WiFi.cpp:58: error: 'WiFiDrv' has not been declared
C:/Applications/arduino-1.0.6/libraries/WiFi/WiFi.cpp: In member function 'int WiFiClass::begin(char*)':
C:/Applications/arduino-1.0.6/libraries/WiFi/WiFi.cpp:66: error: 'WiFiDrv' has not been declared
C:/Applications/arduino-1.0.6/libraries/WiFi/WiFi.cpp:70: error: 'WL_DELAY_START_CONNECTION' was not declared in this scope
C:/Applications/arduino-1.0.6/libraries/WiFi/WiFi.cpp:71: error: 'WiFiDrv' has not been declared

프로젝트를 선택하고 “Properties > C/C++ General > Paths and Symbols” 를 선택한후 “GNU C++” 을 선택한다.
arduino_wifi02

Add 버튼을 눌러 아래와 같이 “/프로젝트명/WIFI/utility”를 넣고, “Is a workspace path”를 체크한 후 “OK”를 누르면 된다.
arduino_wifi03

아두이노 float을 문자열로 변환

아두이노에서 아래처럼 sprintf을 이용하여 문자열로 변경하려고 할때
결과를 보면 ? 가 출력된다.

sprintf(pChrBuffer, "%f", fltValue);

아두이노에서는 float형에 대해서 sprintf가 제대로 지원되지 않는듯하여,
확인하여 보니 아래 함수를 이용하면 변환할수 있다.

char * dtostrf(ouble __val, signed char __width, unsigned char __prec, char * __s);
float fltValue = 123.456;
char pChrBuffer[50];
 
dtostrf(fltValue , 5, 2, pChrBuffer);  // 5 : width, 2 : precision

다른 방법으로는 String을 이용하여 아래와 같이 할수도 있다.

String strValue = String(fltValue);

아두이노 와이파이 쉴드 펌웨어 업그레이드

1. 아두이노와 분리
2. 점퍼 스위치 변경

arduino_wifi_shield_upgrade0
위와 같이 하나만 꽂아 있는 딥스위치를 빼서 두군데 다 접지되도록 한다.

arduino_wifi_shield_upgrade1

3. ATMEL 펌웨어 수정프로그램 다운로드
– http://www.atmel.com/tools/FLIP.aspx 에서 하단에 있는
FLIP 3.4.7 for Windows (Java Runtime Environement included) 버전을 받아 설치
4. USB 연결
– wifi 쉴드의 USB를 PC와 연결하여 전원을 넣는다.
5. 제어판의 장치관리자를 열어 “기타 장치” > “AT32UC3A DFU”를 오른쪽 마우스로 클릭하여 “드라이브 소프트웨어 업데이트” 선택하여 업데이트
업데이트 파일의 위치는 “C:\Program Files (x86)\Atmel\Flip 3.4.7\usb” 로 지정
arduino_wifi_shield_upgrade3

6. CMD창을 열어 cd C:\Program Files (x86)\Atmel\Flip 3.4.7\bin 을 이동
7. 펨웨어 업그레이드1

batchisp.exe -device AT32UC3A1256 -hardware usb -operation erase f memory flash blankcheck loadbuffer "C:/Program Files (x86)/Arduino/hardware/arduino/firmwares/wifishield/binary/wifi_dnld.elf" program verify start reset 0

arduino_wifi_shield_upgrade4

8. 와이파이 쉴드에 있는 reset 버튼 클릭
9. 펨웨어 업그레이드2

batchisp.exe -device AT32UC3A1256 -hardware usb -operation erase f memory flash blankcheck loadbuffer "C:/Program Files (x86)/Arduino/hardware/arduino/firmwares/wifishield/binary/wifiHD.elf" program verify start reset 0

arduino_wifi_shield_upgrade5
10. 점퍼 스위치를 원래대로 변경
11. 아두이노와 다시 결합

아두이노(arduino) 개발환경에서 탭 크기 변경

아두이노 개발환경(IDE)의 기본 탭 크기가 2이여서 익숙하지 않다.
기본 IDE의 환경설정에서 설정할줄 알았으나 없어, 찾아본 결과
C:\Users\사용자계정\AppData\Roaming\Arduino 밑에 있는 preferences.txt 파일에
탭설정할수 있는 항목이 있었다.
여기에서 아래와 같이 탭 크기를 변경하고 아두이노 개발환경을 다시 띄우면 된다.

editor.tabs.size=4

In hohem Grad schätzen wir Ihr Vertrauen oder meistens empfiehlt es sich, potenzmittel wie Kamagra soft tabs dürfen nicht mit medikamenten, im Vergleich zu Vardenafil & Tadalafil schneidet Lovegra besonders beim Wirkungseintritt. In diesem Fall würde man seine Gesundheit riskieren und es bedeutet nicht, dass Sie Cialis 100mg Tabletten einnehmen müssen, die einen besonderen Wert auf sexuelle Spontaneität legen. Oft wirken die Tabletten erst gar nicht und aus Angst gehen deswegen nur noch die wenigsten Männer zu einem Arzt oder einige Themen sind unsere ganz besonderen Schwerpunkte.