User avatar
T-EGWZ34
Posts: 27
Joined: Sat Aug 18, 2018 11:39 am
Location: Bourne, UK

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 4:50 pm

I'm very happy with this now, I'm using it for monitoring the temperature of 2 IPC's which handle my flight tracking. When the weather was "warm" a few weeks ago they were running at nearly 90 degrees.

The latest update does fail with the following Bob:

Code: Select all

Traceback (most recent call last):
  File "templcd9.py", line 143, in <module>
    main()
  File "templcd9.py", line 126, in main
    lcd_string(result ,lcdline[sensor])
  File "templcd9.py", line 72, in lcd_string
    lcd_byte(line, LCD_CMD)
  File "templcd9.py", line 48, in lcd_byte
    bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT
TypeError: unsupported operand type(s) for &: 'str' and 'int'
...but I'm not massively worried because it works as is. One of my upcoming projects is to build Raspberry Pi Zero W's with a single temperature and humidity sensor to feed back to a portal - but that now seems so simple in comparison!

Thanks for all of your hard work Bob, and thanks to everyone for the advise. Understood about the 750ms delay, I can live with that.

Thanks,
Bret

pcmanbob
Posts: 4462
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 5:18 pm

Bret

If you are willing to keep testing code I will try and get the sensor reading in to a loop so we can update the display in one go.

I have made some changes to the last code I posted that I hope will work this time, once I get this working I can then sort it so it saves the the results in a loop and then writes the display in another loop.

Code: Select all


# -*- coding: utf-8
import smbus
import time

# Define some device parameters
I2C_ADDR  = 0x27 # I2C device address, if any error, change this address to 0x3f
LCD_WIDTH = 20   # Maximum characters per line

# Define some device constants
LCD_CHR = 1 # Mode - Sending data
LCD_CMD = 0 # Mode - Sending command

LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line
LCD_LINE_3 = 0x94 # LCD RAM address for the 3rd line
LCD_LINE_4 = 0xD4 # LCD RAM address for the 4th line

LCD_BACKLIGHT  = 0x08  # On
#LCD_BACKLIGHT = 0x00  # Off

ENABLE = 0b00000100 # Enable bit

# Timing constants
E_PULSE = 0.0005
E_DELAY = 0.0005

#Open I2C interface
#bus = smbus.SMBus(0)  # Rev 1 Pi uses 0
bus = smbus.SMBus(1) # Rev 2 Pi uses 1

def lcd_init():
  # Initialise display
  lcd_byte(0x33,LCD_CMD) # 110011 Initialise
  lcd_byte(0x32,LCD_CMD) # 110010 Initialise
  lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction
  lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off 
  lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size
  lcd_byte(0x01,LCD_CMD) # 000001 Clear display
  time.sleep(E_DELAY)

def lcd_byte(bits, mode):
  # Send byte to data pins
  # bits = the data
  # mode = 1 for data
  #        0 for command

  bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT
  bits_low = mode | ((bits<<4) & 0xF0) | LCD_BACKLIGHT

  # High bits
  bus.write_byte(I2C_ADDR, bits_high)
  lcd_toggle_enable(bits_high)

  # Low bits
  bus.write_byte(I2C_ADDR, bits_low)
  lcd_toggle_enable(bits_low)

def lcd_toggle_enable(bits):
  # Toggle enable
  time.sleep(E_DELAY)
  bus.write_byte(I2C_ADDR, (bits | ENABLE))
  time.sleep(E_PULSE)
  bus.write_byte(I2C_ADDR,(bits & ~ENABLE))
  time.sleep(E_DELAY)

def lcd_string(message,line):
  # Send string to display

  message = message.ljust(LCD_WIDTH," ")

  lcd_byte(line, LCD_CMD)

  for i in range(LCD_WIDTH):
    lcd_byte(ord(message[i]),LCD_CHR)

    
# sensor read 
device_file = ""

def read_temp_raw():
    global device_file
    f = open(device_file, "r")
    lines = f.readlines()
    f.close()
    return lines
 
