2차 프로젝트에서 기존 1차에서 쓰던 방식

(AT 커맨드를 통해 ESP-8266 모듈을 직접 제어하고, GET 방식으로 센서 값 전송)

을 그대로 쓸려다 MQTT 통신을 써 볼려니 문제가 생겼다. 

ESP8266과 ESP 01 어댑터를 조합하여 아두이노에 연결하고,

WiFiEsp 라이브러리를 같이 사용했는데,

테스트 코드를 업로드 했을 때 unsupported firmware version / module initialize failed

등등의 오류를 많이 구경하다...해결 방법을 찾아서 정리해본다.

 

0. 펌웨어 교체 - 통신속도(보레이트) 확인

 

최근 나오는 모델은 보통 기본 통신속도가 9600으로 되어있는 경우가 많다. 

또는 아두이노에서 실습을 할려고 통신속도를 변경하는 경우가 많은데, 

 

공식적으론 115200으로 출고가 된다. 

이를 115200으로 원상복구 시켜줘야 하는데

AT+CIOBAUD=115200 또는 AT+UART_DEF=115200,8,1,0,0 명령으로 변경할 수 있다.

사전 설치된 모듈의 펌웨어에 따라 사용 할 수 있는 명령어가 다르니 확인하도록 하자!

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX

void setup() {
  Serial.begin(9600);

  mySerial.begin(9600); // 115200인 경우 변경해주면 됨
}

void loop() { 
  if (mySerial.available()) {
    Serial.write(mySerial.read());
  }
  if (Serial.available()) {
    mySerial.write(Serial.read());
  }
}

 

코드를 업로드 한 후 라인 인코딩은 Both NL & CL, 보레이트는 9600으로 설정하고

AT를 입력하여 OK 응답이 날라오는지 확인한다.

 

아두이노와의 배선은 다음과 같이 연결한다.

https://funyphp.com/archive/arduino/20 의 배선도 참고

다만 업데이트 하기 전에 3.3V 핀 위에 있는 RESET 핀과 GND 핀을 쇼트시킨 상태에서 진행해야 성공률이 높다.

(아두이노에 내장된 MCU를 비활성화 시키는 역활을 한다.)

 

1. 펌웨어 파일 업로드하기

esp_iot_sdk_v1.5.0_15_11_27.zip
2.08MB
FLASH_DOWNLOAD_TOOLS_v2.4_150924.rar
5.44MB

상단의 두 파일을 받아 적당한 위치에 압축을 해제한다.

ESP_DOWNLOAD_TOOL_V2.4.exe 파일을 실행하면 다음과 같은 화면이 표시된다.

 

1-1 Download Path Config 설정

순서는 상관 없지만 파일 명과 주소는 반드시 맟줘주어야 한다! 

 

  bin\at\nobooteagle\flash.bin  , ADDR : 0x00000

  bin\at\nobooteagle\irom0text.bin , ADDR :  0x40000

  bin\blank.bin  , ADDR :  0xfe000

  bin\blank.bin  , ADDR : 0x7e000

추가한 뒤 좌측의 체크 표시를 모두 활성화 시켜준다.

 

1-2 기타 설정

 

SPI SPEED : 40MHz

SPI MODE : QIO OR DOUT

FLASH SIZE : DETECTED INFO 표시되는 정보대로 맞춰주기 (대부분 8Mbit이긴 함)

COM PORT & BAUDRATE : 장치관리자에 표시되는 아두이노의 시리얼 포트 / 115200으로 설정

 

START를 누른 뒤 완료되길 기다리면 된다. 설정 값에 문제가 없다면 완료 메세지를 확인할 수 있을 것이다.

 

 

 

다만...ESP-8266 모듈의 단점이 자체 전원 소비량이 많다는 것 (어디까지나 아두이노에 붙여 사용할때의 문제)

인지, 완벽히 호환되지는 않는 듯 하다. 아두이노에 종속적인 센서들을 많이 쓰는 지라

ESP 32로의 이동은 어려워서 아두이노 메가를 사용중에 있는데, 

MQTT 라이브러리와 이런저런 센서를 붙혀서 올리고 하는 과정이 꽤나 손이 많이 간다.

분명 저장 공간상으론 남아도는데 틈만 나면 커넥션이 끊겼다가 다시 붙거나 / 아예 못잡거나 / 무한정 시도하거나 이 세가지의 동작이 지속되고 있다. MQTT 로직이 섞여들어가서 그런건지는 모르겠으나 의도한 동작 때문에

