ESP8266 개요

하드웨어/ESP8266 2016. 10. 13. 13:00

1.1 ESP8266 개요 c{mpy0101}


ESP8266은 Espressif Systems 라는 상하이 소재 중국 회사에서 2014년도에 출시한 마이크로 컨트롤러이다.


[그림] ESP8266


ESP8266은 다음과 같은 물리적인 스펙을 가지고 있다.


  • Voltage : 3.3V

  • Current consumption : 10uA – 170mA

  • Flash memory attachable : 16MB max (512K normal)

  • Processor : Tensilica L106 32 bit

  • Processor speed : 80-160MHz

  • RAM : 32K + 80K

  • GPIOs : 17 (multiplexed with other functions)

  • ADC(Analog to Digital) : 1 input with 1024 step resolution

  • 802.11 support : b/g/n/d/e/i/k/r

  • Maximum concurrent TCP connections : 5


스펙을 보면 알겠지만 이 칩만으로도 독립된 프로세서 보드를 구성할 수 있는 충분한 기능이 내장되어 있다. Wi-Fi 기능을 내장하고 있으면서도 저렴한 가격 때문에 무선인터넷 기반의 제품을 만드는 경우 무선모듈로 널리 사용되고 있으며 아두이노(arduino)와 같은 보드와 시리얼통신으로 연결하여 무선인터넷 기능을 구현할 수 있다.


[그림] ESP-01모듈(좌)과 ESP-12모듈(우)


특히 주목할만한 것은 Lua(eLua) 나 python(MicroPython) 혹은 javascript 같은 스크립트 언어로 제어할 수 있게끔 해주는 펌웨어도 존재한다는 점이다. 이는 c++ 기반으로 개발하는 것 보터 훨씬 더 편리한 환경에서 개발을 진행할 수 있다는 것을 의미하며  ESP-12 모듈 기반의 NodeMCU, WeMos 등등 다양하고 저렴한 응용 보드가 제작되어 널리 사용되고 있다.


NodeMCU보드

WeMos d1 mini 보드


이러한 보드에 eLua나 MicroPython 과 같은 펌웨어를 올려서 Lua 혹은 python으로 보드와 주변 기기들을 제어할 수 있다.


Posted by 살레시오
,

 만약 어떤 조건이 참일때와 거짓일 때를 구분해서 실행시키려면 if ~ then ~ else ~ end 구문을 사용한다.


if 조건식 then
   코드블럭1
else
   코드블럭2
end


조건식이 참이라면 then~else 사이의 코드블럭1이, 거짓이라면 else~end 사이의 코드블럭2가 수행된다. end는 맨 마지막에만 붙는다는 것에 유의해야 한다. 즉, if 와 짝을 이루는 end 하나만 마지막에 와야 한다. 예를 들면 다음과 같다.


a = 11
if a%2 == 0 then
   print('even number')
else
   print('odd number')
end

실행 결과

odd number


if ~ then 사이의 조건이 거짓이이므로 else~end 사이의 코드가 수행된다.


 여러 조건을 검사해야 할 때는 elseif 를 사용한다.


if 조건식1 then
   코드블럭1
elseif 조건식2 then
   코드블럭2
elseif 조건식3 then
   코드블럭3
...
else
   코드블럭n
end


elseif가 공백이 없는 한 단어이다. 이렇게 하면 여러가지 조건에 따라서 서로 다른 코드블럭을 수행할 수 있다. 예를 들면 다음과 같다. 여기에서도 end는 맨 마지막에 하나만 와야 한다. 마지막 코드블럭n은 모든 조건식들이 다 거짓일 경우 수행된다.


if a < 0 then
   print('negative')
elseif a==0 then
   print('zero')
else
   print('positive')
end


이 예에서 만약 a가 음수이면 ‘negative’가, 0이라면 ‘zero’가, 양수라면’positive’가 출력될 것이다.

 

 루아에서는 C계열 언어의 switch~case 구문이 없다. 하지만 elseif 구문을 사용하면 동일한 기능을 하는 코드를 작성할 수 있다.



Posted by 살레시오
,

 루아에서 조건문들 상의 논리 관계를 규정할 때 and, or, not 연산자를 사용한다. 예를 들어 변수 x가 -1과 1 사이의 값인지를 검사하려면


