워드프레스 테마 업데이트 중 “이전 테마를 지울 수 없습니다.” 에러 나올때

워드프레스 업데이트 할때 가끔씩 테마 또는 플러그인이 업데이트가 안될 경우가 가끔씩 있다.
여러번 업데이트 해보았지만 한번 에러난 항목에 대해서는 끝까지 에러가 발생하는것 같다.
wp_theme_01

따라서 이를 해결하려면 직접적으로 소스가 있는 위치로 이동하여 해결해야 한다.

1. 해당 테마기 있는 폴더로 이동한다.
– 예: [워드프레스 설치폴더]\wp-content\themes\twentyten

2. 혹시 모르니, twentyten 폴더 이하를 c:\temp등의 폴더로 복사하여 백업한다.

3. 업그레이드를 위해 워드프레스가 다운받은 폴더[\wp-content\upgrade\twentyten.tmp\twentyten]에서 복사하여
테마설치폴더[\wp-content\themes\twentyten]로 복사하여 넣어준다.
wp_theme_02

아두이노와 푸시(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함수를 통해 받을수 있는 데이터의 길이도 작으므로 푸시서버에서
긴 데이터를 전송한다면 문제가 될것이다. (즉, 큰 데이터는 수신 못할 가능성이 많음)

유닉스 파일 시스템을 체크하여 SMS을 보내는 쉘 프로그램

아래는 간단히 유닉스 파일시스템을 읽어 Config.ini에 정해놓은 용량보다 크게되면
SMS를 전송하는 쉘스크립트이다.

#! /bin/ksh -f
MANPATH=/usr/man:/usr/share/man:/opt/SUNWspro/man

# Set up the oracle variables:
ORACLE_HOME=/rtd_orahome
ORACLE_SID=XXXX
ORACLE_TERM=vt100
ORAWEB_HOME=$ORACLE_HOME/ows/3.0
ORAWEB_SITE=web

ORA_NLS32=$ORACLE_HOME/ocommon/nls/admin/data
TNS_ADMIN=$ORACLE_HOME/network/admin
ORACLE_OWNER=AAAA
LANG=korean
NLS_LANG=American_America.KO16KSC5601

# Set up the search paths:
PATH=/opt/SUNWspro/bin:/usr/ccs/bin:/usr/bin:/usr/ucb:/etc:/usr/sbin:/usr/openwin/bin:$ORACLE_HOME/bin:$ORAWEB_HOME/bin:.
LD_LIBRARY_PATH=/opt/SUNWspro/lib:/usr/lib:/usr/ccs/lib:/usr/openwin/lib:/usr/ucblib:$ORACLE_HOME/lib
export PATH ORACLE_HOME ORACLE_SID ORACLE_TERM LANG LD_LIBRARY_PATH ORAWEB_HOME MANPATH ORA_NLS32 TNS_ADMIN ORACLE_OWNER
#=============================================================================================================

SMS_CLIENT=/rtd_home/monitor/bin/SmsSender 
CONFIG_FILE=/rtd_home/monitor/cfg/config.ini
HOST_NAME=`hostname`
#let intCnt=0 
grep -w "FILESYSTEM" $CONFIG_FILE | while read strCategory strFileSystemNm intDangerCapacity
do
	intCurCapacity=`df -k $strFileSystemNm |tail -1|awk '{print $5}' |cut -d % -f 1` 
	if (( intCurCapacity > intDangerCapacity ))
	then
 		intCurCapacity=`df -k $strFileSystemNm |tail -1|awk '{print $5}' |cut -d % -f 1`
		if (( intCurCapacity > intDangerCapacity )) 
		then
			grep -w "FILESYSTEM_NOTIFY_PHONE_NUMBER" $CONFIG_FILE | while read strCategory NOTIFY_PHONE_NUMBER
			do
				$SMS_CLIENT 'Moramcnt' $NOTIFY_PHONE_NUMBER 021234567 "$HOST_NAME Server['FILE SYSTEM $strFileSystemNm'] exceeded $intDangerCapacity%. Current : $intCurCapacity%"
				sleep 1
			done
			print `date '+%Y-%m-%d %T'` "$HOST_NAME :FILE SYSTEM $strFileSystemNm'이 $intDangerCapacity%를 넘었습니다. 현재 : $intCurCapacity%" >> /rtd_home/monitor/logs/check_filesystem_err.log
			#let intCnt=intCnt+1
		else
			print `date '+%Y-%m-%d %T'` "$HOST_NAME : File System 정상 $strFileSystemNm : $intCurCapacity%" >> /rtd_home/monitor/logs/check_filesystem.log
		fi
	else
		print `date '+%Y-%m-%d %T'` "$HOST_NAME : File System 정상 $strFileSystemNm : $intCurCapacity%" >> /rtd_home/monitor/logs/check_filesystem.log
	fi
done
exit 0

Config.ini파일의 내용은 다음과 같다.

[FILE_SYSTEM]
FILESYSTEM					/			90
FILESYSTEM					/tmp			90
FILESYSTEM					/rtd_orahome		90
FILESYSTEM					/rtd_home		92
FILESYSTEM					/rtd_data1		90
FILESYSTEM					/rtd_data2		90
FILESYSTEM					/rtd_data3		90
FILESYSTEM					/rtd_data4		90
FILESYSTEM					/rtd_data5		90
FILESYSTEM					/rtd_data6		90
FILESYSTEM					/rtd_data7		90
FILESYSTEM					/rtd_data8		90
FILESYSTEM					/rtd_data9		90
FILESYSTEM					/rtd_data10		90
FILESYSTEM					/backup			95

그리고, SMSSender프로그램은 이전글 “오라클 Alert Log에 에러 발생시 SMS로 전송하는 쉘 스크립트” 을 참고하면된다.

오라클 Alert Log에 에러 발생시 SMS로 전송하는 쉘 스크립트

아래는 장애발생시 오라클의 alert 로그에 “ORA-“와 같이 쌓이는것을 착안하여 만든 프로그램이다.

#! /bin/ksh
export ORACLE_HOME=/rtd_orahome
export ORACLE_SID=XXXXX
export ORACLE_OWNER=AAAAA
export ORAWEB_HOME=$ORACLE_HOME/ows/3.0
export ORAWEB_SITE=web
export LANG=korean
export NLS_LANG=American_America.KO16KSC5601
export ORA_NLS32=$ORACLE_HOME/ocommon/nls/admin/data
export PATH=$PATH:.:/opt/SUNWspro/bin:/usr/ccs/bin:/usr/bin:/usr/ucb:/etc:/usr/sbin:/usr/openwin/bin:$ORACLE_HOME/bin:$ORAWEB_HOME/bin:.
export LD_LIBRARY_PATH=/opt/SUNWspro/lib:/usr/lib:/usr/ccs/lib:/usr/openwin/lib:/usr/ucblib:$ORACLE_HOME/lib

SMS_CLIENT=/rtd_home/monitor/bin/SmsSender 
CONFIG_FILE=/rtd_home/monitor/cfg/config.ini
HOST_NAME=`hostname`

# 로그의 라인수 저장파일
LOG_CNT=/rtd_home/monitor/temp/alertlog_line_cnt.txt

touch $LOG_CNT
# 이전에 기록한 라인수를 읽는다
cat $LOG_CNT | read intPrevLineCnt

# 전체라인수 카운트
intTotLineCnt=$(cat /rtd_orahome/admin/RTDORA7/bdump/alert_RTDORA7.log | wc -l)

# Cat할 라인수 지정
let LoopCnt=intTotLineCnt-intPrevLineCnt 

cat /rtd_orahome/admin/RTDORA7/bdump/alert_RTDORA7.log  | tail -$LoopCnt | grep ORA- | while read ORAMSG
do
	grep -w "ORACLE_NOTIFY_PHONE_NUMBER" $CONFIG_FILE | while read TEMP NOTIFY_PHONE_NUMBER
	do
		$SMS_CLIENT 'Moramcnt' $NOTIFY_PHONE_NUMBER 021234567 "$HOST_NAME $ORAMSG"	
		sleep 1
	done
	print `date '+%Y-%m-%d %T'` "$HOST_NAME $ORAMSG" >> /rtd_home/monitor/logs/check_alertlog_err.log

done
rm -f $LOG_CNT
print $intTotLineCnt >> $LOG_CNT
exit 0

위의 쉘 프로그램은 Config.ini와 SMSSender라는 프로그램이 필요하다.
Config.ini의 파일의 내용은 다음과 같이 sms를 수신받을 대상이 기록되어 있다.

[ORACLE]
ORACLE_NOTIFY_PHONE_NUMBER		0101234567

또한 SMSSender는 오라클 Pro*C로 간단한게 구현되어 있다.


#include 
#include 
#include 
#include 


#define	TRUE		1
#define	FALSE		0
#define	CONSOLE_MODE	0

int Connection( char *, char *, char *);
int Commit( void);
int RollBack( void);
int Trim(char *);
int SendSMS( char *, char *, char *, char *);

int Connection( char *szUserId, char *szPasswd, char *szConnection)
{
EXEC SQL BEGIN DECLARE SECTION;
    VARCHAR vcConnection[21];
    VARCHAR vcUserId[21];
	VARCHAR vcPasswd[21];
EXEC SQL END DECLARE SECTION;

	strcpy( (char *)vcUserId.arr, szUserId);
	vcUserId.len	= strlen( szUserId);

	strcpy( (char *)vcPasswd.arr, szPasswd);
	vcPasswd.len	= strlen( szPasswd);

	/* If Connection String Is Not Empty */ 
	if (szConnection[ 0] != NULL)
	{
		strcpy( (char *)vcConnection.arr, szConnection);
		vcConnection.len	= strlen( szConnection);
	}
	else
	{
		vcConnection.arr[0] = '\0';
		vcConnection.len	= 0;
	}

	
	/* Connection */
	EXEC SQL CONNECT :vcUserId IDENTIFIED BY :vcPasswd USING :vcConnection;
	if( sqlca.sqlcode != 0)
	{
#ifdef CONSOLE_MODE
        printf("Oracle Connect Fail : %s\n", sqlca.sqlerrm.sqlerrmc);
#endif
		return FALSE;
	}

#ifdef CONSOLE_MODE
    printf("Oracle Connected.\n");
#endif
	return TRUE;
}


int Commit( void)
{

EXEC SQL COMMIT WORK RELEASE;

  	if (sqlca.sqlcode != 0)
	{
		/* ORA-1034 : ORACLE not available */
		if (sqlca.sqlcode == 1034) return FALSE;
#ifdef XCONSOLE_MODE
		printf("Oracle Commit Fail : %s\n", sqlca.sqlerrm.sqlerrmc);
#endif
		return FALSE;
    }
#ifdef CONSOLE_MODE
	printf("Oracle Commit Work Relese, Oracle DisConnected.\n");
#endif
    return TRUE;
}


int RollBack( void)
{
	EXEC SQL ROLLBACK WORK;
	if (sqlca.sqlcode != 0) 
	{
		/* ORA-1034 : ORACLE not available */
		if (sqlca.sqlcode==1034) return FALSE;
#ifdef CONSOLE_MODE
		printf("Oracle Rollback Fail : %s\n", sqlca.sqlerrm.sqlerrmc);
#endif
		return FALSE;
	}
	return TRUE;
}

int Trim(char *szText)
{
    int iCnt, iLength = strlen(szText);

    for (iCnt = iLength-1; iCnt >= 0; iCnt--)
	{
        if (szText[iCnt]==' ' || szText[iCnt]=='\n' || szText[iCnt]=='\r')
		{
            szText[iCnt] = '\0';
            iLength--;
        }
		else
			break;
    }
    return iLength;
}


/*==================================================================================
 * SMS 전송
 ===================================================================================*/
int SendSMS( char *szTranId, char *szTransPhone, char *szCallBackNo, char* szMessage)
{

EXEC SQL BEGIN	DECLARE	SECTION;
	VARCHAR		vcTranId[21];
	VARCHAR 	vcTransPhone[16];
	VARCHAR		vcTranCallBack[16];
	VARCHAR		vcMessage[256];
EXEC SQL END	DECLARE	SECTION;

	memset( &vcTranId,		0, sizeof(vcTransPhone));
	memset( &vcTransPhone,	0, sizeof(vcTransPhone));
	memset( &vcTranCallBack, 0, sizeof(vcTranCallBack));
	memset( &vcMessage,		0, sizeof(vcMessage));


	strncpy(vcTranId.arr, szTranId, 20);
	vcTranId.len	= Trim( (char *)vcTranId.arr);
	vcTranId.arr[ vcTranId.len] = '\0';


	strncpy(vcTransPhone.arr, szTransPhone, 15);
	vcTransPhone.len	= Trim( (char *)vcTransPhone.arr);
	vcTransPhone.arr[ vcTransPhone.len] = '\0';

	strncpy(vcTranCallBack.arr, szCallBackNo, 15);
	vcTranCallBack.len	= Trim( (char *)vcTranCallBack.arr);
	vcTranCallBack.arr[ vcTranCallBack.len] = '\0';

	strncpy(vcMessage.arr, szMessage, 255);
	vcMessage.len	= Trim( (char *)vcMessage.arr);
	vcMessage.arr[ vcMessage.len] = '\0';

#ifdef CONSOLE_MODE
	printf("SMS szTranId...%s|\n", vcTranId.arr);
	printf("SMS szTransPhone...%s\n", vcTransPhone.arr);
	printf("SMS szCallBackNo...%s\n", vcTranCallBack.arr);
	printf("SMS szMessage...%s\n", vcMessage.arr);
#endif	

EXEC SQL INSERT INTO
		em_tran(tran_pr, tran_id, tran_phone, tran_callback, tran_status, tran_date, tran_msg, tran_type)
		VALUES(EM_TRAN_PR.NEXTVAL, :vcTranId, :vcTransPhone, :vcTranCallBack, '1', SYSDATE, :vcMessage, '1');

	if (sqlca.sqlcode == 0)
	{
		if (!Commit())
		{	
			RollBack();
			return FALSE;
		}
#ifdef CONSOLE_MODE
    printf("SMS Sent...\n");
#endif	

		return TRUE;
	}
	else
		return FALSE;
}



int main(int argc, char* argv[])
{
	if( !Connection("오라클계정", "오라클패스워드", "오라클SID")) return -1;
	SendSMS( argv[ 1], argv[ 2], argv[ 3], argv[ 4]);
}





오라클 아카이브 로그 백업 및 이동 쉘 스크립트

오라클 아카이브로그 백업 및 이동
– find 명령에 -mtime은 일당인데 -mmin 같은 옵션이 없어 touch로 파일생성후
그 파일의 생성일과 비교하여 1시간 전 데이터를 검색 할수 있다.

#! /bin/ksh

ORACLE_ARCHIVE_SRC_DIR="/rtd_data10/ARCH"
ORACLE_ARCHIVE_DST_DIR="/backup/rtd/rtd_data10/ARCH"
ORACLE_ARCHIVE_PREFIX_NAME="archive"

#------------------------------------------------------
# 오래된 압출파일 삭제 주기(일단위)
#------------------------------------------------------
DEL_GZIP_FILE_INTERVAL="60"

#------------------------------------------------------
# KST-9는 시간 -8은 1시간전
#------------------------------------------------------
FIND_TIME=`TZ=KST-8; date +%Y%m%d%H%M`

TEMP_DIR=$ORACLE_ARCHIVE_SRC_DIR/$FIND_TIME

#------------------------------------------------------
# 임시폴더 생성
#------------------------------------------------------
mkdir -p $TEMP_DIR

#------------------------------------------------------
# 임시폴더에 생성일이 1시간전인 파일 생성
#------------------------------------------------------
touch -t $FIND_TIME  $TEMP_DIR/$FIND_TIME

#------------------------------------------------------
# 템프폴더로 이동
#------------------------------------------------------
find $ORACLE_ARCHIVE_SRC_DIR -name "$ORACLE_ARCHIVE_PREFIX_NAME*" ! -newer $TEMP_DIR/$FIND_TIME -exec mv {} $TEMP_DIR \;

#------------------------------------------------------
# 실제 로그저장소로 압축
#------------------------------------------------------
tar cf - $TEMP_DIR | gzip > $ORACLE_ARCHIVE_DST_DIR/$FIND_TIME.tar.gz

#------------------------------------------------------
# 템프폴더 삭제
#------------------------------------------------------
find $TEMP_DIR -exec rm -rf {} \;

#------------------------------------------------------
# 기존 압출파일 삭제, 현재 30일전 압축파일을 모두 삭제한다
#------------------------------------------------------
find $ORACLE_ARCHIVE_DST_DIR -name "*.tar.gz" -mtime +$DEL_GZIP_FILE_INTERVAL -exec rm -f {} \;
exit

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

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

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

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

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

CORS (Cross-origin resource sharing) 서비스가 다른 크로스도메인 해결방법

Ajax에서 특정 서비스 호출 시 도메인이 서로 다를경우, 정상적인 서비스를 호출하기 위해서는 Spring MVC의 필터링을 이용하여 처리할 수 있다.

1. OncePerRequestFilter 를 상속 필터 클레스 구현

package 패키지명;

import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;

public class CorsFilter extends OncePerRequestFilter {

	@Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        response.addHeader("Access-Control-Allow-Origin", "*");
        if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())); {
            // CORS "pre-flight" request
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
            response.addHeader("Access-Control-Allow-Headers", "Authorization");
            response.addHeader("Access-Control-Max-Age", "1728000");
        }
        filterChain.doFilter(request, response);
    }
}

2. web.xml에 필터로 설정

  
      corsFilter
      패키지.CorsFilter 
  
  
      corsFilter
      /data/* 
  

이클립스 아두이노에서 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);