def read_temp():
    lines = read_temp_raw()
    while lines[0].strip()[-3:] != "YES":
        time.sleep(0.2)
        lines = read_temp_raw()
    equals_pos = lines[1].find("t=")
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_c = float(temp_string) / 1000.0
        
        return temp_c   
    
    
    
    
def main():
  global device_file
  # Main program block

  # Initialise display
  lcd_init()

  while True:

    # Send temp readings to lcd
    sensorids = ["28-0215629f5fff", "28-011562bc68ff", "28-0115629bb3ff", "28-000003ebf0ab"]
    
    sensorname = ["Out Temp:", "In  Temp:", "RX  Temp:", "VRS Temp:"]
    
    lcdline = [0x80, 0xC0, 0x94, 0xD4]
    
    # write line on LCD inc temperature reading
    for sensor in range(len(sensorids)):
        device_file = "/sys/bus/w1/devices/"+ sensorids[sensor] +"/w1_slave"
        temperature = (read_temp())
        dtemp = "%.1f" % temperature
        result = sensorname[sensor] + (str(dtemp)) + "`C "
        
        lcd_string(result ,lcdline[sensor])
    
   

    time.sleep(3)
  
    # Send some more text
    lcd_string("Time: %s" %time.strftime("%H:%M"),LCD_LINE_1)
    lcd_string("Date: %s" %time.strftime("%d/%m/%Y"),LCD_LINE_2)
    lcd_string("  IP:" ,LCD_LINE_3)
    lcd_string("Host:",LCD_LINE_4)

    time.sleep(3)

if __name__ == '__main__':

  try:
    main()
  except KeyboardInterrupt:
    pass
  finally:
    lcd_byte(0x01, LCD_CMD)

Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

User avatar
DougieLawson
Posts: 34156
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 5:38 pm

I never got a degree to work so I defined my own at custom char 0.
Microprocessor, Raspberry Pi & Arduino Hacker
Mainframe database troubleshooter
MQTT Evangelist
Twitter: @DougieLawson

2012-18: 1B*5, 2B*2, B+, A+, Z, ZW, 3Bs*3, 3B+

Any DMs sent on Twitter will be answered next month.

pcmanbob
Posts: 4462
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 5:46 pm

DougieLawson wrote:
Mon Aug 20, 2018 5:38 pm
I never got a degree to work so I defined my own at custom char 0.
Exactly what I did using RPLCD, just one of the many functions this driver for this type of LCD offers, but not sure how to do it using the LCD driver T-EGWZ34 is using.
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

User avatar
DougieLawson
Posts: 34156
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 6:04 pm

pcmanbob wrote:
Mon Aug 20, 2018 5:46 pm
DougieLawson wrote:
Mon Aug 20, 2018 5:38 pm
I never got a degree to work so I defined my own at custom char 0.
Exactly what I did using RPLCD, just one of the many functions this driver for this type of LCD offers, but not sure how to do it using the LCD driver T-EGWZ34 is using.
I really think we should encourage the OP to switch to the RPLCD library as it's got a create_char() function that looks just like the one in my C code (https://github.com/DougieLawson/Raspber ... ommonLcd.c)

The degree char I've defined is

Code: Select all

  0b00111,
  0b00101,
  0b00111,
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b00000 
Microprocessor, Raspberry Pi & Arduino Hacker
Mainframe database troubleshooter
MQTT Evangelist
Twitter: @DougieLawson

2012-18: 1B*5, 2B*2, B+, A+, Z, ZW, 3Bs*3, 3B+

Any DMs sent on Twitter will be answered next month.

User avatar
T-EGWZ34
Posts: 27
Joined: Sat Aug 18, 2018 11:39 am
Location: Bourne, UK

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 6:11 pm

Evening chaps,

I'm more than happy to keep testing, I'm learning too so it would be good for me.

With regard to RPLCD, I had looked at this script before and forgot about it. Good in principle but doesn't support I2C according to the website, which I need to use. Open to suggestions though. I have tried loads of different options for the degree but I can't make anything work.

I'll check out the updated script now Bob.

