반응형

If the baud rate of ESP01 is not set to 9600, refer to the post below to set it up.

Please refer to the post below for how to connect Arduino and ESP01.

[Arduino] - Setting up Wi-Fi module ESP01 and basic code for Arduino remote control

 

ADUPAD application

 

- Modify the HTTP response code in loop() function according to the protocol for "TEXT" set in the ADUPAD app.

if (gotData) { 
  Data = "%%F4";   // protocol header of text for ADUPAD
  Data += "Hello World ";
  Data += random(100,200);
  Data += "%%F1";  // protocol footer of text for ADUPAD
  Data += '\n';    // termination character of wifi for ADUPAD
  Serial.println(Data); // Output the message to the serial monitor.
  http_response();
  gotData = false;
}

ARDUINO_ESP01_ADUPAD_BASIC.zip

 

ARDUINO_ESP01_ADUPAD_BASIC.zip
0.00MB

 

- Output of Serial Monitor after upload scketch "ARDUINO_ESP01_ADUPAD_BASIC.ino"

 

Connecting to the assigned IP while ESP01 is connected to the router

- Input the assigned IP address "192.168.1.7" on ADUPAD app connected to network of "skynet".

received data of "%%F5" and "%%F8connect"
Respons of HTTP from ESP01

 

Connecting directly to the ESP01 and then connecting the access point

- Connect to ESP01 on the WiFi Setting of a mobile phone.

 

- Input the Password for the ACCESS POINT of ESP01.

 

- Select "Keep WiFi on" if the message output below.

 

- Input the address "192.168.4.1" on ADUPAD app connected to ESP01.

received data of "%%F5" and "%%F8connect"
Respons of HTTP from ESP01

 

Code for remote control with WiFi of ADUPAD applications

- wifi_read() function

1. Protocol header definition

ADUPAD app's protocol header settings
ADUPAD app's protocol header settings

Define the headers for WiFi in the Arduino sketch according to the protocol header settings in the ADUPAD app.

#define pinHD F("%%F0")
#define joyHD F("%%F3")
#define strHD F("%%F4")
#define footHD F("%%F1")
#define echoHD F("%%E1")
#define connectHD F("%%F8")
#define optionHD F("%%F9")
#define checkHD F("%%F5")
#define HDLen 4
#define addHD F("%%")
#define addHDLen 2

 

2. Code to check the connection attempt of ADUPAD app

bool appConnection = false;

if (appConnection) { // If app connection is confirmed
  // Execute code after app connection is confirmed
} else { // Before app connection check
  if (income_wifi == checkHD) { // Check if the value is %%F5 and set the initial settings
    appConnection = true; http_response(); // Confirm the connection of ADUPAD
    if (connectionId != 48) { // Initialize ESP01 connection ID when connecting for the first time
      while (connectionId != 48) { 
        connectionId--;
        String command = F("AT+CIPCLOSE=");
        command += String(connectionId-48);
        command += F("\r\n");
        esp01.print(command);
        delay(1);
      } 
    }
  }
}

 

3. Handling of values according to connection header "connectHD(%%F8)"

%%F8 + connect: Transmit the necessary app settings and current Arduino state values through the iniSet() and sendState() functions

%%F8 + disconnect: Disconnect and change value of appConnection to false

%%F8 + WiFi: change WiFi setting values

if (income_wifi == F("connect")) iniSet();
else if (income_wifi == F("disconnect")) appConnection = false;  
else if (income_wifi.startsWith(F("WiFi"))) { 
  sendMessage(F("This funtion is not available.")); 
} else Serial.println(income_wifi);

 

4. Handling of values according to option header "optionHD(%%F9)"

void CheckF9(String temp) {
  Serial.println(temp);
  if (temp.startsWith(F("RAD"))) { } // if it starts with "RAD"
  else if (temp.startsWith(F("CKB"))) { } // if it starts with "CKB"
  else if (temp.startsWith(F("CHD"))) { } // if it starts with "CHD"
  else if (temp.startsWith(F("LSD"))) { } // if it starts with "LSD"
  else if (temp.startsWith(F("STR"))) { } // if it starts with "STR"
}

 

5. Handling of values according to button header "pinHD(%%F0)"

// income_wifi: %%F0 + Value + %%F1
while(income_wifi.indexOf(pinHD) != -1) { // need while function depend on left arrow pad mode 
  income_wifi.remove(0, 4); // remove %%F0
  ed = income_wifi.indexOf(footHD); // check the index number where footHD(%%F1)
  if (ed != -1) {                   // if the index number is found in the value
    temp = income_wifi.substring(0, ed); //Extract data up to index number
    uint8_t value = temp.toInt();   // convert to numeric value
    income_wifi.remove(0, ed+4);    // remove got data
    pin_control(value);             // execute the code corresponding to the value
  } else break;                     // exit while loop if there's no %%F0
}

 

6. Handling of values according to SeekBar(slide bar) header "pwmHD(%%F3)"

// income_wifi: id + Count + %% + Heading + %% + Strength + %%F1 (with protocol header %%F3 removed)
temp = income_wifi.substring(0, 1);
uint8_t id = temp.toInt(); // id: 0 or 1 or 2
income_wifi.remove(0, 1);  // remove id
ed = income_wifi.indexOf(addHD);      // index for %%
temp = income_wifi.substring(0, ed);  // extract count
uint16_t count = temp.toInt();        // convert to numeric value
bool ok = true;
if (id == 0) {                        // 0: left Joystic
  if (count == 0) leftCount = 0;      // reset leftCount
  if (count < leftCount) ok = false;  // Skip if the count is less than the stored leftCount
  else leftCount = count;             // update leftCount
} else if (id == 1) {                 // 1: right Joystic
  if (count == 0) rightCount = 0;     // reset rightCount
  if (count < rightCount) ok = false; // Skip if the count is less than the stored rightCount
  else rightCount = count;            // update leftCount
} else {                              // 2: gravity sensor
  if (count == 0) centerCount = 0;    // reset centerCount
  if (count < centerCount) ok = false;// Skip if the count is less than the stored centerCount
  else centerCount = count;           // update leftCount
}
if (ok) {                             // if count validation is OK
  income_wifi.remove(0, ed+addHDLen); // remove %%
  ed = income_wifi.indexOf(addHD);    // index for %%
  temp = income_wifi.substring(0, ed);// extract heading
  uint16_t heading = temp.toInt();    // convert to numeric value
  income_wifi.remove(0, ed+addHDLen); // remove %%
  ed = income_wifi.indexOf(addHD);    // index for %%
  temp = income_wifi.substring(0, ed);// extract strength
  uint8_t strength = temp.toInt();    // convert to numeric value
  income_wifi.remove(0, ed);          // remove value for strength
  if (income_wifi == footHD) {        // if the value left is %%F1
    joystick_control(id, heading, strength); // execute the code corresponding to the value
  }
}

 

