arduino bluetooth controller PWM v3.5
안드로이드 버전업에 따라 안드로이드 특정버전에서만 와이이파이 및 블루투스 연결이 가능합니다.
(*** 와이파이 연결은 안드로이드8 [갤럭시S7]이하 버전에서만 작동합니다 ***)
(*** 블루투스 연결은 안드로이드10 이하 버전에서만 작동합니다 ***)
https://play.google.com/store/apps/details?id=com.appybuilder.arduino_appy.arduino_BT_controller_PWM
플레이 스토어에서 "아두이노 pwm"이나 "arduino pwm"을 검색하시면 빠르게 찾을 수 있습니다.
특징
- Bluetooth 2.0 / Bluetooth 4.0 BLE 연결 : HC-05, HC-06, HM-10, AT-09, BT05
- ESP8266 NodeMcu 와이파이 / ESP32 Bluetooth 2.0, BLE, 와이파이 연결 가능
- 디지털 버튼 12개 : 토글 및 푸쉬 버튼 속성 설정 기능
- 아날로그 콘트롤러 3개(PWM) : Min 및 Max 값 설정 기능
RGB LED 제어용 Color Picker 모드
PWM 제어용 디지털 노브 모드
- 텍스트 입력 기능 및 전송 옵션 설정 기능(NO-없음, NL-새 줄, CR-캐리지 리턴, BOTH-캐리지 리턴+새 줄)
- 표시 설정 화면:
메인화면의 버튼 및 PWM 슬라이드 표시 설정
버튼 라벨 사용자 지정 기능
라벨 외부 파일 저장 기능: /arduino_BT_button_label.txt
- 통신 연결 시 안드로이드 시스템 날짜 및 시간 자동 전송 기능
- 플로팅 버튼
푸시버튼 4개(13, 14, 15, 16)
안드로이드 시스템 날짜 및 시간 수동 전송 버튼
시간 설정값 전송 버튼
메인화면
표시 설정 화면
버튼 속성 설정 화면
연결 옵션 설정
Send Date/Time : 통신 연결 시 안드로이드 시스템의 현재 날짜 및 시간을 1회만 전송합니다.
SERVICE UUID : Bluetooth 4.0 BLE의 Custom UUID를 설정할 수 있습니다.
Wifi PWM / Bluetooth PWM : PWM 제어를 위한 데이터 전송 간격, 단위-밀리초
값이 클수록 배터리 소모를 줄일 수 있지만 아두이노의 응답은 느려집니다.
값이 너무 작으면 아두이노 및 모듈의 성능에 따라 리셋될 수 있습니다.
Read data from arduino : 체크 해제 시 아두이노로부터 오는 데이터를 받지 않습니다.
(Bluetooth 2.0 Classic, Wifi 연결 시)
배터리 소모를 줄일 수 있습니다.
Reading Interval : Read data from arduino가 체크된 상태에서 데이터를 읽어오는 간격을 설정합니다.
값이 클수록 배터리 소모를 줄일 수 있지만 데이터 수신에 대한 표시는 느려집니다.
- Bluetooth 접속 :
블루투스 아이콘 클릭 -> Bluetooth 2.0 / Bluetooth 4.0 BLE 선택 -> Bluetooth 버튼 클릭 -> 모듈 선택
- 와이파이 연결 : 와이파이 아이콘 클릭 -> Soft AP 접속 및 확인 -> Soft IP 주소 입력 -> Confirm 클릭
- 제어용 PROTOCOL
1. 블루투스 : 앱 송신 -> 아두이노 수신
디지털 버튼: 0xF0 + 1byte number + 0xF1
PWM : 0xF3 + 1byte number + 2byte number + 0xF1
Date / Time: 0xF8 + 07/24/2019(String) + 0x7C + 15:55:32(String) + \n(새 줄)
Alarm: 0xF9 + 21:20(String) + \n(새 줄)
uint8_t pin_a[3] = {0, };
uint8_t pwm_a[5] = {0, };
void btSerial_read() {
if (btSerial.available()) {
if (btSerial.peek() == 0xF3) get_pwm_val = true;
else if (btSerial.peek() == 0xF0) get_pin_val = true;
if (get_pwm_val == true ) { // pwm 제어값 수신
uint8_t temp = btSerial.read();
pwm_a[pwm_count] = temp;
pwm_count++;
if (temp == 0xF1) {
get_pwm_val = false;
pwm_count = 0;
pwm_control();
}
}
else if (get_pin_val == true) { // 디지털 핀 제어값 수신
uint8_t temp = btSerial.read();
pin_a[pin_count] = temp;
pin_count++;
if (temp == 0xF1) {
get_pin_val = false;
pin_count = 0;
pin_control();
}
}
else {
if (btSerial.peek() == 0xF8) {
String temp = btSerial.readStringUntil('\n');
Serial.println(temp);
}
else if (btSerial.peek() == 0xF9) {
String temp = btSerial.readStringUntil('\n');
Serial.println(temp);
}
else {
general_use(); // 텍스트 출력함수
}
}
}
}
블루투스 : 아두이노 송신 -> 앱 수신
디지털 버튼: 0xF0 + 1byte number + 0xF1
PWM echo(pwm 값 확인) : 0xF3+1byte number+2byte number+0xF1
PWM slide(슬라이드 위치 변경): 0xF4 + 1byte number + 2byte number + 0xF1
uint8_t pin_echo[] = {0xF0, 0, 0xF1};
void send_pin_echo(uint8_t pin_val){
pin_echo[1] = pin_val;
for (int i = 0; i < 3; i++) {
SerialBT.write(pin_echo[i]);
}
}
uint8_t pwm_echo[] = {0xF3, 0, 0, 0, 0xF1};
void send_pwm_echo(uint8_t slide, uint16_t pwm_val) {
pwm_echo[1] = slide;
if (pwm1 < 256) {
pwm_echo[2] = pwm_val;
pwm_echo[3] = 0;
}
else {
pwm_echo[2] = pwm_val;
pwm_echo[3] = pwm_val >> 8;
}
for (int i = 0; i < 5; i++) {
SerialBT.write(pwm_echo[i]);
}
}
uint8_t pwm_slide[] = {0xF4, 0, 0, 0, 0xF1};
void send_pwm_slide(uint8_t slide, uint16_t pwm_val) {
pwm_slide[1] = slide;
if (pwm1 < 256) {
pwm_slide[2] = pwm_val;
pwm_slide[3] = 0;
}
else {
pwm_slide[2] = pwm_val;
pwm_slide[3] = pwm_val >> 8;
}
for (int i = 0; i < 5; i++) {
SerialBT.write(pwm_slide[i]);
}
}
2. 와이파이 : 앱 송신 -> 아두이노 수신
디지털 버튼: %%F0 + 1byte number + %%F1
PWM1 : %%F31 + String + %%F1
PWM2 : %%F32 + String + %%F1
PWM3 : %%F33 + String + %%F1
Date / Time: %%F8 + 07/24/2019 + %7C + 15:55:32 + \n(새 줄)
Alarm: %%F9 + 21:20 + \n(새 줄)
아두이노 응답 요청: %%F5
void wifi_read() { // wifi 데이터 수신
client = server.available(); // 서버가 작동하고 있으면 client 생성
if(client.available()) { // 클라이언트에 데이터가 있으면
income_wifi = client.readStringUntil('\r');
if (income_wifi.indexOf("%%F1") != -1) { // 종료문자가 있으면
if (income_wifi.indexOf("%%F0") != -1) { // 디지털 핀 값 수신
String wifi_temp = income_wifi.substring(income_wifi.indexOf("%%F0")+4, income_wifi.indexOf("%%F1"));
pin_val = wifi_temp.toInt();
pin_control();
}
else if (income_wifi.indexOf("%%F31") != -1) { // 슬라이드1, PWM 값 수신
String wifi_temp = income_wifi.substring(income_wifi.indexOf("%%F31")+5, income_wifi.indexOf("%%F1"));
pwm1 = wifi_temp.toInt();
Serial.print("pwm1: "); Serial.println(pwm1);
}
else if (income_wifi.indexOf("%%F32") != -1) { // 슬라이드2, PWM 값 수신
String wifi_temp = income_wifi.substring(income_wifi.indexOf("%%F32")+5, income_wifi.indexOf("%%F1"));
pwm2 = wifi_temp.toInt();
Serial.print("pwm2: "); Serial.println(pwm2);
}
else if (income_wifi.indexOf("%%F33") != -1) { // 슬라이드3, PWM 값 수신
String wifi_temp = income_wifi.substring(income_wifi.indexOf("%%F33")+5, income_wifi.indexOf("%%F1"));
pwm3 = wifi_temp.toInt();
Serial.print("pwm3: "); Serial.println(pwm3);
}
}
else if (income_wifi.indexOf("%%F5") != -1) { // 스케쥴 접속확인 응답, 텍스트 및 로컬값 전송
client.println("HTTP/1.1 200 OK\r\n"); // 스케쥴 웹요청시 응답 헤더 "%%F5"
if (send_pin != "") { // 전송할 핀 상태 값이 있으면 "/ HTTP/1.1"
client.print(send_pin);
send_pin = "";
}
if (send_Pwm_echo != "") { // 전송할 PWM 상태(echo) 값이 있으면
client.print(send_Pwm_echo);
send_Pwm_echo = "";
}
if (send_Pwm_slide != "") { // 전송할 PWM 슬라이브 바 상태 값이 있으면
client.print(send_Pwm_slide);
send_Pwm_slide = "";
}
if (send_text != "") { // 전송할 텍스트가 있으면
client.print(send_text);
send_text = "";
}
}
else{
if (income_wifi.indexOf("%%F8") != -1) { // 날짜 및 시간 정보 수신
String wifi_temp = income_wifi.substring(income_wifi.indexOf("%%F8")+4, income_wifi.indexOf("\n"));
Serial.print("Date/Time: "); Serial.println(wifi_temp);
}
else if (income_wifi.indexOf("%%F9") != -1) { // 알람 설정값 수신
String wifi_temp = income_wifi.substring(income_wifi.indexOf("%%F9")+4, income_wifi.indexOf("\n"));
Serial.print("Alarm set: "); Serial.println(wifi_temp);
}
else { // 텍스트 시리얼 출력
String wifi_temp = income_wifi.substring(income_wifi.indexOf("GET /")+5, income_wifi.indexOf("HTTP/1.1")-1);
if (wifi_temp.indexOf("%20") != -1) { // 웹브라우저 공백문자 %20을 공백문자로 변경
String space = "%20";
String space_convert = " ";
wifi_temp.replace(space, space_convert);
}
Serial.println(wifi_temp);
}
}
income_wifi = "";
}
}
3. 와이파이: 아두이노 송신 -> 앱 수신
디지털 버튼: %%F0 + 스트링 값 + %%P1
PWM1 echo(pwm 값 확인): %%F31 + String + %%E1
PWM2 echo(pwm 값 확인): %%F32 + String + %%E1
PWM3 echo(pwm 값 확인): %%F33 + String + %%E1
PWM1 slide(슬라이드 위치 변경): %%F41 + String + %%S1
PWM2 slide(슬라이드 위치 변경): %%F42 + String + %%S1
PWM3 slide(슬라이드 위치 변경): %%F43 + String + %%S1
String send_pin = "";
String send_Pwm_echo = "";
String send_Pwm_slide = "";
void send_pin_echo(uint8_t pin_val){ // 디지털 버튼 상태값 전송
String s_temp ="";
s_temp += "%%F0";
s_temp += pin_val;
s_temp += "%%P1";
if (client.connected()) client.print(s_temp); // 사용자 웹요청 응답
else send_pin = s_temp; // 스케쥴 웹요청 응답
}
void send_pwm_echo(uint8_t slide, uint16_t pwm_val) { // PWM값 echo 전송
String s_temp ="";
s_temp += "%%F3";
s_temp += slide;
s_temp += pwm_val;
s_temp += "%%E1";
if (client.connected()) client.print(s_temp); // 사용자 웹요청 응답
else send_Pwm_echo = s_temp; // 스케쥴 웹요청 응답
}
void send_pwm_slide(uint8_t slide, uint16_t pwm_val) { // 슬라이더 상태값 전송
String s_temp ="";
s_temp += "%%F4";
s_temp += slide;
s_temp += pwm_val;
s_temp += "%%S1";
if (client.connected()) client.print(s_temp); // 사용자 웹요청 응답
else send_Pwm_slide = s_temp; // 스케쥴 웹요청 응답
}
4. 디지털 버튼 1byte number 값 (토글 버튼 on/off, 푸시버튼 down/up)
Button1 on: 11, off: 10 또는 down: 11, up: 10
Button2 on: 21, off: 20 또는 down: 21, up: 20
.
.
.
Button12 on: 121, off: 120 또는 down: 121, up: 120
Button13 down: 131, up: 130
Button14 down: 141, up: 140
Button15 down: 151, up: 150
Button16 down: 161, up: 160
5. PWM 1byte number 값: slide 번호
PWM 2byte number 값: PWM 값
- RGB LED 제어용 Color Picker 모드
색상 휠 상의 점을 드래그하거나 색상 휠의 특정 지점을 터치하면 그때의 색상 RGB 값을 송신하여 LED 제어
PWM 최대 최솟값 강제 고정: 0 ~ 255
PWM 라벨 강제 고정: Red / Green / Blue
- PWM 디지털 노브 모드
디지털 노브를 이용하여 PWM의 제어를 더 편하게 할 수 있습니다.
우측 1/2/3 버튼: 슬라이드 선택 버튼
좌측 + - 버튼: 미세조정 및 길게 누를 경우 빠르게 이동
- 아두이노 + 통신 모듈(HC-06 블루투스 2.0 CLASSIC / AT-09 블루투스 4.0 BLE)
#include <SoftwareSerial.h>
#define BT_rxPin 3 // Bluetooth RX -> 3(arduino TX)
#define BT_txPin 2 // Bluetooth TX -> 2(arduino RX)
SoftwareSerial btSerial(BT_txPin, BT_rxPin); // (arduino RX, arduino TX)
String s =""; // 시리얼 모니터 텍스트 제어용 변수
// 블루투스 앱 디지털 핀 제어용 변수
bool get_pin_val = false;
uint8_t pin_count = 0;
uint8_t pin_a[3] = {0, };
uint8_t pin_val;
// 블루투스 앱 PWM 제어용 변수
bool get_pwm_val = false;
uint8_t pwm_count = 0;
uint8_t pwm_a[5] = {0, };
uint16_t pwm1 = 0;
uint16_t pwm2 = 0;
uint16_t pwm3 = 0;
// 블루투스 앱 상태표시 변수
uint8_t pin_echo[] = {0xF0, 0, 0xF1};
uint8_t pwm_echo[] = {0xF3, 0, 0, 0, 0xF1};
uint8_t pwm_slide[] = {0xF4, 0, 0, 0, 0xF1};
void setup() {
Serial.begin(9600);
btSerial.begin(9600); //Bluetooth
}
void loop() {
btSerial_read(); // 블루투스 시리얼 읽기 함수
if(Serial.available()) { // 시리얼 버퍼에 데이터 있으면
char c = Serial.read();
if(c != '\n') {
s += c;
} else {
if(s == "on"){ // 시리얼 모니터 제어 led on
Serial.println("LED ON");
send_pin_echo(11); // 블루투스 앱 버튼 상태: on
btSerial.print("LED ON");
s = "";
}
else if(s == "off"){ // 시리얼 모니터 제어 led off
Serial.println("LED OFF");
send_pin_echo(10); // 블루투스 앱 버튼 상태: off
btSerial.print("LED OFF");
s = "";
}
else {
btSerial.println(s);
s = "";
}
}
}
}
void general_use() {
char text = btSerial.read(); // text value for some purpose.
Serial.write(text); // print text to Serial Monitor
}
void pin_control() {
pin_val = pin_a[1];
if (pin_val != 0) {
switch (pin_val) {
case 11: Serial.println("button 1 : on");
break;
case 10: Serial.println("button 1 : off");
break;
case 21: Serial.println("button 2 : on");
send_pin_echo(pin_val); // 버튼 상태 echo
break;
case 20: Serial.println("button 2 : off");
send_pin_echo(pin_val); // 버튼 상태 echo
break;
case 31: Serial.println("button 3 : on");
break;
case 30: Serial.println("button 3 : off");
break;
case 41: Serial.println("button 4 : on");
break;
case 40: Serial.println("button 4 : off");
break;
case 51: Serial.println("button 5 : on");
break;
case 50: Serial.println("button 5 : off");
break;
case 61: Serial.println("button 6 : on");
break;
case 60: Serial.println("button 6 : off");
break;
case 71: Serial.println("button 7 : on");
break;
case 70: Serial.println("button 7 : off");
break;
case 81: Serial.println("button 8 : on");
break;
case 80: Serial.println("button 8 : off");
break;
case 91: Serial.println("button 9 : on");
break;
case 90: Serial.println("button 9 : off");
break;
case 101: Serial.println("button 10 : on");
break;
case 100: Serial.println("button 10 : off");
break;
case 111: Serial.println("button 11 : on");
break;
case 110: Serial.println("button 11 : off");
break;
case 121: Serial.println("button 12 : on");
break;
case 120: Serial.println("button 12 : off");
break;
}
pin_val = 0;
}
}
void pwm_control() {
uint16_t temp = pwm_a[3];
temp = temp << 8 | pwm_a[2];
if (pwm_a[1] == 1) { // 슬라이드 1번
pwm1 = temp;
// send_pwm_echo(1, pwm1); // PWM 값 echo
Serial.print("pwm1: "); Serial.println(pwm1);
}
else if (pwm_a[1] == 2) { // 슬라이드 2번
pwm2 = temp;
Serial.print("pwm2: "); Serial.println(pwm2);
}
else if (pwm_a[1] == 3) { // 슬라이드 3번
pwm3 = temp;
Serial.print("pwm3: "); Serial.println(pwm3);
}
}
void btSerial_read() {
if (btSerial.available()) {
if (btSerial.peek() == 0xF3) get_pwm_val = true;
else if (btSerial.peek() == 0xF0) get_pin_val = true;
if (get_pwm_val == true ) { // pwm 제어값 수신
uint8_t temp = btSerial.read();
pwm_a[pwm_count] = temp;
pwm_count++;
if (temp == 0xF1) {
get_pwm_val = false;
pwm_count = 0;
pwm_control();
}
}
else if (get_pin_val == true) { // 디지털 핀 제어값 수신
uint8_t temp = btSerial.read();
pin_a[pin_count] = temp;
pin_count++;
if (temp == 0xF1) {
get_pin_val = false;
pin_count = 0;
pin_control();
}
}
else {
if (btSerial.peek() == 0xF8) {
String temp = btSerial.readStringUntil('\n');
Serial.println(temp);
}
else if (btSerial.peek() == 0xF9) {
String temp = btSerial.readStringUntil('\n');
Serial.println(temp);
}
else {
general_use(); // 텍스트 출력함수
}
}
}
}
void send_pin_echo(uint8_t pin_val){
pin_echo[1] = pin_val;
for (int i = 0; i < 3; i++) {
btSerial.write(pin_echo[i]);
}
}
void send_pwm_echo(uint8_t slide, uint16_t pwm_val) {
pwm_echo[1] = slide;
if (pwm_val < 256) {
pwm_echo[2] = pwm_val;
pwm_echo[3] = 0;
}
else {
pwm_echo[2] = pwm_val;
pwm_echo[3] = pwm_val >> 8;
}
for (int i = 0; i < 5; i++) {
btSerial.write(pwm_echo[i]);
}
}
void send_pwm_slide(uint8_t slide, uint16_t pwm_val) {
pwm_slide[1] = slide;
if (pwm_val < 256) {
pwm_slide[2] = pwm_val;
pwm_slide[3] = 0;
}
else {
pwm_slide[2] = pwm_val;
pwm_slide[3] = pwm_val >> 8;
}
for (int i = 0; i < 5; i++) {
btSerial.write(pwm_slide[i]);
}
}
- ESP8266, NodeMcu wifi_Soft_AP
#include <ESP8266WiFi.h>
#define AP_SSID "Esp12"
#define AP_PASS "1234test"
String s =""; // 시리얼 모니터 텍스트 제어용 변수
// 디지털 핀 제어용 변수
uint8_t pin_val = 0;
// PWM 제어용 변수
uint16_t pwm1 = 0;
uint16_t pwm2 = 0;
uint16_t pwm3 = 0;
String income_wifi = ""; // 와이파이 수신 스트링 저장 변수
// 웹요청 응답용 변수
String send_pin = "";
String send_Pwm_echo = "";
String send_Pwm_slide = "";
String send_text = "";
WiFiServer server(80);
WiFiClient client;
void setup() {
Serial.begin(115200);
WiFi.softAP(AP_SSID, AP_PASS); // WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.begin();
}
void loop() {
wifi_delay(); // 와이파이 데이터 읽기
if (Serial.available()) {
char c = Serial.read();
if(c != '\n') {
s += c;
} else {
if(s == "on"){ // 시리얼 모니터 제어 led on
Serial.println("LED_ON");
send_pin_echo(11); // 스케쥴 웹요청 응답, 블루투스 앱 버튼 상태: on
send_text = "LED ON"; // 스케쥴 웹요청 응답
s = "";
}
else if(s == "off"){ // 시리얼 모니터 제어 led off
Serial.println("LED_OFF");
send_pin_echo(10); // 스케쥴 웹요청 응답, 블루투스 앱 버튼 상태: off
send_text = "LED OFF"; // 스케쥴 웹요청 응답
s = "";
}
else {
send_text = s; // 스케쥴 웹요청시 응답변수에 저장
s = "";
}
}
}
}
void pin_control() {
if (pin_val != 0) {
switch (pin_val) {
case 11: Serial.println("button 1 : on"); // button 1 : on
client.println("HTTP/1.1 200 OK\r\n"); // 사용자 웹요청시 응답 헤더
send_pin_echo(pin_val);
client.print("LED_ON_11");
break;
case 10: Serial.println("button 1 : off"); // button 1 : off
client.println("HTTP/1.1 200 OK\r\n"); // 사용자 웹요청시 응답 헤더
send_pin_echo(pin_val);
client.print("LED_ON_10");
break;
case 21: Serial.println("button 2 : on");
break;
case 20: Serial.println("button 2 : off");
break;
case 31: Serial.println("button 3 : on");
break;
case 30: Serial.println("button 3 : off");
break;
case 41: Serial.println("button 4 : on");
break;
case 40: Serial.println("button 4 : off");
break;
case 51: Serial.println("button 5 : on");
break;
case 50: Serial.println("button 5 : off");
break;
case 61: Serial.println("button 6 : on");
break;
case 60: Serial.println("button 6 : off");
break;
case 71: Serial.println("button 7 : on");
break;
case 70: Serial.println("button 7 : off");
break;
case 81: Serial.println("button 8 : on");
break;
case 80: Serial.println("button 8 : off");
break;
case 91: Serial.println("button 9 : on");
break;
case 90: Serial.println("button 9 : off");
break;
case 101: Serial.println("button 10 : on");
break;
case 100: Serial.println("button 10 : off");
break;
case 111: Serial.println("button 11 : on");
break;
case 110: Serial.println("button 11 : off");
break;
case 121: Serial.println("button 12 : on");
break;
case 120: Serial.println("button 12 : off");
break;
}
pin_val = 0;
}
}
unsigned long int one_millis = 0;
void wifi_delay() { // 30 밀리초 마다 client 연결 확인 및 데이터 수신
if (millis() - one_millis > 30) {
one_millis = millis();
wifi_read();
}
}
void wifi_read() { // wifi 데이터 수신
client = server.available(); // 서버가 작동하고 있으면 client 생성
if(client.available()) { // 클라이언트에 데이터가 있으면
income_wifi = client.readStringUntil('\r');
if (income_wifi.indexOf("%%F1") != -1) { // 종료문자가 있으면
if (income_wifi.indexOf("%%F0") != -1) { // 디지털 핀 값 수신
String wifi_temp = income_wifi.substring(income_wifi.indexOf("%%F0")+4, income_wifi.indexOf("%%F1"));
pin_val = wifi_temp.toInt();
pin_control();
}
else if (income_wifi.indexOf("%%F31") != -1) { // 슬라이드1, PWM 값 수신
String wifi_temp = income_wifi.substring(income_wifi.indexOf("%%F31")+5, income_wifi.indexOf("%%F1"));
pwm1 = wifi_temp.toInt();
Serial.print("pwm1: "); Serial.println(pwm1);
}
else if (income_wifi.indexOf("%%F32") != -1) { // 슬라이드2, PWM 값 수신
String wifi_temp = income_wifi.substring(income_wifi.indexOf("%%F32")+5, income_wifi.indexOf("%%F1"));
pwm2 = wifi_temp.toInt();
Serial.print("pwm2: "); Serial.println(pwm2);
}
else if (income_wifi.indexOf("%%F33") != -1) { // 슬라이드3, PWM 값 수신
String wifi_temp = income_wifi.substring(income_wifi.indexOf("%%F33")+5, income_wifi.indexOf("%%F1"));
pwm3 = wifi_temp.toInt();
Serial.print("pwm3: "); Serial.println(pwm3);
}
}
else if (income_wifi.indexOf("%%F5") != -1) { // 스케쥴 접속확인 응답, 텍스트 및 로컬값 전송
client.println("HTTP/1.1 200 OK\r\n"); // 스케쥴 웹요청시 응답 헤더 "%%F5"
if (send_pin != "") { // 전송할 핀 상태 값이 있으면 "/ HTTP/1.1"
client.print(send_pin);
send_pin = "";
}
if (send_Pwm_echo != "") { // 전송할 PWM 상태(echo) 값이 있으면
client.print(send_Pwm_echo);
send_Pwm_echo = "";
}
if (send_Pwm_slide != "") { // 전송할 PWM 슬라이브 바 상태 값이 있으면
client.print(send_Pwm_slide);
send_Pwm_slide = "";
}
if (send_text != "") { // 전송할 텍스트가 있으면
client.print(send_text);
send_text = "";
}
}
else{
if (income_wifi.indexOf("%%F8") != -1) { // 슬라이드3, PWM 값 수신
String wifi_temp = income_wifi.substring(income_wifi.indexOf("%%F8")+4, income_wifi.indexOf("\n"));
Serial.print("Date/Time: "); Serial.println(wifi_temp);
}
else if (income_wifi.indexOf("%%F9") != -1) { // 슬라이드3, PWM 값 수신
String wifi_temp = income_wifi.substring(income_wifi.indexOf("%%F9")+4, income_wifi.indexOf("\n"));
Serial.print("Alarm set: "); Serial.println(wifi_temp);
}
else { // 텍스트 시리얼 출력
String wifi_temp = income_wifi.substring(income_wifi.indexOf("GET /")+5, income_wifi.indexOf("HTTP/1.1")-1);
if (wifi_temp.indexOf("%20") != -1) { // 웹브라우저 공백문자 %20을 공백문자로 변경
String space = "%20";
String space_convert = " ";
wifi_temp.replace(space, space_convert);
}
Serial.println(wifi_temp);
}
}
income_wifi = "";
}
}
void send_pin_echo(uint8_t pin_val){ // 디지털 버튼 상태값 전송
String s_temp ="";
s_temp += "%%F0";
s_temp += pin_val;
s_temp += "%%P1";
if (client.connected()) client.print(s_temp); // 사용자 웹요청 응답
else send_pin = s_temp; // 스케쥴 웹요청 응답
}
void send_pwm_echo(uint8_t slide, uint16_t pwm_val) { // PWM값 echo 전송
String s_temp ="";
s_temp += "%%F3";
s_temp += slide;
s_temp += pwm_val;
s_temp += "%%E1";
if (client.connected()) client.print(s_temp); // 사용자 웹요청 응답
else send_Pwm_echo = s_temp; // 스케쥴 웹요청 응답
}
void send_pwm_slide(uint8_t slide, uint16_t pwm_val) { // 슬라이더 상태값 전송
String s_temp ="";
s_temp += "%%F4";
s_temp += slide;
s_temp += pwm_val;
s_temp += "%%S1";
if (client.connected()) client.print(s_temp); // 사용자 웹요청 응답
else send_Pwm_slide = s_temp; // 스케쥴 웹요청 응답
}
- ESP32 DevKit Blutooth 2.0
#include "BluetoothSerial.h"
BluetoothSerial SerialBT;
String s =""; // 시리얼 모니터 텍스트 제어용 변수
// 블루투스 앱 디지털 핀 제어용 변수
bool get_pin_val = false;
uint8_t pin_count = 0;
uint8_t pin_a[3] = {0, };
uint8_t pin_val;
// 블루투스 앱 PWM 제어용 변수
bool get_pwm_val = false;
uint8_t pwm_count = 0;
uint8_t pwm_a[5] = {0, };
uint16_t pwm1 = 0;
uint16_t pwm2 = 0;
uint16_t pwm3 = 0;
// 블루투스 앱 상태표시 변수
uint8_t pin_echo[] = {0xF0, 0, 0xF1};
uint8_t pwm_echo[] = {0xF3, 0, 0, 0, 0xF1};
uint8_t pwm_slide[] = {0xF4, 0, 0, 0, 0xF1};
void setup() {
Serial.begin(115200);
SerialBT.begin("ESP32test"); //Bluetooth device name
}
void loop() {
SerialBT_read(); // 블루투스 시리얼 읽기 함수
if(Serial.available()) { // 시리얼 버퍼에 데이터 있으면
char c = Serial.read();
if(c != '\n') {
s += c;
} else {
if(s == "on"){ // 시리얼 모니터 제어 led on
Serial.println("LED ON");
send_pin_echo(11); // 블루투스 앱 버튼 상태: on
SerialBT.print("LED ON");
s = "";
}
else if(s == "off"){ // 시리얼 모니터 제어 led off
Serial.println("LED OFF");
send_pin_echo(10); // 블루투스 앱 버튼 상태: off
SerialBT.print("LED OFF");
s = "";
}
else {
SerialBT.println(s);
s = "";
}
}
}
}
void general_use() {
char text = SerialBT.read(); // text value for some purpose.
Serial.write(text); // print text to Serial Monitor
}
void pin_control() {
pin_val = pin_a[1];
if (pin_val != 0) {
switch (pin_val) {
case 11: Serial.println("button 1 : on");
break;
case 10: Serial.println("button 1 : off");
break;
case 21: Serial.println("button 2 : on");
send_pin_echo(pin_val); // 버튼 상태 echo
break;
case 20: Serial.println("button 2 : off");
send_pin_echo(pin_val); // 버튼 상태 echo
break;
case 31: Serial.println("button 3 : on");
break;
case 30: Serial.println("button 3 : off");
break;
case 41: Serial.println("button 4 : on");
break;
case 40: Serial.println("button 4 : off");
break;
case 51: Serial.println("button 5 : on");
break;
case 50: Serial.println("button 5 : off");
break;
case 61: Serial.println("button 6 : on");
break;
case 60: Serial.println("button 6 : off");
break;
case 71: Serial.println("button 7 : on");
break;
case 70: Serial.println("button 7 : off");
break;
case 81: Serial.println("button 8 : on");
break;
case 80: Serial.println("button 8 : off");
break;
case 91: Serial.println("button 9 : on");
break;
case 90: Serial.println("button 9 : off");
break;
case 101: Serial.println("button 10 : on");
break;
case 100: Serial.println("button 10 : off");
break;
case 111: Serial.println("button 11 : on");
break;
case 110: Serial.println("button 11 : off");
break;
case 121: Serial.println("button 12 : on");
break;
case 120: Serial.println("button 12 : off");
break;
}
pin_val = 0;
}
}
void pwm_control() {
uint16_t temp = pwm_a[3];
temp = temp << 8 | pwm_a[2];
if (pwm_a[1] == 1) { // 슬라이드 1번
pwm1 = temp;
// send_pwm_echo(1, pwm1); // PWM 값 echo
Serial.print("pwm1: "); Serial.println(pwm1);
}
else if (pwm_a[1] == 2) { // 슬라이드 2번
pwm2 = temp;
Serial.print("pwm2: "); Serial.println(pwm2);
}
else if (pwm_a[1] == 3) { // 슬라이드 3번
pwm3 = temp;
Serial.print("pwm3: "); Serial.println(pwm3);
}
}
void SerialBT_read() {
if (SerialBT.available()) {
if (SerialBT.peek() == 0xF3) get_pwm_val = true;
else if (SerialBT.peek() == 0xF0) get_pin_val = true;
if (get_pwm_val == true ) { // pwm 제어값 수신
uint8_t temp = SerialBT.read();
pwm_a[pwm_count] = temp;
pwm_count++;
if (temp == 0xF1) {
get_pwm_val = false;
pwm_count = 0;
pwm_control();
}
}
else if (get_pin_val == true) { // 디지털 핀 제어값 수신
uint8_t temp = SerialBT.read();
pin_a[pin_count] = temp;
pin_count++;
if (temp == 0xF1) {
get_pin_val = false;
pin_count = 0;
pin_control();
}
}
else {
if (SerialBT.peek() == 0xF8) {
String temp = SerialBT.readStringUntil('\n');
Serial.println(temp);
}
else if (SerialBT.peek() == 0xF9) {
String temp = SerialBT.readStringUntil('\n');
Serial.println(temp);
}
else {
general_use(); // 텍스트 출력함수
}
}
}
}
void send_pin_echo(uint8_t pin_val){
pin_echo[1] = pin_val;
for (int i = 0; i < 3; i++) {
SerialBT.write(pin_echo[i]);
}
}
void send_pwm_echo(uint8_t slide, uint16_t pwm_val) {
pwm_echo[1] = slide;
if (pwm_val < 256) {
pwm_echo[2] = pwm_val;
pwm_echo[3] = 0;
}
else {
pwm_echo[2] = pwm_val;
pwm_echo[3] = pwm_val >> 8;
}
for (int i = 0; i < 5; i++) {
SerialBT.write(pwm_echo[i]);
}
}
void send_pwm_slide(uint8_t slide, uint16_t pwm_val) {
pwm_slide[1] = slide;
if (pwm_val < 256) {
pwm_slide[2] = pwm_val;
pwm_slide[3] = 0;
}
else {
pwm_slide[2] = pwm_val;
pwm_slide[3] = pwm_val >> 8;
}
for (int i = 0; i < 5; i++) {
SerialBT.write(pwm_slide[i]);
}
}
- ESP32 DevKit Blutooth 4.0 BLE
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
BLEServer *pServer = NULL;
BLECharacteristic * pTxCharacteristic;
bool deviceConnected = false;
bool rx_received = false; // BLE 수신시 함수 실행 플래그
std::string rxValue; // BLE 클래스 수신 데이터 값 전역변수 설정
#define SERVICE_UUID "0000FFE0-0000-1000-8000-00805F9B34FB" // UART service UUID
#define CHARACTERISTIC_UUID_RX "0000FFE1-0000-1000-8000-00805F9B34FB"
#define CHARACTERISTIC_UUID_TX "0000FFE2-0000-1000-8000-00805F9B34FB"
String s =""; // 시리얼 모니터 텍스트 제어용 변수
// 블루투스 앱 디지털 핀 제어용 변수
bool get_pin_val = false;
uint8_t pin_a[3] = {0, };
uint8_t pin_val;
// 블루투스 앱 PWM 제어용 변수
bool get_pwm_val = false;
uint8_t pwm_a[5] = {0, };
uint16_t pwm1 = 0;
uint16_t pwm2 = 0;
uint16_t pwm3 = 0;
// 블루투스 앱 상태표시 변수
uint8_t pin_echo[] = {0xF0, 0, 0xF1};
uint8_t pwm_echo[] = {0xF3, 0, 0, 0, 0xF1};
uint8_t pwm_slide[] = {0xF4, 0, 0, 0, 0xF1};
bool date_time = false;
bool alarm_set = false;
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
pServer->getAdvertising()->start();
}
};
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
rxValue = pCharacteristic->getValue();
// if (rxValue.length() > 0) {
// for (int i = 0; i < rxValue.length(); i++) {
// Serial.print(i); Serial.print(": "); Serial.println(rxValue[i], HEX);
// }
// }
rx_received = true;
}
};
void setup() {
Serial.begin(115200);
BLEDevice::init("ESP32 BLE"); // Create the BLE Device
pServer = BLEDevice::createServer(); // Create the BLE Server
pServer->setCallbacks(new MyServerCallbacks());
BLEService *pService = pServer->createService(SERVICE_UUID); // Create the BLE Service
pTxCharacteristic = pService->createCharacteristic ( // Create a BLE Characteristic
CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_NOTIFY
);
pTxCharacteristic->addDescriptor(new BLE2902());
BLECharacteristic * pRxCharacteristic = pService->createCharacteristic (
CHARACTERISTIC_UUID_RX,
BLECharacteristic::PROPERTY_WRITE
);
pRxCharacteristic->setCallbacks(new MyCallbacks());
pService->start(); // Start the service
pServer->getAdvertising()->start(); // Start advertising
Serial.println("Waiting a client connection to notify...");
}
void loop() {
BLE_read();
if(Serial.available()) { // 시리얼 버퍼에 데이터 있으면
char c = Serial.read();
if(c != '\n') {
s += c;
} else {
if(s == "on"){ // 시리얼 모니터 제어 led on
Serial.println("LED ON");
send_pin_echo(11); // 블루투스 앱 버튼 상태: on
pTxCharacteristic->setValue("LED ON");
pTxCharacteristic->notify();
s = "";
}
else if(s == "off"){ // 시리얼 모니터 제어 led off
Serial.println("LED OFF");
send_pin_echo(10); // 블루투스 앱 버튼 상태: off
pTxCharacteristic->setValue("LED OFF");
pTxCharacteristic->notify();
s = "";
}
else {
char temp [21];
s.toCharArray(temp, s.length()+1);
pTxCharacteristic->setValue(temp);
pTxCharacteristic->notify();
s = "";
}
}
}
}
void general_use() {
for (int i = 0; i < rxValue.length(); i++) Serial.write(rxValue[i]);
}
void pin_control() {
pin_val = pin_a[1];
if (pin_val != 0) {
switch (pin_val) {
case 11: Serial.println("button 1 : on");
break;
case 10: Serial.println("button 1 : off");
break;
case 21: Serial.println("button 2 : on");
send_pin_echo(pin_val); // 버튼 상태 echo
break;
case 20: Serial.println("button 2 : off");
send_pin_echo(pin_val); // 버튼 상태 echo
break;
case 31: Serial.println("button 3 : on");
break;
case 30: Serial.println("button 3 : off");
break;
case 41: Serial.println("button 4 : on");
break;
case 40: Serial.println("button 4 : off");
break;
case 51: Serial.println("button 5 : on");
break;
case 50: Serial.println("button 5 : off");
break;
case 61: Serial.println("button 6 : on");
break;
case 60: Serial.println("button 6 : off");
break;
case 71: Serial.println("button 7 : on");
break;
case 70: Serial.println("button 7 : off");
break;
case 81: Serial.println("button 8 : on");
break;
case 80: Serial.println("button 8 : off");
break;
case 91: Serial.println("button 9 : on");
break;
case 90: Serial.println("button 9 : off");
break;
case 101: Serial.println("button 10 : on");
break;
case 100: Serial.println("button 10 : off");
break;
case 111: Serial.println("button 11 : on");
break;
case 110: Serial.println("button 11 : off");
break;
case 121: Serial.println("button 12 : on");
break;
case 120: Serial.println("button 12 : off");
break;
}
pin_val = 0;
}
}
void pwm_control() {
uint16_t temp = pwm_a[3];
temp = temp << 8 | pwm_a[2];
if (pwm_a[1] == 1) { // 슬라이드 1번
pwm1 = temp;
// send_pwm_echo(1, pwm1); // PWM 값 echo
Serial.print("pwm1: "); Serial.println(pwm1);
}
else if (pwm_a[1] == 2) { // 슬라이드 2번
pwm2 = temp;
Serial.print("pwm2: "); Serial.println(pwm2);
}
else if (pwm_a[1] == 3) { // 슬라이드 3번
pwm3 = temp;
Serial.print("pwm3: "); Serial.println(pwm3);
}
}
void BLE_read() {
if (rx_received == true) {
if (rxValue[0] == 0xF0) get_pin_val = true;
else if (rxValue[0] == 0xF3) get_pwm_val = true;
if (get_pin_val == true) { // 디지털 핀 제어값 수신
pin_a[0] = rxValue[0];
pin_a[1] = rxValue[1];
pin_a[2] = rxValue[2];
if (pin_a[0] == 0xF0 && pin_a[2] == 0xF1) { // 수신값 검증 완료시
pin_control(); // 디지털 핀 출력함수 실행}
}
get_pin_val = false;
}
else if (get_pwm_val == true) { // pwm 제어값 수신
pwm_a[0] = rxValue[0];
pwm_a[1] = rxValue[1];
pwm_a[2] = rxValue[2];
pwm_a[3] = rxValue[3];
pwm_a[4] = rxValue[4];
if (pwm_a[0] == 0xF3 && pwm_a[4] == 0xF1) { // 수신값 검증 완료시
pwm_control(); // PWM 출력함수 실행
}
get_pwm_val = false;
}
else {
if (rxValue[0] == 0xF8) date_time = true;
else if (rxValue[0] == 0xF9) alarm_set = true;
if (date_time == true) {
String temp = "";
for (int i = 0; i < rxValue.length(); i++) {
if (rxValue[i] != '\n') temp += rxValue[i];
else break;
}
Serial.println(temp);
}
else if (alarm_set == true) {
String temp = "";
for (int i = 0; i < rxValue.length(); i++) {
if (rxValue[i] != '\n') temp += rxValue[i];
else break;
}
Serial.println(temp);
}
else {
general_use(); // 텍스트 출력함수
}
}
rx_received = false;
}
}
void send_pin_echo(uint8_t pin_val){
pin_echo[1] = pin_val;
pTxCharacteristic->setValue((uint8_t*)&pin_echo, 3);
pTxCharacteristic->notify();
}
void send_pwm_echo(uint8_t slide, uint16_t pwm_val) {
pwm_echo[1] = slide;
if (pwm_val < 256) {
pwm_echo[2] = pwm_val;
pwm_echo[3] = 0;
}
else {
pwm_echo[2] = pwm_val;
pwm_echo[3] = pwm_val >> 8;
}
pTxCharacteristic->setValue((uint8_t*)&pwm_echo, 5);
pTxCharacteristic->notify();
}
void send_pwm_slide(uint8_t slide, uint16_t pwm_val) {
pwm_slide[1] = slide;
if (pwm_val < 256) {
pwm_slide[2] = pwm_val;
pwm_slide[3] = 0;
}
else {
pwm_slide[2] = pwm_val;
pwm_slide[3] = pwm_val >> 8;
}
pTxCharacteristic->setValue((uint8_t*)&pwm_slide, 5);
pTxCharacteristic->notify();
}
- ESP32 DevKit wifi_Soft_AP
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>
#define AP_SSID "Esp32"
#define AP_PASS "1234test"
String s =""; // 시리얼 모니터 텍스트 제어용 변수
// 디지털 핀 제어용 변수
uint8_t pin_val = 0;
// PWM 제어용 변수
uint16_t pwm1 = 0;
uint16_t pwm2 = 0;
uint16_t pwm3 = 0;
String income_wifi = ""; // 와이파이 수신 스트링 저장 변수
// 웹요청 응답용 변수
String send_pin = "";
String send_Pwm_echo = "";
String send_Pwm_slide = "";
String send_text = "";
WiFiServer server(80);
WiFiClient client;
void setup() {
Serial.begin(115200);
WiFi.softAP(AP_SSID, AP_PASS);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.begin();
}
void loop() {
wifi_delay(); // 와이파이 데이터 읽기
if (Serial.available()) {
char c = Serial.read();
if(c != '\n') {
s += c;
} else {
if(s == "on"){ // 시리얼 모니터 제어 led on
Serial.println("LED ON");
send_pin_echo(11); // 스케쥴 웹요청 응답, 블루투스 앱 버튼 상태: on
send_text = "LED ON"; // 스케쥴 웹요청 응답
s = "";
}
else if(s == "off"){ // 시리얼 모니터 제어 led off
Serial.println("LED OFF");
send_pin_echo(10); // 스케쥴 웹요청 응답, 블루투스 앱 버튼 상태: off
send_text = "LED OFF"; // 스케쥴 웹요청 응답
s = "";
}
else {
send_text = s; // 스케쥴 웹요청시 응답변수에 저장
s = "";
}
}
}
}
void pin_control() {
if (pin_val != 0) {
switch (pin_val) {
case 11: Serial.println("button 1 : on");
client.println("HTTP/1.1 200 OK\r\n"); // 사용자 웹요청시 응답 헤더
send_pin_echo(pin_val);
client.print("LED_ON_11");
break;
case 10: Serial.println("button 1 : off");
client.println("HTTP/1.1 200 OK\r\n"); // 사용자 웹요청시 응답 헤더
send_pin_echo(pin_val);
client.print("LED_ON_10");
break;
case 21: Serial.println("button 2 : on");
break;
case 20: Serial.println("button 2 : off");
break;
case 31: Serial.println("button 3 : on");
break;
case 30: Serial.println("button 3 : off");
break;
case 41: Serial.println("button 4 : on");
break;
case 40: Serial.println("button 4 : off");
break;
case 51: Serial.println("button 5 : on");
break;
case 50: Serial.println("button 5 : off");
break;
case 61: Serial.println("button 6 : on");
break;
case 60: Serial.println("button 6 : off");
break;
case 71: Serial.println("button 7 : on");
break;
case 70: Serial.println("button 7 : off");
break;
case 81: Serial.println("button 8 : on");
break;
case 80: Serial.println("button 8 : off");
break;
case 91: Serial.println("button 9 : on");
break;
case 90: Serial.println("button 9 : off");
break;
case 101: Serial.println("button 10 : on");
break;
case 100: Serial.println("button 10 : off");
break;
case 111: Serial.println("button 11 : on");
break;
case 110: Serial.println("button 11 : off");
break;
case 121: Serial.println("button 12 : on");
break;
case 120: Serial.println("button 12 : off");
break;
}
pin_val = 0;
}
}
unsigned long int one_millis = 0;
void wifi_delay() { // 30 밀리초 마다 client 연결 확인 및 데이터 수신
if (millis() - one_millis > 30) {
one_millis = millis();
wifi_read();
}
}
void wifi_read() { // wifi 데이터 수신
client = server.available(); // 서버가 작동하고 있으면 client 생성
if(client.available()) { // 클라이언트에 데이터가 있으면
income_wifi = client.readStringUntil('\r');
if (income_wifi.indexOf("%%F1") != -1) { // 종료문자가 있으면
if (income_wifi.indexOf("%%F0") != -1) { // 디지털 핀 값 수신
String wifi_temp = income_wifi.substring(income_wifi.indexOf("%%F0")+4, income_wifi.indexOf("%%F1"));
pin_val = wifi_temp.toInt();
pin_control();
}
else if (income_wifi.indexOf("%%F31") != -1) { // 슬라이드1, PWM 값 수신
String wifi_temp = income_wifi.substring(income_wifi.indexOf("%%F31")+5, income_wifi.indexOf("%%F1"));
pwm1 = wifi_temp.toInt();
Serial.print("pwm1: "); Serial.println(pwm1);
}
else if (income_wifi.indexOf("%%F32") != -1) { // 슬라이드2, PWM 값 수신
String wifi_temp = income_wifi.substring(income_wifi.indexOf("%%F32")+5, income_wifi.indexOf("%%F1"));
pwm2 = wifi_temp.toInt();
Serial.print("pwm2: "); Serial.println(pwm2);
}
else if (income_wifi.indexOf("%%F33") != -1) { // 슬라이드3, PWM 값 수신
String wifi_temp = income_wifi.substring(income_wifi.indexOf("%%F33")+5, income_wifi.indexOf("%%F1"));
pwm3 = wifi_temp.toInt();
Serial.print("pwm3: "); Serial.println(pwm3);
}
}
else if (income_wifi.indexOf("%%F5") != -1) { // 스케쥴 접속확인 응답, 텍스트 및 로컬값 전송
client.println("HTTP/1.1 200 OK\r\n"); // 스케쥴 웹요청시 응답 헤더 "%%F5"
if (send_pin != "") { // 전송할 핀 상태 값이 있으면 "/ HTTP/1.1"
client.print(send_pin);
send_pin = "";
}
if (send_Pwm_echo != "") { // 전송할 PWM 상태(echo) 값이 있으면
client.print(send_Pwm_echo);
send_Pwm_echo = "";
}
if (send_Pwm_slide != "") { // 전송할 PWM 슬라이브 바 상태 값이 있으면
client.print(send_Pwm_slide);
send_Pwm_slide = "";
}
if (send_text != "") { // 전송할 텍스트가 있으면
client.print(send_text);
send_text = "";
}
}
else{
if (income_wifi.indexOf("%%F8") != -1) { // 슬라이드3, PWM 값 수신
String wifi_temp = income_wifi.substring(income_wifi.indexOf("%%F8")+4, income_wifi.indexOf("\n"));
Serial.print("Date/Time: "); Serial.println(wifi_temp);
}
else if (income_wifi.indexOf("%%F9") != -1) { // 슬라이드3, PWM 값 수신
String wifi_temp = income_wifi.substring(income_wifi.indexOf("%%F9")+4, income_wifi.indexOf("\n"));
Serial.print("Alarm set: "); Serial.println(wifi_temp);
}
else { // 텍스트 시리얼 출력
String wifi_temp = income_wifi.substring(income_wifi.indexOf("GET /")+5, income_wifi.indexOf("HTTP/1.1")-1);
if (wifi_temp.indexOf("%20") != -1) { // 웹브라우저 공백문자 %20을 공백문자로 변경
String space = "%20";
String space_convert = " ";
wifi_temp.replace(space, space_convert);
}
Serial.println(wifi_temp);
}
}
income_wifi = "";
client.stop();
}
}
void send_pin_echo(uint8_t pin_val){ // 디지털 버튼 상태값 전송
String s_temp ="";
s_temp += "%%F0";
s_temp += pin_val;
s_temp += "%%P1";
if (client.connected()) client.print(s_temp); // 사용자 웹요청 응답
else send_pin = s_temp; // 스케쥴 웹요청 응답
}
void send_pwm_echo(uint8_t slide, uint16_t pwm_val) { // PWM값 echo 전송
String s_temp ="";
s_temp += "%%F3";
s_temp += slide;
s_temp += pwm_val;
s_temp += "%%E1";
if (client.connected()) client.print(s_temp); // 사용자 웹요청 응답
else send_Pwm_echo = s_temp; // 스케쥴 웹요청 응답
}
void send_pwm_slide(uint8_t slide, uint16_t pwm_val) { // 슬라이더 상태값 전송
String s_temp ="";
s_temp += "%%F4";
s_temp += slide;
s_temp += pwm_val;
s_temp += "%%S1";
if (client.connected()) client.print(s_temp); // 사용자 웹요청 응답
else send_Pwm_slide = s_temp; // 스케쥴 웹요청 응답
}
arduino bluetooth controller PWM v3.5 사용 예제 글
[arduino] - 아두이노 - 안드로이드를 이용한 무선 원격제어 그리고 시리얼 통신 - 1편
[arduino] - 아두이노 - 안드로이드를 이용한 무선 원격제어 그리고 시리얼 통신 - 2편
[arduino] - 아두이노 - 안드로이드를 이용한 무선 원격제어 그리고 시리얼 통신 - 3편
[arduino] - 아두이노 - 안드로이드를 이용한 무선 원격제어 그리고 시리얼 통신 - 4편
[arduino] - 아두이노 - 안드로이드를 이용한 무선 원격제어 그리고 시리얼 통신 - 5편
[arduino] - 블루투스 4.0 BLE 이용 아두이노 및 ESP32 원격제어
[arduino] - 아두이노 - 시리얼통신 주요함수와 예제, String class
[arduino] - 아두이노 - ESP01 wifi 모듈 무선 원격제어 그리고 시리얼 통신 - 6편
[arduino] - ESP8266 - NodeMcu 1.0 와이파이 이용 원격제어(soft AP, wifi)
[arduino] - ESP32 - Dev Module 와이파이 이용 원격제어(soft AP, wifi)
최신 버전 유료앱(광고 제거)
https://play.google.com/store/apps/details?id=com.tistory.postpop.hmi
※ 특징
- 블루투스 2.0 / 블루투스 4.0 BLE 연결 : HC-05, HC-06, HM-10, AT-09, BT05
- WiFi를 통해 모듈의 Access Point 또는 공용 네트워크의 IP에 연결
- 15개의 디지털 버튼: 토글 및 푸시 버튼 속성 설정
- 6개의 아날로그 컨트롤러(SeekBar): 최소 및 최대 값 설정
- 메인 화면 표시 설정
- 버튼 레이블 사용자 정의
- 설정값 저장 기능
- RGB LED 제어를 위한 색상 선택기
- PWM 제어를 위한 다이얼 노브
- Arduino Sketch의 HTML 페이지용 웹 뷰어
- 비밀번호를 이용하여 제어권한을 설정할 수 있는 대화창 제공
- 사용자 정의 대화창 제공(라디오박스, 체크박스, 텍스트 입력 등)
- 앱이 실행되는 동안 화면이 계속 켜져 있음(화면이 꺼지는 것을 방지)
[Arduino] - Setting up Wi-Fi module ESP01 and basic code for Arduino remote control
[Arduino/ADUCON] - Arduino WiFi remote control with ADUCON and ESP-01
[Arduino] - Arduino Basic code for bluetooth remote contol with HC-06
[Arduino/ADUCON] - Arduino Bluetooth remote control with ADUCON and HC-06
[Arduino] - Arduino Basic code for BLE remote contol with BT05
[Arduino/ADUCON] - Arduino BLE remote control with ADUCON and BT05
[Arduino] - ESP32/NodeMcu Basic code for WiFi remote contol
[Arduino/ADUCON] - ESP32/NodeMcu WiFi remote control with ADUCON
[Arduino/ADUCON] - ESP32 Bluetooth remote control with ADUCON
[Arduino/ADUCON] - ESP32 BLE remote control with ADUCON
https://play.google.com/store/apps/details?id=io.kodular.skyship72.pad01
- 조이스틱 2개.
- 1개의 중력 센서 컨트롤러.
- 제어용 20개 버튼: 토글 및 푸시 버튼 속성 설정 기능.
일부 버튼 레이블은 사용자 정의할 수 있습니다.
- 비밀번호를 이용하여 제어권한을 설정할 수 있는 대화창 제공
- 사용자 정의 대화창 제공(라디오박스, 체크박스, 텍스트 입력 등)
- 앱이 실행되는 동안 화면이 계속 켜져 있음(화면이 꺼지는 것을 방지)
[Arduino] - Setting up Wi-Fi module ESP01 and basic code for Arduino remote control
[Arduino/ADUPAD] - Arduino WiFi remote control with ADUPAD and ESP-01
[Arduino] - Arduino Basic code for bluetooth remote contol with HC-06
[Arduino/ADUPAD] - Arduino Bluetooth remote control with ADUPAD and HC-06
[Arduino] - Arduino Basic code for BLE remote contol with BT05
[Arduino/ADUPAD] - Arduino BLE remote control with ADUPAD and BT05
[Arduino] - ESP32/NodeMcu Basic code for WiFi remote contol
[Arduino/ADUPAD] - ESP32/NodeMcu WiFi remote control with ADUPAD
[Arduino/ADUPAD] - ESP32 Bluetooth remote control with ADUPAD
[Arduino/ADUPAD] - ESP32 BLE remote control with ADUPAD