Python programming taught by ChatGPT
Data acquisition and graph display with temperature/humidity sensor SHT30

Not many people can handle programming at will. This is especially true if it is not part of their job. However, it is no longer necessary to know how to program at all.

I am also one of those people who cannot write programming code from a completely blank sheet of paper. So far, there was nothing I could do about it, but with ChatGPT, I can now explore mistakes and questions in my code.

ChatGPT, which has been available to everyone since 2022, has evolved considerably since its introduction. The ability to ask questions is important because it is used in the form of asking questions and receiving answers, and there are still issues to be verified, such as whether the answers given are correct and whether there is any infringement of rights.

This time, I tried to connect a module that can manage temperature with i2c to an industrial raspberry pi “PL-R4” for simple programming. No, I tried to get it to ChatGPT.

The following is a step-by-step process of how a desired program can be created from a completely blank sheet of paper.

Python Programs

The Python program we used this time is compatible with Raspberry Pi and can be used right away without the need for a prior environment.
Compared to other programs, Python is one of the easiest to understand. I recommend Python as a good first learning tool.

We borrowed an industrial Raspberry Pi with Raspberry Pi Compute Module 4.

Environment of this time

  • PL-R4 BASIC IP20 (OPT port i2c specification)
  • Raspberry Pi OS 32bit Bullseye
  • Python Programs
  • Temperature/humidity sensor (SHT30)

Let me preface this a bit.
I know some basic programming stuff. That is not to say that I don’t know anything at all.
Still, I can’t write this code from scratch.
If you have any knowledge at all, it would be helpful to modify the code you have answered.

Naturally, even if you know little about the code content, you can ask questions to pinpoint the strange parts (errors, etc.) and they will be able to tell you how to improve and what to check.

If it is not too complicated, the code will work reasonably well by squashing errors in the execution results.
We tried it by trial and error.

The final goal of this project

We will decide roughly what we want the final product to do, because we can do whatever we want with the programming.

Since we are using a temperature/humidity sensor, we would like to have it acquire temperature and humidity in real time and be able to store those values.
Furthermore, we wanted the display to be viewable in a web browser, preferably in a graph.

  • Storing acquired values
  • Display in Web View
  • Graph Display

The objective is to implement roughly these three functions.

First question.

So let’s start with the first question. I asked the following question.
“Please write a Python program to connect the SHT30 to the Raspberry Pi and measure the temperature.”
Then what do you think? The required items, wiring example, and Python program were displayed.

Depending on the nature of the question, the answer tends to be very general. With this question, I have the impression that there are no major mistakes.

What surprised me more than the code output was that it even showed these necessary items and wiring examples.
I remember that when ChatGPT first appeared, it was not this friendly.

This is probably the result of learning as an AI, such as the contents of many websites.
Perhaps they are published with exactly the same information.

I am surprised that it is easier to read than when it first appeared, using icons, list format, and table format.

Enable I2C

The ChatGPT answer also states at the beginning that I2C must be enabled.

Since SHT30 is connected via I2C communication, I2C must first be enabled.

command to check if it is enabled or not.

raspi-config nonint get_i2c
1

If the return value is 0, it is valid, and if it is 1, it remains invalid. Initially, it is disabled (1).

Enable I2C and reboot by following the raspi-config menu.

sudo raspi-config

Or, enable and reboot with the following command

sudo raspi-config nonint do_i2c 0

Once the SHT30 is physically connected to the Raspberry Pi, check that it is properly recognized.
Use the ls command to examine the device’s port.

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

Check with the i2cdetect command.

sudo i2cdetect -y 0(今回は0)

*In this test machine, /dev*i2c*is specified as 0 because there are two s, /dev/i2c-0 and /dev/i2c-1. Generally, it is 1.
As you can see, addresses 44, 60 and 68 (UU) were displayed.

 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: -- -- -- -- -- -- -- --       

By default (standard), the I2C address is 0x44, so this time it is standard. The address was used in the program code, so if it is different, you will have to change the corresponding part in the later code.

Originally, it would be OK if only address 44 was displayed, but something is also displayed at addresses 60 and 68.
You can also ask this on ChatGPT and they will tell you.

It’s a bit of a special test device, so you can ignore it; 60 is also in use by another device, and the UU indicator will show UU if it is already in use or reserved.

Anyway, I found that the I2C address was 44 and it was recognized.

Python program code obtained from the first question

The Python program code generated from ChatGPT in the first question produced the following output

import time
from smbus2 import SMBus

# SHT30のI2Cアドレス(0x44 または 0x45)
SHT30_ADDR = 0x44

# コマンド(高精度測定、クロックストレッチなし)
MEASUREMENT_CMD = [0x2C, 0x06]

