first commit
This commit is contained in:
commit
a5a0434432
1126 changed files with 439481 additions and 0 deletions
64
Software/Python/GrovePi_Hardware_Test.py
Normal file
64
Software/Python/GrovePi_Hardware_Test.py
Normal 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
30
Software/Python/README.md
Executable 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.
|
||||
63
Software/Python/firmware_tests/digital_analog.py
Normal file
63
Software/Python/firmware_tests/digital_analog.py
Normal 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")
|
||||
51
Software/Python/firmware_tests/multi_analog_read.py
Normal file
51
Software/Python/firmware_tests/multi_analog_read.py
Normal 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")
|
||||
55
Software/Python/firmware_tests/multi_digital_read.py
Normal file
55
Software/Python/firmware_tests/multi_digital_read.py
Normal 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")
|
||||
64
Software/Python/firmware_tests/multi_led_blink.py
Normal file
64
Software/Python/firmware_tests/multi_led_blink.py
Normal 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")
|
||||
63
Software/Python/grove_2_coil_latching_relay.py
Normal file
63
Software/Python/grove_2_coil_latching_relay.py
Normal 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")
|
||||
158
Software/Python/grove_4_digit_display.py
Normal file
158
Software/Python/grove_4_digit_display.py
Normal 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")
|
||||
|
|
@ -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")
|
||||
|
||||
211
Software/Python/grove_6axis_acc_compass/lsm303d.py
Normal file
211
Software/Python/grove_6axis_acc_compass/lsm303d.py
Normal 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()
|
||||
64
Software/Python/grove_80cm_infrared_proximity_sensor.py
Normal file
64
Software/Python/grove_80cm_infrared_proximity_sensor.py
Normal 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")
|
||||
26
Software/Python/grove_accelerometer_16g/LICENSE.txt
Normal file
26
Software/Python/grove_accelerometer_16g/LICENSE.txt
Normal 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.
|
||||
24
Software/Python/grove_accelerometer_16g/README.md
Normal file
24
Software/Python/grove_accelerometer_16g/README.md
Normal 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.
|
||||
112
Software/Python/grove_accelerometer_16g/adxl345.py
Normal file
112
Software/Python/grove_accelerometer_16g/adxl345.py
Normal 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'] ))
|
||||
19
Software/Python/grove_accelerometer_16g/basic_example.py
Normal file
19
Software/Python/grove_accelerometer_16g/basic_example.py
Normal 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)
|
||||
|
||||
17
Software/Python/grove_accelerometer_16g/example.py
Normal file
17
Software/Python/grove_accelerometer_16g/example.py
Normal 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'] ))
|
||||
64
Software/Python/grove_air_quality_sensor.py
Normal file
64
Software/Python/grove_air_quality_sensor.py
Normal 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")
|
||||
50
Software/Python/grove_analog_read.py
Normal file
50
Software/Python/grove_analog_read.py
Normal 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")
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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.
|
||||
|
|
@ -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")
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
|
@ -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))
|
||||
|
|
@ -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)
|
||||
50
Software/Python/grove_button.py
Normal file
50
Software/Python/grove_button.py
Normal 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")
|
||||
61
Software/Python/grove_buzzer.py
Normal file
61
Software/Python/grove_buzzer.py
Normal 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")
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
Binary file not shown.
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
@ -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)
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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")
|
||||
|
|
@ -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")
|
||||
|
|
@ -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")
|
||||
46
Software/Python/grove_co2_sensor/grove_co2_example.py
Normal file
46
Software/Python/grove_co2_sensor/grove_co2_example.py
Normal 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)
|
||||
|
||||
61
Software/Python/grove_co2_sensor/grove_co2_lib.py
Normal file
61
Software/Python/grove_co2_sensor/grove_co2_lib.py
Normal 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)
|
||||
50
Software/Python/grove_collision_sensor.py
Normal file
50
Software/Python/grove_collision_sensor.py
Normal 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")
|
||||
43
Software/Python/grove_compass_example.py
Normal file
43
Software/Python/grove_compass_example.py
Normal 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)
|
||||
102
Software/Python/grove_compass_lib.py
Normal file
102
Software/Python/grove_compass_lib.py
Normal 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)
|
||||
|
||||
58
Software/Python/grove_dht_pro.py
Normal file
58
Software/Python/grove_dht_pro.py
Normal 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")
|
||||
210
Software/Python/grove_dht_pro_filter/grove_dht.py
Normal file
210
Software/Python/grove_dht_pro_filter/grove_dht.py
Normal 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]")
|
||||
56
Software/Python/grove_dht_pro_filter/grove_dht_example1.py
Normal file
56
Software/Python/grove_dht_pro_filter/grove_dht_example1.py
Normal 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
|
||||
66
Software/Python/grove_dht_pro_filter/grove_dht_example2.py
Normal file
66
Software/Python/grove_dht_pro_filter/grove_dht_example2.py
Normal 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
|
||||
90
Software/Python/grove_dht_pro_filter/grove_dht_example3.py
Normal file
90
Software/Python/grove_dht_pro_filter/grove_dht_example3.py
Normal 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()
|
||||
64
Software/Python/grove_dry_reed_relay.py
Normal file
64
Software/Python/grove_dry_reed_relay.py
Normal 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")
|
||||
65
Software/Python/grove_dust_sensor.py
Normal file
65
Software/Python/grove_dust_sensor.py
Normal 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()
|
||||
|
|
@ -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()
|
||||
68
Software/Python/grove_electricity_sensor.py
Normal file
68
Software/Python/grove_electricity_sensor.py
Normal 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")
|
||||
65
Software/Python/grove_electromagnet.py
Normal file
65
Software/Python/grove_electromagnet.py
Normal 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")
|
||||
63
Software/Python/grove_encoder_read.py
Normal file
63
Software/Python/grove_encoder_read.py
Normal 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()
|
||||
|
|
@ -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)
|
||||
45
Software/Python/grove_firmware_version_check.py
Normal file
45
Software/Python/grove_firmware_version_check.py
Normal 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")
|
||||
50
Software/Python/grove_flame_sensor.py
Normal file
50
Software/Python/grove_flame_sensor.py
Normal 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")
|
||||
66
Software/Python/grove_flow_read.py
Normal file
66
Software/Python/grove_flow_read.py
Normal 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()
|
||||
72
Software/Python/grove_gas_sensor.py
Normal file
72
Software/Python/grove_gas_sensor.py
Normal 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")
|
||||
46
Software/Python/grove_gesture_sensor/README.md
Normal file
46
Software/Python/grove_gesture_sensor/README.md
Normal 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.
|
||||
44
Software/Python/grove_gesture_sensor/gesture_print.py
Normal file
44
Software/Python/grove_gesture_sensor/gesture_print.py
Normal 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)
|
||||
68
Software/Python/grove_gesture_sensor/gesture_value.py
Normal file
68
Software/Python/grove_gesture_sensor/gesture_value.py
Normal 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)
|
||||
533
Software/Python/grove_gesture_sensor/grove_gesture_sensor.py
Normal file
533
Software/Python/grove_gesture_sensor/grove_gesture_sensor.py
Normal 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)
|
||||
74
Software/Python/grove_gps/GroveGPS.py
Normal file
74
Software/Python/grove_gps/GroveGPS.py
Normal 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."
|
||||
74
Software/Python/grove_gps/README.md
Normal file
74
Software/Python/grove_gps/README.md
Normal 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)
|
||||
168
Software/Python/grove_gps/dextergps.py
Normal file
168
Software/Python/grove_gps/dextergps.py
Normal 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)
|
||||
192
Software/Python/grove_gps/grove_gps_data.py
Executable file
192
Software/Python/grove_gps/grove_gps_data.py
Executable 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)
|
||||
|
||||
85
Software/Python/grove_gps/grove_gps_hardware_test.py
Normal file
85
Software/Python/grove_gps/grove_gps_hardware_test.py
Normal 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
|
||||
'''
|
||||
62
Software/Python/grove_hcho_sensor.py
Normal file
62
Software/Python/grove_hcho_sensor.py
Normal 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")
|
||||
55
Software/Python/grove_hightemperature_sensor/README.md
Normal file
55
Software/Python/grove_hightemperature_sensor/README.md
Normal 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`.
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
1277
Software/Python/grove_hightemperature_sensor/thermocouple_table.json
Normal file
1277
Software/Python/grove_hightemperature_sensor/thermocouple_table.json
Normal file
File diff suppressed because it is too large
Load diff
49
Software/Python/grove_i2c_accelerometer.py
Normal file
49
Software/Python/grove_i2c_accelerometer.py
Normal 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")
|
||||
5
Software/Python/grove_i2c_adc/README.md
Normal file
5
Software/Python/grove_i2c_adc/README.md
Normal 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
|
||||
49
Software/Python/grove_i2c_adc/grove_i2c_adc.py
Normal file
49
Software/Python/grove_i2c_adc/grove_i2c_adc.py
Normal 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)
|
||||
45
Software/Python/grove_i2c_adc/i2c_adc_example.py
Normal file
45
Software/Python/grove_i2c_adc/i2c_adc_example.py
Normal 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)
|
||||
|
|
@ -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")
|
||||
326
Software/Python/grove_i2c_color_sensor/grove_i2c_color_sensor.py
Normal file
326
Software/Python/grove_i2c_color_sensor/grove_i2c_color_sensor.py
Normal 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
|
||||
161
Software/Python/grove_i2c_digital_light_sensor/Adafruit_I2C.py
Normal file
161
Software/Python/grove_i2c_digital_light_sensor/Adafruit_I2C.py
Normal 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")
|
||||
|
|
@ -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()
|
||||
|
|
@ -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.
|
||||
|
|
@ -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)
|
||||
76
Software/Python/grove_i2c_motor_driver/motor_example.py
Normal file
76
Software/Python/grove_i2c_motor_driver/motor_example.py
Normal 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")
|
||||
|
||||
|
|
@ -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()
|
||||
320
Software/Python/grove_i2c_oled_128_64/grove_128_64_oled.py
Normal file
320
Software/Python/grove_i2c_oled_128_64/grove_128_64_oled.py
Normal 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)
|
||||
|
|
@ -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
|
||||
49
Software/Python/grove_i2c_rtc.py
Normal file
49
Software/Python/grove_i2c_rtc.py
Normal 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")
|
||||
195
Software/Python/grove_i2c_sunlight_sensor/I2C.py
Normal file
195
Software/Python/grove_i2c_sunlight_sensor/I2C.py
Normal 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)
|
||||
106
Software/Python/grove_i2c_sunlight_sensor/Platform.py
Normal file
106
Software/Python/grove_i2c_sunlight_sensor/Platform.py
Normal 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
|
||||
7
Software/Python/grove_i2c_sunlight_sensor/README.md
Normal file
7
Software/Python/grove_i2c_sunlight_sensor/README.md
Normal 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)
|
||||
264
Software/Python/grove_i2c_sunlight_sensor/SI1145.py
Normal file
264
Software/Python/grove_i2c_sunlight_sensor/SI1145.py
Normal 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)
|
||||
|
||||
53
Software/Python/grove_i2c_sunlight_sensor/simpletest.py
Normal file
53
Software/Python/grove_i2c_sunlight_sensor/simpletest.py
Normal 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)
|
||||
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue