BLE and Wifi dont work properly toghether

unme11
Posts: 2
Joined: Sun Oct 01, 2017 2:10 pm

BLE and Wifi dont work properly toghether

Postby unme11 » Sun Oct 01, 2017 2:22 pm

Hi,
I want to scan for beacons and then transmit the information to the user by implementing a web server on ESP32. I implemented a code for scanning for beacons and it works perfectly. Then I implemented a web server using "https://github.com/cmmakerclub/esp32-webserver". The web server works alright and I can get HTTP response whenever I want and its fast. However, when I try to merge the codes into a one that scans for beacons and also has the web server code, HTTP web page becomes very slow. I should wait a lot of time which is not constant for getting a response from the webserver. I guess that's because scan Task doesn't allow the web server Task to work properly. I even tried to run them on separate cores but the problem is still there. How can I solve the problem?
Here is my merged code( and again: web server code and BLE code work perfectly when they are separate)

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "bt.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "freertos/task.h"
#include "nvs_flash.h"
#include "sdkconfig.h"

#include "esp_blufi_api.h"
#include "esp_bt_defs.h"
#include "esp_bt_device.h"
#include "esp_bt_main.h"
#include "esp_gap_ble_api.h"


#include "freertos/FreeRTOS.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
#include "freertos/portmacro.h"
#include "freertos/event_groups.h"
#include "esp_log.h"
#include "tcpip_adapter.h"
static EventGroupHandle_t wifi_event_group;
const int CONNECTED_BIT = BIT0;
//static char* TAG = "app_main";

#include "lwip/err.h"
#include "string.h"


#define LED_BUILTIN 16
#define delay(ms) (vTaskDelay(ms/portTICK_RATE_MS))

// The IP address that we want our device to have.
#define DEVICE_IP          "192.168.1.20"

// The Gateway address where we wish to send packets.
// This will commonly be our access point.
#define DEVICE_GW          "192.168.1.2"

// The netmask specification.
#define DEVICE_NETMASK     "255.255.255.0"



const static char http_html_hdr[] =
    "HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n";
const static char http_index_hml[] = "<!DOCTYPE html>"
      "<html>\n"
      "<head>\n"
      "  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n"
      "  <style type=\"text/css\">\n"
      "    html, body, iframe { margin: 0; padding: 0; height: 100%; }\n"
      "    iframe { display: block; width: 100%; border: none; }\n"
      "  </style>\n"
      "<title>HELLO ESP32</title>\n"
      "</head>\n"
      "<body>\n"
      "<h1>Hello World, from ESP32!</h1>\n"
      "</body>\n"
      "</html>\n";
const int MAX_string=100;
static char wi_bu[100];

#include "lwip/sys.h"
#include "lwip/netdb.h"
#include "lwip/api.h"

extern void bt_task(void *ignore);

static const char tag[] = "BLE";

    static esp_ble_scan_params_t ble_scan_params = {
        .scan_type = BLE_SCAN_TYPE_PASSIVE,
        .own_addr_type = BLE_ADDR_TYPE_PUBLIC,
        .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
        .scan_interval = 0x20,
        .scan_window =  0x20};


long num_scan=0;
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
    esp_ble_gap_cb_param_t *p = (esp_ble_gap_cb_param_t *)param;
	if( p->scan_rst.search_evt==ESP_GAP_SEARCH_INQ_CMPL_EVT)
	{
		
	esp_bt_controller_disable(); // reinit ... 
	esp_bt_controller_enable(ESP_BT_MODE_BTDM);  // ... bluetooth
	esp_ble_gap_set_scan_params(&ble_scan_params); // reset parameters
	esp_ble_gap_start_scanning(100); 
	
	}
    else if (p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT) {
        // Check for iBeacon adv prefix. Ignore 3rd byte, this varies from beacon type to beacon type
        /*
		p->scan_rst.ble_adv[2] = 0x00;
        for (int i = 0; i < sizeof(ibeacon_prefix); i++) {
            if (p->scan_rst.ble_adv[i] != ibeacon_prefix[i]) {
                return;
            }
        }
		*/
		/*
		strcpy(wi_bu, "BDA:");
		
		for(int i=0;i<6;i++)
		{
			char snum[5];
			itoa(p->scan_rst.bda[i], snum, 10);
			strcat(wi_bu, snum);
		}

		*/
        ESP_LOGI(tag, "BDA %02X:%02X:%02X:%02X:%02X:%02X, RSSI %d",
                 p->scan_rst.bda[0],
                 p->scan_rst.bda[1],
                 p->scan_rst.bda[2],
                 p->scan_rst.bda[3],
                 p->scan_rst.bda[4],
                 p->scan_rst.bda[5],

                 p->scan_rst.rssi

                 );
    }
}

