Ver código fonte

update lib for lcd shield

Tobias Müller 9 meses atrás
pai
commit
fc5115a5c6
2 arquivos alterados com 179 adições e 40 exclusões
  1. 171 27
      Libs/LCD_Shield/__init__.py
  2. 8 13
      main.py

+ 171 - 27
Libs/LCD_Shield/__init__.py

@@ -1,7 +1,7 @@
 """
 Author:     Tobias Müller
 Date:       30.06.2023
-Version:    1.0
+Version:    0.5
 
 This file contains classes for LCD, Button and Led control.
 """
@@ -10,6 +10,7 @@ This file contains classes for LCD, Button and Led control.
 
 from time import sleep_us
 from machine import Pin, PWM, I2C
+import re
 
 ##############################                  Code                  ##############################
 
@@ -31,16 +32,45 @@ class LCD:
                      "LCD_PARA_DIS_CON": 0x0C,      # Display on/off Control (Cursor off, Blink off)
                      "LCD_PARA_CLR_DIS": 0x01}      # Clear Display
 
+    __lcd_control = {"CONTROL_BYTE": 0x80,          # Set Continue Bit
+                     "CONTROL_BYTE_DCB": 0x40,      # Data/Command Selection Bit set
+                     "LCD_PARA_CLR_DIS": 0x01,      # Clear Display
+                     "LCD_PARA_DIS_ROW1": 0x80,     # Display Row 1
+                     "LCD_PARA_DIS_ROW2": 0xA0,     # Display Row 2
+                     "LCD_PARA_DIS_ROW3": 0xC0,     # Display Row 3
+                     "LCD_PARA_DIS_ROW4": 0xE0,     # Display Row 4
+                     "LCD_PARA_DIS_COLUMN": 0x0A}   # Columns per Display Row
+
+    __i2c_ports = {"I2C0": {"SDA_PINS": [0, 4 ,8 ,12 ,16 ,20],
+                            "SCL_PINS": [1, 5, 9, 13, 17, 21]},
+                   "I2C1": {"SDA_PINS": [2, 6, 10, 14, 18, 26],
+                            "SCL_PINS": [3, 7, 11, 15, 19, 27]}}
+    
+    __i2c_frequencies = {"STANDARD_MODE": 100000,
+                         "FAST_MODE": 400000,
+                         "FAST_MODE_PLUS": 1000000}
+
+    __i2c_address = 0x3c
+
     ##############################           Constructor          ##############################
 
     def __init__(self,
-                 I2C_SDA_Pin: int = 2,
-                 I2C_SCL_Pin: int = 3,
-                 LCD_Brightness: int = 100):
-
-        self.__i2c_sda_pin, self.__i2c_scl_pin = self.__check_i2c_ports(I2C_SDA_Pin,
-                                                                        I2C_SCL_Pin)
-        self.__lcd_brightness = self.__check_lcd_brightness(LCD_Brightness)
+                 i2c_sda_pin: int|str = 2,
+                 i2c_scl_pin: int|str = 3,
+                 i2c_frequency: int|str = 400000,
+                 lcd_backlight_pin: int|str = 28,
+                 lcd_brightness: int = 100):
+
+        # Check and store input values
+        self.__I2C_Bus, self.__I2C_SDA_Pin, self.__I2C_SCL_Pin = self.__check_i2c_ports(i2c_sda_pin,
+                                                                                        i2c_scl_pin)
+        self.__i2c_frequency = self.__check_i2c_speed(i2c_frequency)
+        self.__lcd_backlight_pin = self.__check_lcd_backlight_pin(lcd_backlight_pin)
+        self.__lcd_brightness = self.__check_lcd_brightness(lcd_brightness)
+
+        # init i2c and backlight
+        self.__init_i2c()
+        self.__init_backlight_pwm()
 
     ##############################           Properties           ##############################
 
@@ -49,34 +79,148 @@ class LCD:
         return self.__lcd_brightness
 
     @lcd_brightness.setter