Protocol function to send data from Arduino to app

1. Change the state of the button.

void sendPinState(uint8_t pin_val){  
  Data += pinHD;
  Data += pin_val;
  Data += footHD;
  Data += '\n';
}

 

2. Transmits an echo for the received value of the button.

void sendPinEcho(uint8_t pin_val){  
  Data += pinHD;
  Data += pin_val;
  Data += echoHD;
  Data += '\n';
}

 

3. Change the Joystick state of the app.

// id 0:Left Joystick, 1:Right Joystick 2:Gravity Sensor(change only text)
void sendJoyState(uint8_t id, uint16_t heading, uint8_t strength) {                      
  Data += joyHD;
  Data += id;
  Data += addHD;
  Data += heading;
  Data += addHD;
  Data += strength;
  Data += footHD;
  Data += '\n';
}

 

4. Transmits the echo for the received value of the Joystick.

// SEND JOYSTIC ECHO - ESP01: USE AT PASSIVE JOYSTIC MODE
void sendJoyEcho(uint8_t id, uint16_t heading, uint8_t strength) {                          
  Data += joyHD;
  Data += id;
  Data += addHD;
  Data += heading;
  Data += addHD;
  Data += strength;
  Data += echoHD;
  Data += '\n';
}

 

5. Send text.

void sendText(String text) {                               
  Data += strHD;
  Data += text;
  Data += footHD;
  Data += '\n';
}

 

6. Instruct the app to click the Disconnect Button.

void sendDisconnect(){ 
  Data += connectHD;
  Data += F("DIS");
  Data += '\n';
}

Disconnect Button
Disconnect Button

 

7. Use when you want to acquire control authority by using the ACCESS POINT password of the module in the internal network connection through the router. (without using HTML web login)

It can be changed to any name through definition of the passName and passNameLen for processing the password in the sketch and the app send datas starting with passName as password value. This is to enhance security.

#define passName F("PAS:")
#define passNameLen 4

void requestPass(bool val){ 
  Data += connectHD;
  Data += val;
  Data += passName;
  Data += '\n';
}

Password dialog
Password dialog

8. If control authority is given through password confirmation, a cookie value is created and transmitted so that control authority for the data transmitted thereafter can be confirmed.

#define cooLength 5
String cooValue = "u7Dv0";

String makeCooValue() {
  cooValue = "";
  uint8_t temp = 0;
  for (int i = 0; i < cooLength; i++) {
    temp = random(39, 123); //random(39, 123); // 39 ~ 122 pick
    if (temp == 47 || temp == 59 || temp == 60 || temp == 62 || temp == 92 || temp == 94 || temp == 96) temp = 79;
    cooValue += char(temp);
  }
  return cooValue;
}

void responsePass(bool val){ 
  Data += connectHD;
  Data += F("RES:");
  if (val) Data += makeCooValue(); 
  else Data += val;
  Data += '\n';
}

 

9. Sends information about the current Wi-Fi connection so that the user can view and edit information in the app about the Wi-Fi connection.

void sendWifiInfo(){ 
  Data += connectHD;
  Data += F("INF:");
  Data += ssidAP;
  Data += ',';
  Data += passAP;
  Data += ',';
  Data += ap;
  Data += ',';
  Data += wifiRouter;
  Data += ',';
  Data += ssid;
  Data += ',';
  Data += pass;
  Data += ',';
  Data += ip;
  Data += '\n';
}

 

10. Outputs the message in the form of a pop-up.

void sendMessage(String str){ 
  Data += connectHD;
  Data += F("MES:");
  Data += str;
  Data += '\n';
}

 

11. Disable the feature, which is default setting, of automatically resend the value When a button or Joystick or Gravity Sensor is changed in the app and then if a response failure error occurs.

It is used when the Arduino intentionally does not respond due to the delay that occurs when sending data using the AT command to the ESP01.

void responseFailResend(bool val) {
  Data += connectHD;
  Data += F("RFR:");
  Data += val;
  Data += '\n';
}

 

12. Set the function to continuously transmit the changed value of the Joystick according to the specified interval.

*** The Gravity Sensor always works in an active Mode.

true: Active Joystick Mode

false: Passive Joystick Mode (transmits only values when the slide bar is touched up)

void setActiveJoystick(bool val){ 
  Data += optionHD;
  Data += F("ACT:");
  Data += val;
  Data += '\n';
}

 

13. Set transmission interval of ACTIVE JOYSTIC MODE. (Unit: Millisecond)

void setJoystickInterval(uint16_t val){ 
  Data += optionHD;
  Data += F("JSI:");
  Data += val;
  Data += '\n';
}

 

14. Set the range where the strength of the joystick becomes 0. (enter a value from 0 to 35)

void setJoyZeroRange(uint8_t val){ 
  if (val > 35) val = 35;
  Data += optionHD;
  Data += F("JZR:");
  Data += val;
  Data += '\n';
}

 

15. Set whether or not to use a function that converts the Strength value of Joystick or Gravity Sensor into a value between 0 and 10.

void setJoyStrengthAdjust(bool val){ 
  Data += optionHD;
  Data += F("ADJ:");
  Data += val;
  Data += '\n';
}

 

16. Activate a timer that sends checkHD(%%F5) at regular time intervals.

