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.
@@ -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