Page 3 of 4

Re: GUI for display management

Posted: Sun Nov 08, 2015 1:00 pm
by paolojo

Re: GUI for display management

Posted: Sun Nov 08, 2015 1:20 pm
by elParaguayo
OK. Same guide as me!

Seems like the Config.set isn't registering. The solution is a bit of a hack I'm afraid, you just need to edit the config.ini file directly.

The file should be at ~/.kivy/config.ini

There will be height and width lines in there.

I really don't know why the Window.size line doesn't work though...

Edit: Spoke too soon - see below.

Re: GUI for display management

Posted: Mon Nov 09, 2015 1:32 pm
by elParaguayo
Looking at the Kivy config source code, it says this:
Applying configurations
-----------------------

Configuration options control the initialization of the :class:`~kivy.app.App`.
In order to avoid situations where the config settings do not work or are not
applied before window creation (like setting an initial window size
),
... Config.set ... should be used before
importing any other Kivy modules. Ideally, this means setting them right at
the start of your main.py script
.
So, try moving the config import and config.set lines to the very top of your script.

Re: GUI for display management

Posted: Mon Nov 09, 2015 7:38 pm
by paolojo

Seems like the Config.set isn't registering. The solution is a bit of a hack I'm afraid, you just need to edit the config.ini file directly.
The file should be at ~/.kivy/config.ini
There will be height and width lines in there.
In "~/.kivy/" directory, i have only the following items:
AUTHORS
CONTRIBUTING.md
examples
LICENSE
MANIFEST.in
setup.cfg
build
doc
kivy
Makefile
README.md
setup.py

So, there isn't the file confing.ini
So, try moving the config import and config.set lines to the very top of your script.
I've tried to move he config import and config.set lines to the very top of my script, but it still doesn't work!

Re: GUI for display management

Posted: Mon Nov 09, 2015 8:11 pm
by elParaguayo
Ok. That doesn't look right at all.

That looks like the files you'd get when you download kivy and try to install it, but they shouldn't be in your .kivy folder.

On my pi, my .kivy folder has this:

Code: Select all

extensions/
icon/
logs/
mods/
config.ini
Also, setting the config.set line at the top of my script had the desired effect.

I think there is therefore an issue with your installation. Does the console output give you any clues when you run your script?

Re: GUI for display management

Posted: Mon Nov 09, 2015 9:47 pm
by paolojo
Sorry!!
I've found finally the "config.ini" file!
I did a mistake: I've confused the folder "kivy" with the right hidden folder ".kivy".
Now I've tried to change the height and width parameters, but nothing changes.
Here follows the content of my config.ini file

Code: Select all

[kivy]
keyboard_repeat_delay = 300
keyboard_repeat_rate = 30
log_dir = logs
log_enable = 1
log_level = info
log_name = kivy_%y-%m-%d_%_.txt
window_icon =
keyboard_mode =
keyboard_layout = qwerty
desktop = 1
exit_on_escape = 1
pause_on_minimize = 0
config_version = 14

[graphics]
display = -1
fullscreen = 1  <<<==I've triedeto set this parameter
height = 200  <<<==I've triedeto set this parameter
left = 0
maxfps = 60
multisamples = 2
position = auto
rotation = 0
show_cursor = 1
top = 0
width = 100  <<<==I've triedeto set this parameter
resizable = 0  <<<==I've triedeto set this parameter
borderless = 0
window_state = visible
minimum_width = 0
minimum_height = 0

[input]
mouse = mouse
%(name)s = probesysfs,provider=hidinput

[postproc]
double_tap_distance = 20
double_tap_time = 250
ignore = []
jitter_distance = 0
jitter_ignore_devices = mouse,mactouch,
retain_distance = 50
jitter_ignore_devices = mouse,mactouch,
retain_distance = 50
retain_time = 0
triple_tap_distance = 20
triple_tap_time = 375