Regardless of the app, it is used to reflect independently changed values in the Arduino to the app.

void setRequest(bool val){ 
  Data += optionHD;
  Data += F("REQ:");
  Data += val;
  Data += '\n';
}

 

17. Set the operation interval of the timer sending checkHD(%%F5). (Unit: Millisecond)

void setRequestInterval(uint16_t val){ 
  Data += optionHD;
  Data += F("INT:");
  Data += val;
  Data += '\n';
}

 

18. Set the group for the left arrow keypad.

// 1: independent 2: group1(up-down) / group2 (left-right) 4: group4(only 1)
void setLeftPadMode(uint8_t val){  
  if (val == 0 || val > 2) val = 4; 
  Data += optionHD;
  Data += F("LPM:");
  Data += val;
  Data += '\n';
}

 

19. Set the 4-way control of the joystick.

// 0: Left & Right False 1: Left 4 Way 2: Right 4Way 3: Both 4 Way
void setJoyWay4(uint8_t val){
  Data += optionHD;
  Data += F("SJW:");
  Data += val;
  Data += '\n';
}

 

20. Set whether or not to display the group button.

// 0: none 1: group1 2: group1&2
void setDisplayAddButton(uint8_t val){ 
  if (val > 2) val = 2;
  Data += optionHD;
  Data += F("DAB:");
  Data += val;
  Data += '\n';
}

21. Set the operation function when clicking the label displaying the current connection status.

0: No function.

1: Show only connection information when it clicked.

2: Show connection information and password when it clicked so that the connection and password can be set.

// 0: not use, 1: show only name, 2: show name & pass, defalult: 2
void setSSIDLabelMode(uint8_t val) { 
  Data += optionHD;
  Data += F("SLM:");
  Data += val;
  Data += '\n';
}

 

22. Set the activation interval of the gravity sensor and transmission of the tilt value.

// defalt interval : 180 millis, 180, 180 * 6 = 1080
void useGravityAndInterval(uint16_t val){ 
  Data += optionHD;
  Data += F("UGI:");
  Data += val;
  Data += '\n';
}

 

23. Set labels for buttons.

Label buttons 1 to 6 in order using ',' as a separator.

//F("BT1,BT2,BT3,BT4,BT5,BT6")
void setAddButtonLabel(String str){ 
  Data += optionHD;
  Data += F("ABL:");
  Data += str;
  Data += '\n';
}

 

24. Set the toggle/push properties of the left 4 buttons or 20 buttons of all.

//F("0000")           // left pad: up-left-right-down
//F("00000000001111110000") // 0000:left, 0000:right, 001111110000:center
void setLeftPadOrAllToggle(String str){ 
  Data += optionHD;
  Data += F("LTG:");
  Data += str;  
  Data += '\n';
}

 

25. Set the toggle/push properties of the right 4 buttons.

// F("0000")           // right pad: top-left-right-bottom
void setRightPadToggle(String str){ 
  Data += optionHD;
  Data += F("RTG:");
  Data += str;  
  Data += '\n';
}

 

26. Set the toggle/push properties of the middle 12 buttons.

// F("000000000000"); // center: view-menu-bt1-bt2-bt3-bt4-bt5-bt6-LB-LT-RB-RT
void setButtonToggle(String str){ 
  Data += optionHD;
  Data += F("BTG:");
  Data += str;  
  Data += '\n';
}

 

27. Dialog Message: radio button

// option = "A,B,C" -> selection index = 1(A) ~ 3(C)
void dialogRadio(uint8_t id, String title, String option, uint8_t selection){ 
  Data += optionHD;
  Data += F("RAD:"); 
  Data += String(id); Data += ':';
  Data += title; Data += ':';
  Data += option; Data += ':';
  Data += String(selection);
  Data += '\n';
} // Return -> RAD:0:1(index) , RAD:id:option index

 

28. Dialog Message: Checkbox

// option = "A,B,C"
void dialogCheckbox(uint8_t id, String title, String option){ 
  Data += optionHD;
  Data += F("CKB:"); 
  Data += String(id); Data += ':';
  Data += title; Data += ':';
  Data += option; 
  Data += '\n';
} // Return -> CKB:0:1,3(index) , CKB:id:option index

 

29. Dialog Message: Select button

// option = "A,B"
void dialogChoose(uint8_t id, String message, String option){ 
  Data += optionHD;
  Data += F("CHD:"); 
  Data += String(id); Data += ':'; 
  Data += message; Data += ':'; 
  Data += option; 
  Data += '\n';
} // Return -> CHD:0:B , CHD:id:option str

 

30. Dialog Message: List Window

// option = "A,B,C,D,E,F,G,H"
void dialogList(uint8_t id, String title, String option){ 
  Data += optionHD;
  Data += F("LSD:"); 
  Data += String(id); Data += ':';
  Data += title; Data += ':'; 
  Data += option; 
  Data += '\n';
} // Return -> LSD:0:F , LSD:id:option str

 

31. Dialog Message: Input text

void dialogInput(uint8_t id, String title){ 
  Data += optionHD;
  Data += F("STR:"); 
  Data += String(id); Data += ':'; 
  Data += title; 
  Data += '\n';
} // Return -> STR:0:str , STR:id:str

 

1.ARDUINO_ESP01_JOYSTICK.zip

1.ARDUINO_ESP01_JOYSTICK.zip
0.01MB

 

https://youtu.be/qUIGxQ3kFGo

 

Main sketch

더보기
#include <SoftwareSerial.h>
#define rxPin 3 
#define txPin 2 
SoftwareSerial esp01(txPin, rxPin); // SoftwareSerial NAME(RX, TX);

const char ssidAP[] = "ESP01";   // your network SSID (name)
const char passAP[] = "12345678"; //"1234test";         // your network password

bool wifiRouter = true;      // 공유기 연결 유무
const char ssid[] = "skynet";    // "SK_WiFiGIGA40F7" your network SSID (name)
const char pass[] = "skynet00";  // "1712037218" your network password 

String ap = "";
String ip = "";

String Data = "";
#include "protocol.h"

