ESP32
wifi + Bluetooth 가 내장된 MCU 보드이다.
아두이노를 IDE로 사용가능한 보드로 IoT프로젝트에 매우 많이 사용되는 MCU 보드이다.
능력 대비 가격이 매우 저렴하다는 장점이 있다.
Arduino IDE 설치
아두이노는 오픈소스이다.
아두이노 공식 홈페이지에 접속해서 IDE를 설치한다
SOFTWARE 탭 클릭 후 IDE를 설치하면 된다.
설치가 완료 되었다면 파일 -> 기본 설정을 클릭하여 언어를 한국어로 변경할 수 있다.
이후 ESP32 보드를 추가해야 사용할 수 있다.
추가 보드 관리자에 URL을 추가해 준다. https://dl.espressif.com/dl/package_esp32_index.json
추가로 보드 매니저에 eps32를 검색해서 설치해 준다.
esp32 by Espressif 로 설치해주면 된다.
연결
ESP32를 마이크로 5pin 케이블로 PC에 연결한다.
연결하면, ESP32 의 전원 LED 에 빨간색 혹은 파란색 불이 들어온다.
ESP32로 wifi 실습 시, 동작되지 않을 경우 PC본체 뒷 편에 있는 메인보드와 연결된 USB포트를 사용해 보자
아두이노는 CubeIDE나 르네사스와 다르게 보드와 포트 설정을 직접 해야한다.
도구 -> 보드 -> esp32 -> Node32s를 클릭한다.
도구 -> 포트 -> 연결된 USB정보의 COM번호를 클릭한다.
COM번호는 장치 관리자에서 체크할 수 있으며, 만약 COM번호가 나타나지 않는다면 장치 드라이버를 설치해야한다.
샘플 테스트
파일 -> 예제 -> 01.Basics -> Blink를 클릭하여 샘플 코드 테스트를 진행한다.
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
샘플 코드를 보면 LED가 1초 간격으로 깜빡이게 되어 있는것을 볼 수 있다.
업로드 버튼을 통해 보드를 업데이트 해줄 수 있다.
아두이노 IDE
Arduino는 기본적으로 setup() , loop() 가 존재한다.
- setup() : 한번만 실행, 주로 설정용 코드들이 위치
- loop() : 반복해서 실행, 주로 동작에 관한 코드들이 위치
pinMap
ESP32의 각 핀에 GPIO와 , I2C, SPI관련 정보를 알 수 있다.
자신이 원하는 핀에 회로를 연결하여 GPIO를 제어하면 된다.
실습
GPIO 17핀에 LED를 할당하여 0.5초 주기로 HIGH, LOW를 전달하여 LED가 깜빡이게 만들기
int led1 = 17;
void setup() {
pinMode(led1, OUTPUT);
}
void loop() {
digitalWrite(led1, HIGH);
delay(500);
digitalWrite(led1, LOW);
delay(500);
}
결과
GPIO 18핀에 버튼을 할당하여 버튼을 눌렀을 때만 HIGH를 전달하여 LED를 키기
누르지 않은 상태에서는 LOW를 전달하여 LED를 끈 상태로 만든다.
int led1 = 17;
int btn1 = 18;
void setup() {
pinMode(led1, OUTPUT);
pinMode(btn1, INPUT);
}
void loop() {
if( digitalRead(btn1)==LOW ){
digitalWrite(led1, HIGH);
}
else{
digitalWrite(led1, LOW);
}
delay(100);
}
결과
UART 데이터 통신
int led1 = 17;
void setup(){
pinMode(led1, OUTPUT);
Serial.begin(9600);
}
void loop(){
if( Serial.available() ){
char a = Serial.read();
if( a=='o' ){
digitalWrite(led1, HIGH);
Serial.println("ON");
}
else if( a=='f'){
digitalWrite(led1, LOW);
Serial.println("OFF");
}
}
delay(100);
}
아두이노의 시리얼 모니터에서 메시지를 보내면 해당 메시지에 맞는 동작을 한다.
예시 코드의 경우 o를 입력받았다면 led에 HIGH가 전달되고, "ON"이라는 로그가 남는다.
f를 입력받았다면 led에 LOW가 전달되고, "OFF"라는 로그가 남는다.
- Serial.begin() : 해당 속도로 시리얼 통신 시작
- Serial.available() : 시리얼 입력 값이 있는 지 체크
- Serial.read() : 시리얼 입력 API, char 단위로 입력 가능
- Serial.println() : 시리얼 출력 API, 자동 줄바꿈
시리얼 모니터
시리얼 모니터를 통해 PC에서 데이터를 보내거나, ESP32 로 들어오는 시리얼 통신 데이터를 확인할 수 있다.
화면 우측 상단 → 돋보기 버튼 클릭
- 우측 박스에서 기기간 통신 속도를 맞춰준다.
- Message입력란에 통신을 위한 시리얼읍 입력한다.
- 하단 빈 공간에 통신에 대한 결과값이 출력된다.
라이브러리 설치
ESP32의 라이브러리를 설치할 수 있다.
왼쪽 탭에 있는 라이브러리 매니저를 클릭하고 설치하고자 하는 라이브러리를 검색한다.
버전을 선택 후 설치버튼을 누르면 자동으로 라이브러리가 설치된다.
동일한 이름이 있을 경우엔 배포자를 확인해 주어야 한다.
종속성 라이브러리가 있을 경우 모두 설치할 것인지 메시지박스가 노출된다.
설치되는 과정은 출력 탭에서 확인할 수 있다.
Timer
ESP32에는 Timer기능이 있다.
//타이머 객체 생성
hw_timer_t *ledTimer = NULL;
int led = 17;
void ARDUINO_ISR_ATTR onTimer(){
digitalWrite(led, !digitalRead(led));
}
int ms = 1000;
void setup() {
Serial.begin(9600);
pinMode(led, OUTPUT);
ledTimer = timerBegin(1000000);//1Mhz
timerAttachInterrupt(ledTimer, &onTimer); // 타이머에 인터럽트 등록
timerAlarm(ledTimer, 500000, true,0); // 알람 주기 설정 / auto reload 됨
timerStart(ledTimer); //타이머 알람 활성화
}
int cnt = 0;
void loop() {
cnt++;
if( cnt> 20 ){
timerEnd(ledTimer); //타이머 알람 비활성화
Serial.println("timer end!");
cnt = 0;
}
Serial.print("current : "); Serial.println(cnt);
delay(500);
}
loop를 돌면서 시리얼 모니터에 current : cnt가 출력된다.
NTP(Network Time Protocol)
Edge 장치는 서버와의 시간 동기화가 매우 중요하다.
시간 기반 제어, 보안, 로그 기록 등에 사용된다.
ESP32는 wifi 를 이용해 NTP 프로토콜로 시간 정보를 갖고 올 수 있다.
파일 -> 예제 -> ESP32 -> Time -> SimpleTime을 클릭해 준다.
#include <WiFi.h>
#include "time.h"
#include "esp_sntp.h"
const char *ssid = "YOUR_SSID";
const char *password = "YOUR_PASS";
const char *ntpServer1 = "pool.ntp.org";
const char *ntpServer2 = "time.nist.gov";
const long gmtOffset_sec = 3600;
const int daylightOffset_sec = 3600;
const char *time_zone = "CET-1CEST,M3.5.0,M10.5.0/3"; // TimeZone rule for Europe/Rome including daylight adjustment rules (optional)
void printLocalTime() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("No time available (yet)");
return;
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}
// Callback function (gets called when time adjusts via NTP)
void timeavailable(struct timeval *t) {
Serial.println("Got time adjustment from NTP!");
printLocalTime();
}
void setup() {
Serial.begin(115200);
// First step is to configure WiFi STA and connect in order to get the current time and date.
Serial.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, password);
/**
* NTP server address could be acquired via DHCP,
*
* NOTE: This call should be made BEFORE esp32 acquires IP address via DHCP,
* otherwise SNTP option 42 would be rejected by default.
* NOTE: configTime() function call if made AFTER DHCP-client run
* will OVERRIDE acquired NTP server address
*/
esp_sntp_servermode_dhcp(1); // (optional)
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" CONNECTED");
// set notification call-back function
sntp_set_time_sync_notification_cb(timeavailable);
/**
* This will set configured ntp servers and constant TimeZone/daylightOffset
* should be OK if your time zone does not need to adjust daylightOffset twice a year,
* in such a case time adjustment won't be handled automagically.
*/
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2);
/**
* A more convenient approach to handle TimeZones with daylightOffset
* would be to specify a environment variable with TimeZone definition including daylight adjustmnet rules.
* A list of rules for your zone could be obtained from https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h
*/
//configTzTime(time_zone, ntpServer1, ntpServer2);
}
void loop() {
delay(5000);
printLocalTime(); // it will take some time to sync time :)
}
- Line 5~6 : wifi 정보
- Line 10 : GMT + 9 적용
- Line 13 : time_zone 변수 삭제
해당 부분을 자신의 환경에 맞게 수정하면 현재 시간 정보가 출력된다.
#include <WiFi.h>
#include "time.h"
// WiFi SSID 및 비밀번호 설정
const char* ssid = "HYEOK";
const char* password = "88888888";
// NTP 서버 및 시간대 설정
const char* ntpServer1 = "pool.ntp.org";
const char* ntpServer2 = "time.nist.gov";
const long gmtOffset_sec = 3600 * 9;
const int daylightOffset_sec = 0;
void printLocalTime()
{
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("No time available (yet)");
return;
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}
void setup()
{
Serial.begin(115200);
Serial.printf("Connecting to %s ", ssid);
// WiFi 연결 시도
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" CONNECTED");
// WiFi 연결 후 NTP 설정
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2);
}
void loop()
{
delay(1000);
printLocalTime();
}
나는 모바일 핫스팟 환경을 통해 wifi를 연결했다.
1초 간격으로 현재 시간이 출력되는 것을 볼 수 있다.
이상한 유니코드로 출력된다면 시리얼의 통신 속도가 맞는지 확인해보자
웹서버 만들기
ESP32 를 웹서버로 동작 시킬 수 있다.
파일 -> 예제 -> Webserver -> HelloServer라는 예제가 존재한다.
접속 환경의 wifi정보를 수정하고 빌드한다.
ip를 출력하고 빌드가 완료 되었다면 해당 ip로 접속하여 구현한 내용을 확인할 수 있다.
'임베디드 > IoT' 카테고리의 다른 글
임베디드 IoT, MQTT (4) | 2024.11.11 |
---|---|
임베디드 IoT (0) | 2024.11.07 |