User avatar
T-EGWZ34
Posts: 27
Joined: Sat Aug 18, 2018 11:39 am
Location: Bourne, UK

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 6:15 pm

Spot on Bob, well done. :)

I'm up to templcd9.py currently! :D

User avatar
bensimmo
Posts: 3329
Joined: Sun Dec 28, 2014 3:02 pm
Location: East Yorkshire

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 6:19 pm

It does support i2c (I have the PCF board on mine)
https://github.com/dbrgn/RPLCD/blob/master/README.rst
Supported I²C Port Expanders
PCF8574 (used by a lot of I²C LCD adapters on Ali Express)
MCP23008 (used in Adafruit I²C LCD backpack)
MCP23017

User avatar
T-EGWZ34
Posts: 27
Joined: Sat Aug 18, 2018 11:39 am
Location: Bourne, UK

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 6:27 pm

So it does, I was on the 0.3.0 page, we're on 1.1.0 now.

I shall have a look at that too, thanks. :)

***EDIT - So, I did already have RPLCD installed, and it is now updated.

pcmanbob
Posts: 4462
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 7:19 pm

So we are making good progress now then , seems abandoning the code we got all messed up in was the right option , staring over and doing things in smaller steps seems to be paying off.

so I have now made it so that the temperature sensors are read in the loop as before but now the results are saved, and once all sensors have been read we then write the 4 lines to the LCD one after another so they should appear to update all at the same time.

I tested the save sensor reading part of the code by simulating the sensor output and writing it to the variables and then had it print out on the screen, so I just had to copying that bit of the code and we should be good baring typos and indent errors.

Does the apostrophe work ok in place of the degree symbol ?

so here is the hopefully final working code....

Code: Select all


# -*- coding: utf-8
import smbus
import time

# Define some device parameters
I2C_ADDR  = 0x27 # I2C device address, if any error, change this address to 0x3f
LCD_WIDTH = 20   # Maximum characters per line

# Define some device constants
LCD_CHR = 1 # Mode - Sending data
LCD_CMD = 0 # Mode - Sending command

LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line
LCD_LINE_3 = 0x94 # LCD RAM address for the 3rd line
LCD_LINE_4 = 0xD4 # LCD RAM address for the 4th line

LCD_BACKLIGHT  = 0x08  # On
#LCD_BACKLIGHT = 0x00  # Off

ENABLE = 0b00000100 # Enable bit

# Timing constants
E_PULSE = 0.0005
E_DELAY = 0.0005

#Open I2C interface
#bus = smbus.SMBus(0)  # Rev 1 Pi uses 0
bus = smbus.SMBus(1) # Rev 2 Pi uses 1

def lcd_init():
  # Initialise display
  lcd_byte(0x33,LCD_CMD) # 110011 Initialise
  lcd_byte(0x32,LCD_CMD) # 110010 Initialise
  lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction
  lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off 
  lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size
  lcd_byte(0x01,LCD_CMD) # 000001 Clear display
  time.sleep(E_DELAY)

def lcd_byte(bits, mode):
  # Send byte to data pins
  # bits = the data
  # mode = 1 for data
  #        0 for command

  bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT
  bits_low = mode | ((bits<<4) & 0xF0) | LCD_BACKLIGHT

  # High bits
  bus.write_byte(I2C_ADDR, bits_high)
  lcd_toggle_enable(bits_high)

  # Low bits
  bus.write_byte(I2C_ADDR, bits_low)
  lcd_toggle_enable(bits_low)

def lcd_toggle_enable(bits):
  # Toggle enable
  time.sleep(E_DELAY)
  bus.write_byte(I2C_ADDR, (bits | ENABLE))
  time.sleep(E_PULSE)
  bus.write_byte(I2C_ADDR,(bits & ~ENABLE))
  time.sleep(E_DELAY)

def lcd_string(message,line):
  # Send string to display

  message = message.ljust(LCD_WIDTH," ")

  lcd_byte(line, LCD_CMD)

  for i in range(LCD_WIDTH):
    lcd_byte(ord(message[i]),LCD_CHR)

    
