I2C and Analog Ports Return Arbitrary Readings

Using Raspi and GrovePi+ cape with 1.3.0 firmware and python library, I can get digital relays and I2C RGB LCD to work, but the readings I’m getting from the analog sensors (light 1.1, gas MQ9, UV) are very sporadic and don’t correlate with reality (e.g. covering the light sensor). Indeed, I still get same range of values when the sensors are disconnected. I am having a similar issue with the TH02 sensor readings on I2C, although it at least throws an error when disconnected.

#-*- coding: utf-8 -*-
#!/usr/bin/env python

from datetime import datetime as dt
import grove_rgb_lcd as LCD
from grove_i2c_temp_hum_mini import th02
import grovepi, time, json, traceback

try:
   with open("ioMap.json") as f:
      ioMap = json.load(f)
      relays = ioMap["digital"]["relay"]
      ls_port = int(ioMap["analog"]["light"])
      buzzer = int(ioMap["digital"]["buzzer"])
      gas_port = int(ioMap["analog"]["MQ9"])

except:
   msg = 'JSON Failed:\n{}'.format(traceback.format_exc())
   print(msg)

#initialize sensors
thSense=th02()
grovepi.pinMode(ls_port,"INPUT")
grovepi.pinMode(gas_port,"INPUT")
grovepi.pinMode(buzzer,"OUTPUT")

for key in relays:
    grovepi.pinMode(relays[key],"OUTPUT")
    print(str(key)+" initialized on port D",relays[key])

def LCD_tempColor(temp):
   "set LCD color based on temperature"
   tooCold = 55
   tooHot = 85
   justRightH = 75
   justRightC = 65

   if(temp < justRightC):
      R = 0
      G = max(int(255*(temp-tooCold)/(justRightC-tooCold)),0)
      B = min(int(255-255*(temp-tooCold)/(justRightC-tooCold)),255)

   elif(temp > justRightH):
      R = min(int(255-255*(tooHot-airTemp)/(tooHot-justRightH)),255)
      G = max(int(255*(tooHot-airTemp)/(tooHot-justRightH)),0)
      B = 0

   else: #just right
      R = 0
      G = 255
      B = 0

   LCD.setRGB(R,G,B)
   return

def Relay(number, toggle):
   if toggle == "on":
      grovepi.digitalWrite(number,0)
   elif toggle == "off":
      grovepi.digitalWrite(number,1)
   else:
      print("relay error")
   return

def Light(port):
   # Get light sensor value time averaged over 2s 
   period_s = 2
   freq_Hz = 10
   measurements = int(period_s*freq_Hz)
   sensor_value = grovepi.analogRead(port)
   for i in range(measurements):
      time.sleep(1/freq_Hz)
      sensor_value += grovepi.analogRead(port)
   return sensor_value/(measurements+1)

def MQ9(port):
   sensor_value = grovepi.analogRead(port)
   return sensor_value

def Buzzer():
    # Buzz for 1 second
    grovepi.digitalWrite(buzzer,1)
    time.sleep(1)
    grovepi.digitalWrite(buzzer,0)
    return

while True:
   try:
      airHum = thSense.getHumidity()
      airTemp = thSense.getTemperature()
      light = Light(ls_port)
      gas = MQ9(gas_port)
      msg = str(dt.now().__format__("%Y.%m.%d %H:%M "))
      msg += "T:%.0fC RH:%.0f%% L:%.0f G:%.0f" %(airTemp, airHum, light, gas)
      print(msg)
      if light > 500:
         Buzzer()
         msg = "ALERT!"
      LCD_tempColor(airTemp)
      LCD.setText(msg)
      time.sleep(10)

   except:
      msg = 'Failed:\n{}'.format(traceback.format_exc())
      print(msg)
      exit()

The output is as follows, with the sensors located in my dining room ( and NOT in the oven as the th02 readings might have you believe :slight_smile:)
image
At various points in that data collection, I disconnected the gas sensor and shone a flashlight on the light sensor. In other runs, I’ve gotten temperature readings as low as -20. Something is clearly not working. I’ve had some of these same sensors working on a Galileo cape previously so am inclined to think it is an issue with this cape, its firmware, or something I’m missing in RPi configuration.

I thought it might have been the old Pi model B I was using originally, but am seeing the same issues with a newer Pi3 and a fresh raspbian stretch lite install.

Any help is much appreciated.

Results of troubleshooting below.