-    def lcd_brightness(self, value: int):
-        self.__lcd_brightness = self.__check_lcd_brightness(value)
-        self.__set_lcd_brightness()
+    def lcd_brightness(self, lcd_brightness: int):
+        self.__lcd_brightness = self.__check_lcd_brightness(lcd_brightness)
+        self.__backlight_pwm.duty_u16(round(65635 * (lcd_brightness / 100)))
 
     ##############################         Methods private        ##############################
 
     @staticmethod
-    def __check_lcd_brightness(value):
-        if not isinstance(value, int):
-            raise ValueError(f"Value \"{value}\" for \"lcd_brightness\" is not type \"int\"!")
-        elif value < 0 or value > 100:
-            raise ValueError(f"Value \"{value}\" for \"lcd_brightness\" is out of range!")
-        else:
-            return value
+    def __reset_pin(pin):
+        Pin(pin, Pin.IN, None)
 
-    def __set_lcd_brightness(self):
-        pass
+    @staticmethod
+    def __check_lcd_brightness(lcd_brightness):
+        if not isinstance(lcd_brightness, int):
+            raise ValueError(f"Value \"{lcd_brightness}\" of \"lcd_brightness\" is not type \"int\"!")
+        elif lcd_brightness < 0 or lcd_brightness > 100:
+            raise ValueError(f"Value \"{lcd_brightness}\" of \"lcd_brightness\" is out of range!")
+        else:
+            return lcd_brightness
 
     @staticmethod
