반응형

ADUCON application

 

Please refer to the post below for how to connect Arduino and HC-06.

[Arduino] - Arduino Basic code for bluetooth remote contol with HC-06

 

ARDUINO_HC06_BASIC.zip

ARDUINO_HC06_BASIC.zip
0.00MB

 

- loop() function

bool gotData = false;

void loop() {
  if (SerialBT.available()) { // when incomming data from HC06
    uint8_t temp = SerialBT.read();
    Serial.println(temp); // Output data of the HC06 to the serial monitor.
    gotData = true; // the flag for response
  } else {
    if (gotData) {   // if response
      String setVal = "";
      setVal += char(0xF4);      // protocol header of text for ADUCON with bluetooth
      setVal += "Hello World ";
      setVal += random(100,200); // the message for sending
      setVal += char(0xF1);      // protocol footer of text for ADUCON with bluetooth
      Serial.println(setVal);    // Output the message to the serial monitor.
      SerialBT.print(setVal);    // send data to HC06 as response 
      gotData = false;           // initialize the flag
    }
  }
}

 

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

 

Pairing to HC-06 at mobile phone and connecting to HC-06 on the ADUCON app

1. Bluetooth pairing

Select the HC06 on the Bluetooth setting screen of your mobile phone.

Input the password when requesting the pairing password and click the confirm when the connection message is output as shown below.

Bluetooth pairing complete

 

2. Bluetooth 2.0 Search and Connection in the App

Click the Bluetooth icon in the app and select Bluetooth 2.0 in Select Ver.

Click the Bluetooth button and select the HC06.

Select HC06
connected to HC06
received data "248(0xF8) 99(c) 111(o) 110(n) 110(n) 101(e) 99(c) 116(t) 10(\n)"
response from HC06

 

Code for remote control with Bluetooth of ADUCON applications

- SerialBT_read() function

1. Protocol header definition

ADUCON app's protocol header settings
ADUCON app's protocol header settings

Define the headers for Bluetooth in the Arduino sketch according to the protocol header settings in the ADUCON app.

#define pinHD 0xF0
#define pwmHD 0xF3
#define strHD 0xF4
#define footHD 0xF1
#define echoHD 0xE1
#define connectHD 0xF8
#define optionHD 0xF9
#define checkHD 0xF5

 

2. Code to check the connection attempt of ADUCON app

bool appConnection = false;

if (appConnection) { // If app connection is confirmed
  // Execute code after app connection is confirmed
} else {
  if (SerialBT.peek() == connectHD) appConnection = true; // Check if the value is 0xF8.
  else { uint8_t dump = SerialBT.read(); }
}

 

3. Handling of values according to connection header "connectHD(0xF8)"

0xF8 + connect: Transmit the necessary app settings and current Arduino state values through the iniSet() and send_State() functions.

0xF8 + disconnect: Disconnect and change value of appConnection to false.

0xF8 + NA: Change setting values for HC-06.

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

 

4. Handling of values according to option header "optionHD(0xF9)"

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"
  else { // if not
    if (temp.length() < 10) Serial.println(F("alarm")); // set the time if the length of the value is less than 10
    else Serial.println(F("date/time")); // current date/time if larger
  }
}

 

5. Handling of values according to button header "pinHD(0xF0)"

// 0xF0 + 1byte Num + 0xF1
SerialBT.readBytes(data, 3); // Store 3 bytes of data in array "data" from Serial Buffer
if (data[2] == footHD) {     // if the third byte is 0xF1
  pin_control(data[1]);      // execute the code with the value of second byte
  data[2] = 0;
}

 

6. Handling of values according to SeekBar(slide bar) header "pwmHD(0xF3)"

// 0xF3 + 1byte Num(slide number) + 2byte Num(PWM) + 0xF1
while (SerialBT.peek() == pwmHD) { // Process 3 PWM values of COLOR PICKER
  SerialBT.readBytes(data, 5); // Store 5 bytes of data in array "data" from Serial Buffer
  if (data[4] == footHD) {     // if the fifth byte is 0xF1
    uint16_t value = data[3];  // Swap third and fourth bytes
    value = value << 8 | data[2];
    pwm_control(data[1], value); // execute the code with values
    data[4] = 0;
  }
  delay(1);
}
if (pwmEcho) { sendPwmEcho(); pwmEcho = 0; } // Prevent data transmission while receiving data
// refer to "Precautions when using the HC-06 with Serial communication" posted in Basic code.

 

7. Sending a flag that causes the ADUCON app to immediately terminate the timer for receiving data

if (dataSend) { SerialBT.write(checkHD); dataSend = false; } // send 0xF5 to terminate the timer.

 

Protocol function to send data from Arduino to app

1. Change the state of the button.

