5.33 综合案例2.0 -ESP32拍照上传阿里云OSS

2023-05-16

综合案例2.0 - ESP32拍照上传阿里云OSS

  • 案例说明
  • 连线
  • 功能实现
    • 1.阿里云平台连接
    • 2.OSS对象存储服务
    • 3.ESP32-CAM开发环境
    • 4.代码
      • ESP32-CAM开发板代码
      • HaaS506开发板代码
  • 测试
  • 数据转图片方法

案例说明

使用ESP32拍照,将照片数据上传阿里云OSS(通过4G网络上传)。

  • 代码流程
    • haas506连接阿里云,云端物模型下发指令给Haas506。
    • Haas506通过TTL串口发送拍照指令给ESP32。
    • ESP32将拍摄的照片数据发送给Haas506以TXT格式存入SD卡。
    • Haas506将TXT文件上传OSS。

连线

在这里插入图片描述

功能实现

1.阿里云平台连接

阿里云环境创建参考高级组件库-aliyunIoT进行搭建。
创建产品,添加产品后添加物模型。
在这里插入图片描述

2.OSS对象存储服务

OSS对象存储服务开通参考2.12 haas506开发教程-高级组件库-OSS
开通存储服务,注意记录相关信息

keyid = 'yourKeyId'
keysecret = 'yourKeySecret'
endpoint = 'yourEndPoint'
bucketname = 'yourBucketName'
objectname = '文件存储地址'

3.ESP32-CAM开发环境

参考3.26 haas506 2.0开发教程-example- 简易相机-串口控制ESP32-CAM OV2640拍照
详细Arduino环境安装需要自己搜一下,网上资源很多。

4.代码

ESP32-CAM开发板代码

  • 使用Arduino环境下载
#include "esp_camera.h"
#include "FS.h"
#include <time.h> 
#include "string.h"

String inputString = "";
bool stringComplete = false;


//**************************************************************************************************************************************  摄像头初始化
static camera_config_t camera_config = {
    .pin_pwdn = 32,
    .pin_reset = -1,
    .pin_xclk = 0,
    .pin_sscb_sda = 26,
    .pin_sscb_scl = 27,
    
    .pin_d7 = 35,
    .pin_d6 = 34,
    .pin_d5 = 39,
    .pin_d4 = 36,
    .pin_d3 = 21,
    .pin_d2 = 19,
    .pin_d1 = 18,
    .pin_d0 = 5,
    .pin_vsync = 25,
    .pin_href = 23,
    .pin_pclk = 22,
    
    .xclk_freq_hz = 20000000,
    .ledc_timer = LEDC_TIMER_0,
    .ledc_channel = LEDC_CHANNEL_0,
    
    .pixel_format = PIXFORMAT_JPEG,
    .frame_size = FRAMESIZE_SVGA,   // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA      320×240|  |640×480|800×600|1024×768|1400×1050|1600×1200
    .jpeg_quality = 12,            //10-63 lower number means higher quality
    .fb_count = 1,
};
  
esp_err_t camera_init() {
    //initialize the camera
    esp_err_t err = esp_camera_init(&camera_config);
    if (err != ESP_OK) {
        Serial.print("Camera Init Failed");
        return err;
    }
    sensor_t * s = esp_camera_sensor_get();
    //initial sensors are flipped vertically and colors are a bit saturated
    if (s->id.PID == OV2640_PID) {
    //        s->set_vflip(s, 1);//flip it back
    //        s->set_brightness(s, 1);//up the blightness just a bit
    //        s->set_contrast(s, 1);
    }
    Serial.print("Camera Init OK");
    return ESP_OK;
}
//**************************************************************************************************************************************



void setup()
{
  Serial.begin(115200);   //初始化串口波特率
  camera_init();  //摄像头初始化
}


