1st release version. Set TYBLE16 as Central mode
Fork of TYBLE16_BME280_data_sender by
Please refer following page.
/users/kenjiArai/notebook/tyble16-module--uart-communication-between-central/#
Revision 2:17fdd6d3877f, committed 2017-11-19
- 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
--- 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