# sensor read 
device_file = ""

def read_temp_raw():
    global device_file
    f = open(device_file, "r")
    lines = f.readlines()
    f.close()
    return lines
 
def read_temp():
    lines = read_temp_raw()
    while lines[0].strip()[-3:] != "YES":
        time.sleep(0.2)
        lines = read_temp_raw()
    equals_pos = lines[1].find("t=")
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_c = float(temp_string) / 1000.0
        
        return temp_c   
    
    
    
    
def main():
  global device_file
  # Main program block

  # Initialise display
  lcd_init()

  while True:

    # Send temp readings to lcd
    
    result = ["0", "1", "2", "3"]
    
    sensorids = ["28-0215629f5fff", "28-011562bc68ff", "28-0115629bb3ff", "28-000003ebf0ab"]
    
    sensorname = ["Out Temp:", "In  Temp:", "RX  Temp:", "VRS Temp:"]
    
    lcdline = [0x80, 0xC0, 0x94, 0xD4]
    
    # get 4 temperature readings
    for sensor in range(4):
        device_file = "/sys/bus/w1/devices/"+ sensorids[sensor] +"/w1_slave"
        temperature = (read_temp())
        dtemp = "%.1f" % temperature
        result[sensor] = sensorname[sensor] + (str(dtemp)) + "`C "
        
    # write 4 lines of text to LCD     
    for sensor in range(4): 
        lcd_string(result[sensor] ,lcdline[sensor])
    
   

    time.sleep(3)
  
    # Send some more text
    lcd_string("Time: %s" %time.strftime("%H:%M"),LCD_LINE_1)
    lcd_string("Date: %s" %time.strftime("%d/%m/%Y"),LCD_LINE_2)
    lcd_string("  IP:" ,LCD_LINE_3)
    lcd_string("Host:",LCD_LINE_4)

    time.sleep(3)

if __name__ == '__main__':

  try:
    main()
  except KeyboardInterrupt:
    pass
  finally:
    lcd_byte(0x01, LCD_CMD)

So presuming this works all you need now is to add the data for the last 2 lines in the second LCD display loop.
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

User avatar
T-EGWZ34
Posts: 27
Joined: Sat Aug 18, 2018 11:39 am
Location: Bourne, UK

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 7:42 pm

Yes, that's all working fine - looking good. No luck with the apostrophe though, I'm still fighting with that one.

pcmanbob
Posts: 4462
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 7:56 pm

T-EGWZ34 wrote:
Mon Aug 20, 2018 7:42 pm
Yes, that's all working fine - looking good. No luck with the apostrophe though, I'm still fighting with that one.
So we have the code updating the display all at once at last....................... :D :D