def read_sht30(bus):
    # 測定コマンド送信
    bus.write_i2c_block_data(SHT30_ADDR, MEASUREMENT_CMD[0], [MEASUREMENT_CMD[1]])
    time.sleep(0.5)  # 測定待ち

    # 6バイトのデータを読み取り(温度2+CRC1、湿度2+CRC1)
    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(1) as bus:
        while True:
            temperature, humidity = read_sht30(bus)
            print(f"温度: {temperature:.2f}°C, 湿度: {humidity:.2f}%")
            time.sleep(2)

I have worked with Python to some extent in running the Raspberry Pi site. As a hobbyist, I have a basic understanding of the old basics, so I’m not amused when I look at the code. If you are new to Python, it is normal to not understand what it means.

Without knowing, let’s run it once anyway.

I’ll run it as is.

I saved the code as a sensor.pyfile and ran it from the command.

It is suddenly an error!

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

Apparently, the error was that the smbus2 module was missing and could not be imported.

Oh, I forgot. I had not installed it yet.
It is smbus2 that was mentioned in the prerequisites.
Install smbus2-0.5.0 with pip.

sudo pip3 install smbus2

I will run it again.
Oops, no I/O error at all.

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

I stumbled over it suddenly. What is wrong?
I will ask ChatGPT again to fix it.

Request a correction

Those who can program may already be aware of this.
In fact, the test machine used /dev/i2c-0 instead of the more common /dev/i2c-1, which is why the read designation in the code was incorrect.

As for ChatGPT, I have proposed the code because I assumed a generic /dev/i2c-1.
Therefore, we could have simply replaced the general SMBus(1) with SMBus(0).

Since this test machine is a little special, SMBus(1) should be fine for most Raspberry Pi.

with SMBus(0) as bus:  # ← ここを 0 にする

How I asked the question to know about this amendment, I just copied and pasted the error as is and sent it.

Among the many suggested checkpoints, I thought I might be able to track them down from the results of the i2cdetect command, so I next asked for a copy and paste of the i2cdetect results as well.

He then explained the contents in detail and also found an important point, i.e., 0 and 1 mistakes.

Thanks! I checked the i2cdetect output and found some important points!

The newly modified code is no longer commented out, which was indicated earlier as an extra.
Instead, it was politely pointed out as # ← ここを 0 にする. Thank you.

import time
from smbus2 import SMBus

SHT30_ADDR = 0x44  # i2cdetect で見えていたアドレス

MEASUREMENT_CMD = [0x2C, 0x06]

def read_sht30(bus):
    # 測定コマンド送信
    bus.write_i2c_block_data(SHT30_ADDR, MEASUREMENT_CMD[0], [MEASUREMENT_CMD[1]])
    time.sleep(0.5)  # 測定待ち

    # データ読み取り
    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:  # ← ここを 0 にする
        while True:
            try:
                temperature, humidity = read_sht30(bus)
                print(f"温度: {temperature:.2f}°C, 湿度: {humidity:.2f}%")
            except Exception as e:
                print("エラー:", e)
            time.sleep(2)

Change senseor.py and run it again.
This time it was executed without error.

Output Results:

sudo python3 sensor.py 

温度: 22.65°C, 湿度: 63.77%
温度: 22.65°C, 湿度: 63.81%
温度: 22.66°C, 湿度: 63.79%
温度: 22.64°C, 湿度: 63.80%
温度: 22.65°C, 湿度: 63.77%
温度: 22.64°C, 湿度: 63.78%

The temperature and humidity were repeatedly displayed on the console screen (terminal). That’s good.
There is no code written to exit, so press Ctrl + C to force termination.

Further customization (data storage)

As per our stated goal, we would like to add the ability to save values first.
Saving a single bite may be as simple as outputting it to text, or it may be stored in a database.

It would be more convenient to store the data in a database so that it can be retrieved later, rather than just outputting text.
It may be a good idea to specify the database type as well, so this time we will use SQLite, which requires only one file.

As intended, they output the code with the added ability to save to the database under the following conditions.

  • Record measured “time”, “temperature”, and “humidity” in SQLite
  • Automatic creation of tables at startup if they do not exist
  • Retrieve, save, and output to console every 2 seconds

I will try to run it once as is, regardless of any scrutiny of its contents.
I have saved it as a new sensor_data.py.

Output Results:

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

The resulting value is the same as before, but this time with a timestamp.

Now let’s check if it is properly stored in the database.
The application “DB Browser for SQLite” is just right, so let’s install a new one and take a peek.

sudo apt update
sudo apt install sqlitebrowser

A file named sensor_data.db is created and loaded.

In the Browse Data tab, you can see that the data is properly stored. In this case, there are 10 items.
Now you can retrieve the values at any time.

Further customization (Web View)

The next step is to add functionality so that it can be displayed in a web browser.
Since you just suggested using Flask, I will ask you to do so as is.

