SSブログ

ESP32 の BLEデバイス化にチャレンジ!(1) [Arduino]

ESP32 をスマホからBLEデバイスにするために試行錯誤をしています。コードを解析すればうまくいくかなと思ったのですが、なかなかうまくいかない。


DSC04856.JPG


BLEデバイスの中でも一番簡単なTHERMOMETER デバイスなら簡単にいくだろうと思い、 スケッチ化してみることにしました。参考にしたサイトはこちら。


Development of ESP-WROOM-32
https://github.com/mitazet/esp/blob/master/thermometer/main/gatts_thermometer.c


改造した Arduino のスケッチ?(ほぼCのプログラムですが)がこちらです。デバッグコードが入っていて、少し見苦しいですが我慢ください。


#pragma GCC diagnostic push
#pragma GCC diagnostic warning "-fpermissive"

#include 
#include 
#include 
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "bt.h"
#include "bta_api.h"

#include "esp_gap_ble_api.h"
#include "esp_gatts_api.h"
#include "esp_bt_defs.h"
#include "esp_bt_main.h"
#include "esp_bt_main.h"

#include "sdkconfig.h"

#define GATTS_TAG "GATTS_THERMO"

static void gatts_profile_thermo_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);

#define GATTS_SERVICE_UUID_THERMOMETER 0x00FF
#define GATTS_CHAR_UUID_THERMOMETER 0xFF01

#define GATTS_DESCR_UUID_THERMOMETER 0x3333
#define GATTS_NUM_HANDLE_THERMOMETER 4

#define TEST_DEVICE_NAME "ESP_THERMOMETER"


#define GATTS_DEMO_CHAR_VAL_LEN_MAX 0x40

#define PREPARE_BUF_MAX_SIZE 1024

#define PROFILE_NUM 1
#define PROFILE_THERMOMETER_ID 0

uint8_t char1_str[] = {0x11,0x22,0x33};
esp_attr_value_t gatts_demo_char1_val =
{
    .attr_max_len = GATTS_DEMO_CHAR_VAL_LEN_MAX,
    .attr_len = sizeof(char1_str),
    .attr_value = char1_str,
};

static uint8_t service_uuid128[32] = {
    /* LSB <--------------------------------------------------------------------------------> MSB */
    //first uuid, 16bit, [12],[13] is the value
    0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xAB, 0xCD, 0x00, 0x00,
    //second uuid, 32bit, [12], [13], [14], [15] is the value
    0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xAB, 0xCD, 0xAB, 0xCD,
};

static esp_ble_adv_data_t test_adv_data = {
    .set_scan_rsp = false,
    .include_name = true,
    .include_txpower = true,
    .min_interval = 0x20,
    .max_interval = 0x40,
    .appearance = 0x00,
    .manufacturer_len = 0,
    .p_manufacturer_data = NULL,
    .service_data_len = 0,
    .p_service_data = NULL,
    .service_uuid_len = 32,
    .p_service_uuid = service_uuid128,
    .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
};

static esp_ble_adv_params_t test_adv_params;

struct gatts_profile_inst {
    esp_gatts_cb_t gatts_cb;
    uint16_t gatts_if;
    uint16_t app_id;
    uint16_t conn_id;
    uint16_t service_handle;
    esp_gatt_srvc_id_t service_id;
    esp_bt_uuid_t char_uuid;
    esp_bt_uuid_t descr_uuid;
    uint16_t char_handle;
    esp_gatt_perm_t perm;
    esp_gatt_char_prop_t property;
    uint16_t descr_handle;
};

static struct gatts_profile_inst test_profile;

typedef struct {
    uint8_t *prepare_buf;
    int prepare_len;
} prepare_type_env_t;

static prepare_type_env_t a_prepare_write_env;

void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param);
void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param);

static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
    Serial.println("gap_event_handler");

    switch (event) {
    case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
        Serial.println("ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT");
        esp_ble_gap_start_advertising(&test_adv_params);
        break;
        
    case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
        Serial.println("ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT");
        esp_ble_gap_start_advertising(&test_adv_params);
        break;
        
    case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT:
        Serial.println("ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT");
        esp_ble_gap_start_advertising(&test_adv_params);
        break;
        
    case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
        Serial.println("ESP_GAP_BLE_ADV_START_COMPLETE_EVT");
        if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) {
            Serial.println("Advertising start failed\n");
        }
        break;
    case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
        Serial.println("ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT");
        if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS) {
            Serial.println("Advertising stop failed\n");
        }
        else {
            Serial.println("Stop adv successfully\n");
        }
        break;
    case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
        Serial.println("ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT");
        break;
    default:
        break;
    }
}

