由 ChatGPT 教授的 Python 编程
使用温度/湿度传感器 SHT30 进行数据采集和图表显示

并不是很多人都能随心所欲地进行编程。如果编程不是他们工作的一部分,情况更是如此。不过,现在已经完全不需要知道如何编程了。

我也是那种无法从一张完全空白的纸上写出编程代码的人。但有了 ChatGPT,我现在可以探索代码中的错误和问题。

ChatGPT 自 2022 年起向所有人开放,自推出以来已经有了很大的发展。提问功能之所以重要,是因为它是以提问和接收答案的形式使用的,而且还有一些问题需要核实,比如给出的答案是否正确、是否存在侵权行为等。

这次,我试图将一个可以通过 i2c 管理温度的模块连接到工业用 raspberry pi “PL-R4 “上进行简单编程。不,我是想让它连接 ChatGPT。

下面将逐步介绍如何从一张完全空白的纸上创建所需的程序。

Python 程序

我们这次使用的 Python 程序与 Raspberry Pi 兼容,无需预先搭建环境即可立即使用。
与其他程序相比,Python 是最容易理解的程序之一。我推荐将 Python 作为第一个学习工具。

我们借用了一台配有 Raspberry Pi 计算模块 4 的工业级 Raspberry Pi。

当时的环境

  • PL-R4 BASIC IP20(OPT 端口 i2c 规格)
  • 树莓派操作系统 32 位牛眼
  • Python 程序
  • 温度/湿度传感器(SHT30)

让我先介绍一下。
我知道一些基本的编程知识。这并不是说我什么都不懂。
不过,我还是无法从头开始编写这些代码。
如果您有任何知识,请修改您所回答的代码。

当然,即使您对代码内容知之甚少,也可以通过提问来找出奇怪的部分(错误等),他们会告诉您如何改进以及需要检查哪些内容。

如果不是太复杂,代码会通过压制执行结果中的错误而得到合理的运行。
我们通过试验和错误进行了尝试。

该项目的最终目标

我们将大致决定我们希望最终产品做什么,因为我们可以在编程方面为所欲为。

由于我们使用的是温度/湿度传感器,我们希望它能实时获取温度和湿度,并能存储这些值。
此外,我们还希望能在网络浏览器中查看显示内容,最好是以图表形式显示。

  • 存储获取的值
  • 在网络视图中显示
  • 图表显示

目标是大致实现这三个功能。

第一个问题

让我们从第一个问题开始。我提出了以下问题
“请编写一个 Python 程序,将 SHT30 连接到 Raspberry Pi 并测量温度”。
您觉得如何?显示所需项目、布线示例和 Python 程序。

根据问题的性质,答案往往很笼统。对于这道题,我的印象是没有大的错误。

比代码输出更让我惊讶的是,它甚至显示了这些必要的项目和接线示例。
,我记得 ChatGPT 刚出现时,并没有这么友好。

这可能是人工智能学习的结果,比如许多网站的内容。
,也许它们发布的信息完全相同。

我感到惊讶的是,它使用了图标、列表格式和表格格式,比最初出现时更容易阅读。

启用 I2C

ChatGPT 答案开头还指出,必须启用 I2C。

由于 SHT30 通过 I2C 通信连接,因此必须首先启用 I2C。

命令来检查是否启用。

raspi-config nonint get_i2c
1

如果返回值为 0,则表示有效;如果返回值为 1,则表示仍然无效。初始值为禁用 (1)。

启用 I2C 并按照 raspi-config 菜单重新启动。

sudo raspi-config

或者使用以下命令启用并重新启动

sudo raspi-config nonint do_i2c 0

将 SHT30 与 Raspberry Pi 物理连接后,检查它是否被正确识别。
使用 ls 命令检查设备的端口。

ls /dev*i2c*
/dev/i2c-0  /dev/i2c-1

使用 i2cdetect 命令进行检查。

sudo i2cdetect -y 0(今回は0)

*在本测试机中,/dev*i2c*指定为 0,因为有两个 s,即 /dev/i2c-0 和 /dev/i2c-1。一般情况下,它是 1。
如图所示,显示了地址 44、60 和 68(UU)。

 i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- 44 -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: 60 -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --       

默认情况下(标准),I2C 地址为0x44 ,所以这次是标准地址。程序代码中使用了该地址,因此如果地址不同,则必须更改后面代码中的相应部分。


您也可以在 ChatGPT 上询问,他们会告诉您。

