BLE and Wifi dont work properly toghether
Posted: 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)
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);
}