void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param){
    
    Serial.println("example_write_event_env");
    
    esp_gatt_status_t status = ESP_GATT_OK;

    if (param->write.need_rsp){
        if (param->write.is_prep){
            if (prepare_write_env->prepare_buf == NULL) {
                prepare_write_env->prepare_buf = (uint8_t*)malloc(PREPARE_BUF_MAX_SIZE*sizeof(uint8_t));
                prepare_write_env->prepare_len = 0;
            } else {
                if(param->write.offset > PREPARE_BUF_MAX_SIZE) {
                    status = ESP_GATT_INVALID_OFFSET;
                } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) {
                    status = ESP_GATT_INVALID_ATTR_LEN;
                }
            }
            esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t*)malloc(sizeof(esp_gatt_rsp_t));
            gatt_rsp->attr_value.len = param->write.len;
            gatt_rsp->attr_value.handle = param->write.handle;
            gatt_rsp->attr_value.offset = param->write.offset;
            gatt_rsp->attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE;
            memcpy(gatt_rsp->attr_value.value, param->write.value, param->write.len);
            esp_err_t response_err = esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, gatt_rsp);
            free(gatt_rsp);
            if (status != ESP_GATT_OK) {
                return;
            }
            memcpy(prepare_write_env->prepare_buf + param->write.offset, param->write.value, param->write.len);
            prepare_write_env->prepare_len += param->write.len;
        }else{
            esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, NULL);
        }
    }
}

void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param){ 
    
    Serial.println("example_exec_write_event_env");
    
    if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC){
        esp_log_buffer_hex(GATTS_TAG, prepare_write_env->prepare_buf, prepare_write_env->prepare_len);
    }
    
    if (prepare_write_env->prepare_buf) {
        free(prepare_write_env->prepare_buf);
        prepare_write_env->prepare_buf = NULL;
    }
    
    prepare_write_env->prepare_len = 0;
}