这是一个比较特殊的测试设备,所以可以忽略它;60 也在被另一个设备使用,如果它已被使用或保留,UU 指示器将显示 UU。

总之,我发现 I2C 地址是 44,而且它被识别了。

从第一个问题中获得的 Python 程序代码

第一个问题中由 ChatGPT 生成的 Python 程序代码产生了以下输出结果

import time
from smbus2 import SMBus

# I2C address of SHT30 (0x44 or 0x45)
SHT30_ADDR = 0x44

# Command for high repeatability measurement, no clock stretching
MEASUREMENT_CMD = [0x2C, 0x06]

def read_sht30(bus):
    # Send measurement command
    bus.write_i2c_block_data(SHT30_ADDR, MEASUREMENT_CMD[0], [MEASUREMENT_CMD[1]])
    time.sleep(0.5)  # Wait for measurement

    # Read 6 bytes of data (temperature 2 + CRC1, humidity 2 + CRC1)
    data = bus.read_i2c_block_data(SHT30_ADDR, 0x00, 6)

    # Calculate temperature
    temp_raw = data[0] << 8 | data[1]
    temperature = -45 + (175 * temp_raw / 65535.0)

    # Calculate humidity (as a bonus)
    humid_raw = data[3] << 8 | data[4]
    humidity = 100 * humid_raw / 65535.0

    return temperature, humidity

if __name__ == "__main__":
    with SMBus(1) as bus:
        while True:
            temperature, humidity = read_sht30(bus)
            print(f"Temperature: {temperature:.2f}°C, Humidity: {humidity:.2f}%")
            time.sleep(2)

在运行 Raspberry Pi 网站时,我曾在一定程度上使用过 Python。作为一个业余爱好者,我对以前的基础知识有基本的了解,所以当我看到这些代码时并不觉得好笑。如果你是 Python 的新手,不理解它的意思是很正常的。

既然不知道,那就运行一次吧。

我会按原样运行。

我将代码保存为sensor.py文件,然后通过命令运行。

突然出现错误!

sudo python3 sensor.py 
Traceback (most recent call last):
  File "/home/pi/test/sensor.py", line 2, in <module>
    from smbus2 import SMBus

显然,错误原因是缺少 smbus2 模块,无法导入。

哦,我忘了。我还没有安装。
前提条件中提到的是 smbus2。
使用 pip 安装 smbus2-0.5.0。

sudo pip3 install smbus2

我再运行一次。
哎呀,根本没有 I/O 错误。

sudo python3 sensor.py 
Traceback (most recent call last):
  File "/home/pi/test/sensor.py", line 31, in <module>
    temperature, humidity = read_sht30(bus)
  File "/home/pi/test/sensor.py", line 12, in read_sht30
    bus.write_i2c_block_data(SHT30_ADDR, MEASUREMENT_CMD[0], [MEASUREMENT_CMD[1]])
  File "/usr/local/lib/python3.9/dist-packages/smbus2/smbus2.py", line 645, in write_i2c_block_data
    ioctl(self.fd, I2C_SMBUS, msg)
OSError: [Errno 121] Remote I/O error

我突然踉跄了一下。怎么了?
我会再次要求 ChatGPT 解决这个问题。

要求更正


事实上,测试机器使用的是 /dev/i2c-0,而不是更常用的 /dev/i2c-1,这就是代码中读取指定不正确的原因。

至于 ChatGPT,我之所以提出这段代码,是因为我假定有一个通用的 /dev/i2c-1。
因此,我们可以简单地用 SMBus(0) 替换掉通用的 SMBus(1)。

由于这台测试机有点特殊,SMBus(1) 对大多数 Raspberry Pi 来说都没问题。

with SMBus(0) as bus:  # ← Use bus number 0 here

我是如何提问以了解这一修正案的,我只是将错误原样复制粘贴并发送了出去。

在建议的众多检查点中,我认为也许可以利用 i2cdetect 命令的结果找到修复方法。于是,我接下来做的事情就是复制并粘贴 i2cdetect 的结果,并提出类似 “i2cdetect 的输出如下 “的问题。有什么问题?

随后,他详细解释了内容,还发现了一个重要问题,即 0 和 1 的错误。

谢谢!我检查了 i2cdetect 的输出,发现了一些要点!

新修改的代码不再有注释,这在早些时候曾被指出是多余的。
相反,它被礼貌地指出为# ← ここを 0 にする 。谢谢。

import time
from smbus2 import SMBus