void loop()
{
    if (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    if (inChar != '\n') 
    {
      inputString += inChar;
    }
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') 
    {
      stringComplete = true;
    }
    
    if (stringComplete) 
    {
      inputString=String(inputString);
      if (inputString == "123")  //指令正确进行拍照
      {
        camera_fb_t * fb = esp_camera_fb_get();
        delay(10);
        //由于Haas506串口接收到的收据限制(1024以下),将照片数据分段发送给Haas506,每50ms发送1000个数据(可以根据实际情况自行调整)
        if(fb != NULL)
        {
        long len_tol=fb->len;
        unsigned char i=0,j=1000;
        for(i=0;i<(len_tol/j);i++)
        {
          // Serial.print(i);
          // Serial.print(len_tol/j);
          Serial.write(fb->buf+i*j,j);
          delay(50);
          }
        Serial.write(fb->buf+i*j,len_tol-i*j);
        }
        
      }
      inputString = "";
      stringComplete = false;
    }
  }
}

HaaS506开发板代码

在这里插入图片描述

aliyun.py

  • 注意更改阿里云产品信息
# coding=utf-8
import network
import ujson
import utime as time
import modem
from  aliyunIoT import Device
import ota
import kv




#更改产品信息
###############################
productKey = "*********"
productSecret = "***********"
###############################
global deviceName,g_connect_status,device_dyn_resigter_succed,netw
g_connect_status = False
netw = None
device = None
deviceSecret = None
device_dyn_resigter_succed = False

#初始化物联网平台Device类,获取device实例
device = Device()
# 定义需要升级的模块和版本号
module_name = 'default'
app_version = '1.0.1'
# 定义升级包的下载和安装路径,其中url,hash_type和hash 会通过服务端推送被保存下来
info = {
        'url': '',
        'store_path': '/data/pyamp/app.zip',
        'install_path': '/data/pyamp/',
        'length': 0,
        'hash_type': '',
        'hash': ''
}

 # ota 消息推送的接受函数
def on_trigger(data):
     global info
 # 保存服务端推送的ota信息
     info['url'] = data['url']
     info['length'] = data['length']
     info['module_name'] = data['module_name']
     info['version'] = data['version']
     info['hash'] = data['hash']
     info['hash_type'] = data['hash_type']
    # 开始ota 包下载
     dl_data = {}
     dl_data['url'] = info['url']
     dl_data['store_path'] = info['store_path']
     ota.download(dl_data)



 # ota 升级包下载结果回调函数
def on_download(data):
     global info
     if data >= 0:
         print('Ota download succeed')
     # 开始ota包校验
         param = {}
         param['length'] = info['length']
         param['store_path'] = info['store_path']
         param['hash_type'] = info['hash_type']
         param['hash'] = info['hash']
         ota.verify(param)

 # ota 升级包校验结果回调函数
def on_verify(data):
      global info
      print(data)
      if data >= 0 :
          print('Ota verify succeed')
          print('Start Upgrade')
     # 开始ota升级
          param = {}
          param['length'] = info['length']
          param['store_path'] = info['store_path']
          param['install_path'] = info['install_path']
          ota.upgrade(param)

 # ota 升级包结果回调函数
def on_upgrade(data):
     if data >= 0 :
        print('Ota succeed')
        #ota升完级后 重启设备
        reboot()


connect_state = False
def get_connect_state():
    global connect_state
    return connect_state
#当iot设备连接到物联网平台的时候触发'connect' 事件
def on_connect(data):
    global module_name,default_ver,productKey,deviceName,deviceSecret,on_trigger,on_download,on_verify,on_upgrade,connect_state
    print('***** connect lp succeed****')
    data_handle = {}
    data_handle['device_handle'] = device.getDeviceHandle()
    # 初始化ota服务
    ota.init(data_handle)
    connect_state = True
    # ota 回调函数注册
    ota.on(1,on_trigger)
    ota.on(2,on_download)
    ota.on(3,on_verify)
    ota.on(4,on_upgrade)
    report_info = {
         "device_handle": data_handle['device_handle'],
         "product_key": productKey ,
         "device_name": deviceName ,
         "module_name": module_name ,
         "version": app_version
         }
    # 上报本机ota相关信息,上报版本信息返回以后程序返回,知道后台推送ota升级包,才会调用on_trigger函数
    ota.report(report_info)   

