社区首页
技术讨论创新帖
全部新帖
资料区
社区活动
联系管理员
★ 社区积分制度
★ 新手必读
★ 申请版主★
请
登录
后使用快捷导航
没有帐号?
注册
首页
|
电子技术
|
嵌入式
模拟电子
单片机
电源管理
传感器
半导体
电子应用
|
工业控制
物联网
汽车电子
网络通信
医疗电子
手机便携
测试测量
安防电子
家用电子
机器人
新能源
电子头条
|
社区
|
论坛
测评
博客
大学堂
|
下载
|
下载中心
电路图
精品文集
电路图
|
参考设计
|
Datasheet
|
活动
|
直播
datasheet
datasheet
文章
搜索
登录
注册
中文
En
论坛
切换旧版
电子工程世界-论坛
»
论坛
›
电子技术交流
›
传感器
›
【DFRobot 云雀气象仪】学习笔记02(自动化获取数据并保 ...
返回列表
发新帖
回复
阅
1067
|
回
1
qzc0927
当前离线
一粒金砂(高级)
最后登录
2025-1-22
在线时间
41 小时
威望
359分
芯积分
299分
(兑换)
E金币
50枚
(兑换)
(兑换)
好友
1
qzc0927
147
帖子
0
TA的资源
一粒金砂(高级)
+ 好友
私信
楼主
发表于2023-11-1 23:37
只看该作者
【DFRobot 云雀气象仪】学习笔记02(自动化获取数据并保存到本地数据库)
[复制链接]
## 5:本地数据库保存 数据在实际工作中应用非常广泛,数据库的产品也比较多,oracle、DB2、SQL2000、mySQL;基于嵌入式linux的数据库主要有SQLite, Firebird, Berkeley DB, eXtremeDB。这里我们主要采用sqlite3数据库,来做本地数据存储; ![image-20231101225100427](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20231101225100427.png) 这里我们首先创建一个Weather天气的数据表,表中包含温度,湿度,海拔,起亚,电压,电池,风向,风速,以及日期的数据字段,ID代表数据序列号,为自增字段。 ## 6:上位机编写 我们编写上位机来自动接收数据,并将接收到的数据放入本地数据库,也就是sqlite3数据库下。上位机实用C#开发,使用visualstudio2019主要分为以下2个步骤: 1. 数据的获取 2. 连接数据库并保存 ### 6.1:数据的获取 数据的获取采用串口通讯来实现,首先进行串口的开关,然后实现串口的收发,最后添加定时器,实现数据的自动化接收。 首先事串口的打开和关闭,我们使用串口组件,和按钮以及多选框来实现串口的打开和关闭。组件设计截图如下: ![image-20231101230018858](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20231101230018858.png) 串口打开和关闭的代码如下: ```C# private void btnSerialOpen_Click(object sender, EventArgs e) { if (serialPort.IsOpen) { //System.Windows.Forms.Application.DoEvents(); //serialPort.Dispose(); serialPort.Close(); cmbSerialNo.Enabled = true;//关闭串口后可以选择串口号和波特率 cmbBand.Enabled = true; } else { /*获取串口名字*/ serialPort.PortName = cmbSerialNo.Text; /*获取波特率信息,并转化为int类型*/ serialPort.BaudRate = Convert.ToInt32(cmbBand.Text, 10); try { serialPort.Open(); //打开串口 serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived); //数据接收事件的方法 cmbBand.Enabled = false;//关闭使能,无法选择 cmbSerialNo.Enabled = false; } catch { MessageBox.Show("串口打开失败!"); return; } } //设置串口按钮状态 btnSerialOpen.Text = serialPort.IsOpen ? "关闭" : "打开"; lblSerialState.ForeColor = serialPort.IsOpen ? Color.Green : Color.Red; toolStripStatusLabel1.Text = serialPort.IsOpen ? "状态:"+"串口已打开" : "状态:" + "串口已关闭"; } ``` 其次,对于串口的收发处理,使用功能函数serialPort_DataReceived来实现,具体代码为: ```C# private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { SerialPort serialPort = (SerialPort)sender; //将当前线程挂起50ms,缓存数据,让数据接收完毕 System.Threading.Thread.Sleep(100); // 读取接收缓冲区中的数据 int bytesToRead = serialPort.BytesToRead; //如果有数据 if (bytesToRead>0) { byte[] buffer = new byte[bytesToRead]; serialPort.Read(buffer, 0, bytesToRead); // 添加数据到接收缓存区 receiveBuffer.AddRange(buffer); //显示接受到的数据 Invoke(new Action(() => { rtxRecvBuff.Text += System.Text.Encoding.UTF8.GetString(receiveBuffer.ToArray()); })); // 处理接收缓存区中的数据 ProcessReceivedData(); } } ``` 最后的添加定时器,进行自动化接收天气数据,为了有效获取数据,我们分别读取各个传感器的数据信息,使用不同的串口指令,利用状态机的形式,配合定时器,循环得到各个传感器的数据,具体代码为: ```C# private void weatherTimer_Tick(object sender, EventArgs e) { switch (sensorState) //写完枚举后敲回车将自动补完枚举类型 { case OptCode.Init: timeCount++; if (timeCount == 1) //延时2S*10=20S { timeCount = 0; Weather_SQL_Insert(); sensorState = OptCode.Temp; } break; case OptCode.Temp: GetTemp_Cmd_Send(); break; case OptCode.Humi: GetHumi_Cmd_Send(); break; case OptCode.WindSpeed: GetWindSpeed_Cmd_Send(); break; case OptCode.WindDirection: GetWindDirection_Cmd_Send(); break; case OptCode.Altitude: GetAltitude_Cmd_Send(); break; case OptCode.Pressure: GetPressure_Cmd_Send(); break; default: break; } } ``` ### 6.2:连接数据库并保存 首先创建sql数据库类,方便数据库操作,具体实现代码如下: ```C# using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.SQLite; namespace SerialPortHelper { class SqLiteHelper { ///
/// 数据库连接定义 ///
private SQLiteConnection dbConnection; ///
/// SQL命令定义 ///
private SQLiteCommand dbCommand; ///
/// 数据读取定义 ///
private SQLiteDataReader dataReader; ///
/// 构造函数 ///
///
连接SQLite库字符串 public SqLiteHelper(string connectionString) { try { dbConnection = new SQLiteConnection(connectionString); dbConnection.Open(); } catch (Exception e) { Log(e.ToString()); } } ///
/// 执行SQL命令 ///
///
The query.
///
SQL命令字符串 public SQLiteDataReader ExecuteQuery(string queryString) { try { dbCommand = dbConnection.CreateCommand(); dbCommand.CommandText = queryString; dataReader = dbCommand.ExecuteReader(); } catch (Exception e) { Log(e.Message); } return dataReader; } ///
/// 关闭数据库连接 ///
public void CloseConnection() { //销毁Commend if (dbCommand != null) { dbCommand.Cancel(); } dbCommand = null; //销毁Reader if (dataReader != null) { dataReader.Close(); } dataReader = null; //销毁Connection if (dbConnection != null) { dbConnection.Close(); } dbConnection = null; } ///
/// 读取整张数据表 ///
///
The full table.
///
数据表名称 public SQLiteDataReader ReadFullTable(string tableName) { string queryString = "SELECT * FROM " + tableName; return ExecuteQuery(queryString); } ///
/// 向指定数据表中插入数据 ///
///
The values.
///
数据表名称 ///
插入的数值 public SQLiteDataReader InsertValues(string tableName, string[] values) { //获取数据表中字段数目 int fieldCount = ReadFullTable(tableName).FieldCount; //当插入的数据长度不等于字段数目时引发异常 if (values.Length != fieldCount) { throw new SQLiteException("values.Length!=fieldCount"); } string queryString = "INSERT INTO " + tableName + " VALUES (" + "'" + values[0] + "'"; for (int i = 1; i < values.Length; i++) { queryString += ", " + "'" + values[i] + "'"; } queryString += " )"; return ExecuteQuery(queryString); } ///
/// 更新指定数据表内的数据 ///
///
The values.
///
数据表名称 ///
字段名 ///
字段名对应的数据 ///
关键字 ///
关键字对应的值 ///
运算符:=,<,>,...,默认“=” public SQLiteDataReader UpdateValues(string tableName, string[] colNames, string[] colValues, string key, string value, string operation = "=") { //当字段名称和字段数值不对应时引发异常 if (colNames.Length != colValues.Length) { throw new SQLiteException("colNames.Length!=colValues.Length"); } string queryString = "UPDATE " + tableName + " SET " + colNames[0] + "=" + "'" + colValues[0] + "'"; for (int i = 1; i < colValues.Length; i++) { queryString += ", " + colNames[i] + "=" + "'" + colValues[i] + "'"; } queryString += " WHERE " + key + operation + "'" + value + "'"; return ExecuteQuery(queryString); } ///
/// 删除指定数据表内的数据 ///
///
The values.
///
数据表名称 ///
字段名 ///
字段名对应的数据 public SQLiteDataReader DeleteValuesOR(string tableName, string[] colNames, string[] colValues, string[] operations) { //当字段名称和字段数值不对应时引发异常 if (colNames.Length != colValues.Length || operations.Length != colNames.Length || operations.Length != colValues.Length) { throw new SQLiteException("colNames.Length!=colValues.Length || operations.Length!=colNames.Length || operations.Length!=colValues.Length"); } string queryString = "DELETE FROM " + tableName + " WHERE " + colNames[0] + operations[0] + "'" + colValues[0] + "'"; for (int i = 1; i < colValues.Length; i++) { queryString += "OR " + colNames[i] + operations[0] + "'" + colValues[i] + "'"; } return ExecuteQuery(queryString); } ///
/// 删除指定数据表内的数据 ///
///
The values.
///
数据表名称 ///
字段名 ///
字段名对应的数据 public SQLiteDataReader DeleteValuesAND(string tableName, string[] colNames, string[] colValues, string[] operations) { //当字段名称和字段数值不对应时引发异常 if (colNames.Length != colValues.Length || operations.Length != colNames.Length || operations.Length != colValues.Length) { throw new SQLiteException("colNames.Length!=colValues.Length || operations.Length!=colNames.Length || operations.Length!=colValues.Length"); } string queryString = "DELETE FROM " + tableName + " WHERE " + colNames[0] + operations[0] + "'" + colValues[0] + "'"; for (int i = 1; i < colValues.Length; i++) { queryString += " AND " + colNames[i] + operations[i] + "'" + colValues[i] + "'"; } return ExecuteQuery(queryString); } ///
/// 创建数据表 ///
+ ///
The table.
///
数据表名 ///
字段名 ///
字段名类型 public SQLiteDataReader CreateTable(string tableName, string[] colNames, string[] colTypes) { string queryString = "CREATE TABLE IF NOT EXISTS " + tableName + "( " + colNames[0] + " " + colTypes[0]; for (int i = 1; i < colNames.Length; i++) { queryString += ", " + colNames[i] + " " + colTypes[i]; } queryString += ") "; return ExecuteQuery(queryString); } ///
/// Reads the table. ///
///
The table.
///
Table name. ///
Items. ///
Col names. ///
Operations. ///
Col values. public SQLiteDataReader ReadTable(string tableName, string[] items, string[] colNames, string[] operations, string[] colValues) { string queryString = "SELECT " + items[0]; for (int i = 1; i < items.Length; i++) { queryString += ", " + items[i]; } queryString += " FROM " + tableName + " WHERE " + colNames[0] + " " + operations[0] + " " + colValues[0]; for (int i = 0; i < colNames.Length; i++) { queryString += " AND " + colNames[i] + " " + operations[i] + " " + colValues[0] + " "; } return ExecuteQuery(queryString); } ///
/// 本类log ///
///
static void Log(string s) { Console.WriteLine("class SqLiteHelper:::" + s); } } } ``` 数据信息的插入,具体的SQL语句可以参考菜鸟教程,里面有项目说明sql的各种操作。 [SQLite 教程 | 菜鸟教程 (runoob.com)](https://www.runoob.com/sqlite/sqlite-tutorial.html) 这里我们就不细说,直接上关键的数据库连接代码。 ```C# public void Weather_SQL_Insert() { try { //连接数据库 Global.sqlConn = new SqLiteHelper("data source=SerialPortHelper.db"); string insertString = "INSERT INTO Weather(Temp,Humi,WindSpeed,WindDirection,Altitude,Pressure,Date)VALUES(" + tempStr + " ," + humiStr + ","+ speedStr + ","+ dirStr + ","+ altiStr + ","+ pressStr + ","+ DateTime.Now.ToLocalTime().ToString("yyyyMMddHHmmss") + ")"; Global.sqlConn.ExecuteQuery(insertString); Global.sqlConn.CloseConnection(); } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { Global.sqlConn.CloseConnection(); } } ``` 最后打开的数据库工具,查看数据是否更新。 ![image-20231101232420951](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20231101232420951.png) 自此,数据保存成功。 具体演示视频如下: https://www.bilibili.com/video/BV1SH4y1z7ys/
测评
,
DFRobot
,
云雀气象仪
,
Arduino
,
空气监测
此帖出自
传感器论坛
最新回复
lugl4313820
楼主的技术牛呀,软件硬件通吃,佩服佩服!
详情
回复
发表于 2023-11-2 06:56
点赞
关注
(0)
回复
分享
扫一扫,分享给好友
复制链接分享
链接复制成功,分享给好友
举报
提升卡
变色卡
千斤顶
lugl4313820
lugl4313820
当前离线
版主
最后登录
2025-1-23
在线时间
171 小时
威望
12373分
芯积分
11129分
(兑换)
E金币
868枚
(兑换)
(兑换)
好友
25
6995
帖子
11
TA的资源
版主
+ 好友
私信
沙发
发表于2023-11-2 06:56
只看该作者
楼主的技术牛呀,软件硬件通吃,佩服佩服!
此帖出自
传感器论坛
回复
举报
返回列表
发新帖
回复
您需要登录后才可以回帖
登录
|
注册
发表回复
回帖后跳转到最后一页
活动
更多>>
走近 AI 重磅新品 STM32N6,解锁在 MCU 部署高性能、节能型边缘 AI!答题有好礼~还有开发板等你拿!
Microchip 直播|多相降压电源控制技术的发展与探讨 报名中!
安世半导体智能工业应用探索站,闯关赢好礼!
24年年终盘点来啦!精选强推:原创、测评、拆解、视频、资料
PI 电源小课堂:集成式半桥驱动IC BridgeSwitch 2, 助力高效永磁同步电机逆变器的设计
Microchip喊你探索dsPIC33A 芯片,70份好礼等你赢!
【瓜分2500元红包】票选2024 DigiKey “感知万物,乐享生活”创意大赛人气作品TOP3!
DigiKey应用探索站重磅上线!潮流应用,硬核技术探秘,N多干货,一站get!
开源项目
更多>>
UNIDOCK
LT6656AIDC-3.3、3.3V 微控制器电压基准和稳压器的典型应用
L78L09AB 输出升压电路正电压稳压器的典型应用
网线分线器
LTM8052AIY 36Vin、3.3Vout 降压型 CVCC 转换器的典型应用
用于便携式的 1.2V、1.8V DC 到 DC 多输出电源
具有辅助 12V 稳压输出的 LT1302-5、3 节电池至 3.3V 降压-升压转换器的典型应用电路
LT6656BCDC-2.048、2.048V 微控制器电压基准和稳压器的典型应用
cell
CWH-CTP-CTX10-YE: 面向CodeWarrior TAP的QorIQ LS处理器调试器接头
随便看看
收到盲盒礼物:FSSDC-9B506-EK Easy Kit
[attach]883467[/attach]这片EasyKit板上扩展了所有芯片的I/O和外设引脚;点阵液晶显示模块128x64个像素;基于FM3芯片,包含片上(Flash,SRAM,Timers,ADC,USD,CAN,UART,SIO,I2C。LIN)等丰富的外设功能;用户自定义的LED:可演示PWM驱动功能;复位按 ...
全球汽车电子域控制器行业规模报告2025
【luckfox fox】RV1106 GPIO测试
射频基础之常见阻抗匹配的方式
谁知道卫星接收卡软件是如何设置参数的?
基于ZX-2型FPGA开发板的串口示波器(三)
MSP430单片机对智能小车的硬件控制设计
求大神帮助
查找数据手册?
搜索
EEWorld Datasheet 技术支持
热门标签
源代码
单片机
放大器
TI
ST
电源
分立器件
传感器
测试测量
模拟
三轴加速度传感器
电源芯片电路图
多普勒效应
DVDT滤波器
SI24R1模块
LDO稳压器
微波通信
高频RFID
IoT-Modbus
ADAS
相关文章
更多>>
日媒分析中国汽车零部件企业竞争力排行:比亚迪第一
1月22日消息,日经中文网日前汇总了分析汽车零部件厂商竞争力的“供应商排行榜”中国企业篇。 在综合评估中,比亚迪位列中国供应商第一,综合分数223点。原因是比亚迪自主生产电池等多种零部件,不仅用
三星电子否认重新设计 1b DRAM,力求提升性能和良率
1 月 22 日消息,消息源 DigiTimes 今天(1 月 22 日)发布博文,报道称三星电子否认了关于重新设计其第五代 10nm 级 DRAM(1b DRAM)的报道。 IT之家昨日援引 ET
韩国系统半导体市占率急剧下降!2027年将跌至1.6%
1月22日消息,据韩国下一代智慧半导体专案小组的研究报告,韩国在全球系统半导体市场的营收市占率正面临急剧下滑的困境。 数据显示,韩国的市占率已从2023年的2.3%下降至今年的2%,预计到2027年
新线索暗示三星无缘代工高通第 2 代骁龙 8 至尊版芯片,台积电是唯一选择
北京:超前布局6G产业,培育人形机器人产业先发优势
北大 2025 首篇 Nature:新型全固态锂硫电池问世,循环寿命超 25000 次
消息称Arm计划将授权许可费用涨价至高300%,三星Exynos芯片未来发展面临变局
中国在量子精密测量领域取得重大突破
脑机接口技术新突破:瘫痪患者靠“想象”就能操控飞行器
台积电 CFO:2024 年四季度已获首笔 15 亿美元美国《CHIPS》法案资金
新帖速递
STM32和无源蜂鸣器播放声音的问题
车规级AECQ200介绍,混合铝电解电容器的选择
嵌入式教程_DSP技术_DSP实验箱操作教程:2-28 搭建轻量级WEB服务器实验
OPA847IDBVR运放器国产替代
AG32VF407测试UART
【得捷电子Follow Me第二期】第一章 收到货物的分享
请问这个红外接收头是什么型号?能用哪个型号代替?谢谢
出售全新未拆封ZYNQ 7Z020 FPGA核心板
用在锂电池供电的水表设置上的LORA模块,当有100块水表集中安装在一个楼道内时,节能
请问一下,当某个端口被设置为 RX0后,这个端口的输入输出方向还有必要设置吗
今年怎么这么难,比疫情时还难,三十了面临失业好迷茫
请教稳压管测试问题
【小华HC32F448测评】关于小华半导体的UART中断发送和PRINTF构造和重定向
【BIGTREETECH PI开发板】 HDMI输出测试
【BIGTREETECH PI开发板】+08.音频测试(zmj)
开发板申请:拥有 AI 加持的 STM32N6570-DK 免费试用 !
申请时间:即日起-3月2日
查看 »
安世半导体智能工业应用探索站,闯关赢好礼!
点击页面内“开始探索”按钮,填写并提交表单;
请根据序号依次完成3个安世半导体智能工业应用的探索,并根据给出的资料完成共计9题(每个应用3题),答对5题以上的玩家即可获得抽奖资格;
每人仅有一次参与答题的机会,请慎重作答,活动结束后,我们将抽取30位玩家赠送礼品。
查看 »
Microchip 直播|多相降压电源控制技术的发展与探讨 报名中!
直播主题:多相降压电源控制技术的发展与探讨
直播时间:2025年2月25日(星期二)上午10:30-11:30
快来报名!
查看 »
回帖赢好礼 | 关于无线技术的那些事儿
【活动时间】即日起—2025年1月31日
【活动好礼】50元京东卡
查看 »
答题赢好礼,PI电源小课堂第3期来啦!
本期内容:集成式半桥驱动IC BridgeSwitch 2, 助力高效永磁同步电机逆变器的设计
活动时间:即日起-2月28日
看视频答题即可赢取京东卡!
查看 »
Microchip喊你探索 dsPIC33A 芯片,70份好礼等你赢!
活动时间:即日起-1月26日
活动奖励:随身Wi-Fi、家用多功能电烤箱、20000mAh充电宝、50元京东卡
查看 »
DigiKey应用探索站重磅上线!潮流应用,硬核技术探秘,N多干货,一站get!
当月好物、热门技术资源、潮流应用技术、特色活动、DigiKey在线实用工具,干货多多~
查看 »
本周精选下载推荐:电源管理基础Dummies
本周小编给大家带来一本超简单、超干货的电子书——《电源管理基础Dummies》!内容深入浅出,排版舒服简洁,分分钟能get到电源管理最核心的知识内容。
查看 »
关闭
站长推荐
1
/8
电子工程世界版权所有
京B2-20211791
京ICP备10001474号-1
电信业务审批[2006]字第258号函
京公网安备 11010802033920号
Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复
返回顶部
返回列表
论坛首页
版块列表
专业技术中心
TI技术论坛
ST传感器与低功耗无线技术论坛
ADI参考电路
DigiKey得捷技术专区
ADI · 世健工业技术
电子技术交流
边缘AI
嵌入式系统
单片机
国产芯片交流
电机控制
FPGA/CPLD
模拟电子
电源技术
无线连接
传感器
PCB设计
综合技术交流
下载中心专版
大学堂专版
测评中心专版
行业应用
汽车电子
机器人开发
工业自动化与控制
能源基础设施
医疗电子
消费电子
创意与实践
电子竞赛
DIY/开源硬件专区
淘e淘
创意市集
休息一下
聊聊、笑笑、闹闹
工作这点儿事
为我们提意见&公告
EEWorld颁奖专区
信息发布
最新帖子
最新帖子
最新回复
精华
消灭零回复
测评中心
活动中心
积分兑换
E金币兑换
芯积分
厂商专区
TI技术论坛
ST传感器与低功耗无线技术论坛