Un ulteriore metodo di generare la GUI di prova mediante PyQt e' quella di avvalersi di QtDesigner (da non confondersi con QtCreator che e' relativo al C ed e' un ambiente di sviluppo completo)
Dopo aver composto l'interfaccia grafica si salva il file (.ui) che non e' altro che un Xml con le informazioni di impaginazione
Successivamente con il comando
puic4.bat -x progressbar.uic > progressbar.py
si puo' generare del codice Python/PyQt per creare la finestra come richiesto
il codice autogenerato dal comando sopra riportato
progressbar.py
---------------------------------------------------
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'c:\Documents and Settings\l.innocenti\Desktop\qt\progressbar.ui'
#
# Created: Mon Aug 27 15:05:35 2012
# by: PyQt4 UI code generator 4.9.4
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(351, 117)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.horizontalSlider = QtGui.QSlider(self.centralwidget)
self.horizontalSlider.setGeometry(QtCore.QRect(10, 10, 331, 21))
self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
self.horizontalSlider.setObjectName(_fromUtf8("horizontalSlider"))
self.progressBar = QtGui.QProgressBar(self.centralwidget)
self.progressBar.setGeometry(QtCore.QRect(10, 70, 341, 23))
self.progressBar.setProperty("value", 24)
self.progressBar.setObjectName(_fromUtf8("progressBar"))
self.label = QtGui.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(10, 40, 331, 20))
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName(_fromUtf8("label"))
MainWindow.setCentralWidget(self.centralwidget)
self.actionCambia_valore = QtGui.QAction(MainWindow)
self.actionCambia_valore.setObjectName(_fromUtf8("actionCambia_valore"))
self.retranslateUi(MainWindow)
QtCore.QObject.connect(self.horizontalSlider, QtCore.SIGNAL("valueChanged(int)"), self.azione)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "Progress Bar", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("MainWindow", "0", None, QtGui.QApplication.UnicodeUTF8))
self.actionCambia_valore.setText(QtGui.QApplication.translate("MainWindow", "cambia_valore", None, QtGui.QApplication.UnicodeUTF8))
def azione(self):
s = self.horizontalSlider.value()
self.label.setText(str(s))
self.progressBar.setValue(s)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
---------------------------------------------------
Il problema fondamentale e' che il programma di conversione e' molto buono per generare il codice dei componenti visuali ma non gestisce bene la creazione degli eventi in particolare quelli custom
Per questo motivo e' necessario editare e modificare il codice a mano (evidenziato in giallo)
Progressbar.ui
----------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>351</width>
<height>117</height>
</rect>
</property>
<property name="windowTitle">
<string>Progress Bar</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QSlider" name="horizontalSlider">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>331</width>
<height>21</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QProgressBar" name="progressBar">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>341</width>
<height>23</height>
</rect>
</property>
<property name="value">
<number>24</number>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>331</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</widget>
<action name="actionCambia_valore">
<property name="text">
<string>cambia_valore</string>
</property>
</action>
</widget>
<resources/>
<connections>
<connection>
<sender>horizontalSlider</sender>
<signal>sliderMoved(int)</signal>
<receiver>actionCambia_valore</receiver>
<slot>trigger()</slot>
<hints>
<hint type="sourcelabel">
<x>175</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>175</x>
<y>58</y>
</hint>
</hints>
</connection>
</connections>
</ui>
----------------------------------------------------
lunedì 27 agosto 2012
Esempio GUI con PyGTK/Glade
In questa versione dell'esempio di GUI l'interfaccia non e' stata creata da codice bensi' mediante il GUI Designer di GTK ovvero Glade
Per iniziare a creare l'interfaccia deve essere prima aggiunto una form (ovvero un TopLevel) a cui deve essere aggiunta una Box (in questo caso un VBox) per impacchettare i Widgets e successivamente si aggiungono i Widgets
Il nome della finestra di TopLevel e' stato definito come MainWindow (nome che servira' per la referenziazione)
In Properties/Signal si puo' definire l'evento che si vuole catturare
Il salvataggio dell'interfaccia puo' avvenire in due formati (GtkBuilder e Libglade). Nell'esempio riportato di seguito e' stato scelto LibGlade
Il programma in Python...il codice e' abbastanza autoesplicativo
---------------------------------------------------
import sys
try:
import pygtk
pygtk.require("2.0")
except:
pass
try:
import gtk
import gtk.glade
except:
sys.exit(1)
class ProgressBar:
def __init__(self):
self.gladefile = "progressbar.glade"
self.wTree = gtk.glade.XML(self.gladefile)
self.window = self.wTree.get_widget("MainWindow")
self.window.show()
if (self.window):
self.window.connect("destroy", gtk.main_quit)
dic = { "on_hscale1_value_changed" : self.cambia_valore}
self.wTree.signal_autoconnect(dic)
def cambia_valore(self, widget):
a = self.wTree.get_widget("hscale1").get_value()
self.wTree.get_widget("label1").set_text(str(int(a)))
self.wTree.get_widget("progressbar1").set_fraction(a/100)
if __name__ == "__main__":
hwg = ProgressBar()
gtk.main()
---------------------------------------------------
progressbar.glade
---------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<glade-interface>
<!-- interface-requires gtk+ 2.24 -->
<!-- interface-naming-policy project-wide -->
<widget class="GtkWindow" id="MainWindow">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Progress Bar</property>
<property name="default_width">250</property>
<property name="default_height">80</property>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<widget class="GtkHScale" id="hscale1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">0 0 110 1 1 10</property>
<property name="lower_stepper_sensitivity">off</property>
<property name="upper_stepper_sensitivity">off</property>
<property name="restrict_to_fill_level">False</property>
<property name="round_digits">1</property>
<property name="digits">0</property>
<property name="draw_value">False</property>
<signal name="change_value" handler="on_hscale1_change_value" swapped="no"/>
<signal name="value_changed" handler="on_hscale1_value_changed" swapped="no"/>
</widget>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">0</property>
</widget>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkProgressBar" id="progressbar1">
<property name="visible">True</property>
<property name="can_focus">False</property>
</widget>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>
---------------------------------------------------
Per iniziare a creare l'interfaccia deve essere prima aggiunto una form (ovvero un TopLevel) a cui deve essere aggiunta una Box (in questo caso un VBox) per impacchettare i Widgets e successivamente si aggiungono i Widgets
Il nome della finestra di TopLevel e' stato definito come MainWindow (nome che servira' per la referenziazione)
In Properties/Signal si puo' definire l'evento che si vuole catturare
Il salvataggio dell'interfaccia puo' avvenire in due formati (GtkBuilder e Libglade). Nell'esempio riportato di seguito e' stato scelto LibGlade
Il programma in Python...il codice e' abbastanza autoesplicativo
---------------------------------------------------
import sys
try:
import pygtk
pygtk.require("2.0")
except:
pass
try:
import gtk
import gtk.glade
except:
sys.exit(1)
class ProgressBar:
def __init__(self):
self.gladefile = "progressbar.glade"
self.wTree = gtk.glade.XML(self.gladefile)
self.window = self.wTree.get_widget("MainWindow")
self.window.show()
if (self.window):
self.window.connect("destroy", gtk.main_quit)
dic = { "on_hscale1_value_changed" : self.cambia_valore}
self.wTree.signal_autoconnect(dic)
def cambia_valore(self, widget):
a = self.wTree.get_widget("hscale1").get_value()
self.wTree.get_widget("label1").set_text(str(int(a)))
self.wTree.get_widget("progressbar1").set_fraction(a/100)
if __name__ == "__main__":
hwg = ProgressBar()
gtk.main()
---------------------------------------------------
progressbar.glade
---------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<glade-interface>
<!-- interface-requires gtk+ 2.24 -->
<!-- interface-naming-policy project-wide -->
<widget class="GtkWindow" id="MainWindow">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Progress Bar</property>
<property name="default_width">250</property>
<property name="default_height">80</property>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<widget class="GtkHScale" id="hscale1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">0 0 110 1 1 10</property>
<property name="lower_stepper_sensitivity">off</property>
<property name="upper_stepper_sensitivity">off</property>
<property name="restrict_to_fill_level">False</property>
<property name="round_digits">1</property>
<property name="digits">0</property>
<property name="draw_value">False</property>
<signal name="change_value" handler="on_hscale1_change_value" swapped="no"/>
<signal name="value_changed" handler="on_hscale1_value_changed" swapped="no"/>
</widget>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">0</property>
</widget>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkProgressBar" id="progressbar1">
<property name="visible">True</property>
<property name="can_focus">False</property>
</widget>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>
---------------------------------------------------
Esempio Gui in Lazarus/Pascal
Per gli esempi delle GUI su Linux stavo cercando di ritirare fuori Kylix (che esisteva anche in versione Open Edition oltre che commerciale) quando mi sono accorto che e' un prodotto praticamente defunto
In ogni caso esiste un sostituto che ne mima le funzionalita', l'interfaccia ed il linguaggio ovvero Lazarus Pascal
La differenza principali nell'Editor di Gui e' che i widgets non si trascinano sul Form ma si deve cliccare sulla toolbar per selezionare il widget e poi cliccare sul Form per inserirlo
Per la gestione degli eventi si usa il tab vicino alle proprieta' del widget, si seleziona l'evento e si apre l'editor di codice che nel caso in esame e' particolarmente semplice
--------------------------------------
ProgressBa1.position = TrackBar1.Position;
Label1.Caption = IntToStr(TrackBar1.Position);
--------------------------------------
In ogni caso esiste un sostituto che ne mima le funzionalita', l'interfaccia ed il linguaggio ovvero Lazarus Pascal
La differenza principali nell'Editor di Gui e' che i widgets non si trascinano sul Form ma si deve cliccare sulla toolbar per selezionare il widget e poi cliccare sul Form per inserirlo
Schermata dell'IDE di Lazarus |
--------------------------------------
ProgressBa1.position = TrackBar1.Position;
Label1.Caption = IntToStr(TrackBar1.Position);
--------------------------------------
Esempio Gui in Mono/C#
La GUI di esempio scritta in C# Mono
Per Debian e' sufficiente installare il pacchetto mono-complete che aggiunge anche l'IDE MonoDevelop
Una prima osservazione: in MonoDevelop i progetti si chiamano soluzioni per cui per creare un progetto si deve creare una soluzione
qwe
Il Designer della GUI si trova nella Interfaccia Utente della Soluzione
Per creare l'evento da associare al Widget si deve cliccare sul Menu' a scomparsa sulla sinistra Proprieta' e, dopo aver selezionato il Widget, si clicca il tab Segnali (dove solo elencati i segnali specifici del widget sia quelli ereditati)
Cliccando sul segnale richiesto si apre l'editor si apre l'editor del codice in cui e' stato inserito
---------------------------------------------
double t = hscale1.Value;
string s = System.Convert.ToString(t) ;
label1.Text = s;
progressbar1.Fraction = t/100;
---------------------------------------------
Per Debian e' sufficiente installare il pacchetto mono-complete che aggiunge anche l'IDE MonoDevelop
Una prima osservazione: in MonoDevelop i progetti si chiamano soluzioni per cui per creare un progetto si deve creare una soluzione
qwe
Il Designer della GUI si trova nella Interfaccia Utente della Soluzione
Gui Designer di Mono Develop |
Per creare l'evento da associare al Widget si deve cliccare sul Menu' a scomparsa sulla sinistra Proprieta' e, dopo aver selezionato il Widget, si clicca il tab Segnali (dove solo elencati i segnali specifici del widget sia quelli ereditati)
Cliccando sul segnale richiesto si apre l'editor si apre l'editor del codice in cui e' stato inserito
---------------------------------------------
double t = hscale1.Value;
string s = System.Convert.ToString(t) ;
label1.Text = s;
progressbar1.Fraction = t/100;
---------------------------------------------
Esempio GUI con GTK in C
Per creare la GUi viene impiegata la libreria GTK senza l'impiego di Glade (ovvero in GUI Designer di GTK)
Impiegando Code::Block e scegliendo il progetto GTK non e' necessario impostare le flag del compilatore che vengono aggiunte in automatico dall'IDE per cui e' molto semplice giungere ad un eseguibile
Compilare l'esempio seguente con Eclipse e' decisamente piu' complicato
Una delle principali differenze rispetto a Qt risiede nel fatto che GTK e' completamente in C (ha una interfaccia in C++ ma solo come wrapper) per cui la gestione degli oggetti non esiste in modo tradizionale. Inoltre per aggiungere una azione ad un widget si usa signal connect
--------------------------------------------------
#include <stdlib.h>
#include <gtk/gtk.h>
#include <stdio.h>
GtkWidget *scale = NULL;
GtkWidget *label = NULL;
GtkWidget *progressbar= NULL;
static void cambia_valore (GtkWidget *wid, GtkWidget *win)
{
gdouble current_value = gtk_range_get_value(GTK_RANGE(scale));
char buffer [14] = { '\0' };
sprintf ( buffer, "%.0f", current_value);
gtk_label_set_text(label,buffer);
gtk_progress_bar_set_fraction(progressbar,current_value/100);
}
int main (int argc, char *argv[])
{
GtkWidget *win = NULL;
GtkWidget *vbox = NULL;
/* Initialize GTK+ */
g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, (GLogFunc) gtk_false, NULL);
gtk_init (&argc, &argv);
g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, g_log_default_handler, NULL);
/* Create the main window */
win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width (GTK_CONTAINER (win), 8);
gtk_window_set_title (GTK_WINDOW (win), "Progress Bar");
gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_CENTER);
gtk_widget_realize (win);
g_signal_connect (win, "destroy", gtk_main_quit, NULL);
/* Create a vertical box with buttons */
vbox = gtk_vbox_new (TRUE, 6);
gtk_container_add (GTK_CONTAINER (win), vbox);
scale = gtk_hscale_new_with_range(0,100,1);
g_signal_connect (G_OBJECT (scale), "value_changed", G_CALLBACK (cambia_valore), (gpointer) win);
gtk_box_pack_start (GTK_BOX (vbox), scale, TRUE, TRUE, 0);
label = gtk_label_new("0");
gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
progressbar = gtk_progress_bar_new();
gtk_box_pack_start (GTK_BOX (vbox), progressbar, TRUE, TRUE, 0);
/* Enter the main loop */
gtk_widget_show_all (win);
gtk_main ();
return 0;
}
--------------------------------------------------
nel caso di compilazione a mano si puo' invece da riga di comando indicare
gcc `pkg-config --cflags --libs gtk+-2.0` main.c -o programma
Impiegando Code::Block e scegliendo il progetto GTK non e' necessario impostare le flag del compilatore che vengono aggiunte in automatico dall'IDE per cui e' molto semplice giungere ad un eseguibile
Compilare l'esempio seguente con Eclipse e' decisamente piu' complicato
Una delle principali differenze rispetto a Qt risiede nel fatto che GTK e' completamente in C (ha una interfaccia in C++ ma solo come wrapper) per cui la gestione degli oggetti non esiste in modo tradizionale. Inoltre per aggiungere una azione ad un widget si usa signal connect
--------------------------------------------------
#include <stdlib.h>
#include <gtk/gtk.h>
#include <stdio.h>
GtkWidget *scale = NULL;
GtkWidget *label = NULL;
GtkWidget *progressbar= NULL;
static void cambia_valore (GtkWidget *wid, GtkWidget *win)
{
gdouble current_value = gtk_range_get_value(GTK_RANGE(scale));
char buffer [14] = { '\0' };
sprintf ( buffer, "%.0f", current_value);
gtk_label_set_text(label,buffer);
gtk_progress_bar_set_fraction(progressbar,current_value/100);
}
int main (int argc, char *argv[])
{
GtkWidget *win = NULL;
GtkWidget *vbox = NULL;
/* Initialize GTK+ */
g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, (GLogFunc) gtk_false, NULL);
gtk_init (&argc, &argv);
g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, g_log_default_handler, NULL);
/* Create the main window */
win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width (GTK_CONTAINER (win), 8);
gtk_window_set_title (GTK_WINDOW (win), "Progress Bar");
gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_CENTER);
gtk_widget_realize (win);
g_signal_connect (win, "destroy", gtk_main_quit, NULL);
/* Create a vertical box with buttons */
vbox = gtk_vbox_new (TRUE, 6);
gtk_container_add (GTK_CONTAINER (win), vbox);
scale = gtk_hscale_new_with_range(0,100,1);
g_signal_connect (G_OBJECT (scale), "value_changed", G_CALLBACK (cambia_valore), (gpointer) win);
gtk_box_pack_start (GTK_BOX (vbox), scale, TRUE, TRUE, 0);
label = gtk_label_new("0");
gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
progressbar = gtk_progress_bar_new();
gtk_box_pack_start (GTK_BOX (vbox), progressbar, TRUE, TRUE, 0);
/* Enter the main loop */
gtk_widget_show_all (win);
gtk_main ();
return 0;
}
--------------------------------------------------
nel caso di compilazione a mano si puo' invece da riga di comando indicare
gcc `pkg-config --cflags --libs gtk+-2.0` main.c -o programma
domenica 26 agosto 2012
Compilare SDL con Code::Blocks
Per compilare con Code::Blocks programmi con dipendenza in SDL sotto Debian 6.0 e' sufficiente installare mediante apt-get le librerie di sviluppo sotto riportate
libsdl-sound1.2-dev
libsdl1.2-dev
libsdl-image1.2-dev
libsdl-mixer1.2-dev
libsdl-net1.2-dev
libsdl-ttf2.0-dev
libsdl-ttf2.0-dev
venerdì 24 agosto 2012
Webcam ARKMicro
Ho ceduto alla tentazione di comprare su DealExtreme una webcam per circa 4 euro (spedizione compresa).
La descrizione parla di una camera 640x480 con led per illuminazione
Una volta inserita nella Linux Box e' stata immediatamente riconosciuta (temevo il peggio)
-----------------------------------------------------------------------
Aug 24 15:15:41 kranz kernel: [ 5669.032091] usb 2-1: new full speed USB device using uhci_hcd and address 2
Aug 24 15:15:41 kranz kernel: [ 5669.195355] usb 2-1: New USB device found, idVendor=18ec, idProduct=3290
Aug 24 15:15:41 kranz kernel: [ 5669.195369] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
Aug 24 15:15:41 kranz kernel: [ 5669.195379] usb 2-1: Product: USB2.0 PC CAMERA
Aug 24 15:15:41 kranz kernel: [ 5669.195386] usb 2-1: Manufacturer: ARKMICRO
Aug 24 15:15:41 kranz kernel: [ 5669.195588] usb 2-1: configuration #1 chosen from 1 choice
Aug 24 15:15:41 kranz kernel: [ 5669.197529] uvcvideo: Found UVC 1.00 device USB2.0 PC CAMERA (18ec:3290)
Aug 24 15:15:41 kranz kernel: [ 5669.200674] input: USB2.0 PC CAMERA as /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.0/input/input11
e qui sono arrivate le sorprese
la webcam e' in realta' una 320x240 di pessima qualita' con dei led nel visibile che sono assolutamente inutili in quanto non riescono ad illuminare in qualsiasi condizioni ambientale (se erano ad infrarossi forse era meglio)
certo che il confronto con la webcam integrata nel portatile 640x480 reali (che pure non e' eccezionale nelle prestazioni soprattutto con poca illumicazione) e' impietoso
certo funzionare funziona e per meno di 4 euro (spedizione compresa) puo' essere anche abbastanza
La descrizione parla di una camera 640x480 con led per illuminazione
Una volta inserita nella Linux Box e' stata immediatamente riconosciuta (temevo il peggio)
-----------------------------------------------------------------------
Aug 24 15:15:41 kranz kernel: [ 5669.032091] usb 2-1: new full speed USB device using uhci_hcd and address 2
Aug 24 15:15:41 kranz kernel: [ 5669.195355] usb 2-1: New USB device found, idVendor=18ec, idProduct=3290
Aug 24 15:15:41 kranz kernel: [ 5669.195369] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
Aug 24 15:15:41 kranz kernel: [ 5669.195379] usb 2-1: Product: USB2.0 PC CAMERA
Aug 24 15:15:41 kranz kernel: [ 5669.195386] usb 2-1: Manufacturer: ARKMICRO
Aug 24 15:15:41 kranz kernel: [ 5669.195588] usb 2-1: configuration #1 chosen from 1 choice
Aug 24 15:15:41 kranz kernel: [ 5669.197529] uvcvideo: Found UVC 1.00 device USB2.0 PC CAMERA (18ec:3290)
Aug 24 15:15:41 kranz kernel: [ 5669.200674] input: USB2.0 PC CAMERA as /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.0/input/input11
-----------------------------------------------------------------------
e qui sono arrivate le sorprese
la webcam e' in realta' una 320x240 di pessima qualita' con dei led nel visibile che sono assolutamente inutili in quanto non riescono ad illuminare in qualsiasi condizioni ambientale (se erano ad infrarossi forse era meglio)
certo che il confronto con la webcam integrata nel portatile 640x480 reali (che pure non e' eccezionale nelle prestazioni soprattutto con poca illumicazione) e' impietoso
certo funzionare funziona e per meno di 4 euro (spedizione compresa) puo' essere anche abbastanza
Webcam ARKMicro |
Webcam integrata nel portatile |
giovedì 23 agosto 2012
Esempio GUI con QTCreator
Da non confondersi con QT Designer questo tool e' una IDE integrata per QT e non un semplice disegnatore di interfacce
per creare l'esempio non e' stata scritta una riga di codice. E' stato sufficiente collegare il segnale del sender (in questo caso lo slider) al widget di destinazione (ovvero la label e la progress bar)
per creare l'esempio non e' stata scritta una riga di codice. E' stato sufficiente collegare il segnale del sender (in questo caso lo slider) al widget di destinazione (ovvero la label e la progress bar)
mercoledì 22 agosto 2012
Propeller Parallax Servo Controller
Per controllare dei servo motori mediante il controller della Parallax si inviano sulla porta seriale delle stringhe cosi' formate
“!SC” C R pw.LOWBYTE, pw.HIGHBYTE, $0D
dove
C = e' il numero di canale dove e' attaccato il servo (da 0 a 31)
R = e' un parametro della funzione di rampa (da 0 a 63) ovvero la velocita' con il motore raggiunge la velocita' richiesta
pw = e' la posizione richiesta del servo motore impostata da 250 a 1250 per una variazione di angoli da 0 a 180°
"!SC" e $0D sono parametri fissi (uno e' il preambolo ed uno il terminatore di riga
e' necessario quindi calcolare il valore del byte basso ed alto per comandare la velocita' dei motori
Tutti i comandi del Propeller sono identificati da una stringa di 8 byte con preambolo variabile e carattere 13 per chiusura
Lo script in Python per inviare comandi e' il seguente
--------------------------------------------------------------------------------
import time
import serial
ser = serial.Serial()
ser.baudrate = 2400
ser.bytesize = 8
ser.stopbits = 1
#ser.xonxoff = 0
#ser.rtscts = 0
#ser.timeout = 0
ser.port = '/dev/ttyUSB0'
ser.parity=serial.PARITY_NONE
ser.open()
ser.isOpen()
out = ''
ser.write("!SCVER?"+chr(13))
time.sleep(0.2)
while ser.inWaiting()> 0:
out += ser.read(1)
print out
v = 1250
v1 = hex(v)
print v1
l_o_w = v1[3:]
h_i_g = "0"+v1[2:3]
print h_i_g+" "+l_o_w
for i in range(250,1250,20):
print i,
v = hex(i)
print v,
l_o_w = v[3:]
h_i_g = "0"+v[2:3]
print h_i_g+l_o_w,
print int(h_i_g,16),
print int(l_o_w,16)
h = int(h_i_g,16)
l = int(l_o_w,16)
out = ''
ser.write("!SC"+chr(0)+chr(25)+chr(l)+chr(h)+chr(13))
time.sleep(0.2)
while ser.inWaiting()> 0:
out += ser.read(1)
print out
out = ''
ser.write("!SCRSP"+chr(0)+chr(13))
time.sleep(0.2)
while ser.inWaiting()> 0:
out += ser.read(1)
print out
--------------------------------------------------------------------------------
Importante: la scheda Propeller prende alimentazione dal cavo USB ma su questo canale non vengono alimentati i servo motori, e' quindi necessario fornire una ulteriore alimentazione separata sul connettore verde e spostare l'interruttore su On
La pedinatura del servo motore sulla Propeller e' indicata dai caratteri W (White), R (Red) e B (Black) che si trova in testa ai canali di connessione dei servo motori
“!SC” C R pw.LOWBYTE, pw.HIGHBYTE, $0D
dove
C = e' il numero di canale dove e' attaccato il servo (da 0 a 31)
R = e' un parametro della funzione di rampa (da 0 a 63) ovvero la velocita' con il motore raggiunge la velocita' richiesta
pw = e' la posizione richiesta del servo motore impostata da 250 a 1250 per una variazione di angoli da 0 a 180°
"!SC" e $0D sono parametri fissi (uno e' il preambolo ed uno il terminatore di riga
e' necessario quindi calcolare il valore del byte basso ed alto per comandare la velocita' dei motori
Tutti i comandi del Propeller sono identificati da una stringa di 8 byte con preambolo variabile e carattere 13 per chiusura
Lo script in Python per inviare comandi e' il seguente
--------------------------------------------------------------------------------
import time
import serial
ser = serial.Serial()
ser.baudrate = 2400
ser.bytesize = 8
ser.stopbits = 1
#ser.xonxoff = 0
#ser.rtscts = 0
#ser.timeout = 0
ser.port = '/dev/ttyUSB0'
ser.parity=serial.PARITY_NONE
ser.open()
ser.isOpen()
out = ''
ser.write("!SCVER?"+chr(13))
time.sleep(0.2)
while ser.inWaiting()> 0:
out += ser.read(1)
print out
v = 1250
v1 = hex(v)
print v1
l_o_w = v1[3:]
h_i_g = "0"+v1[2:3]
print h_i_g+" "+l_o_w
for i in range(250,1250,20):
print i,
v = hex(i)
print v,
l_o_w = v[3:]
h_i_g = "0"+v[2:3]
print h_i_g+l_o_w,
print int(h_i_g,16),
print int(l_o_w,16)
h = int(h_i_g,16)
l = int(l_o_w,16)
out = ''
ser.write("!SC"+chr(0)+chr(25)+chr(l)+chr(h)+chr(13))
time.sleep(0.2)
while ser.inWaiting()> 0:
out += ser.read(1)
print out
out = ''
ser.write("!SCRSP"+chr(0)+chr(13))
time.sleep(0.2)
while ser.inWaiting()> 0:
out += ser.read(1)
print out
--------------------------------------------------------------------------------
Nel video che segue un servo motore comandato da una scheda Propeller Parallax a sua volta comandata da una Raspberry via seriale
Importante: la scheda Propeller prende alimentazione dal cavo USB ma su questo canale non vengono alimentati i servo motori, e' quindi necessario fornire una ulteriore alimentazione separata sul connettore verde e spostare l'interruttore su On
La pedinatura del servo motore sulla Propeller e' indicata dai caratteri W (White), R (Red) e B (Black) che si trova in testa ai canali di connessione dei servo motori
Esempio GUI con WX Python
Cosi' come per PyGtk anche le librerie WxPython non sono aggiornate a Python 3.x per cui si deve usare la versione 2.x
Nella versione per Windows richiedono i privilegi di amministrazione
----------------------------------------------------------
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition,(300,150))
panel = wx.Panel(self, -1)
self.sld = wx.Slider(self, -1, 0, 0, 100,(10,10),(270,50),wx.SL_AUTOTICKS | wx.SL_HORIZONTAL | wx.SL_LABELS)
self.label = wx.StaticText(self,wx.ID_ANY,"0 ",pos=(140,60),size=(100,20))
self.progressbar = wx.Gauge(self,-1,100,pos=(10,90),size=(270,20))
self.Bind(wx.EVT_SLIDER, self.sliderUpdate)
wx.EVT_BUTTON(self, 9, self.OnClose)
def OnClose(self, event):
self.Close()
def sliderUpdate(self,event):
self.label.SetLabel(str(self.sld.GetValue()))
self.progressbar.SetValue(self.sld.GetValue())
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, -1, 'Progress Bar')
frame.Show(True)
frame.Centre()
return True
app = MyApp(0)
----------------------------------------------------------
Nella versione per Windows richiedono i privilegi di amministrazione
----------------------------------------------------------
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition,(300,150))
panel = wx.Panel(self, -1)
self.sld = wx.Slider(self, -1, 0, 0, 100,(10,10),(270,50),wx.SL_AUTOTICKS | wx.SL_HORIZONTAL | wx.SL_LABELS)
self.label = wx.StaticText(self,wx.ID_ANY,"0 ",pos=(140,60),size=(100,20))
self.progressbar = wx.Gauge(self,-1,100,pos=(10,90),size=(270,20))
self.Bind(wx.EVT_SLIDER, self.sliderUpdate)
wx.EVT_BUTTON(self, 9, self.OnClose)
def OnClose(self, event):
self.Close()
def sliderUpdate(self,event):
self.label.SetLabel(str(self.sld.GetValue()))
self.progressbar.SetValue(self.sld.GetValue())
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, -1, 'Progress Bar')
frame.Show(True)
frame.Centre()
return True
app = MyApp(0)
----------------------------------------------------------
Esempio GUI con Java
per scrivere questo esempio e' stato impiegato Eclipse nella versione per sviluppatori Java che include al suo interno il plugin di Google denominato WindowBuilder Pro per la gestione dell'interfaccia grafica di Java
Per creare un progetto Java/WindowBuilder, dopo aver installato Eclipse, si clicca File/New/Other/WindowBuilder/SwingDesigner/Application
per spostarsi tra l'editor visuale e la parte di codice si clicca nei tab in basso. Per il resto la programmazione e' molto simile agli altri ambienti di sviluppo visuale
------------------------------------------------------------------------
package com.test.swing2;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import java.awt.BorderLayout;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.SwingConstants;
public class Swing2 {
private JFrame frmProgressBar;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Swing2 window = new Swing2();
window.frmProgressBar.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Swing2() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frmProgressBar = new JFrame();
frmProgressBar.setTitle("Progress Bar");
frmProgressBar.setBounds(100, 100, 279, 94);
frmProgressBar.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JProgressBar progressBar_1 = new JProgressBar();
frmProgressBar.getContentPane().add(progressBar_1, BorderLayout.SOUTH);
final JSlider slider = new JSlider();
frmProgressBar.getContentPane().add(slider, BorderLayout.NORTH);
final JLabel lblNewLabel = new JLabel("50");
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
frmProgressBar.getContentPane().add(lblNewLabel, BorderLayout.CENTER);
slider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent arg0) {
lblNewLabel.setText(Integer.toString(slider.getValue()));
progressBar_1.setValue(slider.getValue());
}
});
}
}
------------------------------------------------------------------------
Per creare un progetto Java/WindowBuilder, dopo aver installato Eclipse, si clicca File/New/Other/WindowBuilder/SwingDesigner/Application
per spostarsi tra l'editor visuale e la parte di codice si clicca nei tab in basso. Per il resto la programmazione e' molto simile agli altri ambienti di sviluppo visuale
------------------------------------------------------------------------
package com.test.swing2;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import java.awt.BorderLayout;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.SwingConstants;
public class Swing2 {
private JFrame frmProgressBar;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Swing2 window = new Swing2();
window.frmProgressBar.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Swing2() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frmProgressBar = new JFrame();
frmProgressBar.setTitle("Progress Bar");
frmProgressBar.setBounds(100, 100, 279, 94);
frmProgressBar.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JProgressBar progressBar_1 = new JProgressBar();
frmProgressBar.getContentPane().add(progressBar_1, BorderLayout.SOUTH);
final JSlider slider = new JSlider();
frmProgressBar.getContentPane().add(slider, BorderLayout.NORTH);
final JLabel lblNewLabel = new JLabel("50");
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
frmProgressBar.getContentPane().add(lblNewLabel, BorderLayout.CENTER);
slider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent arg0) {
lblNewLabel.setText(Integer.toString(slider.getValue()));
progressBar_1.setValue(slider.getValue());
}
});
}
}
------------------------------------------------------------------------
Esempio GUI con PYGtk
Al contrario degli esempio precedenti PyGtk non funziona con la versione 3.x di Python per cui e' necessario usare un compilatore della serie 2.x
----------------------------------------------
import pygtk
pygtk.require('2.0')
import gtk
class SecondWin:
def __init__(self):
self.win = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.win.connect("delete_event", self.delete_event)
self.win.connect("destroy", self.destroy)
#self.win.set_resizable(gtk.FALSE)
self.win.set_title('Progress Bar')
self.win.set_border_width(5)
self.win.resize(200,100)
self.vbox = gtk.VBox()
self.win.add(self.vbox)
adjustment = gtk.Adjustment(0, 0, 100, 5, 10, 0)
self.hscale = gtk.HScale(adjustment)
self.vbox.pack_start(self.hscale)
self.hscale.set_digits(0)
self.hscale.connect("value-changed", self.scale_moved)
self.label = gtk.Label(str=" ")
self.vbox.pack_start(self.label)
self.progressbar = gtk.ProgressBar()
self.vbox.pack_start(self.progressbar)
self.win.show_all()
def scale_moved(self, event):
self.label.set_text(str(self.hscale.get_value()))
self.progressbar.set_fraction(self.hscale.get_value()/100)
def delete_event(self, widget, event, data=None):
return gtk.FALSE
def destroy(self, widget, data=None):
return gtk.main_quit()
def main(self):
gtk.main()
if __name__ == "__main__":
second = SecondWin()
second.main()
----------------------------------------------
----------------------------------------------
import pygtk
pygtk.require('2.0')
import gtk
class SecondWin:
def __init__(self):
self.win = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.win.connect("delete_event", self.delete_event)
self.win.connect("destroy", self.destroy)
#self.win.set_resizable(gtk.FALSE)
self.win.set_title('Progress Bar')
self.win.set_border_width(5)
self.win.resize(200,100)
self.vbox = gtk.VBox()
self.win.add(self.vbox)
adjustment = gtk.Adjustment(0, 0, 100, 5, 10, 0)
self.hscale = gtk.HScale(adjustment)
self.vbox.pack_start(self.hscale)
self.hscale.set_digits(0)
self.hscale.connect("value-changed", self.scale_moved)
self.label = gtk.Label(str=" ")
self.vbox.pack_start(self.label)
self.progressbar = gtk.ProgressBar()
self.vbox.pack_start(self.progressbar)
self.win.show_all()
def scale_moved(self, event):
self.label.set_text(str(self.hscale.get_value()))
self.progressbar.set_fraction(self.hscale.get_value()/100)
def delete_event(self, widget, event, data=None):
return gtk.FALSE
def destroy(self, widget, data=None):
return gtk.main_quit()
def main(self):
gtk.main()
if __name__ == "__main__":
second = SecondWin()
second.main()
----------------------------------------------
Cattura video su Raspberry
Primo tentativo di cattura video su Raspberry. E' stata utilizzata una Logitech QuickCam 2500 con l'installazione di default di ffmpeg di Rapbian (che e' conosciuta per essere buggata)
La stringa di configurazione di ffmpeg e' la seguente
ffmpeg -f video4linux2 -s 640x472 -r 5 -sameq -i /dev/video0 -f m4v /home/pi/5.m4v
La stringa di configurazione di ffmpeg e' la seguente
ffmpeg -f video4linux2 -s 640x472 -r 5 -sameq -i /dev/video0 -f m4v /home/pi/5.m4v
320x240
640x472
Esempio di GUI con Gambas
Tempo di sviluppo : 3 minuti (e non avevo mai usato prima Gambas)
-----------------------------------------------------------------
PUBLIC SUB Form_Open()
Label1.Alignment = 3
END
PUBLIC SUB Slider1_Change()
Label1.Text = Slider1.Value
ProgressBar1.Value = Slider1.Value / 100
END
-----------------------------------------------------------------
-----------------------------------------------------------------
PUBLIC SUB Form_Open()
Label1.Alignment = 3
END
PUBLIC SUB Slider1_Change()
Label1.Text = Slider1.Value
ProgressBar1.Value = Slider1.Value / 100
END
-----------------------------------------------------------------
martedì 21 agosto 2012
Configurazione DHCP Server su Debian
Per usare Raspberry senza impazzire continuamente con le configurazioni di rete puo' essere comodo montare sulla macchina di sviluppo un server dhcp
su Debian si procedere installando
apt-get install isc-dhcp-server
dopo di cio' si puo' editare il file /etc/dhcp.conf modificando brevemente le righe
subnet 192.168.0.1 netmask 255.255.255.0 {
range 192.168.1.10 192.168.1.20;
}
impostando la macchina di sviluppo per esempio su 192.168.1.1 ed avviando il server con
/etc/init.d/isc-dhcp-server start
e collegando la Raspberry con il cavo cross questa assumera' il primo indirizzo disponibile ovvero 192.168.1.10
su Debian si procedere installando
apt-get install isc-dhcp-server
dopo di cio' si puo' editare il file /etc/dhcp.conf modificando brevemente le righe
subnet 192.168.0.1 netmask 255.255.255.0 {
range 192.168.1.10 192.168.1.20;
}
impostando la macchina di sviluppo per esempio su 192.168.1.1 ed avviando il server con
/etc/init.d/isc-dhcp-server start
e collegando la Raspberry con il cavo cross questa assumera' il primo indirizzo disponibile ovvero 192.168.1.10
USB Serial Converter PL2303
Ho ritirato fuori da un cassetto un convertitore seriale-USB che usavo per scaricare i dati da un GPS sotto Windows. Mi e' venuta voglia di vedere come funziona sotto Linux attacandolo ad un modem seriale US Robotics FaxModem 56 Kb. Peraltro il convertitore mi e' stato venduto praticamente senza nessuna indicazione del chip interno ed io ovviamente non ho piu' il miniCD di installazione
Una volta inserito il convertitore in /var/log/messages compaiono le seguenti righe
Aug 21 16:21:06 kranz kernel: [ 107.649459] pl2303 2-1:1.0: pl2303 converter detected
Aug 21 16:21:06 kranz kernel: [ 107.661505] usb 2-1: pl2303 converter now attached to ttyUSB0
Aug 21 16:21:06 kranz kernel: [ 107.661557] usbcore: registered new interface driver pl2303
Aug 21 16:21:06 kranz kernel: [ 107.661565] pl2303: Prolific PL2303 USB to serial adaptor driver
Aug 21 16:23:24 kranz kernel: [ 245.756599] Marking TSC unstable due to TSC halts in idle
come si puo' vedere in Debian il convertitore e' riconosciuto come un pl2303 e si collega in automatico come porta virtuale alla /dev/ttyUSB0
per la cronaca non ho mai avuto l'alimentatore del modem (perche' mi e' stato regalato) e tirando a caso ho visto che servono 12 V con la seguente pedinatura
Una volta inserito il convertitore in /var/log/messages compaiono le seguenti righe
Aug 21 16:21:06 kranz kernel: [ 107.649459] pl2303 2-1:1.0: pl2303 converter detected
Aug 21 16:21:06 kranz kernel: [ 107.661505] usb 2-1: pl2303 converter now attached to ttyUSB0
Aug 21 16:21:06 kranz kernel: [ 107.661557] usbcore: registered new interface driver pl2303
Aug 21 16:21:06 kranz kernel: [ 107.661565] pl2303: Prolific PL2303 USB to serial adaptor driver
Aug 21 16:23:24 kranz kernel: [ 245.756599] Marking TSC unstable due to TSC halts in idle
come si puo' vedere in Debian il convertitore e' riconosciuto come un pl2303 e si collega in automatico come porta virtuale alla /dev/ttyUSB0
per la cronaca non ho mai avuto l'alimentatore del modem (perche' mi e' stato regalato) e tirando a caso ho visto che servono 12 V con la seguente pedinatura
Esempio GUI con TKinter
Un esempio di uso della GUI Tkinter su Python 3.2 (da confrontare con questo post)
------------------------------------------
import tkinter as tk
from tkinter import ttk
class App:
def __init__(self):
self.root = tk.Tk()
self._job = None
self.root.title("Progress Bar")
self.frame = tk.Frame(self.root, width=200, height=10)
self.frame.pack()
self.slider = tk.Scale(self.root, from_=0, to=100,
orient="horizontal",
command=self.updateValue, length=200)
self.slider.pack()
self.lab = tk.Label(self.root, text=" ")
self.lab.pack()
self.pbar = ttk.Progressbar(self.root, length=200,mode="determinate", maximum=100)
self.pbar.pack(padx=5, pady=5)
self.pbar.start
self.root.mainloop()
def updateValue(self, event):
if self._job:
self.root.after_cancel(self._job)
self.pbar["value"] = int(self.slider.get())
self.lab.config(text=str(self.slider.get()))
app=App()
------------------------------------------
------------------------------------------
import tkinter as tk
from tkinter import ttk
class App:
def __init__(self):
self.root = tk.Tk()
self._job = None
self.root.title("Progress Bar")
self.frame = tk.Frame(self.root, width=200, height=10)
self.frame.pack()
self.slider = tk.Scale(self.root, from_=0, to=100,
orient="horizontal",
command=self.updateValue, length=200)
self.slider.pack()
self.lab = tk.Label(self.root, text=" ")
self.lab.pack()
self.pbar = ttk.Progressbar(self.root, length=200,mode="determinate", maximum=100)
self.pbar.pack(padx=5, pady=5)
self.pbar.start
self.root.mainloop()
def updateValue(self, event):
if self._job:
self.root.after_cancel(self._job)
self.pbar["value"] = int(self.slider.get())
self.lab.config(text=str(self.slider.get()))
app=App()
------------------------------------------
Confronto Webcam
Esempio GUI con PyQt
Un esempio di GUI mediante PyQT
import sys
from PyQt4 import QtGui, QtCore
app = QtGui.QApplication(sys.argv)
widget = QtGui.QWidget()
widget.setGeometry(200, 100, 220, 120)
widget.setWindowTitle('Slider Example')
label1 = QtGui.QLabel("Valore: ", widget)
label1.move(80, 50)
slider = QtGui.QSlider(QtCore.Qt.Horizontal, widget)
slider.setGeometry(10, 10, 200, 30)
slider.setFocusPolicy(QtCore.Qt.NoFocus)
pb = QtGui.QProgressBar(widget)
pb.setGeometry(10, 70, 215, 20)
def getValue(value):
label1.setText("Valore: "+str(value))
pb.setValue(value)
widget.connect(slider, QtCore.SIGNAL('valueChanged(int)'), getValue)
widget.show()
sys.exit(app.exec_())
import sys
from PyQt4 import QtGui, QtCore
app = QtGui.QApplication(sys.argv)
widget = QtGui.QWidget()
widget.setGeometry(200, 100, 220, 120)
widget.setWindowTitle('Slider Example')
label1 = QtGui.QLabel("Valore: ", widget)
label1.move(80, 50)
slider = QtGui.QSlider(QtCore.Qt.Horizontal, widget)
slider.setGeometry(10, 10, 200, 30)
slider.setFocusPolicy(QtCore.Qt.NoFocus)
pb = QtGui.QProgressBar(widget)
pb.setGeometry(10, 70, 215, 20)
def getValue(value):
label1.setText("Valore: "+str(value))
pb.setValue(value)
widget.connect(slider, QtCore.SIGNAL('valueChanged(int)'), getValue)
widget.show()
sys.exit(app.exec_())
lunedì 20 agosto 2012
Nokia 6161 e comandi AT
Dovendo fare qualche prova con uno script seriale e non avendo a tiro nessun modem seriale vero ho tirato fuori il vecchio Nokia 6161 che ha una interfaccia con comandi AT
Il collegamento con il telefono puo' essere effettuato con accoppiamento Bluetooth mediante il menu del telefono oppure mediante il cavo USB (che non porta corrente ma solo segnale per cui e' bene inserire anche l'alimentatore per le prove)
Collegamento Bluetooth
per il collegamento bluetooth si accoppia con il classico comando
rfcomm bind 0 00:1B:EE:58:93:22
la porta su cui collegarsi e' /dev/rfcomm0
Collegamento USB con cavo Ca-53
per il collegamento via cavo devono essere caricati i moduli
usbcore,usbserial,cdc_acm,usbhid,ehci_hcd,ohci_hcd
la porta su cui collegarsi e' /dev/ttyACM0
il syslog riporta le seguenti linee
Aug 20 09:35:25 kranz kernel: [ 1858.174324] usb 5-1: New USB device found, idVendor=0421, idProduct=04d2
Aug 20 09:35:25 kranz kernel: [ 1858.174340] usb 5-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
Aug 20 09:35:25 kranz kernel: [ 1858.174346] usb 5-1: Product: Nokia 6151
Aug 20 09:35:25 kranz kernel: [ 1858.174351] usb 5-1: Manufacturer: Nokia
il primo corretto ed il secondo errato
-------------------------------------------------------------
import time
import serial
ser = serial.Serial()
ser.baudrate = 9600
ser.bytesize = 8
ser.stopbits = 1
ser.port = '/dev/rfcomm0'
ser.parity=serial.PARITY_NONE
ser.open()
ser.isOpen()
while True :
#controlla il livello della batteria
out = ''
ser.write("AT+CBC\r\n")
print "AT+CBC"
time.sleep(1)
while ser.inWaiting()> 0:
out += ser.read(1)
if out != '':
print out
#print "<<"+out[24]
#if out[24] == "O":
#print "Ok"
#forza un comando errato
out = ''
ser.write("AT+CGMM1\r\n")
print "AT+CGMM1"
time.sleep(1)
while ser.inWaiting()> 0:
out += ser.read(1)
if out != '':
print out
#print out[12]
#if out[12] == "E":
#print "Errore"
-------------------------------------------------------------
La risposta al comando corretto e' composta dalla ripetizione del comando
il valore di risposta (in questo caso lo stato di carica della batteria) ed infine
una riga con il codice OK
-------------------------------------------------------------
AT+CBC
+CBC: 1,93
OK
La risposta al comando scorretto e' composta dalla ripetizione del comando
e la stringa ERROR
-------------------------------------------------------------
La risposta al comando scorretto e' composta dalla ripetizione del comando
e la stringa ERROR
-------------------------------------------------------------
AT+CGMM1
ERROR
-------------------------------------------------------------
come si puo' osservare la risposta e' data da una stringa unica con piu' ritorni a capo e senza un separatore univoco..per questo motivo per fare un check da programma del corretto funzionamento si puo' controllare nel primo caso se il carattere 24 della stringa di out contiene una "O" di "OK" mentre nel secondo caso se il carattere 12 contiene una "E" di Error
come si puo' osservare la risposta e' data da una stringa unica con piu' ritorni a capo e senza un separatore univoco..per questo motivo per fare un check da programma del corretto funzionamento si puo' controllare nel primo caso se il carattere 24 della stringa di out contiene una "O" di "OK" mentre nel secondo caso se il carattere 12 contiene una "E" di Error
sabato 18 agosto 2012
Bluetooth su Debian
per installare il pacchetto di utility di Bluetooth si digita
apt-get install bluetooth
successivamente per ricercare il device Bluetooth a cui si vuole collegare
hcitool scan
si copia l'indirizzo esadecimale e si lancia il comando
rfcomm bind 0 00:0A:3A:1F:A4:2E
che apre la seriale /dev/rfcomm0
venerdì 17 agosto 2012
Terminale per porta seriale
Alcuni esempi di terminale su porta seriale (reale o virtuale) su Linux. Le prove sono state effettuate con GPS Bluetooth impostato su /dev/rfcomm0
altrimenti usando la libreria pyserial (che si installa con il seguente comando)
apt-get install python-serial
si puo' usare uno script in Python per fare la stessa cosa
--------------------------
import time
import serial
ser = serial.Serial()
ser.baudrate = 9600
ser.bytesize = 8
ser.stopbits = 1
#ser.xonxoff = 0
#ser.rtscts = 0
#ser.timeout = 0
ser.port = '/dev/rfcomm0'
ser.parity=serial.PARITY_NONE
ser.open()
ser.isOpen()
input=1
out = ''
while True :
time.sleep(1)
while ser.inWaiting()> 0:
out += ser.read(1)
if out != '':
print ">>" + out
Gtkterm
Configurazione |
Schermata del terminale |
Minicom
(da lanciare come minicom -s)
Configurazione |
Schermata del terminale |
altrimenti usando la libreria pyserial (che si installa con il seguente comando)
apt-get install python-serial
si puo' usare uno script in Python per fare la stessa cosa
--------------------------
import time
import serial
ser = serial.Serial()
ser.baudrate = 9600
ser.bytesize = 8
ser.stopbits = 1
#ser.xonxoff = 0
#ser.rtscts = 0
#ser.timeout = 0
ser.port = '/dev/rfcomm0'
ser.parity=serial.PARITY_NONE
ser.open()
ser.isOpen()
input=1
out = ''
while True :
time.sleep(1)
while ser.inWaiting()> 0:
out += ser.read(1)
if out != '':
print ">>" + out
giovedì 16 agosto 2012
Scheda Wireless Kraun Kr.8N
La scheda, visibile in foto, e' costituita da una antenna che integra anche l'elettronica di controllo, e di un supporto con cavo USB
Inserita nella Debian Box stable i messaggi del syslog indicano
Aug 16 09:51:04 kranz NetworkManager[1143]: <warn> wlan1: firmware may be missing.
Aug 16 09:51:04 kranz NetworkManager[1143]: <info> (wlan1): deactivating device (reason: 2).
Aug 16 09:51:04 kranz kernel: [ 348.203942] phy1 -> rt2x00lib_request_firmware: Error - Failed to request Firmware.
Aug 16 09:51:04 kranz kernel: [ 348.210663] rt2800usb 1-7:1.0: firmware: requesting rt2870.bin
Aug 16 09:51:04 kranz kernel: [ 348.222574] phy1 -> rt2x00lib_request_firmware: Error - Failed to request Firmware.
e' quindi necessario inserire tra le sources i repository non-free e successivamente (dopo l'update)
apt-get install firmware-ralink
in Ubuntu invece la scheda viene riconosciuta al volo
Inserita nella Debian Box stable i messaggi del syslog indicano
Aug 16 09:51:04 kranz NetworkManager[1143]: <warn> wlan1: firmware may be missing.
Aug 16 09:51:04 kranz NetworkManager[1143]: <info> (wlan1): deactivating device (reason: 2).
Aug 16 09:51:04 kranz kernel: [ 348.203942] phy1 -> rt2x00lib_request_firmware: Error - Failed to request Firmware.
Aug 16 09:51:04 kranz kernel: [ 348.210663] rt2800usb 1-7:1.0: firmware: requesting rt2870.bin
Aug 16 09:51:04 kranz kernel: [ 348.222574] phy1 -> rt2x00lib_request_firmware: Error - Failed to request Firmware.
e' quindi necessario inserire tra le sources i repository non-free e successivamente (dopo l'update)
apt-get install firmware-ralink
in Ubuntu invece la scheda viene riconosciuta al volo
Iscriviti a:
Post (Atom)
Debugger integrato ESP32S3
Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede nell'ID USB della porta Jtag. Nel modulo...
-
In questo post viene indicato come creare uno scatterplot dinamico basato da dati ripresi da un file csv (nel dettaglio il file csv e' c...
-
La scheda ESP32-2432S028R monta un Esp Dev Module con uno schermo TFT a driver ILI9341 di 320x240 pixels 16 bit colore.Il sito di riferiment...
-
Questo post e' a seguito di quanto gia' visto nella precedente prova Lo scopo e' sempre il solito: creare un sistema che permet...