SHT30_ADDR = 0x44  # Address detected by i2cdetect

MEASUREMENT_CMD = [0x2C, 0x06]

def read_sht30(bus):
    # Send measurement command
    bus.write_i2c_block_data(SHT30_ADDR, MEASUREMENT_CMD[0], [MEASUREMENT_CMD[1]])
    time.sleep(0.5)  # Wait for measurement

    # Read data
    data = bus.read_i2c_block_data(SHT30_ADDR, 0x00, 6)

    temp_raw = data[0] << 8 | data[1]
    temperature = -45 + (175 * temp_raw / 65535.0)

    humid_raw = data[3] << 8 | data[4]
    humidity = 100 * humid_raw / 65535.0

    return temperature, humidity

if __name__ == "__main__":
    with SMBus(0) as bus:  # ← Use bus number 0 here
        while True:
            try:
                temperature, humidity = read_sht30(bus)
                print(f"Temperature: {temperature:.2f}°C, Humidity: {humidity:.2f}%")
            except Exception as e:
                print("Error:", e)
            time.sleep(2)

更改 senseor.py,然后再次运行。
这次执行无误。

输出结果:

sudo python3 sensor.py 

Temperature: 22.65°C, Humidity: 63.77%
Temperature: 22.65°C, Humidity: 63.81%
Temperature: 22.66°C, Humidity: 63.79%
Temperature: 22.64°C, Humidity: 63.80%
Temperature: 22.65°C, Humidity: 63.77%
Temperature: 22.64°C, Humidity: 63.78%

控制台屏幕(终端)上反复显示温度和湿度。这很好。
没有编写退出代码,因此按 Ctrl + C 强制终止。

进一步定制(数据存储)

根据我们的既定目标,我们希望首先添加保存值的功能。
保存单个咬合可以是简单的文本输出,也可以是存储在数据库中。


指定数据库类型也是一个好主意,所以这次我们将使用 SQLite,它只需要一个文件。

英语:
使用 SQLite 作为数据库。

按照计划,它们在输出代码的同时,还能在以下条件下保存到数据库中。

  • 将测量到的 “时间”、”温度 “和 “湿度 “记录在 SQLite 中
  • 如果不存在表格,则在启动时自动创建表格
  • 每 2 秒检索、保存并输出到控制台

无论对其内容进行任何审查,我都会尝试按原样运行一次。
我已将其保存为一个新的sensor_data.py

输出结果:

sudo python3 sensor_data.py 
[2025-04-11 12:37:54] Temperature: 22.78°C, Humidity: 64.27%
[2025-04-11 12:37:57] Temperature: 22.79°C, Humidity: 64.34%
[2025-04-11 12:37:59] Temperature: 22.79°C, Humidity: 64.30%
[2025-04-11 12:38:02] Temperature: 22.76°C, Humidity: 64.31%
[2025-04-11 12:38:04] Temperature: 22.78°C, Humidity: 64.28%
[2025-04-11 12:38:07] Temperature: 22.79°C, Humidity: 64.30%
[2025-04-11 12:38:09] Temperature: 22.78°C, Humidity: 64.32%

生成的值与之前的相同,但这次带有时间戳。


应用程序 “DB Browser for SQLite “正好合适,让我们安装一个新的,然后看一看。

sudo apt update
sudo apt install sqlitebrowser

创建并加载名为 sensor_data.db 的文件。

在 “浏览数据 “选项卡中,可以看到数据已正确存储。在本例中,共有 10 个项目。
现在,您可以随时检索这些值。

进一步定制(网络视图)

下一步是添加功能,使其可以在网络浏览器中显示。
既然您刚刚建议使用 Flask,我就请您按原样操作。

Flask 被称为框架。必须先安装框架。
实际上,Flask 已经安装。不过,版本是 1.0 系列,无法升级到 2.0 或 3.0 系列。虽然不是最新版本,但这次我们将继续使用。

如果要安装,仍可使用pip3 install命令。

flask --version

Python 3.9.2
Flask 1.1.2
Werkzeug 1.0.1

显然,我们必须准备一个新的 py 文件。

  • sensor.py → 获取并保存温度和湿度(之前的数据采集代码)
  • webapp.py → Flask 应用程序

创建一个新的 webapp.py。

我立即按原样运行了它。

python3 webapp.py 
 * Serving Flask app "webapp" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

