Problems with GPIO push button on self build emonPi

What are you trying to do here? That surely is wrong.

Thank you always appreciated, well i am at this stage the monkey behind the keyboard :smile:
Probably know less than 1% ,must say @pb66 is a genius at mqtt, he has help me so much.

Random guessing is always the slow way. You must be methodical and take one small step at a time when you are learning something new.

the logic flow 0,1,2,3 =4 lines
just as a test i used 0,1,3,4

lcd [0]
lcd [1]
lcd [2]
lcd [3]

or 

lcd [0]
lcd [1]
lcd [3]
lcd [4]

I know, been over a week and i can display a test file with 4 lines. Anything else altered in the lcd file kills the script

Would have been nice, if all you had to do, was uncomment a few lines in the file

# uncomment the following default: 16x2
#i2c 20x4
i2c 16x2 

my wishful thinking :slight_smile:

Do you want an honest piece of advice?

I know you’re trying hard, but you are coming close to desperation. Stop trying to modify a quite complicated program, step back and go through a Python tutorial, and learn the basics.

I ought to do that as well. :grin:
I’ve been writing programs for nearly 40 years - the first was in Fortran 4 :astonished: so Python will be just another.

I know you right :smile: , it just amazes me no one has tried a 20x4 yet, it is only slightly more expensive her in South Africa

We cannot get the emonpi complete here, so we have to build it in other ways. 4 line display made more sense to me, our power is so bad in South Africa i try an monitor as much as i can. AKA 4 line

I have had allot of fun getting it to this stage, its been expensive dollar wize to our rand around R3000

It makes it worthwhile and satisfying at the end of the day, as there are such great people on the form, that are willing to help in anyway, and don’t expect anything in return. Such as yourself @pb66 is another.

What does that mean? I can’t see the quote in the file you’re editing.

It looks like Paul pointed you in the right direction a short while ago.
Look at these lines (line no. 385 or so)

    def __setitem__(self, line, string):
        if not 0 <= line <= 1:
            raise IndexError("line number out of range")
        # Format string to exactly the width of LCD
        string = '{0!s:<16.16}'.format(string)
        if string != self._display[line]:
            self._display[line] = string
            self.logger.debug("LCD line {0}: {1}".format(line, string))
            self.lcd.lcd_display_string(string, line + 1)

Did you try changing the first line to:

        if not 0 <= line <= 3:

It’s obvious the array is zero-based, so in conjunction with that, try

lcd[2] = ‘test 456’
lcd[3] = ‘test 789’

My thinking is, in the absence of a meaningful error message (because that screenshot doesn’t come from Python), you don’t know whether the error is in addressing the LCD or in the data you are trying to send to it. Let’s eliminate the last one - send a string that you know works.

Hi @Robert.Wall no error, no displaying ‘789…ect’ does crash when push button to the altered page, where the lcd [2] ,[3] was altered.

So lcd[2] = ‘test 456’ is syntactically correct (i.e, the interpreter didn’t spit it out), but something else caused a crash.

Is your emonPi program using the same LCD library as the test program?

How are you running the script? The way it runs by default is via a systemd service unit so that it starts automatically at boot, however, that is not going to be easy for you to debug as you will need to search for the reported error(s) in the journalctl files.

I recommend that you stop the emonPiLCD service and run the script manually from the command line (if you are not already doing so). That way you will get the errors output to the console when it fails.

Looking at the code further, the lines are also hardcoded to 16 chars in multiple places, firstly the lcd spec’d as 16 char

        # Init LCD using detected I2C address with 16 characters
        self.lcd = lcddriver.lcd(int(current_lcd_i2c, 16))

and then later, the strings are padded out with spaces to or truncated to 16 chars

        # Format string to exactly the width of LCD
        string = '{0!s:<16.16}'.format(string)

you could just edit the 3 instances of “16” to “20” or you could add a variable to do this in one go eg

charCount = 20        # set to 16 or 20 chars per line depending on display used

and edit the code like so

        # Init LCD using detected I2C address.
        self.lcd = lcddriver.lcd(int(current_lcd_i2c, charCount))

and

        # Format string to exactly the width of LCD.
        string = '{0!s:<{1}.{1}}'.format(string, charCount)

The charCount variable should probably sit near the top of the script after the I²C addresses and before the max_number_pages.

Also, it seems the number of lines is also perhaps limited by this line

            self._display = ['', '']