#define ledPin 13

void setup() {
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  Serial.begin(9600);
  esp01.begin(9600); // your esp's baud rate might be different
  sendData(F("RST")); 
  unsigned long int time = millis();
  String temp = "";
  while (time+20000 > millis()) {
    temp = esp01.readStringUntil('\n');
    if (temp.indexOf(F("ready")) != -1) { Serial.println(F("Set")); break; }
  }
  if (wifiRouter) sendData(F("CWMODE=3")); // configure as access point (working mode: AP+STA)
  else sendData(F("CWMODE=2"));
  if (wifiRouter) sendData(F("CWDHCP=1,1"));
  sendData(addID(F("CWSAP="),ssidAP,passAP)+','+String(10)+','+String(3)); 
  sendData(F("CIPMUX=1")); // configure for multiple connections
  sendData(F("CIPSERVER=1,80")); // turn on server on port 80
  if (wifiRouter) {
    retry = 1;
    while(retry) { 
      sendData(addID(F("CWJAP="),ssid,pass)); 
      if (retry > 1) { Serial.print(F("Retrying to connect: ")); Serial.println(retry-1); }
      if (retry > 4) { Serial.println(F("connection failed")); retry = 0; }
    }
  }
  ipCheck(sendData(F("CIFSR"))); // get ip address
}

void pin_control(uint8_t value) {
  if (value != 0) {
    switch (value) {
      case 11: Serial.println(F("button 1 : on")); 
                  break;
      case 10: Serial.println(F("button 1 : off"));
                  break;
      case 21: Serial.println(F("button 2 : on"));
                  break;
      case 20: Serial.println(F("button 2 : off"));
                  break;
      case 31: Serial.println(F("button 3 : on"));
                  break;
      case 30: Serial.println(F("button 3 : off"));
                  break;
      case 41: Serial.println(F("button 4 : on"));
                  break;
      case 40: Serial.println(F("button 4 : off"));
                  break;
      case 51: Serial.println(F("button 5 : on"));
                  break;
      case 50: Serial.println(F("button 5 : off"));
                  break;
      case 61: Serial.println(F("button 6 : on"));
                  break;
      case 60: Serial.println(F("button 6 : off"));
                  break;
      case 71: Serial.println(F("button 7 : on"));
                  break;
      case 70: Serial.println(F("button 7 : off"));
                  break;
      case 81: Serial.println(F("button 8 : on"));
                  break;
      case 80: Serial.println(F("button 8 : off"));
                  break;
      case 91: Serial.println(F("button 9 : on"));
                  break;
      case 90: Serial.println(F("button 9 : off"));
                  break;  
      case 101: Serial.println(F("button 10 : on"));
                //uint8_t id, String title, String option
                dialogList(0, F("MENU"), F("select,tomato,banana,mango")); 
                  break;
      case 100: Serial.println(F("button 10 : off"));
                  break;  
      case 111: Serial.println(F("button 11 : on"));
                  break;
      case 110: Serial.println(F("button 11 : off"));
                  break;  
      case 121: Serial.println(F("button 12 : on"));
                  break;
      case 120: Serial.println(F("button 12 : off"));
                  break;  
      case 131: Serial.println(F("button 13 : on"));
                  break;  
      case 130: Serial.println(F("button 13 : off"));
                  break;  
      case 141: Serial.println(F("button 14 : on"));
                  break;  
      case 140: Serial.println(F("button 14 : off"));
                  break;  
      case 151: Serial.println(F("button 15 : on"));
                  break;  
      case 150: Serial.println(F("button 15 : off"));
                  break;     
      case 161: Serial.println(F("button 16 : on"));
                  break;
      case 160: Serial.println(F("button 16 : off"));
                  break;  
      case 171: Serial.println(F("button 17 : on"));
                  break;
      case 170: Serial.println(F("button 17 : off"));
                  break;  
      case 181: Serial.println(F("button 18 : on"));
                  break;  
      case 180: Serial.println(F("button 18 : off"));
                  break;  
      case 191: Serial.println(F("button 19 : on"));
                  break;  
      case 190: Serial.println(F("button 19 : off"));
                  break;  
      case 201: Serial.println(F("button 20 : on"));
                  break;  
      case 200: Serial.println(F("button 20 : off"));
                  break; 
      case 210: Serial.println(F("button 21 : off"));
                  break;  
      case 220: Serial.println(F("button 22 : off"));
                  break;               
    }
  }
}

// headingVal = false;
//           Top
//         6  7  0
//          \ | /
//  Left 5 --   -- 1 Right
//          / | \
//         4  3  2
//          Bottom

bool headingVal = true; 

void joystick_control(uint8_t id, uint16_t heading, uint8_t strength) {
  //sendJoyEcho(id, heading, strength); 
  if (id == 0) Serial.print(F("L: "));
  else if (id == 1) Serial.print(F("R: "));
  else Serial.print(F("C: "));
  if (headingVal) {
    Serial.print(heading); Serial.print('/'); Serial.println(strength);
  } else {
    if (heading <= 23) heading = 359;
    int8_t stickDir = (heading-23)/45;  
    Serial.println(stickDir);
  }
}

bool appConnection = false;
String income_wifi = ""; // 와이파이 수신 스트링 저장 변수
uint16_t leftCount = 2;
uint16_t rightCount = 2;
uint16_t centerCount = 2;