void bt_task(void *ignore) {
    esp_err_t ret;
    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    esp_bt_controller_init(&bt_cfg);

    ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM);
    if (ret) {
        ESP_LOGE(tag, "%s enable bt controller failed\n", __func__);
        goto end;
    }

    ret = esp_bluedroid_init();
    if (ret != ESP_OK) {
        ESP_LOGE(tag, "%s init bluedroid failed\n", __func__);
        goto end;
    }

    ret = esp_bluedroid_enable();
    if (ret) {
        ESP_LOGE(tag, "%s enable bluedroid failed\n", __func__);
        goto end;
    }
    ret = esp_ble_gap_register_callback(gap_event_handler);
    if (ret != ESP_OK) {
        ESP_LOGE(tag, "esp_ble_gap_register_callback: rc=%d", ret);
        goto end;
    }



    ret = esp_ble_gap_set_scan_params(&ble_scan_params);
    if (ret != ESP_OK) {
        ESP_LOGE(tag, "esp_ble_gap_set_scan_params: rc=%d", ret);
        goto end;
    }

    ret = esp_ble_gap_start_scanning(100);
    if (ret != ESP_OK) {
        ESP_LOGE(tag, "esp_ble_gap_start_scanning: rc=%d", ret);
        goto end;
    }
	ESP_LOGI(tag,"HELLO");
    ESP_LOGI(tag, "Wait for scans...");
end:
    vTaskDelete(NULL);
}

static esp_err_t event_handler(void *ctx, system_event_t *event)
{
    switch(event->event_id) {
    case SYSTEM_EVENT_STA_START:
        esp_wifi_connect();
        break;
    case SYSTEM_EVENT_STA_GOT_IP:
        xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
        printf("got ip\n");
        printf("ip: " IPSTR "\n", IP2STR(&event->event_info.got_ip.ip_info.ip));
        printf("netmask: " IPSTR "\n", IP2STR(&event->event_info.got_ip.ip_info.netmask));
        printf("gw: " IPSTR "\n", IP2STR(&event->event_info.got_ip.ip_info.gw));
        printf("\n");
        fflush(stdout);
        break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
        /* This is a workaround as ESP32 WiFi libs don't currently
           auto-reassociate. */
        esp_wifi_connect();
        xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
        break;
    default:
        break;
    }
    return ESP_OK;
}

static void initialise_wifi(void)
{
    tcpip_adapter_init();
    wifi_event_group = xEventGroupCreate();
	
	tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA); // Don't run a DHCP client
	tcpip_adapter_ip_info_t ipInfo;

	inet_pton(AF_INET, DEVICE_IP, &ipInfo.ip);
	inet_pton(AF_INET, DEVICE_GW, &ipInfo.gw);
	inet_pton(AF_INET, DEVICE_NETMASK, &ipInfo.netmask);
	tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_STA, &ipInfo);
	
	
	
    ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
    ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
    wifi_config_t sta_config = {
        .sta = {
            .ssid = "amino",
            .password = "aminMyad123",
            .bssid_set = false
        }
    };

    ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config) );
    ESP_ERROR_CHECK( esp_wifi_start() );
}

static void
http_server_netconn_serve(struct netconn *conn)
{
  struct netbuf *inbuf;
  char *buf;
  u16_t buflen;
  err_t err;

  /* Read the data from the port, blocking if nothing yet there.
   We assume the request (the part we care about) is in one netbuf */
  err = netconn_recv(conn, &inbuf);

  if (err == ERR_OK) {
    netbuf_data(inbuf, (void**)&buf, &buflen);

    // strncpy(_mBuffer, buf, buflen);

    /* Is this an HTTP GET command? (only check the first 5 chars, since
    there are other formats for GET, and we're keeping it very simple )*/
    printf("buffer = %s \n", buf);
    if (buflen>=5 &&
        buf[0]=='G' &&
        buf[1]=='E' &&
        buf[2]=='T' &&
        buf[3]==' ' &&
        buf[4]=='/' ) {
          printf("buf[5] = %c\n", buf[5]);
      /* Send the HTML header
             * subtract 1 from the size, since we don't send the \0 in the string
             * NETCONN_NOCOPY: our data is const static, so no need to copy it
       */

      netconn_write(conn, http_html_hdr, sizeof(http_html_hdr)-1, NETCONN_NOCOPY);
        /* Send our HTML page */
        netconn_write(conn, http_index_hml, sizeof(http_index_hml)-1, NETCONN_NOCOPY);
    }

  }
  /* Close the connection (server closes in HTTP) */
  netconn_close(conn);

  /* Delete the buffer (netconn_recv gives us ownership,
   so we have to make sure to deallocate the buffer) */
  netbuf_delete(inbuf);
}