void sendPinState(uint8_t pin_val){
  uint8_t pin[3] = {pinHD, pin_val, footHD};
  SerialBT.write(pin, 3);
  dataSend = true;
}

 

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

void sendPinEcho(uint8_t pin_val){
  uint8_t pin[3] = {pinHD, pin_val, echoHD};
  SerialBT.write(pin, 3);
  dataSend = true;
}

 

3. Change the slide state of the app.

void sendPwmSlide(uint8_t slide, uint16_t pwm_val) {
  uint8_t pwm[5] = {pwmHD, slide, pwm_val, pwm_val >> 8, footHD};
  SerialBT.write(pwm, 5);
  dataSend = true;
}

 

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

uint8_t pwmEcho = 0;
uint8_t ecVal[18] = { 0, };

void send_pwm_echo(uint8_t slide, uint16_t pwm_val) {
  if (pwmEcho > 5) pwmEcho = 0;
  ecVal[pwmEcho*3] = slide; 
  ecVal[(pwmEcho*3)+1] = pwm_val;
  ecVal[(pwmEcho*3)+2] = pwm_val >> 8;
  pwmEcho++;
}

void sendPwmEcho() {
  uint8_t ch = 0;
  while (pwmEcho) {
    pwmEcho--;
    uint8_t pwm[5] = {pwmHD, ecVal[ch*3], ecVal[(ch*3)+1], ecVal[(ch*3)+2], echoHD};
    SerialBT.write(pwm, 5); ch++;
  }
  dataSend = true;
}

 

- A code example that reflects the status of the current button and PWM values of Arduino to the app when connected to the ADUCON app

void send_State() { // CURRENT STATE
  sendPinState(10);
  sendPinState(21);
  sendPinState(30);
  sendPinState(41);
  sendPinState(50);
  sendPinState(61);
  sendPinState(71);
  sendPinState(80);
  sendPinState(91);
  sendPinState(101);
  sendPinState(110);
  sendPinState(121);
  sendPinState(130);
  sendPinState(141);
  sendPinState(150);
  sendPwmSlide(1, 110);
  sendPwmSlide(2, 120);
  sendPwmSlide(3, 210);
  sendPwmSlide(4, 0);
  sendPwmSlide(5, 0);
  sendPwmSlide(6, 0);
}

Screen reflecting initial state and labels when connecting Arduino

 

5. Send text.

void sendText(String str) {
  String setVal = "";
  setVal += char(strHD);
  setVal += str;
  setVal += char(footHD);
  SerialBT.print(setVal);
  dataSend = true;
}

 

6. Set to send the date/time of the Android system When connecting, or request the transmission of the date/time if necessary.

void requstDateTime(){ 
  uint8_t setVal[3] = {connectHD, 0x01, 0x00};
  SerialBT.write(setVal, 3);
  dataSend = true;
}

 

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

void sendMessage(String str) {
  String setVal = "";
  setVal += char(connectHD);
  setVal += char(0x04);
  setVal += str;
  setVal += char(footHD);
  SerialBT.print(setVal);
  dataSend = true;
}

 

8. Instruct the app to click the Disconnect Button.

void sendDisconnect(){ // order disconnect to App 
  uint8_t setVal[3] = {connectHD, 0x05, 0x00};
  SerialBT.write(setVal, 3);
  dataSend = true;
}

Disconnect Button for Bluetooth

 

9. Set the function to continuously transmit the changed value of the SeekBar (slide bar) according to the specified interval.

true: Active Slide Mode

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

void setActiveSlide(bool val){ 
  uint8_t setVal[4] = {optionHD, 0x01, val, 0x00};
  SerialBT.write(setVal, 4);
  dataSend = true;
}

 

10. Set transmission interval of ACTIVE SLIDE MODE. (Unit: Millisecond)

void setSlideInterval(uint16_t val){ 
  uint8_t setVal[4] = {optionHD, 0x02, val, val >> 8};
  SerialBT.write(setVal, 4);
  dataSend = true;
}

 

11. Activate a timer that sends checkHD(0xF5) 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){ 
  uint8_t setVal[4] = {optionHD, 0x03, val, 0x00};
  SerialBT.write(setVal, 4);
  dataSend = true;
}

 

12. Set the operation interval of the timer sending checkHD(0xF5). (Unit: Millisecond)

void setRequestInterval(uint16_t val){ // val: millis
  uint8_t setVal[4] = {optionHD, 0x04, val, val >> 8};
  SerialBT.write(setVal, 4);
  dataSend = true;
}

 

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

0: No function.

1: Show only connection information when it clicked.

3: 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(other)/3(HC06): show name & pass, defalult: 2
void setSSIDLabelMode(uint8_t val) { 
  uint8_t setVal[4] = {optionHD, 0x05, val, 0x00};
  SerialBT.write(setVal, 4);
  dataSend = true;
}

