【问题标题】:Cyclic data reading (like 1Wire DS18B20 temperature) without blocking main program循环数据读取(如 1Wire DS18B20 温度),无需阻塞主程序
【发布时间】:2016-11-17 19:14:08
【问题描述】:

我正在尝试使用 Raspberry Pi 上的 DS18B20 传感器读取温度。我的问题是从这个传感器读取数据需要时间。这不是太多,或多或少 1 秒,但我不能让我的主程序等到这完成。我不需要有“最近的价值”。这是温度,所以我会每隔一分钟左右询问一次。但是传感器可以例如每 10 秒进行一次测量,这将为我提供足够近期的值。同时,我必须处理对应用程序提出的其他请求。所以我在想某种无休止的测量循环。一般来说,它看起来像:

> start time measurement
> get DS18B20 value from 1 wire 
> parse output 
> stop measure time
> get the execution time, and put it in some global variable 
> sleep for UPDATE_EVERY_X - execution time

所以我想到了使用 fork(),但这会在主进程退出时创建僵尸。主应用程序是某种服务器,所以大多数时候它不会轻轻退出,所以我需要某种额外的保护,这应该不是Linux独有的方法。我正在尝试将我的应用程序编写为可移植的。

我的第二个想法是使用线程。调度一个线程来执行这个无限循环,并实现一些基本的生产者 - 消费者,使用互斥锁等。该线程只会在所有完成后锁定输出温度,因此这将在阻塞时间上产生显着差异。

第三种选择是使用异步 IO。但这对我来说是一种魔力,我知道。我以前没用过,但它出现在搜索结果中。

为了澄清起见,这并不是严格意义上的 1Wire DS18B20,而是当您需要每 x 秒执行一次任务并在进程之间共享信息时的主要方法,即嵌入式定时器中断。

最好的问候,voodoo16。

【问题讨论】:

  • 如果你把它链接到你的程序,Raspberry 支持 pthread,不是吗?
  • 是的。另外,1Wire读取时间主要是等待结束温度转换,需要750ms。
  • 那么为什么不简单地创建一个新线程呢?我错过了什么吗?
  • 这是我的第二个想法。这种方法好吗?在线程处理的函数中使用带有睡眠和无限循环的时间结构感觉很奇怪。
  • 您不必这样做。您可以每 10 秒创建一个新线程,然后立即进行读取。我不喜欢这样,但创建一个线程并将其设置为休眠 9 秒(10 秒循环时间 - 1 秒读取持续时间)。

标签: c linux multithreading raspberry-pi ipc


【解决方案1】:

如果您想要最简单的选项,请记住“Convert T”和“Read Scratchpad”命令是两个不同的步骤。您的程序可以读取温度,然后再返回获取值。无需停止程序,除非您想在转换完成的那一刻获得温度值。

mainLoop() {
    while(1) {
        // Do things
        int16_t rawTemperature = readScratchpad(myTemperatureSensor); // Get the last temperature reading
        if(!getTemperature(myTemperatureSensor)) { // Start the next conversion
            //Temperature conversion was not done, throw out value
            rawTemperature = INT16_MAX;
        }
        else {
            float temperature = ((float)rawTemperature / 4.0f);
            saveTemperature(temperature);
        }
        // Do other things while temperature conversion happens
    }
}

在这种情况下,getTemperature 发出“转换 T”命令,并根据数据表返回 0 或 1(如果先前的转换未完成,则回复 0,如果已开始新的转换,则回复 1)。

【讨论】:

  • 这是一个不错的解决方案。真的很好,完全不同的解决方案。但这意味着我需要使用这样的东西:lxr.free-electrons.com/ident?i=module_init。它比“cat /sys/bus/w1/devices/28-011581a785ff/w1_slave”多出 1000% 的工作量。但我真的很欣赏它。最后我使用了线程。
猜你喜欢
  • 1970-01-01
  • 2019-09-23
  • 2015-08-26
  • 2014-03-31
  • 1970-01-01
  • 2018-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多