def re_wicth(ret):
    global switch
    switch = ret
    update('switch',switch)

def get_switch():
    global switch
    return switch
switch = 0
#当iot云端下发属性设置时,触发'props'事件
def on_props(request):
    global switch
    print('clound req data is {}'.format(request))
    # # # #获取消息中的params数据
    params=request['params']
    # #去除字符串的'',得到字典数据
    params=eval(params)

    if "switch" in params :
        switch = params["switch"]
        

#当连接断开时,触发'disconnect'事件
def on_disconnect():
    print('linkkit is disconnected')


#当iot云端调用设备service时,触发'service'事件
def on_service(id,request):
    print('clound req id  is {} , req is {}'.format(id,request))
#当设备跟iot平台通信过程中遇到错误时,触发'error'事件
def on_error(err):
    print('err msg is {} '.format(err))

#网络连接的回调函数
def on_4g_cb(args):
    global g_connect_status
    pdp = args[0]
    netwk_sta = args[1]
    if netwk_sta == 1:
        g_connect_status = True

    else:
        g_connect_status = False


#网络连接
def connect_network():
    global netw,on_4g_cb,g_connect_status
    #NetWorkClient该类是一个单例类,实现网络管理相关的功能,包括初始化,联网,状态信息等.
    netw = network.NetWorkClient()
    g_register_network = False
    if netw._stagecode is not None and netw._stagecode == 3 and netw._subcode == 1:
        g_register_network = True
    else:
        g_register_network = False
    if g_register_network:
    #注册网络连接的回调函数on(self,id,func);  1代表连接,func 回调函数  ;return 0 成功
        netw.on(1,on_4g_cb)
        netw.connect(None)
    else:
        print('网络注册失败')
    while True:
        if g_connect_status:
            print('网络连接成功')
            break
        time.sleep_ms(20)


#动态注册回调函数
def on_dynreg_cb(data):
    global deviceSecret,device_dyn_resigter_succed
    deviceSecret = data
    device_dyn_resigter_succed = True

# 连接物联网平台
def dyn_register_device(productKey,productSecret,deviceName):
    global on_dynreg_cb,device,deviceSecret,device_dyn_resigter_succed

    key = '_amp_customer_devicesecret'
    deviceSecretdict = kv.get(key)
    print("deviceSecretdict:",deviceSecretdict)
    if isinstance(deviceSecretdict,str):    
        deviceSecret = deviceSecretdict 

    if deviceSecretdict is None or deviceSecret is None:
        key_info = {
            'productKey': productKey  ,
            'productSecret': productSecret ,
            'deviceName': deviceName
            }
        # 动态注册一个设备,获取设备的deviceSecret
        #下面的if防止多次注册,当前若是注册过一次了,重启设备再次注册就会卡住,
        if not device_dyn_resigter_succed:
            device.register(key_info,on_dynreg_cb)  

def connect():
    global deviceName,g_connect_status,device_dyn_resigter_succed
    deviceName = None
     # 获取设备的IMEI 作为deviceName 进行动态注册
    deviceName = modem.info.getDevImei()
    # 连接网络
    connect_network()
    if deviceName is not None and len(deviceName) > 0 :
        #动态注册一个设备
        dyn_register_device(productKey,productSecret,deviceName)
    else:
        print("获取设备IMEI失败,无法进行动态注册")
    while deviceSecret is None:
        time.sleep(0.2)
    print('动态注册成功:' + deviceSecret)
    key_info = {
        'region' : 'cn-shanghai' ,
        'productKey': productKey ,
        'deviceName': deviceName ,
        'deviceSecret': deviceSecret ,
        'keepaliveSec': 60,
        }
    #打印设备信息
    print(key_info)
    #device.ON_CONNECT 是事件,on_connect是事件处理函数/回调函数
    device.on(device.ON_CONNECT,on_connect)
    device.on(device.ON_DISCONNECT,on_disconnect)
    device.on(device.ON_PROPS,on_props)
    device.on(device.ON_SERVICE,on_service)
    device.on(device.ON_ERROR,on_error)
    device.connect(key_info)