* Default Pin Number of HC-06 for pairing: 1234 (only 4-Digit number)

 

14. Display additional push buttons in the main menu area. (it is possible to control only at Arduino)

void showDialogMenu(bool val){ 
  uint8_t setVal[4] = {optionHD, 0x06, val, 0x00};
  SerialBT.write(setVal, 4);
  dataSend = true;
}

 

15. Change the main screen to Color Picker / Pwm Nob screen from Arduino. (generally set in the options of the app)

uint8_t: list below

0: Display buttons and SeekBar (slide bar) on the main screen

1: Display Color_Picker on the main screen.

2: Display Color_Picker and Group 2 on the main screen.

3: Display PWM Nob on the main screen.

4: Display PWM Nob and Group 2 on the main screen.

String: name of the group

bool: Sets whether to display the SeekBar (slide bar) when the main screen buttons are displayed.

* true: SeekBar (slide bar) is also displayed when button is displayed or Pwm Nob is displayed

* false: SeekBar (slide bar) is not displayed when button is displayed and SeekBar (slide bar) is displayed only when Pwm Nob is displayed

//0: not use 1:color picke 2:color picker+add group 3: pwm nob 4: pwm nob+add group, group1 & group2 Label
void setColorNob(uint8_t val, String group1, String group2, bool pwmDPMain) { 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x07);
  setVal += val; setVal += ','; 
  setVal += group1; setVal += ','; 
  setVal += group2; setVal += ',';
  setVal += pwmDPMain;
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
}

 

16. Set the main screen display of the app.

Set to 0 or 1 in order depending on whether buttons 1 to 15, SeekBar (slide bar) 1 to 6, text input, and floating buttons are displayed.

0: hidden 1: visible

///////////////////////// SET MAIN DISPLAY
//F("111111111111111"  // button 1 ~ 15, 0:hide 1:display
//  "111111"           // slider 1 ~ 6
//  "11")              // Text Input/Floating Button
void setDisplay(String str){ 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x08);
  setVal += str; 
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
}

 

17. Set labels for buttons and SeekBar.

Label buttons 1 to 15 and SeekBar (slide bar) 1 to 6 in order using ',' as a separator.

//F("BT1,BT2,BT3,BT4,BT5,BT6,BT7,BT8,BT9,BT10,BT11,BT12,BT13,BT14,BT15," // button 1 ~ 15
//  "PW1,PW2,PW3,PW4,PW5,PW6")) // slider 1 ~ 6
void setButtonLabel(String str){ 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x09);
  setVal += str; 
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
}

 

18. Set the button's toggle/push properties.

Set the button properties to 0 or 1 in order of buttons 1 to 15.

0: Push 1: Toggle

//F("111111111111111") // button 1 ~ 15, 0:push 1:toggle 
void setButtonToggle(String str){ 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x0A);
  setVal += str; 
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
}

 

19. Set the maximum/minimum values of the SeekBar (slide bar).

SeekBar (slide bar) Specifies the maximum/minimum values from 1 to 6 in order using ',' as a separator.

//F("0,255,0,255,0,255,0,255,0,255,0,255")
void setMinMax(String str){ 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x0B);
  setVal += str; 
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
}

 

20. Set the title of the Arduino sketch.

//title: Test Mode
//text: Arduino<br/>- WiFi Controler<br/><br/>Manual<br/><a href='https://postpop.tistory.com/8'>https://postpop.tistory.com/8</a>
void setAppTitleMessage(String title, String text){
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x0C);
  setVal += title; setVal += ','; 
  setVal += text; 
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
}

 

21. Dialog Message: radio button

// option = "A,B,C" -> index = 1(A) ~ 3(C)
void dialogRadio(uint8_t id, String title, String option, uint8_t selection){ 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x0D);
  setVal += F("RAD:"); 
  setVal += String(id); setVal += ':';
  setVal += title; setVal += ':';
  setVal += option; setVal += ':';
  setVal += String(selection);
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
} // Return -> RAD:0:1(index) , RAD:id:option index

 

22. Dialog Message: Checkbox

// option = "A,B,C"
void dialogCheckbox(uint8_t id, String title, String option){ 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x0D);
  setVal += F("CKB:"); 
  setVal += String(id); setVal += ':';
  setVal += title; setVal += ':';
  setVal += option; 
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
} // Return -> CKB:0:1,3(index) , CKB:id:option index

 

23. Dialog Message: Select button

// option = "A,B"
void dialogChoose(uint8_t id, String message, String option){ 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x0D);
  setVal += F("CHD:"); 
  setVal += String(id); setVal += ':';
  setVal += message; setVal += ':';
  setVal += option; 
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
} // Return -> CHD:0:B , CHD:id:option str

 

24. Dialog Message: List Window