코드를 그렇게 짰는데..  머리가 너무 복잡하다.

 

라즈베리파이를 셋팅하면서 나름대로 오류를 해결한 방법들에 대해 정리해보고자 한다.

 

 

1. 저장장치 준비

16G 정도의 마이크로 SD 카드나, USB 메모리, 외장하드를 준비한다.

특히나 마이크로 SD카드의 경우 읽기 쓰기 속도가 빠른 제품을 사용하는 것이 사용 시의 답답함을 줄일 수 있다.

(별도의 EMMC가 내장 된 것이 아니라, 마이크로 SD카드 혹은 외장 하드를 운영체제 저장공간으로 사용하기 때문에

이러한 장치들의 읽기, 쓰기 속도에 영향을 많이 받는다.)

 

2. 라즈베리파이용 OS (라즈비안) 이미지 다운로드 받기

 

https://www.raspberrypi.com/software/

 

Raspberry Pi OS – Raspberry Pi

From industries large and small, to the kitchen table tinkerer, to the classroom coder, we make computing accessible and affordable for everybody.

www.raspberrypi.com

공식 사이트에 접속한다.

 

상단의 Software를 클릭하고, 하단으로 내려간다.

 

'See all download option'를 클릭한다. 

 

Raspberry Pi OS 에서 Raspberry Pi OS with desktop and recommended software  아래의 Download를 클릭하여 이미지를 내려받는다. (각종 IDE, 게임, 툴들이 사전 설치되어있는 이미지이다.)

 

3. balenaEtcher 다운로드 (또는 Windiskimager32 사용해도 무관)

 

https://www.balena.io/etcher/? 

 

balena - The complete IoT fleet management platform

Infrastructure and tools to develop, deploy, and manage connected devices at scale. Your first ten devices are always free.

www.balena.io

프로그램 제작사의 홈페이지로 이동한다.

 

중앙에서 Download for Windows (x86|x64) 를 클릭하고, (Portable) 표시가 있는 걸 클릭한다. 

다운로드가 완료되면 저장장치를 PC에 연결하고, Etcher를 실행한다. (포터블 버전이라 실행에 시간이 걸림).

 

4. 이미지 플래싱 하기

Etcher가 실행되면, 화면에서 Flash from file을 클릭하고, 아까 다운로드받았던 이미지를 지정해준다. 

 

Select target를 클릭하여 이미지를 설치할 저장장치를 선택하고, 하단의 Select를 클릭한다. 

그런 뒤 Flash를 클릭하면 UAC 창이 뜨면서 명령 프롬프트를 사용하기 위한 권한을 물어본다. (거기서 예 클릭해야 함)

자동으로 Flash (쓰기) 작업을 진행하고, verify(검증) 절차가 끝나게 된다. 

 

끝나게 되면 무조건 이런 메세지가 뜨게 되는데 이유는 다음과 같다.

윈도우에서 인식할 수 없는 ext4 형식을 사용하기 때문에 포맷을 하겠냐고 물어보게 되는데, 여기서 디스크 포맷을 누르면 4단계 처음부터 다시 해야 하니 취소를 눌러준다.

 

4-1 WiFi 네트워크 사전설정하기

boot 드라이브 내에 다음과 같은 파일을 생성한다. (저장 타입은 모든 파일 (All Types)으로!)

 

파일명 :: wpa_supplicant.conf


ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
    ssid="WIFI 이름"
    psk="WIFI 암호"
}

ssid 자리에는 사용중인 인터넷 공유기의 SSID를, psk자리에는 공유기의 비밀번호를 넣고 저장한다.

작성이 완료되면 저장장치를 제거한다.

 

 

5.저장장치 연결 및 부팅

라즈베리파이 하단에 아까 작업한 SD 카드를 연결하거나, USB 포트에 저장장치를 연결한다.

전원을 연결하기 전에 모니터 케이블과 키보드, 마우스를 연결하고, 전원을 연결해야 한다,

랜선이 있다면 랜선도 같이 연결한다.

 

 

6-1. 초기 설정 (비밀번호 변경)

 

초기 id, 비밀번호는 pi / raspberry 이다.