if -1 < x and x<1 then … end


와 같이 -1<x 와 x<1 을 and로 연결하면 된다. and 연산자는 조건식 두 개를 받아서 둘 다 true인 경우에만 true가 된다. or연산자는 둘 다 false 인 경우에만 false 가 된다.


x

y

x and y

x or y

true

true

true

true

true

fasle

false

true

fasle

true

false

true

fasle

fasle

false

false


만약 ‘변수 a가 -2보다 작거나 1보다 크다’는 조건을 검사하려면 다음과 같이 하면 될 것이다.


if a<-2 or a>1 then … end


 연산자 not 은 피연산자가 하나인 단항 연산자로서 not x 의 경우 x가 true이면 false가 되고 x가 false이면 true가 된다.


a = nil
b = 0
c = not a
d = not b


위의 예어서 c에 저장되는 값은 true이다. 왜냐면 nil은 false 로 간주되므로 false의 역은 true이기 때문이다. 루아에서는 오직 nil과 false 만 거짓으로 간주된다는 사실에 유의해야 한다. 숫자 0은 true이므로 d에는 false가 대입된다.


local b = 10
if not a then b=b+1 end


위 예에서 a 는 선언되지 않았으므로 nil이다. 따라서 then~end 블럭이 수행된다. not a 가 true이기 때문이다. 이 프로그램이 수행되면 b에는 11이 저장될 것이다.



Posted by 살레시오
,

 루아에서 어떤 조건에 따라서 수행될 명령어 집합을 지정해 줄 때 if 명령어를 사용한다. 기본적인 문법은 다음과 같다.


if 조건식 then
  명령문1
  명령문2
  ...
end


if와 then 사이에는 조건식이 오는데 이 조건식이 true 일 경우 then 과 end 사이의 명령어들을 수행하고 false일 경우는 수행하지 않는다.(조건식을 괄호로 묶어줄 필요는 없다.) 루아는 프로그램 블럭(bloc)을 지정할 때 다른 언어에서 흔히 쓰이는 {...} 를  사용하지 않는다. 대신 이 기호는 뒤어 설명할 테이블을 생성할 때 사용된다. 루아에서의 코딩 블럭은 then~end, do ~ end, 와 같이 then, do, else 등 특정한 키워드로 시작하고  end로 마감된다.

 변수에 대입된 숫자가 짝수일 경우 ‘even number’라고 출력하는 프로그램을 작성해 보면 다음과 같다. 2로 나눈 나머지가 0이라면 짝수, 1이면 홀수라는 사실을 이용한다.


a = 12
if a%2 == 0 then
   print('even number')
end

실행 결과

even number


if~then사이에는 조건식 뿐만 아니라 변수와 같은도 올 수 있으며 이 경우에도 그 표현식이 true일 경우 then ~ end 블럭이 수행된다. 루아에서 false 로 간주되는 것은 false와 nil 뿐이다. 따라서 0이나 ‘’ (빈 문자열)은 true 로 간주된다.


count = 0
if count then
   print('count = '..count)
end

실행 결과

count = 0


위 예에서 count는 0값을 가지므로 true이다. 따라서 then~end 블럭이 수행된다. 그리고 일전에 선언되지 않은 변수는 nil값을 가진다고 설명한 바 있다.


if num then
   print('num is not false nor nil.')
end

실행결과



따라서 위 예에서 num은 선언되지 않았으므로 nil이고 nil은 false로 간주되므로 아무것도 실행되지 않는다.



Posted by 살레시오
,

 루아에는 ‘nil’이라는 자료형이 있는데 여기서 nil은 현재 선언되지 않았거나 선언은 되었는데 아무 값도 들어가 있지 않은 변수의 값을 나타낸다. 즉 ‘선언되지 않은 변수의 값’, 또는 ‘아무 것도 아닌 값’이라는 의미를 갖는 자료형이다. 예를 들어 선언되지 않은 변수 a의 값을 출력하려고 하면 nil 이 찍힌다.


print(a)
local b -- 변수 b를 지역 변수로 사용하겠다고 선언
print(b)