void wifi_read() {
  while (esp01.available()) { 
    income_wifi = esp01.readStringUntil('\n');
    if (income_wifi.startsWith(F("+IPD"))) {
      income_wifi.remove(0,5);
      connectionId = income_wifi.charAt(0);
      int st = income_wifi.indexOf(F("GET /"))+5;
      income_wifi.remove(0,st);
      if (!income_wifi.startsWith(F("fav"))) { // favicon.ico 는 통과 
        int ed = income_wifi.lastIndexOf(F("HTTP/1.1"));
        income_wifi.remove(ed-1);
        String temp = ""; 
        if (appConnection) {  
          temp = income_wifi.substring(0, 4);
          uint8_t order = 0; 
          if (temp == checkHD) order = 1;
          else if (temp == pinHD) order = 2;
          else if (temp == joyHD) order = 3;
          else if (temp == connectHD) order = 4;
          else if (temp == optionHD) order = 5; 
          if (order > 2) income_wifi.remove(0, 4); //프로토콜 헤더 제거
          if (order == 1) { // send data to app when change local/web control value
            
          } else if (order == 2) { // %%F0
            while(income_wifi.indexOf(pinHD) != -1) { // need depend on left arrow pad mode 
              income_wifi.remove(0, 4);
              ed = income_wifi.indexOf(footHD);
              if (ed != -1) {
                temp = income_wifi.substring(0, ed);
                uint8_t value = temp.toInt();
                income_wifi.remove(0, ed+4);
                pin_control(value);
              } else break;
            }
          } else if (order == 3) { // %%F3
            temp = income_wifi.substring(0, 1);
            uint8_t id = temp.toInt();
            income_wifi.remove(0, 1);
            ed = income_wifi.indexOf(addHD);
            temp = income_wifi.substring(0, ed);
            uint16_t count = temp.toInt();
            bool ok = true;
            if (id == 0) {
              if (count == 0) leftCount = 0;
              if (count < leftCount) ok = false;
              else leftCount = count;
            } else if (id == 1) {
              if (count == 0) rightCount = 0;
              if (count < rightCount) ok = false;
              else rightCount = count;
            } else {
              if (count == 0) centerCount = 0;
              if (count < centerCount) ok = false;
              else centerCount = count;
            }
            if (ok) {
              income_wifi.remove(0, ed+addHDLen);
              ed = income_wifi.indexOf(addHD);
              temp = income_wifi.substring(0, ed);
              uint16_t heading = temp.toInt();
              income_wifi.remove(0, ed+addHDLen);
              ed = income_wifi.indexOf(addHD);
              temp = income_wifi.substring(0, ed);
              uint8_t strength = temp.toInt();
              income_wifi.remove(0, ed);
              if (income_wifi == footHD) {
                joystick_control(id, heading, strength);
              }
            }
          } else if (order == 4) { // %%F8
            if (income_wifi == F("connect")) iniSet();
            else if (income_wifi == F("disconnect")) appConnection = false;  
            else if (income_wifi.startsWith(F("WiFi"))) { 
              sendMessage(F("This funtion is not available.")); 
            } else Serial.println(income_wifi);
          } else if (order == 5) { // %%F9
            income_wifi.replace(F("%20"), F(" ")); // URL Decoding 공백문자 변경
            CheckF9(income_wifi); 
          } else { 
            income_wifi.replace(F("%20"), F(" ")); // URL Decoding 공백문자 변경
            Serial.println(income_wifi);
          }
          http_response();
        } else {
          if (income_wifi == checkHD) { 
            appConnection = true; http_response(); 
            if (connectionId != 48) {
              while (connectionId != 48) { 
                connectionId--;
                String command = F("AT+CIPCLOSE=");
                command += String(connectionId-48);
                command += F("\r\n");
                esp01.print(command);
                delay(1);
              } 
            }
          }
        }
      }
      income_wifi = "";
    }
  }      
}     
 
void loop() {
  wifi_read();
  if(Serial.available()) { // 시리얼 버퍼에 데이터 있으면
    String temp = Serial.readStringUntil('\n'); // 시리얼 모니터 - NEW LINE 옵션
    Serial.println(temp);
    if(temp == "1"){   
      
    } else if(temp == "2"){ 
      
    } else if(temp == "3"){ 
      
    } else if(temp == "4"){
      
    } else if(temp == "5"){
      
    } 
  }
}

 

Protocol sketch

더보기
//////////////////////////////////////////////////////////// COMMON
///////////////////////////////////////// ESSENTIAL 
#define pinHD F("%%F0")
#define joyHD F("%%F3")
#define strHD F("%%F4")
#define footHD F("%%F1")
#define echoHD F("%%E1")
#define connectHD F("%%F8")
#define optionHD F("%%F9")
#define checkHD F("%%F5")
#define HDLen 4
#define addHD F("%%")
#define addHDLen 2

// SEND PIN VALUE
void sendPinState(uint8_t pin_val){  
  Data += pinHD;
  Data += pin_val;
  Data += footHD;
  Data += '\n';
}

// SEND PIN ECHO
void sendPinEcho(uint8_t pin_val){  
  Data += pinHD;
  Data += pin_val;
  Data += echoHD;
  Data += '\n';
}

// id 0:Left Joystick, 1:Right Joystick 2:Gravity Sensor(change only text)
void sendJoyState(uint8_t id, uint16_t heading, uint8_t strength) {                      
  Data += joyHD;
  Data += id;
  Data += addHD;
  Data += heading;
  Data += addHD;
  Data += strength;
  Data += footHD;
  Data += '\n';
}

// SEND JOYSTIC ECHO - ESP01: USE AT PASSIVE JOYSTIC MODE
void sendJoyEcho(uint8_t id, uint16_t heading, uint8_t strength) {                          
  Data += joyHD;
  Data += id;
  Data += addHD;
  Data += heading;
  Data += addHD;
  Data += strength;
  Data += echoHD;
  Data += '\n';
}

// SEND TEXT
void sendText(String text) {                               
  Data += strHD;
  Data += text;
  Data += footHD;
  Data += '\n';
}

///////////////////////////////////////// CONNECTION 
void sendDisconnect(){ 
  Data += connectHD;
  Data += F("DIS");
  Data += '\n';
}

//#define passName F("PAS:")
//#define passNameLen 4
//
//void requestPass(bool val){ 
//  Data += connectHD;
//  Data += val;
//  Data += passName;
//  Data += '\n';
//}
//
//#define cooLength 5
//String cooValue = "u7Dv0";
//
//String makeCooValue() {
//  cooValue = "";
//  uint8_t temp = 0;
//  for (int i = 0; i < cooLength; i++) {
//    temp = random(39, 123); //random(39, 123); // 39 ~ 122 pick
//    if (temp == 47 || temp == 59 || temp == 60 || temp == 62 || temp == 92 || temp == 94 || temp == 96) temp = 79;
//    cooValue += char(temp);
//  }
//  return cooValue;
//}
//
//void responsePass(bool val){ 
//  Data += connectHD;
//  Data += F("RES:");
//  if (val) Data += makeCooValue(); 
//  else Data += val;
//  Data += '\n';
//}