-    def __check_i2c_ports(SDA_Pin, SCL_Pin):
-        return SDA_Pin, SCL_Pin
+    def __check_lcd_backlight_pin(lcd_backlight_pin):
+        if not isinstance(lcd_backlight_pin, int) and not isinstance(lcd_backlight_pin, str):
+            raise ValueError(f"Value \"{lcd_backlight_pin}\" of \"lcd_backlight_pin\" is not type" +
+                             " \"int\" or \"str\"!")
+        elif isinstance(lcd_backlight_pin, str) and not re.match(r"^GP\d\d?$",lcd_backlight_pin):
+            raise ValueError(f"String value \"{lcd_backlight_pin}\" of \"lcd_backlight_pin\" has" +
+                             "  wrong format!")
+        else:
+            return lcd_backlight_pin
+
+    def __check_i2c_ports(self, i2c_sda_pin, i2c_scl_pin):
+        if not isinstance(i2c_sda_pin, int) and not isinstance(i2c_sda_pin, str):
+            raise ValueError(f"Value \"{i2c_sda_pin}\" of \"i2c_sda_pin\" is not type \"int\"" +
+                             " or \"str\"!")
+        elif not isinstance(i2c_scl_pin, int) and not isinstance(i2c_scl_pin, str):
+            raise ValueError(f"Value \"{i2c_scl_pin}\" of \"i2c_scl_pin\" is not type \"int\"" +
+                             " or \"str\"!")
+        elif isinstance(i2c_sda_pin, str) and not re.match(r"^GP\d\d?$",i2c_sda_pin):
+            raise ValueError(f"String value \"{i2c_sda_pin}\" of \"i2c_sda_pin\" has wrong format!")
+        elif isinstance(i2c_scl_pin, str) and not re.match(r"^GP\d\d?$",i2c_scl_pin):
+            raise ValueError(f"String value \"{i2c_scl_pin}\" of \"i2c_scl_pin\" has wrong format!")
+        elif ((isinstance(i2c_sda_pin, int) and
+               not i2c_sda_pin in self.__i2c_ports["I2C0"]["SDA_PINS"] and
+               not i2c_sda_pin in self.__i2c_ports["I2C1"]["SDA_PINS"]) or
+              (isinstance(i2c_sda_pin, str) and
+               not int(i2c_sda_pin[2:]) in self.__i2c_ports["I2C0"]["SDA_PINS"] and
+               not int(i2c_sda_pin[2:]) in self.__i2c_ports["I2C1"]["SDA_PINS"])):
+            raise ValueError(f"Value \"{i2c_sda_pin}\" of \"i2c_sda_pin\" is not an I2C SDA-Pin!")
+        elif ((isinstance(i2c_scl_pin, int) and
+               not i2c_scl_pin in self.__i2c_ports["I2C0"]["SCL_PINS"] and
+               not i2c_scl_pin in self.__i2c_ports["I2C1"]["SCL_PINS"]) or
+              (isinstance(i2c_scl_pin, str) and
+               not int(i2c_scl_pin[2:]) in self.__i2c_ports["I2C0"]["SCL_PINS"] and
+               not int(i2c_scl_pin[2:]) in self.__i2c_ports["I2C1"]["SCL_PINS"])):
+            raise ValueError(f"Value \"{i2c_scl_pin}\" of \"i2c_scl_pin\" is not an I2C SCL-Pin!")
+        elif ((((isinstance(i2c_sda_pin, int) and 
+                 i2c_sda_pin in self.__i2c_ports["I2C0"]["SDA_PINS"]) or
+                (isinstance(i2c_sda_pin, str) and 
+                 int(i2c_sda_pin[2:]) in self.__i2c_ports["I2C0"]["SDA_PINS"])) and not
+               ((isinstance(i2c_scl_pin, int) and 
+                 i2c_scl_pin in self.__i2c_ports["I2C0"]["SCL_PINS"]) or
+                (isinstance(i2c_scl_pin, str) and 
+                 int(i2c_scl_pin[2:]) in self.__i2c_ports["I2C0"]["SCL_PINS"]))) or
+              (((isinstance(i2c_sda_pin, int) and 
+                 i2c_sda_pin in self.__i2c_ports["I2C1"]["SDA_PINS"]) or
+                (isinstance(i2c_sda_pin, str) and 
+                 int(i2c_sda_pin[2:]) in self.__i2c_ports["I2C1"]["SDA_PINS"])) and not
+               ((isinstance(i2c_scl_pin, int) and 
+                 i2c_scl_pin in self.__i2c_ports["I2C1"]["SCL_PINS"]) or
+                (isinstance(i2c_scl_pin, str) and 
+                 int(i2c_scl_pin[2:]) in self.__i2c_ports["I2C1"]["SCL_PINS"])))):
+            raise ValueError(f"Value \"{i2c_scl_pin}\" of \"i2c_scl_pin\" and " +
+                             f"Value \"{i2c_sda_pin}\" of \"i2c_sda_pin\" " +
+                             "are not part of the same I2C Bus!")
+        else:
+            if ((isinstance(i2c_sda_pin, int) and 
+                 i2c_sda_pin in self.__i2c_ports["I2C0"]["SDA_PINS"]) or
+                (isinstance(i2c_sda_pin, str) and 
+                 int(i2c_sda_pin[2:]) in self.__i2c_ports["I2C0"]["SDA_PINS"])):
+                return 0, i2c_sda_pin, i2c_scl_pin
+            else:
+                return 1, i2c_sda_pin, i2c_scl_pin
+
+    def __check_i2c_speed(self, i2c_frequency):
+        if not isinstance(i2c_frequency, int) and not isinstance(i2c_frequency, str):
+            raise ValueError(f"Value \"{i2c_frequency}\" of \"i2c_frequency\" is not type \"int\"" +
+                             " or \"str\"!")
+        elif (isinstance(i2c_frequency, int) and not i2c_frequency in self.__i2c_frequencies.values() or
+              isinstance(i2c_frequency, str) and not i2c_frequency in self.__i2c_frequencies.keys()):
+            raise ValueError(f"Value \"{i2c_frequency}\" of \"i2c_frequency\" is not supported!")
+        else:
+            return i2c_frequency
+    
+
+    def __init_i2c(self):
+        self.__i2c = I2C(self.__I2C_Bus,
+                         sda=Pin(self.__I2C_SDA_Pin),
+                         scl=Pin(self.__I2C_SCL_Pin),
+                         freq=(self.__i2c_frequency if isinstance(self.__i2c_frequency, int) else
+                               self.__i2c_frequencies[self.__i2c_frequency]))
+        self.__i2c.writeto(self.__i2c_address, bytes(self.__lcd_setting.values()))
+
+    def __deinit_i2c(self):
+        self.__reset_pin(self.__I2C_SCL_Pin)
+        self.__reset_pin(self.__I2C_SDA_Pin)
+
+    def __init_backlight_pwm(self):
+        self.__backlight_pwm = PWM(Pin(self.__lcd_backlight_pin))
+        self.__backlight_pwm.freq(1000)
+        self.__backlight_pwm.duty_u16(round(65635 * (self.lcd_brightness / 100)))
+
+    def __deinit_backlight_pwm(self):
+        self.__backlight_pwm.deinit()
+        self.__reset_pin(self.__lcd_backlight_pin)
 
     ##############################         Methods public         ##############################
 