Check space left
================
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        30G  1.9G   27G   7% /
devtmpfs        434M     0  434M   0% /dev
tmpfs           438M     0  438M   0% /dev/shm
tmpfs           438M  5.9M  432M   2% /run
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           438M     0  438M   0% /sys/fs/cgroup
/dev/mmcblk0p1   44M   23M   22M  51% /boot
tmpfs            88M     0   88M   0% /run/user/1000

Check for dependencies
======================
python 2.7.13-2 install ok installed
python-pip 9.0.1-2+rpt2 install ok installed
git 1:2.11.0-3+deb9u4 install ok installed
libi2c-dev 3.1.2-3 install ok installed
python-serial 3.2.1-1 install ok installed
python-rpi.gpio 0.6.5~stretch-1 install ok installed
i2c-tools 3.1.2-3 install ok installed
python-smbus 3.1.2-3 install ok installed
dpkg-query: no packages found matching arduino
dpkg-query: no packages found matching minicom
dpkg-query: no packages found matching scratch

wiringPi Not Found (ERR)
I2C still in blacklist (ERR)
SPI still in blacklist (ERR)


Check for addition in /modules
==============================
I2C-dev already there
i2c-bcm2708 already there
spi-dev already there


Hardware revision
=================
./software_status.sh: line 78: gpio: command not found


Check the /dev folder
=====================
i2c-1
spidev0.0
spidev0.1
ttyAMA0

USB device status
=================
Bus 001 Device 004: ID 0424:7800 Standard Microsystems Corp. 
Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 1: Dev 3, If 0, Class=Hub, Driver=hub/3p, 480M
            |__ Port 1: Dev 4, If 0, Class=Vendor Specific Class, Driver=lan78xx, 480M
Raspbian for Robots Version
===========================
cat: /home/pi/di_update/Raspbian_For_Robots/Version: No such file or directory


Hostname
========
HabLab2


Checking for Atmega chip
========================

avrdude: Version 5.10, compiled on Jun 18 2012 at 12:38:29
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch

         System wide configuration file is "/etc/avrdude.conf"
         User configuration file is "/root/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : unknown
         Using Programmer              : gpio
         AVR Part                      : ATMEGA328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65     5     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : GPIO
         Description     : Use sysfs interface to bitbang GPIO lines

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f
avrdude: safemode: lfuse reads as FF
avrdude: safemode: hfuse reads as DA
avrdude: safemode: efuse reads as 5

avrdude: safemode: lfuse reads as FF
avrdude: safemode: hfuse reads as DA
avrdude: safemode: efuse reads as 5
avrdude: safemode: Fuses OK

avrdude done.  Thank you.


Checking I2C bus for devices
============================

Checking I2C bus 0
==================
Error: Could not open file `/dev/i2c-0' or `/dev/i2c/0': No such file or directory

Checking I2C bus 1
==================
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          03 04 -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 3e -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- 62 -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: 70 -- -- -- -- -- -- --                         

Checking for firmware version
=============================
GrovePi has firmware version: 1.3.0

So, let me reiterate the sensors/devices that you’re using:

  1. An RGB LCD - which works on the I2C.
  2. A TH02 - which works on the I2C.
  3. 3 analog sensors on the GrovePi - light, gas MQ9 and a UV detector.

The RGB LCD and the TH02 have nothing to do with the GrovePi, so their values should not be influenced in any way by the GrovePi.

That leaves us the 3 analog sensors: if you happen to have problems with these (which you seem to not by judging your post), take out the other I2C devices out and leave these 3 in. Check if they show any inexplicable irregularities and if they do, try testing one sensor at the time.

Maybe, just maybe, the I2C devices get into conflict with the GrovePi, which theoretically, this is not possible as long as you’re running this in a single Python process. Still, it might be a good idea to test these in 2 batches: at one time test all 3 analog sensors and then switch them with the I2C devices (the TH02 and the RGB LCD). Just like before, check if you see any problem while running them in this configuration.

Thank you!

  1. An RGB LCD - which works on the I2C.
  2. A TH02 - which works on the I2C.
  3. 3 analog sensors on the GrovePi - light, gas MQ9 and a UV detector.

The LCD works but the TH02 values seem spurious. I have tried the analog sensors without the TH02 connected and vice versa, but not with the LCD disconnected. I’ll give that a try.

What do you make of the troubleshooting report?:

wiringPi Not Found (ERR)
I2C still in blacklist (ERR)
SPI still in blacklist (ERR)

The troubleshooting looked fine to me. Nothing out of the ordinary.

Please test that and let me know how it goes. Even though it’s an I2C device and they shouldn’t be getting into conflict with one another (since they are all slaves).

Cheers!

