first commit

This commit is contained in:
pandacraft 2025-03-21 16:04:17 +01:00
commit a5a0434432
1126 changed files with 439481 additions and 0 deletions

View file

@ -0,0 +1,64 @@
#!/usr/bin/env python
#
# GrovePi Hardware Test
# Connect Buzzer to Port D8
# Connect Button to Analog Port A0
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.grovepi.com
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
import grovepi
# Connect the Grove Button to Analog Port 0.
button = 14 # This is the A0 pin.
buzzer = 8 # This is the D8 pin.
grovepi.pinMode(button,"INPUT")
grovepi.pinMode(buzzer,"OUTPUT")
print("GrovePi Basic Hardware Test.")
print("Setup: Connect the button sensor to port A0. Connect a Grove Buzzer to port D8.")
print("Press the button and the buzzer will buzz!")
while True:
try:
butt_val = grovepi.digitalRead(button) # Each time we go through the loop, we read A0.
print (butt_val) # Print the value of A0.
if butt_val == 1:
grovepi.digitalWrite(buzzer,1)
print ('start')
time.sleep(1)
else:
grovepi.digitalWrite(buzzer,0)
time.sleep(.5)
except IOError:
print ("Error")

30
Software/Python/README.md Executable file
View file

@ -0,0 +1,30 @@
## Installing the GrovePi for Python
This is how the GrovePi python library has to be installed:
```bash
curl -kL dexterindustries.com/update_grovepi | bash
```
You can also install it by running the `setup.py` installer, but beware of the other requirements for it too: specifically about the `di_i2c` module from https://github.com/DexterInd/RFR_Tools that has to be installed and the enabling of the I2C in `raspi-config` menu.
```
pip install -r requirements.txt
```
```
python3 setup.py install
```
You can also run `python setup.py test` to test import the modules of the GrovePi package that are listed in the [package_modules.txt](package_modules.txt) file. The `python setup.py test` commands should be run after pip installing the dependencies.
## Library Breakdown
There are 2 kind of example scripts:
1. Example programs that only require the `grovepi` module - these example scripts are found in this directory (or root directory of the Python package).
1. Example programs that are based on other sublibraries other than the `grovepi` module - these example scripts are found in the subdirectories of this directory.
The libraries installed with the GrovePi package are listed in [here](package_modules.txt).
## Python Consideration
Even though you can install the GrovePi package for both versions of it (2.x and 3.x), some libraries other than the main one (`grovepi.py`) can only be used with Python3. Therefore, it's just better to use Python 3 by-default, instead of relying on an older version of Python which will anyway get retired in the very near future.

View file

@ -0,0 +1,63 @@
#!/usr/bin/env python
#
# GrovePi Example for testing both digital and anlog reads
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://www.dexterindustries.com/forum/?forum=grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
import grovepi
# Connect the Grove Button to digital port D3
# SIG,NC,VCC,GND
button2 = 2
button3 = 3
button4 = 4
sensor0 = 0
sensor1 = 1
sensor2 = 2
grovepi.pinMode(button2,"INPUT")
grovepi.pinMode(button3,"INPUT")
grovepi.pinMode(button4,"INPUT")
while True:
try:
print time.time(),
d2=grovepi.digitalRead(button2)
d3=grovepi.digitalRead(button3)
d4=grovepi.digitalRead(button4)
sensor_value0 = grovepi.analogRead(sensor0)
sensor_value1 = grovepi.analogRead(sensor1)
sensor_value2 = grovepi.analogRead(sensor2)
print ("%d,%d,%d" %(d2,d3,d4)),
print ("%d,%d,%d" %(sensor_value0,sensor_value1,sensor_value2))
except IOError:
print ("Error")

View file

@ -0,0 +1,51 @@
#!/usr/bin/env python
#
# GrovePi test for using the multiple analog sensors
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://www.dexterindustries.com/forum/?forum=grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
import grovepi
#Sensor connected to A0,A1,A2 Port
sensor0 = 0
sensor1 = 1
sensor2 = 2
while True:
try:
sensor_value0 = grovepi.analogRead(sensor0)
sensor_value1 = grovepi.analogRead(sensor1)
sensor_value2 = grovepi.analogRead(sensor2)
print ("%d,%d,%d" %(sensor_value0,sensor_value1,sensor_value2))
except IOError:
print ("Error")

View file

@ -0,0 +1,55 @@
#!/usr/bin/env python
#
# GrovePi test for multiple digital reads
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://www.dexterindustries.com/forum/?forum=grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
import grovepi
# Connect the Grove Button to digital port D2,D3 and D4
# SIG,NC,VCC,GND
button2 = 2
button3 = 3
button4 = 4
grovepi.pinMode(button2,"INPUT")
grovepi.pinMode(button3,"INPUT")
grovepi.pinMode(button4,"INPUT")
while True:
try:
d2=grovepi.digitalRead(button2)
d3=grovepi.digitalRead(button3)
d4=grovepi.digitalRead(button4)
print ("%d,%d,%d" %(d2,d3,d4))
except IOError:
print ("Error")

View file

@ -0,0 +1,64 @@
#!/usr/bin/env python
# GrovePi LED blink test for the Grove LED Socket (http://www.seeedstudio.com/wiki/Grove_-_LED_Socket_Kit)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://www.dexterindustries.com/forum/?forum=grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
from grovepi import *
# Connect the Grove LED to digital port D4,D5,D6
led0 = 4
led1 = 5
led2 = 6
pinMode(led0,"OUTPUT")
pinMode(led1,"OUTPUT")
pinMode(led2,"OUTPUT")
while True:
try:
#Blink the LED
digitalWrite(led0,1) # Send HIGH to switch on LED
digitalWrite(led1,1) # Send HIGH to switch on LED
digitalWrite(led2,1) # Send HIGH to switch on LED
print ("LED ON!")
time.sleep(1)
digitalWrite(led0,0) # Send LOW to switch off LED
digitalWrite(led1,0) # Send LOW to switch off LED
digitalWrite(led2,0) # Send LOW to switch off LED
print ("LED OFF!")
time.sleep(1)
except IOError: # Print "Error" if communication error encountered
print ("Error")

View file

@ -0,0 +1,63 @@
#!/usr/bin/env python
#
# GrovePi Example for using a Grove 2-Coil Latching Relay(http://www.seeedstudio.com/wiki/Grove_-_2-Coil_Latching_Relay)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
# NOTE: Contrast to the ordinary relay, this latching relay does not need continuous power to keep the state, which makes it especially low power consumption
import time
import grovepi
# Connect the Grove 2-Coil Latching Relay to digital port D4
# SIG,NC,VCC,GND
relay = 4
grovepi.pinMode(relay,"OUTPUT")
while True:
try:
# switch on for 5 seconds
grovepi.digitalWrite(relay,1)
print ("on")
time.sleep(5)
# switch off for 5 seconds
grovepi.digitalWrite(relay,0)
print ("off")
time.sleep(5)
except KeyboardInterrupt:
grovepi.digitalWrite(relay,0)
break
except IOError:
print ("Error")

View file