void sendWifiInfo(){ 
  Data += connectHD;
  Data += F("INF:");
  Data += ssidAP;
  Data += ',';
  Data += passAP;
  Data += ',';
  Data += ap;
  Data += ',';
  Data += wifiRouter;
  Data += ',';
  Data += ssid;
  Data += ',';
  Data += pass;
  Data += ',';
  Data += ip;
  Data += '\n';
}

void sendMessage(String str){ 
  Data += connectHD;
  Data += F("MES:");
  Data += str;
  Data += '\n';
}

// defalt: true
void responseFailResend(bool val) {
  Data += connectHD;
  Data += F("RFR:");
  Data += val;
  Data += '\n';
}

///////////////////////////////////////// OPTION
///////////////////////// SET FUNCION
void setActiveJoystick(bool val){ 
  Data += optionHD;
  Data += F("ACT:");
  Data += val;
  Data += '\n';
}

// SEND SLIDE GET VALUE INTERVAL
void setJoystickInterval(uint16_t val){ 
  Data += optionHD;
  Data += F("JSI:");
  Data += val;
  Data += '\n';
}

void setJoyZeroRange(uint8_t val){ 
  if (val > 35) val = 35;
  Data += optionHD;
  Data += F("JZR:");
  Data += val;
  Data += '\n';
}

void setJoyStrengthAdjust(bool val){ 
  Data += optionHD;
  Data += F("ADJ:");
  Data += val;
  Data += '\n';
}

void setRequest(bool val){ 
  Data += optionHD;
  Data += F("REQ:");
  Data += val;
  Data += '\n';
}

void setRequestInterval(uint16_t val){ 
  Data += optionHD;
  Data += F("INT:");
  Data += val;
  Data += '\n';
}

// 1: independent 2: group1(up-down) / group2 (left-right) 4: group4(only 1)
void setLeftPadMode(uint8_t val){  
  if (val == 0 || val > 2) val = 4; 
  Data += optionHD;
  Data += F("LPM:");
  Data += val;
  Data += '\n';
}

// 0: Left & Right False 1: Left 4 Way 2: Right 4Way 3: Both 4 Way
void setJoyWay4(uint8_t val){
  Data += optionHD;
  Data += F("SJW:");
  Data += val;
  Data += '\n';
}

// 0: none 1: group1 2: group1&2
void setDisplayAddButton(uint8_t val){ 
  if (val > 2) val = 2;
  Data += optionHD;
  Data += F("DAB:");
  Data += val;
  Data += '\n';
}

// 0: not use, 1: show only name, 2: show name & pass, defalult: 2
void setSSIDLabelMode(uint8_t val) { 
  Data += optionHD;
  Data += F("SLM:");
  Data += val;
  Data += '\n';
}

// defalt interval : 180 millis, 180, 180 * 6 = 1080
void useGravityAndInterval(uint16_t val){ 
  Data += optionHD;
  Data += F("UGI:");
  Data += val;
  Data += '\n';
}

//f("BT1,BT2,BT3,BT4,BT5,BT6")
void setAddButtonLabel(String str){ 
  Data += optionHD;
  Data += F("ABL:");
  Data += str;
  Data += '\n';
}

//F("0000")           // left pad: up-left-right-down
void setLeftPadOrAllToggle(String str){ 
  Data += optionHD;
  Data += F("LTG:");
  Data += str;  
  Data += '\n';
}
// F("0000")           // right pad: top-left-right-bottom
void setRightPadToggle(String str){ 
  Data += optionHD;
  Data += F("RTG:");
  Data += str;  
  Data += '\n';
}
// F("000000000000"); // center: view-menu-bt1-bt2-bt3-bt4-bt5-bt6-LB-LT-RB-RT
void setButtonToggle(String str){ 
  Data += optionHD;
  Data += F("BTG:");
  Data += str;  
  Data += '\n';
}

///////////////////////// PERFORM DIALOG
// option = "A,B,C" -> index = 1(A) ~ 3(C)
void dialogRadio(uint8_t id, String title, String option, uint8_t selection){ 
  Data += optionHD;
  Data += F("RAD:"); 
  Data += String(id); Data += ':';
  Data += title; Data += ':';
  Data += option; Data += ':';
  Data += String(selection);
  Data += '\n';
} // Return -> RAD:0:1(index) , RAD:id:option index

// option = "A,B,C"
void dialogCheckbox(uint8_t id, String title, String option){ 
  Data += optionHD;
  Data += F("CKB:"); 
  Data += String(id); Data += ':';
  Data += title; Data += ':';
  Data += option; 
  Data += '\n';
} // Return -> CKB:0:1,3(index) , CKB:id:option index

// option = "A,B"
void dialogChoose(uint8_t id, String message, String option){ 
  Data += optionHD;
  Data += F("CHD:"); 
  Data += String(id); Data += ':'; 
  Data += message; Data += ':'; 
  Data += option; 
  Data += '\n';
} // Return -> CHD:0:B , CHD:id:option str

// option = "A,B,C,D,E,F,G,H"
void dialogList(uint8_t id, String title, String option){ 
  Data += optionHD;
  Data += F("LSD:"); 
  Data += String(id); Data += ':';
  Data += title; Data += ':'; 
  Data += option; 
  Data += '\n';
} // Return -> LSD:0:F , LSD:id:option str 

void dialogInput(uint8_t id, String title){ 
  Data += optionHD;
  Data += F("STR:"); 
  Data += String(id); Data += ':'; 
  Data += title; 
  Data += '\n';
} // Return -> STR:0:str , STR:id:str