static void gatts_profile_thermo_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) {
  
    switch (event) {
    case ESP_GATTS_REG_EVT:
        Serial.println("ESP_GATTS_REG_EVT");    
        test_profile.service_id.is_primary = true;
        test_profile.service_id.id.inst_id = 0x00;
        test_profile.service_id.id.uuid.len = ESP_UUID_LEN_16;
        test_profile.service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_THERMOMETER;
        esp_ble_gap_set_device_name(TEST_DEVICE_NAME);
        esp_ble_gap_config_adv_data(&test_adv_data);
        esp_ble_gatts_create_service(gatts_if, &test_profile.service_id, GATTS_NUM_HANDLE_THERMOMETER);
        break;
        
    case ESP_GATTS_READ_EVT: {
        Serial.println("ESP_GATTS_READ_EVT");
        char temp1 = 0x1E; // dummy data
        char temp2 = 0x00; // dummy data
        esp_gatt_rsp_t rsp;
        memset(&rsp, 0, sizeof(esp_gatt_rsp_t));
        rsp.attr_value.handle = param->read.handle;
        rsp.attr_value.len = 2;
        rsp.attr_value.value[0] = temp1;
        rsp.attr_value.value[1] = temp2;
        esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id, ESP_GATT_OK, &rsp);
        break;
    }
    case ESP_GATTS_WRITE_EVT: {
        Serial.println("ESP_GATTS_WRITE_EVT");
        example_write_event_env(gatts_if, &a_prepare_write_env, param);
        break;
    }
    case ESP_GATTS_EXEC_WRITE_EVT:
        Serial.println("ESP_GATTS_EXEC_EVT");
        esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL);
        example_exec_write_event_env(&a_prepare_write_env, param);
        break;
        
    case ESP_GATTS_MTU_EVT:
        Serial.println("ESP_GATTS_MTU_EVT");
        break;
        
    case ESP_GATTS_CONF_EVT:
        Serial.println("ESP_GATTS_CONF_EVT");
        break;
        
    case ESP_GATTS_UNREG_EVT:
        Serial.println("ESP_GATTS_UNREG_EVT");
        break;
        
    case ESP_GATTS_CREATE_EVT:
        Serial.println("ESP_GATTS_CREATE_EVT");
        test_profile.service_handle = param->create.service_handle;
        test_profile.char_uuid.len = ESP_UUID_LEN_16;
        test_profile.char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_THERMOMETER;
        
        esp_ble_gatts_start_service(test_profile.service_handle);
        esp_ble_gatts_add_char(test_profile.service_handle, &test_profile.char_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY, &gatts_demo_char1_val, NULL);
        break;
        
    case ESP_GATTS_ADD_INCL_SRVC_EVT:
        Serial.println("ESP_GATTS_ADD_INCL_SRVC_EVT");
        break;

    case ESP_GATTS_ADD_CHAR_EVT: {
        uint16_t length = 0;
        const uint8_t *prf_char;
        
        Serial.println("ESP_GATTS_ADD_CHAR_EVT");
        
        test_profile.char_handle = param->add_char.attr_handle;
        test_profile.descr_uuid.len = ESP_UUID_LEN_16;
        test_profile.descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
        
        esp_ble_gatts_get_attr_value(param->add_char.attr_handle, &length, &prf_char);
        esp_ble_gatts_add_char_descr(test_profile.service_handle, &test_profile.descr_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL);
        break;
    }

    case ESP_GATTS_ADD_CHAR_DESCR_EVT:
        Serial.println("ESP_GATTS_ADD_CHAR_DESCR_EVT");
        break;
        
    case ESP_GATTS_DELETE_EVT:
        Serial.println("ESP_GATTS_DELETE_EVT");
        break;
        
    case ESP_GATTS_START_EVT:
        Serial.println("ESP_GATTS_START_EVT");
        break;
        
    case ESP_GATTS_STOP_EVT:
        Serial.println("ESP_GATTS_STOP_EVT");
        break;
        
    case ESP_GATTS_CONNECT_EVT: {
        Serial.println("ESP_GATTS_CONNECT_EVT");
        
        esp_ble_conn_update_params_t conn_params = {0};
        memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
        
        /* For the IOS system, please reference the apple official documents about the ble connection parameters restrictions. */
        conn_params.latency = 0;
        conn_params.max_int = 0x50; // max_int = 0x50*1.25ms = 100ms
        conn_params.min_int = 0x30; // min_int = 0x30*1.25ms = 60ms
        conn_params.timeout =  400; // timeout = 400*10ms = 4000ms
        test_profile.conn_id = param->connect.conn_id;
        
        //start sent the update connection parameters to the peer device.
        esp_ble_gap_update_conn_params(&conn_params);
        break;
    }
    case ESP_GATTS_DISCONNECT_EVT:
        Serial.println("ESP_GATTS_DISCONNECT_EVT");
        esp_ble_gap_start_advertising(&test_adv_params);
        break;
        
    case ESP_GATTS_OPEN_EVT:
        Serial.println("ESP_GATTS_OPEN_EVT");
        break;

    case ESP_GATTS_CANCEL_OPEN_EVT:
        Serial.println("ESP_GATTS_CANCEL_OPEN_EVT");
        break;

    case ESP_GATTS_CLOSE_EVT:
        Serial.println("ESP_GATTS_CLOSE_EVT");
        break;

    case ESP_GATTS_LISTEN_EVT:
        Serial.println("ESP_GATTS_LISTEN_EVT");
        break;

    case ESP_GATTS_CONGEST_EVT:
        Serial.println("ESP_GATTS_CONGEST_EVT");
        break;

    default:
        break;
    }
}

static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
{
    Serial.println("gatts_event_handler");

    /* If event is register event, store the gatts_if for each profile */
    if (event == ESP_GATTS_REG_EVT) {
        if (param->reg.status == ESP_GATT_OK) {
            test_profile.gatts_if = gatts_if;
        } else {
            return;
        }
    }

    if (gatts_if == ESP_GATT_IF_NONE || gatts_if == test_profile.gatts_if) {
        if (test_profile.gatts_cb) {
            test_profile.gatts_cb(event, gatts_if, param);
        }
    }
}

void setup() {

    Serial.begin(115200);

    /* initialize advertising info */
    test_adv_params.adv_int_min       = 0x20;
    test_adv_params.adv_int_max      = 0x40;
    test_adv_params.adv_type            = ADV_TYPE_IND;
    test_adv_params.own_addr_type  = BLE_ADDR_TYPE_PUBLIC;
    test_adv_params.channel_map     = ADV_CHNL_ALL;
    test_adv_params.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY;

    /* initialize profile and characteristic */
    test_profile.gatts_cb = gatts_profile_thermo_event_handler;
    test_profile.gatts_if = ESP_GATT_IF_NONE; 

    esp_err_t ret;
    
    btStart();
    ret = esp_bluedroid_init();
    if (ret) {
        Serial.println("Init bluetooth failed");
        return;
    }
    ret = esp_bluedroid_enable();
    if (ret) {
        Serial.println("Enable bluetooth failed");
        return;
    }

    esp_ble_gatts_register_callback(gatts_event_handler);
    esp_ble_gap_register_callback(gap_event_handler);
    esp_ble_gatts_app_register(PROFILE_THERMOMETER_ID);

    Serial.println("Bluetooth setup success!");
}