실행 결과

nil
nil


이 예에서 a변수는 선언되지 않은 변수이므로 print(a)라고 하면 nil이 출력된다. 변수 b는 지역 변수로 사용하겠다는 선언이 되어 있지만 아직 값이 저장되지 않은 상태이므로 print(b) 명령어도 마찬가지로 nil이 출력된다.


 nil 자체가 자료형이자 값이기 때문에 변수에 대입도 가능하다.


x = nil
y = ‘hi’
...
y = nil


위의 예에서 변수 x는 nil값으로 초기화 시켰고 변수 y는 처음에는 문자열을 대입했다가 나중에 nil을 대입했다. 어떤 변수에 nil 을 대입하면 더 이상 그 변수를 사용하지 않겠다고 선언하는 것으로 일정 시간이 지난 후에 내부 메모리에서 사용된 값은 삭제가 된다.  즉, 사용하고 있던 변수를 더이상 사용하지 않겠다고 지정하고 싶을 때도 nil 값을 대입한다. 이것을 garbage collecting 이라고 하며 자동으로 수행되며 루아는 특별한 경우를 제외하고는 프로그래머가 메모리를 관리할 필요가 없다.



Posted by 살레시오
,

 루아에서 문자열은 큰따옴표 “~” 혹은 작은 따옴표 ‘~’ 로 둘러싸인 문자들의 집합이다. 단문자 자료형은 없으며 작은 따옴표도 큰 따옴표와 동일하게 문자열을 입력하는데 사용된다.


print("Hello world")
print('hi Lua')

실행 결과

Hello world
hi Lua


큰 따옴표를 사용한 문자열 내부에서 작은 따옴표는 문자로 취급되고 반대의 경우도 마찬가지이다.


a = "I'am a programmer."
b = 'He said "Hi."'
print(a)
print(b)

실행 결과

I'am a programmer.
He said "Hi."


문자열 내에서 다음과 같은 특수 문자를 사용할 수 있다.


표 1.5.1 문자열 내의 특수문자

특수문자

표시 문자

\n

줄바꿈

\t

\r

줄 맨앞으로

\b

한 문자 뒤로

\\

‘\’문자 자체를 표시


예를 들면 다음과 같다.


print('Table\n-----------------------')
print('1\t2\t3')
print('one\ttwo\tthree')
print('하나\t둘\t셋')
print('-----------------------')

실행 결과

Table
-----------------------
1 2 3
one two three
하나
-----------------------


 문자열과 함께 많이 쓰이는 기본 연산자로서 ‘..’ 가 있는데 두 문자열을 병합하는 기능을 수행한다.


a = 'hello '
b = 'world'
c = a .. b
d = 22
print(c)
print('d='..d)

실행 결과

hello world
d=22


 위 예제와 같이 ‘..’ 연산자는 print()함수 내에서 여러 문자열을 합쳐서 표시하는데 많이 사용된다.



'프로그래밍언어.Lib > 루아(Lua)' 카테고리의 다른 글

루아(Lua)의 조건분기문 if ~ then ~ end  (0) 2016.01.27
루아(Lua)의 nil  (0) 2016.01.26
루아(Lua)의 부울형과 조건연산자  (3) 2016.01.26
루아의 산술 연산자  (0) 2016.01.25
루아(Lua)의 숫자형  (0) 2016.01.25
Posted by 살레시오
,

 루아에서는 부울형(bool type) 데이터로 true/false 가 있으며 각각 참과 거짓을 표현한다.

 

a = true -- 변수 a에 ‘참’을 대입
x = false -- 변수 b에 ‘거짓’을 대입

 

true/false 는 보통 조건식의 결과이다. 조건식에 쓰이는 연산자(조건 연산자)는 다음과 같은  것들이 있다.

 

조건연산자 의미
x == y
x ~= y
x와 y가 같으면 true 반환
x와 y가 다르면 true 반환 (주의)
x > y
x >= y
x보다  y가 크면 true 반환
x보다  y가 크거나 같으면 true 반환
x < y
x <= y
x보다  y가 작으면 true 반환
x보다  y가 작거나 같으면 true 반환

 