def update(key,value):
    global device
    post_data_str=ujson.dumps({key:value})
    data={
        "params":post_data_str
    }
    device.postProps(data)

main.py

  • 更改代码中的相关信息
    • keyid = ‘yourKeyId’
    • keysecret = ‘yourKeySecret’
    • endpoint = ‘yourEndPoint’
    • bucketname = ‘yourBucketName’
    • objectname = ‘文件存储地址’
import utime as time
import aliyun
import _thread
from driver import UART
import ubinascii 
import OSS as oss
import uos

writeBuf = bytearray('123\n')       #拍照指令
readBuf = bytearray(1000)       #每次读取字节,不超过1024
total_data=bytearray()      #总数据初始化
#计算串口收发是否完成
t=0
t_add = False


#上传阿里云oss
def oss_upload_file(filename):
    keyid = 'LTAI5t7czX8UZBqzj14Fry9V'
    keysecret = '5LKycgC9rXCulXt9mbsGhWMPJOztZk'
    endpoint = 'oss-cn-shanghai.aliyuncs.com'
    bucketname = 'testdemo5'
    objectname = '/test/test.log'
    ret = oss.uploadFile(keyid,keysecret,endpoint,bucketname,objectname,filename)
    return ret


#将数据保存SD卡,如需使用删除ffd9后的补充字符
# 文本保存的字符串必须是形如"c8770783a87b86d5..."的十六进制字符串,有无效字符会读取失败。
def write_txt_content(path,mode,data):
    with open(path, mode) as f:
        f.write(data)
    print("--------------write----------------")
    time.sleep_ms(1200)



if __name__ == '__main__':
    #串口实例化
    uart=UART()
    uart.open("serial1")

    #等待阿里云连接
    aliyun.connect()
    aliyun.get_connect_state()
    while  not aliyun.get_connect_state():
        time.sleep_ms(20)

    while  True:
        if aliyun.get_switch():
            uart.write(writeBuf)
            aliyun.re_wicth(0)
            print('start---')

        ret = uart.read(readBuf)
        if ret > 0:
            t_add = True
            t=0
            #print(ret,readBuf[:ret])
            total_data+=readBuf[:ret]
            #print(ubinascii.hexlify(total_data))
        elif ret==0:
            if t_add:
                t+=1

        time.sleep_ms(20)
        
        if t >3:  # 串口接收到数据后连续4次读取为空 
            #启用sd卡
            uos.mountsd()
            total_data+=bytearray('5')       #补充一个上传oss时丢失的字符
            total_data=ubinascii.hexlify(total_data).decode()     #转化为字符格式
            #print(total_data)      #方便看到完整的接收数据
            print('total_data ok!!')
            write_txt_content('/sdcard0/test.log','w',total_data)      #存入SD中的文件名   
            oss_upload_file('/sdcard0/test.log') 
            time.sleep_ms(1200)
            print('upload oss finished...')
            total_data=bytearray()
            t_add = False
            t=0

borad.json

  • 使用485读取log
{
  "name": "haas506",
  "version": "2.0.0",
  "io": {       
  "serial1":{
    "type":"UART",
    "port":0,
    "dataWidth":8,
    "baudRate":115200,
    "stopBits":1,
    "flowControl":"disable",
    "parity":"none"
  }
  },
  "debugLevel": "ERROR",
  "repl": "enable",
  "replPort": 2
}

测试

1.上电后打印连接阿里云相关信息
在这里插入图片描述
阿里云设备在线
在这里插入图片描述

2.在线调试,发送拍照指令给Haas506在这里插入图片描述

  • 阿里云指令下发成功

  • 照片数据传回并写入SD卡

  • 上传0SS
    在这里插入图片描述

  • 文件存入OSS成功
    在这里插入图片描述

数据转图片方法

(1)复制数据
 代码运行完毕,会打印图片的16进制数据,该数据以ffd8开头,ffd9结尾,复制该数据。
