1st release version. Set TYBLE16 as Central mode

Dependencies:   mbed

Fork of TYBLE16_BME280_data_sender by Kenji Arai

Please refer following page.
/users/kenjiArai/notebook/tyble16-module--uart-communication-between-central/#

Files at this revision

API Documentation at this revision

Comitter:
kenjiArai
Date:
Sun Nov 19 09:43:39 2017 +0000
Parent:
1:f2982d4f4037
Commit message:
1st release version. Set TYBLE16 as Central mode

Changed in this revision

BME280.lib Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- a/BME280.lib	Sun Oct 29 23:25:26 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://mbed.org/users/MACRUM/code/BME280/#c1f1647004c4
--- a/main.cpp	Sun Oct 29 23:25:26 2017 +0000
+++ b/main.cpp	Sun Nov 19 09:43:39 2017 +0000
@@ -12,186 +12,317 @@
  *  http://www.page.sannet.ne.jp/kenjia/index.html
  *  http://mbed.org/users/kenjiArai/
  *      Created:    October   27th, 2017
- *      Revised:    October   30th, 2017
+ *      Revised:    November  19th, 2017
  */
 
 /*
     Tested condition
-        mbed-os-5.6.3 & mbed Rev.154
-    Nucleo-F446RE   TYBLE16 /also F411RE & F042K6(only mbed & pin assign differ)
-        PA_9         pin5 / P0.03(UART_RX)
-        PA_10        pin6 / P0.01(UART_TX)
-                     pin7 / P0.02(UART_CTS) connected to pin8 / P0.00(UART_RTS)
+        mbed-os-5.6.4 & mbed Rev.157(release 155)
+    Nucleo-F446RE   TYBLE16 /also F411RE
+        PA_9 (D8)    pin5  / P0.03(UART_RX)
+        PA_10(D2)    pin6  / P0.01(UART_TX)
+                     pin7  / P0.02(UART_CTS) connected to pin8 / P0.00(UART_RTS)
         +3.3v        pin14 / +V
         GND          pin13 / GND
-    Nucleo-F446RE   BME280
-        PB_9(SDA)    SDI
-        PB_8(SCL)    SDK
-                     SDO = GND, CSB = +3.3V
-    Communcation with iPhone 7 iOS 11.0.3
-        TYs Terminal App
-        https://itunes.apple.com/jp/app/tys-terminal-app/id1184640145?mt=8
+ */
+
+/*
+  --- HOW TO SET "CENTRAL(CLIENT) MODE" ---
+    TYBLE16 default setting is "Peripheral(Server) Mode"
+    If you want to use it as "Central mode", you need to proceed follows
+    1) You run this program on a Mbed board connected with TYBLE16 module
+    2) Just after running the program, you can identify the mode "Central" or
+       "Peripheral" in your terminal screen
+    3) If your module is "Peripheral", please enter 'c' for switching the mode
+    4) Power off the module then restart again and check the mode
+    5) Please use
+       "TYBLE16_UART_Central_and_Peripheral" program as sample application
  */
 
 //  Include --------------------------------------------------------------------
 #include "mbed.h"
-#include "BME280.h"
 
 //  Definition -----------------------------------------------------------------
-#define     TIME_OUT         5       // 5 sec
-#define     ADT_TIME        15       // 15 sec
+enum operating_mode_t {
+    MODE_UNKNOWN            = -1,   // Unknown Error
+    MODE_CENTRAL            =  0,   // Central
+    MODE_PERIPHERAL         =  1,   // Peripheral
+};
 
 //  Object/ Constructor --------------------------------------------------------
 Serial      pc(USBTX,USBRX);
-Serial      tyble16(PA_9, PA_10);
-BME280      bme280(I2C_SDA, I2C_SCL);
+Serial      tyble16(D8, D2);    // Choose proper pin assignment in your Mbed
+Ticker      t;
 
 //  RAM ------------------------------------------------------------------------
-bool        state_connection    = false;
-bool        received_data       = false;
-uint32_t    cmd_timeout_cntr    = ADT_TIME;
-Ticker      t;
+uint8_t timeout_readable;
+operating_mode_t my_role;
+uint8_t cmd[8];
 
 //  ROM / Constant data --------------------------------------------------------
+char *const msg =
+    "Set TYBLE16 Central or Peripheral, created on UTC: "__TIME__","__DATE__"";
+char *const err_msg =
+    "Cannot detect BLE! Please check the hardware!\r\n";
+char *const ble_msg = "-- From BLE(followed line) --";
+char *const cmd_force_reset = "BRS\r\n";
+char *const cmd_advert_stop = "BCD0\r\n";
+char *const cmd_change_to_c = "BRL1\r\n";
+char *const cmd_change_to_p = "BRL0\r\n";
 
 //  Function prototypes --------------------------------------------------------