@ -0,0 +1,158 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove 4 Digit Display ( http://www.seeedstudio.com/wiki/Grove_-_4-Digit_Display)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
# NOTE: 4x red 7 segment display with colon and 8 luminance levels, but no decimal points
import time
import grovepi
# Connect the Grove 4 Digit Display to digital port D5
# CLK,DIO,VCC,GND
display = 5
grovepi.pinMode(display,"OUTPUT")
# If you have an analog sensor connect it to A0 so you can monitor it below
sensor = 0
grovepi.pinMode(sensor,"INPUT")
time.sleep(.5)
# 4 Digit Display methods
# grovepi.fourDigit_init(pin)
# grovepi.fourDigit_number(pin,value,leading_zero)
# grovepi.fourDigit_brightness(pin,brightness)
# grovepi.fourDigit_digit(pin,segment,value)
# grovepi.fourDigit_segment(pin,segment,leds)
# grovepi.fourDigit_score(pin,left,right)
# grovepi.fourDigit_monitor(pin,analog,duration)
# grovepi.fourDigit_on(pin)
# grovepi.fourDigit_off(pin)
while True:
try:
print ("Test 1) Initialise")
grovepi.fourDigit_init(display)
time.sleep(.5)
print ("Test 2) Set brightness")
for i in range(0,8):
grovepi.fourDigit_brightness(display,i)
time.sleep(.2)
time.sleep(.3)
# set to lowest brightness level
grovepi.fourDigit_brightness(display,0)
time.sleep(.5)
print ("Test 3) Set number without leading zeros")
leading_zero = 0
grovepi.fourDigit_number(display,1,leading_zero)
time.sleep(.5)
grovepi.fourDigit_number(display,12,leading_zero)
time.sleep(.5)
grovepi.fourDigit_number(display,123,leading_zero)
time.sleep(.5)
grovepi.fourDigit_number(display,1234,leading_zero)
time.sleep(.5)
print ("Test 4) Set number with leading zeros")
leading_zero = 1
grovepi.fourDigit_number(display,5,leading_zero)
time.sleep(.5)
grovepi.fourDigit_number(display,56,leading_zero)
time.sleep(.5)
grovepi.fourDigit_number(display,567,leading_zero)
time.sleep(.5)
grovepi.fourDigit_number(display,5678,leading_zero)
time.sleep(.5)
print ("Test 5) Set individual digit")
grovepi.fourDigit_digit(display,0,2)
grovepi.fourDigit_digit(display,1,6)
grovepi.fourDigit_digit(display,2,9)
grovepi.fourDigit_digit(display,3,15) # 15 = F
time.sleep(.5)
print ("Test 6) Set individual segment")
grovepi.fourDigit_segment(display,0,118) # 118 = H
grovepi.fourDigit_segment(display,1,121) # 121 = E
grovepi.fourDigit_segment(display,2,118) # 118 = H
grovepi.fourDigit_segment(display,3,121) # 121 = E
time.sleep(.5)
grovepi.fourDigit_segment(display,0,57) # 57 = C
grovepi.fourDigit_segment(display,1,63) # 63 = O
grovepi.fourDigit_segment(display,2,63) # 63 = O
grovepi.fourDigit_segment(display,3,56) # 56 = L
time.sleep(.5)
print ("Test 7) Set score")
grovepi.fourDigit_score(display,0,0)
time.sleep(.2)
grovepi.fourDigit_score(display,1,0)
time.sleep(.2)
grovepi.fourDigit_score(display,1,1)
time.sleep(.2)
grovepi.fourDigit_score(display,1,2)
time.sleep(.2)
grovepi.fourDigit_score(display,1,3)
time.sleep(.2)
grovepi.fourDigit_score(display,1,4)
time.sleep(.2)
grovepi.fourDigit_score(display,1,5)
time.sleep(.5)
print ("Test 8) Set time")
grovepi.fourDigit_score(display,12,59)
time.sleep(.5)
print ("Test 9) Monitor analog pin")
seconds = 10
grovepi.fourDigit_monitor(display,sensor,seconds)
time.sleep(.5)
print ("Test 10) Switch all on")
grovepi.fourDigit_on(display)
time.sleep(.5)
print ("Test 11) Switch all off")
grovepi.fourDigit_off(display)
time.sleep(.5)
except KeyboardInterrupt:
grovepi.fourDigit_off(display)
break
except IOError:
print ("Error")

View file

@ -0,0 +1,58 @@
#!/usr/bin/env python
#
# GrovePi example for using the Grove - 6-Axis Accelerometer&Compass v2.0(http://www.seeedstudio.com/depot/Grove-6Axis-AccelerometerCompass-v20-p-2476.html)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this library? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import lsm303d
try:
acc_mag=lsm303d.lsm303d()
while True:
# Get accelerometer values
acc=acc_mag.getRealAccel()
# Wait for compass to get ready
while True:
if acc_mag.isMagReady():
break
# Read the heading
heading= acc_mag.getHeading()
print("Acceleration of X,Y,Z is %.3fg, %.3fg, %.3fg" %(acc[0],acc[1],acc[2]))
print("Heading %.3f degrees\n" %(heading))
except IOError:
print("Unable to read from accelerometer, check the sensor and try again")

View file

@ -0,0 +1,211 @@
#!/usr/bin/env python
#
# GrovePi Library for using the Grove - 6-Axis Accelerometer&Compass v2.0(http://www.seeedstudio.com/depot/Grove-6Axis-AccelerometerCompass-v20-p-2476.html)
#
# This sensor uses LSM303D chip and the library works in Python for the Raspberry Pi
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this library? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
# Released under the MIT license (http://choosealicense.com/licenses/mit/).
# For more information see https://github.com/DexterInd/GrovePi/blob/master/LICENSE
import time,sys
import RPi.GPIO as GPIO
import smbus
import math
# use the bus that matches your raspi version
rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
bus = smbus.SMBus(1)
else:
bus = smbus.SMBus(0)
class lsm303d:
# LSM303 Address definitions
LSM303D_ADDR = 0x1E # assuming SA0 grounded
# LSM303 Register definitions
TEMP_OUT_L = 0x05
TEMP_OUT_H = 0x06
STATUS_REG_M = 0x07
OUT_X_L_M = 0x08
OUT_X_H_M = 0x09
OUT_Y_L_M = 0x0A
OUT_Y_H_M = 0x0B
OUT_Z_L_M = 0x0C
OUT_Z_H_M = 0x0D
WHO_AM_I = 0x0F
INT_CTRL_M = 0x12
INT_SRC_M = 0x13
INT_THS_L_M = 0x14
INT_THS_H_M = 0x15
OFFSET_X_L_M = 0x16
OFFSET_X_H_M = 0x17
OFFSET_Y_L_M = 0x18
OFFSET_Y_H_M = 0x19
OFFSET_Z_L_M = 0x1A
OFFSET_Z_H_M = 0x1B
REFERENCE_X = 0x1C
REFERENCE_Y = 0x1D
REFERENCE_Z = 0x1E
CTRL_REG0 = 0x1F
CTRL_REG1 = 0x20
CTRL_REG2 = 0x21
CTRL_REG3 = 0x22
CTRL_REG4 = 0x23
CTRL_REG5 = 0x24
CTRL_REG6 = 0x25
CTRL_REG7 = 0x26
STATUS_REG_A = 0x27
OUT_X_L_A = 0x28
OUT_X_H_A = 0x29
OUT_Y_L_A = 0x2A
OUT_Y_H_A = 0x2B
OUT_Z_L_A = 0x2C
OUT_Z_H_A = 0x2D
FIFO_CTRL = 0x2E
FIFO_SRC = 0x2F
IG_CFG1 = 0x30
IG_SRC1 = 0x31
IG_THS1 = 0x32
IG_DUR1 = 0x33
IG_CFG2 = 0x34
IG_SRC2 = 0x35
IG_THS2 = 0x36
IG_DUR2 = 0x37
CLICK_CFG = 0x38
CLICK_SRC = 0x39
CLICK_THS = 0x3A
TIME_LIMIT = 0x3B
TIME_LATENCY = 0x3C
TIME_WINDOW = 0x3D
ACT_THS = 0x3E
ACT_DUR = 0x3F
MAG_SCALE_2 = 0x00 #full-scale is +/-2Gauss
MAG_SCALE_4 = 0x20 #+/-4Gauss
MAG_SCALE_8 = 0x40 #+/-8Gauss
MAG_SCALE_12 = 0x60 #+/-12Gauss
ACCELE_SCALE = 2
X = 0
Y = 1
Z = 2
# Set up the sensor
def __init__(self,):
self.write_reg(0x57, self.CTRL_REG1) # 0x57 = ODR=50hz, all accel axes on
self.write_reg((3<<6)|(0<<3), self.CTRL_REG2) # set full-scale
self.write_reg(0x00, self.CTRL_REG3) # no interrupt
self.write_reg(0x00, self.CTRL_REG4) # no interrupt
self.write_reg((4<<2), self.CTRL_REG5) # 0x10 = mag 50Hz output rate
self.write_reg(self.MAG_SCALE_2, self.CTRL_REG6) # magnetic scale = +/-1.3Gauss
self.write_reg(0x00, self.CTRL_REG7) # 0x00 = continouous conversion mode
time.sleep(.005)
# get the status of the sensor
def status(self):
if self.read_reg(self.WHO_AM_I) !=73:
return -1
return 1
# Write data to a reg on the I2C device
def write_reg(self,data,reg):
bus.write_byte_data(self.LSM303D_ADDR, reg, data)
# Read data from the sensor
def read_reg(self,reg):
return bus.read_byte_data(self.LSM303D_ADDR, reg)
# Check if compass is ready
def isMagReady(self):
if self.read_reg(self.STATUS_REG_M)&0x03!=0:
return 1
return 0
# Get raw accelerometer values
def getAccel(self):
raw_accel=[0,0,0]
raw_accel[0]=((self.read_reg(self.OUT_X_H_A)<<8)|self.read_reg(self.OUT_X_L_A))
raw_accel[1]=((self.read_reg(self.OUT_Y_H_A)<<8)|self.read_reg(self.OUT_Y_L_A))
raw_accel[2]=((self.read_reg(self.OUT_Z_H_A)<<8)|self.read_reg(self.OUT_Z_L_A))
#2's compiment
for i in range(3):
if raw_accel[i]>32767:
raw_accel[i]=raw_accel[i]-65536
return raw_accel
# Get accelerometer values in g
def getRealAccel(self):
realAccel=[0.0,0.0,0.0]
accel=self.getAccel()
for i in range(3):
realAccel[i] = round(accel[i] / math.pow(2, 15) * self.ACCELE_SCALE,3)
return realAccel
# Get compass raw values
def getMag(self):
raw_mag=[0,0,0]
raw_mag[0]=(self.read_reg(self.OUT_X_H_M)<<8)|self.read_reg(self.OUT_X_L_M)
raw_mag[1]=(self.read_reg(self.OUT_Y_H_M)<<8)|self.read_reg(self.OUT_Y_L_M)
raw_mag[2]=(self.read_reg(self.OUT_Z_H_M)<<8)|self.read_reg(self.OUT_Z_L_M)
#2's compiment
for i in range(3):
if raw_mag[i]>32767:
raw_mag[i]=raw_mag[i]-65536
return raw_mag
# Get heading from the compass
def getHeading(self):
magValue=self.getMag()
heading = 180*math.atan2(magValue[self.Y], magValue[self.X])/math.pi# // assume pitch, roll are 0
if (heading <0):
heading += 360
return round(heading,3)
def getTiltHeading(self):
magValue=self.getMag()
accelValue=self.getRealAccel()
X=self.X
Y=self.Y
Z=self.Z
pitch = math.asin(-accelValue[X])
print(accelValue[Y],pitch,math.cos(pitch),accelValue[Y]/math.cos(pitch),math.asin(accelValue[Y]/math.cos(pitch)))
roll = math.asin(accelValue[Y]/math.cos(pitch))
xh = magValue[X] * math.cos(pitch) + magValue[Z] * math.sin(pitch)
yh = magValue[X] * math.sin(roll) * math.sin(pitch) + magValue[Y] * math.cos(roll) - magValue[Z] * math.sin(roll) * math.cos(pitch)
zh = -magValue[X] * (roll) * math.sin(pitch) + magValue[Y] * math.sin(roll) + magValue[Z] * math.cos(roll) * math.cos(pitch)
heading = 180 * math.atan2(yh, xh)/math.pi
if (yh >= 0):
return heading
else:
return (360 + heading)
if __name__ == "__main__":
acc_mag=lsm303d()
while True:
print(acc_mag.getRealAccel())
while True:
if acc_mag.isMagReady():
break
print(acc_mag.getHeading())
# Do not use, math error
# print acc_mag.getTiltHeading()

View file

@ -0,0 +1,64 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove 80cm Infrared Proximity Sensor(http://www.seeedstudio.com/wiki/Grove_-_80cm_Infrared_Proximity_Sensor)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
import grovepi
# Connect the Grove 80cm Infrared Proximity Sensor to analog port A0
# SIG,NC,VCC,GND
sensor = 0
grovepi.pinMode(sensor,"INPUT")
time.sleep(1)
# Reference voltage of ADC is 5v
adc_ref = 5
# Vcc of the grove interface is normally 5v
grove_vcc = 5
while True:
try:
# Read sensor value
sensor_value = grovepi.analogRead(sensor)
# Calculate voltage
voltage = round((float)(sensor_value) * adc_ref / 1024, 2)
print("sensor_value =", sensor_value, " voltage =", voltage)
except IOError:
print ("Error")

View file

@ -0,0 +1,26 @@
Copyright (c) 2013, Pimoroni Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
- Neither the name of the copyright holders nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,24 @@
adxl345-python
==============
Raspberry Pi Python i2c library for the ADXL3453-axis MEMS accelerometer IC which is used in breakout boards like the Adafruit ADXL345 Triple-Axis Accelerometer (http://www.adafruit.com/product/163).
This library is a basic implementation of the i2c protocol for the IC offering a simple way to get started with it on the Raspberry Pi.
You can import the module and get a sensor reading like this:
from adxl345 import ADXL345
adxl345 = ADXL345()
axes = adxl345.getAxes(True)
print "ADXL345 on address 0x%x:" % (adxl345.address)
print " x = %.3fG" % ( axes['x'] )
print " y = %.3fG" % ( axes['y'] )
print " z = %.3fG" % ( axes['z'] )
or you can run it directly from the command line like this:
sudo python ADXL345.py
which will output the current x, y, and z axis readings in Gs.

View file

@ -0,0 +1,112 @@
# ADXL345 Python library for Raspberry Pi
#
# author: Jonathan Williamson
# license: BSD, see LICENSE.txt included in this package
#
# This is a Raspberry Pi Python implementation to help you get started with
# the Adafruit Triple Axis ADXL345 breakout board:
# http://shop.pimoroni.com/products/adafruit-triple-axis-accelerometer
import smbus
from time import sleep
# select the correct i2c bus for this revision of Raspberry Pi
with open('/proc/cpuinfo', 'r') as file:
revision = ([l[12:-1] for l in file.readlines() if l[:8]=="Revision"]+['0000'])[0]
bus = smbus.SMBus(1 if int(revision, 16) >= 4 else 0)
# ADXL345 constants
EARTH_GRAVITY_MS2 = 9.80665
SCALE_MULTIPLIER = 0.004
DATA_FORMAT = 0x31
BW_RATE = 0x2C
POWER_CTL = 0x2D
BW_RATE_1600HZ = 0x0F
BW_RATE_800HZ = 0x0E
BW_RATE_400HZ = 0x0D
BW_RATE_200HZ = 0x0C
BW_RATE_100HZ = 0x0B
BW_RATE_50HZ = 0x0A
BW_RATE_25HZ = 0x09
RANGE_2G = 0x00
RANGE_4G = 0x01
RANGE_8G = 0x02
RANGE_16G = 0x03
MEASURE = 0x08
AXES_DATA = 0x32
class ADXL345:
address = None
def __init__(self, address = 0x53):
self.address = address
self.setBandwidthRate(BW_RATE_100HZ)
self.setRange(RANGE_2G)
self.enableMeasurement()
def enableMeasurement(self):
bus.write_byte_data(self.address, POWER_CTL, MEASURE)
def setBandwidthRate(self, rate_flag):
bus.write_byte_data(self.address, BW_RATE, rate_flag)
# set the measurement range for 10-bit readings
def setRange(self, range_flag):
value = bus.read_byte_data(self.address, DATA_FORMAT)
value &= ~0x0F;
value |= range_flag;
value |= 0x08;
bus.write_byte_data(self.address, DATA_FORMAT, value)
# returns the current reading from the sensor for each axis
#
# parameter gforce:
# False (default): result is returned in m/s^2
# True : result is returned in gs
def getAxes(self, gforce = False):
bytes = bus.read_i2c_block_data(self.address, AXES_DATA, 6)
x = bytes[0] | (bytes[1] << 8)
if(x & (1 << 16 - 1)):
x = x - (1<<16)
y = bytes[2] | (bytes[3] << 8)
if(y & (1 << 16 - 1)):
y = y - (1<<16)
z = bytes[4] | (bytes[5] << 8)
if(z & (1 << 16 - 1)):
z = z - (1<<16)
x = x * SCALE_MULTIPLIER
y = y * SCALE_MULTIPLIER
z = z * SCALE_MULTIPLIER
if gforce == False:
x = x * EARTH_GRAVITY_MS2
y = y * EARTH_GRAVITY_MS2
z = z * EARTH_GRAVITY_MS2
x = round(x, 4)
y = round(y, 4)
z = round(z, 4)
return {"x": x, "y": y, "z": z}
if __name__ == "__main__":
# if run directly we'll just create an instance of the class and output
# the current readings
adxl345 = ADXL345()
axes = adxl345.getAxes(True)
print("ADXL345 on address 0x%x:" % (adxl345.address))
print(" x = %.3fG" % ( axes['x'] ))
print(" y = %.3fG" % ( axes['y'] ))
print(" z = %.3fG" % ( axes['z'] ))

View file

@ -0,0 +1,19 @@
# ADXL345 Python example
#
# author: Jonathan Williamson
# license: BSD, see LICENSE.txt included in this package
#
# This is an example to show you how to the Grove +-16g Accelerometer
# http://www.seeedstudio.com/depot/Grove-3Axis-Digital-Accelerometer16g-p-1156.html
from adxl345 import ADXL345
import time
adxl345 = ADXL345()
print("ADXL345 on address 0x%x:" % (adxl345.address))
while True:
axes = adxl345.getAxes(True)
print(( axes['x'] ),"\t",( axes['y'] ),"\t",( axes['z'] ))
time.sleep(.1)

View file

@ -0,0 +1,17 @@
# ADXL345 Python example
#
# author: Jonathan Williamson
# license: BSD, see LICENSE.txt included in this package
#
# This is an example to show you how to the Grove +-16g Accelerometer
# http://www.seeedstudio.com/depot/Grove-3Axis-Digital-Accelerometer16g-p-1156.html
from adxl345 import ADXL345
adxl345 = ADXL345()
axes = adxl345.getAxes(True)
print("ADXL345 on address 0x%x:" % (adxl345.address))
print(" x = %.3fG" % ( axes['x'] ))
print(" y = %.3fG" % ( axes['y'] ))
print(" z = %.3fG" % ( axes['z'] ))

View file

@ -0,0 +1,64 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove Air Quality Sensor (http://www.seeedstudio.com/wiki/Grove_-_Air_Quality_Sensor)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
# NOTE: # Wait 2 minutes for the sensor to heat-up
import time
import grovepi
# Connect the Grove Air Quality Sensor to analog port A0
# SIG,NC,VCC,GND
air_sensor = 0
grovepi.pinMode(air_sensor,"INPUT")
while True:
try:
# Get sensor value
sensor_value = grovepi.analogRead(air_sensor)
if sensor_value > 700:
print ("High pollution")
elif sensor_value > 300:
print ("Low pollution")
else:
print ("Air fresh")
print("sensor_value =", sensor_value)
time.sleep(.5)
except IOError:
print ("Error")

View file

@ -0,0 +1,50 @@
#!/usr/bin/env python
#
# GrovePi Example for using the analog read command to read analog sensor values
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
import grovepi
#Sensor connected to A0 Port
sensor = 14 # Pin 14 is A0 Port.
grovepi.pinMode(sensor,"INPUT")
while True:
try:
sensor_value = grovepi.analogRead(sensor)
print ("sensor_value = %d" %sensor_value)
time.sleep(.5)
except IOError:
print ("Error")

View file

@ -0,0 +1,42 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove Barometer module (http://www.seeedstudio.com/depot/Grove-Barometer-HighAccuracy-p-1865.html)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import grove_barometer_lib
b = grove_barometer_lib.barometer()
while True():
print ("Temp:",b.temperature," Pressure:",b.pressure," Altitude:",b.altitude)
b.update()
time.sleep(.1)

View file

@ -0,0 +1,93 @@
#!/usr/bin/env python
# #######################################################################
# This library is for using the Grove Barometer module with he GrovePi
# http://www.dexterindustries.com/GrovePi/
# Barometer module: http://www.seeedstudio.com/depot/Grove-Barometer-HighAccuracy-p-1865.html
#
# History
# ------------------------------------------------
# Author Date Comments
# Bill 26.07.2014 Initial Port to Python
# Guruth 29.08.2014 Clean up and put to usable libary
#
# Re-written from: https://github.com/Seeed-Studio/Grove_Barometer_HP20x
# Refer to the datasheet to add additional functionality http://www.seeedstudio.com/wiki/images/d/d8/HP206C_Datasheet.pdf
########################################################################
# Released under the MIT license (http://choosealicense.com/licenses/mit/).
# For more information see https://github.com/DexterInd/GrovePi/blob/master/LICENSE
import smbus
import time
import RPi.GPIO as GPIO
rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
bus = smbus.SMBus(1)
else:
bus = smbus.SMBus(0)
HP20X_I2C_DEV_ID = 0x76 # Barometer device address
HP20X_SOFT_RST = 0x06 # Soft reset the device
OK_HP20X_DEV = 0X80 # Default value for
HP20X_READ_PARA_REG = 0x8F # Read Register
HP20X_ADC_CVT = 0x48 # Digital filter rate and channel
HP20X_READ_P = 0x30 # Read Pressure
HP20X_READ_A = 0x31 # Read Altitude
HP20X_READ_T = 0x32 # Read Temperature
class barometer:
temperature = 0
pressure = 0
altitude = 0
def __init__(self):
# Send reset cmd to sensor
bus.write_byte(HP20X_I2C_DEV_ID, HP20X_SOFT_RST)
time.sleep(0.1)
# Check if reset was successful
if self.isAvailable():
self.update()
def isAvailable(self):
# Read register status register
bus.write_byte(HP20X_I2C_DEV_ID, HP20X_READ_PARA_REG)
# Retrieve the value from he bus
ret = bus.read_byte(HP20X_I2C_DEV_ID)
# Check if reset was successful
if ret == OK_HP20X_DEV:
return True
else:
return False
# Read sensor value
def readSensor(self, sensor):
# Set digital filter rate
bus.write_byte(HP20X_I2C_DEV_ID, HP20X_ADC_CVT)
time.sleep(.25)
# Send cmd to read from sensor X
# 0x30 || 0x31 || 0x32
bus.write_byte(HP20X_I2C_DEV_ID, sensor)
# Read data from bus
data = bus.read_i2c_block_data(HP20X_I2C_DEV_ID, 0)
value = data[0] << 16 | data[1] << 8 | data[2]
return value
# Update barometer values
def update(self):
# Read temp
self.temperature = self.readSensor(HP20X_READ_T)
time.sleep(0.2)
# Read pressure
self.pressure = self.readSensor(HP20X_READ_P)
time.sleep(0.2)
# Read altitude
self.altitude = self.readSensor(HP20X_READ_A)
time.sleep(0.2)

View file

@ -0,0 +1,18 @@
This is a Python 2.7 script wich can be used to get readings from the Grove Digital Barometic Sensor(BMP085) (http://www.seeedstudio.com/depot/Grove-Barometer-Sensor-p-1199.html) connected to the GrovePi on a Raspberry Pi.
The script Grove_Barometic_Sensor.py containes a class BMP085 (this is the actual sensor-chip on the device). All functions are inside this class and can be called from other scripts if you set the following code in the script:
from Grove_Barometic_Sensor import BMP085
If you set debug = True in the def__init__ function it displays all calculations on screen. If you set debug = False, the script just runs and sends the output to the calling script.
The script reads the raw temperature and raw pressure from the sensor. It then performs some calculations to transform the readed temperature to a calbrated temperature in °C and to perform a compenstion to the readed pressure to changed it to a calibrated value in Pascal. Finaly it calculates the altitude in meters above sea level using the barometric hight formula (sea http://en.wikipedia.org/wiki/Atmospheric_pressure). Standard it uses the sea level standard atmospheric pressure 101329 Pa. If you want to use a local sea level pressure, call the function readAltitude(123456) with the correct value between brackryd (make sure to give the value in Pascal (or multiply the value in hPa by 100)).
The script works in 4 modes (depending on how the initialisations is done in the calling script:
0 ULTRA LOW POWER Mode
1 Standard Mode
2 HIRES Mode
3 ULTRAHIRES Mode
If you need a value of the pressure in hPa, make sure to divide the returned value by 100 in the calling script.
September 2014.

View file

@ -0,0 +1,161 @@
#!/usr/bin/python
import re
import smbus
# ===========================================================================
# Adafruit_I2C Class
# ===========================================================================
class Adafruit_I2C(object):
@staticmethod
def getPiRevision():
"Gets the version number of the Raspberry Pi board"
# Revision list available at: http://elinux.org/RPi_HardwareHistory#Board_Revision_History
try:
with open('/proc/cpuinfo', 'r') as infile:
for line in infile:
# Match a line of the form "Revision : 0002" while ignoring extra
# info in front of the revsion (like 1000 when the Pi was over-volted).
match = re.match('Revision\s+:\s+.*(\w{4})$', line)
if match and match.group(1) in ['0000', '0002', '0003']:
# Return revision 1 if revision ends with 0000, 0002 or 0003.
return 1
elif match:
# Assume revision 2 if revision ends with any other 4 chars.
return 2
# Couldn't find the revision, assume revision 0 like older code for compatibility.
return 0
except:
return 0
@staticmethod
def getPiI2CBusNumber():
# Gets the I2C bus number /dev/i2c#
return 1 if Adafruit_I2C.getPiRevision() > 1 else 0
def __init__(self, address, busnum=-1, debug=False):
self.address = address
# By default, the correct I2C bus is auto-detected using /proc/cpuinfo
# Alternatively, you can hard-code the bus version below:
# self.bus = smbus.SMBus(0); # Force I2C0 (early 256MB Pi's)
# self.bus = smbus.SMBus(1); # Force I2C1 (512MB Pi's)
self.bus = smbus.SMBus(busnum if busnum >= 0 else Adafruit_I2C.getPiI2CBusNumber())
self.debug = debug
def reverseByteOrder(self, data):
"Reverses the byte order of an int (16-bit) or long (32-bit) value"
# Courtesy Vishal Sapre
byteCount = len(hex(data)[2:].replace('L','')[::2])
val = 0
for i in range(byteCount):
val = (val << 8) | (data & 0xff)
data >>= 8
return val
def errMsg(self):
print("Error accessing 0x%02X: Check your I2C address" % self.address)
return -1
def write8(self, reg, value):
"Writes an 8-bit value to the specified register/address"
try:
self.bus.write_byte_data(self.address, reg, value)
if self.debug:
print("I2C: Wrote 0x%02X to register 0x%02X" % (value, reg))
except IOError as err:
return self.errMsg()
def write16(self, reg, value):
"Writes a 16-bit value to the specified register/address pair"
try:
self.bus.write_word_data(self.address, reg, value)
if self.debug:
print ("I2C: Wrote 0x%02X to register pair 0x%02X,0x%02X" %
(value, reg, reg+1))
except IOError as err:
return self.errMsg()
def writeRaw8(self, value):
"Writes an 8-bit value on the bus"
try:
self.bus.write_byte(self.address, value)
if self.debug:
print("I2C: Wrote 0x%02X" % value)
except IOError as err:
return self.errMsg()
def writeList(self, reg, list):
"Writes an array of bytes using I2C format"
try:
if self.debug:
print("I2C: Writing list to register 0x%02X:" % reg)
print(list)
self.bus.write_i2c_block_data(self.address, reg, list)
except IOError as err:
return self.errMsg()
def readList(self, reg, length):
"Read a list of bytes from the I2C device"
try:
results = self.bus.read_i2c_block_data(self.address, reg, length)
if self.debug:
print ("I2C: Device 0x%02X returned the following from reg 0x%02X" %
(self.address, reg))
print(results)
return results
except IOError as err:
return self.errMsg()
def readU8(self, reg):
"Read an unsigned byte from the I2C device"
try:
result = self.bus.read_byte_data(self.address, reg)
if self.debug:
print("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
(self.address, result & 0xFF, reg))
return result
except IOError as err:
return self.errMsg()
def readS8(self, reg):
"Reads a signed byte from the I2C device"
try:
result = self.bus.read_byte_data(self.address, reg)
if result > 127: result -= 256
if self.debug:
print("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
(self.address, result & 0xFF, reg))
return result
except IOError as err:
return self.errMsg()
def readU16(self, reg, little_endian=True):
"Reads an unsigned 16-bit value from the I2C device"
try:
result = self.bus.read_word_data(self.address,reg)
# Swap bytes if using big endian because read_word_data assumes little
# endian on ARM (little endian) systems.
if not little_endian:
result = ((result << 8) & 0xFF00) + (result >> 8)
if (self.debug):
print("I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg))
return result
except IOError as err:
return self.errMsg()
def readS16(self, reg, little_endian=True):
"Reads a signed 16-bit value from the I2C device"
try:
result = self.readU16(reg,little_endian)
if result > 32767: result -= 65536
return result
except IOError as err:
return self.errMsg()
if __name__ == '__main__':
try:
bus = Adafruit_I2C(address=0)
print("Default I2C bus is accessible")
except:
print("Error accessing default I2C bus")

View file

@ -0,0 +1,288 @@
#!/usr/bin/python
# Copyright 2014 Johan Vandewalle. All rights reserved.
#
# Redistributian and use in source and binary forms, with or without
# modification, are permitted provide that the following conditions are
# met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import time
from Adafruit_I2C import Adafruit_I2C
import math
# ===========================================================================
# BMP085 Class
# ===========================================================================
class BMP085 :
i2c = None
# Operating Modes
__BMP085_ULTRALOWPOWER = 0
__BMP085_STANDARD = 1
__BMP085_HIGHRES = 2
__BMP085_ULTRAHIGHRES = 3
# BMP085 Registers
__BMP085_CAL_AC1 = 0xAA # R Calibration data (16 bits)
__BMP085_CAL_AC2 = 0xAC # R Calibration data (16 bits)
__BMP085_CAL_AC3 = 0xAE # R Calibration data (16 bits)
__BMP085_CAL_AC4 = 0xB0 # R Calibration data (16 bits)
__BMP085_CAL_AC5 = 0xB2 # R Calibration data (16 bits)
__BMP085_CAL_AC6 = 0xB4 # R Calibration data (16 bits)
__BMP085_CAL_B1 = 0xB6 # R Calibration data (16 bits)
__BMP085_CAL_B2 = 0xB8 # R Calibration data (16 bits)
__BMP085_CAL_MB = 0xBA # R Calibration data (16 bits)
__BMP085_CAL_MC = 0xBC # R Calibration data (16 bits)
__BMP085_CAL_MD = 0xBE # R Calibration data (16 bits)
__BMP085_CONTROL = 0xF4
__BMP085_TEMPDATA = 0xF6
__BMP085_PRESSUREDATA = 0xF6
__BMP085_READTEMPCMD = 0x2E
__BMP085_READPRESSURECMD = 0x34
# Private Fields
_cal_AC1 = 0
_cal_AC2 = 0
_cal_AC3 = 0
_cal_AC4 = 0
_cal_AC5 = 0
_cal_AC6 = 0
_cal_B1 = 0
_cal_B2 = 0
_cal_MB = 0
_cal_MC = 0
_cal_MD = 0
# Constructor
def __init__(self, address=0x77, mode=1, debug=False):
self.i2c = Adafruit_I2C(address)
self.address = address
self.debug = debug
# Make sure the specified mode is in the appropriate range
if ((mode < 0) | (mode > 3)):
if (self.debug):
print("Invalid Mode: Using STANDARD by default")
self.mode = self.__BMP085_STANDARD
else:
self.mode = mode
# Read the calibration data
self.readCalibrationData()
def readS16(self, register):
"Reads a signed 16-bit value"
hi = self.i2c.readS8(register)
lo = self.i2c.readU8(register+1)
return (hi << 8) + lo
def readU16(self, register):
"Reads an unsigned 16-bit value"
hi = self.i2c.readU8(register)
lo = self.i2c.readU8(register+1)
return (hi << 8) + lo
def readCalibrationData(self):
"Reads the calibration data from the IC"
self._cal_AC1 = self.readS16(self.__BMP085_CAL_AC1) # INT16
self._cal_AC2 = self.readS16(self.__BMP085_CAL_AC2) # INT16
self._cal_AC3 = self.readS16(self.__BMP085_CAL_AC3) # INT16
self._cal_AC4 = self.readU16(self.__BMP085_CAL_AC4) # UINT16
self._cal_AC5 = self.readU16(self.__BMP085_CAL_AC5) # UINT16
self._cal_AC6 = self.readU16(self.__BMP085_CAL_AC6) # UINT16
self._cal_B1 = self.readS16(self.__BMP085_CAL_B1) # INT16
self._cal_B2 = self.readS16(self.__BMP085_CAL_B2) # INT16
self._cal_MB = self.readS16(self.__BMP085_CAL_MB) # INT16
self._cal_MC = self.readS16(self.__BMP085_CAL_MC) # INT16
self._cal_MD = self.readS16(self.__BMP085_CAL_MD) # INT16
if (self.debug):
self.showCalibrationData()
def showCalibrationData(self):
"Displays the calibration values for debugging purposes"
print("DBG: AC1 = %6d" % (self._cal_AC1))
print("DBG: AC2 = %6d" % (self._cal_AC2))
print("DBG: AC3 = %6d" % (self._cal_AC3))
print("DBG: AC4 = %6d" % (self._cal_AC4))
print("DBG: AC5 = %6d" % (self._cal_AC5))
print("DBG: AC6 = %6d" % (self._cal_AC6))
print("DBG: B1 = %6d" % (self._cal_B1))
print("DBG: B2 = %6d" % (self._cal_B2))
print("DBG: MB = %6d" % (self._cal_MB))
print("DBG: MC = %6d" % (self._cal_MC))
print("DBG: MD = %6d" % (self._cal_MD))
def readRawTemp(self):
"Reads the raw (uncompensated) temperature from the sensor"
self.i2c.write8(self.__BMP085_CONTROL, self.__BMP085_READTEMPCMD)
time.sleep(0.005) # Wait 5ms
raw = self.readU16(self.__BMP085_TEMPDATA)
if (self.debug):
print("DBG: Raw Temp: 0x%04X (%d)" % (raw & 0xFFFF, raw))
return raw
def readRawPressure(self):
"Reads the raw (uncompensated) pressure level from the sensor"
self.i2c.write8(self.__BMP085_CONTROL, self.__BMP085_READPRESSURECMD + (self.mode << 6))
if (self.mode == self.__BMP085_ULTRALOWPOWER):
time.sleep(0.005)
elif (self.mode == self.__BMP085_HIGHRES):
time.sleep(0.014)
elif (self.mode == self.__BMP085_ULTRAHIGHRES):
time.sleep(0.026)
else:
time.sleep(0.008)
msb = self.i2c.readU8(self.__BMP085_PRESSUREDATA)
lsb = self.i2c.readU8(self.__BMP085_PRESSUREDATA+1)
xlsb = self.i2c.readU8(self.__BMP085_PRESSUREDATA+2)
raw = ((msb << 16) + (lsb << 8) + xlsb) >> (8 - self.mode)
if (self.debug):
print("DBG: Raw Pressure: 0x%04X (%d)" % (raw & 0xFFFF, raw))
return raw
def readTemperature(self):
"Gets the compensated temperature in degrees celcius"
UT = 0
X1 = 0
X2 = 0
B5 = 0
temp = 0.0
# Read raw temp before aligning it with the calibration values
UT = self.readRawTemp()
X1 = ((UT - self._cal_AC6) * self._cal_AC5) >> 15
X2 = (self._cal_MC << 11) / (X1 + self._cal_MD)
B5 = X1 + X2
temp = (int(B5 + 8) >> 4) / 10.0
if (self.debug):
print("DBG: Calibrated temperature = %f C" % temp)
return temp
def readPressure(self):
"Gets the compensated pressure in pascal"
UT = 0
UP = 0
B3 = 0
B5 = 0
B6 = 0
X1 = 0
X2 = 0
X3 = 0
p = 0
B4 = 0
B7 = 0
UT = self.readRawTemp()
UP = self.readRawPressure()
# You can use the datasheet values to test the conversion results
# dsValues = True
dsValues = False
if (dsValues):
UT = 27898
UP = 23843
self._cal_AC6 = 23153
self._cal_AC5 = 32757
self._cal_MB = -32768;
self._cal_MC = -8711
self._cal_MD = 2868
self._cal_B1 = 6190
self._cal_B2 = 4
self._cal_AC3 = -14383
self._cal_AC2 = -72
self._cal_AC1 = 408
self._cal_AC4 = 32741
self.mode = self.__BMP085_ULTRALOWPOWER
if (self.debug):
self.showCalibrationData()
# True Temperature Calculations
X1 = ((UT - self._cal_AC6) * self._cal_AC5) >> 15
X2 = (self._cal_MC << 11) / (X1 + self._cal_MD)
B5 = X1 + X2
if (self.debug):
print("DBG: X1 = %d" % (X1))
print("DBG: X2 = %d" % (X2))
print("DBG: B5 = %d" % (B5))
print("DBG: True Temperature = %.2f C" % (((B5 + 8) >> 4) / 10.0))
# Pressure Calculations
B6 = B5 - 4000
X1 = (int(self._cal_B2) * int(B6 * B6) >> 12) >> 11
X2 = int(self._cal_AC2 * B6) >> 11
X3 = X1 + X2
B3 = (((self._cal_AC1 * 4 + X3) << self.mode) + 2) / 4
if (self.debug):
print("DBG: B6 = %d" % (B6))
print("DBG: X1 = %d" % (X1))
print("DBG: X2 = %d" % (X2))
print("DBG: X3 = %d" % (X3))
print("DBG: B3 = %d" % (B3))
X1 = int(self._cal_AC3 * B6) >> 13
X2 = (int(self._cal_B1) * (int(B6 * B6) >> 12)) >> 16
X3 = ((X1 + X2) + 2) >> 2
B4 = (self._cal_AC4 * (X3 + 32768)) >> 15
B7 = (UP - B3) * (50000 >> self.mode)
if (self.debug):
print("DBG: X1 = %d" % (X1))
print("DBG: X2 = %d" % (X2))
print("DBG: X3 = %d" % (X3))
print("DBG: B4 = %d" % (B4))
print("DBG: B7 = %d" % (B7))
if (B7 < 0x80000000):
p = (B7 * 2) / B4
else:
p = (B7 / B4) * 2
if (self.debug):
print("DBG: X1 = %d" % (X1))
X1 = (int(p) >> 8) * (int(p) >> 8)
X1 = (X1 * 3038) >> 16
X2 = (-7357 * int(p)) >> 16
if (self.debug):
print("DBG: p = %d" % (p))
print("DBG: X1 = %d" % (X1))
print("DBG: X2 = %d" % (X2))
p = p + ((X1 + X2 + 3791) >> 4)
if (self.debug):
print("DBG: Pressure = %d Pa" % (p))
return p
def readAltitude(self, seaLevelPressure=101325):
"Calculates the altitude in meters"
altitude = 0.0
pressure = float(self.readPressure())
temperature = float(self.readTemperature())
# altitude = 44330.0 * (1.0 - pow(pressure / seaLevelPressure, 0.1903))
altitude = round( -math.log( pressure / seaLevelPressure ) * 8314 * ( temperature + 273.15 ) / ( 25 * 9.81 ) , 2 )
# this isn't completely correct. The formula uses the temperature of the sensor while it should be using the temperature
# at sea level. At lower altitudes and close (less then 200 km) from the shore, the difference is neglectable. If you want
# to use the script at higher locations or deeper inland, comment this line and uncomment the line above.
if (self.debug):
print("DBG: Altitude = %.2f m" % (altitude))
return altitude
return 0

View file

@ -0,0 +1,44 @@
#!/usr/bin/python
import smbus
import RPi.GPIO as GPIO
#import grovepi
from grove_i2c_barometic_sensor_BMP180 import BMP085
# ===========================================================================
# Example Code
# ===========================================================================
# Initialise the BMP085 and use STANDARD mode (default value)
# bmp = BMP085(0x77, debug=True)
bmp = BMP085(0x77, 1)
# To specify a different operating mode, uncomment one of the following:
# bmp = BMP085(0x77, 0) # ULTRALOWPOWER Mode
# bmp = BMP085(0x77, 1) # STANDARD Mode
# bmp = BMP085(0x77, 2) # HIRES Mode
# bmp = BMP085(0x77, 3) # ULTRAHIRES Mode
rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
bus = smbus.SMBus(1)
else:
bus = smbus.SMBus(0)
temp = bmp.readTemperature()
# Read the current barometric pressure level
pressure = bmp.readPressure()
# To calculate altitude based on an estimated mean sea level pressure
# (1013.25 hPa) call the function as follows, but this won't be very accurate
# altitude = bmp.readAltitude()
# To specify a more accurate altitude, enter the correct mean sea level
# pressure level. For example, if the current pressure level is 1023.50 hPa
# enter 102350 since we include two decimal places in the integer value
altitude = bmp.readAltitude(101560)
print("Temperature: %.2f C" % temp)
print("Pressure: %.2f hPa" % (pressure / 100.0))
print("Altitude: %.2f m" % altitude)

View file

@ -0,0 +1,3 @@
These python scripts work on both major versions of it (2.x and 3.x).
These scripts are used for getting readings from the [Grove - Barometer Sensor(BMP180)](http://www.seeedstudio.com/depot/Grove-Barometer-SensorBMP180-p-1840.html) which has to be connected to the GrovePi's I2C port.

View file

@ -0,0 +1,73 @@
#!/usr/bin/env python
#
# Kalman filter Library for using the Grove - Barometer (High-Accuracy)(http://www.seeedstudio.com/depot/Grove-Barometer-HighAccuracy-p-1865.html
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this library? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
# This library is derived from the Arduino library written by Oliver Wang for SeeedStudio (https://github.com/Seeed-Studio/Grove_Barometer_HP20x/tree/master/HP20x_dev)
from random import randint
Rand_Table=[
0.5377,1.8339,-2.2588,0.8622,0.3188,-1.3077,-0.4336,0.342,3.5784,
2.7694,-1.3499,3.0349,0.7254,-0.0631,0.7147,-0.2050,-0.1241,1.4897,
1.4090,1.4172,0.6715,-1.2075,0.7172,1.6302,0.4889,1.0347,0.7269,
-0.3034,0.2939,-0.7873,0.8884,-1.1471,-1.0689,-0.8095,-2.9443,1.4384,
0.3252,-0.7549,1.3703,-1.7115,-0.1022,-0.2414,0.3192,0.3129,-0.8649,
-0.0301,-0.1649,0.6277,1.0933,1.1093,-0.8637,0.0774,-1.2141,-1.1135,
-0.0068,1.5326,-0.7697,0.3714,-0.2256,1.1174,-1.0891,0.0326,0.5525,
1.1006,1.5442,0.0859,-1.4916,-0.7423,-1.0616,2.3505,-0.6156,0.7481,
-0.1924,0.8886,-0.7648,-1.4023,-1.4224,0.4882,-0.1774,-0.1961,1.4193,
0.2916,0.1978,1.5877,-0.8045,0.6966,0.8351,-0.2437,0.2157,-1.1658,
-1.1480,0.1049,0.7223,2.5855,-0.6669,0.1873,-0.0825,-1.9330,-0.439,
-1.7947]
class KalmanFilter:
X_pre=0
X_post=0
P_pre=0
P_post=0
K_cur=0
def __init__(self):
self.X_pre=0
def Gaussian_Noise_Cov(self):
index = 0
tmp=[0.0]*10
average = 0.0
sum = 0.0
#Get random number */
for i in range(10):
index = randint(0,90)
tmp[i] = Rand_Table[index]
sum += tmp[i];
# Calculate average
average = sum/10
#Calculate Variance
Variance = 0.0
for j in range(10):
Variance += (tmp[j]-average)*(tmp[j]-average)
Variance/=10.0
return Variance
def Filter(self,origin):
modelNoise = 0.0
observeNoise = 0.0
# Get model and observe Noise
modelNoise = self.Gaussian_Noise_Cov()
observeNoise = self.Gaussian_Noise_Cov()
# Algorithm
self.X_pre = self.X_post
self.P_pre = self.P_post + modelNoise;
self.K_cur = self.P_pre/(self.P_pre + observeNoise);
self.P_post = (1 - self.K_cur)*self.P_pre;
self.X_post = self.X_pre + self.K_cur*(origin - self.X_pre);
return self.X_post

View file

@ -0,0 +1,48 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove - Barometer (High-Accuracy)(http://www.seeedstudio.com/depot/Grove-Barometer-HighAccuracy-p-1865.html
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this library? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
# This library is derived from the Arduino library written by Oliver Wang for SeeedStudio (https://github.com/Seeed-Studio/Grove_Barometer_HP20x/tree/master/HP20x_dev)
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import hp206c
h= hp206c.hp206c()
ret=h.isAvailable()
if h.OK_HP20X_DEV == ret:
print("HP20x_dev is available.")
else:
print("HP20x_dev isn't available.")
temp=h.ReadTemperature()
pressure=h.ReadPressure()
altitude=h.ReadAltitude()
print("Temperature\t: %.2f C\nPressure\t: %.2f hPa\nAltitude\t: %.2f m" %(temp,pressure,altitude))

View file

@ -0,0 +1,136 @@
#!/usr/bin/env python
#
# GrovePi Library for using the Grove - Barometer (High-Accuracy)(http://www.seeedstudio.com/depot/Grove-Barometer-HighAccuracy-p-1865.html
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this library? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
# This library is derived from the Arduino library written by Oliver Wang for SeeedStudio (https://github.com/Seeed-Studio/Grove_Barometer_HP20x/tree/master/HP20x_dev)
# Released under the MIT license (http://choosealicense.com/licenses/mit/).
# For more information see https://github.com/DexterInd/GrovePi/blob/master/LICENSE
import time,sys
import RPi.GPIO as GPIO
import smbus
# use the bus that matches your raspi version
rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
bus = smbus.SMBus(1)
else:
bus = smbus.SMBus(0)
class hp206c:
address = None
HP20X_I2C_DEV_ID =(0xEC)>>1 #CSB PIN is VDD level(address is 0x76)
HP20X_I2C_DEV_ID2 =(0XEE)>>1 #CSB PIN is GND level(address is 0x77)
HP20X_SOFT_RST =0x06
HP20X_WR_CONVERT_CMD =0x40
HP20X_CONVERT_OSR4096 =0<<2
HP20X_CONVERT_OSR2048 =1<<2
HP20X_CONVERT_OSR1024 =2<<2
HP20X_CONVERT_OSR512 =3<<2
HP20X_CONVERT_OSR256 =4<<2
HP20X_CONVERT_OSR128 =5<<2
HP20X_READ_P =0x30 #read_p command
HP20X_READ_A =0x31 #read_a command
HP20X_READ_T =0x32 #read_t command
HP20X_READ_PT =0x10 #read_pt command
HP20X_READ_AT =0x11 #read_at command
HP20X_READ_CAL =0X28 #RE-CAL ANALOG
HP20X_WR_REG_MODE =0xC0
HP20X_RD_REG_MODE =0x80
ERR_WR_DEVID_NACK =0x01
ERR_RD_DEVID_NACK =0x02
ERR_WR_REGADD_NACK =0x04
ERR_WR_REGCMD_NACK =0x08
ERR_WR_DATA_NACK =0x10
ERR_RD_DATA_MISMATCH =0x20
I2C_DID_WR_MASK =0xFE
I2C_DID_RD_MASK =0x01
T_WIN_EN =0X01
PA_WIN_EN =0X02
T_TRAV_EN =0X04
PA_TRAV_EN =0X08
PA_RDY_EN =0X20
T_RDY_EN =0X10
T_WIN_CFG =0X01
PA_WIN_CFG =0X02
PA_MODE_P =0X00
PA_MODE_A =0X40
T_TRAV_CFG =0X04
OK_HP20X_DEV =0X80 #HP20x_dev successfully initialized
REG_PARA =0X0F #Status register
OSR_CFG = HP20X_CONVERT_OSR1024
OSR_ConvertTime = 25
def __init__(self,address=0x76):
self.address=address
self.HP20X_IIC_WriteCmd(self.HP20X_SOFT_RST)
time.sleep(.1)
def isAvailable(self):
return self.HP20X_IIC_ReadReg(self.REG_PARA)
def ReadTemperature(self):
self.HP20X_IIC_WriteCmd(self.HP20X_WR_CONVERT_CMD|self.OSR_CFG)
time.sleep(self.OSR_ConvertTime/1000.0)
t_raw = bus.read_i2c_block_data(self.address, self.HP20X_READ_T, 3)
t=t_raw[0]<<16|t_raw[1]<<8|t_raw[2]
if t&0x800000:
t|=0xff000000;
us = (1<<32)
t = -1 * (us - t)
return t/100.0
def ReadPressure(self):
self.HP20X_IIC_WriteCmd(self.HP20X_WR_CONVERT_CMD|self.OSR_CFG)
time.sleep(self.OSR_ConvertTime/1000.0)
p_raw = bus.read_i2c_block_data(self.address, self.HP20X_READ_P, 3)
p=p_raw[0]<<16|p_raw[1]<<8|p_raw[2]
if p&0x800000:
p|=0xff000000;
return p/100.0
def ReadAltitude(self):
self.HP20X_IIC_WriteCmd(self.HP20X_WR_CONVERT_CMD|self.OSR_CFG)
time.sleep(self.OSR_ConvertTime/1000.0)
a_raw = bus.read_i2c_block_data(self.address, self.HP20X_READ_A, 3)
a=a_raw[0]<<16|a_raw[1]<<8|a_raw[2]
if a&0x800000:
a|=0xff000000;
us = (1<<32)
a = -1 * (us - a)
return a/100.0
def HP20X_IIC_WriteCmd(self,uCmd):
bus.write_byte(self.address, uCmd)
def HP20X_IIC_ReadReg(self, bReg):
# self.HP20X_IIC_WriteCmd(bReg|self.HP20X_RD_REG_MODE)
return bus.read_byte_data(self.address, bReg|self.HP20X_RD_REG_MODE)
if __name__ == "__main__":
h= hp206c()
ret=h.isAvailable()
if h.OK_HP20X_DEV == ret:
print("HP20x_dev is available.")
else:
print("HP20x_dev isn't available.")
temp=h.ReadTemperature()
pressure=h.ReadPressure()
altitude=h.ReadAltitude()
print(temp,pressure,altitude)

View file

@ -0,0 +1,50 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove Button (http://www.seeedstudio.com/wiki/Grove_-_Button)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
import grovepi
# Connect the Grove Button to digital port D3
# SIG,NC,VCC,GND
button = 3
grovepi.pinMode(button,"INPUT")
while True:
try:
print(grovepi.digitalRead(button))
time.sleep(.5)
except IOError:
print ("Error")

View file

@ -0,0 +1,61 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove Buzzer (http://www.seeedstudio.com/wiki/Grove_-_Buzzer)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
import grovepi
# Connect the Grove Buzzer to digital port D8
# SIG,NC,VCC,GND
buzzer = 8
grovepi.pinMode(buzzer,"OUTPUT")
while True:
try:
# Buzz for 1 second
grovepi.digitalWrite(buzzer,1)
print ('start')
time.sleep(1)
# Stop buzzing for 1 second and repeat
grovepi.digitalWrite(buzzer,0)
print ('stop')
time.sleep(1)
except KeyboardInterrupt:
grovepi.digitalWrite(buzzer,0)
break
except IOError:
print ("Error")

View file

@ -0,0 +1,135 @@
#!/usr/bin/env python
#
# GrovePi Library for using the Grove Chainable RGB LED (http://www.seeedstudio.com/wiki/Grove_-_Chainable_RGB_LED)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
# Derived from the C library for the P9813 LED's by DaochenShi here: https://github.com/DC-Shi/PN532SPI-P9813GPIO
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2015 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
# Note: Connect the chainable LED to port RPISER on the GrovePi
import time,sys
import RPi.GPIO as GPIO
import smbus
class rgb_led:
r_all=[]
g_all=[]
b_all=[]
def __init__(self,led=1):
GPIO.setwarnings(False)
self.num_led=led
self.r_all=[0] * self.num_led
self.g_all=[0] * self.num_led
self.b_all=[0] * self.num_led
GPIO.setmode(GPIO.BCM)
self.clk_pin= 15 #RX pin BCM
self.data_pin= 14 # TX pin BCM
self.tv_nsec= 100
GPIO.setup(self.clk_pin, GPIO.OUT)
GPIO.setup(self.data_pin, GPIO.OUT)
def sendByte(self,b):
# print b
for loop in range(8):
# digitalWrite(CLKPIN, LOW);
GPIO.output(self.clk_pin,0)
time.sleep(self.tv_nsec/1000000.0)
# nanosleep(&TIMCLOCKINTERVAL, NULL);
# The ic will latch a bit of data when the rising edge of the clock coming, And the data should changed after the falling edge of the clock;
# Copyed from P9813 datasheet
if (b & 0x80) != 0:
# digitalWrite(DATPIN, HIGH)
GPIO.output(self.data_pin,1)
else:
# digitalWrite(DATPIN, LOW):
GPIO.output(self.data_pin,0)
# digitalWrite(CLKPIN, HIGH);
GPIO.output(self.clk_pin,1)
# nanosleep(&TIMCLOCKINTERVAL, NULL);
time.sleep(self.tv_nsec/1000000.0)
# //usleep(CLOCKINTERVAL);
b <<= 1
def sendColor(self,r, g, b):
prefix = 0b11000000;
if (b & 0x80) == 0:
prefix |= 0b00100000
if (b & 0x40) == 0:
prefix |= 0b00010000
if (g & 0x80) == 0:
prefix |= 0b00001000
if (g & 0x40) == 0:
prefix |= 0b00000100
if (r & 0x80) == 0:
prefix |= 0b00000010
if (r & 0x40) == 0:
prefix |= 0b00000001
self.sendByte(prefix)
self.sendByte(b)
self.sendByte(g)
self.sendByte(r)
def setColorRGB(self,r,g,b):
for i in range(4):
self.sendByte(0)
self.sendColor(r, g, b);
for i in range(4):
self.sendByte(0)
def setColorRGBs(self,r,g,b,count):
for i in range(4):
self.sendByte(0)
for i in range(count):
self.sendColor(r[i], g[i], b[i])
for i in range(4):
self.sendByte(0)
def setOneLED(self,r,g,b,led_num):
self.r_all[led_num]=r
self.g_all[led_num]=g
self.b_all[led_num]=b
self.setColorRGBs(self.r_all,self.g_all,self.b_all,self.num_led)
if __name__ == "__main__":
num_led=3
l= rgb_led(num_led)
l.setColorRGB(255,0,0)
r=[0,0,255]
g=[0,255,0]
b=[255,0,0]
l.setColorRGBs(r,g,b,num_led)

View file

@ -0,0 +1,83 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove Chainable RGB LED (http://www.seeedstudio.com/wiki/Grove_-_Chainable_RGB_LED)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
# Derived from the C library for the P9813 LED's by DaochenShi here: https://github.com/DC-Shi/PN532SPI-P9813GPIO
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2015 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
# Note: Connect the chainable LED to port RPISER on the GrovePi
import chainable_rgb_direct
num_led=3
l= chainable_rgb_direct.rgb_led(num_led)
###########################
#Set Color on the first LED
#l.setColorRGB(255,0,0)
###########################
#Set color on LED chain
#RGB array needs to be sent
#r[0],g[0],b[0] specifies the color for led[0]
#r[1],g[1],b[1] specifies the color for led[1]
#r[2],g[2],b[1] specifies the color for led[2]
#Make the array length as the number of LED's
# r=[0,0,255]
# g=[0,255,0]
# b=[255,0,0]
# l.setColorRGBs(r,g,b,num_led)
###########################
#Turn off all LED's
# r=[0,0,0]
# g=[0,0,0]
# b=[0,0,0]
# l.setColorRGBs(r,g,b,num_led)
###########################
# #Show a pattern with 3 LED's
# while 1:
# for i in range(0,255,5):
# r[0]=i
# g[0]=255-i
# b[0]=0
# r[1]=0
# g[1]=i
# b[1]=255-i
# r[2]=255-i
# g[2]=0
# b[2]=i
# l.setColorRGBs(r,g,b,num_led)
###########################
# Control one LED at at time
l.setOneLED(127,127,0,0) #Set LED 0
l.setOneLED(0,127,127,1) #Set LED 1
l.setOneLED(0,0,0,0) #Clear LED 0

View file

@ -0,0 +1,32 @@
# compiler:
CC = gcc
## args: especially libs
CFLAGS = -O3 -Wunused
LIBS = -lwiringPi
OUTPUT = NFCLight
all: NFCLight
debug: CC += -DDEBUG
debug: NFCLight
NFCLightusable: main.o P9813GPIO.o PN532SPIusable.o
$(CC) $(CFLAGS) -DDEBUG -DPN532DEBUG $(LIBS) -o $@ $^
NFCLight: main.o P9813GPIO.o PN532SPI.o
$(CC) $(CFLAGS) $(LIBS) -o $@ $^
main.o: main.c PN532SPI.h
PN532SPI.o: PN532SPI.c PN532SPI.h
P9813GPIO.0: P9813GPIO.c P9813GPIO.h
clean:
rm -rf *.o NFCLight

View file

@ -0,0 +1,328 @@
/*
Bitbanged the GPIO to simulate SPI interface.
Used CLKPIN and DATPIN.
LED1,2,3 gives the indicator of different light levels.
Since P9813 and PN532 are using SPI, but P9813 is without ChipSelect wire, so any data on MOSI would be accepted by P9813, that leads to blinking light sometimes.
But this simulation is also unstable when raspberry pi under high load.
Reference here: http://www.seeedstudio.com/wiki/File:P9813_datasheet.pdf
Verified for 1 LED, and this should be compatible with multiple LEDs. It is said that 1024 LEDs is allowed.
This project is created by @DaochenShi (shidaochen@live.com)
*/
#include <stdio.h> // printf,etc.
#include <stdlib.h> // exit
#include <signal.h> // for Ctrl+C
//#include <unistd.h> // usleep
#include <time.h> // nanosleep
#include <math.h> // abs
#include <errno.h> // errno
#include "P9813GPIO.h"
static struct timespec TIMCLOCKINTERVAL;
// Send a byte bit by bit using digitalWrite
void sendByte(unsigned char b)
{
char loop = 8;
#ifndef DRYRUN
for(loop = 0; loop < 8; loop++)
{
digitalWrite(CLKPIN, LOW);
nanosleep(&TIMCLOCKINTERVAL, NULL);
//usleep(CLOCKINTERVAL);
// The ic will latch a bit of data when the rising edge of the clock coming, And the data should changed after the falling edge of the clock;
// Copyed from P9813 datasheet
if ((b & 0x80) != 0)
digitalWrite(DATPIN, HIGH);
else
digitalWrite(DATPIN, LOW);
digitalWrite(CLKPIN, HIGH);
nanosleep(&TIMCLOCKINTERVAL, NULL);
//usleep(CLOCKINTERVAL);
b <<= 1;
}
#endif
}
// Send a color(RGB) information to LED.
void sendColor(unsigned char r, unsigned char g, unsigned char b)
{
unsigned char prefix = 0b11000000;
if ((b & 0x80) == 0) prefix |= 0b00100000;
if ((b & 0x40) == 0) prefix |= 0b00010000;
if ((g & 0x80) == 0) prefix |= 0b00001000;
if ((g & 0x40) == 0) prefix |= 0b00000100;
if ((r & 0x80) == 0) prefix |= 0b00000010;
if ((r & 0x40) == 0) prefix |= 0b00000001;
sendByte(prefix);
sendByte(b);sendByte(g);sendByte(r);
}
#ifdef GPIO_PURE_LED
#ifdef GPIO_PURE_LED1
static unsigned char LED1value = 0;
#endif
#ifdef GPIO_PURE_LED2
static unsigned char LED2value = 0;
#endif
#ifdef GPIO_PURE_LED3
static unsigned char LED3value = 0;
#endif
#endif
static unsigned char previousR = 0;
static unsigned char previousG = 0;
static unsigned char previousB = 0;
static unsigned char unchangedTimes = 0;
// Set the color, used stored previous RGB information to avoid writing the same thing repeatedly.
// This is 'buffered'. If the color is the same as previous color, we might ignore it.
// Also, this function handled GPIO pure LEDs, so remove GPIO_PURE_LED to get access only to P9813.
// Advantage: Fewer GPIO write leads to less CPU costs.
// Disadvantage: Your request may not be applied, apply once every 2^8 times.
void setColorRGBbuffered(unsigned char r, unsigned char g, unsigned char b)
{
unsigned char max = 0;
max = (max > r) ? max : r;
max = (max > g) ? max : g;
max = (max > b) ? max : b;
#ifdef GPIO_PURE_LED
#ifdef GPIO_PURE_LED1
if (LED1value != (max > 0x40))
{
digitalWrite(GPIO_PURE_LED1, (max > 0x40));
LED1value = (max > 0x40);
}
else
{
unchangedTimes++;
#ifdef P9813DEBUG
printf("Unchanged this time, %d\n", unchangedTimes);
#endif
}
#endif
#ifdef GPIO_PURE_LED1
if (LED2value != (max > 0x80))
{
digitalWrite(GPIO_PURE_LED2, (max > 0x80));
LED2value = (max > 0x80);
}
else
{
unchangedTimes++;
#ifdef P9813DEBUG
printf("Unchanged this time, %d\n", unchangedTimes);
#endif
}
#endif
#ifdef GPIO_PURE_LED3
if (LED3value != (max > 0xC0))
{
digitalWrite(GPIO_PURE_LED3, (max > 0xC0));
LED3value = (max > 0xC0);
}
else
{
unchangedTimes++;
#ifdef P9813DEBUG
printf("Unchanged this time, %d\n", unchangedTimes);
#endif
}
#endif
#endif
if ( (previousR != r) || (previousG != g) || (previousB != b) || (!unchangedTimes))
{
sendByte(0);sendByte(0);sendByte(0);sendByte(0);
sendColor(r, g, b);
sendByte(0);sendByte(0);sendByte(0);sendByte(0);
previousR = r;
previousG = g;
previousB = b;
}
else
{
unchangedTimes++;
#ifdef P9813DEBUG
printf("Unchanged this time, %d\n", unchangedTimes);
#endif
}
}
// Set the color to LED, or the first LED.
// This is not 'buffered', every time you invoke this method, it would send the signals directly to the bus.
// Advantage: What you see is what you want.
// Disadvantage: If you invoke this all the time, and write the same color, it costs a lot of CPU.
void setColorRGB(unsigned char r, unsigned char g, unsigned char b)
{
sendByte(0);sendByte(0);sendByte(0);sendByte(0);
sendColor(r, g, b);
sendByte(0);sendByte(0);sendByte(0);sendByte(0);
previousR = r;
previousG = g;
previousB = b;
}
// Set the color with multiple LEDs.
// Not tested yet.
void setColorRGBs(unsigned char* r, unsigned char* g, unsigned char* b, int count)
{
int i = 0;
sendByte(0);sendByte(0);sendByte(0);sendByte(0);
for ( i = 0; i < count; i++ )
{
printf("led %d color = %d,%d,%d\n",i,r[i], g[i], b[i]);
sendColor(r[i], g[i], b[i]);
}
sendByte(0);sendByte(0);sendByte(0);sendByte(0);
}
// Initializing
// I noted this because occasionally the light was brought up, and cannot be set.
// Because I rebooted the Pi, and forgot to set to OUTPUT direction.
void initialP9813GPIO()
{
int result = wiringPiSetup();
if (result < 0)
{
printf("wiringPi setup failed, are you root?\n");
exit(1);
}
TIMCLOCKINTERVAL.tv_sec = 0;
TIMCLOCKINTERVAL.tv_nsec = 20000L;
pinMode(CLKPIN, OUTPUT);
pinMode(DATPIN, OUTPUT);
setColorRGB(0, 0, 0);
#ifdef GPIO_PURE_LED
// use wiringPi pinout
#ifdef GPIO_PURE_LED1
pinMode(GPIO_PURE_LED1, OUTPUT);
digitalWrite(GPIO_PURE_LED1, 0);
printf("Set up wiringPi GPIO%d\n", GPIO_PURE_LED1);
#endif
#ifdef GPIO_PURE_LED2
pinMode(GPIO_PURE_LED2, OUTPUT);
digitalWrite(GPIO_PURE_LED2, 0);
printf("Set up wiringPi GPIO%d\n", GPIO_PURE_LED2);
#endif
#ifdef GPIO_PURE_LED3
pinMode(GPIO_PURE_LED3, OUTPUT);
digitalWrite(GPIO_PURE_LED3, 0);
printf("Set up wiringPi GPIO%d\n", GPIO_PURE_LED3);
#endif
#endif
}
////////////////////////////////////
// These functions below are for testing alone. You can test this file only when changing 'LEDmain' to 'main'
////////////////////////////////////
/// Question: I do NOT want these functions to be called outside this file, how to do it?
#ifdef SINGLE_FILE_DEBUG
static int loop = 1;
void CtrlCBreak(int sig)
{
signal(sig, SIG_IGN);
loop = 0;
signal(sig, SIG_DFL);
}
int LEDmain(int argc, const char* argv[])
{
int result = 0;
int nextColor;
unsigned char nextR, nextG, nextB, colorR, colorG, colorB, maxDiff;
result = wiringPiSetup();
signal(SIGINT,CtrlCBreak);
if (result < 0)
{
printf("wiringPi setup failed, are you root?\n");
exit(1);
}
pinMode(CLKPIN, OUTPUT);
pinMode(DATPIN, OUTPUT);
setColorRGBbuffered(0, 0, 0);
sleep(1);
//sendColor(255, 0, 0);
setColorRGBbuffered(255, 0, 0);
sleep(1);
//sendColor(0, 255, 0);
setColorRGBbuffered(0, 255, 0);
sleep(1);
//sendColor(0, 0, 255);
setColorRGBbuffered(0, 0, 255);
sleep(1);
while(loop)
{
if ((colorR == nextR) && (colorG == nextG) && (colorB == nextB))
{
nextColor = rand() & 0x00FFFFFF;
nextR = (nextColor & 0x00FF0000) >> 16;
nextG = (nextColor & 0x0000FF00) >> 8;
nextB = (nextColor & 0x000000FF);
//printf("nextColor is %dR, %dG, %dB\n", nextR, nextG, nextB);
}
else
{
// colorR = (color & 0x00FF0000) >> 16;
// colorG = (color & 0x0000FF00) >> 8;
// colorB = (color & 0x000000FF);
maxDiff = 0;
maxDiff = (maxDiff > abs(colorR - nextR)) ? maxDiff : abs(colorR - nextR);
maxDiff = (maxDiff > abs(colorG - nextG)) ? maxDiff : abs(colorG - nextG);
maxDiff = (maxDiff > abs(colorB - nextB)) ? maxDiff : abs(colorB - nextB);
if (maxDiff == 0)
{
printf("Bug comes out,,,,,\n");
break;
}
colorR = colorR - (colorR - nextR) / maxDiff;
colorR = colorR & 0xFF;
colorG = colorG - (colorG - nextG) / maxDiff;
colorG = colorG & 0xFF;
colorB = colorB - (colorB - nextB) / maxDiff;
colorB = colorB & 0xFF;
}
setColorRGBbuffered(colorR, colorG, colorB);
usleep(15000);
}
printf("End.\n");
setColorRGBbuffered(0, 0, 0);
return 0;
}
#endif

View file

@ -0,0 +1,64 @@
/*
Bitbanged the GPIO to simulate SPI interface.
Used CLKPIN and DATPIN.
LED1,2,3 gives the indicator of different light levels.
Since P9813 and PN532 are using SPI, but P9813 is without ChipSelect wire, so any data on MOSI would be accepted by P9813, that leads to blinking light sometimes.
But this simulation is also unstable when raspberry pi under high load.
Reference here: http://www.seeedstudio.com/wiki/File:P9813_datasheet.pdf
Verified for 1 LED, and this should be compatible with multiple LEDs. It is said that 1024 LEDs is allowed.
This project is created by @DaochenShi (shidaochen@live.com)
*/
#include <wiringPi.h> // GPIO handling
// use wiringPi pinout
#define CLKPIN 16
#define DATPIN 15
// 20 microseconds to sleep
#define CLOCKINTERVAL 20
// This is to let other LEDs (pure light) controlled by GPIO(on/off)
// Comment out the line would control P9813 only.
//#define GPIO_PURE_LED
#ifdef GPIO_PURE_LED
// use wiringPi pinout
#define GPIO_PURE_LED1 0
#define GPIO_PURE_LED2 2
#define GPIO_PURE_LED3 3
#endif
// Send a byte bit by bit using digitalWrite
void sendByte(unsigned char b);
// Send a color(RGB) information to LED.
void sendColor(unsigned char r, unsigned char g, unsigned char b);
// Set the color, used stored previous RGB information to avoid writing the same thing repeatedly.
// This is 'buffered'. If the color is the same as previous color, we might ignore it.
// Advantage: Fewer GPIO write leads to less CPU costs.
// Disadvantage: Your request may not be applied, apply once every 2^8 times.
void setColorRGBbuffered(unsigned char r, unsigned char g, unsigned char b);
// Set the color to LED, or the first LED.
// This is not 'buffered', every time you invoke this method, it would send the signals directly to the bus.
// Advantage: What you see is what you want.
// Disadvantage: If you invoke this all the time, and write the same color, it costs a lot of CPU.
void setColorRGB(unsigned char r, unsigned char g, unsigned char b);
// Set the color with multiple LEDs.
// Not tested yet.
void setColorRGBs(unsigned char* r, unsigned char* g, unsigned char* b, int count);
// Initializing
// I noted this because occasionally the light was brought up, and cannot be set.
// Because I rebooted the Pi, and forgot to set to OUTPUT direction.
void initialP9813GPIO();

View file

@ -0,0 +1,537 @@
/*
The original files can be found in http://blog.iteadstudio.com/to-drive-itead-pn532-nfc-module-with-raspberry-pi/
All the contents are based on that article. I made some modification to the file, removed P2P communication, simplified some codes.
This files(include the header file and source file) are modified by @DaochenShi (shidaochen@live.com)
*/
#include "PN532SPI.h"
//#define PN532DEBUG
byte pn532ack[] = {0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00};
byte pn532response_firmwarevers[] = {0x00, 0xFF, 0x06, 0xFA, 0xD5, 0x03};
#define PN532_PACK_BUFF_SIZE 64
#define SPISPEED 1000000
byte pn532_packetbuffer[PN532_PACK_BUFF_SIZE];
/*Construct PN532 object and construct PN532's own SPI interface object */
int i,j;
unsigned char a=0xaa;
void initialPN532SPI()
{
j = wiringPiSetup();
wiringPiSPISetup(channel, SPISPEED);
#ifdef PN532DEBUG
printf("wiringPiSetup is %d\n",j);
#endif
#ifdef CHIPSELECT
pinMode(_chipSelect, OUTPUT);
digitalWrite(_chipSelect, HIGH);
digitalWrite(_chipSelect, LOW);
#endif
sleep(1);
pn532_packetbuffer[0] = PN532_FIRMWAREVERSION;
sendCommandCheckAck(pn532_packetbuffer, 1, 1000);
#ifdef CHIPSELECT
//digitalWrite(_chipSelect, HIGH); // to prevent wrong select.
#endif
}
uint32_t getFirmwareVersion(void)
{
uint32_t response;
pn532_packetbuffer[0] = PN532_FIRMWAREVERSION;
if (!sendCommandCheckAck(pn532_packetbuffer, 1, 1000))
return 0;
//nfcPN532Read data packet
nfcPN532Read(pn532_packetbuffer, 12);
//Check response headers.
if (0 != strncmp((char *)pn532_packetbuffer, (char *)pn532response_firmwarevers, 6))
{
#ifdef PN532DEBUG
for (response = 0; response < 12; response++)
{
printf("%X ", pn532response_firmwarevers[response]);
}
printf("\n");
#endif
return 0;
}
response = pn532_packetbuffer[6];
response <<= 8;
response |= pn532_packetbuffer[7];
response <<= 8;
response |= pn532_packetbuffer[8];
response <<= 8;
response |= pn532_packetbuffer[9];
return response;
}
/**********************************************************************/
/*Function: Send command to PN532 with SPI and check the ACK. */
/*Parameter:-uint8_t* cmd,The pointer that saves the command code to be sent;*/
/* -uint8_t cmd_len,The number of bytes of the command; */
/* -uint16_t timeout,default timeout is one second */
/*Return: boolean,ture = send command successfully */
boolean sendCommandCheckAck(uint8_t* cmd, uint8_t cmd_len, uint16_t timeout)
{
uint16_t timer = 0;
// nfcPN532Write the command
writeCommand(cmd, cmd_len);
// Wait for chip to say it's ready!
while (readSpiStatus() != PN532_SPI_READY)
{
if (timeout != 0)
{
timer+=20;
if (timer > timeout)
{
#ifdef PN532DEBUG
printf("timeout\n");
#endif
return false;
}
}
usleep(20 * 1000);
}
// nfcPN532Read acknowledgement
if (!checkSpiAck())
{
#ifdef PN532DEBUG
printf("spi no answer\n");
#endif
return false;
}
timer = 0;
#ifdef PN532DEBUG
printf("check spi finsh\n");
#endif
// Wait for chip to say its ready!
while (readSpiStatus() != PN532_SPI_READY)
{
if (timeout != 0)
{
timer+=20;
if (timer > timeout)
#ifdef PN532DEBUG
printf("nfcPN532Read spi timeout\n");
#endif
return false;
}
usleep(20 * 1000);
}
#ifdef PN532DEBUG
printf("the spi return ture\n");
#endif
return true; // ack'd command
}
boolean SAMConfig(void)
{
pn532_packetbuffer[0] = PN532_SAMCONFIGURATION;
pn532_packetbuffer[1] = 0x01; // normal mode;
pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second
pn532_packetbuffer[3] = 0x01; // use IRQ pin! What's that?
if (! sendCommandCheckAck(pn532_packetbuffer, 4,1000))
return false;
// nfcPN532Read data packet
nfcPN532Read(pn532_packetbuffer, 8);
return (pn532_packetbuffer[5] == 0x15);
}
uint32_t authenticateBlock(uint8_t cardnumber /*1 or 2*/,uint32_t cid /*Card NUID*/, uint8_t blockaddress /*0 to 63*/,uint8_t authtype/*Either KEY_A or KEY_B */, uint8_t * keys)
{
pn532_packetbuffer[0] = PN532_INDATAEXCHANGE;
pn532_packetbuffer[1] = cardnumber; // either card 1 or 2 (tested for card 1)
if(authtype == KEY_A)
{
pn532_packetbuffer[2] = PN532_AUTH_WITH_KEYA;
}
else
{
pn532_packetbuffer[2] = PN532_AUTH_WITH_KEYB;
}
pn532_packetbuffer[3] = blockaddress; //This address can be 0-63 for MIFARE 1K card
pn532_packetbuffer[4] = keys[0];
pn532_packetbuffer[5] = keys[1];
pn532_packetbuffer[6] = keys[2];
pn532_packetbuffer[7] = keys[3];
pn532_packetbuffer[8] = keys[4];
pn532_packetbuffer[9] = keys[5];
pn532_packetbuffer[10] = ((cid >> 24) & 0xFF);
pn532_packetbuffer[11] = ((cid >> 16) & 0xFF);
pn532_packetbuffer[12] = ((cid >> 8) & 0xFF);
pn532_packetbuffer[13] = ((cid >> 0) & 0xFF);
if (! sendCommandCheckAck(pn532_packetbuffer, 14,1000))
return false;
// nfcPN532Read data packet
nfcPN532Read(pn532_packetbuffer, 2+6);
#ifdef PN532DEBUG
int iter = 0;
for(iter=0;iter<14;iter++)
{
printf("%X ",(pn532_packetbuffer[iter]));
}
printf("\n");
// check some basic stuff
printf("AUTH");
for(i=0;i<2+6;i++)
{
printf("%d\n",(pn532_packetbuffer[i]));
printf(" ");
}
#endif
if((pn532_packetbuffer[6] == 0x41) && (pn532_packetbuffer[7] == 0x00))
{
return true;
}
else
{
return false;
}
}
/****************************************************************************/
/*Function: nfcPN532Read a block(16 bytes) from the tag and stores in the parameter.*/
/*Parameter:-uint8_t cardnumber,can be 1 or 2; */
/* -blockaddress,range from 0 to 63; */
/* -uint8_t* block,will save 16bytes that nfcPN532Read from tag. */
/*Return: boolean */
boolean readMemoryBlock(uint8_t cardnumber,uint8_t blockaddress,uint8_t * block)
{
uint8_t i;
pn532_packetbuffer[0] = PN532_INDATAEXCHANGE;
pn532_packetbuffer[1] = cardnumber; // either card 1 or 2 (tested for card 1)
pn532_packetbuffer[2] = PN532_MIFARE_READ;
pn532_packetbuffer[3] = blockaddress; //This address can be 0-63 for MIFARE 1K card
if (! sendCommandCheckAck(pn532_packetbuffer, 4,1000))
return false;
nfcPN532Read(pn532_packetbuffer, 64);
#ifdef PN532DEBUG
for( i = 0; i < 64; i++)
{
printf("%x ", pn532_packetbuffer[i]);
if(i%8==7)
printf("\r\n");
}
#endif
// nfcPN532Read data packet
nfcPN532Read(pn532_packetbuffer, 18+6);
// check some basic stuff
#ifdef PN532DEBUG
printf("nfcPN532Read");
#endif
for(i=8;i<18+6;i++)
{
block[i-8] = pn532_packetbuffer[i];
#ifdef PN532DEBUG
printf("%d\n",(pn532_packetbuffer[i]));
#endif
}
if((pn532_packetbuffer[6] == 0x41) && (pn532_packetbuffer[7] == 0x00))
{
return true; //nfcPN532Read successful
}
else
{
return false;
}
}
/****************************************************************************/
/*Function: nfcPN532Write a block(16 bytes) to the tag. */
/*Parameter:-uint8_t cardnumber,can be 1 or 2; */
/* -blockaddress,range from 0 to 63; */
/* -uint8_t* block,saves 16bytes that will nfcPN532Write to the tag. */
/*Return: boolean */
/*Note:Donot nfcPN532Write to Sector Trailer Block unless you know what you are doing.*/
boolean writeMemoryBlock(uint8_t cardnumber,uint8_t blockaddress,uint8_t * block)
{
uint8_t bytes;
pn532_packetbuffer[0] = PN532_INDATAEXCHANGE;
pn532_packetbuffer[1] = cardnumber; // either card 1 or 2 (tested for card 1)
pn532_packetbuffer[2] = PN532_MIFARE_WRITE;
pn532_packetbuffer[3] = blockaddress;
for(bytes = 0; bytes < 16; bytes++)
{
pn532_packetbuffer[4+bytes] = block[bytes];
}
if (! sendCommandCheckAck(pn532_packetbuffer, 20,1000))
return false;
// nfcPN532Read data packet
nfcPN532Read(pn532_packetbuffer, 2+6);
#ifdef PN532DEBUG
// check some basic stuff
printf("nfcPN532Write");
for(i=0;i<2+6;i++)
{
printf("%d\n",(pn532_packetbuffer[i]));
}
printf("\n");
#endif
if((pn532_packetbuffer[6] == 0x41) && (pn532_packetbuffer[7] == 0x00))
{
return true; //nfcPN532Write successful
}
else
{
return false;
}
}
uint32_t readPassiveTargetID(uint8_t cardbaudrate)
{
uint32_t cid;
uint16_t sens_res;
uint8_t i;
pn532_packetbuffer[0] = PN532_INLISTPASSIVETARGET;
pn532_packetbuffer[1] = 1; // max 1 cards at once (we can set this to 2 later)
pn532_packetbuffer[2] = cardbaudrate;
if (! sendCommandCheckAck(pn532_packetbuffer, 3,1000))
return 0x0; // no cards nfcPN532Read
// nfcPN532Read data packet
nfcPN532Read(pn532_packetbuffer, 20);// why 20?! buffer total is 64!
// check some basic stuff
#ifdef PN532DEBUG
printf("Found ");
printf("%d",(pn532_packetbuffer[7]));
printf(" tags\n");
#endif
if (pn532_packetbuffer[7] != 1)
return 0;
sens_res = pn532_packetbuffer[9];
sens_res <<= 8;
sens_res |= pn532_packetbuffer[10];
#ifdef PN532DEBUG
printf("Sens Response: ");
printf("%d\n",(sens_res));
printf("Sel Response: ");
printf("%d",(pn532_packetbuffer[11]));
printf("\n");
#endif
cid = 0;
for (i=0; i< pn532_packetbuffer[12]; i++)
{
cid <<= 8;
cid |= pn532_packetbuffer[13+i];
#ifdef PN532DEBUG
printf(" 0x");
printf("%X\n",(pn532_packetbuffer[13+i]));
#endif
}
#ifdef PN532DEBUG
printf("TargetID");
for(i=0;i<20;i++)
{
printf("%d\n",(pn532_packetbuffer[i]));
}
printf("\n");
#endif
return cid;
}
/**********************************************************************/
/*Function: nfcPN532Read n bytes data and it stores in the parameter . */
/*Parameter:-uint8_t* buff,saves the data nfcPN532Read from PN532; */
/* -uint8_t n,tells it wll nfcPN532Read n bytes. */
/*Return: void */
void nfcPN532Read(uint8_t* buff, uint8_t n)
{
uint8_t i;
#ifdef CHIPSELECT
digitalWrite(_chipSelect, LOW);
#endif
usleep(2000);
nfcPN532Write(PN532_SPI_DATAREAD);
#ifdef PN532DEBUG
printf("Reading:\n");
#endif
for (i=0; i < n; i ++)
{
usleep(1000);
buff[i] = readF();
#ifdef PN532DEBUG
printf("debug readf is %d\n",buff[i]);
#endif
}
#ifdef CHIPSELECT
digitalWrite(_chipSelect, HIGH);
#endif
}
void writeCommand(uint8_t* cmd, uint8_t cmd_len)
{
uint8_t checksum;
uint8_t cmdlen_1;
uint8_t i;
uint8_t checksum_1;
cmd_len++;
#ifdef PN532DEBUG
printf("Sending: \n");
#endif
#ifdef CHIPSELECT
digitalWrite(_chipSelect, LOW);
#endif
usleep(2000); // or whatever the delay is for waking up the board
nfcPN532Write(PN532_SPI_DATAWRITE); //0x01
checksum = PN532_PREAMBLE + PN532_PREAMBLE + PN532_STARTCODE2;
nfcPN532Write(PN532_PREAMBLE); //0x00
nfcPN532Write(PN532_PREAMBLE); //0x00
nfcPN532Write(PN532_STARTCODE2); //0xff
nfcPN532Write(cmd_len); //0x02
cmdlen_1 = ~cmd_len + 1;
nfcPN532Write(cmdlen_1); //0x01
nfcPN532Write(PN532_HOSTTOPN532); //0xd4
checksum += PN532_HOSTTOPN532;
#ifdef PN532DEBUG
printf("preamble is %X\n",(PN532_PREAMBLE));
printf("startcode2 is %X\n",(PN532_STARTCODE2));
printf("cmd_len is %X\n",(cmd_len));
printf("cmdlen_1 is %X\n",(cmdlen_1));
printf("hosttopn532 is %X\n",(PN532_HOSTTOPN532));
#endif
for (i=0; i<cmd_len-1; i++)
{
nfcPN532Write(cmd[i]);
checksum += cmd[i];
#ifdef PN532DEBUG
printf("cmd[i] is %X\n",(cmd[i]));
#endif
}
checksum_1 = ~checksum;
nfcPN532Write(checksum_1);
nfcPN532Write(PN532_POSTAMBLE);
#ifdef CHIPSELECT
digitalWrite(_chipSelect, HIGH);
#endif
#ifdef PN532DEBUG
printf("checksum is %d\n", (checksum_1));
printf("postamble is %d\n", (PN532_POSTAMBLE));
printf("postamble is %d\n", (PN532_POSTAMBLE));
#endif
}
/************** high level SPI */
boolean checkSpiAck()
{
uint8_t ackbuff[6];
nfcPN532Read(ackbuff, 6);
return (0 == strncmp((char *)ackbuff, (char *)pn532ack, 6));
}
/************** mid level SPI */
uint8_t readSpiStatus(void)
{
uint8_t status;
#ifdef CHIPSELECT
digitalWrite(_chipSelect, LOW);
#endif
usleep(2000);
nfcPN532Write(PN532_SPI_STATREAD);
status = readF();
#ifdef CHIPSELECT
digitalWrite(_chipSelect, HIGH);
#endif
return status;
}
/************** low level SPI ********/
/*Function:Transmit a byte to PN532 through the SPI interface. */
void nfcPN532Write(uint8_t _data)
{
unsigned char writeData = 0, p;
for(p=0;p<8;p++)
{
if(_data & 0x01)
writeData |= 1<<(7-p);
_data = _data>>1;
}
wiringPiSPIDataRW(channel, &writeData, 1);
}
/*Function:Receive a byte from PN532 through the SPI interface */
uint8_t readF(void)
{
unsigned char readData,redata = 0,p;
wiringPiSPIDataRW(channel, &readData, 1);
for(p=0;p<8;p++)
{
if(readData & 0x01)
{
redata |= 1<<(7-p);
}
readData = readData >> 1;
}
return redata;
}

View file

@ -0,0 +1,99 @@
/*
The original files can be found in http://blog.iteadstudio.com/to-drive-itead-pn532-nfc-module-with-raspberry-pi/
All the contents are based on that article. I made some modification to the file, removed P2P communication, simplified some codes.
This files(include the header file and source file) are modified by @DaochenShi (shidaochen@live.com)
*/
#ifndef __PN532_H__
#define __PN532_H__
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <wiringPi.h>
#include <wiringPiSPI.h>
#define PN532_PREAMBLE 0x00
#define PN532_STARTCODE1 0x00
#define PN532_STARTCODE2 0xFF
#define PN532_POSTAMBLE 0x00
#define PN532_HOSTTOPN532 0xD4
#define PN532_FIRMWAREVERSION 0x02
#define PN532_GETGENERALSTATUS 0x04
#define PN532_SAMCONFIGURATION 0x14
#define PN532_INLISTPASSIVETARGET 0x4A
#define PN532_INDATAEXCHANGE 0x40
#define PN532_INJUMPFORDEP 0x56
#define PN532_TGINITASTARGET 0x8C
#define PN532_TGGETDATA 0x86
#define PN532_TGSETDATA 0x8E
#define PN532_MIFARE_READ 0x30
#define PN532_MIFARE_WRITE 0xA0
#define PN532_AUTH_WITH_KEYA 0x60
#define PN532_AUTH_WITH_KEYB 0x61
#define PN532_WAKEUP 0x55
#define PN532_SPI_STATREAD 0x02
#define PN532_SPI_DATAWRITE 0x01
#define PN532_SPI_DATAREAD 0x03
#define PN532_SPI_READY 0x01
#define PN532_MIFARE_ISO14443A 0x0
#define KEY_A 1
#define KEY_B 2
#define PN532_BAUDRATE_201K 1
#define PN532_BAUDRATE_424K 2
#define boolean int
#define channel 1
#define byte unsigned char
#define false 0
#define true 1
#define CHIPSELECT
// This is which pin you used for ChipSelect. SPI slave accept the instrctions when its CS pulled to ground.
#ifdef CHIPSELECT
#define _chipSelect 11
#endif
void initialPN532SPI(void);
boolean SAMConfig(void);
uint32_t getFirmwareVersion(void);
uint32_t readPassiveTargetID(uint8_t cardbaudrate);
uint32_t authenticateBlock(
uint8_t cardnumber /*1 or 2*/,
uint32_t cid /*Card NUID*/,
uint8_t blockaddress /*0 to 63*/,
uint8_t authtype /*Either KEY_A or KEY_B */,
uint8_t* keys);
boolean readMemoryBlock(uint8_t cardnumber /*1 or 2*/,uint8_t blockaddress /*0 to 63*/, uint8_t * block);
//boolean writeMemoryBlock(uint8_t cardnumber /*1 or 2*/,uint8_t blockaddress /*0 to 63*/, uint8_t * block);
//uint32_t configurePeerAsInitiator(uint8_t baudrate /* Any number from 0-2. 0 for 106kbps or 1 for 201kbps or 2 for 424kbps */); //106kps is not supported
//uint32_t configurePeerAsTarget();
//boolean initiatorTxRx(char* dataOut,char* dataIn);
//uint32_t targetTxRx(char* dataOut,char* dataIn);
boolean sendCommandCheckAck(uint8_t *cmd, uint8_t cmdlen, uint16_t timeout);
void nfcPN532Write(uint8_t _data);
uint8_t readF(void);
uint8_t readSpiStatus(void);
boolean checkSpiAck();
void nfcPN532Read(uint8_t* buff, uint8_t n);
void writeCommand(uint8_t* cmd, uint8_t cmdlen);
#endif

View file

@ -0,0 +1,32 @@
This one is to read RFID card by PN532 through SPI, respond to LED lights(P9813) and a beeper
Input: PN532(SPI)
Output: P9813, GPIO 1 port
NFC module: http://www.seeedstudio.com/wiki/NFC_Shield_V2.0
LED light: http://www.seeedstudio.com/wiki/Grove_-_Chainable_RGB_LED
beeper: http://item.taobao.com/item.htm?spm=0.0.0.0.A0Zkth&id=6859691900
Outline:
Repeatedly read from NFC, use cardID to identify, // currently I don't know how to read the blocks.
if it matches some fixed number, it shows green light and beepGPIO;
otherwise, it shows red and beepGPIO another sound.
You need the wiringPi lib.
Compile:
make
Run:
sudo ./NFClight
Thanks the following persons developed the libs which this project used.
wiringPi lib from: Gordons Projects @ https://projects.drogon.net/raspberry-pi/wiringpi/
nfc lib from: Katherine @ http://blog.iteadstudio.com/to-drive-itead-pn532-nfc-module-with-raspberry-pi/
This project is created by @DaochenShi (shidaochen@live.com)

View file

@ -0,0 +1,303 @@
/*
This one is to read RFID card by PN532 through SPI, respond to LED lights(P9813) and a beeper
Input: PN532(SPI)
Output: P9813, GPIO 1 port
NFC module: http://www.seeedstudio.com/wiki/NFC_Shield_V2.0
LED light: http://www.seeedstudio.com/wiki/Grove_-_Chainable_RGB_LED
beeper: http://item.taobao.com/item.htm?spm=0.0.0.0.A0Zkth&id=6859691900
Outline:
Repeatedly read from NFC, use cardID to identify, // currently I don't know how to read the blocks.
if it matches some fixed number, it shows white light and beepGPIO;
if it matches another number, the program exits.
otherwise, it gradually dim the light.
You need the wiringPi lib.
Compile:
make
Run:
sudo ./NFClight
Thanks the following persons developed the libs which this project used.
wiringPi lib from: Gordons Projects @ https://projects.drogon.net/raspberry-pi/wiringpi/
nfc lib from: Katherine @ http://blog.iteadstudio.com/to-drive-itead-pn532-nfc-module-with-raspberry-pi/
This project is created by @DaochenShi (shidaochen@live.com)
20140322 maintaince:
LED init and control should be done by P9813GPIO, so any LED init related are removed from this file. Go check P9813GPIO.c
*/
#include "PN532SPI.h"
#include <stdio.h>
#include <unistd.h> // for usleep
#include <signal.h> // for SIG_IGN etc.
#include <fcntl.h> // for O_WRONLY
#include <errno.h> // for errno
#include <time.h> // for clock()
#include <pthread.h> // for multithreading
//#define DEBUG_COLOR
//#define BEEPER_GPIO_PIN 6
int initialWiringPi();
void break_program(int sig);
void* adjust_color();
//#define MAXWAITINGTIME 10
static int loopingStatus = 0;
static unsigned char colorBase[3];
static unsigned char colorTarget[3];
//gcc main.c -lwiringPi P9813GPIO.h P9813GPIO.c
void rgbcycle(void)
{
int i=0;
while (1)
{
i++;
if (i>255)
i=0;
setColorRGBbuffered(0,0,1);
printf("color = %d\n",i);
usleep(20 * 1000);
}
}
int main(int argc, const char* argv[])
{
unsigned char r[]={255,0,0};
unsigned char g[]={0,255,0};
unsigned char b[]={0,0,255};
int i;
// NFC related, the read card ID. Currently I can only read this. I don't know how to get other infos.
// uint32_t cardID;
// int allowFailureTimes = 2;
// // run this program in background when not in Debug mode
// #ifndef DEBUG
// {
// pid_t pid, sid;
// pid = fork();
// if (pid < 0)
// {
// exit(EXIT_FAILURE);
// }
// if (pid > 0)
// {
// exit(EXIT_SUCCESS);
// }
// // change file mode mask
// umask(0);
// // open logs,,, but I did not record any logs
// // create SID for child process
// sid = setsid();
// if (sid < 0)
// {
// exit(EXIT_FAILURE);
// }
// close(STDIN_FILENO);
// close(STDOUT_FILENO);
// //close(STDERR_FILENO);
// }
// #endif
initialWiringPi();
// pthread_t _colorThread;
// loopingStatus = 1;
// pthread_create(&_colorThread, NULL, adjust_color, NULL);
// adjust_color();
printf("All initialized...\n");
// adjust_color();
// setColorRGB(0, 0, 0);
// rgbcycle();
setColorRGBs(&r[0],&g[0],&b[0],3);
for ( i = 0; i < 3; i++ )
{
printf("led %d color = %d,%d,%d\n",i,r[i], g[i], b[i]);
}
// while(loopingStatus)
// {
// #ifdef DEBUG
// printf("waiting for card read...\n");
// #endif
// cardID = readPassiveTargetID(PN532_MIFARE_ISO14443A);
// if ( cardID == 0 && allowFailureTimes > 0)
// {
// allowFailureTimes--;
// continue;
// }
// if ( cardID != 0 )
// {
// allowFailureTimes = 2;
// if ((cardID % 256) == authCID)
// {
// colorBase[0] = 0xFF; colorBase[1] = 0xFF; colorBase[2] = 0xFF;
// colorTarget[0] = 0xFF; colorTarget[1] = 0xFF; colorTarget[2] = 0xFF;
// setColorRGBbuffered(colorBase[0], colorBase[1], colorBase[2]);
// }
// else
// {
// if ((cardID % 256) == exitCID)
// {
// loopingStatus = 0;
// break;
// }
// colorTarget[0] = (cardID >> 16) % 256;
// colorTarget[1] = (cardID >> 8) % 256;
// colorTarget[2] = cardID % 256;
// #ifdef DEBUG
// printf("cardID = %X\n", cardID);
// #endif
// }
// }
// else
// {
// // allowFailureTimes < 0 and cardID == 0, which means no card.
// #ifdef DEBUG
// printf("no card\n");
// #endif
// colorTarget[0] = 0; colorTarget[1] = 0; colorTarget[2] = 0;
// }
// sleep(1);
// }
// colorTarget[0] = 0; colorTarget[1] = 0; colorTarget[2] = 0;
// colorBase[0] = 2; colorBase[1] = 3; colorBase[2] = 6;
// setColorRGB(10, 7, 6);
// #ifdef BEEPER_GPIO_PIN
// digitalWrite(BEEPER_GPIO_PIN, 1);
// usleep(100 * 1000);
// digitalWrite(BEEPER_GPIO_PIN, 0);
// #endif
// sleep(1);
// setColorRGB(0, 0, 0);
// pthread_join(_colorThread, NULL);
// return 0;
}
// Set-up some necessary wiringPi and devices.
int initialWiringPi()
{
#ifdef DEBUG
printf("Initializing.\n");
#endif
// uint32_t nfcVersion;
// First to setup wiringPi
if (wiringPiSetup() < 0)
{
fprintf(stderr, "Unable to setup wiringPi: %s \n", strerror(errno));
exit(1);
}
#ifdef DEBUG
printf("Set wiringPi.\n");
#endif
// Initializing LEDs
initialP9813GPIO();
// Hook crtl+c event
signal(SIGINT, break_program);
#ifdef DEBUG
printf("Hooked Ctrl+C.\n");
#endif
// #ifdef BEEPER_GPIO_PIN
// pinMode(BEEPER_GPIO_PIN, OUTPUT);
// digitalWrite(BEEPER_GPIO_PIN, 1);
// usleep(100 * 1000);
// digitalWrite(BEEPER_GPIO_PIN, 0);
// #endif
// // Use init function from nfc.c
// // why you use such a simple function name?!
// initialPN532SPI();
// #ifdef DEBUG
// printf("NFC initialized begin().\n");
// #endif
// nfcVersion = getFirmwareVersion();
// if (!nfcVersion)
// {
// fprintf(stderr, "Cannot find PN53x board after getFirmwareVersion.\n");
// exit(1);
// }
// SAMConfig();
#ifdef DEBUG
printf("Initialized.\n");
#endif
return 0;
}
// Accept Ctrl+C command, this seems not work when main process is forked.
void break_program(int sig)
{
signal(sig, SIG_IGN);
loopingStatus = 0;
printf("Program end.\n");
signal(sig, SIG_DFL);
}
// static clock_t previousTimeClock;
// Adjust the P9813 color by another thread.
void* adjust_color(void)
{
// LED related
int colorMaxDiff;
while (1){
/// Parse current color, and gradually fade-in/fade-out
printf("Changing color...loop = %d\n", loopingStatus);
colorMaxDiff = 0;
colorMaxDiff = (colorMaxDiff > abs(colorBase[0] - colorTarget[0])) ? colorMaxDiff : abs(colorBase[0] - colorTarget[0]);
colorMaxDiff = (colorMaxDiff > abs(colorBase[1] - colorTarget[1])) ? colorMaxDiff : abs(colorBase[1] - colorTarget[1]);
colorMaxDiff = (colorMaxDiff > abs(colorBase[2] - colorTarget[2])) ? colorMaxDiff : abs(colorBase[2] - colorTarget[2]);
colorMaxDiff = (colorMaxDiff > 15) ? colorMaxDiff/16 : colorMaxDiff;
if (colorMaxDiff)
{
{
colorBase[0] = colorBase[0] - (colorBase[0] - colorTarget[0]) / colorMaxDiff;
colorBase[1] = colorBase[1] - (colorBase[1] - colorTarget[1]) / colorMaxDiff;
colorBase[2] = colorBase[2] - (colorBase[2] - colorTarget[2]) / colorMaxDiff;
setColorRGBbuffered(colorBase[0], colorBase[1], colorBase[2]);
}
// printf("interval of previous %d\n", (clock() - previousTimeClock));
// previousTimeClock = clock();
printf("colorMaxDiff = %d, %dR->%dR, %dG->%dG, %dB->%dB\n",
colorMaxDiff,
colorBase[0], colorTarget[0],
colorBase[1], colorTarget[1],
colorBase[2], colorTarget[2]);
}
usleep(20 * 1000);
}
}

View file

@ -0,0 +1,174 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove Chainable RGB LED (http://www.seeedstudio.com/wiki/Grove_-_Chainable_RGB_LED)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://www.dexterindustries.com/forum/?forum=grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
import grovepi
# Connect first LED in Chainable RGB LED chain to digital port D7
# In: CI,DI,VCC,GND
# Out: CO,DO,VCC,GND
pin = 7
# I have 10 LEDs connected in series with the first connected to the GrovePi and the last not connected
# First LED input socket connected to GrovePi, output socket connected to second LED input and so on
numleds = 4 #If you only plug 1 LED, change 10 to 1
grovepi.pinMode(pin,"OUTPUT")
time.sleep(1)
# Chainable RGB LED methods
# grovepi.storeColor(red, green, blue)
# grovepi.chainableRgbLed_init(pin, numLeds)
# grovepi.chainableRgbLed_test(pin, numLeds, testColor)
# grovepi.chainableRgbLed_pattern(pin, pattern, whichLed)
# grovepi.chainableRgbLed_modulo(pin, offset, divisor)
# grovepi.chainableRgbLed_setLevel(pin, level, reverse)
# test colors used in grovepi.chainableRgbLed_test()
testColorBlack = 0 # 0b000 #000000
testColorBlue = 1 # 0b001 #0000FF
testColorGreen = 2 # 0b010 #00FF00
testColorCyan = 3 # 0b011 #00FFFF
testColorRed = 4 # 0b100 #FF0000
testColorMagenta = 5 # 0b101 #FF00FF
testColorYellow = 6 # 0b110 #FFFF00
testColorWhite = 7 # 0b111 #FFFFFF
# patterns used in grovepi.chainableRgbLed_pattern()
thisLedOnly = 0
allLedsExceptThis = 1
thisLedAndInwards = 2
thisLedAndOutwards = 3
try:
print("Test 1) Initialise")
# init chain of leds
grovepi.chainableRgbLed_init(pin, numleds)
time.sleep(.5)
# change color to green
grovepi.storeColor(0,255,0)
time.sleep(.5)
# set led 1 to green
grovepi.chainableRgbLed_pattern(pin, thisLedOnly, 0)
time.sleep(.5)
# change color to red
grovepi.storeColor(255,0,0)
time.sleep(.5)
# set led 10 to red
grovepi.chainableRgbLed_pattern(pin, thisLedOnly, 9)
time.sleep(.5)
# pause so you can see what happened
time.sleep(2)
# reset (all off)
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
time.sleep(.5)
print ("Test 2a) Test Patterns - black")
# test pattern 0 - black (all off)
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
time.sleep(1)
print ("Test 2b) Test Patterns - blue")
# test pattern 1 blue
grovepi.chainableRgbLed_test(pin, numleds, testColorBlue)
time.sleep(1)
print ("Test 2c) Test Patterns - green")
# test pattern 2 green
grovepi.chainableRgbLed_test(pin, numleds, testColorGreen)
time.sleep(1)
print ("Test 2d) Test Patterns - cyan")
# test pattern 3 cyan
grovepi.chainableRgbLed_test(pin, numleds, testColorCyan)
time.sleep(1)
print ("Test 2e) Test Patterns - red")
# test pattern 4 red
grovepi.chainableRgbLed_test(pin, numleds, testColorRed)
time.sleep(1)
print ("Test 2f) Test Patterns - magenta")
# test pattern 5 magenta
grovepi.chainableRgbLed_test(pin, numleds, testColorMagenta)
time.sleep(1)
print ("Test 2g) Test Patterns - yellow")
# test pattern 6 yellow
grovepi.chainableRgbLed_test(pin, numleds, testColorYellow)
time.sleep(1)
print ("Test 2h) Test Patterns - white")
# test pattern 7 white
grovepi.chainableRgbLed_test(pin, numleds, testColorWhite)
time.sleep(1)
# pause so you can see what happened
time.sleep(2)
# reset (all off)
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
time.sleep(.5)
except KeyboardInterrupt:
# reset (all off)
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
except IOError:
print ("Error")

View file

@ -0,0 +1,130 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove Chainable RGB LED (http://www.seeedstudio.com/wiki/Grove_-_Chainable_RGB_LED)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://www.dexterindustries.com/forum/?forum=grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
import grovepi
# Connect first LED in Chainable RGB LED chain to digital port D7
# In: CI,DI,VCC,GND
# Out: CO,DO,VCC,GND
pin = 7
# I have 10 LEDs connected in series with the first connected to the GrovePi and the last not connected
# First LED input socket connected to GrovePi, output socket connected to second LED input and so on
numleds = 4 #If you only plug 1 LED, change 10 to 1
grovepi.pinMode(pin,"OUTPUT")
time.sleep(1)
# Chainable RGB LED methods
# grovepi.storeColor(red, green, blue)
# grovepi.chainableRgbLed_init(pin, numLeds)
# grovepi.chainableRgbLed_test(pin, numLeds, testColor)
# grovepi.chainableRgbLed_pattern(pin, pattern, whichLed)
# grovepi.chainableRgbLed_modulo(pin, offset, divisor)
# grovepi.chainableRgbLed_setLevel(pin, level, reverse)
# test colors used in grovepi.chainableRgbLed_test()
testColorBlack = 0 # 0b000 #000000
testColorBlue = 1 # 0b001 #0000FF
testColorGreen = 2 # 0b010 #00FF00
testColorCyan = 3 # 0b011 #00FFFF
testColorRed = 4 # 0b100 #FF0000
testColorMagenta = 5 # 0b101 #FF00FF
testColorYellow = 6 # 0b110 #FFFF00
testColorWhite = 7 # 0b111 #FFFFFF
# patterns used in grovepi.chainableRgbLed_pattern()
thisLedOnly = 0
allLedsExceptThis = 1
thisLedAndInwards = 2
thisLedAndOutwards = 3
sleep_time=0.5
#Turns off the led specified by led_num
def turn_off_led(led_num):
grovepi.storeColor(0,0,0)
time.sleep(.1)
grovepi.chainableRgbLed_pattern(pin, thisLedOnly, led_num)
time.sleep(.1)
#Turns on the led specified by led_num to color set by r,g,b
def turn_on_led(led_num,r,g,b):
grovepi.storeColor(r,g,b)
time.sleep(.1)
grovepi.chainableRgbLed_pattern(pin, thisLedOnly, led_num)
time.sleep(.1)
try:
print("Initialise")
# init chain of leds
grovepi.chainableRgbLed_init(pin, numleds)
time.sleep(.5)
print("1")
# turn on led at 0
turn_on_led(0,0,255,0)
time.sleep(sleep_time)
# turn on led at 1
print("2")
turn_off_led(0)
turn_on_led(1,0,255,0)
time.sleep(sleep_time)
# turn on led at 2
print("3")
turn_off_led(1)
turn_on_led(2,0,255,0)
time.sleep(sleep_time)
# turn on led at 3
print("4")
turn_off_led(2)
turn_on_led(3,0,255,0)
time.sleep(sleep_time)
# turn off all
print("Off")
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
time.sleep(sleep_time)
except KeyboardInterrupt:
# reset (all off)
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
except IOError:
print ("Error")

View file

@ -0,0 +1,379 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove Chainable RGB LED (http://www.seeedstudio.com/wiki/Grove_-_Chainable_RGB_LED)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
# Released under the MIT license (http://choosealicense.com/licenses/mit/).
# For more information see https://github.com/DexterInd/GrovePi/blob/master/LICENSE
import time
import grovepi
# Connect first LED in Chainable RGB LED chain to digital port D7
# In: CI,DI,VCC,GND
# Out: CO,DO,VCC,GND
pin = 7
# I have 10 LEDs connected in series with the first connected to the GrovePi and the last not connected
# First LED input socket connected to GrovePi, output socket connected to second LED input and so on
numleds = 4 #If you only plug 1 LED, change 10 to 1
grovepi.pinMode(pin,"OUTPUT")
time.sleep(1)
# Chainable RGB LED methods
# grovepi.storeColor(red, green, blue)
# grovepi.chainableRgbLed_init(pin, numLeds)
# grovepi.chainableRgbLed_test(pin, numLeds, testColor)
# grovepi.chainableRgbLed_pattern(pin, pattern, whichLed)
# grovepi.chainableRgbLed_modulo(pin, offset, divisor)
# grovepi.chainableRgbLed_setLevel(pin, level, reverse)
# test colors used in grovepi.chainableRgbLed_test()
testColorBlack = 0 # 0b000 #000000
testColorBlue = 1 # 0b001 #0000FF
testColorGreen = 2 # 0b010 #00FF00
testColorCyan = 3 # 0b011 #00FFFF
testColorRed = 4 # 0b100 #FF0000
testColorMagenta = 5 # 0b101 #FF00FF
testColorYellow = 6 # 0b110 #FFFF00
testColorWhite = 7 # 0b111 #FFFFFF
# patterns used in grovepi.chainableRgbLed_pattern()
thisLedOnly = 0
allLedsExceptThis = 1
thisLedAndInwards = 2
thisLedAndOutwards = 3
try:
print("Test 1) Initialise")
# init chain of leds
grovepi.chainableRgbLed_init(pin, numleds)
time.sleep(.5)
# change color to green
grovepi.storeColor(0,255,0)
time.sleep(.5)
# set led 1 to green
grovepi.chainableRgbLed_pattern(pin, thisLedOnly, 0)
time.sleep(.5)
# change color to red
grovepi.storeColor(255,0,0)
time.sleep(.5)
# set led 10 to red
grovepi.chainableRgbLed_pattern(pin, thisLedOnly, 9)
time.sleep(.5)
# pause so you can see what happened
time.sleep(2)
# reset (all off)
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
time.sleep(.5)
print ("Test 2a) Test Patterns - black")
# test pattern 0 - black (all off)
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
time.sleep(1)
print ("Test 2b) Test Patterns - blue")
# test pattern 1 blue
grovepi.chainableRgbLed_test(pin, numleds, testColorBlue)
time.sleep(1)
print ("Test 2c) Test Patterns - green")
# test pattern 2 green
grovepi.chainableRgbLed_test(pin, numleds, testColorGreen)
time.sleep(1)
print ("Test 2d) Test Patterns - cyan")
# test pattern 3 cyan
grovepi.chainableRgbLed_test(pin, numleds, testColorCyan)
time.sleep(1)
print ("Test 2e) Test Patterns - red")
# test pattern 4 red
grovepi.chainableRgbLed_test(pin, numleds, testColorRed)
time.sleep(1)
print ("Test 2f) Test Patterns - magenta")
# test pattern 5 magenta
grovepi.chainableRgbLed_test(pin, numleds, testColorMagenta)
time.sleep(1)
print ("Test 2g) Test Patterns - yellow")
# test pattern 6 yellow
grovepi.chainableRgbLed_test(pin, numleds, testColorYellow)
time.sleep(1)
print ("Test 2h) Test Patterns - white")
# test pattern 7 white
grovepi.chainableRgbLed_test(pin, numleds, testColorWhite)
time.sleep(1)
# pause so you can see what happened
time.sleep(2)
# reset (all off)
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
time.sleep(.5)
print ("Test 3a) Set using pattern - this led only")
# change color to red
grovepi.storeColor(255,0,0)
time.sleep(.5)
# set led 3 to red
grovepi.chainableRgbLed_pattern(pin, thisLedOnly, 2)
time.sleep(.5)
# pause so you can see what happened
time.sleep(2)
# reset (all off)
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
time.sleep(.5)
print ("Test 3b) Set using pattern - all leds except this")
# change color to blue
grovepi.storeColor(0,0,255)
time.sleep(.5)
# set all leds except for 3 to blue
grovepi.chainableRgbLed_pattern(pin, allLedsExceptThis, 3)
time.sleep(.5)
# pause so you can see what happened
time.sleep(2)
# reset (all off)
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
time.sleep(.5)
print ("Test 3c) Set using pattern - this led and inwards")
# change color to green
grovepi.storeColor(0,255,0)
time.sleep(.5)
# set leds 1-3 to green
grovepi.chainableRgbLed_pattern(pin, thisLedAndInwards, 2)
time.sleep(.5)
# pause so you can see what happened
time.sleep(2)
# reset (all off)
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
time.sleep(.5)
print ("Test 3d) Set using pattern - this led and outwards")
# change color to green
grovepi.storeColor(0,255,0)
time.sleep(.5)
# set leds 7-10 to green
grovepi.chainableRgbLed_pattern(pin, thisLedAndOutwards, 6)
time.sleep(.5)
# pause so you can see what happened
time.sleep(2)
# reset (all off)
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
time.sleep(.5)
print ("Test 4a) Set using modulo - all leds")
# change color to black (fully off)
grovepi.storeColor(0,0,0)
time.sleep(.5)
# set all leds black
# offset 0 means start at first led
# divisor 1 means every led
grovepi.chainableRgbLed_modulo(pin, 0, 1)
time.sleep(.5)
# change color to white (fully on)
grovepi.storeColor(255,255,255)
time.sleep(.5)
# set all leds white
grovepi.chainableRgbLed_modulo(pin, 0, 1)
time.sleep(.5)
# pause so you can see what happened
time.sleep(2)
# reset (all off)
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
time.sleep(.5)
print ("Test 4b) Set using modulo - every 2")
# change color to red
grovepi.storeColor(255,0,0)
time.sleep(.5)
# set every 2nd led to red
grovepi.chainableRgbLed_modulo(pin, 0, 2)
time.sleep(.5)
# pause so you can see what happened
time.sleep(2)
print ("Test 4c) Set using modulo - every 2, offset 1")
# change color to green
grovepi.storeColor(0,255,0)
time.sleep(.5)
# set every 2nd led to green, offset 1
grovepi.chainableRgbLed_modulo(pin, 1, 2)
time.sleep(.5)
# pause so you can see what happened
time.sleep(2)
# reset (all off)
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
time.sleep(.5)
print ("Test 4d) Set using modulo - every 3, offset 0")
# change color to red
grovepi.storeColor(255,0,0)
time.sleep(.5)
# set every 3nd led to red
grovepi.chainableRgbLed_modulo(pin, 0, 3)
time.sleep(.5)
# change color to green
grovepi.storeColor(0,255,0)
time.sleep(.5)
# set every 3nd led to green, offset 1
grovepi.chainableRgbLed_modulo(pin, 1, 3)
time.sleep(.5)
# change color to blue
grovepi.storeColor(0,0,255)
time.sleep(.5)
# set every 3nd led to blue, offset 2
grovepi.chainableRgbLed_modulo(pin, 2, 3)
time.sleep(.5)
# pause so you can see what happened
time.sleep(2)
# reset (all off)
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
time.sleep(.5)
print ("Test 4e) Set using modulo - every 3, offset 1")
# change color to yellow
grovepi.storeColor(255,255,0)
time.sleep(.5)
# set every 4nd led to yellow
grovepi.chainableRgbLed_modulo(pin, 1, 3)
time.sleep(.5)
# pause so you can see what happened
time.sleep(2)
print ("Test 4f) Set using modulo - every 3, offset 2")
# change color to magenta
grovepi.storeColor(255,0,255)
time.sleep(.5)
# set every 4nd led to magenta
grovepi.chainableRgbLed_modulo(pin, 2, 3)
time.sleep(.5)
# pause so you can see what happened
time.sleep(2)
# reset (all off)
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
time.sleep(.5)
print ("Test 5a) Set level 6")
# change color to green
grovepi.storeColor(0,255,0)
time.sleep(.5)
# set leds 1-6 to green
grovepi.write_i2c_block(0x04,[95,pin,6,0])
time.sleep(.5)
# pause so you can see what happened
time.sleep(2)
# reset (all off)
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
time.sleep(.5)
print ("Test 5b) Set level 7 - reverse")
# change color to red
grovepi.storeColor(255,0,0)
time.sleep(.5)
# set leds 4-10 to red
grovepi.write_i2c_block(0x04,[95,pin,7,1])
time.sleep(.5)
except KeyboardInterrupt:
# reset (all off)
grovepi.chainableRgbLed_test(pin, numleds, testColorBlack)
except IOError:
print ("Error")

View file

@ -0,0 +1,46 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove - CO2 Sensor(http://www.seeedstudio.com/depot/Grove-CO2-Sensor-p-1863.html)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
# Connect the CO2 sensor to the RPISER port on the GrovePi
import grove_co2_lib
import time
co2= grove_co2_lib.CO2()
while True:
[ppm,temp]= co2.read()
print("CO2 Conc: %d ppm\t Temp: %d C" %(ppm,temp))
time.sleep(1)

View file

@ -0,0 +1,61 @@
#!/usr/bin/env python
######################################################################## # GrovePi Library for using the Grove - CO2 Sensor(http://www.seeedstudio.com/depot/Grove-CO2-Sensor-p-1863.html)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this library? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
#
# NOTES:
# * Calibration and read of the CO2 sensor MH-Z16 according to the datasheet : http://www.seeedstudio.com/wiki/images/c/ca/MH-Z16_CO2_datasheet_EN.pdf
# * output value directly in ppm
# * Library derived from the inital controbution by Doms Genoud (@domsgen) here: http://www.dexterindustries.com/topic/how-to-use-co2-grove-sensor-with-serial-grovepi/
#
# History
# ------------------------------------------------
# Author Date Comments
# Doms Genoud 13 Apr 15 Initial Authoring
# Karan 07 Jan 16 Code cleanup and added to main Github repo
#
# These files have been made available online through a Creative Commons Attribution-ShareAlike 3.0 license.
# (http://creativecommons.org/licenses/by-sa/3.0/)
#
########################################################################
import serial, time
class CO2:
#inspired from c code of http://www.seeedstudio.com/wiki/Grove_-_CO2_Sensor
#Gas concentration= high level *256+low level
inp = []
cmd_zero_sensor = b'\xff\x87\x87\x00\x00\x00\x00\x00\xf2'
cmd_span_sensor = b'\xff\x87\x87\x00\x00\x00\x00\x00\xf2'
cmd_get_sensor = b'\xff\x01\x86\x00\x00\x00\x00\x00\x79'
def __init__(self):
#To open the raspberry serial port
ser = serial.Serial('/dev/serial0', 9600, timeout = 1) #Open the serial port at 9600 baud
#init serial
ser.flush()
def read(self):
try:
ser.write(self.cmd_get_sensor)
self.inp = ser.read(9)
high_level = self.inp[2]
low_level = self.inp[3]
temp_co2 = self.inp[4] - 40
#output in ppm, temp
conc = high_level*256+low_level
return [conc,temp_co2]
except IOError:
return [-1,-1]
if __name__ == "__main__":
c = CO2()
while True:
print(c.read())
time.sleep(1)

View file

@ -0,0 +1,50 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove Collision Sensor (http://www.seeedstudio.com/wiki/Grove_-_Collision_Sensor)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
import grovepi
# Connect the Grove Collision Sensor to digital port D2
# SIG,NC,VCC,GND
collision_sensor = 2
grovepi.pinMode(collision_sensor,"INPUT")
while True:
try:
print(grovepi.digitalRead(collision_sensor))
time.sleep(.5)
except IOError:
print ("Error")

View file

@ -0,0 +1,43 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove Compass module (http://www.seeedstudio.com/depot/Grove-3Axis-Digital-Compass-p-759.html)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import grove_compass_lib
import time
c=grove_compass_lib.compass()
while True:
print("X:",c.x,"Y:",c.y,"X:",c.z,"Heading:",c.headingDegrees)
c.update()
time.sleep(.1)

View file

@ -0,0 +1,102 @@
#!/usr/bin/env python
#
# GrovePi Library for using the Grove Compass module HCM5883 (http://www.seeedstudio.com/depot/Grove-3Axis-Digital-Compass-p-759.html)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
# History
# ------------------------------------------------
# Author Date Comments
# Karan 22 July 14 Initial Authoring
#
# NOTE:
# Refer to the datasheet to add additional functionality https://www.seeedstudio.com/wiki/images/4/42/HMC5883.pdf
import smbus
import time
import math
import RPi.GPIO as GPIO
import struct
rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
bus = smbus.SMBus(1)
else:
bus = smbus.SMBus(0)
HMC5883L_ADDRESS =0x1E
#CONFIGURATION_REGISTERA =0x00
#CONFIGURATION_REGISTERB =0x01
MODE_REGISTER =0x02
#DATA_REGISTER_BEGIN =0x03
#MEASUREMENT_CONTINUOUS =0x00
#MEASUREMENT_SINGLE_SHOT =0x01
#MEASUREMENT_IDLE =0x03
#Do two's compiment of val (for parsing the input)
#http://stackoverflow.com/a/9147327/1945052
def twos_comp(val, bits):
"""compute the 2's compliment of int value val"""
if( (val&(1<<(bits-1))) != 0 ):
val = val - (1<<bits)
return val
#Compass class for all the values and functions
class compass:
x=0
y=0
z=0
heading=0
headingDegrees=0
def __init__(self):
#Enable the compass
bus.write_byte_data(HMC5883L_ADDRESS,MODE_REGISTER,0)
time.sleep(.1)
data=bus.read_i2c_block_data(HMC5883L_ADDRESS,0)
compass.update(self)
#Update the compass values
def update(self):
data=bus.read_i2c_block_data(HMC5883L_ADDRESS,0)
compass.x=twos_comp(data[3]*256+data[4],16)
compass.z=twos_comp(data[5]*256+data[6],16)
compass.y=twos_comp(data[7]*256+data[8],16)
compass.heading=math.atan2(compass.y, compass.x)
if compass.heading <0:
compass.heading+=2*math.pi
if compass.heading >2*math.pi:
compass.heading-=2*math.pi
compass.headingDegrees=round(math.degrees(compass.heading),2)

View file

@ -0,0 +1,58 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove Temperature & Humidity Sensor Pro
# (http://www.seeedstudio.com/wiki/Grove_-_Temperature_and_Humidity_Sensor_Pro)
#
# The GrovePi connects the Raspberry Pi and Grove sensors.
# You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import grovepi
import math
# Connect the Grove Temperature & Humidity Sensor Pro to digital port D4
# This example uses the blue colored sensor.
# SIG,NC,VCC,GND
sensor = 4 # The Sensor goes on digital port 4.
# temp_humidity_sensor_type
# Grove Base Kit comes with the blue sensor.
blue = 0 # The Blue colored sensor.
white = 1 # The White colored sensor.
while True:
try:
# This example uses the blue colored sensor.
# The first parameter is the port, the second parameter is the type of sensor.
[temp,humidity] = grovepi.dht(sensor,blue)
if math.isnan(temp) == False and math.isnan(humidity) == False:
print("temp = %.02f C humidity =%.02f%%"%(temp, humidity))
except IOError:
print ("Error")

View file

@ -0,0 +1,210 @@
# Released under the MIT license (http://choosealicense.com/licenses/mit/).
# For more information see https://github.com/DexterInd/GrovePi/blob/master/LICENSE
import threading # we need threads for processing data seperately from the main thread
import numpy # for statistical computations
import datetime
import math # for NaNs
from grovepi import dht # we built on top of the base function found in the grovepi library
from grovepi import statisticalNoiseReduction # importing function which is meant for removing outliers from a given set
import time
'''
# after a list of numerical values is provided
# the function returns a list with the outlier(or extreme) values removed
# make the std_factor_threshold bigger so that filtering becomes less strict
# and make the std_factor_threshold smaller to get the opposite
def statisticalNoiseReduction(values, std_factor_threshold = 2):
if len(values) == 0:
return []
mean = numpy.mean(values)
standard_deviation = numpy.std(values)
# just return if we only got constant values
if standard_deviation == 0:
return values
# remove outlier values which are less than the average but bigger than the calculated threshold
filtered_values = [element for element in values if element > mean - std_factor_threshold * standard_deviation]
# the same but in the opposite direction
filtered_values = [element for element in filtered_values if element < mean + std_factor_threshold * standard_deviation]
return filtered_values
'''
# class for the Grove DHT sensor
# it was designed so that on a separate thread the values from the DHT sensor are read
# on the same separate thread, the filtering process takes place
class Dht(threading.Thread):
# refresh_period specifies for how long data is captured before it's filtered
def __init__(self, pin = 4, refresh_period = 10.0, debugging = False):
super(Dht, self).__init__(name = "DHT filtering")
self.pin = pin
self.refresh_period = refresh_period
self.debugging = debugging
self.event_stopper = threading.Event()
self.blue_sensor = 0
self.white_sensor = 1
self.filtering_aggresiveness = 2
self.callbackfunc = None
self.sensor_type = self.blue_sensor
self.lock = threading.Lock()
self.filtered_temperature = []
self.filtered_humidity = []
self.last_temperature = None
self.last_humidity = None
# refresh_period specifies for how long data is captured before it's filtered
def setRefreshPeriod(self, time):
self.refresh_period = time
# sets the digital port
def setDhtPin(self, pin):
self.pin = pin
# use the white sensor module
def setAsWhiteSensor(self):
self.sensor_type = self.white_sensor
# use the blue sensor module
def setAsBlueSensor(self):
self.sensor_type = self.blue_sensor
# removes the processed data from the buffer
def clearBuffer(self):
self.lock.acquire()
self.filtered_humidity = []
self.filtered_temperature = []
self.lock.release()
# the bigger the parameter, the less strict is the filtering process
# it's also vice-versa
def setFilteringAggresiveness(self, filtering_aggresiveness = 2):
self.filtering_aggresiveness = filtering_aggresiveness
# whenever there's new data processed
# a callback takes place
# arguments can also be sent
def setCallbackFunction(self, callbackfunc, *args):
self.callbackfunc = callbackfunc
self.args = args
# stops the current thread from running
def stop(self):
self.event_stopper.set()
self.join()
# replaces the need to custom-create code for outputting logs/data
# print(dhtObject) can be used instead
def __str__(self):
string = ""
self.lock.acquire()
# check if we have values in the buffer
if len(self.filtered_humidity) > 0:
self.last_temperature = self.filtered_temperature.pop()
self.last_humidity = self.filtered_humidity.pop()
self.lock.release()
# retrieve the last read value
if not self.last_humidity is None:
string = '[{}][temperature = {:.01f}][humidity = {:.01f}]'.format(
datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
self.last_temperature, self.last_humidity)
# otherwise it means we haven't got values yet
else:
string = '[{}][waiting for buffer to fill]'.format(
datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
return string
# returns a tuple with the (temperature, humidity) format
# if there's nothing in the buffer, then it returns (None, None)
def feedMe(self):
if self.length() > 0:
self.lock.acquire()
temp = self.filtered_temperature.pop()
hum = self.filtered_humidity.pop()
self.lock.release()
return (temp, hum)
else:
return (None, None)
# returns the length of the buffer
# the buffer is filled with filtered data
def length(self):
self.lock.acquire()
length = len(self.filtered_humidity)
self.lock.release()
return length
# you musn't call this function from the user-program
# this one is called by threading.Thread's start function
def run(self):
values = []
# while we haven't called stop function
while not self.event_stopper.is_set():
counter = 0
# while we haven't done a cycle (period)
while counter < self.refresh_period and not self.event_stopper.is_set():
temp = None
humidity = None
# read data
try:
[temp, humidity] = dht(self.pin, self.sensor_type)
# check for NaN errors
if math.isnan(temp) is False and math.isnan(humidity) is False:
new_entry = {"temp" : temp, "hum" : humidity}
values.append(new_entry)
else:
raise RuntimeWarning("[dht sensor][we've caught a NaN]")
counter += 1
# in case we have an I2C error
except IOError:
if self.debugging is True:
print("[dht sensor][we've got an IO error]")
# intented to catch NaN errors
except RuntimeWarning as error:
if self.debugging is True:
print(str(error))
finally:
# the DHT can be read once a second
time.sleep(1)
if len(values) > 0:
# remove outliers
temp = numpy.mean(statisticalNoiseReduction([x["temp"] for x in values], self.filtering_aggresiveness))
humidity = numpy.mean(statisticalNoiseReduction([x["hum"] for x in values], self.filtering_aggresiveness))
# insert into the filtered buffer
self.lock.acquire()
self.filtered_temperature.append(temp)
self.filtered_humidity.append(humidity)
self.lock.release()
# if we have set a callback then call that function w/ its parameters
if not self.callbackfunc is None:
self.callbackfunc(*self.args)
# reset the values for the next iteration/period
values = []
if self.debugging is True:
print("[dht sensor][called for joining thread]")

View file

@ -0,0 +1,56 @@
#!/usr/bin/env python3
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
# Connect the Grove DHT Sensor (Blue One) to Port 4 in this example.
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
from grove_dht import Dht # from a custom made grovepi-based library import our needed class
from time import sleep # we need to use the sleep function to delay readings
# Don't forget to run it with Python 3 !!
# Don't forget to run it with Python 3 !!
# Don't forget to run it with Python 3 !!
dht_pin = 4 # use Digital Port 4 found on GrovePi
dht_sensor = Dht(dht_pin) # instantiate a dht class with the appropriate pin
dht_sensor.start() # start collecting from the DHT sensor
try:
# do this indefinitely
while True:
print(dht_sensor) # prints values in a nice format
sleep(0.8) # wait around 800 ms before the next iteration
# when pressing CTRL-C
except KeyboardInterrupt:
dht_sensor.stop() # stop gathering data

View file

@ -0,0 +1,66 @@
#!/usr/bin/env python3
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
# Connect the Grove DHT Sensor (Blue One) to Port 4 in this example.
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
from grove_dht import Dht # from a custom made grovepi-based library import our needed class
from time import sleep # we need to use the sleep function to delay readings
import datetime # that's for printing the current date
# Don't forget to run it with Python 3 !!
# Don't forget to run it with Python 3 !!
# Don't forget to run it with Python 3 !!
dht_pin = 4 # use Digital Port 4 found on GrovePi
dht_sensor = Dht(dht_pin) # instantiate a dht class with the appropriate pin
dht_sensor.start() # start collecting from the DHT sensor
try:
# do this indefinitely
while True:
string = '[' + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + ']' # keep a track of the current time
temperature, humidity = dht_sensor.feedMe() # try to read values
# if any of the read values is a None type, then it means there're no available values
if not temperature is None:
string += '[temperature = {:.01f}][humidity = {:.01f}]'.format(temperature, humidity)
else:
string += '[waiting for buffer to fill]'
print(string)
sleep(0.8) # wait around 800 ms before the next iteration
# when pressing CTRL-C
except KeyboardInterrupt:
dht_sensor.stop() # stop gathering data

View file

@ -0,0 +1,90 @@
#!/usr/bin/env python3
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
# Connect the Grove DHT Sensor (Blue One) to Port 4 in this example.
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
from grove_dht import Dht
import signal
import sys
# Don't forget to run it with Python 3 !!
# Don't forget to run it with Python 3 !!
# Don't forget to run it with Python 3 !!
# Please read the source file(s) for more explanations
# Source file(s) are more comprehensive
dht_sensor = Dht()
def signal_handler(signal, frame):
global dht_sensor
dht_sensor.stop()
def callbackFunc():
global dht_sensor
print(dht_sensor)
def Main():
print("[program is running][please wait]")
global dht_sensor
digital_port = 4
# set the digital port for the DHT sensor
dht_sensor.setDhtPin(digital_port)
# using the blue kind of sensor
# there's also the white one which can be set by calling [dht.setAsWhiteSensor()] function
dht_sensor.setAsBlueSensor()
# specifies for how long we record data before we filter it
# it's better to have larger periods of time,
# because the statistical algorithm has a vaster pool of values
dht_sensor.setRefreshPeriod(12)
# the bigger is the filtering factor (as in the filtering aggresiveness)
# the less strict is the algorithm when it comes to filtering
# it's also valid vice-versa
# the factor must be greater than 0
# it's recommended to leave its default value unless there is a better reason
dht_sensor.setFilteringAggresiveness(2.1)
# every time the Dht object loads new filtered data inside the buffer
# a callback is what it follows
dht_sensor.setCallbackFunction(callbackFunc)
# start the thread for gathering data
dht_sensor.start()
# if you want to stop the thread just
# call dht.stop() and you're done
if __name__ == "__main__":
signal.signal(signal.SIGINT, signal_handler)
Main()

View file

@ -0,0 +1,64 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove Dry Reed Relay (http://www.seeedstudio.com/wiki/Grove_-_Dry-Reed_Relay)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
import grovepi
# Connect the Grove Dry Reed Relay to digital port D4
# SIG,NC,VCC,GND
relay = 4
# Relay is normally open. LED will illuminate when closed and there is no clicking sound
grovepi.pinMode(relay,"OUTPUT")
while True:
try:
# switch on for 5 seconds
grovepi.digitalWrite(relay,1)
print ("on")
time.sleep(5)
# switch off for 5 seconds
grovepi.digitalWrite(relay,0)
print ("off")
time.sleep(5)
except KeyboardInterrupt:
grovepi.digitalWrite(relay,0)
break
except IOError:
print ("Error")

View file

@ -0,0 +1,65 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove Dust sensor(http://www.seeedstudio.com/depot/Grove-Dust-Sensor-p-1050.html) with the GrovePi
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
# USAGE
#
# Connect the dust sensor to Port D2 on the GrovePi. The dust sensor only works on that port
# The dust sensor takes 30 seconds to update the new values
#
# It returns the LPO time, the percentage (LPO time divided by total period, in this case being 30000 ms)
# and the concentration in pcs/0.01cf
import time
import grovepi
print("Reading from the Grove Dust Sensor")
# default pin is 2 and default update period is 30000 ms
grovepi.dust_sensor_en()
time_to_run = 125 # 10 seconds
start = time.time() # current time in seconds
old_val = [0, 0.0, 0.0]
while start + time_to_run > time.time():
# defaults to pin 2
new_val = grovepi.dust_sensor_read()
if old_val[0] != new_val[0]:
print("LPO time = {:3d} | LPO% = {:5.2f} | pcs/0.01cf = {:6.1f}".format(*new_val))
old_val = new_val
# and disable the interrupt on pin 2
grovepi.dust_sensor_dis()

View file

@ -0,0 +1,87 @@
# Code contributed by Alessandro Graps a.graps@joulehub.com
# May 2020
# Many thanks !!!
from datetime import datetime
from datetime import timedelta
import time
import grovepi
# Connect the Grove Ear Clip Sensor to digital port D3
sensorPin = 3
start_time = datetime.now()
counter = 0
temp = [0] * 21
data_effect = True
heart_rate = 0
max_heartpulse_duty = 2000
def millis():
global start_time
dt = datetime.now() - start_time
ms = (dt.days * 24 * 60 * 60 + dt.seconds) * 1000 + dt.microseconds / 1000.0
return ms
def arrayInit():
global temp
global counter
counter = 0
temp = [0] * 21
temp[20] = millis()
def sum():
global heart_rate, temp, data_effect
if data_effect:
heart_rate=1200000/(temp[20]-temp[0]);
def interrupt():
global counter
global temp
global data_effect
temp[counter] = millis()
if counter == 0:
sub = temp[counter]-temp[20]
else:
sub = temp[counter]-temp[counter-1]
if sub > max_heartpulse_duty:
data_effect = False
counter = 0
arrayInit()
if counter == 20 and data_effect:
counter = 0
sum()
elif counter != 20 and data_effect:
counter += 1
else:
counter = 0
data_effect = True
def main():
global heart_rate
print("Please place the sensor correctly")
time.sleep(4)
print("Starting measurement...")
arrayInit()
grovepi.set_pin_interrupt(sensorPin, grovepi.COUNT_CHANGES, grovepi.RISING, 1000)
while True:
value = grovepi.read_interrupt_state(sensorPin)
if value > 0:
interrupt()
time.sleep(0.73)
print("HR: {:2.0f}".format(heart_rate))
if __name__ == '__main__':
main()

View file

@ -0,0 +1,68 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove Electricity Sensor (http://www.seeedstudio.com/wiki/Grove_-_Electricity_Sensor)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
import grovepi
# Connect the Grove Electricity Sensor to analog port A0
# SIG,NC,NC,GND
sensor = 0
grovepi.pinMode(sensor,"INPUT")
# Vcc of the grove interface is normally 5v
grove_vcc = 5
while True:
try:
# Get sensor value
sensor_value = grovepi.analogRead(sensor)
# Calculate amplitude current (mA)
amplitude_current = (float)(sensor_value / 1024 * grove_vcc / 800 * 2000000)
# Calculate effective value (mA)
effective_value = amplitude_current / 1.414
# minimum_current = 1 / 1024 * grove_vcc / 800 * 2000000 / 1.414 = 8.6(mA)
# Only for sinusoidal alternating current
print("sensor_value", sensor_value)
print("The amplitude of the current is", amplitude_current, "mA")
print("The effective value of the current is", effective_value, "mA")
time.sleep(1)
except IOError:
print ("Error")

View file

@ -0,0 +1,65 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove Electromagnet (http://www.seeedstudio.com/wiki/Grove_-_Electromagnet)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
import grovepi
# The electromagnet can hold a 1KG weight
# Connect the Grove Electromagnet to digital port D4
# SIG,NC,VCC,GND
electromagnet = 4
grovepi.pinMode(electromagnet,"OUTPUT")
time.sleep(1)
while True:
try:
# Switch on electromagnet
grovepi.digitalWrite(electromagnet,1)
print ("on")
time.sleep(2)
# Switch off electromagnet
grovepi.digitalWrite(electromagnet,0)
print ("off")
time.sleep(2)
except KeyboardInterrupt:
grovepi.digitalWrite(electromagnet,0)
break
except IOError:
print ("Error")

View file

@ -0,0 +1,63 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove Encoder(http://www.seeedstudio.com/depot/Grove-Encoder-p-1352.html) with the GrovePi
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
# USAGE
#
# Connect the grove encoder to D2 on the GrovePi.
# The encoder values go from 0 up to 32
# (although these can be subsequently changed by utilizing a different parameter for the encoder_en function)
import time
import grovepi
print("Reading from the Grove Encoder")
# default pin is 2 and default number of steps is 32
grovepi.encoder_en()
time_to_run = 10 # 10 seconds
start = time.time() # current time in seconds
old_val = 0
while start + time_to_run > time.time():
# defaults to pin 2
new_val = grovepi.encoderRead()
if old_val != new_val:
print("{:3d}/32 position".format(new_val))
old_val = new_val
# and disable the interrupt on pin 2
grovepi.encoder_dis()

View file

@ -0,0 +1,65 @@
#!/usr/bin/env python
#
# GrovePi Library for using the Grove - Finger-clip Heart Rate Sensor(http://www.seeedstudio.com/depot/Grove-Fingerclip-Heart-Rate-Sensor-with-shell-p-2420.html)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this library? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
#################################################################################################################################################
# NOTE:
# The software for this sensor is still in development and might make your GrovePi unuable as long as this sensor is connected with the GrovePi
#################################################################################################################################################
import time,sys
import RPi.GPIO as GPIO
import smbus
# use the bus that matches your raspi version
rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
bus = smbus.SMBus(1)
else:
bus = smbus.SMBus(0)
class grove_fingerclip_heart_sensor:
address = 0x50
def pulse_read(self):
print(bus.read_byte(0x50))
# return bus.read_i2c_block_data(self.address, 1,1)
if __name__ == "__main__":
pulse= grove_fingerclip_heart_sensor()
while True:
try:
pulse.pulse_read()
except IOError:
print("Error")
time.sleep(.5)

View file

@ -0,0 +1,45 @@
#!/usr/bin/env python
#
# GrovePi Example for checking the firmware for the GrovePi
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
#
# NOTE: If you get a version of 255.255.255, they try running the script again, if the issue still persists then you are using an old deprecated firmware
import grovepi
try:
print("GrovePi has firmware version: %s" %grovepi.version())
except KeyboardInterrupt:
print ("KeyboardInterrupt")
except IOError:
print ("Error")

View file

@ -0,0 +1,50 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove Flame Sensor (http://www.seeedstudio.com/wiki/Grove_-_Flame_Sensor)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
import grovepi
# Connect the Grove Flame Sensor to digital port D2
# SIG,NC,VCC,GND
flame_sensor = 2
grovepi.pinMode(flame_sensor,"INPUT")
while True:
try:
print(grovepi.digitalRead(flame_sensor))
time.sleep(.5)
except IOError:
print ("Error")

View file

@ -0,0 +1,66 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove 1/4'' Flow Sensor(http://www.seeedstudio.com/depot/G14-Water-Flow-Sensor-p-1345.html) with the GrovePi
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
# USAGE
#
# Connect the Flow meter to Port 2 on the GrovePi. The flow meter only works on that port
# You can send 'run_in_bk=1' as a parameter, e.g. grovepi.flowRead(run_in_bk=1) to run the flow meter code in the background on the GrovePi. This allows you to use other functions such as digitalRead to run with the flow meter read running in the background
#
# Since the flow meter uses interrupts, it is better to disable it once you are done using it
# The flow sensor readings are updated once every 2 seconds on the firmware
import time
import grovepi
print("Reading from the Flow meter")
# default pin is 2 and default update period is 2000 ms
grovepi.flowEnable()
time_to_run = 10 # 10 seconds
start = time.time() # current time in seconds
old_val = 0
while start + time_to_run > time.time():
# defaults to pin 2
new_val = grovepi.flowRead()
if old_val != new_val:
print("{:3d} L/h".format(new_val))
old_val = new_val
# and disable the interrupt on pin 2
grovepi.flowDisable()

View file

@ -0,0 +1,72 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove Gas Sensor
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
# NOTE:
# There are 5 gas sensors
# MQ2 - Combustible Gas, Smoke
# MQ3 - Alcohol Vapor
# MQ5 - LPG, Natural Gas, Town Gas
# MQ9 - Carbon Monoxide, Coal Gas, Liquefied Gas
# 02 - Oxygen
# The sensitivity can be adjusted by the onboard potentiometer
#
# http://www.seeedstudio.com/wiki/Grove_-_Gas_Sensor
# http://www.seeedstudio.com/wiki/Grove_-_Gas_Sensor(MQ5)
# http://www.seeedstudio.com/wiki/Grove_-_Gas_Sensor(O%E2%82%82)
import time
import grovepi
# Connect the Grove Gas Sensor to analog port A0
# SIG,NC,VCC,GND
gas_sensor = 0
grovepi.pinMode(gas_sensor,"INPUT")
while True:
try:
# Get sensor value
sensor_value = grovepi.analogRead(gas_sensor)
# Calculate gas density - large value means more dense gas
density = (float)(sensor_value / 1024)
print("sensor_value =", sensor_value, " density =", density)
time.sleep(.5)
except IOError:
print ("Error")

View file

@ -0,0 +1,46 @@
Grove - Gesture Sensor v1.0 Python library and examples
=======================================================
####This library is for using the Grove - Gesture Sensor v1.0(http://www.seeedstudio.com/depot/Grove-Gesture-p-2463.html)
Code derived from the basic Arduino library for the Gesture Sensor by Seeed: https://github.com/Seeed-Studio/Gesture_PAJ7620
#####Files:
* **grove_gesture_sensor.p**y: library with functions to read data from the gesture sensors
* **gesture_print.py**: This example prints the gesture on the screen when a user does an action over the sensor. Useful when testing the gesture sensor
* **gesture_value.py**: This example returns a value when a user does an action over the sensor. Useful when integrating in your own examples
#####NOTE:
* This is an I2C sensor so you can connect it to any I2C port on the GrovePi
* The gesture sensor might restart your GrovePi if you hot-plug the sensor when the GrovePi is already powered on. Please connect the sensor before powering on the GrovePi
* The sensor polls the sensor ~.1s and after reading takes ~.4s to 1s to start polling again
* The datasheet for the sensor mentions the sensing distance b/w 5 and 15 cm
* The sensor uses IR so it would be better to keep it away from IR sources of light
######The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
######Have a question about this library? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
# License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View file

@ -0,0 +1,44 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove - Gesture Sensor v1.0(http://www.seeedstudio.com/depot/Grove-Gesture-p-2463.html)
#
# This example prints the gesture on the screen when a user does an action over the sensor
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import grove_gesture_sensor
import time
g=grove_gesture_sensor.gesture()
g.init()
while True:
g.print_gesture()
time.sleep(.1)

View file

@ -0,0 +1,68 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove - Gesture Sensor v1.0(http://www.seeedstudio.com/depot/Grove-Gesture-p-2463.html)
#
# This example returns a value when a user does an action over the sensor
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import grove_gesture_sensor
import time
g=grove_gesture_sensor.gesture()
g.init()
while True:
gest=g.return_gesture()
#Match the gesture
if gest==g.FORWARD:
print("FORWARD")
elif gest==g.BACKWARD:
print("BACKWARD")
elif gest==g.RIGHT:
print("RIGHT")
elif gest==g.LEFT:
print("LEFT")
elif gest==g.UP:
print("UP")
elif gest==g.DOWN:
print("DOWN")
elif gest==g.CLOCKWISE:
print("CLOCKWISE")
elif gest==g.ANTI_CLOCKWISE:
print("ANTI_CLOCKWISE")
elif gest==g.WAVE:
print("WAVE")
elif gest==0:
print("-")
else:
print("Error")
time.sleep(.1)

View file

@ -0,0 +1,533 @@
#!/usr/bin/env python
#
# GrovePi Library for using the Grove - Gesture Sensor v1.0(http://www.seeedstudio.com/depot/Grove-Gesture-p-2463.html)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this library? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
# History
# ------------------------------------------------
# Author Date Comments
# Karan 31 Dec 15 Initial Authoring
#
# Code derived from the basic Arduino library for the Gesture Sensor by Seeed: https://github.com/Seeed-Studio/Gesture_PAJ7620
# Released under the MIT license (http://choosealicense.com/licenses/mit/).
# For more information see https://github.com/DexterInd/GrovePi/blob/master/LICENSE
import time,sys
import RPi.GPIO as GPIO
import smbus
# use the bus that matches your raspi version
rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
bus = smbus.SMBus(1)
else:
bus = smbus.SMBus(0)
class gesture:
#Registers and variables for the gesture sensor
GES_REACTION_TIME =.500 # You can adjust the reaction time according to the actual circumstance.
GES_ENTRY_TIME =.800 # When you want to recognize the Forward/Backward gestures, your gestures' reaction time must less than GES_ENTRY_TIME(0.8s).
GES_QUIT_TIME =1.000
BANK0 = 0
BANK1 = 1
PAJ7620_ADDR_BASE =0x00
#REGISTER BANK SELECT
PAJ7620_REGITER_BANK_SEL =(PAJ7620_ADDR_BASE + 0xEF) #W
#DEVICE ID
PAJ7620_ID =0x73
#REGISTER BANK 0
PAJ7620_ADDR_SUSPEND_CMD =(PAJ7620_ADDR_BASE + 0x3) #W
PAJ7620_ADDR_GES_PS_DET_MASK_0 =(PAJ7620_ADDR_BASE + 0x41) #RW
PAJ7620_ADDR_GES_PS_DET_MASK_1 =(PAJ7620_ADDR_BASE + 0x42) #RW
PAJ7620_ADDR_GES_PS_DET_FLAG_0 =(PAJ7620_ADDR_BASE + 0x43) #R
PAJ7620_ADDR_GES_PS_DET_FLAG_1 =(PAJ7620_ADDR_BASE + 0x44) #R
PAJ7620_ADDR_STATE_INDICATOR =(PAJ7620_ADDR_BASE + 0x45) #R
PAJ7620_ADDR_PS_HIGH_THRESHOLD =(PAJ7620_ADDR_BASE + 0x69) #RW
PAJ7620_ADDR_PS_LOW_THRESHOLD =(PAJ7620_ADDR_BASE + 0x6A) #RW
PAJ7620_ADDR_PS_APPROACH_STATE =(PAJ7620_ADDR_BASE + 0x6B) #R
PAJ7620_ADDR_PS_RAW_DATA =(PAJ7620_ADDR_BASE + 0x6C) #R
#REGISTER BANK 1
PAJ7620_ADDR_PS_GAIN =(PAJ7620_ADDR_BASE + 0x44) #RW
PAJ7620_ADDR_IDLE_S1_STEP_0 =(PAJ7620_ADDR_BASE + 0x67) #RW
PAJ7620_ADDR_IDLE_S1_STEP_1 =(PAJ7620_ADDR_BASE + 0x68) #RW
PAJ7620_ADDR_IDLE_S2_STEP_0 =(PAJ7620_ADDR_BASE + 0x69) #RW
PAJ7620_ADDR_IDLE_S2_STEP_1 =(PAJ7620_ADDR_BASE + 0x6A) #RW
PAJ7620_ADDR_OP_TO_S1_STEP_0 =(PAJ7620_ADDR_BASE + 0x6B) #RW
PAJ7620_ADDR_OP_TO_S1_STEP_1 =(PAJ7620_ADDR_BASE + 0x6C) #RW
PAJ7620_ADDR_OP_TO_S2_STEP_0 =(PAJ7620_ADDR_BASE + 0x6D) #RW
PAJ7620_ADDR_OP_TO_S2_STEP_1 =(PAJ7620_ADDR_BASE + 0x6E) #RW
PAJ7620_ADDR_OPERATION_ENABLE =(PAJ7620_ADDR_BASE + 0x72) #RW
#PAJ7620_REGITER_BANK_SEL
PAJ7620_BANK0=0
PAJ7620_BANK1=1
#PAJ7620_ADDR_SUSPEND_CMD
PAJ7620_I2C_WAKEUP =1
PAJ7620_I2C_SUSPEND =0
#PAJ7620_ADDR_OPERATION_ENABLE
PAJ7620_ENABLE=1
PAJ7620_DISABLE=0
#ADC, delete
REG_ADDR_RESULT = 0x00
REG_ADDR_ALERT = 0x01
REG_ADDR_CONFIG = 0x02
REG_ADDR_LIMITL = 0x03
REG_ADDR_LIMITH = 0x04
REG_ADDR_HYST = 0x05
REG_ADDR_CONVL = 0x06
REG_ADDR_CONVH = 0x07
GES_RIGHT_FLAG =1<<0
GES_LEFT_FLAG =1<<1
GES_UP_FLAG =1<<2
GES_DOWN_FLAG =1<<3
GES_FORWARD_FLAG =1<<4
GES_BACKWARD_FLAG =1<<5
GES_CLOCKWISE_FLAG =1<<6
GES_COUNT_CLOCKWISE_FLAG =1<<7
GES_WAVE_FLAG =1<<0
#Gesture output
FORWARD = 1
BACKWARD = 2
RIGHT = 3
LEFT = 4
UP = 5
DOWN = 6
CLOCKWISE = 7
ANTI_CLOCKWISE = 8
WAVE = 9
#Initial register state
initRegisterArray=( [0xEF,0x00],
[0x32,0x29],
[0x33,0x01],
[0x34,0x00],
[0x35,0x01],
[0x36,0x00],
[0x37,0x07],
[0x38,0x17],
[0x39,0x06],
[0x3A,0x12],
[0x3F,0x00],
[0x40,0x02],
[0x41,0xFF],
[0x42,0x01],
[0x46,0x2D],
[0x47,0x0F],
[0x48,0x3C],
[0x49,0x00],
[0x4A,0x1E],
[0x4B,0x00],
[0x4C,0x20],
[0x4D,0x00],
[0x4E,0x1A],
[0x4F,0x14],
[0x50,0x00],
[0x51,0x10],
[0x52,0x00],
[0x5C,0x02],
[0x5D,0x00],
[0x5E,0x10],
[0x5F,0x3F],
[0x60,0x27],
[0x61,0x28],
[0x62,0x00],
[0x63,0x03],
[0x64,0xF7],
[0x65,0x03],
[0x66,0xD9],
[0x67,0x03],
[0x68,0x01],
[0x69,0xC8],
[0x6A,0x40],
[0x6D,0x04],
[0x6E,0x00],
[0x6F,0x00],
[0x70,0x80],
[0x71,0x00],
[0x72,0x00],
[0x73,0x00],
[0x74,0xF0],
[0x75,0x00],
[0x80,0x42],
[0x81,0x44],
[0x82,0x04],
[0x83,0x20],
[0x84,0x20],
[0x85,0x00],
[0x86,0x10],
[0x87,0x00],
[0x88,0x05],
[0x89,0x18],
[0x8A,0x10],
[0x8B,0x01],
[0x8C,0x37],
[0x8D,0x00],
[0x8E,0xF0],
[0x8F,0x81],
[0x90,0x06],
[0x91,0x06],
[0x92,0x1E],
[0x93,0x0D],
[0x94,0x0A],
[0x95,0x0A],
[0x96,0x0C],
[0x97,0x05],
[0x98,0x0A],
[0x99,0x41],
[0x9A,0x14],
[0x9B,0x0A],
[0x9C,0x3F],
[0x9D,0x33],
[0x9E,0xAE],
[0x9F,0xF9],
[0xA0,0x48],
[0xA1,0x13],
[0xA2,0x10],
[0xA3,0x08],
[0xA4,0x30],
[0xA5,0x19],
[0xA6,0x10],
[0xA7,0x08],
[0xA8,0x24],
[0xA9,0x04],
[0xAA,0x1E],
[0xAB,0x1E],
[0xCC,0x19],
[0xCD,0x0B],
[0xCE,0x13],
[0xCF,0x64],
[0xD0,0x21],
[0xD1,0x0F],
[0xD2,0x88],
[0xE0,0x01],
[0xE1,0x04],
[0xE2,0x41],
[0xE3,0xD6],
[0xE4,0x00],
[0xE5,0x0C],
[0xE6,0x0A],
[0xE7,0x00],
[0xE8,0x00],
[0xE9,0x00],
[0xEE,0x07],
[0xEF,0x01],
[0x00,0x1E],
[0x01,0x1E],
[0x02,0x0F],
[0x03,0x10],
[0x04,0x02],
[0x05,0x00],
[0x06,0xB0],
[0x07,0x04],
[0x08,0x0D],
[0x09,0x0E],
[0x0A,0x9C],
[0x0B,0x04],
[0x0C,0x05],
[0x0D,0x0F],
[0x0E,0x02],
[0x0F,0x12],
[0x10,0x02],
[0x11,0x02],
[0x12,0x00],
[0x13,0x01],
[0x14,0x05],
[0x15,0x07],
[0x16,0x05],
[0x17,0x07],
[0x18,0x01],
[0x19,0x04],
[0x1A,0x05],
[0x1B,0x0C],
[0x1C,0x2A],
[0x1D,0x01],
[0x1E,0x00],
[0x21,0x00],
[0x22,0x00],
[0x23,0x00],
[0x25,0x01],
[0x26,0x00],
[0x27,0x39],
[0x28,0x7F],
[0x29,0x08],
[0x30,0x03],
[0x31,0x00],
[0x32,0x1A],
[0x33,0x1A],
[0x34,0x07],
[0x35,0x07],
[0x36,0x01],
[0x37,0xFF],
[0x38,0x36],
[0x39,0x07],
[0x3A,0x00],
[0x3E,0xFF],
[0x3F,0x00],
[0x40,0x77],
[0x41,0x40],
[0x42,0x00],
[0x43,0x30],
[0x44,0xA0],
[0x45,0x5C],
[0x46,0x00],
[0x47,0x00],
[0x48,0x58],
[0x4A,0x1E],
[0x4B,0x1E],
[0x4C,0x00],
[0x4D,0x00],
[0x4E,0xA0],
[0x4F,0x80],
[0x50,0x00],
[0x51,0x00],
[0x52,0x00],
[0x53,0x00],
[0x54,0x00],
[0x57,0x80],
[0x59,0x10],
[0x5A,0x08],
[0x5B,0x94],
[0x5C,0xE8],
[0x5D,0x08],
[0x5E,0x3D],
[0x5F,0x99],
[0x60,0x45],
[0x61,0x40],
[0x63,0x2D],
[0x64,0x02],
[0x65,0x96],
[0x66,0x00],
[0x67,0x97],
[0x68,0x01],
[0x69,0xCD],
[0x6A,0x01],
[0x6B,0xB0],
[0x6C,0x04],
[0x6D,0x2C],
[0x6E,0x01],
[0x6F,0x32],
[0x71,0x00],
[0x72,0x01],
[0x73,0x35],
[0x74,0x00],
[0x75,0x33],
[0x76,0x31],
[0x77,0x01],
[0x7C,0x84],
[0x7D,0x03],
[0x7E,0x01])
#Enable debug message
debug=0
#Initialize the sensors
def init(self):
time.sleep(.001)
self.paj7620SelectBank(self.BANK0)
self.paj7620SelectBank(self.BANK0)
data0 = self.paj7620ReadReg(0, 1)[0]
data1 = self.paj7620ReadReg(1, 1)[0]
if self.debug:
print("data0:",data0,"data1:",data1)
if data0 != 0x20 :#or data1 <> 0x76:
print("Error with sensor")
#return 0xff
if data0 == 0x20:
print("wake-up finish.")
for i in range(len(self.initRegisterArray)):
self.paj7620WriteReg(self.initRegisterArray[i][0],self.initRegisterArray[i][1])
self.paj7620SelectBank(self.BANK0)
print("Paj7620 initialize register finished.")
#Write a byte to a register on the Gesture sensor
def paj7620WriteReg(self,addr,cmd):
bus.write_word_data(self.PAJ7620_ID, addr, cmd)
#Select a register bank on the Gesture Sensor
def paj7620SelectBank(self,bank):
if bank==self.BANK0:
self.paj7620WriteReg(self.PAJ7620_REGITER_BANK_SEL, self.PAJ7620_BANK0)
#Read a block of bytes of length "qty" starting at address "addr" from the Gesture sensor
def paj7620ReadReg(self,addr,qty):
return bus.read_i2c_block_data(self.PAJ7620_ID, addr,qty)
#Print the values from the gesture sensor
def print_gesture(self):
data=self.paj7620ReadReg(0x43,1)[0]
if data==self.GES_RIGHT_FLAG:
time.sleep(self.GES_ENTRY_TIME)
data=self.paj7620ReadReg(0x43, 1)[0]
if data == self.GES_FORWARD_FLAG:
print("Forward")
time.sleep(self.GES_QUIT_TIME)
elif data == self.GES_BACKWARD_FLAG:
print("Backward")
time.sleep(self.GES_QUIT_TIME)
else:
print("Right")
elif data==self.GES_LEFT_FLAG:
time.sleep(self.GES_ENTRY_TIME)
data=self.paj7620ReadReg(0x43, 1)[0]
if data == self.GES_FORWARD_FLAG:
print("Forward")
time.sleep(self.GES_QUIT_TIME)
elif data == self.GES_BACKWARD_FLAG:
print("Backward")
time.sleep(self.GES_QUIT_TIME)
else:
print("Left")
elif data==self.GES_UP_FLAG:
time.sleep(self.GES_ENTRY_TIME)
data=self.paj7620ReadReg(0x43, 1)[0]
if data == self.GES_FORWARD_FLAG:
print("Forward")
time.sleep(self.GES_QUIT_TIME)
elif data == self.GES_BACKWARD_FLAG:
print("Backward")
time.sleep(self.GES_QUIT_TIME)
else:
print("Up")
elif data==self.GES_DOWN_FLAG:
time.sleep(self.GES_ENTRY_TIME)
data=self.paj7620ReadReg(0x43, 1)[0]
if data == self.GES_FORWARD_FLAG:
print("Forward")
time.sleep(self.GES_QUIT_TIME)
elif data == self.GES_BACKWARD_FLAG:
print("Backward")
time.sleep(self.GES_QUIT_TIME)
else:
print("Down")
elif data==self.GES_FORWARD_FLAG:
print("Forward")
time.sleep(self.GES_QUIT_TIME)
elif data==self.GES_BACKWARD_FLAG:
print("Backward")
time.sleep(self.GES_QUIT_TIME)
elif data==self.GES_CLOCKWISE_FLAG:
print("Clockwise")
elif data==self.GES_COUNT_CLOCKWISE_FLAG:
print("anti-clockwise")
else:
data1=self.paj7620ReadReg(0x44, 1)[0]
if (data1 == self.GES_WAVE_FLAG):
print("wave")
#Return a vlaue from the gestire sensor which can be used in a program
# 0:nothing
# 1:Forward
# 2:Backward
# 3:Right
# 4:Left
# 5:Up
# 6:Down
# 7:Clockwise
# 8:anti-clockwise
# 9:wave
def return_gesture(self):
data=self.paj7620ReadReg(0x43,1)[0]
if data==self.GES_RIGHT_FLAG:
time.sleep(self.GES_ENTRY_TIME)
data=self.paj7620ReadReg(0x43, 1)[0]
if data == self.GES_FORWARD_FLAG:
return 1
time.sleep(self.GES_QUIT_TIME)
elif data == self.GES_BACKWARD_FLAG:
return 2
time.sleep(self.GES_QUIT_TIME)
else:
return 3
elif data==self.GES_LEFT_FLAG:
time.sleep(self.GES_ENTRY_TIME)
data=self.paj7620ReadReg(0x43, 1)[0]
if data == self.GES_FORWARD_FLAG:
return 1
time.sleep(self.GES_QUIT_TIME)
elif data == self.GES_BACKWARD_FLAG:
return 2
time.sleep(self.GES_QUIT_TIME)
else:
return 4
elif data==self.GES_UP_FLAG:
time.sleep(self.GES_ENTRY_TIME)
data=self.paj7620ReadReg(0x43, 1)[0]
if data == self.GES_FORWARD_FLAG:
return 1
time.sleep(self.GES_QUIT_TIME)
elif data == self.GES_BACKWARD_FLAG:
return 2
time.sleep(self.GES_QUIT_TIME)
else:
return 5
elif data==self.GES_DOWN_FLAG:
time.sleep(self.GES_ENTRY_TIME)
data=self.paj7620ReadReg(0x43, 1)[0]
if data == self.GES_FORWARD_FLAG:
return 1
time.sleep(self.GES_QUIT_TIME)
elif data == self.GES_BACKWARD_FLAG:
return 2
time.sleep(self.GES_QUIT_TIME)
else:
return 6
elif data==self.GES_FORWARD_FLAG:
return 1
time.sleep(self.GES_QUIT_TIME)
elif data==self.GES_BACKWARD_FLAG:
return 2
time.sleep(self.GES_QUIT_TIME)
elif data==self.GES_CLOCKWISE_FLAG:
return 7
elif data==self.GES_COUNT_CLOCKWISE_FLAG:
return 8
else:
data1=self.paj7620ReadReg(0x44, 1)[0]
if (data1 == self.GES_WAVE_FLAG):
return 9
return 0
if __name__ == "__main__":
g=gesture()
g.init()
while True:
g.print_gesture()
time.sleep(.1)
# print g.return_gesture()
# time.sleep(.1)

View file

@ -0,0 +1,74 @@
import serial, time
import smbus
import math
import RPi.GPIO as GPIO
import struct
import sys
ser = serial.Serial('/dev/ttyAMA0', 9600, timeout = 0) #Open the serial port at 9600 baud
ser.flush()
def readlineCR():
rv = ""
while True:
time.sleep(0.001) # This is the critical part. A small pause
# works really well here.
ch = ser.read()
rv += ch
if ch=='\r' or ch=='':
return rv
class GPS:
#The GPS module used is a Grove GPS module http://www.seeedstudio.com/depot/Grove-GPS-p-959.html
inp=[]
# Refer to SIM28 NMEA spec file http://www.seeedstudio.com/wiki/images/a/a0/SIM28_DATA_File.zip
GGA=[]
#Read data from the GPS
def read(self):
while True:
# GPS.inp=ser.readline()
GPS.inp = readlineCR().strip()
if GPS.inp[:6] =='$GPGGA': # GGA data , packet 1, has all the data we need
break
time.sleep(0.1)
try:
ind=GPS.inp.index('$GPGGA',5,len(GPS.inp)) #Sometimes multiple GPS data packets come into the stream. Take the data only after the last '$GPGGA' is seen
GPS.inp=GPS.inp[ind:]
except ValueError:
print ""
GPS.GGA=GPS.inp.split(",") #Split the stream into individual parts
return [GPS.GGA]
#Split the data into individual elements
def vals(self):
time=GPS.GGA[1]
lat=GPS.GGA[2]
lat_ns=GPS.GGA[3]
long=GPS.GGA[4]
long_ew=GPS.GGA[5]
fix=GPS.GGA[6]
sats=GPS.GGA[7]
alt=GPS.GGA[9]
return [time,fix,sats,alt,lat,lat_ns,long,long_ew]
g=GPS()
f=open("gps_data.csv",'w') #Open file to log the data
f.write("name,latitude,longitude\n") #Write the header to the top of the file
ind=0
while True:
try:
x=g.read() #Read from GPS
[t,fix,sats,alt,lat,lat_ns,long,long_ew]=g.vals() #Get the individial values
print "Time:",t,"Fix status:",fix,"Sats in view:",sats,"Altitude",alt,"Lat:",lat,lat_ns,"Long:",long,long_ew
s=str(t)+","+str(float(lat)/100)+","+str(float(long)/100)+"\n"
f.write(s) #Save to file
time.sleep(2)
except IndexError:
print "Unable to read"
except KeyboardInterrupt:
f.close()
print "Exiting"
sys.exit(0)
except:
print "Raw String appears to be empty."

View file

@ -0,0 +1,74 @@
## Using the [Grove GPS Module](http://www.seeedstudio.com/depot/Grove-GPS-p-959.html?cPath=25_130) with the GrovePi
### Setting It Up
On newer versions of the Raspberry Pi, the hardware serial port `/dev/ttyAMAO` which is used in our library, is actually set to be used by the bluetooth module, leaving the software implementation `/dev/ttyS0` (aka mini UART) to the actual pins of the serial line.
The problem with this mini UART is that it's too slow for what we need, so we have to switch them so that the hardware serial points to our serial pins.
To do that, add/modify these lines to `/boot/config.txt`
```bash
dtoverlay=pi3-miniuart-bt
dtoverlay=pi3-disable-bt
enable_uart=1
```
Next, remove the 2 console statements from `/boot/cmdline.txt`.
Initially, `/boot/cmdline.txt` might look this way:
```
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes root wait
```
After you remove the 2 statements, it should be like this:
```
dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes root wait
```
Once you've done these 2 steps from above, a reboot will be required. Do it now, and then proceed to the next section.
For more information on how the serial ports are set up, you can [read this article](https://spellfoundry.com/2016/05/29/configuring-gpio-serial-port-raspbian-jessie-including-pi-3/#Disabling_the_Console).
### Running it
To run the GPS script, you need to have followed the instructions in the previous section and have connected the [Grove GPS Module](http://www.seeedstudio.com/depot/Grove-GPS-p-959.html?cPath=25_130) to the **RPIser** port of the GrovePi.
The script can be either launched with Python 2 or Python 3.
```bash
sudo python dextergps.py
```
or
```bash
sudo python3 dextergps.py
```
The output of any of these 2 commands looks this way:
```bash
['$GPGGA', '150954.000', '4520.7858', 'N', '02557.6659', 'E', '1', '5', '2.84', '76.9', 'M', '36.1', 'M', '', '*6E']
['$GPGGA', '150955.000', '4520.7859', 'N', '02557.6655', 'E', '1', '5', '2.84', '77.0', 'M', '36.1', 'M', '', '*6A']
['$GPGGA', '150956.000', '4520.7861', 'N', '02557.6652', 'E', '1', '5', '2.85', '77.0', 'M', '36.1', 'M', '', '*64']
['$GPGGA', '150957.000', '4520.7861', 'N', '02557.6645', 'E', '1', '4', '2.90', '77.1', 'M', '36.1', 'M', '', '*67']
['$GPGGA', '150958.000', '4520.7861', 'N', '02557.6645', 'E', '1', '4', '2.90', '77.1', 'M', '36.1', 'M', '', '*68']
['$GPGGA', '150959.000', '4520.7861', 'N', '02557.6645', 'E', '1', '4', '2.90', '77.1', 'M', '36.1', 'M', '', '*69']
['$GPGGA', '151000.000', '4520.7861', 'N', '02557.6645', 'E', '1', '4', '2.90', '77.1', 'M', '36.1', 'M', '', '*6D']
['$GPGGA', '151001.000', '4520.7861', 'N', '02557.6645', 'E', '1', '4', '2.90', '77.1', 'M', '36.1', 'M', '', '*6C']
['$GPGGA', '151002.000', '4520.7863', 'N', '02557.6618', 'E', '1', '4', '2.90', '77.5', 'M', '36.1', 'M', '', '*61']
['$GPGGA', '151003.000', '4520.7864', 'N', '02557.6612', 'E', '1', '4', '2.90', '77.6', 'M', '36.1', 'M', '', '*6E']
['$GPGGA', '151004.000', '4520.7865', 'N', '02557.6606', 'E', '1', '4', '2.90', '77.6', 'M', '36.1', 'M', '', '*6D']
['$GPGGA', '151005.000', '4520.7865', 'N', '02557.6597', 'E', '1', '4', '2.90', '77.6', 'M', '36.1', 'M', '', '*67']
['$GPGGA', '151006.000', '4520.7865', 'N', '02557.6588', 'E', '1', '4', '2.90', '77.6', 'M', '36.1', 'M', '', '*6A']
```
### Regarding the Library
**gps.lat** and **gps.NS** go hand in hand, so do **gps.lon** and **gps.EW**
**gps.latitude** and **gps.longitude** are calculated to give you a Google Map appropriate format and make use of negative numbers to indicate either South or West
*Note*:
You would only get good data when fix is 1 and you have 3 or more satellites in view. You might have to take the module near a window with access to open sky for good results
### Old GPS Scripts
`dextergps.py` is the new go-to script for getting values off of the Grove GPS module. The old ones that are no longer used but are kept in here for legacy reasons are:
* [grove_gps_data.py](grove_gps_data.py)
* [grove_gps_hardware_test.py](grove_gps_hardware_test.py)
* [GroveGPS.py](GroveGPS.py)

View file

@ -0,0 +1,168 @@
# Released under the MIT license (http://choosealicense.com/licenses/mit/).
# For more information see https://github.com/DexterInd/GrovePi/blob/master/LICENSE
import grovepi
import serial, time, sys
import re
en_debug = False
def debug(in_str):
if en_debug:
print(in_str)
patterns=["$GPGGA",
"/[0-9]{6}\.[0-9]{2}/", # timestamp hhmmss.ss
"/[0-9]{4}.[0-9]{2,/}", # latitude of position
"/[NS]", # North or South
"/[0-9]{4}.[0-9]{2}", # longitude of position
"/[EW]", # East or West
"/[012]", # GPS Quality Indicator
"/[0-9]+", # Number of satellites
"/./", # horizontal dilution of precision x.x
"/[0-9]+\.[0-9]*/" # altitude x.x
]
class GROVEGPS():
def __init__(self, port='/dev/ttyAMA0', baud=9600, timeout=0):
self.ser = serial.Serial(port, baud, timeout=timeout)
self.ser.flush()
self.raw_line = ""
self.gga = []
self.validation =[] # contains compiled regex
# compile regex once to use later
for i in range(len(patterns)-1):
self.validation.append(re.compile(patterns[i]))
self.clean_data()
# self.get_date() # attempt to gete date from GPS.
def clean_data(self):
'''
clean_data:
ensures that all relevant GPS data is set to either empty string
or -1.0, or -1, depending on appropriate type
This occurs right after initialisation or
after 50 attemps to reach GPS
'''
self.timestamp = ""
self.lat = -1.0 # degrees minutes and decimals of minute
self.NS = ""
self.lon = -1.0
self.EW = ""
self.quality = -1
self.satellites = -1
self.altitude = -1.0
self.latitude = -1.0 #degrees and decimals
self.longitude = -1.0
self.fancylat = "" #
# def get_date(self):
# '''
# attempt to get date from GPS data. So far no luck. GPS does
# not seem to send date sentence at all
# function is unfinished
# '''
# valid = False
# for i in range(50):
# time.sleep(0.5)
# self.raw_line = self.ser.readline().strip()
# if self.raw_line[:6] == "GPZDA": # found date line!
# print (self.raw_line)
def read(self):
'''
Attempts 50 times at most to get valid data from GPS
Returns as soon as valid data is found
If valid data is not found, then clean up data in GPS instance
'''
valid = False
for _ in range(50):
time.sleep(0.5)
self.raw_line = self.ser.readline()
try:
self.line = self.raw_line.decode('utf-8')
self.line = self.line.strip()
except:
self.line = ""
debug(self.line)
if self.validate(self.line):
valid = True
break
if valid:
return self.gga
else:
self.clean_data()
return []
def validate(self, in_line):
'''
Runs regex validation on a GPGAA sentence.
Returns False if the sentence is mangled
Return True if everything is all right and sets internal
class members.
'''
if in_line == "":
return False
if in_line[:6] != "$GPGGA":
return False
self.gga = in_line.split(",")
debug (self.gga)
#Sometimes multiple GPS data packets come into the stream. Take the data only after the last '$GPGGA' is seen
try:
ind=self.gga.index('$GPGGA', 5, len(self.gga))
self.gga=self.gga[ind:]
except ValueError:
pass
if len(self.gga) != 15:
debug ("Failed: wrong number of parameters ")
debug (self.gga)
return False
for i in range(len(self.validation)-1):
if len(self.gga[i]) == 0:
debug ("Failed: empty string %d"%i)
return False
test = self.validation[i].match(self.gga[i])
if test == False:
debug ("Failed: wrong format on parameter %d"%i)
return False
else:
debug("Passed %d"%i)
try:
self.timestamp = self.gga[1]
self.lat = float(self.gga[2])
self.NS = self.gga[3]
self.lon = float(self.gga[4])
self.EW = self.gga[5]
self.quality = int(self.gga[6])
self.satellites = int(self.gga[7])
self.altitude = float(self.gga[9])
self.latitude = self.lat // 100 + self.lat % 100 / 60
if self.NS == "S":
self.latitude = - self.latitude
self.longitude = self.lon // 100 + self.lon % 100 / 60
if self.EW == "W":
self.longitude = -self.longitude
except ValueError:
debug( "FAILED: invalid value")
return True
if __name__ =="__main__":
gps = GROVEGPS()
while True:
time.sleep(1)
in_data = gps.read()
if in_data != []:
print (in_data)

View file

@ -0,0 +1,192 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove GPS Module http://www.seeedstudio.com/depot/Grove-GPS-p-959.html?cPath=25_130
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
# History
# ------------------------------------------------
# Author Date Comments
# Karan 21 Aug 14 Initial Authoring
# Karan 10 June 15 Updated the code to reflect the decimal GPS coordinates (contributed by rschmidt on the DI forums: http://www.dexterindustries.com/forum/?topic=gps-example-questions/#post-5668)
# Karan 18 Mar 16 Updated code to handle conditions where no fix from satellite
#
#
#####################################################
#
# GPS SENSOR GOES INTO RPISER PORT
#
#####################################################
#
import serial, time
import smbus
import math
import RPi.GPIO as GPIO
import struct
import sys
import ir_receiver_check
enable_debug=1
enable_save_to_file=0
if ir_receiver_check.check_ir():
print("Disable IR receiver before continuing")
exit()
ser = serial.Serial('/dev/ttyAMA0', 9600, timeout = 0) #Open the serial port at 9600 baud
ser.flush()
def cleanstr(in_str):
out_str = "".join([c for c in in_str if c in "0123456789.-" ])
if len(out_str)==0:
out_str = "-1"
return out_str
def safefloat(in_str):
try:
out_str = float(in_str)
except ValueError:
out_str = -1.0
return out_str
class GPS:
#The GPS module used is a Grove GPS module http://www.seeedstudio.com/depot/Grove-GPS-p-959.html
inp=[]
# Refer to SIM28 NMEA spec file http://www.seeedstudio.com/wiki/images/a/a0/SIM28_DATA_File.zip
GGA=[]
#Read data from the GPS
def read(self):
while True:
GPS.inp=ser.readline()
if GPS.inp[:6] =='$GPGGA': # GGA data , packet 1, has all the data we need
break
time.sleep(0.1) #without the cmd program will crash
try:
ind=GPS.inp.index('$GPGGA',5,len(GPS.inp)) #Sometimes multiple GPS data packets come into the stream. Take the data only after the last '$GPGGA' is seen
GPS.inp=GPS.inp[ind:]
except ValueError:
print ("")
GPS.GGA=GPS.inp.split(",") #Split the stream into individual parts
return [GPS.GGA]
#Split the data into individual elements
def vals(self):
if enable_debug:
print(GPS.GGA)
time=GPS.GGA[1]
if GPS.GGA[2]=='': # latitude. Technically a float
lat =-1.0
else:
lat=safefloat(cleanstr(GPS.GGA[2]))
if GPS.GGA[3]=='': # this should be either N or S
lat_ns=""
else:
lat_ns=str(GPS.GGA[3])
if GPS.GGA[4]=='': # longitude. Technically a float
long=-1.0
else:
long=safefloat(cleanstr(GPS.GGA[4]))
if GPS.GGA[5]=='': # this should be either W or E
long_ew=""
else:
long_ew=str(GPS.GGA[5])
fix=int(cleanstr(GPS.GGA[6]))
sats=int(cleanstr(GPS.GGA[7]))
if GPS.GGA[9]=='':
alt=-1.0
else:
# change to str instead of float
# 27"1 seems to be a valid value
alt=str(GPS.GGA[9])
return [time,fix,sats,alt,lat,lat_ns,long,long_ew]
# Convert to decimal degrees
def decimal_degrees(self, raw_degrees):
try:
degrees = float(raw_degrees) // 100
d = float(raw_degrees) % 100 / 60
return degrees + d
except:
return raw_degrees
if __name__ == "__main__":
g=GPS()
if enable_save_to_file:
f=open("gps_data.csv",'w') #Open file to log the data
f.write("name,latitude,longitude\n") #Write the header to the top of the file
ind=0
while True:
time.sleep(0.01)
try:
x=g.read() #Read from GPS
[t,fix,sats,alt,lat,lat_ns,longitude,long_ew]=g.vals() #Get the individial values
# Convert to decimal degrees
if lat !=-1.0:
lat = g.decimal_degrees(safefloat(lat))
if lat_ns == "S":
lat = -lat
if longitude !=-1.0:
longitude = g.decimal_degrees(safefloat(longitude))
if long_ew == "W":
longitude = -longitude
# print ("Time:",t,"Fix status:",fix,"Sats in view:",sats,"Altitude",alt,"Lat:",lat,lat_ns,"Long:",long,long_ew)
try:
print("Time\t\t: %s\nFix status\t: %d\nSats in view\t: %d\nAltitude\t: %s\nLat\t\t: %f\nLong\t\t: %f") %(t,fix,sats,alt,lat,longitude)
except:
print("Time\t\t: %s\nFix status\t: %s\nSats in view\t: %s\nAltitude\t: %s\nLat\t\t: %s\nLong\t\t: %s") %(t,str(fix),str(sats),str(alt),str(lat),str(longitude))
s=str(t)+","+str(safefloat(lat)/100)+","+str(safefloat(longitude)/100)+"\n"
if enable_save_to_file:
f.write(s) #Save to file
time.sleep(2)
except IndexError:
print ("Unable to read")
except KeyboardInterrupt:
if enable_save_to_file:
f.close()
print ("Exiting")
sys.exit(0)

View file

@ -0,0 +1,85 @@
#!/usr/bin/env python
########################################################################
# This example is for is the simplest GPS Script. It reads the
# raw output of the GPS sensor on the GoPiGo or GrovePi and prints it.
#
# GPS SENSOR GOES INTO RPISER PORT
#
#####################################################
#
# http://www.dexterindustries.com/GoPiGo/
# http://www.dexterindustries.com/GrovePi/
# History
# ------------------------------------------------
# Author Date Comments
# John 2/25/2015 Initial Authoring
# John 6/17/2016 Add some comments.
#
# These files have been made available online through a Creative Commons Attribution-ShareAlike 3.0 license.
# (http://creativecommons.org/licenses/by-sa/3.0/)
#
########################################################################
import serial, time
import smbus
import math
import RPi.GPIO as GPIO
import struct
import sys
import ir_receiver_check
if ir_receiver_check.check_ir():
print("Disable IR receiver before continuing")
exit()
ser = serial.Serial('/dev/ttyAMA0', 9600, timeout = 0) #Open the serial port at 9600 baud
ser.flush()
def readlineCR():
rv = ""
while True:
time.sleep(0.01) # This is the critical part. A small pause
# works really well here.
ch = ser.read()
rv += ch
if ch=='\r' or ch=='':
return rv
while True:
#readlineCR()
x=readlineCR()
print(x)
########################################################################
#
# The output should look like something below.
#
#
########################################################################
'''
$GPGGA,001929.799,,,,,0,0,,,M,,M,,*4C
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,1,1,00*79
$GPRMC,001929.799,V,,,,,0.00,0.00,060180,,,N*46
$GPGGA,001930.799,,,,,0,0,,,M,,M,,*44
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,1,1,00*79
$GPRMC,001930.799,V,,,,,0.00,0.00,060180,,,N*4E
$GPGGA,001931.799,,,,,0,0,,,M,,M,,*45
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,1,1,00*79
$GPRMC,001931.799,V,,,,,0.00,0.00,060180,,,N*4F
$GPGGA,001932.799,,,,,0,0,,,M,,M,,*46
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,1,1,00*79
$GPRMC,001932.799,V,,,,,0.00,0.00,060180,,,N*4C
$GPGGA,001933.799,,,,,0,0,,,M,,M,,*47
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,1,1,00*79
$GPRMC,001933.799,V,,,,,0.00,0.00,060180,,,N*4D
$GPGGA,001934.799,,,,,0,0,,,M,,M,,*40
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,1,1,00*79
$GPRMC,001934.799,V,,,,,0.00,0.00,060180,,,N*4A
$GPGGA,001935.799,,,,,0,0,,,M,,M,,*41
'''

View file

@ -0,0 +1,62 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove HCHO Sensor (http://www.seeedstudio.com/wiki/Grove_-_HCHO_Sensor)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
import grovepi
# The sensitivity can be adjusted by the onboard potentiometer
# Connect the Grove HCHO Sensor to analog port A0
# SIG,NC,VCC,GND
hcho_sensor = 0
grovepi.pinMode(hcho_sensor,"INPUT")
# Vcc of the grove interface is normally 5v
grove_vcc = 5
while True:
try:
# Get sensor value
sensor_value = grovepi.analogRead(hcho_sensor)
# Calculate voltage
voltage = (float)(sensor_value * grove_vcc / 1024)
print("sensor_value =", sensor_value, " voltage =", voltage)
time.sleep(.5)
except IOError:
print ("Error")

View file

@ -0,0 +1,55 @@
## Calibrating the Grove High Temperature sensor
##### Attention:
This `README.md` is only for calibrating the probe and not the onboard sensor. So, this sensor comes with 2 thermometers:
1. One which is for measuring room temperatures - that's found on the sensor's board.
2. Another one which is for measuring temperatures between `-50 °C` and `+650 °C` - it's the long metal wire. **This is the one we're calibrating.**
## Step 1
Make the `GrovePi` continously read an analog port and print the values in the console. The analog port should be that of the `Grove High Temperature Sensor's`.
## Step 2
Put the sensor's long wire into a cup of boiling/hot water and take note of the value that's printed in the `Raspberry Pi`'s console. At the same time, use a professional thermometer and measure the temperature and write it down.
Do the same thing with cold water.
## Step 3
We will now have 4 values written down in a note:
* 2 values that were printed in the `Raspberry Pi`'s console - these values correspond with the following 2 values.
* 2 values where the measurement unit is in `Celsius Degrees` - measured with the professional thermometer.
Now, take the values that were measured with the professional thermometer and get them translated with the table provided in `thermocouple_table.json` file.
I.e: In `thermocouple_table.json` file, `90 °C` corresponds to `3.682`.
Now, lets assign the following values to each of these variables:
* `i1` = the translated value (from the table) we got when we measured the hot water w/ the **professional thermometer**.
* `i2` = the translated value (from the table) we got when we measured the cold water w/ the **professional thermometer**.
* `o1` = the value we got in our console when we measured the hot water w/ **our GrovePi**.
* `o2` = the value we got in our console when we measured the cold water w/ **our GrovePi**.
## Step 4
Let's calculate an `offset` and a `factor`. We will insert the calculated values in our table (`thermocouple_table.json` file).
First, lets calculated the `offset`.
* `offset` = `(o1 * i2 - i1 * o2) / (i2 - i1)`
And then, we get to calculate the `factor`. Use the `offset` value for calculating the `factor`.
* `factor` = `(o1 - offset) / i1`
## Step 5
Open up `thermocouple_table.json` file and update the following values:
* For `amp_offset` set the value we got for `offset` - it's preferable to have up to 6-7 digits in precision.
* For `amp_factor` set the value we got for `factor` - it's preferable to have up to 6-7 digits in precision.
Save the modifications.
## Step 6
Run the `high_temperature_example.py` program.
It's going to use the newly updated values.
------
###### `Note 1`: Calibrate the sensor when the values don't match with a professional thermometer by a long shot (i.e. 10 degrees). The sensor has already been calibrated, but who knows.
###### `Note 2`: The sensor's precision is around `+-3 Celsius Degrees`.

View file

@ -0,0 +1,120 @@
# Released under the MIT license (http://choosealicense.com/licenses/mit/).
# For more information see https://github.com/DexterInd/GrovePi/blob/master/LICENSE
import grovepi
import math
import json
import numpy as np
from scipy.interpolate import interp1d
# Library written for Python 3!
# take a look in the datasheet
# http://www.mouser.com/catalog/specsheets/Seeed_111020002.pdf
# class for the K-Type temperature sensor (w/ long probe/sonde)
class HighTemperatureSensor:
# initialize the object with the appropriate sensor pins on the GrovePi and configuration JSON
def __init__(self, _temperature_pin, _thermocouple_pin, _json_path = None):
if(_json_path is None):
_json_path = 'thermocouple_table.json'
try:
with open(_json_path) as table_file:
table = json.load(table_file)
self.__interpolateTable(table)
self.__amp_av = table["amp_factor"]
self.__vol_offset = table["amp_offset"]
except:
self.sensor_table = None
self.__amp_av = 1
self.__vol_offset = 1
self.voltage_to_degrees_table = None
# save the variables inside the object
self.temperature_pin = _temperature_pin
self.thermocouple_pin = _thermocouple_pin
# set the pins as INPUT
# this sensor outputs analog values so you can
# use one of the 3 analog ports on the GrovePi
grovepi.pinMode(self.temperature_pin, "INPUT")
grovepi.pinMode(self.thermocouple_pin, "INPUT")
# function for retrieving the room temperature_pin
# if values exceed what's written in the datasheet
# then it throws a ValueError exception
def getRoomTemperature(self):
# ratio for translating from 3.3V to 5.0V (what we read is in the range of 0 -> 3.3V)
voltage_ratio = 5.0 / 3.3
# and multiply what we read by that ratio
# and read it for about 12 times -> this way we get smoother readings
# the reason we average it is because the table we provided isn't big enough
# and as a consequence you'd get values like (20 degrees, 24 degrees and so on)
analog_sum = 0
for step in range(12):
analog_sum += grovepi.analogRead(self.temperature_pin)
pass
analog_value = (analog_sum / 12) * voltage_ratio
# see the datasheet for more information
try:
calculated_resistance = (1023 - analog_value) * 10000 / analog_value
calculated_temperature = 1 / (math.log(calculated_resistance / 10000) / 3975 + 1 / 298.15) - 273.15
# if the values exceed a certain threshold
# then raise a ValueError exception
if not (calculated_temperature >= -50.0 and calculated_temperature <= 145.0):
raise ValueError('temperature out of range')
# and return what we got calculated
return calculated_temperature
except ZeroDivisionError:
return 0
# function for retrieving the temperature at the tip of the probe / sonde
# only the temperature of the tip of the probe is measured
# the rest of the K-Type sensor is for reaching the hot environment you want to measure
# so you don't get burned
def getProbeTemperature(self):
if not self.voltage_to_degrees_table is None:
probe_tip_voltage = self.__getThermocoupleVoltage()
degrees_from_table = self.voltage_to_degrees_table(probe_tip_voltage)
return float(degrees_from_table)
else:
return None
# private function which can't be accessed from the outside
# this is an imperitave solution - it was found through experiments
# basically it calculates the voltage of the K-type sensor
# before it gets into the amplifier - so the voltage is between -6.48 mV to 54.9 mV
def __getThermocoupleVoltage(self):
analog_value = grovepi.analogRead(self.thermocouple_pin);
probe_tip_voltage = (analog_value - self.__vol_offset) / self.__amp_av
return probe_tip_voltage
# function for interpolating values from [table] array
def __interpolateTable(self, table):
degrees_keys_list = list(table["degrees_table"].keys())
degrees_list = [int(x) for x in degrees_keys_list]
voltages_list = []
for degrees in degrees_keys_list:
voltage_corespondent = table["degrees_table"][degrees]
voltages_list.append(voltage_corespondent)
self.voltage_to_degrees_table = interp1d(voltages_list, degrees_list)

View file

@ -0,0 +1,83 @@
#!/usr/bin/env python3
# -*- coding: utf8 -*-
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import grove_hightemperature_sensor as grovepi # our library
from time import sleep # and for the sleep function
import sys # we need this for the exception throwing stuff
# Don't forget to run it with Python 3 !!
# Don't forget to run it with Python 3 !!
# Don't forget to run it with Python 3 !!
def Main():
room_temperature_pin = 15 # this is equal to A1
probe_temperature_pin = 14 # this is equal to A0
# so you have to connect the sensor to A0 port
# instatiate a HighTemperatureSensor object
sensor = grovepi.HighTemperatureSensor(room_temperature_pin, probe_temperature_pin)
# and do this indefinitely
while True:
# read the room temperature
room_temperature = sensor.getRoomTemperature()
# and also what's important to us: the temperature at the tip of the K-Type sensor
probe_temperature = sensor.getProbeTemperature()
# print it in a fashionable way
print('[room temperature: {:5.2f}°C][probe temperature: {:5.2f}°C]'.format(room_temperature, probe_temperature))
# and wait for 250 ms before taking another measurement - so we don't overflow the terminal
sleep(0.25)
if __name__ == "__main__":
try:
Main()
# in case CTRL-C / CTRL-D keys are pressed (or anything else that might interrupt)
except KeyboardInterrupt:
print('[Keyboard interrupted]')
sys.exit(0)
# in case there's an IO error aka I2C
except IOError:
print('[IO Error]')
sys.exit(0)
# in case we have a math error (like division by 0 - can happen depending on the read values)
# or if the values exceed a certain threshold
# experiment and you'll see
except ValueError as e:
print('[{}]'.format(str(e)))
sys.exit(0)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,49 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove I2C 3-axis Accelerometer (http://www.seeedstudio.com/wiki/Grove_-_3-Axis_Digital_Accelerometer(%C2%B11.5g))
# Find more here: http://www.seeedstudio.com/depot/Grove-3Axis-Digital-Accelerometer16g-p-1156.html
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
import grovepi
# Connect the Grove Accelerometer (+/- 1.5g) to any I2C port eg. I2C-1
# Can be found at I2C address 0x4c
# SCL,SDA,VCC,GND
while True:
try:
print(grovepi.acc_xyz())
time.sleep(.5)
except IOError:
print ("Error")

View file

@ -0,0 +1,5 @@
Grove I2C ADC
==============
Raspberry Pi Python i2c library for Grove I2C ADC (http://www.seeedstudio.com/depot/Grove-I2C-ADC-p-1580.html)
Grove - I2C ADC is a 12-bit precision ADC module based on ADC121C021. It helps you increase the accuracy of value collected from analog sensor by providing a constant reference voltage. Because its address is changeable, you can use up to 9 I2C ADC at the same time at most

View file

@ -0,0 +1,49 @@
#!/usr/bin/env python
#
# GrovePi Library for using the Grove - I2C ADC(http://www.seeedstudio.com/depot/Grove-I2C-ADC-p-1580.html)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this library? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
# Released under the MIT license (http://choosealicense.com/licenses/mit/).
# For more information see https://github.com/DexterInd/GrovePi/blob/master/LICENSE
import time,sys
import RPi.GPIO as GPIO
import smbus
# use the bus that matches your raspi version
rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
bus = smbus.SMBus(1)
else:
bus = smbus.SMBus(0)
class ADC:
address = None
REG_ADDR_RESULT = 0x00
REG_ADDR_ALERT = 0x01
REG_ADDR_CONFIG = 0x02
REG_ADDR_LIMITL = 0x03
REG_ADDR_LIMITH = 0x04
REG_ADDR_HYST = 0x05
REG_ADDR_CONVL = 0x06
REG_ADDR_CONVH = 0x07
def __init__(self,address=0x55):
self.address=address
bus.write_byte_data(self.address, self.REG_ADDR_CONFIG,0x20)
def adc_read(self):
data=bus.read_i2c_block_data(self.address, self.REG_ADDR_RESULT, 2)
raw_val=(data[0]&0x0f)<<8 | data[1]
return raw_val
if __name__ == "__main__":
adc= ADC()
while True:
print(adc.adc_read())
time.sleep(.5)

View file

@ -0,0 +1,45 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove - I2C ADC(http://www.seeedstudio.com/depot/Grove-I2C-ADC-p-1580.html)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import grove_i2c_adc
import time
# You can initialize with a different address too: grove_i2c_adc.ADC(address=0x56)
adc= grove_i2c_adc.ADC()
while True:
#Print the 12 bit value from the I2C ADC
print(adc.adc_read())
time.sleep(.5)

View file

@ -0,0 +1,47 @@
import time
import grove_i2c_color_sensor
# Open connection to sensor
color_sensor = grove_i2c_color_sensor.GroveI2CColorSensor()
# Perform continuous integration with predefined duration of 100ms
color_sensor.use_continuous_integration(100)
# Set gain to 16x
color_sensor.set_gain_and_prescaler(16)
# Start integration
color_sensor.start_integration()
time.sleep(.1)
if color_sensor.is_integration_complete():
print ("Continuous integration complete. Read color:")
color = color_sensor.read_rgbc()
print("RGB: {},{},{} - Clear {}".format(color[0], color[1], color[2], color[3]))
color = color_sensor.read_xy()
print("xy: {},{}".format(color[0], color[1]))
color = color_sensor.read_color_name()
print("Closest color match: {}".format(color))
else:
print("Continuous integration incomplete")
# Stop integration before changing settings
color_sensor.stop_integration()
# Perform manual integration
color_sensor.use_manual_integration()
# Set gain to 4x
color_sensor.set_gain_and_prescaler(4)
# Integrate during 200ms
color_sensor.start_integration()
time.sleep(0.2)
color_sensor.stop_integration()
if color_sensor.is_integration_complete():
print ("Manual integration complete. Read color:")
color = color_sensor.read_rgbc()
print("RGB: {},{},{} - Clear {}".format(color[0], color[1], color[2], color[3]))
color = color_sensor.read_xy()
print("xy: {},{}".format(color[0], color[1]))
color = color_sensor.read_color_name()
print("Closest color match: {}".format(color))
else:
print("Manual integration incomplete")

View file

@ -0,0 +1,326 @@
import smbus
import time
import math
import RPi.GPIO
# Released under the MIT license (http://choosealicense.com/licenses/mit/).
# For more information see https://github.com/DexterInd/GrovePi/blob/master/LICENSE
class GroveI2CColorSensor:
""" Provides access to the Grove I2C color sensor from Seeedstudio.
This library supports 2 of the operating modes of the sensor:
- Continuous, back-to-back color measures ('integrations') of pre-defined durations
- Single measure of arbitrary duration
The other sensor operating modes (using an external SYNC pin, interrupts...) which are not supported by this
library.
Usage:
1. Use either use_continuous_integration() or use_manual_integration() to select operating mode
2. If necessary, adjust gain and prescaler to obtain a color measure of sufficient precision without saturating the
sensor.
3. Start integration using start_integration()
4. In manual integration mode: use stop_integration() after the desired duration
5. Use one of the read functions to get the measured color value
Reference documentation:
- Seeedstudio wiki: http://www.seeedstudio.com/wiki/index.php?title=Twig_-_I2C_Color_Sensor_v0.9b
- TCS3414-A Datasheet: http://www.seeedstudio.com/wiki/File:TCS3404_TCS3414-A.pdf
"""
# Common colors coordinates (CIE xy and RGB)
COLOR_TABLE = {"Red": {"x": 0.64, "y": 0.33, "r": 255, "g": 0, "b": 0},
"Green": {"x": 0.3, "y": 0.6, "r": 0, "g": 255, "b": 0},
"Blue": {"x": 0.15, "y": 0.06, "r": 0, "g": 0, "b": 255},
"Yellow": {"x": 0.419, "y": 0.505, "r": 255, "g": 255, "b": 0},
"Magenta": {"x": 0.321, "y": 0.154, "r": 255, "g": 0, "b": 255},
"Cyan": {"x": 0.225, "y": 0.329, "r": 0, "g": 255, "b": 255},
"Deep pink": {"x": 0.466, "y": 0.238, "r": 255, "g": 20, "b": 147},
"Orange": {"x": 0.5, "y": 0.441, "r": 255, "g": 165, "b": 0},
"Saddle brown": {"x": 0.526, "y": 0.399, "r": 139, "g": 69, "b": 19},
"Grey / White": {"x": 0.313, "y": 0.329, "r": 255, "g": 255, "b": 255},
"Black": {"x": 0, "y": 0, "r": 0, "g": 0, "b": 0}}
# Sensor address on SMBus / I2C bus
_I2C_SENSOR_ADDRESS = 0X39
# Sensor registers addresses
_REGISTER_COMMAND = 0X80
_REGISTER_CONTROL = _REGISTER_COMMAND | 0X00
_REGISTER_TIMING = _REGISTER_COMMAND | 0X01
_REGISTER_INTERRUPT_CONTROL = _REGISTER_COMMAND | 0X02
_REGISTER_INT_SOURCE = _REGISTER_COMMAND | 0X03
_REGISTER_ID = _REGISTER_COMMAND | 0X04
_REGISTER_GAIN = _REGISTER_COMMAND | 0X07
_REGISTER_INTERRUPT_LOW_THRESH_LOW_BYTE = _REGISTER_COMMAND | 0X08
_REGISTER_INTERRUPT_LOW_THRESH_HIGH_BYTE = _REGISTER_COMMAND | 0X09
_REGISTER_INTERRUPT_HIGH_THRESH_LOW_BYTE = _REGISTER_COMMAND | 0X0A
_REGISTER_INTERRUPT_HIGH_THRESH_HIGH_BYTE = _REGISTER_COMMAND | 0X0B
_REGISTER_DATA_GREEN_LOW = _REGISTER_COMMAND | 0X10
_REGISTER_DATA_GREEN_HIGH = _REGISTER_COMMAND | 0X11
_REGISTER_DATA_RED_LOW = _REGISTER_COMMAND | 0X012
_REGISTER_DATA_RED_HIGH = _REGISTER_COMMAND | 0X13
_REGISTER_DATA_BLUE_LOW = _REGISTER_COMMAND | 0X14
_REGISTER_DATA_BLUE_HIGH = _REGISTER_COMMAND | 0X15
_REGISTER_DATA_CLEAR_LOW = _REGISTER_COMMAND | 0X16
_REGISTER_DATA_CLEAR_HIGH = _REGISTER_COMMAND | 0X17
_REGISTER_INTERRUPT_CLEAR = _REGISTER_COMMAND | 0X60
# Values for control register
_CONTROL_ADC_IS_VALID = 0X10
_CONTROL_ADC_ENABLE = 0X02
_CONTROL_ADC_DISABLE = 0X00
_CONTROL_ADC_POWER_ON = 0X01
_CONTROL_ADC_POWER_OFF = 0X00
# Values for timing register
_TIMING_SYNC_EDGE = 0X40
_TIMING_INTEGRATION_MODE_CONTINUOUS = 0X00
_TIMING_INTEGRATION_MODE_MANUAL = 0X10
_TIMING_INTEGRATION_MODE_SYNC_SINGLE_PULSE = 0X20
_TIMING_INTEGRATION_MODE_SYNC_MULTIPLE_PULSE = 0X30
_TIMING_PARAM_INTEGRATION_TIME_12MS = 0X00
_TIMING_PARAM_INTEGRATION_TIME_100MS = 0X01
_TIMING_PARAM_INTEGRATION_TIME_400MS = 0X02
_TIMING_PARAM_SYNC_PULSE_COUNT_1 = 0X00
_TIMING_PARAM_SYNC_PULSE_COUNT_2 = 0X01
_TIMING_PARAM_SYNC_PULSE_COUNT_4 = 0X02
_TIMING_PARAM_SYNC_PULSE_COUNT_8 = 0X03
_TIMING_PARAM_SYNC_PULSE_COUNT_16 = 0X04
_TIMING_PARAM_SYNC_PULSE_COUNT_32 = 0X05
_TIMING_PARAM_SYNC_PULSE_COUNT_64 = 0X06
_TIMING_PARAM_SYNC_PULSE_COUNT_128 = 0X07
_TIMING_PARAM_SYNC_PULSE_COUNT_256 = 0X08
# Values for interrupt control register
_INTERRUPT_CONTROL_MODE_DISABLE = 0X00
_INTERRUPT_CONTROL_MODE_LEVEL = 0X10
_INTERRUPT_CONTROL_MODE_SMB_ALERT = 0x20
_INTERRUPT_CONTROL_PERSIST_EVERY_CYCLE = 0X00
_INTERRUPT_CONTROL_PERSIST_OUTSIDE_RANGE_ONCE = 0X01
_INTERRUPT_CONTROL_PERSIST_OUTSIDE_RANGE_100MS = 0X02
_INTERRUPT_CONTROL_PERSIST_OUTSIDE_RANGE_1000MS = 0X03
# Values for interrupt source register
_INTERRUPT_SOURCE_GREEN = 0X00
_INTERRUPT_SOURCE_RED = 0X01
_INTERRUPT_SOURCE_BLUE = 0X10
_INTERRUPT_SOURCE_CLEAR = 0X03
# Values for gain register
_GAIN_1X = 0X00
_GAIN_4X = 0X10
_GAIN_16X = 0X20
_GAIN_64X = 0X30
_PRESCALER_1 = 0X00
_PRESCALER_2 = 0X01
_PRESCALER_4 = 0X02
_PRESCALER_8 = 0X03
_PRESCALER_16 = 0X04
_PRESCALER_32 = 0X05
_PRESCALER_64 = 0X06
# Wait time introduced after each register write (except integration start)
_SLEEP_VALUE = 0.05
def __init__(self, bus_number=None):
"""Initialize i2c communication with the sensor and sets default parameters.
Default parameters: continuous integration (not started) with 12ms cycles, gain 1x, pre-scale 1.
:param bus_number: the i2c bus number (usually 0 or 1, depending on the hardware). Use the i2cdetect command
line tool to identify the right bus. If set to None, will use the Raspberry Pi revision number to guess which
bus to use.
"""
if bus_number is None:
# Use Rasbperry Pi revision to choose bus number
board_revision = RPi.GPIO.RPI_REVISION
if board_revision == 2 or board_revision == 3:
bus_number = 1
else:
bus_number = 0
self.bus = smbus.SMBus(bus_number)
self.use_continuous_integration()
self.set_gain_and_prescaler(1, 1)
def use_continuous_integration(self, integration_time_in_ms=12):
"""Configure the sensor to perform continuous, back-to-back integrations of pre-defined duration.
Continuous integration will begin after calling start_integration() and will stop after calling
stop_integration().
:param integration_time_in_ms: supported values in ms are 12, 100 and 400.
"""
assert integration_time_in_ms == 12 \
or integration_time_in_ms == 100 \
or integration_time_in_ms == 400, \
"Continuous integration supports only 12ms, 100ms or 400ms integration durations"
# Convert integration time value into the corresponding byte values expected by the sensor.
if integration_time_in_ms == 12:
integration_time_reg = self._TIMING_PARAM_INTEGRATION_TIME_12MS
elif integration_time_in_ms == 100:
integration_time_reg = self._TIMING_PARAM_INTEGRATION_TIME_100MS
elif integration_time_in_ms == 400:
integration_time_reg = self._TIMING_PARAM_INTEGRATION_TIME_400MS
else:
integration_time_reg = self._TIMING_PARAM_INTEGRATION_TIME_12MS
self.bus.write_i2c_block_data(self._I2C_SENSOR_ADDRESS,
self._REGISTER_TIMING,
[self._TIMING_INTEGRATION_MODE_CONTINUOUS | integration_time_reg])
time.sleep(self._SLEEP_VALUE)
def use_manual_integration(self):
"""Configure the sensor to perform a single integration manually started and stopped.
Manual integration will begin after calling start_integration(), and will stop after calling stop_integration().
"""
self.bus.write_i2c_block_data(self._I2C_SENSOR_ADDRESS,
self._REGISTER_TIMING,
[self._TIMING_INTEGRATION_MODE_MANUAL])
time.sleep(self._SLEEP_VALUE)
def set_gain_and_prescaler(self, gain_multiplier=1, prescaler_divider=1):
"""Configure the sensor gain and prescaler.
:param gain_multiplier: Gain sets the sensibility of the sensor, effectively extending the dynamic range of the
sensor but eventually inducing saturation. Supported values are 1, 4, 16 and 64.
:param prescaler_divider: Prescaler scales the values by dividing them before storage in the output registers,
hence reducing saturation at the cost of reducing measurement precision. Supported prescaler dividers are 1, 2,
4, 8, 16, 32 and 64.
"""
assert gain_multiplier == 1 or gain_multiplier == 4 or gain_multiplier == 16 or gain_multiplier == 64, \
"Supported gain multipliers: 1, 4, 16 and 64"
assert prescaler_divider == 1 \
or prescaler_divider == 2 \
or prescaler_divider == 4 \
or prescaler_divider == 8 \
or prescaler_divider == 16 \
or prescaler_divider == 32 \
or prescaler_divider == 64, \
"Supported prescaler dividers: 1, 2, 4, 8, 16, 32 and 64"
# Convert gain multiplier into the corresponding byte values expected by the sensor.
if gain_multiplier == 1:
gain_reg = self._GAIN_1X
elif gain_multiplier == 4:
gain_reg = self._GAIN_4X
elif gain_multiplier == 16:
gain_reg = self._GAIN_16X
elif gain_multiplier == 64:
gain_reg = self._GAIN_64X
else:
gain_reg = self._GAIN_1X
# Convert prescaler divider into the corresponding byte values expected by the sensor.
if prescaler_divider == 1:
prescaler_reg = self._PRESCALER_1
elif prescaler_divider == 2:
prescaler_reg = self._PRESCALER_2
elif prescaler_divider == 4:
prescaler_reg = self._PRESCALER_4
elif prescaler_divider == 8:
prescaler_reg = self._PRESCALER_8
elif prescaler_divider == 16:
prescaler_reg = self._PRESCALER_16
elif prescaler_divider == 32:
prescaler_reg = self._PRESCALER_32
elif prescaler_divider == 64:
prescaler_reg = self._PRESCALER_64
else:
prescaler_reg = self._PRESCALER_1
self.bus.write_i2c_block_data(self._I2C_SENSOR_ADDRESS, self._REGISTER_GAIN, [gain_reg | prescaler_reg])
time.sleep(self._SLEEP_VALUE)
def start_integration(self):
"""Start the integration.
"""
self.bus.write_i2c_block_data(
self._I2C_SENSOR_ADDRESS,
self._REGISTER_CONTROL,
[self._CONTROL_ADC_ENABLE | self._CONTROL_ADC_POWER_ON])
def stop_integration(self):
"""Stop the integration.
"""
self.bus.write_i2c_block_data(
self._I2C_SENSOR_ADDRESS,
self._REGISTER_CONTROL,
[self._CONTROL_ADC_DISABLE | self._CONTROL_ADC_POWER_ON])
def is_integration_complete(self):
""" Checks if an integration has been successfully completed and color data is ready to be read.
:return: True if integration is completed.
"""
integration_status = self.bus.read_i2c_block_data(self._I2C_SENSOR_ADDRESS, self._REGISTER_CONTROL, 1)
return integration_status[0] & self._CONTROL_ADC_IS_VALID == self._CONTROL_ADC_IS_VALID
def read_rgbc_word(self):
""" Reads the measured color, split over 4 channels: red, green, blue, clear.
Each value is provided as a word.
:return: a (r,g,b,c) tuple of the 4 word values measured by the red/green/blue/clear channels
"""
# Integration result registers are 8 consecutive bytes starting by lower value of green channel.
# Reading them in a single pass.
raw_color = self.bus.read_i2c_block_data(self._I2C_SENSOR_ADDRESS, self._REGISTER_DATA_GREEN_LOW, 8)
return (raw_color[2] + raw_color[3] * 256,
raw_color[0] + raw_color[1] * 256,
raw_color[4] + raw_color[5] * 256,
raw_color[6] + raw_color[7] * 256)
def read_rgbc(self):
""" Reads the measured color, split over 4 channels: red, green, blue, clear (unfiltered).
Each value is provided as a byte.
:return: a (r,g,b,c) tuple of the 4 byte values measured by the red/green/blue/clear channels
"""
# Integration result registers are 8 consecutive bytes starting by lower value of green channel.
# Reading them in a single pass.
raw_color = self.bus.read_i2c_block_data(self._I2C_SENSOR_ADDRESS, self._REGISTER_DATA_GREEN_LOW, 8)
# Discard lower byte of each channel
return (raw_color[3],
raw_color[1],
raw_color[5],
raw_color[7])
def read_xy(self):
""" Reads the measured color and converts it as CIE x,y coordinates.
See http://www.techmind.org/colour/ and https://en.wikipedia.org/wiki/CIE_1931_color_space for more information.
:return: a (x, y) tuple
"""
rgbc = self.read_rgbc_word()
x_bar = -0.14282 * rgbc[0] + 1.54924 * rgbc[1] + -0.95641 * rgbc[2]
y_bar = -0.32466 * rgbc[0] + 1.57837 * rgbc[1] + -0.73191 * rgbc[2]
z_bar = -0.68202 * rgbc[0] + 0.77073 * rgbc[1] + 0.563320 * rgbc[2]
x = x_bar / (x_bar + y_bar + z_bar)
y = y_bar / (x_bar + y_bar + z_bar)
return [x, y]
def read_color_name(self):
""" Reads the measured color and maps it to the nearest color present in COLOR_TABLE.
Warning: current implementation does not work well with white / grey / black or dark colors.
:return: The color name used as a key in COLOR_TABLE.
"""
xy = self.read_xy()
closest_color = None
closest_distance = 1
for current_color in self.COLOR_TABLE:
current_coordinates = self.COLOR_TABLE[current_color]
current_dist = math.sqrt(
(current_coordinates["y"] - xy[1])**2 + (current_coordinates["x"] - xy[0])**2)
if current_dist < closest_distance:
closest_color = current_color
closest_distance = current_dist
return closest_color

View file

@ -0,0 +1,161 @@
#!/usr/bin/python
import re
import smbus
# ===========================================================================
# Adafruit_I2C Class
# ===========================================================================
class Adafruit_I2C(object):
@staticmethod
def getPiRevision():
"Gets the version number of the Raspberry Pi board"
# Revision list available at: http://elinux.org/RPi_HardwareHistory#Board_Revision_History
try:
with open('/proc/cpuinfo', 'r') as infile:
for line in infile:
# Match a line of the form "Revision : 0002" while ignoring extra
# info in front of the revsion (like 1000 when the Pi was over-volted).
match = re.match('Revision\s+:\s+.*(\w{4})$', line)
if match and match.group(1) in ['0000', '0002', '0003']:
# Return revision 1 if revision ends with 0000, 0002 or 0003.
return 1
elif match:
# Assume revision 2 if revision ends with any other 4 chars.
return 2
# Couldn't find the revision, assume revision 0 like older code for compatibility.
return 0
except:
return 0
@staticmethod
def getPiI2CBusNumber():
# Gets the I2C bus number /dev/i2c#
return 1 if Adafruit_I2C.getPiRevision() > 1 else 0
def __init__(self, address, busnum=-1, debug=False):
self.address = address
# By default, the correct I2C bus is auto-detected using /proc/cpuinfo
# Alternatively, you can hard-code the bus version below:
# self.bus = smbus.SMBus(0); # Force I2C0 (early 256MB Pi's)
# self.bus = smbus.SMBus(1); # Force I2C1 (512MB Pi's)
self.bus = smbus.SMBus(busnum if busnum >= 0 else Adafruit_I2C.getPiI2CBusNumber())
self.debug = debug
def reverseByteOrder(self, data):
"Reverses the byte order of an int (16-bit) or long (32-bit) value"
# Courtesy Vishal Sapre
byteCount = len(hex(data)[2:].replace('L','')[::2])
val = 0
for i in range(byteCount):
val = (val << 8) | (data & 0xff)
data >>= 8
return val
def errMsg(self):
print("Error accessing 0x%02X: Check your I2C address" % self.address)
return -1
def write8(self, reg, value):
"Writes an 8-bit value to the specified register/address"
try:
self.bus.write_byte_data(self.address, reg, value)
if self.debug:
print("I2C: Wrote 0x%02X to register 0x%02X" % (value, reg))
except IOError as err:
return self.errMsg()
def write16(self, reg, value):
"Writes a 16-bit value to the specified register/address pair"
try:
self.bus.write_word_data(self.address, reg, value)
if self.debug:
print("I2C: Wrote 0x%02X to register pair 0x%02X,0x%02X" %
(value, reg, reg+1))
except IOError as err:
return self.errMsg()
def writeRaw8(self, value):
"Writes an 8-bit value on the bus"
try:
self.bus.write_byte(self.address, value)
if self.debug:
print("I2C: Wrote 0x%02X" % value)
except IOError as err:
return self.errMsg()
def writeList(self, reg, list):
"Writes an array of bytes using I2C format"
try:
if self.debug:
print("I2C: Writing list to register 0x%02X:" % reg)
print(list)
self.bus.write_i2c_block_data(self.address, reg, list)
except IOError as err:
return self.errMsg()
def readList(self, reg, length):
"Read a list of bytes from the I2C device"
try:
results = self.bus.read_i2c_block_data(self.address, reg, length)
if self.debug:
print("I2C: Device 0x%02X returned the following from reg 0x%02X" %
(self.address, reg))
print(results)
return results
except IOError as err:
return self.errMsg()
def readU8(self, reg):
"Read an unsigned byte from the I2C device"
try:
result = self.bus.read_byte_data(self.address, reg)
if self.debug:
print("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
(self.address, result & 0xFF, reg))
return result
except IOError as err:
return self.errMsg()
def readS8(self, reg):
"Reads a signed byte from the I2C device"
try:
result = self.bus.read_byte_data(self.address, reg)
if result > 127: result -= 256
if self.debug:
print("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
(self.address, result & 0xFF, reg))
return result
except IOError as err:
return self.errMsg()
def readU16(self, reg, little_endian=True):
"Reads an unsigned 16-bit value from the I2C device"
try:
result = self.bus.read_word_data(self.address,reg)
# Swap bytes if using big endian because read_word_data assumes little
# endian on ARM (little endian) systems.
if not little_endian:
result = ((result << 8) & 0xFF00) + (result >> 8)
if (self.debug):
print("I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg))
return result
except IOError as err:
return self.errMsg()
def readS16(self, reg, little_endian=True):
"Reads a signed 16-bit value from the I2C device"
try:
result = self.readU16(reg,little_endian)
if result > 32767: result -= 65536
return result
except IOError as err:
return self.errMsg()
if __name__ == '__main__':
try:
bus = Adafruit_I2C(address=0)
print("Default I2C bus is accessible")
except:
print("Error accessing default I2C bus")

View file

@ -0,0 +1,310 @@
#!/usr/bin/python
# TSL2561 I2C Light-To-Digital converter library for the Raspberry Pi.
# Datasheet: https://www.adafruit.com/datasheets/TSL2561.pdf
#
# This library is based on the work by Cedric Maion https://github.com/cmaion/TSL2561
#
# Read http://www.dexterindustries.com/topic/greehouse-project/ for the forum discussion about the sensor
from time import sleep
import smbus
from Adafruit_I2C import Adafruit_I2C
import RPi.GPIO as GPIO
from smbus import SMBus
TSL2561_Control = 0x80
TSL2561_Timing = 0x81
TSL2561_Interrupt = 0x86
TSL2561_Channel0L = 0x8C
TSL2561_Channel0H = 0x8D
TSL2561_Channel1L = 0x8E
TSL2561_Channel1H = 0x8F
TSL2561_Address = 0x29 #device address
LUX_SCALE = 14 # scale by 2^14
RATIO_SCALE = 9 # scale ratio by 2^9
CH_SCALE = 10 # scale channel values by 2^10
CHSCALE_TINT0 = 0x7517 # 322/11 * 2^CH_SCALE
CHSCALE_TINT1 = 0x0fe7 # 322/81 * 2^CH_SCALE
K1T = 0x0040 # 0.125 * 2^RATIO_SCALE
B1T = 0x01f2 # 0.0304 * 2^LUX_SCALE
M1T = 0x01be # 0.0272 * 2^LUX_SCALE
K2T = 0x0080 # 0.250 * 2^RATIO_SCA
B2T = 0x0214 # 0.0325 * 2^LUX_SCALE
M2T = 0x02d1 # 0.0440 * 2^LUX_SCALE
K3T = 0x00c0 # 0.375 * 2^RATIO_SCALE
B3T = 0x023f # 0.0351 * 2^LUX_SCALE
M3T = 0x037b # 0.0544 * 2^LUX_SCALE
K4T = 0x0100 # 0.50 * 2^RATIO_SCALE
B4T = 0x0270 # 0.0381 * 2^LUX_SCALE
M4T = 0x03fe # 0.0624 * 2^LUX_SCALE
K5T = 0x0138 # 0.61 * 2^RATIO_SCALE
B5T = 0x016f # 0.0224 * 2^LUX_SCALE
M5T = 0x01fc # 0.0310 * 2^LUX_SCALE
K6T = 0x019a # 0.80 * 2^RATIO_SCALE
B6T = 0x00d2 # 0.0128 * 2^LUX_SCALE
M6T = 0x00fb # 0.0153 * 2^LUX_SCALE
K7T = 0x029a # 1.3 * 2^RATIO_SCALE
B7T = 0x0018 # 0.00146 * 2^LUX_SCALE
M7T = 0x0012 # 0.00112 * 2^LUX_SCALE
K8T = 0x029a # 1.3 * 2^RATIO_SCALE
B8T = 0x0000 # 0.000 * 2^LUX_SCALE
M8T = 0x0000 # 0.000 * 2^LUX_SCALE
K1C = 0x0043 # 0.130 * 2^RATIO_SCALE
B1C = 0x0204 # 0.0315 * 2^LUX_SCALE
M1C = 0x01ad # 0.0262 * 2^LUX_SCALE
K2C = 0x0085 # 0.260 * 2^RATIO_SCALE
B2C = 0x0228 # 0.0337 * 2^LUX_SCALE
M2C = 0x02c1 # 0.0430 * 2^LUX_SCALE
K3C = 0x00c8 # 0.390 * 2^RATIO_SCALE
B3C = 0x0253 # 0.0363 * 2^LUX_SCALE
M3C = 0x0363 # 0.0529 * 2^LUX_SCALE
K4C = 0x010a # 0.520 * 2^RATIO_SCALE
B4C = 0x0282 # 0.0392 * 2^LUX_SCALE
M4C = 0x03df # 0.0605 * 2^LUX_SCALE
K5C = 0x014d # 0.65 * 2^RATIO_SCALE
B5C = 0x0177 # 0.0229 * 2^LUX_SCALE
M5C = 0x01dd # 0.0291 * 2^LUX_SCALE
K6C = 0x019a # 0.80 * 2^RATIO_SCALE
B6C = 0x0101 # 0.0157 * 2^LUX_SCALE
M6C = 0x0127 # 0.0180 * 2^LUX_SCALE
K7C = 0x029a # 1.3 * 2^RATIO_SCALE
B7C = 0x0037 # 0.00338 * 2^LUX_SCALE
M7C = 0x002b # 0.00260 * 2^LUX_SCALE
K8C = 0x029a # 1.3 * 2^RATIO_SCALE
B8C = 0x0000 # 0.000 * 2^LUX_SCALE
M8C = 0x0000 # 0.000 * 2^LUX_SCALE
# bus parameters
rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
bus = smbus.SMBus(1)
else:
bus = smbus.SMBus(0)
i2c = Adafruit_I2C(TSL2561_Address)
debug = False
cooldown_time = 0.005 # measured in seconds
packageType = 0 # 0=T package, 1=CS package
gain = 0 # current gain: 0=1x, 1=16x [dynamically selected]
gain_m = 1 # current gain, as multiplier
timing = 2 # current integration time: 0=13.7ms, 1=101ms, 2=402ms [dynamically selected]
timing_ms = 0 # current integration time, in ms
channel0 = 0 # raw current value of visible+ir sensor
channel1 = 0 # raw current value of ir sensor
schannel0 = 0 # normalized current value of visible+ir sensor
schannel1 = 0 # normalized current value of ir sensor
def readRegister(address):
try:
byteval = i2c.readU8(address)
sleep(cooldown_time)
if (debug):
print("TSL2561.readRegister: returned 0x%02X from reg 0x%02X" % (byteval, address))
return byteval
except IOError:
print("TSL2561.readRegister: error reading byte from reg 0x%02X" % address)
return -1
def writeRegister(address, val):
try:
i2c.write8(address, val)
sleep(cooldown_time)
if (debug):
print("TSL2561.writeRegister: wrote 0x%02X to reg 0x%02X" % (val, address))
except IOError:
sleep(cooldown_time)
print("TSL2561.writeRegister: error writing byte to reg 0x%02X" % address)
return -1
def powerUp():
writeRegister(TSL2561_Control, 0x03)
def powerDown():
writeRegister(TSL2561_Control, 0x00)
def setTintAndGain():
global gain_m, timing_ms
if gain == 0:
gain_m = 1
else:
gain_m = 16
if timing == 0:
timing_ms = 13.7
elif timing == 1:
timing_ms = 101
else:
timing_ms = 402
writeRegister(TSL2561_Timing, timing | gain << 4)
def readLux():
sleep(float(timing_ms + 1) / 1000)
ch0_low = readRegister(TSL2561_Channel0L)
ch0_high = readRegister(TSL2561_Channel0H)
ch1_low = readRegister(TSL2561_Channel1L)
ch1_high = readRegister(TSL2561_Channel1H)
global channel0, channel1
channel0 = (ch0_high<<8) | ch0_low
channel1 = (ch1_high<<8) | ch1_low
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: channel 0 = %i, channel 1 = %i [gain=%ix, timing=%ims]" % (channel0, channel1, gain_m, timing_ms))
def readVisibleLux():
global timing, gain
powerUp()
readLux()
if channel0 < 500 and timing == 0:
timing = 1
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: too dark. Increasing integration time from 13.7ms to 101ms")
setTintAndGain()
readLux()
if channel0 < 500 and timing == 1:
timing = 2
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: too dark. Increasing integration time from 101ms to 402ms")
setTintAndGain()
readLux()
if channel0 < 500 and timing == 2 and gain == 0:
gain = 1
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: too dark. Setting high gain")
setTintAndGain()
readLux()
if (channel0 > 20000 or channel1 > 20000) and timing == 2 and gain == 1:
gain = 0
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: enough light. Setting low gain")
setTintAndGain()
readLux()
if (channel0 > 20000 or channel1 > 20000) and timing == 2:
timing = 1
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: enough light. Reducing integration time from 402ms to 101ms")
setTintAndGain()
readLux()
if (channel0 > 10000 or channel1 > 10000) and timing == 1:
timing = 0
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: enough light. Reducing integration time from 101ms to 13.7ms")
setTintAndGain()
readLux()
powerDown()
if (timing == 0 and (channel0 > 5000 or channel1 > 5000)) or (timing == 1 and (channel0 > 37000 or channel1 > 37000)) or (timing == 2 and (channel0 > 65000 or channel1 > 65000)):
# overflow
return -1
return calculateLux(channel0, channel1)
def calculateLux(ch0, ch1):
chScale = 0
if timing == 0: # 13.7 msec
chScale = CHSCALE_TINT0
elif timing == 1: # 101 msec
chScale = CHSCALE_TINT1;
else: # assume no scaling
chScale = (1 << CH_SCALE)
if gain == 0:
chScale = chScale << 4 # scale 1X to 16X
# scale the channel values
global schannel0, schannel1
schannel0 = (ch0 * chScale) >> CH_SCALE
schannel1 = (ch1 * chScale) >> CH_SCALE
ratio = 0
if schannel0 != 0:
ratio = (schannel1 << (RATIO_SCALE+1)) / schannel0
ratio = (ratio + 1) >> 1
if packageType == 0: # T package
if ((ratio >= 0) and (ratio <= K1T)):
b=B1T; m=M1T;
elif (ratio <= K2T):
b=B2T; m=M2T;
elif (ratio <= K3T):
b=B3T; m=M3T;
elif (ratio <= K4T):
b=B4T; m=M4T;
elif (ratio <= K5T):
b=B5T; m=M5T;
elif (ratio <= K6T):
b=B6T; m=M6T;
elif (ratio <= K7T):
b=B7T; m=M7T;
elif (ratio > K8T):
b=B8T; m=M8T;
elif packageType == 1: # CS package
if ((ratio >= 0) and (ratio <= K1C)):
b=B1C; m=M1C;
elif (ratio <= K2C):
b=B2C; m=M2C;
elif (ratio <= K3C):
b=B3C; m=M3C;
elif (ratio <= K4C):
b=B4C; m=M4C;
elif (ratio <= K5C):
b=B5C; m=M5C;
elif (ratio <= K6C):
b=B6C; m=M6C;
elif (ratio <= K7C):
b=B7C; m=M7C;
temp = ((schannel0*b)-(schannel1*m))
if temp < 0:
temp = 0;
temp += (1<<(LUX_SCALE-1))
# strip off fractional portion
lux = temp>>LUX_SCALE
sleep(cooldown_time)
if debug:
print("TSL2561.calculateLux: %i" % lux)
return lux
def init():
powerUp()
setTintAndGain()
writeRegister(TSL2561_Interrupt, 0x00)
powerDown()
def main():
init()
while (True):
print("Lux: %i [Vis+IR=%i, IR=%i @ Gain=%ix, Timing=%.1fms]" % (readVisibleLux(), channel0, channel1, gain_m, timing_ms))
sleep(1)
if __name__ == "__main__":
main()

View file

@ -0,0 +1,12 @@
This is a Python 2.7 script which can be used to get readings from the Grove Digital Light Sensor(http://www.seeedstudio.com/wiki/Grove_-_Digital_Light_Sensor) connected to the GrovePi on a Raspberry Pi.
If you set debug = 1 (standard option) it displays all calculations on screen.
If you set debug = 0, the script just runs and only displays the output.
The script get's both the IR-reading and ambient reading from the sensor. It then scales the the readings and calculates the lux-value.
the main function performs a continuous loop, gets the readings and calculated lux-value and displays the result (depending on the result the output can be normal values and a message 'it's light' or 'it's dark' or a message if the sensor is saturated and no values can be achieved. The loop is repeated with a time.sleep(10) so you can easily read the result on screen.
If your not interested in the IR or ambient values but just want the lux value, comment out the undisered output lines. Be sure not to comment out the reading and calculating lines in the different functions because you need both the IR and the ambient values in order to calculate the lux value.
September 2014.

View file

@ -0,0 +1,73 @@
#!/usr/bin/env python
#
# GrovePi Library for using the Grove - I2C Motor Driver(http://www.seeedstudio.com/depot/Grove-I2C-Motor-Driver-p-907.html)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this library? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
# Released under the MIT license (http://choosealicense.com/licenses/mit/).
# For more information see https://github.com/DexterInd/GrovePi/blob/master/LICENSE
import time,sys
import RPi.GPIO as GPIO
import smbus
# use the bus that matches your raspi version
rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
bus = smbus.SMBus(1)
else:
bus = smbus.SMBus(0)
class motor_driver:
MotorSpeedSet = 0x82
PWMFrequenceSet = 0x84
DirectionSet = 0xaa
MotorSetA = 0xa1
MotorSetB = 0xa5
Nothing = 0x01
EnableStepper = 0x1a
UnenableStepper = 0x1b
Stepernu = 0x1c
I2CMotorDriverAdd = 0x0f #Set the address of the I2CMotorDriver
def __init__(self,address=0x0f):
self.I2CMotorDriverAdd=address
#Maps speed from 0-100 to 0-255
def map_vals(self,value, leftMin, leftMax, rightMin, rightMax):
#http://stackoverflow.com/questions/1969240/mapping-a-range-of-values-to-another
# Figure out how 'wide' each range is
leftSpan = leftMax - leftMin
rightSpan = rightMax - rightMin
# Convert the left range into a 0-1 range (float)
valueScaled = float(value - leftMin) / float(leftSpan)
# Convert the 0-1 range into a value in the right range.
return int(rightMin + (valueScaled * rightSpan))
#Set motor speed
def MotorSpeedSetAB(self,MotorSpeedA,MotorSpeedB):
MotorSpeedA=self.map_vals(MotorSpeedA,0,100,0,255)
MotorSpeedB=self.map_vals(MotorSpeedB,0,100,0,255)
bus.write_i2c_block_data(self.I2CMotorDriverAdd, self.MotorSpeedSet, [MotorSpeedA,MotorSpeedB])
time.sleep(.02)
#Set motor direction
def MotorDirectionSet(self,Direction):
bus.write_i2c_block_data(self.I2CMotorDriverAdd, self.DirectionSet, [Direction,0])
time.sleep(.02)
if __name__ == "__main__":
m= motor_driver()
while True:
m.MotorSpeedSetAB(100,100)
m.MotorDirectionSet(0b1010)
time.sleep(2)
m.MotorSpeedSetAB(100,100)
m.MotorDirectionSet(0b0101)
time.sleep(2)

View file

@ -0,0 +1,76 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove - I2C Motor Driver(http://www.seeedstudio.com/depot/Grove-I2C-Motor-Driver-p-907.html)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
# NOTE:
# * Refer to the wiki to make sure that the address is correct: http://www.seeedstudio.com/wiki/Grove_-_I2C_Motor_Driver_V1.3
# * The I2C motor driver is very sensitive to the commands being sent to it
# * Do not run i2cdetect or send a wrong command to it, the motor driver will stop working and also pull down the I2C clock line, which makes the GrovePi or any other device to stop working too
# *Press reset when if you keep getting errors
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import grove_i2c_motor_driver
import time
try:
# You can initialize with a different address too: grove_i2c_motor_driver.motor_driver(address=0x0a)
m= grove_i2c_motor_driver.motor_driver()
#FORWARD
print("Forward")
m.MotorSpeedSetAB(100,100) #defines the speed of motor 1 and motor 2;
m.MotorDirectionSet(0b1010) #"0b1010" defines the output polarity, "10" means the M+ is "positive" while the M- is "negtive"
time.sleep(2)
#BACK
print("Back")
m.MotorSpeedSetAB(100,100)
m.MotorDirectionSet(0b0101) #0b0101 Rotating in the opposite direction
time.sleep(2)
#STOP
print("Stop")
m.MotorSpeedSetAB(0,0)
time.sleep(1)
#Increase speed
for i in range (100):
print("Speed:",i)
m.MotorSpeedSetAB(i,i)
time.sleep(.02)
print("Stop")
m.MotorSpeedSetAB(0,0)
except IOError:
print("Unable to find the motor driver, check the addrees and press reset on the motor driver and try again")

View file

@ -0,0 +1,85 @@
#!/usr/bin/env python
#NOTE:
# This sensor is on port 0x04, so not compatible with grovepi unless you load an alternate firmware
# This is work in progress, would need logic analyzer and arduino to get working
# Error:
# Traceback (most recent call last):
# File "multichannel_gas_sensor.py", line 67, in <module>
# m= MutichannelGasSensor()
# File "multichannel_gas_sensor.py", line 21, in __init__
# if self.readR0() >= 0:
# File "multichannel_gas_sensor.py", line 27, in readR0
# rtnData = self.readData(0x11)
# File "multichannel_gas_sensor.py", line 52, in readData
# buffer=bus.read_i2c_block_data(self.address, cmd, 4)
#IOError: [Errno 5] Input/output error
#
# LINKS
# http://www.seeedstudio.com/wiki/Grove_-_Multichannel_Gas_Sensor
# https://github.com/Seeed-Studio/Mutichannel_Gas_Sensor
import time,sys
import RPi.GPIO as GPIO
import smbus
# use the bus that matches your raspi version
rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
bus = smbus.SMBus(1)
else:
bus = smbus.SMBus(0)
class MutichannelGasSensor:
address = None
is_connected = 0
res=[0]*3
def __init__(self,address=0x04):
self.address=address
is_connected = 0
if self.readR0() >= 0:
self.is_connected = 1
def readR0(self):
rtnData = 0
rtnData = self.readData(0x11)
if(rtnData >= 0):
self.res0[0] = rtnData
else:
return rtnData
rtnData = self.readData(0x12)
if(rtnData >= 0):
self.res0[0] = rtnData
else:
return rtnData
rtnData = self.readData(0x13)
if(rtnData >= 0):
self.res0[0] = rtnData
else:
return rtnData
return 0
def readData(self,cmd):
timeout = 0
buffer=[0]*4
checksum = 0
rtnData = 0
buffer=bus.read_i2c_block_data(self.address, cmd, 4)
print(data)
checksum = buffer[0] + buffer[1] + buffer[2]
if checksum != buffer[3]:
return -4
rtnData = ((buffer[1] << 8) + buffer[2])
return rtnData
def sendI2C(self,cmd):
bus.write_byte(self.address, cmd)
if __name__ == "__main__":
m= MutichannelGasSensor()

View file

@ -0,0 +1,320 @@
#!/usr/bin/env python
#
# GrovePi library for the basic functions of Grove 128x64 OLED (http://www.seeedstudio.com/depot/Grove-OLED-Display-112-p-781.html)
# v1.0
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
# LICENSE:
# These files have been made available online through a [Creative Commons Attribution-ShareAlike 3.0](http://creativecommons.org/licenses/by-sa/3.0/) license.
#
# Karan Nayan
# Initial Date: 12 Aug 2015
# Last Updated: 12 Aug 2015
#
# Based on the Arduino library "SeeedOLED.cpp"
# Seeed Technology Inc.
# written by: Visweswara R
import smbus
import time
import math
import RPi.GPIO as GPIO
import struct
rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
bus = smbus.SMBus(1)
else:
bus = smbus.SMBus(0)
address=0x3c
addressingMode= None
SeeedOLED_Max_X =127 #128 Pixels
SeeedOLED_Max_Y =63 #64 Pixels
PAGE_MODE =1
HORIZONTAL_MODE =2
SeeedOLED_Address =0x3c
SeeedOLED_Command_Mode =0x80
SeeedOLED_Data_Mode =0x40
SeeedOLED_Display_Off_Cmd =0xAE
SeeedOLED_Display_On_Cmd =0xAF
SeeedOLED_Normal_Display_Cmd =0xA6
SeeedOLED_Inverse_Display_Cmd =0xA7
SeeedOLED_Activate_Scroll_Cmd =0x2F
SeeedOLED_Dectivate_Scroll_Cmd =0x2E
SeeedOLED_Set_Brightness_Cmd =0x81
Scroll_Left =0x00
Scroll_Right =0x01
Scroll_2Frames =0x7
Scroll_3Frames =0x4
Scroll_4Frames =0x5
Scroll_5Frames =0x0
Scroll_25Frames =0x6
Scroll_64Frames =0x1
Scroll_128Frames =0x2
Scroll_256Frames =0x3
BasicFont = [[0 for x in range(8)] for x in range(10)]
BasicFont=[[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
[0x00,0x00,0x5F,0x00,0x00,0x00,0x00,0x00],
[0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00],
[0x00,0x14,0x7F,0x14,0x7F,0x14,0x00,0x00],
[0x00,0x24,0x2A,0x7F,0x2A,0x12,0x00,0x00],
[0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00],
[0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00],
[0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00],
[0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00],
[0x00,0x41,0x22,0x1C,0x00,0x00,0x00,0x00],
[0x00,0x08,0x2A,0x1C,0x2A,0x08,0x00,0x00],
[0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00],
[0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00],
[0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00],
[0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00],
[0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00],
[0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x00],
[0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x00],
[0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x00],
[0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x00],
[0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x00],
[0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00],
[0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x00],
[0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x00],
[0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00],
[0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00],
[0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00],
[0x00,0x00,0xAC,0x6C,0x00,0x00,0x00,0x00],
[0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00],
[0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00],
[0x00,0x41,0x22,0x14,0x08,0x00,0x00,0x00],
[0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00],
[0x00,0x32,0x49,0x79,0x41,0x3E,0x00,0x00],
[0x00,0x7E,0x09,0x09,0x09,0x7E,0x00,0x00],
[0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x00],
[0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x00],
[0x00,0x7F,0x41,0x41,0x22,0x1C,0x00,0x00],
[0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x00],
[0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x00],
[0x00,0x3E,0x41,0x41,0x51,0x72,0x00,0x00],
[0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00],
[0x00,0x41,0x7F,0x41,0x00,0x00,0x00,0x00],
[0x00,0x20,0x40,0x41,0x3F,0x01,0x00,0x00],
[0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x00],
[0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x00],
[0x00,0x7F,0x02,0x0C,0x02,0x7F,0x00,0x00],
[0x00,0x7F,0x04,0x08,0x10,0x7F,0x00,0x00],
[0x00,0x3E,0x41,0x41,0x41,0x3E,0x00,0x00],
[0x00,0x7F,0x09,0x09,0x09,0x06,0x00,0x00],
[0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x00],
[0x00,0x7F,0x09,0x19,0x29,0x46,0x00,0x00],
[0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00],
[0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x00],
[0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x00],
[0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x00],
[0x00,0x3F,0x40,0x38,0x40,0x3F,0x00,0x00],
[0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x00],
[0x00,0x03,0x04,0x78,0x04,0x03,0x00,0x00],
[0x00,0x61,0x51,0x49,0x45,0x43,0x00,0x00],
[0x00,0x7F,0x41,0x41,0x00,0x00,0x00,0x00],
[0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00],
[0x00,0x41,0x41,0x7F,0x00,0x00,0x00,0x00],
[0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00],
[0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00],
[0x00,0x01,0x02,0x04,0x00,0x00,0x00,0x00],
[0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00],
[0x00,0x7F,0x48,0x44,0x44,0x38,0x00,0x00],
[0x00,0x38,0x44,0x44,0x28,0x00,0x00,0x00],
[0x00,0x38,0x44,0x44,0x48,0x7F,0x00,0x00],
[0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00],
[0x00,0x08,0x7E,0x09,0x02,0x00,0x00,0x00],
[0x00,0x18,0xA4,0xA4,0xA4,0x7C,0x00,0x00],
[0x00,0x7F,0x08,0x04,0x04,0x78,0x00,0x00],
[0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00],
[0x00,0x80,0x84,0x7D,0x00,0x00,0x00,0x00],
[0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00],
[0x00,0x41,0x7F,0x40,0x00,0x00,0x00,0x00],
[0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x00],
[0x00,0x7C,0x08,0x04,0x7C,0x00,0x00,0x00],
[0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00],
[0x00,0xFC,0x24,0x24,0x18,0x00,0x00,0x00],
[0x00,0x18,0x24,0x24,0xFC,0x00,0x00,0x00],
[0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00],
[0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00],
[0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00],
[0x00,0x3C,0x40,0x40,0x7C,0x00,0x00,0x00],
[0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x00],
[0x00,0x3C,0x40,0x30,0x40,0x3C,0x00,0x00],
[0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00],
[0x00,0x1C,0xA0,0xA0,0x7C,0x00,0x00,0x00],
[0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00],
[0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x00],
[0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00],
[0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00],
[0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00],
[0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00]]
def sendCommand(byte):
try:
block=[]
block.append(byte)
return bus.write_i2c_block_data(address,SeeedOLED_Command_Mode,block)
except IOError:
print("IOError")
return -1
def sendData(byte):
try:
block=[]
block.append(byte)
return bus.write_i2c_block_data(address,SeeedOLED_Data_Mode,block)
except IOError:
print("IOError")
return -1
def multi_comm(commands):
for c in commands:
sendCommand(c)
# Init function of the OLED
def init():
sendCommand(SeeedOLED_Display_Off_Cmd) #display off
time.sleep(.005)
sendCommand(SeeedOLED_Display_On_Cmd) #display on
time.sleep(.005)
sendCommand(SeeedOLED_Normal_Display_Cmd) #Set Normal Display (default)
def setBrightness(Brightness):
sendCommand(SeeedOLED_Set_Brightness_Cmd)
sendCommand(Brightness)
def setHorizontalMode():
global addressingMode
addressingMode = HORIZONTAL_MODE
sendCommand(0x20) #set addressing mode
sendCommand(0x00) #set horizontal addressing mode
def setPageMode():
global addressingMode
addressingMode = PAGE_MODE
sendCommand(0x20) #set addressing mode
sendCommand(0x02) #set page addressing mode
def setTextXY(Column,Row):
sendCommand(0xB0 + Row) #set page address
sendCommand(0x00 + (8*Column & 0x0F)) #set column lower address
sendCommand(0x10 + ((8*Column>>4)&0x0F)) #set column higher address
def clearDisplay():
sendCommand(SeeedOLED_Display_Off_Cmd) #display off
for j in range(8):
setTextXY(0,j)
for i in range(16): #clear all columns
putChar(' ')
sendCommand(SeeedOLED_Display_On_Cmd) #display on
setTextXY(0,0)
def putChar(C):
C_add=ord(C)
if C_add<32 or C_add>127: # Ignore non-printable ASCII characters
C=' '
C_add=ord(C)
for i in range(8):
data=(BasicFont[C_add-32][i])
sendData(data)
# for i in range(0,8,2):
# for j in range(0,8):
# c=0x00
# bit1=((BasicFont[C_add-32][i])>>j)&0x01
# bit2=((BasicFont[C_add-32][i+1])>>j)&0x01
# if bit1:
# c=c|grayH
# else:
# c=c|0x00
# if bit2:
# c=c|grayL
# else:
# c=c|0x00
# sendData(c)
def putString(s):
for i in range(len(s)):
putChar(s[i])
def putNumber(long_num):
char_buffer[10]=None
i = 0
f = 0
if (long_num < 0) :
f=1
putChar('-')
long_num = -long_num
elif (long_num == 0) :
f=1
putChar('0')
return f
while (long_num > 0):
char_buffer[i] = long_num % 10
long_num /= 10
i+=1
f=f+i
while(i>0):
putChar('0'+ char_buffer[i - 1])
i-=1
return f
def setHorizontalScrollProperties(direction,startPage, endPage, scrollSpeed):
'''
Use the following defines for 'direction' :
Scroll_Left
Scroll_Right
Use the following defines for 'scrollSpeed' :
Scroll_2Frames
Scroll_3Frames
Scroll_4Frames
Scroll_5Frames
Scroll_25Frames
Scroll_64Frames
Scroll_128Frames
Scroll_256Frames
'''
if(Scroll_Right == direction):
#Scroll Right
sendCommand(0x26)
else:
#Scroll Left
sendCommand(0x27)
sendCommand(0x00)
sendCommand(startPage)
sendCommand(scrollSpeed)
sendCommand(endPage)
sendCommand(0x00)
sendCommand(0xFF)
def activateScroll():
sendCommand(SeeedOLED_Activate_Scroll_Cmd)
def deactivateScroll():
sendCommand(SeeedOLED_Dectivate_Scroll_Cmd)
def setNormalDisplay():
sendCommand(SeeedOLED_Normal_Display_Cmd)
def setInverseDisplay():
sendCommand(SeeedOLED_Inverse_Display_Cmd)

View file

@ -0,0 +1,45 @@
#!/usr/bin/env python
#
# GrovePi example for the basic functions of Grove 128x64 OLED (http://www.seeedstudio.com/depot/Grove-OLED-Display-112-p-781.html)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import grove_128_64_oled as oled
oled.init() #initialze SEEED OLED display
oled.clearDisplay() #clear the screen and set start position to top left corner
oled.setNormalDisplay() #Set display to normal mode (i.e non-inverse mode)
oled.setPageMode() #Set addressing mode to Page Mode
for i in range(6):
oled.setTextXY(i,i) #Set the cursor to Xth Page, Yth Column
oled.putString("Hello World!") #Print the String

View file

@ -0,0 +1,49 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove I2C RTC (http://www.seeedstudio.com/wiki/Grove_-_RTC)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import time
import grovepi
# Connect the Grove Real Time Clock to any I2C port eg. I2C-1
# Can be found at I2C address 0x68
# SCL,SDA,VCC,GND
while True:
try:
print(grovepi.rtc_getTime())
time.sleep(.5)
except IOError:
print ("Error")

View file

@ -0,0 +1,195 @@
# Copyright (c) 2014 Adafruit Industries
# Author: Tony DiCola
# Based on Adafruit_I2C.py created by Kevin Townsend.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import logging
import subprocess
import smbus
import Platform
def reverseByteOrder(data):
"""Reverses the byte order of an int (16-bit) or long (32-bit) value."""
# Courtesy Vishal Sapre
byteCount = len(hex(data)[2:].replace('L','')[::2])
val = 0
for i in range(byteCount):
val = (val << 8) | (data & 0xff)
data >>= 8
return val
def get_default_bus():
"""Return the default bus number based on the device platform. For a
Raspberry Pi either bus 0 or 1 (based on the Pi revision) will be returned.
For a Beaglebone Black the first user accessible bus, 1, will be returned.
"""
plat = Platform.platform_detect()
if plat == Platform.RASPBERRY_PI:
if Platform.pi_revision() == 1:
# Revision 1 Pi uses I2C bus 0.
return 0
else:
# Revision 2 Pi uses I2C bus 1.
return 1
elif plat == Platform.BEAGLEBONE_BLACK:
# Beaglebone Black has multiple I2C buses, default to 1 (P9_19 and P9_20).
return 1
else:
raise RuntimeError('Could not determine default I2C bus for platform.')
def get_i2c_device(address, busnum=None, **kwargs):
"""Return an I2C device for the specified address and on the specified bus.
If busnum isn't specified, the default I2C bus for the platform will attempt
to be detected.
"""
if busnum is None:
busnum = get_default_bus()
return Device(address, busnum, **kwargs)
def require_repeated_start():
"""Enable repeated start conditions for I2C register reads. This is the
normal behavior for I2C, however on some platforms like the Raspberry Pi
there are bugs which disable repeated starts unless explicitly enabled with
this function. See this thread for more details:
http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=15840
"""
plat = Platform.platform_detect()
if plat == Platform.RASPBERRY_PI:
# On the Raspberry Pi there is a bug where register reads don't send a
# repeated start condition like the kernel smbus I2C driver functions
# define. As a workaround this bit in the BCM2708 driver sysfs tree can
# be changed to enable I2C repeated starts.
subprocess.check_call('chmod 666 /sys/module/i2c_bcm2708/parameters/combined', shell=True)
subprocess.check_call('echo -n 1 > /sys/module/i2c_bcm2708/parameters/combined', shell=True)
# Other platforms are a no-op because they (presumably) have the correct
# behavior and send repeated starts.
class Device(object):
"""Class for communicating with an I2C device using the smbus library.
Allows reading and writing 8-bit, 16-bit, and byte array values to registers
on the device."""
def __init__(self, address, busnum):
"""Create an instance of the I2C device at the specified address on the
specified I2C bus number."""
self._address = address
self._bus = smbus.SMBus(busnum)
self._logger = logging.getLogger('Adafruit_I2C.Device.Bus.{0}.Address.{1:#0X}' \
.format(busnum, address))
def writeRaw8(self, value):
"""Write an 8-bit value on the bus (without register)."""
value = value & 0xFF
self._bus.write_byte(self._address, value)
self._logger.debug("Wrote 0x%02X",
value)
def write8(self, register, value):
"""Write an 8-bit value to the specified register."""
value = value & 0xFF
self._bus.write_byte_data(self._address, register, value)
self._logger.debug("Wrote 0x%02X to register 0x%02X",
value, register)
def write16(self, register, value):
"""Write a 16-bit value to the specified register."""
value = value & 0xFFFF
self._bus.write_word_data(self._address, register, value)
self._logger.debug("Wrote 0x%04X to register pair 0x%02X, 0x%02X",
value, register, register+1)
def writeList(self, register, data):
"""Write bytes to the specified register."""
self._bus.write_i2c_block_data(self._address, register, data)
self._logger.debug("Wrote to register 0x%02X: %s",
register, data)
def readList(self, register, length):
"""Read a length number of bytes from the specified register. Results
will be returned as a bytearray."""
results = self._bus.read_i2c_block_data(self._address, register, length)
self._logger.debug("Read the following from register 0x%02X: %s",
register, results)
return results
def readRaw8(self):
"""Read an 8-bit value on the bus (without register)."""
result = self._bus.read_byte(self._address) & 0xFF
self._logger.debug("Read 0x%02X",
result)
return result
def readU8(self, register):
"""Read an unsigned byte from the specified register."""
result = self._bus.read_byte_data(self._address, register) & 0xFF
self._logger.debug("Read 0x%02X from register 0x%02X",
result, register)
return result
def readS8(self, register):
"""Read a signed byte from the specified register."""
result = self.readU8(register)
if result > 127:
result -= 256
return result
def readU16(self, register, little_endian=True):
"""Read an unsigned 16-bit value from the specified register, with the
specified endianness (default little endian, or least significant byte
first)."""
result = self._bus.read_word_data(self._address,register) & 0xFFFF
self._logger.debug("Read 0x%04X from register pair 0x%02X, 0x%02X",
result, register, register+1)
# Swap bytes if using big endian because read_word_data assumes little
# endian on ARM (little endian) systems.
if not little_endian:
result = ((result << 8) & 0xFF00) + (result >> 8)
return result
def readS16(self, register, little_endian=True):
"""Read a signed 16-bit value from the specified register, with the
specified endianness (default little endian, or least significant byte
first)."""
result = self.readU16(register, little_endian)
if result > 32767:
result -= 65536
return result
def readU16LE(self, register):
"""Read an unsigned 16-bit value from the specified register, in little
endian byte order."""
return self.readU16(register, little_endian=True)
def readU16BE(self, register):
"""Read an unsigned 16-bit value from the specified register, in big
endian byte order."""
return self.readU16(register, little_endian=False)
def readS16LE(self, register):
"""Read a signed 16-bit value from the specified register, in little
endian byte order."""
return self.readS16(register, little_endian=True)
def readS16BE(self, register):
"""Read a signed 16-bit value from the specified register, in big
endian byte order."""
return self.readS16(register, little_endian=False)

View file

@ -0,0 +1,106 @@
# Copyright (c) 2014 Adafruit Industries
# Author: Tony DiCola
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import platform
import re
# Platform identification constants.
UNKNOWN = 0
RASPBERRY_PI = 1
BEAGLEBONE_BLACK = 2
MINNOWBOARD = 3
def platform_detect():
"""Detect if running on the Raspberry Pi or Beaglebone Black and return the
platform type. Will return RASPBERRY_PI, BEAGLEBONE_BLACK, or UNKNOWN."""
# Handle Raspberry Pi
pi = pi_version()
if pi is not None:
return RASPBERRY_PI
# Handle Beaglebone Black
# TODO: Check the Beaglebone Black /proc/cpuinfo value instead of reading
# the platform.
plat = platform.platform()
if plat.lower().find('armv7l-with-debian') > -1:
return BEAGLEBONE_BLACK
elif plat.lower().find('armv7l-with-ubuntu') > -1:
return BEAGLEBONE_BLACK
elif plat.lower().find('armv7l-with-glibc2.4') > -1:
return BEAGLEBONE_BLACK
# Handle Minnowboard
# Assumption is that mraa is installed
try:
import mraa
if mraa.getPlatformName()=='MinnowBoard MAX':
return MINNOWBOARD
except ImportError:
pass
# Couldn't figure out the platform, just return unknown.
return UNKNOWN
def pi_revision():
"""Detect the revision number of a Raspberry Pi, useful for changing
functionality like default I2C bus based on revision."""
# Revision list available at: http://elinux.org/RPi_HardwareHistory#Board_Revision_History
with open('/proc/cpuinfo', 'r') as infile:
for line in infile:
# Match a line of the form "Revision : 0002" while ignoring extra
# info in front of the revsion (like 1000 when the Pi was over-volted).
match = re.match('Revision\s+:\s+.*(\w{4})$', line, flags=re.IGNORECASE)
if match and match.group(1) in ['0000', '0002', '0003']:
# Return revision 1 if revision ends with 0000, 0002 or 0003.
return 1
elif match:
# Assume revision 2 if revision ends with any other 4 chars.
return 2
# Couldn't find the revision, throw an exception.
raise RuntimeError('Could not determine Raspberry Pi revision.')
def pi_version():
"""Detect the version of the Raspberry Pi. Returns either 1, 2 or
None depending on if it's a Raspberry Pi 1 (model A, B, A+, B+),
Raspberry Pi 2 (model B+), or not a Raspberry Pi.
"""
# Check /proc/cpuinfo for the Hardware field value.
# 2708 is pi 1
# 2709 is pi 2
# Anything else is not a pi.
with open('/proc/cpuinfo', 'r') as infile:
cpuinfo = infile.read()
# Match a line like 'Hardware : BCM2709'
match = re.search('^Hardware\s+:\s+(\w+)$', cpuinfo,
flags=re.MULTILINE | re.IGNORECASE)
if not match:
# Couldn't find the hardware, assume it isn't a pi.
return None
if match.group(1) == 'BCM2708':
# Pi 1
return 1
elif match.group(1) == 'BCM2709':
# Pi 2
return 2
else:
# Something else, not a pi.
return None

View file

@ -0,0 +1,7 @@
Grove I2C Touch Sensor
======================
Raspberry Pi Python i2c library for Grove I2C Touch sensor (http://www.seeedstudio.com/depot/Grove-I2C-Touch-Sensor-p-840.html)
The I2C Touch Sensor is based on FreeScale MPR121, it feels the touch or proximity of human being fingers.
The python library used for this sensor is based on the Python_SI1145 library by THP-JOE(https://github.com/THP-JOE/Python_SI1145)

View file

@ -0,0 +1,264 @@
#!/usr/bin/python
# Author: Joe Gutting
# With use of Adafruit SI1145 library for Arduino, Adafruit_GPIO.I2C & BMP Library by Tony DiCola
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import logging
import time
import I2C
# COMMANDS
SI1145_PARAM_QUERY = 0x80
SI1145_PARAM_SET = 0xA0
SI1145_NOP = 0x0
SI1145_RESET = 0x01
SI1145_BUSADDR = 0x02
SI1145_PS_FORCE = 0x05
SI1145_ALS_FORCE = 0x06
SI1145_PSALS_FORCE = 0x07
SI1145_PS_PAUSE = 0x09
SI1145_ALS_PAUSE = 0x0A
SI1145_PSALS_PAUSE = 0xB
SI1145_PS_AUTO = 0x0D
SI1145_ALS_AUTO = 0x0E
SI1145_PSALS_AUTO = 0x0F
SI1145_GET_CAL = 0x12
# Parameters
SI1145_PARAM_I2CADDR = 0x00
SI1145_PARAM_CHLIST = 0x01
SI1145_PARAM_CHLIST_ENUV = 0x80
SI1145_PARAM_CHLIST_ENAUX = 0x40
SI1145_PARAM_CHLIST_ENALSIR = 0x20
SI1145_PARAM_CHLIST_ENALSVIS = 0x10
SI1145_PARAM_CHLIST_ENPS1 = 0x01
SI1145_PARAM_CHLIST_ENPS2 = 0x02
SI1145_PARAM_CHLIST_ENPS3 = 0x04
SI1145_PARAM_PSLED12SEL = 0x02
SI1145_PARAM_PSLED12SEL_PS2NONE = 0x00
SI1145_PARAM_PSLED12SEL_PS2LED1 = 0x10
SI1145_PARAM_PSLED12SEL_PS2LED2 = 0x20
SI1145_PARAM_PSLED12SEL_PS2LED3 = 0x40
SI1145_PARAM_PSLED12SEL_PS1NONE = 0x00
SI1145_PARAM_PSLED12SEL_PS1LED1 = 0x01
SI1145_PARAM_PSLED12SEL_PS1LED2 = 0x02
SI1145_PARAM_PSLED12SEL_PS1LED3 = 0x04
SI1145_PARAM_PSLED3SEL = 0x03
SI1145_PARAM_PSENCODE = 0x05
SI1145_PARAM_ALSENCODE = 0x06
SI1145_PARAM_PS1ADCMUX = 0x07
SI1145_PARAM_PS2ADCMUX = 0x08
SI1145_PARAM_PS3ADCMUX = 0x09
SI1145_PARAM_PSADCOUNTER = 0x0A
SI1145_PARAM_PSADCGAIN = 0x0B
SI1145_PARAM_PSADCMISC = 0x0C
SI1145_PARAM_PSADCMISC_RANGE = 0x20
SI1145_PARAM_PSADCMISC_PSMODE = 0x04
SI1145_PARAM_ALSIRADCMUX = 0x0E
SI1145_PARAM_AUXADCMUX = 0x0F
SI1145_PARAM_ALSVISADCOUNTER = 0x10
SI1145_PARAM_ALSVISADCGAIN = 0x11
SI1145_PARAM_ALSVISADCMISC = 0x12
SI1145_PARAM_ALSVISADCMISC_VISRANGE = 0x20
SI1145_PARAM_ALSIRADCOUNTER = 0x1D
SI1145_PARAM_ALSIRADCGAIN = 0x1E
SI1145_PARAM_ALSIRADCMISC = 0x1F
SI1145_PARAM_ALSIRADCMISC_RANGE = 0x20
SI1145_PARAM_ADCCOUNTER_511CLK = 0x70
SI1145_PARAM_ADCMUX_SMALLIR = 0x00
SI1145_PARAM_ADCMUX_LARGEIR = 0x03
# REGISTERS
SI1145_REG_PARTID = 0x00
SI1145_REG_REVID = 0x01
SI1145_REG_SEQID = 0x02
SI1145_REG_INTCFG = 0x03
SI1145_REG_INTCFG_INTOE = 0x01
SI1145_REG_INTCFG_INTMODE = 0x02
SI1145_REG_IRQEN = 0x04
SI1145_REG_IRQEN_ALSEVERYSAMPLE = 0x01
SI1145_REG_IRQEN_PS1EVERYSAMPLE = 0x04
SI1145_REG_IRQEN_PS2EVERYSAMPLE = 0x08
SI1145_REG_IRQEN_PS3EVERYSAMPLE = 0x10
SI1145_REG_IRQMODE1 = 0x05
SI1145_REG_IRQMODE2 = 0x06
SI1145_REG_HWKEY = 0x07
SI1145_REG_MEASRATE0 = 0x08
SI1145_REG_MEASRATE1 = 0x09
SI1145_REG_PSRATE = 0x0A
SI1145_REG_PSLED21 = 0x0F
SI1145_REG_PSLED3 = 0x10
SI1145_REG_UCOEFF0 = 0x13
SI1145_REG_UCOEFF1 = 0x14
SI1145_REG_UCOEFF2 = 0x15
SI1145_REG_UCOEFF3 = 0x16
SI1145_REG_PARAMWR = 0x17
SI1145_REG_COMMAND = 0x18
SI1145_REG_RESPONSE = 0x20
SI1145_REG_IRQSTAT = 0x21
SI1145_REG_IRQSTAT_ALS = 0x01
SI1145_REG_ALSVISDATA0 = 0x22
SI1145_REG_ALSVISDATA1 = 0x23
SI1145_REG_ALSIRDATA0 = 0x24
SI1145_REG_ALSIRDATA1 = 0x25
SI1145_REG_PS1DATA0 = 0x26
SI1145_REG_PS1DATA1 = 0x27
SI1145_REG_PS2DATA0 = 0x28
SI1145_REG_PS2DATA1 = 0x29
SI1145_REG_PS3DATA0 = 0x2A
SI1145_REG_PS3DATA1 = 0x2B
SI1145_REG_UVINDEX0 = 0x2C
SI1145_REG_UVINDEX1 = 0x2D
SI1145_REG_PARAMRD = 0x2E
SI1145_REG_CHIPSTAT = 0x30
# I2C Address
SI1145_ADDR = 0x60
class SI1145(object):
def __init__(self, address=SI1145_ADDR, busnum=I2C.get_default_bus()):
self._logger = logging.getLogger('SI1145')
# Create I2C device.
self._device = I2C.Device(address, busnum)
#reset device
self._reset()
# Load calibration values.
self._load_calibration()
# device reset
def _reset(self):
self._device.write8(SI1145_REG_MEASRATE0, 0)
self._device.write8(SI1145_REG_MEASRATE1, 0)
self._device.write8(SI1145_REG_IRQEN, 0)
self._device.write8(SI1145_REG_IRQMODE1, 0)
self._device.write8(SI1145_REG_IRQMODE2, 0)
self._device.write8(SI1145_REG_INTCFG, 0)
self._device.write8(SI1145_REG_IRQSTAT, 0xFF)
self._device.write8(SI1145_REG_COMMAND, SI1145_RESET)
time.sleep(.01)
self._device.write8(SI1145_REG_HWKEY, 0x17)
time.sleep(.01)
# write Param
def writeParam(self, p, v):
self._device.write8(SI1145_REG_PARAMWR, v)
self._device.write8(SI1145_REG_COMMAND, p | SI1145_PARAM_SET)
paramVal = self._device.readU8(SI1145_REG_PARAMRD)
return paramVal
# load calibration to sensor
def _load_calibration(self):
# /***********************************/
# Enable UVindex measurement coefficients!
self._device.write8(SI1145_REG_UCOEFF0, 0x29)
self._device.write8(SI1145_REG_UCOEFF1, 0x89)
self._device.write8(SI1145_REG_UCOEFF2, 0x02)
self._device.write8(SI1145_REG_UCOEFF3, 0x00)
# Enable UV sensor
self.writeParam(SI1145_PARAM_CHLIST, SI1145_PARAM_CHLIST_ENUV | SI1145_PARAM_CHLIST_ENALSIR | SI1145_PARAM_CHLIST_ENALSVIS | SI1145_PARAM_CHLIST_ENPS1)
# Enable interrupt on every sample
self._device.write8(SI1145_REG_INTCFG, SI1145_REG_INTCFG_INTOE)
self._device.write8(SI1145_REG_IRQEN, SI1145_REG_IRQEN_ALSEVERYSAMPLE)
# /****************************** Prox Sense 1 */
# Program LED current
self._device.write8(SI1145_REG_PSLED21, 0x03) # 20mA for LED 1 only
self.writeParam(SI1145_PARAM_PS1ADCMUX, SI1145_PARAM_ADCMUX_LARGEIR)
# Prox sensor #1 uses LED #1
self.writeParam(SI1145_PARAM_PSLED12SEL, SI1145_PARAM_PSLED12SEL_PS1LED1)
# Fastest clocks, clock div 1
self.writeParam(SI1145_PARAM_PSADCGAIN, 0)
# Take 511 clocks to measure
self.writeParam(SI1145_PARAM_PSADCOUNTER, SI1145_PARAM_ADCCOUNTER_511CLK)
# in prox mode, high range
self.writeParam(SI1145_PARAM_PSADCMISC, SI1145_PARAM_PSADCMISC_RANGE | SI1145_PARAM_PSADCMISC_PSMODE)
self.writeParam(SI1145_PARAM_ALSIRADCMUX, SI1145_PARAM_ADCMUX_SMALLIR)
# Fastest clocks, clock div 1
self.writeParam(SI1145_PARAM_ALSIRADCGAIN, 0)
# Take 511 clocks to measure
self.writeParam(SI1145_PARAM_ALSIRADCOUNTER, SI1145_PARAM_ADCCOUNTER_511CLK)
# in high range mode
self.writeParam(SI1145_PARAM_ALSIRADCMISC, SI1145_PARAM_ALSIRADCMISC_RANGE)
# fastest clocks, clock div 1
self.writeParam(SI1145_PARAM_ALSVISADCGAIN, 0)
# Take 511 clocks to measure
self.writeParam(SI1145_PARAM_ALSVISADCOUNTER, SI1145_PARAM_ADCCOUNTER_511CLK)
# in high range mode (not normal signal)
self.writeParam(SI1145_PARAM_ALSVISADCMISC, SI1145_PARAM_ALSVISADCMISC_VISRANGE)
# measurement rate for auto
self._device.write8(SI1145_REG_MEASRATE0, 0xFF) # 255 * 31.25uS = 8ms
# auto run
self._device.write8(SI1145_REG_COMMAND, SI1145_PSALS_AUTO)
# returns the UV index * 100 (divide by 100 to get the index)
def readUV(self):
return self._device.readU16LE(0x2C)
#returns visible + IR light levels
def readVisible(self):
return self._device.readU16LE(0x22)
#returns IR light levels
def readIR(self):
return self._device.readU16LE(0x24)
# Returns "Proximity" - assumes an IR LED is attached to LED
def readProx(self):
return self._device.readU16LE(0x26)

View file

@ -0,0 +1,53 @@
#!/usr/bin/python
# Author: Joe Gutting
# With use of Adafruit SI1145 library for Arduino, Adafruit_GPIO.I2C & BMP Library by Tony DiCola
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# Can enable debug output by uncommenting:
#import logging
#logging.basicConfig(level=logging.DEBUG)
import time
import SI1145
# Default constructor will pick a default I2C bus.
#
# For the Raspberry Pi this means you should hook up to the only exposed I2C bus
# from the main GPIO header and the library will figure out the bus number based
# on the Pi's revision.
sensor = SI1145.SI1145()
print('Press Cntrl + Z to stop')
print('')
while True:
vis = sensor.readVisible()
IR = sensor.readIR()
UV = sensor.readUV()
uvIndex = UV / 100.0
print('Vis: ' + str(vis))
print('IR: ' + str(IR))
print('UV Index: ' + str(uvIndex))
print('')
time.sleep(1)

View file

@ -0,0 +1,47 @@
#!/usr/bin/env python
#
# GrovePi Example for using the Grove - Temperature&Humidity Sensor (HDC1000)(http://www.seeedstudio.com/depot/Grove-TemperatureHumidity-Sensor-HDC1000-p-2535.html)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this example? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
# This example is derived from the HDC1000 example by control everyhing here: https://github.com/ControlEverythingCommunity/HDC1000/blob/master/Python/HDC1000.py
'''
## License
The MIT License (MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2017 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
from grove_i2c_temp_hum_hdc1000 import HDC1000
import time
hdc = HDC1000()
hdc.Config()
while 1:
print('Temp : %.2f C' % hdc.Temperature())
print('Humidity: %.2f %%' % hdc.Humidity())
print('-' * 17)
time.sleep(1)

View file

@ -0,0 +1,72 @@
#!/usr/bin/env python
#
# GrovePi Library for using the Grove - Temperature&Humidity Sensor (HDC1000)(http://www.seeedstudio.com/depot/Grove-TemperatureHumidity-Sensor-HDC1000-p-2535.html)
#
# The GrovePi connects the Raspberry Pi and Grove sensors. You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
#
# Have a question about this library? Ask on the forums here: http://forum.dexterindustries.com/c/grovepi
#
# This library is derived from the HDC1000 library by aklib here: https://github.com/nonNoise/akilib/blob/master/akilib/raspberrypi/AKI_I2C_HDC1000.py
#
# Released under the MIT license (http://choosealicense.com/licenses/mit/).
# For more information see https://github.com/DexterInd/GrovePi/blob/master/LICENSE
import smbus
import RPi.GPIO as GPIO
import time
rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
bus = smbus.SMBus(1)
else:
bus = smbus.SMBus(0)
class HDC1000:
I2C_ADDR = 0
def __init__(self):
self.I2C_ADDR=0x40
def Config(self):
# HDC1000 address, 0x40(64)
# Select configuration register, 0x02(02)
# 0x30(48) Temperature, Humidity enabled, Resolultion = 14-bits, Heater on
bus.write_byte_data(self.I2C_ADDR, 0x02, 0x30)
def Temperature(self):
try :
bus.write_byte(self.I2C_ADDR,0x00)
time.sleep(0.50)
# Read data back, 2 bytes
# temp MSB, temp LSB
data0 = bus.read_byte(0x40)
data1 = bus.read_byte(0x40)
# Convert the data
temp = (data0 * 256) + data1
cTemp = (temp / 65536.0) * 165.0 - 40
return cTemp
except IOError as err:
print("No ACK!")
time.sleep(0.1)
self.Temperature()
def Humidity(self):
try :
bus.write_byte(self.I2C_ADDR,0x01)
time.sleep(0.50)
# Read data back, 2 bytes
# humidity MSB, humidity LSB
data0 = bus.read_byte(0x40)
data1 = bus.read_byte(0x40)
# Convert the data
humidity = (data0 * 256) + data1
humidity = (humidity / 65536.0) * 100.0
return humidity
except IOError as err:
print("No ACK!")
time.sleep(0.1)
self.Humidity()

Some files were not shown because too many files have changed in this diff Show more