x宝买的5F 5.4V 电池
加上一个ams1117模块正好可以输出3.3v

单模块可以供给esp32开发版使用airtag运行模块 8分钟左右
电容的充电图

可以考虑使用再加上一个太阳能成为一个 无限续航电池
x宝买的5F 5.4V 电池
加上一个ams1117模块正好可以输出3.3v

单模块可以供给esp32开发版使用airtag运行模块 8分钟左右
电容的充电图

可以考虑使用再加上一个太阳能成为一个 无限续航电池
平均功率15.7mw,平均电流3.15ma
1分钟连接一次 耗时0.8s
最大电流 为启动阶段 500ma
连接最大电流 170ma





5F 电容 原则上可以使用1个小时
实际使用8分钟(直接给5V 供电)
AIRTAG ESP32 代码简约(貌似没有引入新的库,蛮简单的啊。)
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include "nvs_flash.h"
#include "esp_partition.h"
#include "esp_bt.h"
#include "esp_gap_ble_api.h"
#include "esp_gattc_api.h"
#include "esp_gatt_defs.h"
#include "esp_bt_main.h"
#include "esp_bt_defs.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
static const char* LOG_TAG = "open_haystack";
/** Callback function for BT events */
static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);
/** Random device address */
static esp_bd_addr_t rnd_addr = { 0xFF, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
/** Advertisement payload */
static uint8_t adv_data[31] = {
0x1e, /* Length (30) */
0xff, /* Manufacturer Specific Data (type 0xff) */
0x4c, 0x00, /* Company ID (Apple) */
0x12, 0x19, /* Offline Finding type and length */
0x00, /* State */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, /* First two bits */
0x00, /* Hint (0x00) */
};
/* https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/esp_gap_ble.html#_CPPv420esp_ble_adv_params_t */
static esp_ble_adv_params_t ble_adv_params = {
// Advertising min interval:
// Minimum advertising interval for undirected and low duty cycle
// directed advertising. Range: 0x0020 to 0x4000 Default: N = 0x0800
// (1.28 second) Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec
.adv_int_min = 0x0640, // 1s
// Advertising max interval:
// Maximum advertising interval for undirected and low duty cycle
// directed advertising. Range: 0x0020 to 0x4000 Default: N = 0x0800
// (1.28 second) Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec
.adv_int_max = 0x0C80, // 2s
// Advertisement type
.adv_type = ADV_TYPE_NONCONN_IND,
// Use the random address
.own_addr_type = BLE_ADDR_TYPE_RANDOM,
// All channels
.channel_map = ADV_CHNL_ALL,
// Allow both scan and connection requests from anyone.
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};
static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
esp_err_t err;
switch (event) {
case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
esp_ble_gap_start_advertising(&ble_adv_params);
break;
case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
//adv start complete event to indicate adv start successfully or failed
if ((err = param->adv_start_cmpl.status) != ESP_BT_STATUS_SUCCESS) {
ESP_LOGE(LOG_TAG, "advertising start failed: %s", esp_err_to_name(err));
} else {
ESP_LOGI(LOG_TAG, "advertising has started.");
}
break;
case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
if ((err = param->adv_stop_cmpl.status) != ESP_BT_STATUS_SUCCESS){
ESP_LOGE(LOG_TAG, "adv stop failed: %s", esp_err_to_name(err));
}
else {
ESP_LOGI(LOG_TAG, "stop adv successfully");
}
break;
default:
break;
}
}
int load_key(uint8_t *dst, size_t size) {
const esp_partition_t *keypart = esp_partition_find_first(0x40, 0x00, "key");
if (keypart == NULL) {
ESP_LOGE(LOG_TAG, "Could not find key partition");
return 1;
}
esp_err_t status;
status = esp_partition_read(keypart, 0, dst, size);
if (status != ESP_OK) {
ESP_LOGE(LOG_TAG, "Could not read key from partition: %s", esp_err_to_name(status));
}
return status;
}
void set_addr_from_key(esp_bd_addr_t addr, uint8_t *public_key) {
addr[0] = public_key[0] | 0b11000000;
addr[1] = public_key[1];
addr[2] = public_key[2];
addr[3] = public_key[3];
addr[4] = public_key[4];
addr[5] = public_key[5];
}
void set_payload_from_key(uint8_t *payload, uint8_t *public_key) {
/* copy last 22 bytes */
memcpy(&payload[7], &public_key[6], 22);
/* append two bits of public key */
payload[29] = public_key[0] >> 6;
}
void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
esp_bt_controller_init(&bt_cfg);
esp_bt_controller_enable(ESP_BT_MODE_BLE);
esp_bluedroid_init();
esp_bluedroid_enable();
// Load the public key from the key partition
static uint8_t public_key[28];
if (load_key(public_key, sizeof(public_key)) != ESP_OK) {
ESP_LOGE(LOG_TAG, "Could not read the key, stopping.");
return;
}
set_addr_from_key(rnd_addr, public_key);
set_payload_from_key(adv_data, public_key);
ESP_LOGI(LOG_TAG, "using device address: %02x %02x %02x %02x %02x %02x", rnd_addr[0], rnd_addr[1], rnd_addr[2], rnd_addr[3], rnd_addr[4], rnd_addr[5]);
esp_err_t status;
//register the scan callback function to the gap module
if ((status = esp_ble_gap_register_callback(esp_gap_cb)) != ESP_OK) {
ESP_LOGE(LOG_TAG, "gap register error: %s", esp_err_to_name(status));
return;
}
if ((status = esp_ble_gap_set_rand_addr(rnd_addr)) != ESP_OK) {
ESP_LOGE(LOG_TAG, "couldn't set random address: %s", esp_err_to_name(status));
return;
}
if ((esp_ble_gap_config_adv_data_raw((uint8_t*)&adv_data, sizeof(adv_data))) != ESP_OK) {
ESP_LOGE(LOG_TAG, "couldn't configure BLE adv: %s", esp_err_to_name(status));
return;
}
ESP_LOGI(LOG_TAG, "application initialized");
}