[widgets]
scroll_timeout = 250
scroll_distance = 20
scroll_friction = 1.
scroll_stoptime = 300
scroll_moves = 5

[modules]
Is there another parameter that I have to modify?

Re: GUI for display management

Posted: Mon Nov 09, 2015 9:51 pm
by elParaguayo
Are you running kivy using "sudo"?

If so, have a look for the config file in "/root/.kivy/".

Just change the height and width for now and see if you can get those to change.

Re: GUI for display management

Posted: Mon Nov 09, 2015 10:06 pm
by paolojo
even if I don't execute the script with "sudo", I've tried to modify the /root/.kivy/config.ini.
Nothing changes! :roll: :twisted: :cry:

Re: GUI for display management

Posted: Mon Nov 09, 2015 10:22 pm
by elParaguayo
It just doesn't make sense to me!

Can you remove the config.set lines from your script and just include these two:

Code: Select all

print Config.get("graphics", "height")
print Config.get("graphics", "width")
so we can see what values are being read.

Re: GUI for display management

Posted: Mon Nov 09, 2015 10:29 pm
by paolojo
I obtain:
100
200
...so, this is corret! but I don't see changes in my tv!
Is it normal?

Re: GUI for display management

Posted: Mon Nov 09, 2015 10:52 pm
by elParaguayo
I'm all out of ideas here. Kivy seems to be reading your config so there's no reason for the window size not to be set.

Post your full code again and let me have one last look.

Re: GUI for display management

Posted: Mon Nov 09, 2015 11:10 pm
by paolojo

Code: Select all

#!/usr/bin/env python


import kivy
kivy.require('1.9.0')
from kivy.config import Config
Config.set('graphics', 'width', '250')
Config.set('graphics', 'height', '150')
# le righe di config e relativi import,devono essere in testa allo script
# se l'impostazioni di dimensione dello scherma non ha effetto,
# impostarlo dal file config.ini in /home/pi/.kivy/config.ini


# MainApp.py
from threading import Thread
from time import sleep
from kivy.app import App
from kivy.uix.carousel import Carousel
from kivy.uix.image import AsyncImage
from glob import glob
from os.path import join, dirname
from kivy.uix.scatter import Scatter
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import StringProperty
from random import randint
from kivy.clock import Clock
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.core.window import Window
from kivy.uix.image import Image

import RPi.GPIO as gpio

# This is a worker class that will work in a separate thread.
class TempWorker(Thread):

    def __init__(self, callback):
        super(TempWorker, self).__init__()

        # Save reference to our callback function
        self.callback = callback

        # Initialise GPIO here
        gpio.setmode(gpio.BCM)  
        gpio.setup(4, gpio.IN, pull_up_down=gpio.PUD_DOWN)

    def run(self):
        # The "run" method is called when a thread is started

        # Initialise your variables
        numero=0
        pulse_cnt_high=0
        pulse_cnt_low=0
        max_pulse_cnt=1
        pulse_status=pulse_status_old=0

        # Start your loop
        while True:
           
            if gpio.input(4):

                pulse_cnt_low=0

                if (pulse_cnt_high<max_pulse_cnt):
                    pulse_cnt_high=pulse_cnt_high+1

                else:

                    pulse_status=1
                    pulse_cnt_high=0

            else:

                pulse_cnt_high=0

            if (pulse_cnt_low<max_pulse_cnt):

                pulse_cnt_low=pulse_cnt_low+1

            else:

                pulse_status=0
                pulse_cnt_low=0

            # Send the value of pulse_status to our callback
            self.callback(pulse_status)

            # Sleep for 100ms
            sleep(0.1)