이미 셋팅해놓은 라즈베리파이에서 캡처한 것이나 모양만 보고 따라가는 게 좋을 것이다.

상단 산딸기 아이콘 클릭 - Help 아래 기본 설정 탭 클릭  - Raspberry Pi Configuration 클릭 후 

System tab 이동, Change Password.. 클릭

 

 

변경할 비밀번호를 모두 입력해주고, OK를 클릭한다.

 

 

6-2. 초기 설정 (패키지 저장소 경로 변경)

기본적으로 외국으로 저장소가 잡혀있어 업데이트 설치 시 시간이 오래 걸린다. 

https://www.raspbian.org/RaspbianMirrors/

 

RaspbianMirrors - Raspbian

Raspbian Mirrors Raspbian Repository Mirrors CONTINENT COUNTRY MIRROR DEB/DEB-SRC ADDRESS ISSUES Europe United Kingdom University of Oxford http://mirror.ox.ac.uk/sites/archive.raspbian.org/archive/raspbian Europe* United Kingdom Mythic Beasts (http|rsync)

www.raspbian.org

이 사이트에 접속한다. 

 

이 부분이 우리나라에 있는 라즈비안의 미러 저장소 목록이다.

작업 표시줄의 이 아이콘을 눌러

터미널 창을 실행하고, 화면에 sudo nano /etc/apt/sources.list 를 입력한다. 커서로 이동하고,

다음의 내용을 입력한다. 

 

2021 10월자에 나온  bullseye의 경우 다음의 두 줄을 추가한다.

deb http://ftp.kaist.ac.kr/raspbian/raspbian/ bullseye main contrib non-free rpi
deb-src http://ftp.kaist.ac.kr/raspbian/raspbian/ bullseye main contrib non-free rpi

 

2021 06월자의 buster의 경우 다음의 두 줄을 추가한다.

deb http://ftp.kaist.ac.kr/raspbian/raspbian/ buster main contrib non-free rpi
deb-src http://ftp.kaist.ac.kr/raspbian/raspbian/ buster main contrib non-free rpi

Ctrl + o를 눌러 저장하고, y를 입력해 저장한다. Ctrl+x를 눌러 빠져나온다.

 

 

6-3. 초기 설정 (시간대 설정)

 

 

아까 실행했던 Raspberry Pi Configuration로 들어가 Localisation Tab의 Set Timezone를 클릭하고, 

Area를 Asia로, Location을 Seoul로 잡아준 뒤 확인을 누른다. 시간대가 정상적으로 바뀐 후 다음 단계를 진행한다.

 

6-4. 초기 설정 (업데이트 및 한글 설정)

터미널 창을 실행한다. sudo apt-get update를 입력해 캐시를 업데이트 해 준 후, 

sudo apt-get upgrade -y를 입력해 업데이트를 진행한다.

bullseye 버전의 경우 vlc 오류가 발생하며 업데이트가 안 되는 경우도 있는데, 

그런 경우 sudo apt remove vlc -y를 입력해 vlc를 삭제하고,

sudo apt-get autoremove를 진행해 사용하지 않는 패키지를 같이 지워준다.

그런 후 sudo apt-get upgrade -y를 다시 시도한다.

 

 

업데이트가 끝나면 sudo apt-get install fonts-unfonts-core -y를 사용해서 한글 폰트를 설치해준다.

 

설치가 완료되면 Language를 ko(Korean), Character Set을 UTF-8로 변경하고, OK를 클릭한다.

한번 재부팅을 해 주면 언어가 한글로 바뀐 것을 확인할 수 있다.

 

7. 한글 키보드 설치

터미널 창에 sudo apt-get install ibus ibus-hangul -y 를 입력하고, 설치가 완료되길 기다린다.

 

Yes를 클릭해 실행해준다. 

 

"..."을 클릭한 뒤, Shift를 체크해주고 추가 & 적용을 눌러주고 확인을 클릭해 나온다. 

재부팅 후  좌측 Shift + Space 키 조합으로 한영 전환이 되는 걸 확인하고, 사용하면 된다.

 

*한글 입력이 안 되는 경우

sudo apt-get remove ibus ibus-hangul , sudo apt autoremove 를 순서대로 완료해준 뒤

sudo apt-get install fcitx-hangul을 입력해 fcitx 입력기를 설치한다.

 

sudo nano /etc/default/im-config 를 입력해 시작 시 자동 실행이 될 수 있도록 