// option = "A,B,C,D,E,F,G,H"
void dialogList(uint8_t id, String title, String option){ 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x0D);
  setVal += F("LSD:"); 
  setVal += String(id); setVal += ':';
  setVal += title; setVal += ':';
  setVal += option; 
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
} // Return -> LSD:0:F , LSD:id:option str

 

25. Dialog Message: Input text

void dialogInput(uint8_t id, String title){ 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x0D);
  setVal += F("STR:"); 
  setVal += String(id); setVal += ':';
  setVal += title; 
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
} // Return -> STR:0:str , STR:id:str

 

ARDUINO_HMI_BT_CONTROL.zip

ARDUINO_HMI_BT_CONTROL.zip
0.00MB

 

https://youtu.be/9we0UNgdLTw

 

Main sketch

더보기
#include <SoftwareSerial.h> 
#define BT_rxPin 3 // Bluetooth RX -> 3(arduino TX)
#define BT_txPin 2 // Bluetooth TX -> 2(arduino RX)
SoftwareSerial SerialBT(BT_txPin, BT_rxPin); // (arduino RX, arduino TX)

#define btName F("HC06")
#define pass F("1234")  // pin number for paring

#include "protocol.h"

#define ledPin 13

void setup() {
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  Serial.begin(9600);
  SerialBT.begin(9600); //Bluetooth 
  Serial.println(sendData(F("NAME"),btName,false)); // SET NAME "HC06"
  //Serial.println(sendData(F("PIN"),pass,true));   // SET PASS 
  Serial.println(F("Bluetooth 2.0"));
}

void pin_control(uint8_t value) {
  if (value != 0) {
    switch (value) {
      case 11: Serial.println(F("button 1 : on"));
               digitalWrite(ledPin, HIGH); 
               sendPinEcho(value);
               sendText(F("1: ON"));  
                  break;
      case 10: Serial.println(F("button 1 : off"));
               digitalWrite(ledPin, LOW); 
               sendText(F("1: OFF")); 
               sendPinEcho(value);
                  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"));
                  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 : click"));
                  break; 
      case 171: Serial.println(F("button 17 : click"));
                  break;
      case 181: Serial.println(F("button 18 : click"));
                  break;  
      case 191: Serial.println(F("button 19 : click"));
                  break;  
      case 201: Serial.println(F("button 20 : click"));
                dialogList(0, F("MENU"), F("select,Dial Nob,Color Picker,Key Pad,Arrow Pad,Main"));
                  break;               
    }
  }
}

void pwm_control(uint8_t num, uint16_t value) {
  if (num == 1) {  // SeekBar (slide bar) 1
    send_pwm_echo(num, value);
    Serial.print(F("pwm1: ")); Serial.println(value);
  } else if (num == 2) {  // SeekBar (slide bar) 2
    send_pwm_echo(num, value);
    Serial.print(F("pwm2: ")); Serial.println(value);
  } else if (num == 3) {  // SeekBar (slide bar) 3
    send_pwm_echo(num, value);
    Serial.print(F("pwm3: ")); Serial.println(value);
  } else if (num == 4) {  // SeekBar (slide bar) 4
    Serial.print(F("pwm4: ")); Serial.println(value);
  } else if (num == 5) {  // SeekBar (slide bar) 5
    Serial.print(F("pwm5: ")); Serial.println(value);
  } else if (num == 6) {  // SeekBar (slide bar) 6
    Serial.print(F("pwm6: ")); Serial.println(value);
  }
}

bool appConnection = false;
uint8_t data[5] = {0, 0, 0, 0, 0};

void SerialBT_read() {
  if (SerialBT.available()) { 
    if (appConnection) {
      if (SerialBT.peek() == pwmHD) { // 0xF3
        while (SerialBT.peek() == pwmHD) {
          SerialBT.readBytes(data, 5);
          if (data[4] == footHD) {
            uint16_t value = data[3];
            value = value << 8 | data[2];
            pwm_control(data[1], value);
            data[4] = 0;
          }
          delay(1);
        }
        if (pwmEcho) { sendPwmEcho(); pwmEcho = 0; }
      } else if (SerialBT.peek() == pinHD) {  // 0xF0
        SerialBT.readBytes(data, 3);
        if (data[2] == footHD) {
          pin_control(data[1]);
          data[2] = 0;
        }
      } else {
        uint8_t dump;
        if (SerialBT.peek() == checkHD) { dump = SerialBT.read(); dataSend = true; }
        else if (SerialBT.peek() == optionHD || SerialBT.peek() == connectHD) { 
          dump = SerialBT.read();
          String temp = SerialBT.readStringUntil('\n');
          if (dump == connectHD) {
            if (temp == F("connect")) { iniSet(); send_State(); }
            else if (temp == F("disconnect")) { appConnection = false; Serial.println(F("disconnect")); }
            else if (temp.startsWith(F("NA"))) { sendMessage(F("This funtion is not available.")); } 
            else Serial.println(temp);
          } else CheckF9(temp); 
        } else {
          dump = SerialBT.read();
          Serial.write(dump);
        }
      }
      if (dataSend) { SerialBT.write(checkHD); dataSend = false; }
    } else {
      if (SerialBT.peek() == connectHD) appConnection = true;
      else { uint8_t dump = SerialBT.read(); }
    }
  } 
}