class Screen(FloatLayout):
    def __init__(self, **kwargs):
        super(Screen, self).__init__(**kwargs)
	 
        layout = BoxLayout(orientation='horizontal', spacing=3)
		#il parametro spacing determina la distanza tra i due box
        tx = '[b][size=45][color=ff3333]The current value of pulse_status is:[/color][/size][/b]'

        self.lbl = Label(
		          	text=tx, 
				markup=True, 
				size_hint=(.4, 1),
				pos_hint={"center_x":.5, "center_y":.7})

        carousel = Carousel(direction='right', size_hint=(.6, 1))

        carousel.loop = True

        curdir = dirname(__file__)

        for filename in glob(join(curdir, '/home/pi/myfolder/img', '*')):
            picture = Image(source=filename,allow_stretch=True)
            carousel.add_widget(picture)

        Clock.schedule_interval(carousel.load_next, 5)

        layout.add_widget(carousel)
        layout.add_widget(self.lbl)
        
        self.add_widget(layout)

		# Create the thread object and pass the reference to our callback
        # function
        worker = TempWorker(callback=self.update_label_text)

        # Daemonising the thread means that when you exit Kivy, this thread
        # will also be killed
        worker.daemon = True

        # Start the thread
        worker.start()

    def update_label_text(self, val):

        # Update our label text
        self.lbl.text = "Current value: {}".format(val)


class MainApp(App):
    def build(self):
        #imposto il colore dello sfondo
	Window.clearcolor = (255, 255, 255, 1)
        #Window.size=(500, 500)
	return Screen()

MainApp().run()

I'm trying in this moment this version!
In addition of size window problems, I'm getting other problems: the value of pulse_status is not visualized..and neither the label!
In fact, reading the code, I don't find relation among the label and the value of pulse_status!In other words, if I've understood right, the instruction that visualizes the text (label) is:

layout.add_widget(self.lbl)

where:

self.lbl = Label(text=tx, markup=True, size_hint_x=0.5)

and

tx = '[color=ff3333]The current value of pulse_status is:[/color]'

So, there isn't a link between the label and value of pulse_status!

Re: GUI for display management

Posted: Tue Nov 10, 2015 8:54 am
by elParaguayo
I don't know about the size issue but I can explain the link to the label.

You are right, when you create the label, it has an initial value of whatever text is stored in the "tx" variable.

However, the script then creates a worker object and passes a reference to a callback function:

Code: Select all

worker = TempWorker(callback=self.update_label_text)
Once the worker is running (i.e. after the "start()" call) your GPIO loop runs.

At the end of each loop, the callback function is called, with the value of "pulse_status" as an argument:

Code: Select all

self.callback(pulse_status)
The callback function, looks like this:

Code: Select all

    def update_label_text(self, val):

        # Update our label text
        self.lbl.text = "Current value: {}".format(val)
As you can see, the function accepts a "val" argument. In this case, your "pulse_status" value will be stored in "val".

The function then updates the label text with the new value:

Code: Select all

self.lbl.text = "Current value: {}".format(val)
This is not the same way of binding values to labels that you may have come across in Kivy elsewhere, but it is still a valid way of changing the text.

Re: GUI for display management

Posted: Tue Nov 10, 2015 2:01 pm
by paolojo
ok, I've understood, but the label isn't updated.
Reading on the web, I've found a very interesting function: GPIO.add_event_detect (http://sourceforge.net/p/raspberry-gpio ... ki/Inputs/); this function generates a new thread for callback function.
I've tried use it and here follows the entire code:

Code: Select all

# MainApp.py

from threading import Thread
from kivy.app import App
from kivy.uix.carousel import Carousel
from kivy.uix.image import AsyncImage
from glob import glob
from os.path import join, dirname
from kivy.uix.scatter import Scatter
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import StringProperty
from random import randint
from kivy.clock import Clock
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.core.window import Window
from kivy.uix.image import Image
import RPi.GPIO as GPIO  

