You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派传感器数据上传ThingSpeak报错:SGP30对象无closed属性

Fixing Your Raspberry Pi Sensor-to-ThingSpeak Upload Code

Hey there, let's work through why your code stops after one successful data send and throws that 'SGP30' has no attribute 'closed' error. Here's a breakdown of the issues and a fixed version of your code:

1. The Main Error Cause

That chip.closed line at the end of your sensors() function is the problem. The SGP30 class from the sgp30 library doesn’t have a closed attribute at all. Even better—you don’t need this line! The with statement automatically handles closing the SGP30 resource when the block exits, so manual checks or calls like this are unnecessary.

2. Other Hidden Issues to Fix

  • Infinite Loop Inside with Block: Nesting your while True inside the with block keeps the SGP30 connection open indefinitely, which can cause resource leaks if the loop breaks unexpectedly.
  • ThingSpeak Rate Limit: The free ThingSpeak tier only allows one update every 15 seconds. Without a delay, you’ll hit this limit immediately, leading to failed requests.
  • Typo in HTTP Header: Content-typZZe should be Content-Type—this could have caused silent failures in data sending.
  • No Sensor Initialization: Most SGP30 implementations require an initialization step to get accurate readings.

Fixed Code

import httplib
import urllib
import time
import sys
import Adafruit_DHT
from sgp30 import SGP30
from smbus import SMBus

# Replace with your actual ThingSpeak API key
THINGSPEAK_API_KEY = "xxxxxxx"
SMBUS_BUS_NUMBER = 1

def read_sensor_data(chip):
    """Read and return data from SGP30 and DHT11 sensors"""
    # Read air quality from SGP30
    air_quality = chip.measure_air_quality()
    voc_ppb = air_quality.voc_ppb
    co2_ppm = air_quality.co2_ppm
    
    # Read temp/humidity from DHT11
    humidity, temperature = Adafruit_DHT.read_retry(11, 4)
    
    # Handle cases where DHT11 read fails
    if humidity is None or temperature is None:
        print("Warning: Failed to read DHT11 data!")
        return None, None, None, None
    
    return temperature, humidity, voc_ppb, co2_ppm

def send_to_thingspeak(temp, hum, voc, co2):
    """Send sensor data to ThingSpeak"""
    params = urllib.urlencode({
        'field1': temp,
        'field2': hum,
        'field3': voc,
        'field4': co2,
        'key': THINGSPEAK_API_KEY
    })
    headers = {
        "Content-Type": "application/x-www-form-urlencoded",
        "Accept": "text/plain"
    }
    
    try:
        conn = httplib.HTTPConnection("api.thingspeak.com:80")
        conn.request("POST", "/update", params, headers)
        response = conn.getresponse()
        
        print(f"Sent data: Temp={temp}°C | Hum={hum}% | VOC={voc}ppb | CO2={co2}ppm")
        print(f"ThingSpeak response: {response.status} {response.reason}")
        
        conn.close()
        return True
    except Exception as e:
        print(f"Failed to connect: {str(e)}")
        return False

def main():
    smbus = SMBus(SMBUS_BUS_NUMBER)
    # Use with statement to auto-manage SGP30 resource
    with SGP30(smbus) as sgp_chip:
        # Initialize SGP30 for accurate readings
        sgp_chip.initialise()
        print("Sensors initialized. Starting continuous data upload...")
        
        while True:
            temp, hum, voc, co2 = read_sensor_data(sgp_chip)
            # Only send data if all sensor readings are valid
            if all(value is not None for value in [temp, hum, voc, co2]):
                send_to_thingspeak(temp, hum, voc, co2)
            
            # Wait 15 seconds to comply with ThingSpeak's free tier limit
            time.sleep(15)

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        print("\nProgram stopped by user.")
        sys.exit(0)

Key Changes Explained

  • Removed chip.closed: The with statement takes care of closing the SGP30 connection automatically when the program exits the block.
  • Restructured Code: Split sensor reading and data sending into separate functions for better readability and reusability.
  • Added SGP30 Initialization: The sgp_chip.initialise() call ensures the sensor calibrates itself for accurate air quality readings.
  • 15-Second Delay: Prevents hitting ThingSpeak’s rate limit, which is critical for consistent data uploads.
  • Fixed Header Typo: Corrected the misspelled Content-Type header to ensure proper HTTP request formatting.
  • DHT11 Error Handling: Skips sending data if the DHT11 fails to read, avoiding invalid entries in ThingSpeak.
  • Clean Exit Handling: Lets you stop the program safely with Ctrl+C without leaving resources hanging.

This code should run continuously, sending data to ThingSpeak every 15 seconds without hitting the original closed attribute error.

内容的提问来源于stack exchange,提问作者Marcello Ianni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 15:53:12