void loop() {
  SerialBT_read(); 
  if(Serial.available()) { // if there is data in the serial buffer
    String temp = Serial.readStringUntil('\n'); // option of serial monitor: NEW LINE
    Serial.println(temp);
    if(temp == "on"){ // input serial monitor: "on"
      Serial.println("LED ON");
      sendPinState(11); // button state of the app: on
      sendText("LED ON");
      send_pwm_echo(1, 150);
    } else if(temp == "off"){ // input serial monitor: "off"
      Serial.println("LED OFF");
      send_pwm_echo(1, 150);
      sendPinEcho(10); // button echo: off
      sendText("LED OFF");
    } else if(temp == "1"){   
      
    } 
  }
}

 

Protocol sketch

더보기
//////////////////////////////////////////////////////////// COMMON
///////////////////////////////////////// ESSENTIAL 
#define pinHD 0xF0
#define pwmHD 0xF3
#define strHD 0xF4
#define footHD 0xF1
#define echoHD 0xE1
#define connectHD 0xF8
#define optionHD 0xF9
#define checkHD 0xF5

bool dataSend = false;

void sendPinState(uint8_t pin_val){
  uint8_t pin[3] = {pinHD, pin_val, footHD};
  SerialBT.write(pin, 3);
  dataSend = true;
}

void sendPinEcho(uint8_t pin_val){
  uint8_t pin[3] = {pinHD, pin_val, echoHD};
  SerialBT.write(pin, 3);
  dataSend = true;
}

void sendPwmSlide(uint8_t slide, uint16_t pwm_val) {
  uint8_t pwm[5] = {pwmHD, slide, pwm_val, pwm_val >> 8, footHD};
  SerialBT.write(pwm, 5);
  dataSend = true;
}

uint8_t pwmEcho = 0;
uint8_t ecVal[18] = { 0, };

void send_pwm_echo(uint8_t slide, uint16_t pwm_val) {
  if (pwmEcho > 5) pwmEcho = 0;
  ecVal[pwmEcho*3] = slide; 
  ecVal[(pwmEcho*3)+1] = pwm_val;
  ecVal[(pwmEcho*3)+2] = pwm_val >> 8;
  pwmEcho++;
}

void sendPwmEcho() {
  uint8_t ch = 0;
  while (pwmEcho) {
    pwmEcho--;
    uint8_t pwm[5] = {pwmHD, ecVal[ch*3], ecVal[(ch*3)+1], ecVal[(ch*3)+2], echoHD};
    SerialBT.write(pwm, 5); ch++;
  }
  dataSend = true;
}

void sendText(String str) {
  String setVal = "";
  setVal += char(strHD);
  setVal += str;
  setVal += char(footHD);
  SerialBT.print(setVal);
  dataSend = true;
}

///////////////////////////////////////// CONNECTION 
void requstDateTime(){ 
  uint8_t setVal[3] = {connectHD, 0x01, 0x00};
  SerialBT.write(setVal, 3);
  dataSend = true;
}

//#define passName F("PAS:")
//#define passNameLen 0x04
//
//void requestPass(bool val){ 
//  String setVal = "";
//  setVal += char(connectHD);
//  setVal += char(0x02);
//  if (val) {
//    setVal += char(passNameLen);
//    setVal += passName;
//  } else setVal += char(val);
//  SerialBT.print(setVal);
//  dataSend = true;
//}
//
//void responsePass(bool val){ 
//  uint8_t setVal[3] = {connectHD, 0x03, val};
//  SerialBT.write(setVal, 3);
//  dataSend = true;
//}

void sendMessage(String str) {
  String setVal = "";
  setVal += char(connectHD);
  setVal += char(0x04);
  setVal += str;
  setVal += char(footHD);
  SerialBT.print(setVal);
  dataSend = true;
}

void sendDisconnect(){ // order disconnect to App 
  uint8_t setVal[3] = {connectHD, 0x05, 0x00};
  SerialBT.write(setVal, 3);
  dataSend = true;
}

///////////////////////////////////////// OPTION
///////////////////////// SET FUNCION
void setActiveSlide(bool val){ 
  uint8_t setVal[4] = {optionHD, 0x01, val, 0x00};
  SerialBT.write(setVal, 4);
  dataSend = true;
}

