树莓派3向Ubidots发送土壤湿度传感器数据返回None求助
Hey there, let's work through your soil moisture sensor + Ubidots issue step by step! I'll break down what's causing that weird None in your output, fix the Ubidots data transmission, and show you how to properly log error tracebacks.
1. Why you're seeing Moisture Level: 26508 None
That output has two separate issues:
- The
>in your format string is an HTML escape character—Python's string formatting doesn't recognize it, so it's being treated as plain text. You need to use a regular>instead for right-aligned number formatting. - The
Noneis coming from thetraceback.print_exc()line at the very end of your code. When your loop runs normally (without hitting Ctrl+C), after the loop exits, that line executes—but since there's no active exception,traceback.print_exc()returnsNone, which gets printed in some environments.
2. Fixing the Ubidots data send
Your current code uses data=payload to send data, but Ubidots' API prefers JSON-formatted payloads. Switching to json=payload will make sure your data is parsed correctly. Also, double-check that your token is correctly formatted (remove the curly braces around it if you haven't already!).
3. Properly capturing and printing tracebacks
Your current traceback.print_exc() is in the wrong place—it only runs after the loop ends. To catch errors during the Ubidots request (like network drops or invalid tokens), you need to move it inside an exception block that specifically handles request-related errors.
Fixed Full Code
import time import requests import traceback import Adafruit_ADS1x15 # Initialize ADS1115 ADC adc = Adafruit_ADS1x15.ADS1115() GAIN = 1 # Configure Ubidots credentials (replace with your actual values!) UBIDOTS_TOKEN = "A1E-6l4DwwC86SDR6QRTJWXGDwshTGPHFl" DEVICE_LABEL = "raspberry" print('Reading ADS1x15 values, press Ctrl-C to quit...') try: while True: # Read soil moisture value from ADC channel 0 moisture_value = adc.read_adc(0, gain=GAIN) # Use underscores in variable names to avoid Ubidots parsing issues payload = {'soil_humidity': moisture_value} try: # Send data to Ubidots using JSON format response = requests.post( f'http://things.ubidots.com/api/v1.6/devices/{DEVICE_LABEL}/?token={UBIDOTS_TOKEN}', json=payload ) # Raise an error if the HTTP request fails (4xx/5xx status codes) response.raise_for_status() # Print clean, formatted output with request status print(f'Moisture Level: {moisture_value:>6} | Ubidots Status: {response.status_code}') except requests.exceptions.RequestException as e: # Print user-friendly error + detailed traceback if request fails print(f'Failed to send data to Ubidots: {str(e)}') traceback.print_exc() time.sleep(1) except KeyboardInterrupt: print('\nProgram stopped by user.')
Key Improvements
- Fixed the format string by replacing
>with>for proper right-aligned number display. - Switched to
json=payloadto match Ubidots' API requirements, reducing parsing errors. - Moved
traceback.print_exc()inside the request error handler—now it only runs when there's an actual issue (like bad token or no internet), giving you actionable debug info. - Added
response.raise_for_status()to catch HTTP errors (like invalid tokens) immediately. - Added Ubidots status code to the output so you can confirm data is being sent successfully (a 201 status means your data was accepted).
How to Test
- Run the fixed code—you should see clean output like
Moisture Level: 26508 | Ubidots Status: 201if everything works. - If you hit issues (e.g., no internet, wrong token), the code will print a clear error message plus a detailed traceback to help you diagnose the problem.
内容的提问来源于stack exchange,提问作者Tia