在这里插入图片描述

在这里插入图片描述
(2)粘贴数据
 先在电脑桌面上新建一个文件夹,例如txt2jpg。然后在该文件夹内创建一个txt文本,例如text.txt,将(1)中所复制的数据粘贴到test.txt内。
在这里插入图片描述

(3)执行python脚本
 打开pythonIDE,将test.txt的路径填写到下面的代码中(注意是"/"),执行该脚本,将txt文本转化成jpg图片。

import binascii
with open('C:/Users/further/Desktop/txt2jpg/test.txt','rb') as f1, open('C:/Users/further/Desktop/txt2jpg/test.jpg', "wb") as f2:
    payload=f1.read()  
    pic = binascii.a2b_hex(payload)
    f2.write(pic)

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

5.33 综合案例2.0 -ESP32拍照上传阿里云OSS 的相关文章

  • CNN实现入侵检测(kdd99)

    文章目录 1 实验说明2 实验过程2 1 数据预处理2 1 1 导入数据2 1 2 one hot编码2 1 3 归一化2 1 4 标签编码 2 2 数据加载2 3 搭建模型2 4 模型训练 3 实验结果4 完整代码 1 实验说明 CNN模
  • All about VDIs

    This tutorial is an experiment to see if forum users find it useful to have a single collected reference for some common
  • PUTTY无法远程连接服务器故障解决

    对于一个刚刚了解putty工具的新手来说 xff0c 在putty工具使用中有时出现了问题而无法解决 今天就来介绍怎么解决putty无法远程连接服务器的故障 用putty远程连接服务器时 提示错误 server unexpectedlycl
  • 驱动中获取进程名的正确方法

    这是个古老的话题 xff0c 没有技术含量 xff0c 只不过看到网上很多驱动代码在获取进程名时总喜欢去读偏移 EPROCESS ImageFileName xff0c 感觉比较误导新人 这个方法其实很不科学 xff0c 硬编码偏移带来的兼
  • C语言写二进制数据到mysql的Blob字段

    引子 由于调试需要 xff0c 需直接往数据库里写入二进制数据 本来这些数据是由上层软件来写的 xff0c 用的是 C 为了熟悉 C 语言的数据库操作 xff0c 还是决定用 C 来写这段调试代码 概况 xff1a 表名 xff1a Tas
  • 编译器 链接 选项解释:link incrementally的作用

    What is ILT xff08 Incremental Link Table 这两天研究了一下DLL的import export原理 xff0c 看了一些资料 xff0c 无意中发现网上有一篇文章存在错误 xff0c 而这篇文章流传还甚
  • 关于涉密信息系统分级保护的几个问题

    2003年9月7日 xff0c 中共中央办公厅 国务院办公厅转发了 国家信息化领导小组关于加强国家信息安全保障工作的意见 xff0c 其中明确提出了开展信息安全等级保护的任务 xff0c 并指出涉及国家秘密的信息系统 xff08 以下简称涉
  • Launch your application in Vista under the local system account without the UAC popup

    This article describes how to launch an application from session 0 to session 1 under the local system account using a s
  • UTF8ToAnsi 和 AnsiToUTF8

    std string UTF8ToAnsi const std string amp strIn std string amp strOut WCHAR strSrc 61 NULL TCHAR szRes 61 NULL int i 61
  • TCP/IP 配置参数

    TCP IP 配置参数 Windows 2000 TCP IP 协议组件实现从注册表中获取全部配置数据 配置信息 是由安装程序写到注册表中的 一些信息也可以由动态主机配置协议 DHCP 客户 服务提供 xff08 如启用 xff09 本附录
  • ExpLookupHandleTableEntry

    wrk1 2中 ExpLookupHandleTableEntry的内部流程 1 取 Handle EXHANDLE类型 值为tHandle 并将TagBit 低两位 置0 2 取 HandleTable gt NextHandleNeed
  • C++完美转发

    1 std forawrd std forward lt T gt arg 可以实现完美转发 xff0c 即如果 arg 是一个右值引用 xff0c 则转发之后结果仍是右值引用 xff1b 反之 xff0c 如果 arg 是一个左值引用 x
  • win7 usb u盘打不开,设备管理器提示:该设备无法启动。 (代码 10)

    解决 xff1a 禁用改设备 gt 卸载 gt 重新插入u盘
  • linux netlink机制介绍与实例

    开发和维护内核是一件很繁杂的工作 xff0c 因此 xff0c 只有那些最重要或者与系统性能息息相关的代码才将其安排在内核中 其它程序 xff0c 比如GUI xff0c 管理以及控制部分的代码 xff0c 一般都会作为用户态程序 在 li
  • error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项的原因及解决方案

    值 0 不匹配值 2 xff0c Debug使用了Release下的库文件 值 2 不匹配值 0 xff0c Release使用了Debug下的库文件 对于上述两种情况 xff0c 只需要在预处理定义中设定其值使其符合要调用的程序即可 VS
  • SNMP协议详解<二>

    上一篇文章讲解了SNMP的基本架构 xff0c 本篇文章将重点分析SNMP报文 xff0c 并对不同版本 xff08 SNMPv1 v2c v3 xff09 进行区别 xff01 四 SNMP协议数据单元 在SNMP管理中 xff0c 管理
  • SNMP协议详解<三>

    在上篇文章中 xff0c 说到了SNMPv3主要在安全性方面进行了增强 xff0c 采用USM xff08 基于用户的安全模型 xff09 和VACM xff08 基于视图的访问控制模型 xff09 技术 下面我们就主要讲解SNMPv3的报
  • SNMPv3的加密和认证过程

    前面的一些文章详细讲解了SNMPv3的报文内容 xff0c 下面主要的内容就是SNMPv3的加密和认证过程 xff01 USM的定义为实现以下功能 xff1a 鉴别 数据加密 密钥管理 时钟同步化 避免延时和重播攻击 1 UsmSecuri
  • H3C SNMPv3 配置

    1 xff09 H3C SNMPv3 配置 html view plain copy print snmp agent mib view included MIB 2 mib 2 snmp agent mib view included M
  • SNMPv3原理-SNMPv3协议框架

    1 SNMPv3的体系结构 SNMPv3定义了新的体系结构 xff0c 并在其中包含了对SNMPv1和SNMPv2c的兼容 xff0c 即这个新的体系结构也适用于SNMPv1及SNMPv2c xff0c 弥补了SNMP没有完整体系结构的缺点