// SEND SLIDE GET VALUE INTERVAL
void setSlideInterval(uint16_t val){ 
  uint8_t setVal[4] = {optionHD, 0x02, val, val >> 8};
  SerialBT.write(setVal, 4);
  dataSend = true;
}

void setRequest(bool val){ 
  uint8_t setVal[4] = {optionHD, 0x03, val, 0x00};
  SerialBT.write(setVal, 4);
  dataSend = true;
}

void setRequestInterval(uint16_t val){ // val: millis
  uint8_t setVal[4] = {optionHD, 0x04, val, val >> 8};
  SerialBT.write(setVal, 4);
  dataSend = true;
}

// 0: not use, 1: show only name, 2(other)/3(HC06): show name & pass, defalult: 2
void setSSIDLabelMode(uint8_t val) { 
  uint8_t setVal[4] = {optionHD, 0x05, val, 0x00};
  SerialBT.write(setVal, 4);
  dataSend = true;
}

void showDialogMenu(bool val){ 
  uint8_t setVal[4] = {optionHD, 0x06, val, 0x00};
  SerialBT.write(setVal, 4);
  dataSend = true;
}

//0: not use 1:color picke 2:color picker+add group 3: pwm nob 4: pwm nob+add group, group1 & group2 Label
void setColorNob(uint8_t val, String group1, String group2, bool pwmDPMain) { 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x07);
  setVal += val; setVal += ','; 
  setVal += group1; setVal += ','; 
  setVal += group2; setVal += ',';
  setVal += pwmDPMain;
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
}

///////////////////////// SET MAIN DISPLAY
//F("111111111111111"  // button 1 ~ 15, 0:hide 1:display
//  "111111"           // slider 1 ~ 6
//  "11")              // Text Input/Floating Button
void setDisplay(String str){ 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x08);
  setVal += str; 
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
}

//F("BT1,BT2,BT3,BT4,BT5,BT6,BT7,BT8,BT9,BT10,BT11,BT12,BT13,BT14,BT15," // button 1 ~ 15
//  "PW1,PW2,PW3,PW4,PW5,PW6")) // slider 1 ~ 6
void setButtonLabel(String str){ 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x09);
  setVal += str; 
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
}

//F("111111111111111") // button 1 ~ 15, 0:push 1:toggle 
void setButtonToggle(String str){ 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x0A);
  setVal += str; 
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
}

//F("0,255,0,255,0,255,0,255,0,255,0,255")
void setMinMax(String str){ 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x0B);
  setVal += str; 
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
}

void setAppTitleMessage(String title, String text){
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x0C);
  setVal += title; setVal += ','; 
  setVal += text; 
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
}

///////////////////////// PERFORM DIALOG
// option = "A,B,C" -> index = 1(A) ~ 3(C)
void dialogRadio(uint8_t id, String title, String option, uint8_t selection){ 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x0D);
  setVal += F("RAD:"); 
  setVal += String(id); setVal += ':';
  setVal += title; setVal += ':';
  setVal += option; setVal += ':';
  setVal += String(selection);
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
} // Return -> RAD:0:1(index) , RAD:id:option index

// option = "A,B,C"
void dialogCheckbox(uint8_t id, String title, String option){ 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x0D);
  setVal += F("CKB:"); 
  setVal += String(id); setVal += ':';
  setVal += title; setVal += ':';
  setVal += option; 
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
} // Return -> CKB:0:1,3(index) , CKB:id:option index

// option = "A,B"
void dialogChoose(uint8_t id, String message, String option){ 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x0D);
  setVal += F("CHD:"); 
  setVal += String(id); setVal += ':';
  setVal += message; setVal += ':';
  setVal += option; 
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
} // 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){ 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x0D);
  setVal += F("LSD:"); 
  setVal += String(id); setVal += ':';
  setVal += title; setVal += ':';
  setVal += option; 
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
} // Return -> LSD:0:F , LSD:id:option str 

void dialogInput(uint8_t id, String title){ 
  String setVal = "";
  setVal += char(optionHD); 
  setVal += char(0x0D);
  setVal += F("STR:"); 
  setVal += String(id); setVal += ':';
  setVal += title; 
  setVal += char(footHD); 
  SerialBT.print(setVal);
  dataSend = true;
} // Return -> STR:0:str , STR:id:str

//////////////////////////////////////////////////////////// INDIVIDUAL
void iniSet() {
  setActiveSlide(true);
  setSSIDLabelMode(0);
  setRequest(false); //setRequestInterval(100);
}