10
最近都忙于软考
项目信息系统 果然还是背的太多了,看来明年再考个网络的比较好。
-td
docker pull 源地址
docker
run
-i 交互式操作。
-t 终端。
-d 后台
进入容器
在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入:
docker attach
docker exec:推荐大家使用 docker exec 命令,因为此命令会退出容器终端,但不会导致容器的停止。
使用 docker start 启动一个已停止的容器(ID号):
$ docker start b750bbbcfd88
ps -a 查看全部进程
docker stop <容器 ID>
docker restart <容器 ID>
导出
docker export 1e560fca3906 > ubuntu.tar
删除
docker rm -f 1e560fca3906
docker run -d -P training/webapp python app.py
-d:让容器在后台运行。
-P:将容器内部使用的网络端口随机映射到我们使用的主机上。
docker run -d -p 5000:5000 training/webapp python app.py
```
## mysql
docker run -itd –name mysql-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
-p 3306:3306 :映射容器服务的 3306 端口到宿主机的 3306 端口,外部主机可以直接通过 宿主机ip:3306 访问到 MySQL 的服务。
MYSQL_ROOT_PASSWORD=123456:设置 MySQL 服务 root 用户的密码。
docker run -p 3306:3306 –name mysql -v /opt/docker_v/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 -d imageID
-p 3306:3306:将容器的3306端口映射到主机的3306端口
-v /opt/docker_v/mysql/conf:/etc/mysql/conf.d:将主机/opt/docker_v/mysql/conf目录挂载到容器的/etc/mysql/conf.d
-e MYSQL_ROOT_PASSWORD=123456:初始化root用户的密码
-d: 后台运行容器,并返回容器ID
imageID: mysql镜像ID
“-v”与“-mount”的区别是:挂载主机目录使用“-v”时,如果宿主机上没有指定文件不会报错,会自动创建指定文件;当使用“-mount”时,如果宿主机中没有这个文件会报错找不到指定文件,不会自动创建指定文件
docker run -itd –name tmptest –mount type=tmpfs,destination=/app nginx:latest
“`
挂载的类型 type,可以是 bind、volume 或 tmpfs。
要挂载的源 source,对于有名字的卷,这里是卷的名字。对于匿名卷忽略这个字段。可以指定为 src 或 source。
要挂载的目的地 destination,将文件或目录挂载在容器中的路径作为其值。 可能被指定为 destination、dst 或 target。
2.使用命令下载镜像中的文件到本地磁盘。
docker cp 3b4550732f7d:/usr/local/pipenet-docker-patrol/ /mnt/c/Users/14661/upgrade/front-patrol/docker-patrol
3b4550732f7d: 容器id
/usr/local/pipenet-docker-patrol/ : 镜像中的文件路径
/mnt/c/Users/14661/upgrade/front-patrol/docker-patrol :本地磁盘文件路径
文件拷贝:
1、docker 如何从宿主机拷文件到docker容器里面
docker cp 需要拷贝的文件或目录 容器名称:容器目录
2、从docker 容器里将文件拷贝到宿主机。
docker cp 容器名称:容器目录/文件 需要拷贝到宿主机的目录
退出容器三种方式
一, 命令
exit
二,快捷方式
ctrl + D
三,快捷方式
ctrl + P 在加 ctrl + Q