- Run the same Python file from an editor and terminal.
- Create an isolated project environment.
- Write timestamped rows to a CSV file.
- Distinguish simulated data from physical measurements.
- Use error messages to locate environment and path problems.
Before you begin
Know Python variables, loops, functions and files from the Python series. No sensor or GPIO wiring is required for the simulated example.
Separate programming from wiring
A sensor logger combines at least two jobs: obtaining a measurement and saving it correctly. Connecting both for the first time makes failures harder to interpret. We will first supply known simulated values and verify the recording path.
The program runs on the Pi’s processor under Linux. Python is the language interpreter; the editor is where you change the file. Thonny offers an approachable editor on Raspberry Pi OS, but running a saved file from the terminal executes the same code when the same interpreter is selected.
The example uses only Python’s standard library. You do not need pandas or a cloud service to record a few CSV rows. CSV means comma-separated values, a common format for simple tables.
Simulation is honest when clearly labelled. The values below are invented demonstration inputs. They are not weather readings, benchmark results or evidence that a sensor was connected.
Make a project environment
Create a new project folder such as pi-logger under your home directory. In its terminal, run the Bash commands below. If creating the environment reports a missing venv component, install the distribution package python3-venv through apt first.
A virtual environment selects an isolated Python interpreter context and package location for the project. It helps prevent one project’s dependencies from changing another’s. It is not a full virtual computer, and it does not make untrusted code safe.
Current Raspberry Pi OS recommends virtual environments for pip-installed packages. The official OS guidance explains this separation. Later camera and GPIO examples may intentionally expose OS-managed packages using --system-site-packages; that is a specific choice, not the default required here.
python3 -m venv .venv
source .venv/bin/activate
python --version
python -c "import sys; print(sys.executable)"The first command creates .venv in the current project directory. source activates it for this shell. The final two commands show the Python version and executable path, so you can verify which interpreter will run your work.
Expected result: A Python version followed by a path ending in the project’s .venv/bin/python. Activating another terminal requires repeating the activation command.
Write the complete logger
Save this Python code as logger.py in the project folder using Thonny or another editor. Run it from the activated terminal with python logger.py. The output filename is deliberately labelled simulated.
import csv
from datetime import datetime, timezone
from pathlib import Path
from time import sleep
output = Path("simulated-readings.csv")
values = [19.8, 20.1, 20.0, 20.4, 20.2]
with output.open("x", newline="", encoding="utf-8") as handle:
writer = csv.writer(handle)
writer.writerow(["time_utc", "simulated_temperature_c"])
for value in values:
timestamp = datetime.now(timezone.utc).isoformat()
writer.writerow([timestamp, value])
handle.flush()
print(timestamp, value)
sleep(1)
print(f"Saved {len(values)} simulated readings to {output}")csv.writer handles commas and quoting correctly. The context manager closes the file even if an exception occurs. Opening with x creates a new file and refuses to overwrite an existing one. UTC timestamps explicitly include their timezone. flush() passes buffered text to the operating system; it is not a guarantee against every sudden power loss. sleep() spaces the demonstration rows roughly one second apart.
Expected result: Five timestamped values are printed, followed by a saved message. The CSV contains one header and five data rows; timestamps differ each time.
Inspect the result and understand errors
Open the CSV in a text editor or spreadsheet. Confirm that there are exactly five data rows, units appear in the column name and the timestamps are ordered. The values should match the list exactly because no sensor noise exists in this simulation.
Run the script again without renaming the output. A FileExistsError is intentional protection against overwriting your first recording. Choose a new filename or deliberately move the old file aside before rerunning. Do not remove that safeguard without deciding how real recordings should be preserved.
If the terminal says it cannot open logger.py, inspect the current directory and filename. If Python reports a syntax error, check the indicated line and the preceding one for missing punctuation or incorrect indentation. If an import fails for a third-party library later, check the interpreter path before installing packages again.
Avoid naming a script csv.py, time.py or another standard-library name. Python can load your local file instead of the intended library, creating confusing errors. Use a name that describes the project rather than shadows a module.
Prepare the boundary for real hardware
The list of values is the temporary measurement source. In PI07 a sensor read will replace that source while the recording principles remain the same. Keeping acquisition and storage separate means you can test the logger even when the hardware is unavailable.
Real measurements need more context: sensor model, raw units, calibration, missing-data behavior and actual sample time. A failed read should not silently become zero, because zero may be a valid physical value. Record an explicit error or missing value according to the project’s schema.
A one-second sleep does not produce a perfectly one-second sampling period because execution also takes time. For precise scheduling, use a monotonic clock to plan intervals, then record wall-clock timestamps separately. This simple exercise is suitable for learning files, not precision data acquisition.
Keep the project’s code and environment instructions together. When you later install packages, record their versions and the command used. Reproducing a result requires more than keeping the final CSV.
Important terms
- Interpreter
- The program that executes Python code.
- Virtual environment
- An isolated project context for Python and its packages.
- Standard library
- Modules distributed with Python.
- CSV
- A text format for rows and columns.
- Timestamp
- A recorded time associated with an event.
- Simulation
- An explicitly constructed substitute for a real process or measurement.
Mini project: Verify the logger’s contract
- Create and activate the environment, then record the interpreter path.
- Save logger.py and run it once.
- Check the CSV header and all five data rows.
- Run again and confirm that the existing file is protected.
- Finish by changing the output name and one simulated value, then verifying only the intended data changes.
Common mistakes and debugging
- Calling the invented values measured data: retain simulated labels.
- Installing a package in one interpreter and running another: inspect sys.executable.
- Assuming flush guarantees full durability: keep backups and shut down cleanly.
- Naming the script after an imported module: choose a distinct project filename.
Independent challenge
Add a second simulated column for relative light level and state its units. Keep both lists aligned and reject unequal lengths rather than silently dropping rows.
Check your understanding: 10 questions
Why use simulated data before a sensor?
What does file mode x prevent?
How many lines should the sample CSV contain?
Does a virtual environment protect against malicious code?
Why should a failed sensor read not automatically become zero?
In your own words, what does “Interpreter” mean?
In your own words, what does “Virtual environment” mean?
In your own words, what does “Standard library” mean?
In your own words, what does “CSV” mean?
In your own words, what does “Timestamp” mean?
Quiz answers
Reveal all 10 answers after your attempt
- It isolates and tests program and file behavior without electrical or measurement uncertainty.
- Accidentally overwriting an existing file.
- Six: one header and five data rows.
- No. It organizes Python dependencies; it is not a security sandbox.
- Zero may be a valid measurement, making failure indistinguishable from real data.
- The program that executes Python code.
- An isolated project context for Python and its packages.
- Modules distributed with Python.
- A text format for rows and columns.
- A recorded time associated with an event.
Summary
A small Python logger can be verified before hardware exists. Clear environment selection, explicit units and deliberate file handling make later sensor integration easier.
Continue learning
PI06 adds the first physical input and output while keeping the Python program small.
- Linux and Terminal Basics for Raspberry Pi
- Control Raspberry Pi GPIO Pins Safely
- Lists, Dictionaries, and Files in Python
- Python Libraries, pip, and Virtual Environments
- Build a Python Sensor-Data Logger and Analyzer
Sources and further reading
Prepared 2026-09-18. Editorial draft; primary documentation consulted. Hardware build not bench-tested; code has not been executed on the reference board.