随机推荐

  • MBR与GTP

    现有的PC机架构 xff0c 是沿用了数十年的主板BIOS 43 硬盘MBR分区的组合模式 随着不久的将来 xff08 2009年 xff1f xff09 硬盘容量突破2TB xff0c BIOS xff0b MBR组合估计会被主板EFI和
  • R6002-floating point not loaded 的问题解决方法 .

    最近项目的要计算浮点数据 xff0c 为了调试方便 xff0c 输出计算结果值到DEBUG信息 xff0c 结果却出现 R6002 错误 Google了一下 xff0c MSDN上对于R6002的描述信息是 xff1a 错误消息 未加载浮点
  • KVM修改虚拟机配置

    1 修改内存或 CPU 编辑虚拟机配置文件 xff1a root 64 controller virsh edit centos2 如 xff0c span class token tag span class token tag span
  • 调试笔记之观察中断

    调试笔记之观察中断 中断好比计算机系统的脉搏 xff0c 是系统生命力的源泉 在WinDBG做内核调试时该如何观察系统的中断分配和响应情况呢 xff1f WinDBG的帮助文件对此描述甚少 xff0c 已经有的几个重要扩展命令居然也没有出现
  • 活动目录域控制器端口

    活动目录域控制器端口 域成员与域控之间通讯需要开放什么端口 xff0c 除了LDAP389 139 445 DNS21 xff0c 还有其他吗 xff1f 回答 xff1a 根据您的描述 xff0c 我对这个问题的理解是 xff1a DC和
  • Apollo编译卡死问题

    最近在研究apollo xff0c 按照他们官方教程下载安装后 输入下面命令开启并进入docker bash docker scripts dev start sh bash docker scripts dev into sh 然后就进入
  • docker服务器的图形显示方案

    问题描述 xff1a 一般docker实操时都是作为服务器 xff0c 以字符方式交互 xff0c 非常不方便 本人尝试各种图形解决方案 xff0c 最终找到完美方案 最初本人尝试过VNC和SSH方式 xff0c 最终被否定了 1 本来do
  • Centos7下使用CMake

    在进行需要提供跨平台服务的项目时 xff0c 最好有相应的跨平台项目构建工具 本文所述的CMake即其中比较好用的跨平台构建工具之一 下文主要以C 43 43 语言为例进行使用演示 安装C 43 43 所需的环境 xff1a yum ins
  • 树莓派+神经计算棒2实时人脸检测

    树莓派配置摄像头 sudo apt get install python opencv sudo apt get install fswebcam 配置摄像头 sudo nano etc modules 查看树莓派CPU型号 cat pro
  • 学习总结-编写自己的CMakeLists.txt

    cmake minimum required span class token punctuation span VERSION span class token number 3 3 span span class token punct
  • 7.4V锂电池USB平衡充电器 串联锂电池充电器

    7 4V锂电池USB平衡充电器 串联锂电池充电器 本文介绍一种简单实用的串联锂电池充电器 大家知道 xff0c 串联电池的充电 xff0c 是一个麻烦的问题 如果直接拿7 4V来充 xff0c 可能会因为两颗电池的参数差异 xff0c 会导
  • 【Echarts】数据可视化完成大屏地图(拓展乡镇地区)的绘制

    绘制地图要素 地图边缘 地理位置 xff08 中心点或者自定义的未知 xff09 echarts绘制 实现在前 成品展示放在最后 代码太长 xff0c 参考代码可见Github Github地址 获取地图 获取精确到乡镇街道的地图JSON数
  • K8s问题【flannel一直重启问题,CrashLoopBackOff】

    kubectl describe 命令查看 Events Type Reason Age From Message Normal Scheduled 13m default scheduler Successfully assigned k
  • Python openpyxl库

    1 读写单元格 span class token keyword from span openpyxl span class token keyword import span load workbook wb span class tok
  • 子网掩码

    子网掩码 subnet mask 是每个网管必须要掌握的基础知识 xff0c 只有掌握它 xff0c 才能够真正理解TCP IP协议的设置 以下我们就来深入浅出地讲解什么是子网掩码 IP地址的结构 要想理解什么是子网掩码 xff0c 就不能
  • AS学习网址大全

    都是我在学习过程中精心收集的 xff0c 大部分为国内网站 xff0c 绝对是您学习AS最好的去处 本贴于2010年3月22日再次更新 xff0c 并新加了很多好的网站 1 同时将网址全都贴出来 xff0c 方便不想下载的朋友使用 2 附件
  • 紧耦合和松耦合有什么区别

  • 我的大一学习生活总结

    今天最后的一科英语考完了 xff0c 但此刻的我并不觉的轻松 xff0c 我知道从现在开始就标志着我的大一已经结束了 xff0c 在大学仅有的四年时光就过去了四分之一 回想起大一这一年 xff0c 自问一下我到底学到了什么 xff1f 我发
  • 阿里云导出raw文件如何还原查看及centos7系统密码破解

    1 Raw格式转换 1 1 格式介绍 目前阿里云ecs镜像文件的导出格式默认为 raw tar gz xff0c 解压后为 raw格式 raw为最原始的虚拟机镜像文件 xff0c vmdk是vmware Virtual Box的虚拟机镜像文
  • 5.33 综合案例2.0 -ESP32拍照上传阿里云OSS

    综合案例2 0 ESP32拍照上传阿里云OSS 案例说明连线功能实现1 阿里云平台连接2 OSS对象存储服务3 ESP32 CAM开发环境4 代码ESP32 CAM开发板代码HaaS506开发板代码 测试数据转图片方法 案例说明 使用ESP