void loop() {
}



LAPIS Computer から出しているスマホアプリの BLE Tools を起動してみると、ESP32_THERMOMETER が見えました!


ESP32_THERMO_1.png


しかし、値は取れず…残念。


ESP32_THERMO_2.png


シリアルモニターを確認すると、CONNECTまでは成功していますが、その後にREADのイベントが発生していません。

Bluetooth setup success!
gatts_event_handler
ESP_GATTS_REG_EVT
gap_event_handler
ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT
gatts_event_handler
ESP_GATTS_CREATE_EVT
gap_event_handler
ESP_GAP_BLE_ADV_START_COMPLETE_EVT
gatts_event_handler
ESP_GATTS_START_EVT
gatts_event_handler
ESP_GATTS_ADD_CHAR_EVT
gatts_event_handler
ESP_GATTS_ADD_CHAR_DESCR_EVT
gatts_event_handler
ESP_GATTS_CONNECT_EVT
gap_event_handler
ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT
gatts_event_handler



うーん、何が原因なのか。そもそもシーケンスが間違っているのか。。。もう少し追いかけてみたいところですが、最近は忙しくて時間がとれないんだよなぁ。
(;´д`)トホホ





waves ESP32-DevKitC ESP-WROOM-32 ESP32 DevKitC V2 WiFi BLE 技適取得済 国内発送

waves ESP32-DevKitC ESP-WROOM-32 ESP32 DevKitC V2 WiFi BLE 技適取得済 国内発送

  • 出版社/メーカー: waves(ウェイブス)
  • メディア: エレクトロニクス



SparkFun ESP32 Thing Development Workshop (English Edition)

SparkFun ESP32 Thing Development Workshop (English Edition)

  • 出版社/メーカー: PE Press
  • 発売日: 2017/04/09
  • メディア: Kindle版



MicroPython for ESP32 Development Workshop (English Edition)

MicroPython for ESP32 Development Workshop (English Edition)

  • 出版社/メーカー:
  • 発売日: 2017/08/19
  • メディア: Kindle版




タグ:ESP32 Arduino BLE
nice!(28)  コメント(0) 
共通テーマ:趣味・カルチャー

ESP32 を Gatt デバイスにしようとするも早くも心が挫けそう。 [Arduino]

ESP32 を BLE デバイスとして使うなら Gatt に準拠したデバイスとして使いたいところ。


DSC04860.JPG


少し調べてみると、Espressif の SDK を使えば Gatt Client にも Gatt Server としても使えそうなのですが、いかんせん面倒。楽して使いたい。

Arduinoで簡単に使えるものがないかなと調べてみたもののやっと見つけたのがこれ。


How to use Arduino ESP32 BLE as a GATT server
http://www.iotsharing.com/2017/07/how-to-use-ble-in-arduino-esp32.html


ちょっと面倒すぎでしょ。毎回こんなにコード書いてらんないし...。簡単に使えるようにならないか、コードとにらめっこしながら考えてみたいと思います。
(ーω ー;





waves ESP32-DevKitC ESP-WROOM-32 ESP32 DevKitC V2 WiFi BLE 技適取得済 国内発送

waves ESP32-DevKitC ESP-WROOM-32 ESP32 DevKitC V2 WiFi BLE 技適取得済 国内発送

  • 出版社/メーカー: waves(ウェイブス)
  • メディア: エレクトロニクス



Bluetooth Low Energyをはじめよう (Make:PROJECTS)

Bluetooth Low Energyをはじめよう (Make:PROJECTS)

  • 作者: Kevin Townsend
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2015/02/25
  • メディア: 単行本(ソフトカバー)



RN4020搭載、簡単Bluetooth LE スティック

RN4020搭載、簡単Bluetooth LE スティック

  • 出版社/メーカー: マイクロテクニカ
  • メディア: おもちゃ&ホビー




タグ:ESP32 Arduino BLE GATT
nice!(27)  コメント(2) 
共通テーマ:趣味・カルチャー

ESP32 で Simple BLE Device を試してみる [Arduino]

ESP32 には、Wi-Fi の他に BLE もついています。サンプルコードに Simple BLE Device というものがあったので、試して見ることにしました。


DSC04860.JPG


スケッチにはボタンをつけろと出ていたので、2番ピンにボタンを追加しました。


simplebledevice.png


スケッチも2番ピンに変更します。こちらがスケッチです。ボタンを押すとクロックから取得した値を割った数をデバイス名”BLE name: ”に追加するようになっています。


// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Sketch shows how to use SimpleBLE to advertise the name of the device and change it on the press of a button
// Useful if you want to advertise some sort of message
// Button is attached between GPIO 0 and GND, and the device name changes each time the button is pressed

#include "SimpleBLE.h"

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

SimpleBLE ble;

void onButton(){
    String out = "BLE32 name: ";
    out += String(millis() / 1000);
    Serial.println(out);
    ble.begin(out);
}

void setup() {
    Serial.begin(115200);
    Serial.setDebugOutput(true);
    pinMode(2, INPUT_PULLUP);
    Serial.print("ESP32 SDK: ");
    Serial.println(ESP.getSdkVersion());
    ble.begin("ESP32 SimpleBLE");
    Serial.println("Press the button to change the device's name");
}

void loop() {
    static uint8_t lastPinState = 1;
    uint8_t pinState = digitalRead(2);
    if(!pinState && lastPinState){
        onButton();
    }
    lastPinState = pinState;
    while(Serial.available()) Serial.write(Serial.read());
}




実際に動かしてみます。コンソールにはボタンを押せと出ていたので、ボタンを押してみます。すると、"BLE32 name: 5" と出ました。


bledevice_console.png


スマホで確認してみると確かにBLE32 name: 5 というデバイスが現れました。


Screenshot.png


でも、このサンプルこれだけ。ここから何かできるわけではありません。うーん、せめてスマホにデータを送るくらいはしたいよなぁ。
(´・ω・`)