// SEND LOCAL STATE AT PRESENT TO APP
void send_State() { // current state
  sendPinState(10);
  sendPinState(21);
  sendPinState(30);
  sendPinState(41);
  sendPinState(50);
  sendPinState(61);
  sendPinState(71);
  sendPinState(80);
  sendPinState(91);
  sendPinState(101);
  sendPinState(110);
  sendPinState(121);
  sendPinState(130);
  sendPinState(141);
  sendPinState(150);
  sendPwmSlide(1, 110);
  sendPwmSlide(2, 120);
  sendPwmSlide(3, 210);
  sendPwmSlide(4, 0);
  sendPwmSlide(5, 0);
  sendPwmSlide(6, 0);
}

String sendData(String order, String val, bool sendPass) {
  String command = F("AT+");
  command += order;
  command += val;
  if (!sendPass) command += F("\r\n");
  SerialBT.print(command); // send the read character to the SerialBT
  long int time = millis();
  String response = "";
  while( (time+1000) > millis()) {
    while(SerialBT.available()) {  
      char c = SerialBT.read(); 
      response+=c;
    }
  }
  return response;
}

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"))) {  }
  else {  
    if (temp.length() < 10) Serial.println(F("alarm"));
    else Serial.println(F("date/time"));
  }
}

 

Example of using Protocol to set ADUCON app

- ADUCON app settings: label/toggle properties, use of the timer for checkHD(0xF5), Slide Mode settings, etc.

void iniSet() {
  setRequest(false); //setRequestInterval(250); // Disable timer for check(0xF5)
  setDisplay(F("111111111111111" // button 1 ~ 15, 0:hide 1:display
               "111111"          // slider 1 ~ 6
               "11"));           // Text Input/Floating Button
  setColorNob(0, F("GR1"), F("GR2"), false); // Set Color Picker and Pwm Nob
  setButtonLabel(F("BT1,BT2,BT3,BT4,BT5,BT6,BT7,BT8,BT9,BT10,BT11," // set labels
                   "BT12,BT13,BT14,BT15,PW1,PW2,PW3,PW4,PW5,PW6"));
  setButtonToggle(F("111111111111111")); // button 1 ~ 15, toggle setting, 0:push 1:toggle
  setMinMax(F("0,255,0,255,0,255,0,255,0,255,0,255")); // slider 1 ~ 6
  setAppTitleMessage(F("Test Mode"), // Change title for Arduino code on the app
  F("Arduino<br/>- WiFi Controler<br/><br/>Manual<br/>" //Message
    "<a href='https://postpop.tistory.com/8'>"
    "https://postpop.tistory.com/8</a>"));
  setActiveSlide(true); setSlideInterval(100); // Active Slide Mode
  setSSIDLabelMode(0);   // Set the function of the label displaying Wi-Fi connection
  showDialogMenu(true);  // show menu button
}

 

- Example of code processing for each function of a button that changes according to the screen number (pageId).

void pin_control(uint8_t value) {
  if (value != 0) {
    switch (value) {
      case 11: if (pageId == 4) Serial.println(F("powor : on"));
               else Serial.println(F("button 1 : on"));
                  break;
      case 10: if (pageId == 4) Serial.println(F("powor : off"));
               else Serial.println(F("button 1 : off"));
                  break;
      case 21: if (pageId == 4) { 
                 Serial.println(F("motor1 : on")); 
                 sendPinState(30); 
               } else Serial.println(F("button 2 : on"));
                  break;
      case 20: if (pageId == 4) Serial.println(F("motor1 : off"));
               else Serial.println(F("button 2 : off"));
                  break;
      case 31: if (pageId == 4) { 
                 Serial.println(F("motor2 : on")); 
                 sendPinState(20); 
               } else Serial.println(F("button 3 : on"));
                  break;
      case 30: if (pageId == 4) Serial.println(F("motor2 : off"));
               else Serial.println(F("button 3 : off"));
                  break;
      case 201: Serial.println(F("button 20 : click"));
                dialogList(0, F("MENU"), F("select,Dial_Nob,Color_Picker,Key_Pad,Arrow_Pad,Main")); // dialog message
                  break;              
    }
  }
}

 

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

