JoyPi-Advanced-RaspberryPi 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- JoyPi_Advanced_RaspberryPi/LEDMatrix.py +166 -0
- JoyPi_Advanced_RaspberryPi/__init__.py +14 -0
- JoyPi_Advanced_RaspberryPi/adc.py +91 -0
- JoyPi_Advanced_RaspberryPi/barometer.py +104 -0
- JoyPi_Advanced_RaspberryPi/buttonmatrix.py +130 -0
- JoyPi_Advanced_RaspberryPi/colour.py +123 -0
- JoyPi_Advanced_RaspberryPi/gyroscope.py +134 -0
- JoyPi_Advanced_RaspberryPi/servomotor.py +88 -0
- JoyPi_Advanced_RaspberryPi/stepmotor.py +116 -0
- joypi_advanced_raspberrypi-2.0.0.dist-info/METADATA +98 -0
- joypi_advanced_raspberrypi-2.0.0.dist-info/RECORD +13 -0
- joypi_advanced_raspberrypi-2.0.0.dist-info/WHEEL +4 -0
- joypi_advanced_raspberrypi-2.0.0.dist-info/licenses/LICENSE +674 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from rpi_ws281x import PixelStrip, Color
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class LEDMatrix:
|
|
6
|
+
"""
|
|
7
|
+
The Joy-Pi Advanced 2 is no longer compatible with this library for the LED
|
|
8
|
+
matrix. To ensure compatibility with the Raspberry Pi 5, the LED matrix is now
|
|
9
|
+
controlled via I²C because of the RP2040 microcontroller chip. The LED matrix
|
|
10
|
+
can now be controlled with the Joy-Pi Advanced via this repository
|
|
11
|
+
http://github.com/joy-it/JoyPi_RGB_Matrix_RaspberryPi
|
|
12
|
+
"""
|
|
13
|
+
def __init__(self, pin = 18, brightness = 100):
|
|
14
|
+
# LED strip configuration
|
|
15
|
+
self.LED_COUNT = 64 # Number of pixels
|
|
16
|
+
self.LED_PIN = pin # GPIO pin to which the module is connected
|
|
17
|
+
self.LED_FREQ_HZ = 800000 # LED signal frequency
|
|
18
|
+
self.LED_DMA = 10 # DMA channel used to generate the signal
|
|
19
|
+
self.LED_BRIGHTNESS = brightness # Brightness setting
|
|
20
|
+
self.LED_INVERT = False # Signal inversion
|
|
21
|
+
self.LED_CHANNEL = 0 # Set to 1 if GPIOs 13, 19, 41, 45 or 53 are used
|
|
22
|
+
|
|
23
|
+
self.RIGHT_BORDER = [7,15,23,31,39,47,55,63]
|
|
24
|
+
self.LEFT_BORDER = [0,8,16,24,32,40,48,56]
|
|
25
|
+
|
|
26
|
+
# Create NeoPixel object
|
|
27
|
+
self.strip = PixelStrip(self.LED_COUNT, self.LED_PIN, self.LED_FREQ_HZ, self.LED_DMA, self.LED_INVERT, self.LED_BRIGHTNESS, self.LED_CHANNEL)
|
|
28
|
+
|
|
29
|
+
# Initialize library
|
|
30
|
+
self.strip.begin()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def clean(self):
|
|
34
|
+
"""
|
|
35
|
+
Switch off all LEDs
|
|
36
|
+
"""
|
|
37
|
+
for i in range(self.strip.numPixels()):
|
|
38
|
+
self.strip.setPixelColor(i, Color(0, 0, 0))
|
|
39
|
+
self.strip.show()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def setPixel(self, position, colour):
|
|
43
|
+
"""
|
|
44
|
+
set Pixel on position to given colour
|
|
45
|
+
"""
|
|
46
|
+
try:
|
|
47
|
+
r, g, b = colour
|
|
48
|
+
except ValueError:
|
|
49
|
+
print("Colour is not a tuple!")
|
|
50
|
+
|
|
51
|
+
self.strip.setPixelColor(position, Color(r, g, b))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def RGB_on(self,colour):
|
|
55
|
+
"""
|
|
56
|
+
set all pixels to given colour
|
|
57
|
+
"""
|
|
58
|
+
try:
|
|
59
|
+
r, g, b = colour
|
|
60
|
+
except ValueError:
|
|
61
|
+
print("Colour is not a tuple!")
|
|
62
|
+
|
|
63
|
+
for i in range(64):
|
|
64
|
+
self.strip.setPixelColor(i,Color(r, g, b))
|
|
65
|
+
self.strip.show()
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def wheel(self,pos):
|
|
69
|
+
"""
|
|
70
|
+
generate rainbow colours over positions 0-255
|
|
71
|
+
"""
|
|
72
|
+
if pos < 85:
|
|
73
|
+
return Color(pos * 3, 255 - pos * 3, 0)
|
|
74
|
+
elif pos < 170:
|
|
75
|
+
pos -= 85
|
|
76
|
+
return Color(255 - pos * 3, 0, pos * 3)
|
|
77
|
+
else:
|
|
78
|
+
pos -= 170
|
|
79
|
+
return Color(0, pos * 3, 255 - pos * 3)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def rainbow(self, wait_ms=20, iterations=1):
|
|
83
|
+
"""
|
|
84
|
+
Rainbow effect on all LEDs
|
|
85
|
+
"""
|
|
86
|
+
for j in range(256 * iterations):
|
|
87
|
+
for i in range(self.strip.numPixels()):
|
|
88
|
+
self.strip.setPixelColor(i, self.wheel((i + j) & 255))
|
|
89
|
+
self.strip.show()
|
|
90
|
+
time.sleep(wait_ms / 1000.0)
|
|
91
|
+
self.clean()
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def colourWipe(self, colour, wait_ms=50):
|
|
95
|
+
"""
|
|
96
|
+
Move colours pixel by pixel over the LEDs with a given colour
|
|
97
|
+
"""
|
|
98
|
+
try:
|
|
99
|
+
r, g, b = colour
|
|
100
|
+
except ValueError:
|
|
101
|
+
print("Colour is not a tuple!")
|
|
102
|
+
|
|
103
|
+
for i in range(self.strip.numPixels()):
|
|
104
|
+
self.strip.setPixelColor(i, Color(r, g, b))
|
|
105
|
+
self.strip.show()
|
|
106
|
+
time.sleep(wait_ms / 1000.0)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def theaterChase(self, colour, wait_ms=50, iterations=10):
|
|
110
|
+
"""
|
|
111
|
+
Chaser animation with a given colour
|
|
112
|
+
"""
|
|
113
|
+
try:
|
|
114
|
+
r, g, b = colour
|
|
115
|
+
except ValueError:
|
|
116
|
+
print("Colour is not a tuple!")
|
|
117
|
+
|
|
118
|
+
for j in range(iterations):
|
|
119
|
+
for q in range(3):
|
|
120
|
+
for i in range(0, self.strip.numPixels(), 3):
|
|
121
|
+
self.strip.setPixelColor(i + q, Color(r, g, b))
|
|
122
|
+
self.strip.show()
|
|
123
|
+
time.sleep(wait_ms / 1000.0)
|
|
124
|
+
for i in range(0, self.strip.numPixels(), 3):
|
|
125
|
+
self.strip.setPixelColor(i + q, 0)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def demo1(self):
|
|
129
|
+
"""
|
|
130
|
+
Simple demo programm
|
|
131
|
+
"""
|
|
132
|
+
self.theaterChase((127, 127, 127)) # White chaser
|
|
133
|
+
self.theaterChase((127, 0, 0)) # Red chaser
|
|
134
|
+
self.theaterChase((0, 0, 127)) # Blue chaser
|
|
135
|
+
|
|
136
|
+
self.rainbow()
|
|
137
|
+
|
|
138
|
+
self.clean()
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def show(self):
|
|
142
|
+
"""
|
|
143
|
+
displays set pixels
|
|
144
|
+
"""
|
|
145
|
+
self.strip.show()
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def demo2(self):
|
|
149
|
+
"""
|
|
150
|
+
More complex demo programm in a continuous loop
|
|
151
|
+
"""
|
|
152
|
+
heart = [1,6,8,9,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,41,42,43,44,45,46,50,51,52,53,59,60]
|
|
153
|
+
try:
|
|
154
|
+
for i in range(3):
|
|
155
|
+
self.demo1()
|
|
156
|
+
while True:
|
|
157
|
+
for j in range(256):
|
|
158
|
+
for i in heart:
|
|
159
|
+
self.strip.setPixelColor(i,Color(j,0,0))
|
|
160
|
+
self.strip.show()
|
|
161
|
+
for j in range(256, 0, -1):
|
|
162
|
+
for i in heart:
|
|
163
|
+
self.strip.setPixelColor(i,Color(j,0,0))
|
|
164
|
+
self.strip.show()
|
|
165
|
+
except KeyboardInterrupt:
|
|
166
|
+
self.clean()
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from .servomotor import servomotor
|
|
2
|
+
from .stepmotor import stepmotor
|
|
3
|
+
from .gyroscope import gyroscope
|
|
4
|
+
from .barometer import barometer
|
|
5
|
+
from .buttonmatrix import buttonmatrix
|
|
6
|
+
from .colour import colour
|
|
7
|
+
from .adc import adc
|
|
8
|
+
|
|
9
|
+
try:
|
|
10
|
+
from .LEDMatrix import LEDMatrix
|
|
11
|
+
except Exception:
|
|
12
|
+
LEDMatrix = None
|
|
13
|
+
|
|
14
|
+
name = "JoyPiAdvanced"
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
from spidev import SpiDev
|
|
2
|
+
from gpiozero import DigitalOutputDevice
|
|
3
|
+
|
|
4
|
+
class adc:
|
|
5
|
+
SYSTEM_STATUS = 0x00
|
|
6
|
+
READ_CMD = 0x10
|
|
7
|
+
WRITE_CMD = 0x08
|
|
8
|
+
CHANNEL_SEL = 0x11
|
|
9
|
+
PIN_CFG = 0x05
|
|
10
|
+
SEQUENCE_CFG = 0x10
|
|
11
|
+
|
|
12
|
+
def __init__(self, bus = 0, device = 0, cs = 8):
|
|
13
|
+
"""
|
|
14
|
+
initialize ADC
|
|
15
|
+
bus - select bus
|
|
16
|
+
device - select device
|
|
17
|
+
"""
|
|
18
|
+
self.bus, self.device = bus, device
|
|
19
|
+
self.spi = SpiDev()
|
|
20
|
+
self.open()
|
|
21
|
+
self.spi.max_speed_hz = 1000000 # 1MHz
|
|
22
|
+
self.spi.mode = 0
|
|
23
|
+
self.cs = DigitalOutputDevice(cs, initial_value = True)
|
|
24
|
+
|
|
25
|
+
def open(self):
|
|
26
|
+
"""
|
|
27
|
+
start SPI communication
|
|
28
|
+
"""
|
|
29
|
+
self.spi.open(self.bus, self.device)
|
|
30
|
+
self.spi.max_speed_hz = 1000000 # 1MHz
|
|
31
|
+
|
|
32
|
+
def read_value(self, channel):
|
|
33
|
+
"""
|
|
34
|
+
returns raw value from a specific channel
|
|
35
|
+
channel - which channel should be read from
|
|
36
|
+
"""
|
|
37
|
+
data = self.read_register(self.SEQUENCE_CFG)
|
|
38
|
+
self.write_register(self.SEQUENCE_CFG, data[0] & 0xFC)
|
|
39
|
+
self.write_register(self.PIN_CFG, 0x00)
|
|
40
|
+
self.write_register(self.SEQUENCE_CFG, 0x00)
|
|
41
|
+
self.write_register(self.CHANNEL_SEL, channel)
|
|
42
|
+
self.cs.toggle()
|
|
43
|
+
self.spi.readbytes(2)
|
|
44
|
+
self.cs.toggle()
|
|
45
|
+
self.cs.toggle()
|
|
46
|
+
data = self.spi.readbytes(2)
|
|
47
|
+
self.cs.toggle()
|
|
48
|
+
return ((data[0]<<8) | data[1]) >>4
|
|
49
|
+
|
|
50
|
+
def read_voltage(self, channel, value = None):
|
|
51
|
+
"""
|
|
52
|
+
returns measured voltage from a specific channel
|
|
53
|
+
channel - which should be read from
|
|
54
|
+
value - if channel is already read, raw value can be then used to calculate voltage
|
|
55
|
+
"""
|
|
56
|
+
if value is None:
|
|
57
|
+
return round((self.read_value(channel) / 4096) * 5.0, 2)
|
|
58
|
+
return round((value / 4096) * 5.0, 2)
|
|
59
|
+
|
|
60
|
+
def close(self):
|
|
61
|
+
"""
|
|
62
|
+
end SPI communication
|
|
63
|
+
"""
|
|
64
|
+
self.spi.close()
|
|
65
|
+
self.cs.close()
|
|
66
|
+
|
|
67
|
+
def read_register(self, reg):
|
|
68
|
+
"""
|
|
69
|
+
returns value from a specific register
|
|
70
|
+
reg - register which should be read from
|
|
71
|
+
"""
|
|
72
|
+
self.cs.toggle()
|
|
73
|
+
self.spi.writebytes([self.READ_CMD, reg, 0x00])
|
|
74
|
+
self.cs.toggle()
|
|
75
|
+
return self.spi.readbytes(1)
|
|
76
|
+
|
|
77
|
+
def write_register(self, reg, data):
|
|
78
|
+
"""
|
|
79
|
+
write value into a specific register
|
|
80
|
+
reg - register in which should be written
|
|
81
|
+
data - value which should be written into the register
|
|
82
|
+
"""
|
|
83
|
+
self.cs.toggle()
|
|
84
|
+
self.spi.writebytes([self.WRITE_CMD, reg, data])
|
|
85
|
+
self.cs.toggle()
|
|
86
|
+
|
|
87
|
+
def read_status(self):
|
|
88
|
+
"""
|
|
89
|
+
return status of the ADC
|
|
90
|
+
"""
|
|
91
|
+
return self.read_register(self.SYSTEM_STATUS)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import busio
|
|
2
|
+
from adafruit_bus_device import i2c_device
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
class barometer:
|
|
6
|
+
|
|
7
|
+
RESET = 0x1E
|
|
8
|
+
READ = 0x00
|
|
9
|
+
CONV = 0x40
|
|
10
|
+
D1 = 0x00
|
|
11
|
+
D2 = 0x10
|
|
12
|
+
PROM_RD = 0xA0
|
|
13
|
+
ADC_RESOLUTION = {256: 0x00,
|
|
14
|
+
512: 0x02,
|
|
15
|
+
1024: 0x04,
|
|
16
|
+
2048: 0x06,
|
|
17
|
+
4096: 0x08}
|
|
18
|
+
ADC_DELAY = {0x00: 0.001,
|
|
19
|
+
0x02: 0.003,
|
|
20
|
+
0x04: 0.004,
|
|
21
|
+
0x06: 0.006,
|
|
22
|
+
0x08: 0.01}
|
|
23
|
+
|
|
24
|
+
def __init__(self, i2c: busio.I2C, i2c_address = 0x77, resolution=4096):
|
|
25
|
+
"""
|
|
26
|
+
i2c - i2c port
|
|
27
|
+
i2c_address - address of the barometer
|
|
28
|
+
resolution - resolution of the ADC, possible values: 256, 512, 1024, 2048, 4096
|
|
29
|
+
"""
|
|
30
|
+
self.i2c_address = i2c_address
|
|
31
|
+
self.device = i2c_device.I2CDevice(i2c, self.i2c_address)
|
|
32
|
+
self.resolution = self.ADC_RESOLUTION[resolution]
|
|
33
|
+
self.reset()
|
|
34
|
+
self._coefficients = self.read_coefficients()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def reset(self):
|
|
38
|
+
"""
|
|
39
|
+
resets barometer
|
|
40
|
+
"""
|
|
41
|
+
with self.device as bus_device:
|
|
42
|
+
bus_device.write(bytes([self.RESET]))
|
|
43
|
+
|
|
44
|
+
def read_coefficient(self, index):
|
|
45
|
+
"""
|
|
46
|
+
read value for a specific coefficient
|
|
47
|
+
"""
|
|
48
|
+
with self.device as bus_device:
|
|
49
|
+
time.sleep(0.01)
|
|
50
|
+
bus_device.write(bytes([self.PROM_RD + index * 2]))
|
|
51
|
+
result = bytearray(2)
|
|
52
|
+
bus_device.readinto(result)
|
|
53
|
+
result1, result2 = result[0], result[1]
|
|
54
|
+
return (256 * result1) + result2
|
|
55
|
+
|
|
56
|
+
def read_coefficients(self):
|
|
57
|
+
"""
|
|
58
|
+
set values too all coefficients
|
|
59
|
+
"""
|
|
60
|
+
coef = [0] * 6
|
|
61
|
+
for i in range(6):
|
|
62
|
+
coef[i] = self.read_coefficient(i+1)
|
|
63
|
+
if coef[i] == 0 : coef[i] = self.read_coefficient(i+1)
|
|
64
|
+
return coef
|
|
65
|
+
|
|
66
|
+
def conversion(self, data):
|
|
67
|
+
"""
|
|
68
|
+
read digital data
|
|
69
|
+
"""
|
|
70
|
+
with self.device as bus_device:
|
|
71
|
+
time.sleep(0.01)
|
|
72
|
+
bus_device.write(bytes([0x40 | data | self.resolution]))
|
|
73
|
+
time.sleep(self.ADC_DELAY[self.resolution])
|
|
74
|
+
bus_device.write(bytes([self.READ]))
|
|
75
|
+
result = bytearray(3)
|
|
76
|
+
bus_device.readinto(result)
|
|
77
|
+
return 65536 * result[0] + 256 * result[1] + result [2]
|
|
78
|
+
|
|
79
|
+
def get_pressure(self):
|
|
80
|
+
"""
|
|
81
|
+
calculates the measured pressure
|
|
82
|
+
"""
|
|
83
|
+
d1 = self.conversion(self.D1)
|
|
84
|
+
d2 = self.conversion(self.D2)
|
|
85
|
+
dT = d2 - self._coefficients[4] * 256
|
|
86
|
+
off = self._coefficients[1] * 131072 + (self._coefficients[3] * dT)/ 64
|
|
87
|
+
sens = self._coefficients[0] * 65536 + (self._coefficients[2] * dT) / 128
|
|
88
|
+
return round(((d1 * sens / 2097152 - off) / 32768) / 100, 2)
|
|
89
|
+
|
|
90
|
+
def get_temperature(self):
|
|
91
|
+
"""
|
|
92
|
+
calculates the measured temperature
|
|
93
|
+
"""
|
|
94
|
+
d2 = self.conversion(self.D2)
|
|
95
|
+
dT = d2 - self._coefficients[4] * 256
|
|
96
|
+
return round((2000 + dT * self._coefficients[5] / 8388608) / 100, 2)
|
|
97
|
+
|
|
98
|
+
def get_altitude(self, reference_pressure = 1013.25):
|
|
99
|
+
"""
|
|
100
|
+
calculates altitude from the measured pressure
|
|
101
|
+
reference_pressure - mean sea level pressure, should be adjusted to local QNH
|
|
102
|
+
"""
|
|
103
|
+
pressure = self.get_pressure()
|
|
104
|
+
return round(44330 * (1 - (pressure / reference_pressure) ** (1/5.255)), 2)
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import board
|
|
2
|
+
import busio
|
|
3
|
+
import digitalio
|
|
4
|
+
import time
|
|
5
|
+
from adafruit_mcp230xx.mcp23008 import MCP23008
|
|
6
|
+
|
|
7
|
+
class buttonmatrix:
|
|
8
|
+
|
|
9
|
+
# values shown on the button matrix
|
|
10
|
+
dictionary = {(0, 0) : "7",
|
|
11
|
+
(0, 1) : "4",
|
|
12
|
+
(0, 2) : "1",
|
|
13
|
+
(0, 3) : "0",
|
|
14
|
+
(1, 0) : "8",
|
|
15
|
+
(1, 1) : "5",
|
|
16
|
+
(1, 2) : "2",
|
|
17
|
+
(1, 3) : "#",
|
|
18
|
+
(2, 0) : "9",
|
|
19
|
+
(2, 1) : "6",
|
|
20
|
+
(2, 2) : "3",
|
|
21
|
+
(2, 3) : "=",
|
|
22
|
+
(3, 0) : "*",
|
|
23
|
+
(3, 1) : "/",
|
|
24
|
+
(3, 2) : "+",
|
|
25
|
+
(3, 3) : "-"}
|
|
26
|
+
|
|
27
|
+
def __init__(self, i2c: busio.I2C, bounce_time = 0.15, i2c_address = 0x22):
|
|
28
|
+
"""
|
|
29
|
+
i2c - i2c port
|
|
30
|
+
i2c_address - address of the barometer
|
|
31
|
+
bounce_time - buffer time for buttons
|
|
32
|
+
"""
|
|
33
|
+
self.i2c_address = i2c_address
|
|
34
|
+
mcp = MCP23008(i2c, address = self.i2c_address)
|
|
35
|
+
self.rows = [mcp.get_pin(4), mcp.get_pin(5), mcp.get_pin(6), mcp.get_pin(7)]
|
|
36
|
+
self.columns = [mcp.get_pin(0), mcp.get_pin(1), mcp.get_pin(2), mcp.get_pin(3)]
|
|
37
|
+
self.calculated = ""
|
|
38
|
+
self.bounce_time = bounce_time
|
|
39
|
+
self._last_key = None
|
|
40
|
+
self._last_time = 0
|
|
41
|
+
for i in range(len(self.rows)):
|
|
42
|
+
self.rows[i].direction = digitalio.Direction.INPUT
|
|
43
|
+
self.rows[i].pull = digitalio.Pull.UP
|
|
44
|
+
|
|
45
|
+
self.columns[i].direction = digitalio.Direction.OUTPUT
|
|
46
|
+
self.columns[i].value = False
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _checkMatrix(self):
|
|
50
|
+
"""
|
|
51
|
+
returns the column and row which was pressed
|
|
52
|
+
"""
|
|
53
|
+
column_value, row_value = None, None
|
|
54
|
+
for i in range(len(self.rows)):
|
|
55
|
+
if self.rows[i].value == False :
|
|
56
|
+
row_value = i
|
|
57
|
+
|
|
58
|
+
# flip columns and rows to get the column
|
|
59
|
+
for i in range(len(self.columns)):
|
|
60
|
+
self.columns[i].direction = digitalio.Direction.INPUT
|
|
61
|
+
self.columns[i].pull = digitalio.Pull.UP
|
|
62
|
+
self.rows[i].direction = digitalio.Direction.OUTPUT
|
|
63
|
+
self.rows[i].value = False
|
|
64
|
+
|
|
65
|
+
for i in range(len(self.columns)):
|
|
66
|
+
if self.columns[i].value == False :
|
|
67
|
+
column_value = i
|
|
68
|
+
|
|
69
|
+
# set columns and rows back
|
|
70
|
+
for i in range(len(self.rows)):
|
|
71
|
+
self.rows[i].direction = digitalio.Direction.INPUT
|
|
72
|
+
self.rows[i].pull = digitalio.Pull.UP
|
|
73
|
+
self.columns[i].direction = digitalio.Direction.OUTPUT
|
|
74
|
+
self.columns[i].value = False
|
|
75
|
+
|
|
76
|
+
time.sleep(.1)
|
|
77
|
+
return column_value, row_value
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def getKey(self):
|
|
81
|
+
"""
|
|
82
|
+
returns the name of the button which was pressed
|
|
83
|
+
"""
|
|
84
|
+
key = None
|
|
85
|
+
try:
|
|
86
|
+
key = self.dictionary[self._checkMatrix()]
|
|
87
|
+
except KeyError:
|
|
88
|
+
key = None
|
|
89
|
+
current_time = time.monotonic()
|
|
90
|
+
|
|
91
|
+
if key is None:
|
|
92
|
+
self._last_key = None
|
|
93
|
+
return None
|
|
94
|
+
if key == self._last_key and (current_time - self._last_time) < self.bounce_time:
|
|
95
|
+
return None
|
|
96
|
+
self._last_key = key
|
|
97
|
+
self._last_time = current_time
|
|
98
|
+
return key
|
|
99
|
+
|
|
100
|
+
def clearMemory(self):
|
|
101
|
+
"""
|
|
102
|
+
clears class variable calculated
|
|
103
|
+
"""
|
|
104
|
+
self.calculated = ""
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def calculate(self):
|
|
108
|
+
"""
|
|
109
|
+
method to use button matrix as calculator
|
|
110
|
+
"""
|
|
111
|
+
value = self.getKey()
|
|
112
|
+
if value is None:
|
|
113
|
+
return self.calculated
|
|
114
|
+
if value == "=":
|
|
115
|
+
try:
|
|
116
|
+
self.calculated = str(eval(self.calculated))
|
|
117
|
+
return self.calculated
|
|
118
|
+
# catch if number should be divided by zero
|
|
119
|
+
except ZeroDivisionError :
|
|
120
|
+
self.clearMemory()
|
|
121
|
+
raise ValueError("You can not divide by zero!")
|
|
122
|
+
# catch if string is not convertable to a number
|
|
123
|
+
except SyntaxError:
|
|
124
|
+
self.clearMemory()
|
|
125
|
+
raise ValueError("Term can not be calculated!")
|
|
126
|
+
elif value == "#":
|
|
127
|
+
self.clearMemory()
|
|
128
|
+
else:
|
|
129
|
+
self.calculated += value
|
|
130
|
+
return self.calculated
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
#
|
|
4
|
+
###################################################################################
|
|
5
|
+
# Edited by Joy-IT
|
|
6
|
+
#
|
|
7
|
+
###################################################################################
|
|
8
|
+
# Copyright 2020 <pi@kb>
|
|
9
|
+
#
|
|
10
|
+
# This program is free software; you can redistribute it and/or modify
|
|
11
|
+
# it under the terms of the GNU General Public License as published by
|
|
12
|
+
# the Free Software Foundation; either version 2 of the License, or
|
|
13
|
+
# (at your option) any later version.
|
|
14
|
+
#
|
|
15
|
+
# This program is distributed in the hope that it will be useful,
|
|
16
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
17
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
18
|
+
# GNU General Public License for more details.
|
|
19
|
+
#
|
|
20
|
+
# You should have received a copy of the GNU General Public License
|
|
21
|
+
# along with this program; if not, write to the Free Software
|
|
22
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
23
|
+
# MA 02110-1301, USA.
|
|
24
|
+
#
|
|
25
|
+
# Written by BitHead (Britany Head)
|
|
26
|
+
# https://forums.raspberrypi.com/viewtopic.php?t=263498
|
|
27
|
+
# Step 1) Enable I2C in Raspi-Config (Interfacing Options)
|
|
28
|
+
# Step 2) sudo apt-get install i2c-tools python3-smbus
|
|
29
|
+
# Step 3) plug it in (don't forget your pull-up resistors) and run this program
|
|
30
|
+
|
|
31
|
+
import smbus
|
|
32
|
+
import time
|
|
33
|
+
import threading
|
|
34
|
+
import numpy as np
|
|
35
|
+
|
|
36
|
+
class colour:
|
|
37
|
+
|
|
38
|
+
def __init__(self, i2c_address = 0x10):
|
|
39
|
+
"""
|
|
40
|
+
initialize colour sensor
|
|
41
|
+
i2c_address - i2c_address of colour sensor (default 0x10)
|
|
42
|
+
"""
|
|
43
|
+
self.address = i2c_address
|
|
44
|
+
self.bus = smbus.SMBus(1)
|
|
45
|
+
self.enableSensor()
|
|
46
|
+
|
|
47
|
+
def write(self, cmd, val):
|
|
48
|
+
"""
|
|
49
|
+
write value into register on the colour sensor
|
|
50
|
+
cmd - register
|
|
51
|
+
val - value to be written
|
|
52
|
+
"""
|
|
53
|
+
self.bus.write_word_data(self.address, cmd, val)
|
|
54
|
+
|
|
55
|
+
def read(self, cmd):
|
|
56
|
+
"""
|
|
57
|
+
read value from register on the colour sensor
|
|
58
|
+
cmd - register
|
|
59
|
+
"""
|
|
60
|
+
return self.bus.read_word_data(self.address, cmd)
|
|
61
|
+
|
|
62
|
+
def enableSensor(self):
|
|
63
|
+
"""
|
|
64
|
+
activate Sensor
|
|
65
|
+
"""
|
|
66
|
+
conf = self.read(0x00) & 0x00FE
|
|
67
|
+
self.write(0x00, conf)
|
|
68
|
+
|
|
69
|
+
def disableSensor(self):
|
|
70
|
+
"""
|
|
71
|
+
deactivate Sensor
|
|
72
|
+
"""
|
|
73
|
+
conf = (self.read(0x00) & 0x00FE) | 0x000
|
|
74
|
+
self.write(0x00, conf)
|
|
75
|
+
time.sleep(.001)
|
|
76
|
+
|
|
77
|
+
def getRGBW(self):
|
|
78
|
+
"""
|
|
79
|
+
returns colour values from colour sensor - red, green, blue, white
|
|
80
|
+
"""
|
|
81
|
+
return self.read(0x08), self.read(0x09), int(self.read(0x0A) * 1.5), self.read(0x0B)
|
|
82
|
+
|
|
83
|
+
def setIntegrationTime(self, int_time):
|
|
84
|
+
"""
|
|
85
|
+
set integration time with variable int_time
|
|
86
|
+
int_time - integration time
|
|
87
|
+
0 = 40 ms
|
|
88
|
+
1 = 80 ms
|
|
89
|
+
2 = 160 ms
|
|
90
|
+
3 = 320 ms
|
|
91
|
+
4 = 640 ms
|
|
92
|
+
5 = 1280 ms
|
|
93
|
+
"""
|
|
94
|
+
if int_time < 0 or int_time > 5:
|
|
95
|
+
raise ValueError('int_time is not in range')
|
|
96
|
+
conf = self.read(0x00) & 0x0003
|
|
97
|
+
self.write(0x00, (conf | (int_time << 4)))
|
|
98
|
+
|
|
99
|
+
def forceMode(self):
|
|
100
|
+
"""
|
|
101
|
+
forces measurement mode - triggers to start
|
|
102
|
+
"""
|
|
103
|
+
conf = (self.read(0x00) & 0x0072) | 0x0002
|
|
104
|
+
self.write(0x00, conf)
|
|
105
|
+
|
|
106
|
+
def autoMode(self):
|
|
107
|
+
"""
|
|
108
|
+
automatic measurement mode
|
|
109
|
+
"""
|
|
110
|
+
conf = self.read(0x00) & 0x0070
|
|
111
|
+
self.write(0x00, conf)
|
|
112
|
+
|
|
113
|
+
def readAll(self):
|
|
114
|
+
"""
|
|
115
|
+
returns most recognized colour and raw values
|
|
116
|
+
"""
|
|
117
|
+
r, g, b, w = self.getRGBW()
|
|
118
|
+
raw_val = [r, g, b, w]
|
|
119
|
+
dominant_col, dominant_val = "red", r
|
|
120
|
+
if g > dominant_val: dominant_col, dominant_val = "green", g
|
|
121
|
+
if b > dominant_val: dominant_col, dominant_val = "blue", b
|
|
122
|
+
|
|
123
|
+
return dominant_col, raw_val
|