前面的文章介绍了在Windows操作系统中用C#编写Winform程序接收并存储Arduino反馈的湿度、温度、火焰传感器检测值和烟雾传感器检测值。本文将在Ubuntu中使用.net core程序进行测试。
.net core目前在Ubuntu只能创建控制台程序,不支持winform,因此上位机的程序需要改动。同时之前使用的数据库是SqlServer,在Ubuntu下改成mysql。
首先是创建数据库,之前在SQLServer中使用的数据库表创建语句无法在mysql中使用,因此根据mysql要求对语句进行了调整,并创建了EnvironmentMonitor数据库及表EnvironmentRecord。具体的创建语句及创建后的截图如下所示。
CREATE TABLE `EnvironmentMonitor`.`EnvironmentRecord` (
`ID` INT NOT NULL AUTO_INCREMENT,
`CreateTime` VARCHAR(45) NOT NULL,
`DHTState` TINYINT NOT NULL,
`ErrorMsg` NVARCHAR(150) NULL,
`Humidity` INT NULL,
`Temperature` INT NULL,
`FlameValue` INT NULL,
`MQValue` INT NULL,
PRIMARY KEY (`ID`));
接着查看Ubuntu下的串口信息。在windows下面,串口名称一般都是com1、com2等,但是在Ubuntu下就不是上面这些名字了。使用SerialPort类中的静态函数GetPortNames获取当前操作系统中的串口名称。为了使用SerialPort类,需要给项目添加System.IO.Ports程序集引用。在VSCode的终端中使用下列命令添加程序集引用。
dotnet add package System.IO.Ports
接着在项目中调用SerialPort.GetPortNames(),并将结果打印到控制台中,截图图下所示,可以看出Ubuntu下的串口名称比Windows下长,看着也比较复杂。
接下来的代码与windows下的代码类似,暂时不考虑数据库存储的事,先将Arduino反馈数据显示在命令行中,主要的代码及结果如下所示:
static void Main(string[] args)
{
...
SerialPort port=null;
string[] ports=SerialPort.GetPortNames();
if(ports==null || ports.Length<=0)
{
Console.WriteLine("no sertial port detacted");
}
else
{
port = new SerialPort(ports[0], 9600);
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.DataBits = 8;
port.Handshake = Handshake.None;
port.RtsEnable = true;
port.DataReceived += new SerialDataReceivedEventHandler(SerialDataReceived);
port.Open();
}
...
}
private static void SerialDataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadLine().TrimEnd('\r');
Console.WriteLine(indata);
}
接着增加数据库存储功能。首先添加对以下程序集的引用:
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.Tools
MySql.EntityFrameworkCore
由于数据库中已存在表,可根据数据库表生成对应的对象类及数据库处理类。先在项目中创建Models文件夹,然后在VSCode的终端中运行下面的指定,生成的结果如下图所示。
dotnet ef dbcontext scaffold "server=localhost;uid=XXX;pwd=XXXXXXX;database=EnvironmentMonitor" MySql.EntityFrameworkCore -o Models -f
定义EnvironmentMonitorContext的对象,然后在控制台程序的串口DataReceived事件中增加数据解析及存储的代码,程序如下所示:
private static EnvironmentMonitorContext m_dbContext=new EnvironmentMonitorContext();
private const string OK_SIGN = "0";
private const string FAIL_SIGN = "1";
private const char SPLIT_CHAR_1 = ',';
private const char SPLIT_CHAR_2 = ';';
private static void UpdateSerialPortData(string rawData)
{
EnvironmentRecord er = new EnvironmentRecord();
er.CreateTime = DateTime.Now.ToString();
string[] subStrs = rawData.Trim(SPLIT_CHAR_2).Split(SPLIT_CHAR_2);
if (subStrs.Length != 3)
{
return;
}
//解析温湿度
string[] dhtValues = subStrs[0].Split(SPLIT_CHAR_1);
er.Dhtstate = (dhtValues[0] == OK_SIGN)?Convert.ToByte(OK_SIGN):Convert.ToByte(FAIL_SIGN);
if (er.Dhtstate==Convert.ToByte(OK_SIGN))
{
er.Humidity = Convert.ToInt32(dhtValues[1]);
er.Temperature = Convert.ToInt32(dhtValues[2]);
}
else
{
er.ErrorMsg = dhtValues[1];
}
//解析火焰传感器值
er.FlameValue = Convert.ToInt32(subStrs[1]);
//解析烟雾传感器值
er.Mqvalue = Convert.ToInt32(subStrs[2]);
m_dbContext.EnvironmentRecords.Add(er);
m_dbContext.SaveChanges();
}
查看数据库表数据,如下所示。可以看到用.net core编写的控制台程序能够将接收的数据写入数据库。
后续会继续使用ASP.NET Core程序读取数据库数据并在网页中显示。