같다 다르다는 ‘==’과 ‘~=’ 이다. ‘다르다’의 경우 다른 언어에서 많이 쓰이는 ‘!=’과는 문법이 다르니 유의해야 한다.

 

print (1==1)
a  = 2 ~= 2
b = 3
c = b == 3 -- 변수 c에는 부울값이 저장된다.
print(a, c)
d = 4
print(b<d)
실행 결과
true
false true
true

 

정수형의 상등/대소 조건 판별은 아무런 오류가 발생하지 않으나 실수의 경우는 그렇지 않다.(루아도 C/C++ 에서의 실수 비교와 같은 문제를 가지고 있다.)

 

print (0.3 == 0.1*3)
a = 0.2 + 0.2 + 0.2
b = 0.6
print (a, b, a==b)
실행 결과
false
0.6 0.6 false

 

이 예에서 보면 0.1*3 과 0.3은 다르다고  판별되고 0.2를 세 번 더한 것과 0.6이 다르다고 출력된다. 이진수에 대한 지식이 있다면 0.1이나 0.2는 정확하게 이진수로 표현될 수 없으므로 내부적으로 (약간) 부정확한 수가 저장되며 이러한 값들의 연산과 비교 역시 부정확하게 된다는 사실을 알 수 있다. 이 사실은 >=, <= 비교 연산에 대해서도 동일하게 적용된다.

 

a = 0.2 + 0.2 + 0.2
b = 0.6
print (a, b, a<=b)
실행 결과
0.6 0.6 false

 

따라서 실수값 사이의 같다/다르다 판별은 가급적 하지 않는 것이 좋으며 부득이할 경우에는 충분히 주의를 해야 예기치 않은 논리적 오류를 막을 수 있다.   

 

 

'프로그래밍언어.Lib > 루아(Lua)' 카테고리의 다른 글

루아(Lua)의 nil  (0) 2016.01.26
루아(Lua)의 문자열  (0) 2016.01.26
루아의 산술 연산자  (0) 2016.01.25
루아(Lua)의 숫자형  (0) 2016.01.25
루아(Lua)의 식별자 만드는 규칙  (0) 2016.01.25
Posted by 살레시오
,

 산술 연산자는 숫자형의 산술 연산(덧셈, 뺄셈 등)을 수행하며 루아에서 지원하는 산술 연산자는 다음 표와 같다.


표 1.1 루아의 산술연산자

산술연산자

기능

+

덧셈

11+22.2, a+33, x+y

-

뺄셈(부호)

11-22.2, a-33, x-y, -1, -b

*

곱셈

11*22.2, a*33, x*y

/

나눗셈

5/3, 11/22.2, a/33, x/y

%

나머지

5%3, 22.2%11, a%2, x%y

^

거듭제곱

2^10, a^10, x^y


덧셈 연산자는 두 피연산자의 덧셈 결과를 구해 준다. 뺄셈 연산자는 이항 연산자(피연산자가 두 개)로 사용될 때는 뺄셈을, 단항 연산자(피연산자 하나)로 사용될 때에는 부호를 나타내는 연산자이다. 한 가지 주의할 것은 + 연산자는 부호를 나타내는 단항 연산자로 사용되지 못한다. 즉, +1, +x 와 같은 표현은 루아에서는 오류를 발생시킨다.

 곱셈 연산자는 두 피연산자의 곱셈결과를 구하고 나머지 연산자는 a/b의 경우 a를 b로 나눈 몫을 구한다. 나눗셈의 경우 정수끼리의 연산이라도 결과는 실수(double형)이다.

 나머지 연산자는 예를 들어 x%y 는 x를 y로 나눈 정수몫을 구하였을 때의 나머지를 구한다. 피연산자로 정수뿐만 아니라 실수도 사용될 수 있다.


print(3%2)
print(14%3)
print(2.3%2)
print(2.3%1.1)

실행 결과

1
2
0.3
0.1


거듭제곱 연산자도 있다. 예를 들어 a^b는 ab를 계산한다.


print(2^10)
print(2^0.5)
print(0.3^1.5)
print(2^-1)

실행 결과

1024.0
1.4142135623731
0.16431676725155
0.5


