'Communication between GrovePi vibration sensor and Raspberry pi

[code][1]I have a GrovePi to connect the vibration sensor to raspberry pi. I have downloaded the Groove software on my raspberry pi by using the following command:

cd /home/pi/Desktop
sudo git clone https://github.com/DexterInd/GrovePi
cd /home/pi/Desktop/GrovePi/Script
sudo chmod +x install.sh
sudo ./install.sh
sudo pip install grovepi

After this I rebooted my raspberry pi and then when I inside the folder:

cd /home/pi/Desktop/GrovePi/Software/Python
sudo python grove_piezo_vibration_sensor.py

I am getting following errors:

Trceback (most recent call last):

File "grove_piezo_vibration_sensor.py", line 49, in <module>
    print(grovepi.analogRead(piezo))
File "/home/pi/Desktop/GrovePi/Software/Python/grovepi.py", line 227, in analogRead
    return number[1] * 256 +number[2]
TypeError: 'int' object has no attribute '__getitem__'

The code that I used was:

import time
import grovepi
# Connect the Grove Piezo Vibration Sensor to analog port A0
# OUT,NC,VCC,GND
piezo = 0

grovepi.pinMode(piezo,"INPUT")

while True:
    try:
        # When vibration is detected, the sensor outputs a logic high signal
        print grovepi.analogRead(piezo)
        time.sleep(.5)
    except IOError:
        print "Error"

Can you tell me what am I doing wrong. Thank you!



Solution 1:[1]

If you look at the grovepi code, the analogRead function look like this:

def analogRead(pin):
    write_i2c_block(address, aRead_cmd + [pin, unused, unused])
    read_i2c_byte(address)
    number = read_i2c_block(address)
    return number[1] * 256 + number[2]

You're seeing an exception on that last line, where it was expecting some kind of sequence back from read_i2c_block but instead got a single integer. Looking elsewhere in the code, we see that read_i2c_block looks like this:

def read_i2c_block(address):
    for i in range(retries):
        try:
            return bus.read_i2c_block_data(address, 1)
        except IOError:
            if debug:
                print ("IOError")
    return -1

Now, it looks as if read_i2c_block_data (from the smbus module) will always return a list. That means the only way you're getting a single integer back from the above function is if it encounters an IOError exception. This will be masked by the exception IOError block, and the function will then return -1.

There are a number of problems with this code in the grovepi module. First, anything calling read_i2c_block (like the analogRead function) should be checking for the -1 return value. Second, masking the exception like this isn't particularly helpful, because the exception probably contains information that would point to the source of the problem. Consider replacing the above code with:

    for i in range(retries):
        try:
            return bus.read_i2c_block_data(address, 1)
        except IOError:
            if debug:
                raise

And then enable debug mode. That should be something like:

import grovepi
grovepi.debug = 1

Now, run your code, and you should see the exception. See if it contains any more details about the error.

Solution 2:[2]

I also encountered this error. The problem, as @larsks hints above, is that i2c is not working. You can confirm this with:

sudo i2cdetect -y 1

This will output something like the below image. If you don't see the 04 (in column 4, row 00) then your Raspberry Pi cannot communicate with the Atmega chip on the GrovePi hat.

enter image description here

You likely need to update the firmware

# install required packages 
sudo apt-get install python-smbus i2c-tools

Then follow the instructions here https://github.com/DexterInd/GrovePi/tree/master/Firmware

Finally (if you have not already), enable i2C in raspi-config

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 larsks
Solution 2 ow3n