waves ESP32-DevKitC ESP-WROOM-32 ESP32 DevKitC V2 WiFi BLE 技適取得済 国内発送

waves ESP32-DevKitC ESP-WROOM-32 ESP32 DevKitC V2 WiFi BLE 技適取得済 国内発送

  • 出版社/メーカー: waves(ウェイブス)
  • メディア: エレクトロニクス



ESP-WROOM-32 WiFi + Bluetooth 無線モジュール お得な2個セット

ESP-WROOM-32 WiFi + Bluetooth 無線モジュール お得な2個セット

  • 出版社/メーカー: マイクロテクニカ
  • メディア: エレクトロニクス



MicroPython for ESP32 Development Workshop (English Edition)

MicroPython for ESP32 Development Workshop (English Edition)

  • 出版社/メーカー:
  • 発売日: 2017/08/19
  • メディア: Kindle版




nice!(30)  コメント(2) 
共通テーマ:趣味・カルチャー

ESP32 Simple WiFi Server を試してみた [Arduino]

ESP32なら WiFi の機能を試してみなければということで、ESP32 のライブラリの中になるサンプルプログラムを試してみました。


DSC04856.JPG


場所は "Documents\Arduino\hardware\espressif\esp32\libraries\WiFi\examples にあります。念のため、サンプルプログラムを貼っておきます。自宅の環境にあわせて SSID と Password を変更しておいてください。


/*
 WiFi Web Server LED Blink

 A simple web server that lets you blink an LED via the web.
 This sketch will print the IP address of your WiFi Shield (once connected)
 to the Serial monitor. From there, you can open that address in a web browser
 to turn on and off the LED on pin 5.

 If the IP address of your shield is yourAddress:
 http://yourAddress/H turns the LED on
 http://yourAddress/L turns it off

 This example is written for a network using WPA encryption. For
 WEP or WPA, change the Wifi.begin() call accordingly.

 Circuit:
 * WiFi shield attached
 * LED attached to pin 5

 created for arduino 25 Nov 2012
 by Tom Igoe

ported for sparkfun esp32 
31.01.2017 by Jan Hendrik Berlin
 
 */

#include 

const char* ssid     = "your ssid";
const char* password = "your password";

WiFiServer server(80);

void setup()
{
    Serial.begin(115200);
    pinMode(4, OUTPUT);      // set the LED pin mode

    delay(10);

    // We start by connecting to a WiFi network

    Serial.println();
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }

    Serial.println("");
    Serial.println("WiFi connected.");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    
    server.begin();

}

int value = 0;