Checking Analog Sensors
With just the I2C (LCD and TH02) unplugged (and commented out), I get the following readings for light and UV:
image
The red arrow indicates where I unplugged the UV sensor, the blue arrow about where light sensor was unplugged. Note that the sensor values increased! Why???

Running program again to check for consistency, with all I2C and analog (including light and UV sensors) disconnected, I still get these reading for light and UV:
image

These values seem less sporadic than before, but I would still expect to see zeros. Are my assumptions mistaken?

Plugging in the I2C only, and rebooting the Pi I still get nonzero analog readings on the disconnected sensors:
image

Checking TH02 (I2C)
Uncommenting my I2C code and showing the TH02 readings (with no analog connected):
image

Unplugging the LCD and all digital connections too, I still get these bad TH02 readings (should be about 20C, 30%RH):
image
Is it possible that the readings are somehow off by a factor of 10?

I would like to buy better Grove sensors, but can’t really justify it if they aren’t going to work anyway! Why should an analog sensor return a higher value when it is disconnected??

Hi @gdville,

That is the expected behavior.

In order for a port to qualify as an input port, its line must have a high impedance so that it can be driven by low impedance circuits (signals). When the line is high impedance and when it’s not connected to anything, its state cannot be guaranteed.

In your case, it translates to this “floatiness” that you see. There’s actually not much you can do about it and it’s how it actually works. I heard that sometimes, an input port can be paired with a weak pullup/pulldown resistor to take it back to the default value - this obviously requires you to use a big resistor. But there are also drawbacks to that approach, mainly that you won’t be able to let the input change as fast as possible according to the external signal and depending on your application, that can be a show-stopper.

So, the Grove sensors work just fine and you’ll be seeing the same behavior with any other sensor too. Maybe your only option is to add some weak pulldown resistors to the analog input ports - they should be high enough that the input signal can still affect the voltage on the input port and low enough that the input signal can still go down when nothing is connected to the port.

As for the TH02 readings, there isn’t much I can say about. I haven’t played with it at all. Since it’s not dependent on the GrovePi, I take that everything must be in its library, so if there’s something bad with it, then it has to be in there.

Thank you!

Thanks Robert. I understand what you are saying about the pulldowns, should have realized that. Unfortunately, it looks like the TH02 is all over the place from run to run, even if I interpret the results dividing by 10.

Maybe the TH02 sensor is just bad. Is there any chance for you to get a new one to side test it?

Really appreciate your assistance Robert.
Unfortunately, that’s one of the sensors of which I have no duplicate. Can’t really justify buying more Grove sensors at this point.
I do have the analog one (http://wiki.seeedstudio.com/Grove-Temperature_Sensor_V1.2/).
I also have a couple standalone AM2302 TH sensors similar to http://wiki.seeedstudio.com/Grove-Temperature_and_Humidity_Sensor_Pro/.

I did a three way comparison of temp (2 way for humidity) using this code:

import grovepi
from grove_i2c_temp_hum_mini import th02
from time import sleep

dPort = 4 # Connect the Grove Temperature & Humidity Sensor Pro (white AM2302) to digital port D4
aPort = 2 # Connect Temp Sensor to A2
grovepi.pinMode(aPort,"INPUT")
thSense=th02() # Connect TH02 to I2C

print("Temperature(C)     Humidity(%)")

while True:
    try:
        [dTemp,dHumidity] = grovepi.dht(dPort,1) #1 indicates white sensor
        aTemp = grovepi.analogRead(aPort)
        iHumidity = thSense.getHumidity()
        iTemp = thSense.getTemperature()
        print("D%.0f  A%.0f  I%.0f        D%.0f I%.0f" %(dTemp, aTemp, iTemp, dHumidity, iHumidity))
        sleep(2)

    except IOError:
        print ("Error")

The results (using 10k pullup) on the “DHT Pro”:
image

The DHT readings are believable and agree between the two sensors, so I’ll probably just drop the I2C based TH02.

The tuple printing between my readings appears to be coming from the grovepi.dht code reflecting I2C address info. [Edited to reflect getting recycled DHTs to work]

Shouldn’t aTemp be normalized? It returns quite a high number. Anyhow, the most stable sensor seems to be the DHT one (the AM2302 TH).

As for the TH02, maybe there’s something wrong with the library. Going on Google and searching for TH02 python, you’ll see a bunch of libraries written in Python for the given sensor. Since this sensor is not exactly tied to the GrovePi, I think you could very well try out a different library and see if that solves your problem.

If it does solve your problem, then it means ours is bad and has to be updated.