GPIO.setmode(GPIO.BCM) 
GPIO.setup(4, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

n = 0

def my_callback(channel):  
    global n
    print "rising detected on GPIO 4"
    n=n+1
    print "n=",n
    return n

GPIO.add_event_detect(4, GPIO.RISING, callback=my_callback, bouncetime=500)	


class TempWorker(Thread):

    def __init__(self, callback):
        super(TempWorker, self).__init__()

        # Save reference to our callback function
        self.callback = callback

    def run(self):
        # The "run" method is called when a thread is started
		# Send the value of global n to our callback
        self.callback(n)
	

class Screen(FloatLayout):
    def __init__(self, **kwargs):
        super(Screen, self).__init__(**kwargs)
	 
        layout = BoxLayout(orientation='horizontal', spacing=3)
		#il parametro spacing determina la distanza tra i due box
        tx ='[b][size=45][color=ff3333]The value of n is \n\[/color][/size][/b]'

        self.lbl = Label(
		   text=tx, 
		   markup=True, 
		   size_hint=(.4, 1),
		   pos_hint={"center_x":.5, "center_y":.7})
	
        carousel = Carousel(direction='right', size_hint=(.6, 1))

        carousel.loop = True

        curdir = dirname(__file__)

        for filename in glob(join(curdir, '/home/pi/mufolder/img', '*')):
            picture = Image(source=filename,allow_stretch=True)
            carousel.add_widget(picture)

        Clock.schedule_interval(carousel.load_next, 5)

        layout.add_widget(carousel)
        layout.add_widget(self.lbl)
        
        self.add_widget(layout)

    	# Create the thread object and pass the reference to our callback
        # function
        worker = TempWorker(callback=self.update_label_text)

		# Daemonising the thread means that when you exit Kivy, this thread
        # will also be killed
        worker.daemon = True

		# Start the thread
        worker.start()


    def update_label_text(self, val):
        print "update_label_text called and n=", n 
		# Update our label text
        self.lbl.text = "Current ue: {}".format(val)


class MainApp(App):
    def build(self):
        #imposto il colore dello sfondo
	Window.clearcolor = (255, 255, 255, 1)
        #Window.size=(500, 500)
	return Screen()

MainApp().run()

The problem is still the same: the "update_label_text" function doesn't work!
When I run the code, i see that the string "update_label_text called and n=" is printed only one time, this means that the functiion "update_label_text" is called only one time!
Can You help me pleas? I'm going out of head! :cry:
Is correct how I've used "TempWorker(Thread)"?
Thank youuuuuuuu!!!

Re: GUI for display management

Posted: Tue Nov 10, 2015 2:36 pm
by elParaguayo
Can't look in detail now but you "worker" will only call the callback once because your "run" method does not have a loop in it so the thread runs once and exits.

Re: GUI for display management

Posted: Tue Nov 10, 2015 3:11 pm
by paolojo
ok, I understand!
How can I call the "run" method every time that "n" changes value?

Re: GUI for display management

Posted: Tue Nov 10, 2015 4:03 pm
by elParaguayo
You may not need the worker. I included it because you had some looping GPIO code which needed to run at the same time as the Kivy screen.

However, you really need to confirm what you want your GPIO code to do. If it can be handled via the add_event_detect method then we can probably do this without threading. You would then just get your callback to add a value to n and update the label.

I'll be home in a few hours and will post some updated code for you.

Re: GUI for display management

Posted: Tue Nov 10, 2015 4:13 pm
by paolojo
If it can be handled via the add_event_detect method then we can probably do this without threading. You would then just get your callback to add a value to n and update the label.
yes, it can be. In this moment I want only do the following:
every time that GPIO 4 rises (positive edge), i increase the counter "n" (n=n+1) and I update the label with this value.
ll be home in a few hours and will post some updated code for you.
[/quote]
Ok, I'll wait for you! :D

Re: GUI for display management

Posted: Tue Nov 10, 2015 4:45 pm
by elParaguayo
paolojo wrote:yes, it can be. In this moment I want only do the following:
every time that GPIO 4 rises (positive edge), i increase the counter "n" (n=n+1) and I update the label with this value.
Perfect - no need for my separate worker thread.

Re: GUI for display management

Posted: Tue Nov 10, 2015 6:52 pm
by elParaguayo
Let's try this:

Code: Select all

# MainApp.py
from random import randint
from glob import glob
from os.path import join, dirname

from kivy.app import App
from kivy.clock import Clock
from kivy.core.window import Window
from kivy.properties import StringProperty
from kivy.uix.carousel import Carousel
from kivy.uix.image import AsyncImage
from kivy.uix.scatter import Scatter
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.image import Image

import RPi.GPIO as GPIO  

class Screen(FloatLayout):
    def __init__(self, **kwargs):
        super(Screen, self).__init__(**kwargs)

        # Here's your GPIO stuff
        GPIO.setmode(GPIO.BCM) 
        GPIO.setup(4, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) 
        self.n = 0

        # Add a call function
        GPIO.add_event_detect(4,
                              GPIO.RISING,
                              callback=self.my_callback,
                              bouncetime=500) 
    
        layout = BoxLayout(orientation='horizontal', spacing=3)
        #il parametro spacing determina la distanza tra i due box

        # Create a template for your text
        self.tx ='[b][size=45][color=ff3333]The value of n is {n}[/color][/size][/b]'

        self.lbl = Label(text=self.tx.format(n=self.n), 
                         markup=True, 
                         size_hint=(.4, 1),
                         pos_hint={"center_x":.5, "center_y":.7})
   
        carousel = Carousel(direction='right', size_hint=(.6, 1))

        carousel.loop = True

        curdir = dirname(__file__)

        for filename in glob(join(curdir, '/home/pi/mufolder/img', '*')):
            picture = Image(source=filename,allow_stretch=True)
            carousel.add_widget(picture)

        Clock.schedule_interval(carousel.load_next, 5)

        layout.add_widget(carousel)
        layout.add_widget(self.lbl)
        
        self.add_widget(layout)

    def my_callback(self, channel):  
        print "rising detected on GPIO 4"
        self.n += 1

        # Update our template with the current value of n
        tx = self.tx.format(n=self.n)

        # Print it
        print tx

        # Update the text on the label.
        self.lbl.text = tx


class MainApp(App):
    def build(self):
        #imposto il colore dello sfondo
        Window.clearcolor = (255, 255, 255, 1)
        #Window.size=(500, 500)
        return Screen()

MainApp().run()

Re: GUI for display management

Posted: Tue Nov 10, 2015 9:40 pm
by paolojo
GREAT!!!!!!!
IT WORKS!!!! :mrgreen: :mrgreen: :D :D :) :)
Thanks a lot my friend!!!