which is a crude way of creating an empty list with just 2 items (they are 4 single quotes split in to pairs by a comma, not a comma in double quotes). Personally I would have done

            self._display = [""]*2

from there you could then change that to a variable, eg

            self._display = [""]*lineCount

then by adding

lineCount = 4         # set to 2 or 4 lines depending on display used.

Assuming the above is all you need to convert the scripts ability to drive a 20x4 display, as Robert suggests, just keep the testing simple. By adding just

    lcd[2] = "Page {} line 3".format(page)
    lcd[3] = "Page {} line 4".format(page)

after the eleventh page “elif” it should just append the same 3rd and 4th line to every page, only the page number should change as you scroll through the pages.

   elif page == 11:
        lcd[0] = "Shutdown?"
	shutConfirm = True


    lcd[2] = "Page {} line 3".format(page)
    lcd[3] = "Page {} line 4".format(page)

OMG!

No wonder you are having indentation issues !!!

See screen grab below for a very small snippet of the raw original code viewed in notepad++, each red dot is a space and each red line is a tab.

Some 1st level indents are 3 spaces others are 4 spaces others are (4 char) tabs. God knows what those shutConfirm lines are up to! I’m surprised the code runs without you modding it!

image



[edit]
I have just tried tidying up the original code indentations and added the suggestions I’ve made above. I’ve attached to for you to try, it comes with no warranty, sold as seen, use at your own peril :smile: I have no idea if it will run or work, but you are welcome to try it.

emonPiLCD.py.txt (18.5 KB) (18.5 KB) [edit - corrected L159 & L274 indents]

You will need to backup your existing copy, download this one and set it to executable, running this should do that for you

sudo systemctl stop emonPiLCD
mv /home/pi/emonpi/lcd/emonPiLCD.py /home/pi/emonpi/lcd/emonPiLCD.py.bak
wget -P /home/pi/emonpi/lcd/ https://community.openenergymonitor.org/uploads/default/original/2X/d/d9770f64ad45d5bdd75f165e9c6523b055c5eec7.txt 
chmod +x /home/pi/emonpi/lcd/emonPiLCD.py

and then just run the script from the command line at first

/home/pi/emonpi/lcd/emonPiLCD.py

good luck!

1 Like

As always you a star.

I have notepad++ and set to look at white spaces and tabs,compared the 2, at the point that it stops, cant find a fault.

this is the error i get

pi@emonpi:~/emonpi/lcd $ sudo python  emonPiLCD1.py
  File "emonPiLCD1.py", line 159
    lcd.backlight = 1
      ^
IndentationError: expected an indented block
pi@emonpi:~/emonpi/lcd $

Line 159 needs to be indented further as it is the code that only runs if the previous “if” line dictates, so you’ll need to add the 4 spaces to indent it correctly.

Hi @pb66 while i was waiting i tried a few things, not there yet but long last progress, 2nd pic is when i push the button, does not clear the bottom values.And bottom right some strange values. but progress thank you

I took the original script and changed it like this.emonPiLCD.txt (17.8 KB)

You should use the one I have corrected the indentation and modded for 20x4 size, the original and therefore you copy are really difficult to follow as the indents are not correct and hard to edit as you need to try and work to the erratic indentation.

I have corrected L159 in my copy attached previously.

That would be right, the lines are overwritten rather than cleared, so as you only have code to write to lines 3 and 4 on the one page, it will only overwrite line 3&4 when loading that page.

My example puts the code for lines 3&4 outside of any one page so they are updated with every page selection.

Most likely because you are still running 16 char per line code on a 20 char per line display, therefore the last 4 chars are not under control.

Hi @pb66 understood, tried new edit, get this as a result.

pi@emonpi:~/emonpi/lcd $ sudo systemctl stop emonPiLCD
pi@emonpi:~/emonpi/lcd $ sudo python  emonPiLCD1.py
emonPiLCD logging to: /var/log/emonpilcd/emonpilcd.log
I2C LCD DETECTED Ox27
Traceback (most recent call last):
  File "emonPiLCD1.py", line 565, in <module>
    main()
  File "emonPiLCD1.py", line 449, in main
    lcd = LCD(logger)
  File "emonPiLCD1.py", line 391, in __init__
    self.lcd = lcddriver.lcd(int(current_lcd_i2c, charCount))
ValueError: invalid literal for int() with base 20: '0x27'
pi@emonpi:~/emonpi/lcd $