//////////////////////////////////////////////////////////// INDIVIDUAL
void iniSet() {
  sendWifiInfo(); 
  setAddButtonLabel(F("BT1,BT2,BT3,BT4,BT5,BT6"));
  setDisplayAddButton(2); // 0: none 1: group1 2: group1&2
  //setLeftPadMode(1);      // 1: independent 2: group1(up-down) / group2 (left-right) 4: group4(only 1)
  //setLeftPadOrAllToggle(F("00000000001111110000")); 
  setJoyWay4(false);
  setActiveJoystick(false); //setJoystickInterval(100);
  setJoyStrengthAdjust(true);
  setRequest(false); //setRequestInterval(250);
}

void ipCheck(String response) {
  int st, ed;
  if (response.indexOf(F("PIP")) != -1) {
    st = response.indexOf(F("PIP"))+5;
    ed = response.indexOf('"', st+1);
    ap = response.substring(st, ed);
    response.remove(0, ed+1);
    Serial.print(F("ap: ")); Serial.println(ap);
  }
  if (response.indexOf(F("AIP")) != -1) {
    st = response.indexOf(F("AIP"))+5;
    ed = response.indexOf('"', st+1);
    ip = response.substring(st, ed);
    Serial.print(F("ip: ")); Serial.println(ip);
  }
}

uint8_t retry = 1;

String sendData(String order) {
  String command = F("AT+");
  command += order;
  command += F("\r\n");
  esp01.print(command); // send the read character to the esp01
  long int time = millis();
  String response = "";
  while( (time+20000) > millis()) {
    while(esp01.available()) {  // The esp has data so display its output to the serial window
      char c = esp01.read(); // read the next character.
      response+=c;
    }
    if (response.indexOf(F("OK")) != -1) { retry = 0; Serial.println(F("OK")); break; } 
    else if (response.indexOf(F("FAIL")) != -1 || response.indexOf(F("ERROR")) != -1) { 
      if (response.indexOf(F("FAIL")) != -1) retry++;
      else if (response.indexOf(F("ERROR")) != -1) { Serial.println(F("ERROR")); break; } 
      Serial.print(command); Serial.println(F("Failed")); break; 
    }
  }
  return response;
}

String addID(String order, String ssidTemp, String passTemp) {
  String temp = order+'"'+ssidTemp+'"'+','+'"'+passTemp+'"';
  return temp;
}

uint8_t connectionId = 48; // 연결 id 저장 변수

void http_response() {
  String cip = F("AT+CIPSEND=");
  cip += connectionId-48;
  cip += ',';
  cip += Data.length()+19;
  cip += F("\r\n");
  esp01.print(cip);
  unsigned long int time = millis();
  while (time+2000 > millis()) {
    cip = esp01.readStringUntil('\n');
    if (cip.indexOf(F("OK")) != -1) break;
  }
  esp01.print(F("HTTP/1.1 200 OK\r\n\r\n")); // +19
  esp01.print(Data);
  time = millis();
  while (time+2000 > millis()) {
    cip = esp01.readStringUntil('\n');
    if (cip.indexOf(F("OK")) != -1) break;
  }
  Data = "";
  String command = F("AT+CIPCLOSE=");
  command += String(connectionId-48);
  command += F("\r\n");
  esp01.print(command);
}

void CheckF9(String temp) {
  Serial.println(temp);
  if (temp.startsWith(F("RAD"))) {  }
  else if (temp.startsWith(F("CKB"))) {  }
  else if (temp.startsWith(F("CHD"))) {  }
  else if (temp.startsWith(F("LSD"))) {  }
  else if (temp.startsWith(F("STR"))) {  }
}

 

Example of Grabity Sensor using responseFailResend() function

Coded to not respond to values from the gravity sensor continuously transmitted in active mode.

- Example of code to prevent response according to joystick number(Gravity Sensor)

bool joystick_control(uint8_t id, uint16_t heading, uint8_t strength) {
  bool response = true;
  if (id == 0) Serial.print(F("L: "));      // set passive joystick mode by setActiveJoystick(false);
  else if (id == 1) Serial.print(F("R: ")); // set passive joystick mode by setActiveJoystick(false);
  else { Serial.print(F("C: ")); response = false; } // gravity sensor's allways active mode
  if (headingVal) {
    Serial.print(heading); Serial.print('/'); Serial.println(strength);
  } else {
    if (heading <= 23) heading = 359;
    int8_t stickDir = (heading-23)/45; 
    Serial.println(stickDir);
  }
  return response;
}

- Example of code to prevent response about the value of all Joystic.

In Active Joystic Mode, the Response must be prevented due to taking more than 1 second to process AT Command.

bool joystick_control(uint8_t id, uint16_t heading, uint8_t strength) {
  if (id == 0) Serial.print(F("L: "));      
  else if (id == 1) Serial.print(F("R: ")); 
  else { Serial.print(F("C: ")); response = false; } 
  if (headingVal) {
    Serial.print(heading); Serial.print('/'); Serial.println(strength);
  } else {
    if (heading <= 23) heading = 359;
    int8_t stickDir = (heading-23)/45; 
    Serial.println(stickDir);
  }
  return response = false;
}

- Example of code to prevent response about the value of all button except menu-related buttons that must be made a response.

bool pin_control(uint8_t value) {
  bool response = false;
  if (value != 0) {
    switch (value) {
      .
      .
      case 91: Serial.println(F("button 9 : on"));
               //uint8_t id, String title, String option
               dialogList(0, F("LEFT PAD"), F("SELECT,TOGGLE,PUSH")); 
                  break;
      case 90: Serial.println(F("button 9 : off"));
                  break;  
      case 101: Serial.println("button 10 : on");
                //uint8_t id, String title, String option
                dialogList(2, F("RIGHT PAD"), F("SELECT,TOGGLE,PUSH")); 
                  break;
      case 100: Serial.println(F("button 10 : off"));
                  break;  
      .
      .
    }
  }
  if (value == 91 || value == 101) response = true; // must be made a response
  return response;
}

- Example of modifying the wifi_read() function

