社区首页
技术讨论创新帖
全部新帖
资料区
社区活动
联系管理员
★ 社区积分制度
★ 新手必读
★ 申请版主★
请
登录
后使用快捷导航
没有帐号?
注册
首页
|
电子技术
|
嵌入式
模拟电子
单片机
电源管理
传感器
半导体
电子应用
|
工业控制
物联网
汽车电子
网络通信
医疗电子
手机便携
测试测量
安防电子
家用电子
机器人
新能源
电子头条
|
社区
|
论坛
测评
博客
大学堂
|
下载
|
下载中心
电路图
精品文集
电路图
|
参考设计
|
Datasheet
|
活动
|
直播
datasheet
datasheet
文章
搜索
登录
注册
中文
En
论坛
切换旧版
电子工程世界-论坛
»
论坛
›
电子技术交流
›
传感器
›
【DFRobot 云雀气象仪】学习笔记02(自动化获取数据并保 ...
返回列表
发新帖
回复
阅
1080
|
回
1
qzc0927
当前离线
一粒金砂(高级)
最后登录
2025-1-25
在线时间
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-30
在线时间
172 小时
威望
12473分
芯积分
11239分
(兑换)
E金币
868枚
(兑换)
(兑换)
好友
25
7044
帖子
11
TA的资源
版主
+ 好友
私信
沙发
发表于2023-11-2 06:56
只看该作者
楼主的技术牛呀,软件硬件通吃,佩服佩服!
此帖出自
传感器论坛
回复
举报
返回列表
发新帖
回复
您需要登录后才可以回帖
登录
|
注册
发表回复
回帖后跳转到最后一页
浏览过的版块
PCB设计
活动
更多>>
有奖直播 | ADI 超低功耗 MCU MAX326xx 系列介绍
走近 AI 重磅新品 STM32N6,解锁在 MCU 部署高性能、节能型边缘 AI!答题有好礼~还有开发板等你拿!
Microchip 直播|多相降压电源控制技术的发展与探讨 报名中!
安世半导体智能工业应用探索站,闯关赢好礼!
24年年终盘点来啦!精选强推:原创、测评、拆解、视频、资料
PI 电源小课堂:集成式半桥驱动IC BridgeSwitch 2, 助力高效永磁同步电机逆变器的设计
Microchip喊你探索dsPIC33A 芯片,70份好礼等你赢!
【瓜分2500元红包】票选2024 DigiKey “感知万物,乐享生活”创意大赛人气作品TOP3!
开源项目
更多>>
使用 Analog Devices 的 LTC4235IUFD-2 的参考设计
【航顺训练营】基于行顺HK32F030M单片机学习板
LTC1261LIS8 5V 输入、-0.5V 输出 GaAs FET 偏置发生器的典型应用电路
使用 ROHM Semiconductor 的 BA80BC0WFP-E2 的参考设计
ADP121CB-1.2-EVALZ,基于 ADP121 线性稳压器的评估板
基于555定时器的呼吸灯电路
LTC1871、4.5V 至 15V 输入、12.0V/2A 输出 SEPIC 转换器
LT1308ACS8 锂离子至 12V/300mA 升压 DC/DC 转换器的典型应用电路
LTC4267CDHC 演示板,RJ-45 以太网输出,Vout = 3.3V @ 1.0A
EZRadio-2WayLink-DK,基于Si4x55的EZRadio双向链路开发套件
随便看看
求可以pin to pin替代MT3420B的电源芯片
我的一个设计使用了MT3420B这款电源芯片,这款芯片的输入电压范围是2.3~6V。原来使用的5V供电,现在想使用12V供电,又不想改设计,想换一款能pintopin替换的大于12V输入的芯片。不过我找了很多,12V输入和STO32-6的芯片有很多,因为MT3420B的管脚顺序比较特殊 ...
JavaScript -练习册(2) 函数
JavaScript -练习册(1)hello world
为什么LC振荡电路比RC振荡电路频率高?
AGPS和DGPS有何区别?
跪求MSP430的开发实例
初学嵌入开发,请问看哪些书籍会比较合适
怎么在MSP430的LCD上画一个圆心不断变化,半径不变的圆。
查找数据手册?
搜索
EEWorld Datasheet 技术支持
热门标签
源代码
单片机
放大器
TI
ST
电源
分立器件
传感器
测试测量
模拟
变频器专用型滤波器
电介质电导
艾德克斯
甘汞电极
能耗制动
ICP传感器
导电玻璃
热电堆
simulink
cpld
相关文章
更多>>
德州仪器 2024年Q4财报解析:中国市场增长亮眼,目前没有收到反垄断调查通知
在 2024 年第四季度收益电话会议上,德州仪器(TI)向外界展示了一些好消息,尤其是凸显了中国市场在其全球布局中的关键地位。 第四季度,TI 收入为 40 亿美元,环比下降 3%,比去年同期下
欧盟提议成立高级研究机构:专注于AI等战略技术以加强竞争力
据彭博社报道,欧盟将提议仿照美国政府实体建立一个高级研究项目机构,对战略技术进行投资,以此作为提高欧盟竞争力的更广泛努力的一部分。 欧盟还将呼吁为 AI 建设新的超级计算基础设施。知情人士及文件显示
传台积电报废三万片晶圆,三万片受损
晶圆代工龙头厂台积电位于南科的晶圆厂,受地震影响的机台设备移位、晶圆破损经过抢修后,供应链传出,3、 5纳米的先进制程晶圆十八厂,预计将于23日达100%复机,准备恢复正常生产,晶圆十四厂复机还没有
中国芯片出口连续14个月增长
特朗普退出巴黎协定,芯片业碳中和完了没?
汇顶科技 2024 年业绩亮眼,展现强劲发展韧性
谷歌母公司:美国AI难保证对华领先 不少方面是落后
消息称三星电子砍半晶圆代工部门 2025 年设备投资预算,陡降至 5 万亿韩元
史上最佳表现:SK 海力士 2024 年营业利润 23.5 万亿韩元
宇树发布“踢足球”机器人G1-Comp,网友:国足有救了
新帖速递
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日
看视频答题即可赢取京东卡!
查看 »
DigiKey应用探索站重磅上线!潮流应用,硬核技术探秘,N多干货,一站get!
当月好物、热门技术资源、潮流应用技术、特色活动、DigiKey在线实用工具,干货多多~
查看 »
本周精选下载推荐:电源管理基础Dummies
本周小编给大家带来一本超简单、超干货的电子书——《电源管理基础Dummies》!内容深入浅出,排版舒服简洁,分分钟能get到电源管理最核心的知识内容。
查看 »
关闭
站长推荐
1
/7
电子工程世界版权所有
京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传感器与低功耗无线技术论坛