Flask is called a framework. It must be installed first.
Actually, Flask was already installed. However, the version is 1.0 series and cannot be upgraded to 2.0 or 3.0 series. Although it is not up-to-date, we will continue as is this time.

If you want to install it, it is still the pip3 installcommand.

flask --version

Python 3.9.2
Flask 1.1.2
Werkzeug 1.0.1

Apparently, we will have to prepare a new py file.

  • sensor.py → Obtain & save temperature & humidity (previous data acquisition code)
  • webapp.py → Flask app

Create a new webapp.py.

I immediately ran it as is.

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)

When the text you see appears in the console, you can view it by typing localhost:5000/in your web browser.
You can also view it from another machine or your phone by specifying the IP address of the Raspberry Pi. (e.g. http://192.168.0.10:5000/)

*Since this is a simplified version, it is only a test use of the local environment.
This code did not result in an error and did not need to be modified.

Add graph display at the end

Finally, if you have the graph display, you have added the functionality you have targeted for this project.
I used PLOTLY.
plotly is an open source library that enables the creation of graphs.

Install plotly first:

pip3 install plotly

Change webapp.py to the modified code.

When I run it, for some reason plotly does not load and display. It only shows the header title and the rest is blank.

Once you explicitly specify the cdn of the plotly, you can replace it with the pattern you specify.

Manually add <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>to the HTML output by render_template_string().

This still does not display the graph.
I copied and pasted the error results from the web browser side and asked.

I am connected to the internet, but I cannot connect to the explicitly specified plotly cdn.

Now we decided to change to specifying a local js file.
Rewrite to specify a locally downloaded js file.

Download by PC: https://cdn.plot.ly/plotly-latest.min.js

Copy to Raspberry Pi with SCP command:

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

Move plotly-latest.min.js to the newly created /static folder.

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

Finally, we changed the HTML location in the modified webapp.py to the local path.

Changes made in the HTML template:

<script src="https://cdn.plot.ly/plotly-latest.min.js"></script> # 元のコード削除
  ↓
<script src="/static/plotly-latest.min.js"></script> # /staticフォルダのjsファイルを指定に変更

Now it can be displayed successfully.

The graph is in a stable indoor temperature, so the value of the data to be acquired is almost unchanged. It is not very meaningful as a graph.
Nevertheless, we were able to make the graph display function.

From here, you can make further minor modifications, or you can try a completely different function by trial and error.
Now that we have achieved our goal, we will conclude the test at this time.

This is not enough for use in a production environment.
This is necessary because there is not much more advanced or error handling than this.

As I am not a programmer myself, it is a bit overwhelming to have a lot of functions. However, I think that the code is not only suitable for home use, but also for a test environment.

I need to be able to ask questions.

Using ChatGPT still requires the ability to ask questions. Asking broad questions often leads to generalizations that leave out important details and do not feel like accurate answers. It is better to lay out your assumptions once.

If we limit the hardware used to industrial Raspberry Pi or ComputeModule 4, as we did this time, we could imagine that this could be a problem, so we did not dare to specify it. This is because the environment is special.

Even if you copy and paste the error content that is not in Japanese text as it is, it will point out areas for improvement.
Even if implemented as suggested, a qualified response includes just a verbal explanation of “what can’t be done”.

From the first question, “Write a Python program to connect the SHT30 to the Raspberry Pi and measure the temperature,” it took about five questions to produce a Python program code that generally implemented the desired functionality.

Frankly, even if you don’t understand what’s in the code, it can be actually usable program code, since the error is often resolved by following the instructions.

I think it is also suitable for self-study of programming learning, because by re-asking questions about parts of the code that I don’t understand, I can deepen my own understanding of the code.
It would be closer to the feeling of being able to pinpoint the problem rather than searching the Internet to find out what it is.

I can use programming in ChatGPT, although it will be on a case-by-case basis.

Share function

I will link to the process in this article with the ChatGPT share feature.
There were also some details and supplements that I left out in the article because I turned on suggestions in the settings. Please refer to it if you like.

Raspberry Pi SHT30 Temperature Measurement
https://chatgpt.com/share/67f8a391-e8f0-8008-980d-f9a517819172

*I can link to the site without any particular expiration date. However, if I delete the conversation, the link cannot be displayed. Please understand this beforehand.

Reference links:
smbus2: https://pypi.org/project/smbus2/
plotly: https://github.com/plotly/plotly.js
DB Browser for SQLite: https://github.com/ sqlitebrowser/sqlitebrowser
ChatGPT Shared Links FAQ: https://help.openai.com/en/articles/7925741-chatgpt-shared-links-faq


Article contributed by Raspida

Raspberry Pi information site that even non-engineers can enjoy using raspida.com a Raspberry Pi information site that even non-engineers can enjoy and handle. He also contributes technical blog articles to the PiLink site on the Raspberry Pi for industrial use.