if (appConnection) { 
  bool response = true; // add
  if (order == 1) {  }
  else if (order == 2) {  
    response = pin_control(value); // edit
  }
  else if (order == 3) {
    response = joystick_control(id, heading, strength); // edit
  } 
  else if (order == 4) {  }
  else {  }
  if (response) http_response(); // edit
  else {  }
}

 

2.ARDUINO_ESP01_JOYSTICK_GRAVITY_NORESPONSE.zip

2.ARDUINO_ESP01_JOYSTICK_GRAVITY_NORESPONSE.zip
0.01MB

 

https://youtu.be/QjgocTgGyis

 

 

Example of using Protocol to set ADUPAD app

- ADUPAD app settings: label/toggle properties, use of the timer for checkHD(%%F5), Joystic Mode settings, etc.

void iniSet() {
  sendWifiInfo(); 
  setAddButtonLabel(F("BT1,BT2,BT3,BT4,BT5,BT6"));
  setDisplayAddButton(2); // 0: none 1: group1 2: group1&2
  setLeftPadMode(1);      // 1: independent 2: group1(up-down) / group2 (left-right) 4: group4(only 1)
  setLeftPadOrAllToggle(F("00000000001111110000")); 
  setJoyWay4(false);
  setActiveJoystick(false); //setJoystickInterval(100); // Passive Joysitck Mode
  setJoyStrengthAdjust(true);                           // value of Joystick adjusted into 0 ~ 10
  setRequest(false); //setRequestInterval(250);         // Disable timer for check(%%F5)
}

 

- Example of code processing for each function of a button that changes according to the leftPadMode and menu-related button.

void pin_control(uint8_t value) {
  if (value != 0) {
    switch (value) {
      case 11: if (leftPadMode > 1) Serial.println(F("Up DIR"));
               else Serial.println(F("button 1 : on")); 
                  break;
      case 10: if (leftPadMode > 1) Serial.println(F("Up off"));
               else Serial.println(F("button 1 : off"));
                  break;
      case 21: if (leftPadMode > 1) Serial.println(F("Left DIR"));
               else Serial.println(F("button 2 : on"));
                  break;
      case 20: if (leftPadMode > 1) Serial.println(F("Left off"));
               else Serial.println(F("button 2 : off"));
                  break;
      case 31: if (leftPadMode > 1) Serial.println(F("Right DIR"));
               else Serial.println(F("button 3 : on"));
                  break;
      case 30: if (leftPadMode > 1) Serial.println(F("Right off"));
               else Serial.println(F("button 3 : off"));
                  break;
      case 41: if (leftPadMode > 1) Serial.println(F("Down DIR"));
               else Serial.println(F("button 4 : on"));
                  break;
      case 40: if (leftPadMode > 1) Serial.println(F("Down off"));
               else Serial.println(F("button 4 : off"));
                  break;
      .
      .
      case 91: Serial.println(F("button 9 : on"));
               //uint8_t id, String title, String option
               dialogList(0, F("LEFT PAD"), F("SELECT,TOGGLE,PUSH")); // dialog message
                  break;
      case 90: Serial.println(F("button 9 : off"));
                  break;  
      case 101: Serial.println("button 10 : on");
                //uint8_t id, String title, String option
                dialogList(2, F("RIGHT PAD"), F("SELECT,TOGGLE,PUSH")); // dialog message
                  break;
      .
      .
    }
  }
}

 

- Example of modifying the function "CheckF9()" that handles dialog messages.

void CheckF9(String temp) {
  Serial.println(temp);
  if (temp.startsWith(F("RAD"))) {  }         // radio button
  else if (temp.startsWith(F("CKB"))) {  }    // Checkbox
  else if (temp.startsWith(F("CHD"))) {  }    // Select button
  else if (temp.startsWith(F("LSD"))) {       // List Window
    int ed = temp.indexOf(':');
    temp.remove(0, ed+1);
    ed = temp.indexOf(':');
    String ID = temp.substring(0, ed);
    uint8_t id = ID.toInt();
    temp.remove(0, ed+1);
    if (id == 0) {
      if (temp.startsWith(F("PUS"))) { leftPadMode = 0; setLeftPadOrAllToggle(F("0000")); }
      else if (temp.startsWith(F("TOG"))) {
        setLeftPadOrAllToggle(F("1111")); // set toggle for left button
        dialogList(1, F("LEFT PAD MODE AT TOGGLE"), F("SELECT,INDIVIDUAL,TWO GROUP,ONLY ONE")); // dialog message
      }
    } else if (id == 1) {
      if (temp.startsWith(F("IND"))) leftPadMode = 1; // independant
      else if (temp.startsWith(F("TWO"))) leftPadMode = 2; // 2 group: up/down, left/right
      else if (temp.startsWith(F("ONL"))) leftPadMode = 4; // 4psc button is 1 group
      setLeftPadMode(leftPadMode);
    } else if (id == 2) {
      if (temp.startsWith(F("PUS"))) { rightPadMode = 0; setRightPadToggle(F("0000")); } // set push for right button
      else { rightPadMode = 1; setRightPadToggle(F("1111")); }
    }
  }
  else if (temp.startsWith(F("STR"))) {  }       // Input text
}

 

3.ARDUINO_ESP01_JOYSTICK_MENU.zip

3.ARDUINO_ESP01_JOYSTICK_MENU.zip
0.01MB

 

https://youtu.be/oa89VEVs-IM

 

 

App Wifi Manager

You can change the ID and password for connecting to access points and a router without using HTML code.

 

4.ARDUINO_ESP01_JOYSTICK_NAME.zip

4.ARDUINO_ESP01_JOYSTICK_NAME.zip
0.01MB

 

https://youtu.be/FlHNzvcrFOY

 

 

App Login

When connecting through a router, obtain control authority using password of the access point.

 

5.ARDUINO_ESP01_JOYSTICK_PASS.zip

5.ARDUINO_ESP01_JOYSTICK_PASS.zip
0.01MB

 

https://youtu.be/GD8_yDmlI_8

 

[Arduino/ADUPAD] - ADUPAD - Arduino wireless remote control PAD application

 

 

 

 

 

+ Recent posts