当您看到的文本出现在控制台中时,您可以在网页浏览器中输入localhost:5000/进行查看。
您也可以指定 Raspberry Pi 的 IP 地址,从另一台机器或手机上查看。(例如:http://192.168.0.10:5000/)

温湿度日志(最近 50 条记录):ID、时间戳、温度和湿度。

*由于这是一个简化版本,因此仅用于本地环境的测试使用。
这段代码没有导致错误,无需修改。

在末尾添加图表显示


我使用了 PLOTLY。
plotly 是一个可以创建图形的开源库。

先安装 plotly:

pip3 install plotly

将 webapp.py 改为修改后的代码。

当我运行它时,由于某些原因,无法加载和显示 plotly。它只显示标题,其余部分都是空白。

一旦明确指定了 plotly 的 cdn,就可以用指定的模式替换它。

通过 render_template_string() 在 HTML 输出中手动添加<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>


我复制并粘贴了网络浏览器方面的错误结果,并提出了问题。

我已连接到互联网,但无法连接到明确指定的 plotly cdn。


重写为指定本地下载的 js 文件。

通过 PC 下载:https://cdn.plot.ly/plotly-latest.min.js

使用 SCP 命令复制到 Raspberry Pi:

scp plotly-latest.min.js pi@raspberrypi.local:/home/pi/yourapp/static/

将 plotly-latest.min.js 移至新创建的 /static 文件夹。

test/
├── webapp.py
├── sensor.py
├── sensor_data.py
└── static/
    └── plotly-latest.min.js

最后,我们将修改后的 webapp.py 中的 HTML 位置改为本地路径。

对 HTML 模板所做的更改:

<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>  <!-- Remove this line -->
    ↓
<script src="/static/plotly-latest.min.js"></script>  <!-- Change to use local JS file from /static folder -->

现在可以成功显示了。

该图处于稳定的室内温度下,因此要获取的数据值几乎没有变化。作为图表意义不大。
尽管如此,我们还是实现了图形显示功能。

在此基础上,您可以做进一步的小修改,也可以通过试错尝试完全不同的功能。
现在我们已经达到了目标,我们将在此时结束测试。


这是必要的,因为除此以外没有更多的高级功能或错误处理功能。

因为我自己不是程序员,所以很多功能让我有点不知所措。不过,我认为代码不仅适合家庭使用,也适合测试环境。

我需要能够提出问题。

使用 ChatGPT 仍然需要提问的能力。提出宽泛的问题往往会导致以偏概全,遗漏重要细节,感觉不像是准确的答案。最好是一次性提出你的假设。

如果像这次一样,把使用的硬件限制在工业级的 Raspberry Pi 或 ComputeModule 4 上,我们可以想象这可能是个问题,所以我们没敢指定。这是因为环境比较特殊。


即使按建议执行,合格的答复也只是口头解释 “不能做什么”。

从第一个问题 “编写一个 Python 程序,将 SHT30 连接到 Raspberry Pi 并测量温度 “开始,我们花了大约五个问题才编写出一个基本实现所需功能的 Python 程序代码。

坦率地说,即使你不理解代码中的内容,它实际上也可能是可用的程序代码,因为错误往往可以通过遵循说明来解决。

我认为它也适用于编程学习的自学,因为通过对代码中不理解的部分重新提问,可以加深自己对代码的理解。
,这将更接近于能够准确定位问题的感觉,而不是通过上网搜索来找出问题所在。

我可以在 ChatGPT 中使用编程,不过要视具体情况而定。

共享功能

我将在本文中通过 ChatGPT 分享功能链接到该过程。
由于我在设置中开启了建议功能,所以文章中还遗漏了一些细节和补充内容。如果您喜欢,请参阅。

Raspberry Pi SHT30 温度测量
https://chatgpt.com/share/67f8a391-e8f0-8008-980d-f9a517819172

*我可以链接到网站,没有任何特定的失效日期。但是,如果我删除了对话,链接将无法显示。请事先了解这一点。

参考链接:
smbus2: https://pypi.org/project/smbus2/
plotly: https://github.com/plotly/plotly.js
DB Browser for SQLite: https://github.com/ sqlitebrowser/sqlitebrowser
ChatGPT 共享链接常见问题: https://help.openai.com/en/articles/7925741-chatgpt-shared-links-faq


文章由拉斯必达提供

非工程师也能愉快使用的 Raspberry Pi 信息网站 raspida.com一个非工程师也能享受和使用的 Raspberry Pi 信息网站。他还为 PiLink 网站提供有关工业用 Raspberry Pi 的技术博客文章