so try changing the ` to a '

Code: Select all

result[sensor] = sensorname[sensor] + (str(dtemp)) + "'C "
If you switch to using the RPLCD library then you can easily define your own characters, So you can make your own degree symbol and use that.
But you will have to re-write most of the program but you now have an working example to guide you on your way.
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

User avatar
bensimmo
Posts: 3329
Joined: Sun Dec 28, 2014 3:02 pm
Location: East Yorkshire

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 8:19 pm


pcmanbob
Posts: 4462
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 8:22 pm

bensimmo wrote:
Mon Aug 20, 2018 8:19 pm
IP address.
Good luck

https://stackoverflow.com/questions/166 ... ons-stdlib
Actually I found this worked , output IP and host name.

Code: Select all

import subprocess
 
option = ["-I", "-f"]
hostdata = ["1", "2"]
for l in range(2):
    p = subprocess.Popen(("hostname " + option[l]), stdout=subprocess.PIPE, shell=True)
     

    (output, err) = p.communicate()
     

    status = p.wait()


    hostdata[l] = output.rstrip()
    
print hostdata[0]
print hostdata[1]    
discovered this method of using subprocess when I was messing with getting the number of devices connected to a router from within a python program, its in my list of useful program snip-its now.
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

User avatar
T-EGWZ34
Posts: 27
Joined: Sat Aug 18, 2018 11:39 am
Location: Bourne, UK

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 8:32 pm

This is looking great now, working very fast; But if I use a ' I just get a '

Don't let me loose on the IP and host name for goodness sake! :lol:

pcmanbob
Posts: 4462
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 9:06 pm

T-EGWZ34 wrote:
Mon Aug 20, 2018 8:32 pm
This is looking great now, working very fast; But if I use a ' I just get a '
That's what I was expecting its probably your only option as non of the other degree symbols seem to work even though they exists in the LCD character map, that's were RPLCD comes in to its for setting up your own characters.
Don't let me loose on the IP and host name for goodness sake! :lol:
Well now we have broken the back of the problem it would be a shame to stop without adding them. :roll:

so assuming internal IP and pi hostname are not longer than your available LCD line space.
Added it to the code so it updates them on each LCD update probably not really necessary as host name should never change but IP might if the router should power cycle, or the pi looses its connection to the router in some other way.

Code: Select all


# -*- coding: utf-8
import smbus
import time
import subprocess

# Define some device parameters
I2C_ADDR  = 0x27 # I2C device address, if any error, change this address to 0x3f
LCD_WIDTH = 20   # Maximum characters per line

# Define some device constants
LCD_CHR = 1 # Mode - Sending data
LCD_CMD = 0 # Mode - Sending command

LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line
LCD_LINE_3 = 0x94 # LCD RAM address for the 3rd line
LCD_LINE_4 = 0xD4 # LCD RAM address for the 4th line

LCD_BACKLIGHT  = 0x08  # On
#LCD_BACKLIGHT = 0x00  # Off

ENABLE = 0b00000100 # Enable bit

# Timing constants
E_PULSE = 0.0005
E_DELAY = 0.0005

#Open I2C interface
#bus = smbus.SMBus(0)  # Rev 1 Pi uses 0
bus = smbus.SMBus(1) # Rev 2 Pi uses 1

def lcd_init():
  # Initialise display
  lcd_byte(0x33,LCD_CMD) # 110011 Initialise
  lcd_byte(0x32,LCD_CMD) # 110010 Initialise
  lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction
  lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off 
  lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size
  lcd_byte(0x01,LCD_CMD) # 000001 Clear display
  time.sleep(E_DELAY)

def lcd_byte(bits, mode):
  # Send byte to data pins
  # bits = the data
  # mode = 1 for data
  #        0 for command

  bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT
  bits_low = mode | ((bits<<4) & 0xF0) | LCD_BACKLIGHT

  # High bits
  bus.write_byte(I2C_ADDR, bits_high)
  lcd_toggle_enable(bits_high)

  # Low bits
  bus.write_byte(I2C_ADDR, bits_low)
  lcd_toggle_enable(bits_low)

def lcd_toggle_enable(bits):
  # Toggle enable
  time.sleep(E_DELAY)
  bus.write_byte(I2C_ADDR, (bits | ENABLE))
  time.sleep(E_PULSE)
  bus.write_byte(I2C_ADDR,(bits & ~ENABLE))
  time.sleep(E_DELAY)

def lcd_string(message,line):
  # Send string to display

  message = message.ljust(LCD_WIDTH," ")

  lcd_byte(line, LCD_CMD)

  for i in range(LCD_WIDTH):
    lcd_byte(ord(message[i]),LCD_CHR)

# get IP and host name
hostdata = ["1", "2"]
def ip_host():
    global hostdata
    option = ["-I", "-f"]
    pre = ["  IP:", "Host:"]
    for l in range(2):
        p = subprocess.Popen(("hostname " + option[l]), stdout=subprocess.PIPE, shell=True)
        (output, err) = p.communicate()
        status = p.wait()
        hostdata[l] = pre[l] + (output.rstrip())
   
# sensor read 
device_file = ""

def read_temp_raw():
    global device_file
    f = open(device_file, "r")
    lines = f.readlines()
    f.close()
    return lines
 
def read_temp():
    lines = read_temp_raw()
    while lines[0].strip()[-3:] != "YES":
        time.sleep(0.2)
        lines = read_temp_raw()
    equals_pos = lines[1].find("t=")
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_c = float(temp_string) / 1000.0
        
        return temp_c   
    
    
    
    
def main():
  global device_file, hostdata
  # Main program block

  # Initialise display
  lcd_init()

  while True:

    # Send temp readings to lcd
    
    result = ["0", "1", "2", "3"]
    
    sensorids = ["28-0215629f5fff", "28-011562bc68ff", "28-0115629bb3ff", "28-000003ebf0ab"]
    
    sensorname = ["Out Temp:", "In  Temp:", "RX  Temp:", "VRS Temp:"]
    
    lcdline = [0x80, 0xC0, 0x94, 0xD4]
    
    # get 4 temperature readings
    for sensor in range(4):
        device_file = "/sys/bus/w1/devices/"+ sensorids[sensor] +"/w1_slave"
        temperature = (read_temp())
        dtemp = "%.1f" % temperature
        result[sensor] = sensorname[sensor] + (str(dtemp)) + "'C "
        
    # write 4 lines of text to LCD     
    for sensor in range(4): 
        lcd_string(result[sensor] ,lcdline[sensor])
    
   

    time.sleep(3)
  
    # Send some more text
    lcd_string("Time: %s" %time.strftime("%H:%M"),LCD_LINE_1)
    lcd_string("Date: %s" %time.strftime("%d/%m/%Y"),LCD_LINE_2)
    lcd_string(hostdata[0], LCD_LINE_3)
    lcd_string(hostdata[1], LCD_LINE_4)

    time.sleep(3)

if __name__ == '__main__':

  try:
    main()
  except KeyboardInterrupt:
    pass
  finally:
    lcd_byte(0x01, LCD_CMD)

awaiting report of success with bated breath :lol:
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

User avatar
T-EGWZ34
Posts: 27
Joined: Sat Aug 18, 2018 11:39 am
Location: Bourne, UK

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 9:21 pm

Well, it's not broken! However, lines 3 and 4 now just read 1 and 2 - so...

Line 1: Time
Line 2: Date
Line 3: 1
Line 4: 2

I've had a quick nosey but can't see why it's doing that.

pcmanbob
Posts: 4462
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 9:38 pm

Because I forgot to add one line to call the function to get the IP and host name :oops:

Code: Select all


# -*- coding: utf-8
import smbus
import time
import subprocess

# Define some device parameters
I2C_ADDR  = 0x27 # I2C device address, if any error, change this address to 0x3f
LCD_WIDTH = 20   # Maximum characters per line

# Define some device constants
LCD_CHR = 1 # Mode - Sending data
LCD_CMD = 0 # Mode - Sending command

LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line
LCD_LINE_3 = 0x94 # LCD RAM address for the 3rd line
LCD_LINE_4 = 0xD4 # LCD RAM address for the 4th line

LCD_BACKLIGHT  = 0x08  # On
#LCD_BACKLIGHT = 0x00  # Off

ENABLE = 0b00000100 # Enable bit

# Timing constants
E_PULSE = 0.0005
E_DELAY = 0.0005

#Open I2C interface
#bus = smbus.SMBus(0)  # Rev 1 Pi uses 0
bus = smbus.SMBus(1) # Rev 2 Pi uses 1

def lcd_init():
  # Initialise display
  lcd_byte(0x33,LCD_CMD) # 110011 Initialise
  lcd_byte(0x32,LCD_CMD) # 110010 Initialise
  lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction
  lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off 
  lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size
  lcd_byte(0x01,LCD_CMD) # 000001 Clear display
  time.sleep(E_DELAY)

def lcd_byte(bits, mode):
  # Send byte to data pins
  # bits = the data
  # mode = 1 for data
  #        0 for command

  bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT
  bits_low = mode | ((bits<<4) & 0xF0) | LCD_BACKLIGHT

  # High bits
  bus.write_byte(I2C_ADDR, bits_high)
  lcd_toggle_enable(bits_high)

  # Low bits
  bus.write_byte(I2C_ADDR, bits_low)
  lcd_toggle_enable(bits_low)

def lcd_toggle_enable(bits):
  # Toggle enable
  time.sleep(E_DELAY)
  bus.write_byte(I2C_ADDR, (bits | ENABLE))
  time.sleep(E_PULSE)
  bus.write_byte(I2C_ADDR,(bits & ~ENABLE))
  time.sleep(E_DELAY)

def lcd_string(message,line):
  # Send string to display

  message = message.ljust(LCD_WIDTH," ")

  lcd_byte(line, LCD_CMD)

  for i in range(LCD_WIDTH):
    lcd_byte(ord(message[i]),LCD_CHR)

# get IP and host name
hostdata = ["1", "2"]
def ip_host():
    global hostdata
    option = ["-I", "-f"]
    pre = ["  IP:", "Host:"]
    for l in range(2):
        p = subprocess.Popen(("hostname " + option[l]), stdout=subprocess.PIPE, shell=True)
        (output, err) = p.communicate()
        status = p.wait()
        hostdata[l] = pre[l] + (output.rstrip())
   
# sensor read 
device_file = ""

def read_temp_raw():
    global device_file
    f = open(device_file, "r")
    lines = f.readlines()
    f.close()
    return lines
 
def read_temp():
    lines = read_temp_raw()
    while lines[0].strip()[-3:] != "YES":
        time.sleep(0.2)
        lines = read_temp_raw()
    equals_pos = lines[1].find("t=")
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_c = float(temp_string) / 1000.0
        
        return temp_c   
    
    
    
    
def main():
  global device_file, hostdata
  # Main program block

  # Initialise display
  lcd_init()

  while True:

    # Send temp readings to lcd
    
    result = ["0", "1", "2", "3"]
    
    sensorids = ["28-0215629f5fff", "28-011562bc68ff", "28-0115629bb3ff", "28-000003ebf0ab"]
    
    sensorname = ["Out Temp:", "In  Temp:", "RX  Temp:", "VRS Temp:"]
    
    lcdline = [0x80, 0xC0, 0x94, 0xD4]
    
    # get 4 temperature readings
    for sensor in range(4):
        device_file = "/sys/bus/w1/devices/"+ sensorids[sensor] +"/w1_slave"
        temperature = (read_temp())
        dtemp = "%.1f" % temperature
        result[sensor] = sensorname[sensor] + (str(dtemp)) + "'C "
        
    # write 4 lines of text to LCD     
    for sensor in range(4): 
        lcd_string(result[sensor] ,lcdline[sensor])
    
   

    time.sleep(3)
    ip_host()
    # Send some more text
    lcd_string("Time: %s" %time.strftime("%H:%M"),LCD_LINE_1)
    lcd_string("Date: %s" %time.strftime("%d/%m/%Y"),LCD_LINE_2)
    lcd_string(hostdata[0], LCD_LINE_3)
    lcd_string(hostdata[1], LCD_LINE_4)

    time.sleep(3)

if __name__ == '__main__':

  try:
    main()
  except KeyboardInterrupt:
    pass
  finally:
    lcd_byte(0x01, LCD_CMD)

good example of why its advisable to put some basic data in your variables when you define them.
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

User avatar
T-EGWZ34
Posts: 27
Joined: Sat Aug 18, 2018 11:39 am
Location: Bourne, UK

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 9:50 pm

Ah don't worry about little things like that! ;)

100% working - awesome stuff. :D

Maybe 99.9999% working, I'm still arguing with unicode :evil: Why can't software developers make things simple?! Surely a degree symbol is common for this kind of application. Grrrr.

That said, I know what it means so the silly symbol is purely cosmetic.

Well you've been very busy Bob, I feel kind of guilty and while I would love to say maybe I can do the same for you one day... it's never gonna happen. :roll: :lol:

pcmanbob
Posts: 4462
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 10:01 pm

Well I have enjoyed the problem solving and its kept me occupied so only to glad to have helped. :D

With regards to the degree symbol if Dougie said he had to define a custom character to get it working then I think you might be looking at a lost cause trying to use the one in the display character map.

We all have to start some were I only started with python when I got my first pi 5 years ago so keep learning and one day you may be the one helping out.
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

User avatar
T-EGWZ34
Posts: 27
Joined: Sat Aug 18, 2018 11:39 am
Location: Bourne, UK

Re: Multiple DS18B20 Sensors on 20x4 LCD

Mon Aug 20, 2018 10:05 pm

Thanks Bob, wise words. Thanks very much for all of your time spent on this too.

I've got 2 new Raspberry Pi 3B+'s coming next week, you may wish to emigrate. ;)

User avatar
bensimmo
Posts: 3329
Joined: Sun Dec 28, 2014 3:02 pm
Location: East Yorkshire

Re: Multiple DS18B20 Sensors on 20x4 LCD

Tue Aug 21, 2018 8:14 am

Same here with the old Python, started with my first Pi (slowly) A+ and 2B some years back.
Still learning and that's why you'll find me helping out. It helps me learn as well.

It's quite different coming from a general Visual Basic, VBA and BBC Basic. BUT the logic doesn't really change, just the words.

For hostname/IP I was looking for a Python3 way of doing it and not one that needed the OS to get it.
Seems they need to improve that.


You'll learn that the error message tell you the problem, once you work out what they are trying to say, it becomes a bit easier

More often than not, you'll get indents wrong.
I spent ages debuging a very simple program, lighting LEDs up to sort of create the KIT red bar effect, I was only doing it as I thought I could improve one someone had done for the Pimoroni ScrollpHATHD.
But there was a bit hat just looked wrong, timeing was out. I just put it down to the refresh rate of the system. I came back later and thought I would try again (and move it to the RPi SenseHAT).
Anyway there was of course no error.
Eventually it was one line, not indented once more.
That was a FFS.

pcmanbob
Posts: 4462
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Multiple DS18B20 Sensors on 20x4 LCD

Tue Aug 21, 2018 2:40 pm

There are ways of doing it using socket or you can of course use the netifaces module, but the subprocess works and requires no extra modules adding to your pi.

As always if you ask the question you will get several several different ways of doing it in the replies , you just have to choose the one that works for you on the day.

always nice to have options.
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

User avatar
DougieLawson
Posts: 34156
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website

Re: Multiple DS18B20 Sensors on 20x4 LCD

Tue Aug 21, 2018 4:09 pm

I've got some python/python3 code to get your LAN IP address. With a call out to OpenDNS I can get your public IP address.

Can't get it right now I'm on-site at a client in Welwyn Garden City with no access to my VPN.
Microprocessor, Raspberry Pi & Arduino Hacker
Mainframe database troubleshooter
MQTT Evangelist
Twitter: @DougieLawson

2012-18: 1B*5, 2B*2, B+, A+, Z, ZW, 3Bs*3, 3B+

Any DMs sent on Twitter will be answered next month.

User avatar
DougieLawson
Posts: 34156
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website

Re: Multiple DS18B20 Sensors on 20x4 LCD

Wed Aug 22, 2018 10:51 pm

/home/pi/localIPaddr.py

Code: Select all

#!/usr/bin/python3
import socket
import os
testIP = "208.67.222.222"
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((testIP, 0))
ipaddr = s.getsockname()[0]
host = socket.gethostname()
print ("IP:", ipaddr, " Host:", host)
/home/pi/publicIPaddr.py

Code: Select all

#!/usr/bin/python3
import socket
import dns.resolver
resolver = dns.resolver.Resolver()
resolver.nameservers = ['208.67.222.222']
answer = resolver.query('myip.opendns.com')
ip = str(answer.rrset).split()[4]
name, alias, addresslist = socket.gethostbyaddr(ip)
print(ip)
print (name)
Microprocessor, Raspberry Pi & Arduino Hacker
Mainframe database troubleshooter
MQTT Evangelist
Twitter: @DougieLawson

2012-18: 1B*5, 2B*2, B+, A+, Z, ZW, 3Bs*3, 3B+

Any DMs sent on Twitter will be answered next month.

Return to “Python”