Re: GUI for display management

Posted: Tue Nov 10, 2015 9:44 pm
by elParaguayo
You are most welcome. Happy to help.

Re: GUI for display management

Posted: Wed Nov 11, 2015 3:45 pm
by -rst-
For the test setup you would need to create a thread to read the GPIO (yield a bit in the while loop not to hog all CPU) or use a GPIO library that provides events/interrupts.

For temperature measurement (no need for tight loop) you could probably do with the Kivy Clock repeatedly calling a function/method to read the GPIO.

Re: GUI for display management

Posted: Fri Nov 13, 2015 3:42 pm
by paolojo

Code: Select all

    def my_callback(self, channel):  
        print "rising detected on GPIO 4"
        self.n += 1

        # Update our template with the current value of n
        tx = self.tx.format(n=self.n)

        # Print it
        print tx

        # Update the text on the label.
        self.lbl.text = tx
.       #CALL NEW FUNCTION
.        new_script.new_function()

I have just another question. Suppose that In "my_callback" i would call another function "new_function" included in a new script "new_script". I would control the execution of this function with a sort of watchdog: if "new_function" execution need too much time, i want abort it. How can i do? Since "new_function" is called from "my_callback",is it executed in a new thread?

Re: GUI for display management

Posted: Sat Nov 14, 2015 12:34 pm
by elParaguayo
Can you explain what your new function would be doing and what the conditions for killing it are?