void loop(){
 WiFiClient client = server.available();   // listen for incoming clients

  if (client) {                             // if you get a client,
    Serial.println("New Client.");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            // the content of the HTTP response follows the header:
            client.print("Click here to turn the LED on pin 4 on.
"); client.print("Click here to turn the LED on pin 4 off.
"); // The HTTP response ends with another blank line: client.println(); // break out of the while loop: break; } else { // if you got a newline, then clear currentLine: currentLine = ""; } } else if (c != '\r') { // if you got anything else but a carriage return character, currentLine += c; // add it to the end of the currentLine } // Check to see if the client request was "GET /H" or "GET /L": if (currentLine.endsWith("GET /H")) { digitalWrite(4, HIGH); // GET /H turns the LED on } if (currentLine.endsWith("GET /L")) { digitalWrite(4, LOW); // GET /L turns the LED off } } } // close the connection: client.stop(); Serial.println("Client Disconnected."); } }


LEDはサンプルでは LED は 5番ピンでしたが、私は4番ピンに変更しています。Arduino のシリアルモニタを立ち上げておくと、取得したIPアドレスが分かります。

Connecting to xxxxxxxx
.........
WiFi connected.
IP address: 
192.168.2.118



それでは実際の動きをみてみましょう。




今回はビデオ作成用に新しいツールを導入したので、ちょっと凝って Picture In Picture +音楽を試してみました。なんとこれフリーなんですよね。こちらの記事もそのうち。
(^_^)/~





waves ESP32-DevKitC ESP-WROOM-32 ESP32 DevKitC V2 WiFi BLE 技適取得済 国内発送

waves ESP32-DevKitC ESP-WROOM-32 ESP32 DevKitC V2 WiFi BLE 技適取得済 国内発送

  • 出版社/メーカー: waves(ウェイブス)
  • メディア: エレクトロニクス



ESP-WROOM-32 WiFi + Bluetooth 無線モジュール お得な2個セット

ESP-WROOM-32 WiFi + Bluetooth 無線モジュール お得な2個セット

  • 出版社/メーカー: マイクロテクニカ
  • メディア: エレクトロニクス



SparkFun ESP32 Thing Development Workshop (English Edition)

SparkFun ESP32 Thing Development Workshop (English Edition)

  • 出版社/メーカー: PE Press
  • 発売日: 2017/04/09
  • メディア: Kindle版




タグ:WiFi Arduino ESP32
nice!(32)  コメント(3) 
共通テーマ:趣味・カルチャー

ESP32 でLチカをやってみた! [Arduino]

ESP32をついに動かしてみましたー。とは言ってもLチカだけですけども。環境のセットアップはちょっと想定外のことがありましたが、比較的すんなりいきました。


DSC04446.JPG


最初に ESP32 のGitHubから Arduino の開発環境がまとまったZIPをダウンロードしてきます。

ESP32_ArduinoCore.png
https://github.com/espressif/arduino-esp32


右端にある緑の「Clone or download」ボタンをクリックして「Download ZIP」を選択しダウンロードします。解凍をしたら、Documentディレクトリの Arduino\hardware 以下に "espressif\esp32"というディレクトリを作って、そこにまるっと中身を置きます。


ESP32_Install.png


次に、"Arduino\hardware\espressif/esep32/tools/get.exe" をクリックして起動します。


ESP32_Install2.png


するとDOS窓が開いて、コンパイラをダウンロードしはじめます。


ESP32_Install3.png


処理が終わると、自動的にDOS窓が閉じます。これでセットアップは終わりです。Arduinoを開くと、ESP32 のボード設定が見えていますね。

ESP32_Arduino.png


で、ESP32 をつないで見たのですが、シリアルポートを認識しません。


DSC04856.JPG


少し調べてみたら、このブレイクアウトボードは、SiliconLabs の USB-UART チップを使っている模様。なので、ドライバをダウンロードしてきました。


vcp_driver.png
https://jp.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers


さて、これで準備完了なので、スケッチを書き込んでみました。

void setup() {
  pinMode(2, OUTPUT);
}

void loop() {
  digitalWrite(2, HIGH);
  delay(500);
  digitalWrite(2, LOW);
  delay(500);
}


コンパイルは無事済んでで、書き込みをしようとしたところで、なんとエラーが出てしまいました。フラッシュ書き込み用のプログラムがないと怒られてしまいました。

error: "C:\USERS\Documents\Arduino\hardware\epsressif\esp32/tools/gen_esp32part.exe": file does not exist
ボードESP32 Dev Moduleに対するコンパイル時にエラーが発生しました。



で、いろいろ調べたらノートンさんがプログラムを削除してしまった模様。どうも世界中で、利用者が数百人しかいない実績ないプログラムと認識してしまったようです。ESP32って、まだそんなマイナーなんだっけ???


norton.png


対策を講じてようやく動いた様子がこちらです。





これでようやくスタート地点にたちました。(^_^)/~






waves ESP32-DevKitC ESP-WROOM-32 ESP32 DevKitC V2 WiFi BLE 技適取得済 国内発送

waves ESP32-DevKitC ESP-WROOM-32 ESP32 DevKitC V2 WiFi BLE 技適取得済 国内発送

  • 出版社/メーカー: waves(ウェイブス)
  • メディア: エレクトロニクス



ESP-WROOM-32 WiFi + Bluetooth 無線モジュール お得な2個セット

ESP-WROOM-32 WiFi + Bluetooth 無線モジュール お得な2個セット

  • 出版社/メーカー: マイクロテクニカ
  • メディア: エレクトロニクス



SparkFun ESP32 Thing Development Workshop (English Edition)

SparkFun ESP32 Thing Development Workshop (English Edition)

  • 出版社/メーカー: PE Press
  • 発売日: 2017/04/09
  • メディア: Kindle版




タグ:ESP32 Arduino
nice!(27)  コメント(2) 
共通テーマ:趣味・カルチャー

ドローンの電気回路をくみ上げ! [Arduino]

チップ部品との格闘の末、ようやく極小ESP-WROOM-02と、極軽モーターモジュールの組上げました。部品の配置図を示します。最小限の部品構成なのですが、結構ごちゃごちゃしてしまいました。


ESP-WROOM02+MORTORx4.png


モーターの配線を延ばして全体を撮ってみました。まるでガガンボのようですね。


DSC045352.jpg


気になる重さは、5.1g!百円玉とだいたい同じくらいです。頑張ったなーオレ。


DSC04536.JPG


次はいよいよ筐体作り。どれだけ軽く作れるかが勝負です!
(`・ω・´)











SODIAL(R)10個 Nチャネルパワー MOSFET2N60 低ゲート電荷 2A 600V

SODIAL(R)10個 Nチャネルパワー MOSFET2N60 低ゲート電荷 2A 600V

  • 出版社/メーカー: SODIAL(R)
  • メディア: エレクトロニクス




極小ESP-WROOM-02の動作確認 [Arduino]

極小ESP-WROOM-02の動作確認をしてみました。組み上げたときにやってなかったのかよ!と突っ込まれそうですが、その通りです。仕事が忙しくて・・・。

苦労の末、組み上げた配線はこのようになりました。


OLED+ESP-WROOM02.png


これでPCからスケッチの書き込みができてしまいます。我ながら関心関心。


DSC04517-2.jpg


総重量は、電源コネクタをグルーで固めたため1.75g となってしまいました。グルーが意外と重い。。。


DSC04521.JPG


裏面はこんな感じです。配線が汚いですねぇ・・・。


DSC04523.JPG


あとはこれに、2chのモータードライバを二つ載せてモーターとコンデンサを結線すれば電気系は完成するはず。仕事はヤバい状況なのに、こんなことしてる場合じゃないんだけど。現実逃避・・・。
(´ Д`;








FTDI USBシリアル変換アダプター(5V/3.3V切り替え機能付き)

FTDI USBシリアル変換アダプター(5V/3.3V切り替え機能付き)

  • 出版社/メーカー: スイッチサイエンス
  • メディア: エレクトロニクス



ホットメルト コードレスグルーガン 接着機 GG-200CL

ホットメルト コードレスグルーガン 接着機 GG-200CL

  • 出版社/メーカー: 高儀
  • メディア: おもちゃ&ホビー




極小ESP-WROOM-02再び! [Arduino]

仕事をしてばかりでは息が詰まるので、ドローン用のコントローラーとして極小ESP-WROOM-02 を再び作ってみることにしました。苦闘3時間の成果がこちら!


DSC04511-1.jpg


仕様はそのうち披露したいと思います。しかし今回、GNDのはんだ付けにかなり苦労しました。やはり無線モジュールなのでGNDはかなりしっかりしているようです。裏面はこんな感じ。


DSC04512-1.jpg


今回は軽量を目指したので、3.7V -> 3.3V のLDOは省いてしまいました。今まで何度も 3.7VのLiPoバッテリーで直接駆動して問題なかったので大丈夫でしょう。


DSC04510.JPG


トータル重量は1.67gになりました。思ったよりも重くなっちゃったかなぁ。ESP-WROOM-02の重量は1.3gくらいだったので、コネクタとピンヘッダー、接着用のグルーで0.37gも取ってしまったようです。

モーター+プロペラがひとつ0.77g。デュアルFETが一つ0.1gなので二つで0.2g。コンデンサなどの重量はほぼ無視できるので、全体で約5g。バッテリーと筐体の重さを加えて10g未満に抑えたいところです。うーん、できるかなぁ。
σ(ーω ー;








LiPoバッテリー 3.7V 150mAh [Rexi] GB260

LiPoバッテリー 3.7V 150mAh [Rexi] GB260

  • 出版社/メーカー: ジーフォース
  • メディア: おもちゃ&ホビー



10pcs シングル40ピン オス+メスストレートタイプ ピンヘッダー  PCB用 2.54 mm

10pcs シングル40ピン オス+メスストレートタイプ ピンヘッダー PCB用 2.54 mm

  • 出版社/メーカー: ジェネリック
  • メディア: Tools & Hardware




ESP-WROOM-32、ESP-WROOM-02、RTL8710を比較してみた(1) [Arduino]

手元にESP-WROOM-32、ESP-WROOM-02、RTL8710が揃ったので、比較をしてみました。


DSC04493-2.jpg


まず外形から比較します。

 縦 横 ピン数 重量 価格
 ESP-WROOM-32  25.5mm  18.0mm  38pin  1.96g  700円 
 ESP-WROOM-02  20.0mm  18.0mm  18pin  1.29g  500円 
 RTL8710  24.0mm  16.0mm  22pin  1.35g  500円 


この表を見ると、外形はESP-WROOM-02がバランスが良さそうです。

裏面を見てみましょう。ピンのピッチがよく分かります。


DSC04494-2.jpg


ピンのピッチを見ると、ピン数が多くて半田しやすいRTL8710も選択肢の中に入ってきますね。ESP-WROOM-02はピン数が少ないのがネックになることが多いので、RTL8710も悪くなさそうです。

そのうち(仕事がひと段落ついたら)、機能面やソフト面でも比較してみたいと思いますー。
(^_^)/~





waves 2個 ESP-WROOM-32 WiFi + Bluetooth 無線モジュール ESP32 技適取得済 国内発送

waves 2個 ESP-WROOM-32 WiFi + Bluetooth 無線モジュール ESP32 技適取得済 国内発送

  • 出版社/メーカー: waves(ウェイブス)
  • メディア: エレクトロニクス



waves ESP8266 WiFiモジュール(技適取得済み) ESP-WROOM-02

waves ESP8266 WiFiモジュール(技適取得済み) ESP-WROOM-02

  • 出版社/メーカー: waves(ウェイブス)
  • メディア: おもちゃ&ホビー







MOSFETでロジックレベル変換を実現する [Arduino]

最近はマイコンの駆動電圧が3.3Vや1.8Vのものが多くなってきて、周辺デバイスとの電圧レベル変換をすることが多くなってきました。

私のようなソフト屋が回路を組むと何も考えずにレベルシフター置いてしまい、レベルシフターだらけの回路になってしまいます。

レベルシフターは便利なんですが、面積食うし、お財布にも優しくないという話をしていたら、会社の同僚の電気屋さんからMOSFETでレベル変換回路を簡単につくれるよ!と教えてもらいました。

その回路がこちら。


LevelShiftbyFET.png


NチャンネルMOSFETとプルアップ用の抵抗2つで実現しています。すばらしい!

メカニズムはこうです。



(1) 初期状態ではMPUのGPIOは”H"、すなわち3.3V。このときにFETの"G"と”S"に電位差はないので、FETはオフ。Deviceとは絶縁状態ですので、DeviceのIOも"H"、すなわち5Vになります。


(2) MPUのGPIOを”L"にすると、FETの"G"と"S"に電位差が発生します。FETはオンになりますので、MPUとDeviceが通電状態になり、MPUのGPIOもDeviceのIOも"L"になります。


(3) 一方、Deviceが”L"になると、MOSFET内蔵のダイオードに”S"から"D"に電流が流れ、FETの"S"が電圧降下します。その結果、"G"と"S"に電位差が生まれ、FETがオンになりMPUとDeviceが通電状態となり両方"L"になります。



よく出来てますねぇ。目からウロコです。とっても勉強になりました。色んな場面で使ってみたいと思います。
(^_^)/~






Beautyforall 20 Pcs 2N7000 N-Channel Transistor Fast Switch MOSFET TO-92 by Beautyforall [並行輸入品]

Beautyforall 20 Pcs 2N7000 N-Channel Transistor Fast Switch MOSFET TO-92 by Beautyforall [並行輸入品]

  • 出版社/メーカー: Beautyforall
  • メディア: おもちゃ&ホビー



Grove - MOSFET

Grove - MOSFET

  • 出版社/メーカー: seeedstudio
  • メディア:







この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。