在循环运行时从串行端口连续读取数据

时间:2021-03-05 15:09:47

First, please refer to this block of code:

首先,请参考这段代码:

while(1) {
    lt = time(NULL);
    ptr = localtime(&lt);

    int n = read (fd, buf, sizeof(buf));
    strftime(str, 100, "%c", ptr);

    int temp = sprintf(tempCommand, "UPDATE roomtemp SET Temperature='%s' WHERE Date='Today'", buf);
    temp = sprintf(dateCommand, "UPDATE roomtemp SET Date='%s' WHERE Type='DisplayTemp'", str);

    printf("%s", buf);
    mysql_query(conn, tempCommand);
    mysql_query(conn, dateCommand);
}   

The read function is actually reading data coming in from a serial port. It works great, but the problem I am experiencing (I think) is the time it takes for the loop to execute. I have data being sent to the serial port every second. Suppose the data is "22" every second. What this loop does is read in "2222" or sometimes "222222". What I think is happening is that the loop takes too long to iterate, and that causes data to accumulate in the serial buffer. The read statement reads in everything in the buffer, hence giving me repeated values.

读取功能实际上是读取来自串行端口的数据。它工作得很好,但我遇到的问题(我认为)是循环执行所需的时间。我每秒都有数据被发送到串口。假设数据每秒“22”。这个循环的作用是在“2222”或有时“222222”中读取。我认为发生的是循环需要很长时间才能进行迭代,这会导致数据在串行缓冲区中累积。 read语句读入缓冲区中的所有内容,因此给出了重复的值。

Is there any way to get around this? Perhaps at the end of the loop, I can flush the buffer. But I am not certain I know how to do this. Or perhaps there is some way to cut down the code inside the loop in order to reduce the overall time each iteration takes in the first place. My guess is that the MySQL queries are what take the most time anyway.

有没有办法解决这个问题?也许在循环结束时,我可以刷新缓冲区。但我不确定我知道怎么做。或者也许有一些方法可以减少循环中的代码,以减少每次迭代首先占用的总时间。我的猜测是,MySQL查询无论如何都需要花费最多的时间。

1 个解决方案

#1


2  

To start with you should check for errors from read, and also properly terminate the received "string".

首先,您应检查读取的错误,并正确终止收到的“字符串”。

To continue with your problem, there are a couple of ways to solve this. One it to put either the reading from the serial port or the database updates in a separate thread. Then you can pass "messages" between the the threads. Be careful though, as it seems your database is slow and the message queue might build up. This message-buildup can be averted by having a message queue of size one, which always contain the latest temperature read. Then you only need a single flag that the temperature reading thread sets, and the database updating thread checks and then clears.

要继续解决您的问题,有几种方法可以解决这个问题。一个是将串口读取或数据库更新放在一个单独的线程中。然后你可以在线程之间传递“消息”。但要小心,因为您的数据库似乎很慢并且消息队列可能会累积。通过使用大小为1的消息队列可以避免此消息构建,该消息队列始终包含最新的温度读取。然后,您只需要一个温度读取线程设置的标志,数据库更新线程检查然后清除。

Another solution is to modify the protocol used for the communication, so it includes a digit to tell how big the message is.

另一种解决方案是修改用于通信的协议,因此它包含一个数字来表示消息的大小。

#1


2  

To start with you should check for errors from read, and also properly terminate the received "string".

首先,您应检查读取的错误,并正确终止收到的“字符串”。

To continue with your problem, there are a couple of ways to solve this. One it to put either the reading from the serial port or the database updates in a separate thread. Then you can pass "messages" between the the threads. Be careful though, as it seems your database is slow and the message queue might build up. This message-buildup can be averted by having a message queue of size one, which always contain the latest temperature read. Then you only need a single flag that the temperature reading thread sets, and the database updating thread checks and then clears.

要继续解决您的问题,有几种方法可以解决这个问题。一个是将串口读取或数据库更新放在一个单独的线程中。然后你可以在线程之间传递“消息”。但要小心,因为您的数据库似乎很慢并且消息队列可能会累积。通过使用大小为1的消息队列可以避免此消息构建,该消息队列始终包含最新的温度读取。然后,您只需要一个温度读取线程设置的标志,数据库更新线程检查然后清除。

Another solution is to modify the protocol used for the communication, so it includes a digit to tell how big the message is.

另一种解决方案是修改用于通信的协议,因此它包含一个数字来表示消息的大小。