uint8_t pageId = 0;  // screen number

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("Dial"))) {           // Dial Nob screen 
        setDisplay(F("11111111111111111111110")); // hide floating button
        setColorNob(4, F("GR1"), F("GR2"), false); pageId = 1; 
      } else if (temp.startsWith(F("Color"))) {   // Color Picker screen
        setDisplay(F("11111111111111111111110")); // hide floating button
        setColorNob(2, F("GR1"), F("GR2"), false); pageId = 2; 
      } else if (temp.startsWith(F("Key"))) {     // Key Pad screen
        if (pageId <= 2) setColorNob(0, F("GR1"), F("GR2"), false);
        setDisplay(F("11111111111100011111110")); 
        setButtonToggle(F("000000000000111"));
        setButtonLabel(F("1,2,3,4,5,6,7,8,9,*,0,#"));
        pageId = 3;
      } else if (temp.startsWith(F("Arrow"))) {   // Arrow Pad screen
        if (pageId <= 2) setColorNob(0, F("GR1"), F("GR2"), false);
        setDisplay(F("11111101010101011111110")); 
        setButtonToggle(F("111111000000000"));
        setButtonLabel(F("Power,Motor1,Moror2,BT4,BT5,BT6,7,Up,9,Left,0,Right,0,Down"));
        pageId = 4;
      } else {                                    // Main screen
        if (pageId <= 2) { setColorNob(0, F("GR1"), F("GR2"), false); pageId = 0; }
        setDisplay(F("11111111111111111111111"));
        setButtonToggle(F("111111111111111"));
        setButtonLabel(F("BT1,BT2,BT3,BT4,BT5,BT6,BT7,BT8,BT9,BT10,BT11,BT12,BT13,BT14,BT15"));
        send_State();
        pageId = 0;
      }
    }
  }
  else if (temp.startsWith(F("STR"))) {  }       // Input text
  else {  
    if (temp.length() < 6) Serial.println(F("alarm"));
    else Serial.println(F("date/time"));
  }
}

 

ARDUINO_HMI_BT_CONTROL_MENU.zip

ARDUINO_HMI_BT_CONTROL_MENU.zip
0.00MB

 

https://youtu.be/y3eWQIpC_M4

 

 

Change name of HC-06 and Pin Number which is used to pair on ADUCON App

 

- Define array variable to save pin number and name for HC-06.

char pass[5] = "1234";     // 4 NUMER
char btName[11] = "HC06";  // 10 char

 

- EEPROM Setting

#include <EEPROM.h>
void loadConfig() {  // Read ID/Pin number
  for (int i = 0; i < 11; i++) btName[i] = EEPROM.read(1008 + i); // sizeof(pass)-1
  for (int i = 0; i < 4; i++) pass[i] = EEPROM.read(1019 + i); // sizeof(ssid)-1
}

void saveConfig() { // Write ID/Pin number
  for (int i = 0; i < 11; i++) EEPROM.write(1008 + i, btName[i]); // sizeof(pass)-1
  for (int i = 0; i < 4; i++) EEPROM.write(1019 + i, pass[i]); // sizeof(ssid)-1
}

// After uploading the sketch to the Arduino, write it once to the EEPROM or read the values stored in the EEPROM when booting.
void setup() {
  if(EEPROM.read(1023) != 1) { 
    for (int i = 0 ; i < EEPROM.length() ; i++) EEPROM.write(i, 0); // EEPROM Clear
    EEPROM.write(1023, 1);   // flag for status of saving
    saveConfig();      // Write ID and Password at initialization
  } else loadConfig(); // Read saved ID and Password when Arduino is rebooting
}

// EEPROM initialization code at serial monitor
void loop() {
  if(Serial.available()) { // Serial monitor code
    String temp = Serial.readStringUntil('\n'); 
    Serial.println(temp);
    if (temp == F("1")) {
      EEPROM.write(1023, 0);
      Serial.println("EEPROM INI");
    } 
  }
}

 

- Save parsing data for name and pin number and send a message applyed in Arduino.

void changeBTname(String str) { // NA18888HC06
  bool save = false;
  String temp = str.substring(0, 1);
  bool getPass = temp.toInt();
  str.remove(0, 1);
  if (getPass) {
    temp = str.substring(0, 4);
    str.remove(0, 4);
    if (temp != pass) {
      for (int i = 0; i < 4; i++) pass[i] = temp[i];
      save = true;
    }
  } 
  if (str != btName) {
    if (temp != "") {
      for (int i = 0; i < str.length(); i++) btName[i] = str[i];
      btName[str.length()] = '\0';
      save = true; 
    }
  }
  Serial.println(btName);
  Serial.println(pass);
  if (save) {
    saveConfig();
    temp  = F("<p> NAME:  ");
    temp += btName;
    temp += F("</p><p> PASS: ");
    temp += pass;
    temp += F("</p>Value's Saved.");
    temp += F(" It will disconnect for Setting.<br/>try to reconnect.");
    sendMessage(temp);
    sendDisconnect(); delay(1000); 
    Serial.println(sendData(F("NAME"),btName,false)); // SET NAME "HC06"
    Serial.println(sendData(F("PIN"),pass,true));     // SET PASS 
  } else sendMessage(F("There's no change."));
}

 

ARDUINO_HMI_BT_CONTROL_PIN.zip

ARDUINO_HMI_BT_CONTROL_PIN.zip
0.00MB

ARDUINO_EEPROM_INI.zip

ARDUINO_EEPROM_INI.zip
0.00MB

* Change all data to 0 in EEPROM

 

https://youtu.be/BNaIS4CpPaM

 

[Arduino/ADUCON] - ADUCON - Arduino wireless remote control application

 

 

 

 

 

+ Recent posts