-void check_connection(void);
-void parse_input(char *buf);
+void set_central_mode(void);
+void one_sec(void);
+void get_line (char *, int);
+void stop_broadcasting(char *);
+char *get_ble_message(char *);
+void command_preparation(void);
 
 //------------------------------------------------------------------------------
 //  Control Program
 //------------------------------------------------------------------------------
-// special command for BME280 data collection
-bool excute_command(char *buf)
-{
-    char c = buf[1];
-    switch (c){
-        case 'a':       // All data
-        case 'A':
-            tyble16.printf("Pressure: %04.2f hPa\r\n",
-                            bme280.getPressure());
-            tyble16.printf("Temperature: %2.2f degC\r\n",
-                            bme280.getTemperature());
-            tyble16.printf("Humidity: %2.2f %%\r\n",
-                            bme280.getHumidity());
-            break;
-        case 'p':       // Pressure
-        case 'P':
-            tyble16.printf("Pressure: %04.2f hPa\r\n",
-                            bme280.getPressure());
-            break;
-        case 't':       // Temperature
-        case 'T':
-            tyble16.printf("Temperature: %2.2f degC\r\n",
-                            bme280.getTemperature());
-            break;
-        case 'h':       // Humidity
-        case 'H':
-            tyble16.printf("Humidity: %2.2f %%\r\n",
-                            bme280.getHumidity());
-            break;
-        case '?':       // Help
-            tyble16.printf("Command syntax\r\n");
-            tyble16.printf("@a All of data\r\n");
-            tyble16.printf("@p Pressure\r\n");
-            tyble16.printf("@t Temperature\r\n");
-            tyble16.printf("@h Humidity\r\n");
-            break;
-        default:        // no available command
-            tyble16.printf("ommand not available, hit '@?'\r\n");
-            break;
-    }
-    return true;
-}
-
 int main()
 {
-    static char rcv_bf[128];
-    static uint8_t n = 0;
-    char c = 0;
-
-    pc.printf("\r\n\r\nApplication for AE-TYBLE16 Module ");
-    pc.printf(" Peripheral(Sever) side\r\n");
-    pc.printf("  created on %s %s\r\n", __DATE__, __TIME__);
-    tyble16.printf("I'm TYBLE16 module!\r\n");
-    // warming up the sensor
-    for (int n = 0; n < 6; n++){
-        bme280.getPressure();
-        bme280.getTemperature();
-        bme280.getHumidity();
-    }
-    t.attach(check_connection, 1);
+    command_preparation();
+    pc.printf("\r\n\r\n%s\r\n", msg); 
+    t.attach(&one_sec, 1.0f);
     while(true){
-        while(tyble16.readable()){
-            //----- data receive from Client -----------------------------------
-            received_data = true;
-            c = tyble16.getc();         // received data from client
-            pc.putc(c);                 // show to console
-            rcv_bf[n++] = c;            // save int buf
-            if (c == '\n'){             // end one line
-                pc.putc('\r');
-                rcv_bf[n] = 0;
-                if (n >3){
-                    parse_input(rcv_bf);    // ckeck command or not
-                    /*for (int i=0;; i++){
-                        if (rcv_bf[i] == 0){break;}
-                        pc.printf("0x%x,", rcv_bf[i]);
-                    }*/
-                    if ((rcv_bf[0] == '@') && (rcv_bf[2] == '\r')){
-                        excute_command(rcv_bf); // BME280 data output 
-                    }
-                }
-                n = 0;  // Clear buffer
+        set_central_mode();
+    }
+}
+
+// Every 1 second
+void one_sec(void){               // execute every 1second
+    if( timeout_readable){        --timeout_readable; }
+}
+
+// Peripheral mode (Default setting) change to Central mode
+void set_central_mode(void)
+{
+    static char linebuf[64];
+    static char blebuf[64];
+    char *ptr;
+    char c;
+
+    // Reset BLE
+    pc.printf("Start from BLE reset\r\n");
+    {   // need to keep this order (does not divide each other)
+        tyble16.puts(cmd_force_reset);
+        pc.printf("force to reset\r\n%s%s\r\n",
+                ble_msg, get_ble_message(blebuf));
+    }
+    if (strstr(blebuf , "Ver.") != NULL){
+        ;
+    } else {
+        pc.printf(err_msg);
+        while(true){;}
+    }  
+    wait_ms(10);
+    // Stop current action
+    {   // need to keep this order (does not divide each other)
+        tyble16.puts(cmd_advert_stop);
+        get_ble_message(blebuf);
+    }
+    if (strstr(blebuf , "ACK") != NULL){
+        my_role = MODE_PERIPHERAL;
+    } else if (strstr(blebuf , "NAK") != NULL){
+        {   // need to keep this order (does not divide each other)
+            tyble16.printf("%s", cmd);
+            get_ble_message(blebuf);
+        }
+        if (strstr(blebuf , "ACK") != NULL){
+            my_role = MODE_CENTRAL;
+        } else {
+            pc.printf(err_msg);
+            while(true){;}
+        }
+    } else {
+        pc.printf(err_msg);
+        while(true){;}
+    }
+    pc.printf("Current mode: ");
+    if (my_role == MODE_CENTRAL){
+        pc.printf("Central\r\n");
+    } else if (my_role == MODE_PERIPHERAL){
+        pc.printf("Peripheral\r\n");
+    } else {
+        pc.printf("unknown\r\n");
+    }
+    c = linebuf[0];
+    stop_broadcasting(blebuf);
+    pc.printf("Define Central or Peripheral\r\n");
+    pc.printf("Central -> c, Peripheral -> p, ");
+    pc.printf("Keep current setting -> any key\r\n");
+    pc.printf("Please enter c or p\r\n=");
+    ptr = linebuf;
+    get_line(ptr, sizeof(linebuf));
+    pc.putc('\r');
+    c = linebuf[0];
+    if ((c == 'c') || (c == 'C')){
+        pc.printf(cmd_change_to_c);
+        {   // need to keep this order (does not divide each other)
+            tyble16.printf(cmd_change_to_c);
+            pc.printf("Switch to Central\r\n%s%s\r\n",
+                    ble_msg, get_ble_message(blebuf));
+        }
+        if (strstr(blebuf , "ACK") != NULL){     // check ACK words
+            my_role = MODE_CENTRAL;
+            pc.printf("BST5010000\r\n");
+            {// need to keep this order (does not divide each other)
+                tyble16.printf("BST5010000\r\n");
+                pc.printf("Set PSKEY value\r\n");
+                pc.printf("Checking paired signal forever\r\n");
+            }
+            pc.printf("Changed to Central mode\r\nPlease power-off");
+            pc.printf(" then Peripheral will active!\r\n");
+        } else if (strstr(blebuf , "NAK") != NULL){
+            if (my_role == MODE_PERIPHERAL){
+                pc.printf("Stay in Periphral mode\r\n");
+            } else {
+                pc.printf("Stay in Central mode\r\n");
+            }
+        } else {
+            pc.printf("??\r\n");
+        }
+    } else if ((c == 'p') || (c == 'P')){
+        pc.printf(cmd_change_to_p);
+        {   // need to keep this order (does not divide each other)
+            tyble16.printf(cmd_change_to_p);
+            pc.printf("Switch to Peripheral\r\n%s%s\r\n",
+                    ble_msg, get_ble_message(blebuf));
+        }
+        if (strstr(blebuf , "ACK") != NULL){     // check ACK words
+            my_role = MODE_PERIPHERAL;
+            pc.printf("BST501003C\r\n");
+            {// need to keep this order (does not divide each other)
+                tyble16.printf("BST501003C\r\n"); // default data 60 sec
+                pc.printf("Set PSKEY value\r\n");
+                pc.printf("Advertising 60sec timeout\r\n");
+            }
+            pc.printf("Changed to Periphral mode\r\nPlease power-off");
+            pc.printf(" then Peripheral will active!\r\n");
+        } else if (strstr(blebuf , "NAK") != NULL){
+            if (my_role == MODE_PERIPHERAL){
+                pc.printf("Stay in Periphral mode\r\n");
+            } else {
+                pc.printf("Stay in Central mode\r\n");
+            }
+        } else {
+            pc.printf("??\r\n");
+        }
+    } else {
+        pc.printf("Keep current setting\r\n");
+    }
+    pc.printf("Hit any key to go again!\r\n");
+    while(pc.getc() == 0){;}
+}
+
+void stop_broadcasting(char *buf)
+{
+    // Stop Advertising or Scanning (just in case)
+    if (my_role == MODE_PERIPHERAL){
+        pc.printf("Stop Advertising\r\n");
+        tyble16.puts(cmd_advert_stop);
+    } else {
+        pc.printf("Stop Central action\r\n");
+        tyble16.printf("%s", cmd);
+    }
+    // need to keep this order (does not divide puts & get_ble_message)
+    pc.printf("%s%s\r\n", ble_msg, get_ble_message(buf));
+    if (buf[2] == 'A'){
+        if (buf[3] ==  'C'){
+            if (buf[4] ==  'K'){
+                return;
             }
         }
-        while(pc.readable()){
-            //----- data send to Client ----------------------------------------
-            char c = pc.getc();
-            tyble16.putc(c);
-            pc.putc(c);                 // echo back
-            if(c == '\r'){              // if CR then put LF
-                tyble16.putc('\n');
-                pc.putc('\n');
+    }
+    if (my_role == MODE_PERIPHERAL){
+        pc.printf("Try again,Stop Central action\r\n");
+        tyble16.printf("%s", cmd);
+    } else {
+        pc.printf("Try again,Stop Advertising\r\n");
+        tyble16.puts(cmd_advert_stop);   // try Peripheral
+    }
+    // need to keep this order (does not divide puts & get_ble_message)
+    pc.printf("n%s%s\r\n", ble_msg, get_ble_message(buf));
+    if (buf[2] == 'A'){
+        if (buf[3] ==  'C'){
+            if (buf[4] ==  'K'){
+                // change role C to P or P to C
+                if (my_role == MODE_PERIPHERAL){
+                    my_role = MODE_CENTRAL;
+                    pc.printf("Mode changes to Central\r\n");
+                } else {
+                    my_role = MODE_PERIPHERAL;
+                    pc.printf("Mode changes to Peripheral\r\n");
+                }
+                return;
             }
         }
     }
 }
 
-// Check Response Events
-void parse_input(char *buf)
+char *get_ble_message(char *buf)
+{
+    char c;
+
+    uint8_t cr_cnt = 0;
+    uint16_t i = 0;
+    timeout_readable = 5u;  // 5sec
+    while (true){
+        c = tyble16.getc();
+        buf[i++] = c;
+        if (c == '\n'){
+            ++cr_cnt;
+        }
+        if ((cr_cnt == 2u) || (timeout_readable == 0)){
+            buf[i] = 0;
+            break;
+        }
+    }
+    return buf;
+}
+
+//  Get key input data
+void get_line (char *buff, int len)
 {
-    if        (strstr(buf, "CON")){     // Connection successful
-        state_connection = true;
-    } else if (strstr(buf, "DCO")){     // Disconnect
-        state_connection = false; 
-    } else if (strstr(buf, "ADT")){     // Advertising Timeout
-        state_connection = false;
-        cmd_timeout_cntr = 0;
-    } else if (strstr(buf, "NAK")){     // Failed
-        state_connection = false;
-        if (cmd_timeout_cntr == 0){
-            // Both Advertising Start. Connectable and Discoverable.
-            tyble16.printf("BCD3\r\n");     // send Advertising command
-            cmd_timeout_cntr = ADT_TIME;
+    char c;
+    int idx = 0;
+
+    for (;;) {
+        c = pc.getc();
+        if (c == '\r') {
+            buff[idx++] = c;
+            break;
+        }
+        if ((c == '\b') && idx) {
+            idx--;
+            pc.putc(c);
+            pc.putc(' ');
+            pc.putc(c);
+        }
+        if (((uint8_t)c >= ' ') && (idx < len - 1)) {
+            buff[idx++] = c;
+            pc.putc(c);
         }
     }
+    buff[idx++] = '\r';     // <CR>
+    buff[idx++] = '\n';     // <LF>
+    buff[idx] = 0;
+    pc.putc('\n');
+}
+
+// You do not need to understand & just execute
+void command_preparation(void)
+{
+    char *const cmd_abc    = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n";
+    char cmd_abc_order[10] = {1,18,2,0x80,26,27,0xff,0xff,0xff,0xff};
+
+    char *p = cmd_abc;
+    for(uint32_t i = 0; i < 8;i++){
+        char c = cmd_abc_order[i];
+        if(c == 0x80){cmd[i] = '0';} else
+        if(c == 0xff){cmd[i] = 0;} else
+                     {cmd[i] = *(p + c);}
+    }
 }
-
-// Every one second, check communication status
-void check_connection(void)
-{
-    static int8_t counter = 0;
-
-    if ((received_data == false) && (state_connection == false)){
-        if (++counter >= TIME_OUT){
-            tyble16.putc('\n');
-            counter = 0;
-        }
-    } else {
-        counter = 0;
-    }
-    if (cmd_timeout_cntr != 0){
-        --cmd_timeout_cntr;
-    }
-    received_data = false;
-}
--- a/mbed-os.lib	Sun Oct 29 23:25:26 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://github.com/ARMmbed/mbed-os/#e62a1b9236b44e70ae3b0902dc538481c04d455b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Nov 19 09:43:39 2017 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/mbed_official/code/mbed/builds/e7ca05fa8600
\ No newline at end of file