사진과 같이 수정해준다. (기본값은 auto로 되어있음)

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;

시스템 도구 탭에 있는 Fcitx를 실행해 주고 ,

작업 표시줄에 보이는 키보드 아이콘을 우클릭 해서 설정을 클릭한다.

 

 

input Method 항목을 아래 사진과 같이 설정해준 후 창을 닫는다.

 

 

 

1차 프로젝트를 하면서 유용하게 사용한 타이머인터럽트(MsTimer2) 라이브러리에 대한 이야기이다.

아두이노를 활용한 실습을 할때 함수가 많아지는 경우가 있다.

동작이 의도한 대로 안 되거나 정확도를 높히고 싶을 때(센서로부터 받는 값을 특정 주기로 계속 측정하고 싶을 때)

인터럽트를 통해 이러한 걸 구현 할 수 있다. 또는 어딘가로 보내는 통신을 loop문에서 계속 호출한다던가.

 

인터럽트 

쉽게 생각하면, 끼어들기라고 생각하면 좋다. void loop 문 내 기본 메인 동작을 수행하는 도중에 어떤 돌출된 상황이 발생하면(즉, 이벤트) 메인 동작에 영향을 안주는 선에서 끼어들어서 그 상황에 관련된 특정 동작을 수행하고 

다시 되돌아가는 것을 의미한다.

 

아두이노에선 핀에 대한 인터럽트를 다음과 같은 방식으로 사용할 수 있다. (우노 기준 2,3번핀)

attachInterrupt(digitalPinToInterrupt(interruptPin), exchange, FALLING);

attachInterrupt(인터럽트핀, 호출함수, 상태)로 해서 setup()함수에 선언하여 사용한다.

LOW     :   LOW 상태일 때
CHANGE  :  입력 값이 변할때
RISING  :  LOW -> HIGH로 변할때
FALLING :  HIGH -> LOW로 변할때

 

하지만 나의 경우는 측정함수를 설정한 주기 동안 반복하게끔 하고 싶었기 때문에, MsTimer2 라이브러리를 사용했다.

 

설치 방법

Arduino IDE의 라이브러리 매니저에서 MsTimer2를 검색하거나,

https://github.com/PaulStoffregen/MsTimer2 에서 아래와 같은 방법으로 다운로드 받을 수 있다.

 

하지만 프로젝트에서는 아두이노 메가보드(Mega 2560/ADK)를 주력으로 사용하기에

http://www.hellmaker.kr/post/302 이 글을 참고하여 MsTimer2.cpp 파일을 수정하여 사용했다.

 

 

사용 방법

파일의 최 상단에 #include <MsTimer2.h>를 추가해주고, setup 문 안에 다음과 같이 정의한다.

void setup() {
....
  MsTimer2::set(ms, func); 
  MsTimer2::start();
....
  }

 

MsTimer2::stop를 만나기 전 까지 MsTimer2::set에 설정된 ms (1000ms = 1sec)주기로, func를 계속 실행하게 된다.

func 파라미터의 경우 반환형식이 없는 void 형의 함수만 호출이 가능하다. (그게 안 돼서 어리둥절했다는..)

최대 49일까지 설정이 가능하다.

 

 

 

delay를 사용한 blink 예제 vs 타이머 인터럽트를 사용한 blink 예제

void setup(){
	
	pinMode(13,OUTPUT);
	
}
void loop(){
	//문장 1
	digitalWrite(13,!digitalRead(13));
	delay(500);
	//문장 2
}

loop 문 내에 작성하면 동작이 끝난 후에 다음 문장을 실행하기 때문에 여러가지 동작을 loop 문 내에 작성하려는 경우 

delay를 활용하면 안 된다. 

 

#include <MsTimer2.h>

void setup(){
	pinMode(13,OUTPUT);
	MsTimer2::set(500,ledBlink);
	MsTimer2::start();
}

void loop(){
	//문장 1
	//문장 2
}

void ledBlink{
	digitalWrite(13,!digitalRead(13);
	state = !state; 
}

 

타이머인터럽트의 경우 loop문 보다 우선순위가 높아 500ms 간격으로 LED를 제어 할 수 있다.

void Setup 문 안에 위와 같이 선언을 해주고, 다음과 같은 측정함수를 불러오게끔 했다.

+ Recent posts