static void http_server(void *pvParameters)
{
  struct netconn *conn, *newconn;
  err_t err;
  conn = netconn_new(NETCONN_TCP);
  netconn_bind(conn, NULL, 80);
  netconn_listen(conn);
  do {
     err = netconn_accept(conn, &newconn);
     if (err == ERR_OK) {
       http_server_netconn_serve(newconn);
       netconn_delete(newconn);
     }
   } while(err == ERR_OK);
   netconn_close(conn);
   netconn_delete(conn);
}


void app_main(void) {
	nvs_flash_init();

    system_init();
    initialise_wifi();
	
     xTaskCreatePinnedToCore(&http_server, "http_server", 8192, NULL, 2, NULL,1);
    xTaskCreatePinnedToCore(&bt_task, "btTask", 2048, NULL, 5, NULL, 0);
}

ESP_Sprite
Posts: 8884
Joined: Thu Nov 26, 2015 4:08 am

Re: BLE and Wifi dont work properly toghether

Postby ESP_Sprite » Sun Oct 01, 2017 3:37 pm

I'm not a BLE person, so this is somewhat guesswork on my side, but essentially, what you're doing is occupying the (single) radio with the BLE scan. While the radio is on a certain frequency listening for BLE packets, it can't also communicate with the AP. Hence, your throughput will be impacted. I'm not sure if there's much you can do about this, except for maybe scanning less often and with a smaller duration; it's a physical issue.

unme11
Posts: 2
Joined: Sun Oct 01, 2017 2:10 pm

Re: BLE and Wifi dont work properly toghether

Postby unme11 » Sun Oct 01, 2017 6:10 pm

Actually, I'm thinking this too. However, I don't get the ESP32 purpose. If it cannot have both BLE and Wifi simultaneously, why did they build it?I mean, separate ICs for each one will be better than having an IC that can implement one of BLE and Wifi completely. I believe that if the IC cannot run both BLE and WIfi simultaneously and completely it is useless. So, I thought that maybe I am wrong and my code can be implemented so that it does the explained. Can anyone help me?

ESP_Sprite
Posts: 8884
Joined: Thu Nov 26, 2015 4:08 am

Re: BLE and Wifi dont work properly toghether

Postby ESP_Sprite » Mon Oct 02, 2017 7:44 am

Obviously, normally BLE and WiFi can be used together. However, this needs some coordination: BLE devices need to be told that the receiver will be doing other things while the ESP32 uses WiFi; WiFi needs to be told the airwaves will be occupied for a second while BLE is doing its stuff. Normally, this can be handled well: with some magic, we may be able to coordinate the two to even occupy the same channel so the radio can keep tabs on both things. This is called coexistence and we're pretty good at it, from what I understand.

However, what you're doing here isn't normal communication, it's passive scanning. For this to work, the ESP32 needs to 'tune into' all BLE channels sequentially and listen in the hope for a beacon to come along. There's no option to coordinate with BLE devices in order to make nice coexistence work; there is no communication with the BLE devices in the first place; the radio just has to be occupied while listening and there is no other option to do anything else.

Again, I'm not a BLE expert so I may be wrong (and I can't ask around because of the holiday here), but as far as I'm aware this is happening. This does *not* mean that BLE and WiFi don't work together, it *only* means that the radio can't both scan and transmit/receive WiFi packets.


Franco
Posts: 101
Joined: Thu Dec 10, 2015 1:11 pm

Re: BLE and Wifi dont work properly toghether

Postby Franco » Mon Oct 02, 2017 8:45 am

unme11 wrote:Actually, I'm thinking this too. However, I don't get the ESP32 purpose. If it cannot have both BLE and Wifi simultaneously, why did they build it?I mean, separate ICs for each one will be better than having an IC that can implement one of BLE and Wifi completely. I believe that if the IC cannot run both BLE and WIfi simultaneously and completely it is useless. So, I thought that maybe I am wrong and my code can be implemented so that it does the explained. Can anyone help me?
One of the good reasons why having BLE and Wi-Fi is to ease Wi-Fi configuration of an ESP32 in station mode via BLE.

rankit0092
Posts: 16
Joined: Tue Jan 23, 2018 5:31 am

Re: BLE and Wifi dont work properly toghether

Postby rankit0092 » Tue Jan 23, 2018 5:56 am

can you send me both separate code??

Who is online

Users browsing this forum: No registered users and 63 guests