아두이노 + ESP8266 + MQTT
- 정말 삽질의 연속이었다.
- 다음을 위해 기록을 해둔다.
목적
다음과 같이 아두이노 우노에 esp8266을 연결하여 라즈베리에 깔린 브로커를 통해 통신하는 것이 목적이다.
다음 블로그를 변형해 실행시키는 것이다.
- https://randomnerdtutorials.com/raspberry-pi-publishing-mqtt-messages-to-esp8266/
- 이 블로그는 esp8266 보드를 사용했다.
- 다만 나는 방법을 바꿔야 했다.
문제점
- 영 번째로 ESP8266 사용 방법의 문제이다.
- 첫 번째로 ESP8266 펌웨어 관련 문제들이다.
- 두 번째로 ESP8266 라이브러리의 문제이다.
0. 사용 방법 문제
- 보통 인터넷의 자료는 ESP8266 모듈을 연결해 사용하는 방법이 아닌 만들어진 보드를 이용하는 글이 대부분이다.
- 라이브러리나 예제 또한 이를 가정한다.
- 그래서 esp8266 라이브러리 설치를 찾아보면 보드 매니저 관련 내용이 나오는데 이는 esp8266 에 직접 올려 사용하겠다는 뜻이다.
- ESP8266은 두 가지 방법으로 사용된다.
- 모듈을 아두이노에 연결해 시리얼 통신으로 모듈을 제어한다.
- 보드(모듈)에 직접 프로그램을 올린다.
- 나는 아두이노 와이파이 실드나 EPS8266 보드가 없었고, ESP8266 01 ( ESP-01 모듈이다. ) 만 있었다.
- 가격이 저렴했다.
- 나는 아두이노를 통해 모듈을 제어하는 방식으로 사용해야 했다.
- 하지만 이런 방식의 문제는 대부분은 이렇게 안 한다는 것이다.
- 이는 정보의 문제로 이어진다.
- 라이브러리 찾기도 힘들다. (이는 밑에서 다룬다.)
혼동을 피하기 위해 esp8266 01 모듈 자체를 esp8266이라 부르겠다.
- 보드( nodeMCU) 같은 거나 esp8266에 직접 올리는 경우는 편하게 할 수 있다.
- 특히 보드는 펌웨어 관련 문제에서도 편하며 라이브러리도 구하기 쉽다.
1. 펌웨어 및 라이브러리의 문제
- 우선 ESP8266 관련해 글을 찾아보면 보통 이렇다.
- 펌웨어 업데이트
- AT 실습
- 나는 위 과정을 진행하는데 문제가 없었다.
- 다만 직접 AT명령어를 치지 않고, 라이브러리를 이용 방법에서 문제가 생겼다.
- 정확히는 mqtt 라이브러리 PubSubClient.h 를 사용하는데 문제됨
- 우선 ESP8266 의 라이브러리는 많다.
- 정확히는 직접 올려서 돌아가는 라이브러리가 많다.
- 위에서 언급한 보드 매니저를 통한 방법은 ESP8266에 직접 올릴 때 사용된다.
- 다만 이 라이브러리를 아두이노에 올리면 당연히 이상하게 돌아간다. ( 경험상 )
- 하지만 내가 원하는 아두이노에서 시리얼 통신을 통해 esp8266을 조종하는 라이브러리는 찾기 힘들다. 예제도 딱히 없다.
- 다음과 같은 라이브러리가 있다.
- https://github.com/Diaoul/arduino-ESP8266
- WiFiEsp
- 다음과 같은 라이브러리가 있다.
- 위 두 개의 라이브러리 중 WiFiEsp만 컴파일이 잘 됬다.
- 위의 라이브러리는 PubSubClient client(esp8266Client); 과정이 문제됬다.
- 하지만 컴파일 후에도 문제가 생겼다.
- 펌웨어 에러라는 메시지를 확인할 수 있었고, 명령어를 지원하지 않는 것 같았다.
- 혹은 Serial.println(“WiFi shield not present”); 가 계속 찍힌다.
- 코드를 살짝 뒤져보니 AT 보내고 응답을 못하는 것 같았다.
- 이에 제대로 된 업데이트가 필요하다.
- https://crystalcube.co.kr/215?category=913820
- 이 사람의 블로그를 참고하자. 설명이 잘 되어있다.
- 시리얼 모니터는 아두이노에 코드가 안 올라가도 잘 작동된다.
- 명령어 주고 받기 된다.
- 위의 블로그는 보드레이트가 맞춰져 있지 않다.
- 시리얼 모니터를 열고 밑의 블로그를 따라 명령어로 바꿔주자.
- AT+UART_DEF=9600,8,1,0,0
- https://www.robotstory.co.kr/raspberry/?board_name=raspberry_bbs&search_field=fn_title&search_text=ESP&lang=ko_KR&vid=35
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <SoftwareSerial.h>
#include <WiFiEsp.h>
#include <WiFiEspClient.h>
#include <WiFiEspUdp.h>
#include <PubSubClient.h>
#include <stdlib.h>
#include <Wire.h>
IPAddress server(); //your mqtt server adress
char ssid[] = ""; // your network SSID (name)
char pass[] = ""; // your network password
int status = WL_IDLE_STATUS; // the Wifi radio's status
//HDC1000 mySensor(0x41, 2) <-- DRDYn enabled and connected to Arduino pin 2 (allows for faster measurements).
WiFiEspClient esp8266Client;
PubSubClient client(esp8266Client);
SoftwareSerial esp8266(10, 11); // RX, TX to ESP-01
void setup(){
Serial.begin(9600);
esp8266.begin(9600); //software serial to ESP8266
WiFi.init(&esp8266); //ESP8266 wifi //HDC1000 sensor
// check for the presence of the shield
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
// don't continue
while (true);
}
// attempt to connect to WiFi network
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network
status = WiFi.begin(ssid, pass);
}
// you're connected now, so print out the data
Serial.println("You're connected to the network");
//connect to MQTT server
client.setServer("",1883);
//client.setCallback(callback);
}
void loop(){
Serial.print("Temperature: ");
Serial.print("온도프린트");
Serial.print("C, Humidity: ");
Serial.print("습도프린트");
Serial.println("%");
// mqtt out
if (!client.connected()) {
Serial.print("Attempting MQTT connection...");
client.connect("arduinoClient1");
Serial.println("connected");
delay (1000);
client.publish("temperature","온도1");
delay (1000);
client.publish("humidity","습도1");
delay (1000);
}
Serial.println("퍼블리싱중");
client.publish("temperature","1004");
delay (1000);
client.publish("humidity","습도2");
delay (1000);
client.loop();
delay(3000);
}
- 이제 위의 예제가 잘 돌아가는 모습을 볼 수 있다.
- 위의 예제는 아래 블로그를 참고했다.
- https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=hcheong&logNo=221050736456
2. 트러블 슈팅
- 우선 선을 확인하자.
- 귀찮다고 선 대충 연결하면 피본다.
- 아두이노에 업로드하는 상태나 펌웨어 업데이트 통로로 쓰는 방법이나 다 선 연결이 다르다.
- 업데이트나 연결 잘 안되면 선 뽑고 다시 꼽자. 진리이다.
- 귀찮다고 선 대충 연결하면 피본다.
MQTT 통신
- https://randomnerdtutorials.com/raspberry-pi-publishing-mqtt-messages-to-esp8266/
- 다음 예제를 따라했다.
- 잘된다.
- 이 사진은 라즈베리파이의 flask 서버 로그다.
- 이 사진은 아두이노 시리얼 모니터다.
- 설정 잘해야 안 깨진다.