-    def change_I2C_port(self, SDA_Pin, SCL_Pin):
-        pass
-
+    def change_i2c_port(self, i2c_sda_pin: int|str, i2c_scl_pin: int|str):    
+        self.__I2C_Bus, i2c_sda_pin, i2c_scl_pin = self.__check_i2c_ports(i2c_sda_pin, i2c_scl_pin)
+        self.__deinit_i2c()
+        self.__I2C_SCL_Pin = i2c_scl_pin
+        self.__I2C_SDA_Pin = i2c_sda_pin
+        self.__init_i2c()
+
+    def print(self, text: str, **keywords):
+        if not isinstance(text, str):
+            raise ValueError(f"Value \"{text}\" of \"text\" is not type \"str\"!")
+        elif len(keywords) == 0:
+            self.clear()
+            buffer = [self.__lcd_control["CONTROL_BYTE"]]
+            buffer.append(self.__lcd_control["LCD_PARA_DIS_ROW1"])
+            buffer.append(self.__lcd_control["CONTROL_BYTE_DCB"])
+            for i in range(0, self.__lcd_control["LCD_PARA_DIS_COLUMN"] if
+                           len(text) > self.__lcd_control["LCD_PARA_DIS_COLUMN"] else len(text)):
+                buffer.append(ord(text[i]))
+            print(bytes(buffer))
+            self.__i2c.writeto(self.__i2c_address, bytes(buffer))
+
+    def clear(self):
+        buffer = [self.__lcd_control["CONTROL_BYTE"], self.__lcd_control["LCD_PARA_CLR_DIS"]]
+        self.__i2c.writeto(self.__i2c_address, bytes(buffer))
 
 if __name__ == "__main__":
-    pass
-
+    lcd = LCD(i2c_scl_pin="GP3", i2c_sda_pin=2, i2c_frequency=100000)
+    lcd.print("Hallo")

+ 8 - 13
main.py

@@ -9,6 +9,8 @@ Main File to run on the pico.
 ##############################                 Modules                ##############################
 
 from Libs.LCD_Shield import LCD
+from time import sleep_us
+from machine import Pin
 
 ##############################            Global Variables            ##############################
 
@@ -22,21 +24,14 @@ def main():
 
     ##########################           Local Variables            ############################
     
+    led = Pin(28,Pin.OUT)
+    led.on()
+    sleep_us(5000000)
+    led.off()
     
     ##########################                Code                  ############################
-    pin = Pin(2,Pin.OUT)
-    pin.on()
-    foo()
-    d = dht.DHT11(Pin(3))
-    d.measure()
-    print(d.temperature())
-    print(d.humidity())
-    pin.off()
-
-    pwm = PWM(Pin(18))
-    pwm.freq(1000)
-    pwm.duty_u16(2000)
-    pwm.deinit()
+    bar()
+   
 
 ##############################               Functions                ##############################