from machine import Pin from machine import I2C import utime print("Test-Script for LCD Dispay with HD44780 Controller and I2C Interfache Chip PCF8574") # Initialize I2C with pins SDA=GP0 (Pico-Pin1), SDL=GP1 (Pico-Pin2) :: LCD VCC=+5V SDA/SDL 3.3V Logic i2c=machine.I2C(0, sda=machine.Pin(0), scl=machine.Pin(1), freq=100000) # Scan I2C BUS to Display correct wired I2C devices devices = i2c.scan() for d in devices: print('I2C Device found at Address: ',hex(d)) #For I2C Controller PCF8574 with HD44780 LCD 2x16 or 4x40 Hardware Wiering Parameter I2C_LCD_Addr = 0x27 # Must bee one of the scanned I2C Adresses! LCD_RS = 0x01 # am PFC01 needed for Selecting 0=Command 1=DAta LCD_RW = 0x02 # am PFC02 propably not connect and at the LCD fix to GND LCD_E = 0x04 # am PFC03 needed to transfer the Data LCD_LED= 0x08 # am PFC04 propably not connect and at the LCD fix to On LCD_D4 = 0x10 # am PFC05 LCD_D5 = 0x20 # am PFC06 LCD_D6 = 0x40 # am PFC07 LCD_D7 = 0x80 # am PFC08 # LCD Service Routines def LCD_WriteCmd4(Zeichen): # Commands in zwei Nibbles übermitteln i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED] ) ) # 4-Bit-Data=0x?0 + 00-Register i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED+LCD_E]) ) # 4-Bit-Data=0x?0 + 04-Enable + 00-Register i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED]) ) # 4-Bit-Data=0x?0 + 00-Register def LCD_WriteCmd(Zeichen): # Commands in zwei Nibbles übermitteln i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED] ) ) # 4-Bit-Data=0x?0 + 00-Register i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED+LCD_E]) ) # 4-Bit-Data=0x20 + 04-Enable + 00-Register i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED]) ) # 4-Bit-Data=0x20 + 00-Register Zeichen = Zeichen << 4 i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED]) ) # 4-Bit-Data=0x?0 + 00-Register i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED+LCD_E]) ) # 4-Bit-Data=0x20 + 04-Enable + 00-Register i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED])) # 4-Bit-Data=0x?0 + 08-Licht def LCD_WriteChar(Zeichen): # Zeichen in zwei Nibbles übermitteln i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED+LCD_RS])) # 4-Bit-Data=0x?0 + 08-Licht + 01-Register i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED+LCD_RS+LCD_E])) # 4-Bit-Data=0x?0 + 08-Licht + 04-Enable + 01-Register i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED+LCD_RS])) # 4-Bit-Data=0x?0 + 08-Licht + 01-Register Zeichen = Zeichen << 4 i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED+LCD_RS])) # 4-Bit-Data=0x?0 + 08-Licht + 01-Register i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED+LCD_RS+LCD_E])) # 4-Bit-Data=0x?0 + 08-Licht + 04-Enable + 01-Register i2c.writeto(I2C_LCD_Addr, bytes([(Zeichen & 0x0F0)+LCD_LED+LCD_RS])) # 4-Bit-Data=0x?0 + 08-Licht + 01-Register def LCD_Init(): try: # Catch I2C Communication Error LCD_WriteCmd4(0x30) # 0011 D7-D4 HiNibble = SoftReset Sequenz1 except: # Set HD44780 Controller with 4-Bit and Init for use print("I2C Communiation to " + hex(I2C_LCD_Addr) + "h failed - please Check as the I2C Address ist valid") import sys sys.exit("I2C Communiation Error") # TERMINATE SCRIPT ON ERROR utime.sleep_ms(5) # Delay 5ms SoftReset Sequenz1 zu SoftReset Sequenz2 LCD_WriteCmd4(0x30) # 0011 D7-D4 HiNibble = SoftReset Sequenz2 utime.sleep_ms(1) # Delay 1ms SoftReset Sequenz2 zu SoftReset Sequenz3 LCD_WriteCmd4(0x30) # 0011 D7-D4 HiNibble = SoftReset Sequenz3 utime.sleep_ms(1) # Delay 1ms SoftReset Sequenz3 zu 4-Bit Init LCD_WriteCmd4(0x20) # 0010 D7-D4 HiNibble = 4-Bit Mode Init LCD_WriteCmd(0x28) # 0010 1000 - 4Bit Mode Activate LCD_WriteCmd(0x0C) # 0000 1100 - Display ON, Cursor Off, Cursor Blinking Off LCD_WriteCmd(0x06) # 0000 0110 - Entry Mode, Increment cursor position, No display shift LCD_WriteCmd(0x01) # 0000 0001 - Clear Display and Set Cursor to pos 0 utime.sleep_ms(5) # Controller needs Time to Clear the Display LCD_WriteCmd(0x02) # 0000 0010 - Set Cursor to home Pos=0 needs 1.52mS utime.sleep_ms(2) # Controller needs Time to Set Cursor Home, needs 1.52mS def LCD_GotoXY(Position): # Somme HD44780 2end row starts at pos 41 others at 64 if Position > 0x7F : Position=0x7F LCD_WriteCmd(0x80+Position) # 1000 0000 - 0x80 + Position def LCD_CLR(): # LCD Löschen via Kommando HD44780 LCD_WriteCmd(0x01) # 0000 0001 - Display Löschen und Cursor auf 0 utime.sleep_ms(2) # Controller needs Time to Clear the Display, needs 1.52mS def LCD_Print(LCDText): # Print String at the actal position for Zeichen in LCDText: # Send Character by character LCD_WriteChar(ord(Zeichen)) # *** MAIN PROGRAMM *** LCD_Init() LCD_GotoXY(0) LCD_Print(" *** BME280 ***") OnBoardLED = machine.Pin(25, machine.Pin.OUT) # read two bytes as an unsigned int def read_const_u(a): return r[a - reg_base_addr] + (r[a - reg_base_addr + 1] << 8) # read two bytes as a signed int def read_const_s(a): v = r[a - reg_base_addr] + (r[a - reg_base_addr + 1] << 8) if v > 32767: v = v - 65536 return v while True: OnBoardLED.toggle() utime.sleep(1.5) i2c_addr = 0x76 # Change this if the device is on another address # humidity oversampling i2c.writeto_mem(i2c_addr, 0xf2, b'\x03') # ctrl_hum 00000 011 # temp oversampling / pressure / oversampling / sensor mode i2c.writeto_mem(i2c_addr, 0xf4, b'\x6F') # ctrl_meas 011 011 11 #time.sleep(0.1) utime.sleep_ms(200) # reg_base_addr = 0x88 # memory map is from 0x88 to 0xff block_size = 0x100 - reg_base_addr # bytes to read r = i2c.readfrom_mem(i2c_addr, reg_base_addr, block_size) # Read the sensor into a buffer # TEMPERATURE # get raw temperature temp_msb = r[0xfa - reg_base_addr] temp_lsb = r[0xfb - reg_base_addr] temp_xlsb = r[0xfc - reg_base_addr] adc_t = (temp_msb << 12) + (temp_lsb << 4) + (temp_xlsb >> 4) # get compensation parameters (These are constants, only read once in a production system) dig_t1 = read_const_u(0x88) dig_t2 = read_const_s(0x8a) dig_t3 = read_const_s(0x8c) # calc temperature # Shown as done in the datasheet - can be tidied up var1 = ((adc_t >> 3) - (dig_t1 << 1)) * (dig_t2 >> 11) var2 = (((((adc_t >> 4) - dig_t1) * ((adc_t >> 4) - dig_t1)) >> 12) * dig_t3) >> 14 t_fine = (var1 + var2) t = (t_fine * 5 + 128) >> 8 t = t / 100 print("Temperature is " + str(t) + " degrees") LCD_GotoXY(75) LCD_Print("T=" + str(t) + chr(223) + "C") # PRESSURE # get raw pressure press_msb = r[0xf7 - reg_base_addr] press_lsb = r[0xf8 - reg_base_addr] press_xlsb = r[0xf9 - reg_base_addr] adc_p = (press_msb << 12) + (press_lsb << 4) + (press_xlsb >> 4) # get compensation parameters (These are constants, only read once in a production system) dig_p1 = read_const_u(0x8e) dig_p2 = read_const_s(0x90) dig_p3 = read_const_s(0x92) dig_p4 = read_const_s(0x94) dig_p5 = read_const_s(0x96) dig_p6 = read_const_s(0x98) dig_p7 = read_const_s(0x9a) dig_p8 = read_const_s(0x9c) dig_p9 = read_const_s(0x9e) # calc pressure # Shown as done in the datasheet - can be tidied up var1 = t_fine - 128000 var2 = var1 * var1 * dig_p6 var2 = var2 + ((var1 * dig_p5) << 17) var2 = var2 + (dig_p4 << 35) var1 = ((var1 * var1 * dig_p3) >> 8) + ((var1 * dig_p2) << 12) var1 = ((1 << 47) + var1) * dig_p1 >> 33 if var1 == 0: # divide by zero check p = 0 else: p = 1048576 - adc_p p = int((((p << 31) - var2) * 3125) / var1) var1 = (dig_p9 * (p >> 13) * (p >> 13)) >> 25 var2 = (dig_p8 * p) >> 19 p = ((p + var1 + var2) >> 8) + (dig_p7 << 4) print("Pressure is " + str(p / 25600) + " mbar") LCD_GotoXY(64) LCD_Print("P=" + str(p / 25600)[0:6] + "mB") Druck = p / 25600 # HUMIDITY # print("Chip-ID; ",r[0xd0 - reg_base_addr]) # 0x56 BMP280 Muster # 0x57 BMP280 Muster # 0x58 BMP280 Massenfertigung # 0x60 BME280 Massenfertigung # 0x61 BME680 # get raw pressure hum_msb = r[0xfd - reg_base_addr] hum_lsb = r[0xfe - reg_base_addr] adc_h = (hum_msb << 8) + hum_lsb # get compensation parameters (These are constants, only read once in a production system) dig_h1 = r[0xa1 - reg_base_addr] dig_h2 = read_const_s(0xe1) dig_h3 = r[0xe3 - reg_base_addr] dig_h4 = (r[0xe4 - reg_base_addr] << 4) + (r[0xe5 - reg_base_addr] & 0x0f) dig_h5 = (r[0xe6 - reg_base_addr] << 4) + ((r[0xe5 - reg_base_addr] & 0x00f0) >> 4) dig_h6 = r[0xe7 - reg_base_addr] # calc humidity # Shown as done in the datasheet - can be tidied up v_x1_u32r = t_fine - 76800 v_x1_u32r = (((((adc_h << 14) - (dig_h4 << 20) - (dig_h5 * v_x1_u32r)) + 16384) >> 15) * (((((((v_x1_u32r * ( dig_h6)) >> 10) * (((v_x1_u32r * dig_h3) >> 11) + 32768)) >> 10) + 2097152) * dig_h2 + 8192) >> 14)) v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * dig_h1) >> 4)) # limit checks if v_x1_u32r < 0: v_x1_u32r = 0 if v_x1_u32r > 0x19000000: v_x1_u32r = 0x19000000 h = v_x1_u32r >> 12 print("Humidity is " + str(h / 1024) + " %") LCD_GotoXY(20) LCD_Print("h=" + str(int(h / 1024)) + "%RH") import math hoehe = ((273.150+t)/0.0065) * (1-math.pow(Druck/1013,(1/5.255))) LCD_GotoXY(31) LCD_Print("H=" + str(int(hoehe)) + "m üM") print("Höhe="+str(int(hoehe))+"m über Meer") print("")