전술한 바와 같이 루아에서 숫자는 모두 double형 데이터이므로 모든 연산 결과도 마찬가지로 double형 실수로 구해진다.



Posted by 살레시오
,

 보통 다른 언어에서는 숫자 자료형이 세분화되어 있다. C++의 예를 들면 byte, short, int, long, float, double 등등 정수냐 실수냐에 따라 또는 표현 범위에 따라 숫자 자료형이 세분화 되어 있으며 JAVA, C# 같은 언어도 마찬가지이다. 반면 루아에서는 그냥 숫자형(number로 표기된다) 하나이고 내부적으로 모든 숫자를 double 형 데이터로 처리한다.


print( type(1) )
print( type(1.1) )
print( type(1.1e34) )
실행결과
number
number
number


print()함수는 표준출력(보통은 화면)을 하는 내부함수이고 type()은 넘겨진 자료의 자료형 반환하는 내부함수이다. 따라서 print( type(x) ) 는 x의 자료형을 출력하는 명령이다. 위에서 정수 1도 number, 실수 1.1도 number, 1.1e34(지수적 표기법으로 1.1x1034을 나타낸다.)도 number이다. 모두 다 동일한 숫자형(number)라는 것을 알 수 있다.

 똑 같은 일을 변수를 이용하여 작성해 보면 다음과 같다.


a = 1 -- 변수 a에 정수 1을 대입
b = 1.1 -- 변수 b에 실수 1.1을 대입
c = 1.1e34 -- 변수 c에 정수 1.1 x 1034 을 대입
print(type(a)) -- ‘number’ 가 출력된다.
print(type(b)) -- ‘number’ 가 출력된다.
print(type(c)) -- ‘number’ 가 출력된다.


이 예에서 보면 a=1 이라고 하면 변수 a에 1을 대입하라는 것이고 b=1.1은 변수 b에 1.1.을, c=1.1e24는 변수 c에 1.1x1034을 대입하라는 것이다. 변수명은 이전 포스트에서 설명한 식별자 규칙에 의해서 만들어져야 한다. print( type(a) )는 변수 a에 담겨진 데이터의 자료형을 출력하라는 명령이 된다. 변수 a에는 1이 들어가 있으므로 number 가 화면에 출력된다.

 이와 같이 루아에서는 숫자 자료형은 하나밖에 없다. 루아는 내부적으로 정수도 double형이고 실수도 double형으로 처리된다. 일견은 메모리 낭비같이 여겨지기도 하지만 현대의 컴퓨팅 환경에서는 크게 중요한 문제는 아니고 이를 통해서 데이터 처리의 단순함을 얻을 수 있다.



Posted by 살레시오
,

 식별자(identifier)는 변수명이나 함수명 등을 만들때 사용된다. 루아의 식별자를 만드는 규칙은 다음과 같다. (C/C++과 동일하다.)


  1. 영어 대소문자(a~z, A~Z), 숫자(0~9), 언더바(_)로만 조합한다.

  2. 숫자로 시작하거나 공백문자를 포함할 수 없다.

  3. 미리 정의된 예약어(keyword)는 사용하면 안된다.


다른 언어에서와 마찬가지로 식별자는 대소문자를 구별한다. 즉, 대문자 A와 소문자 a는 서로 다른 것으로 구별된다. 식별자는 에를 들면 다음과 같은 것들이다.


x, vla, number, _hello, abc, id123, ch_4_5, name_of_that, _image, __sound


루아의 예약어는 프로그램에서 의미를 갖는 단어로서 다음과 같은 것들이 있다.


and, break, do, else, elseif, end, false, for, function, if, in local, nil, not, or, repeat, return, then, true, until, while


또한 예약어 외에 전역 함수(혹은 객체)에 사용되는 식별자도 사용하면 안되며 다음과 같은 것들이 있다.


_G, _VERSION, getmetatable, tostring, assert, io, rawlen, string, load, bit32, pairs, rawset, select, coroutine, tonumber, next, type, table, xpcall, error, utf8, debug, collectgarbage, math, rawget, os, pcall, ipairs, rawequal, print, setmetatable


이러한 규칙에 따라서 식별자를 만들어야 한다.



Posted by 살레시오
,