Showing posts with label Tkinter. Show all posts
Showing posts with label Tkinter. Show all posts

Tuesday, December 29, 2020

Raspberry Pi/Python as Bluetooth classic client, bi-direction communication with ESP32

Raspberry Pi/Python act as GUI Bluetooth classic client, using tkinter/pybluez:
Connect to bluetooth classic server with hard-coded MAC.
User enter text to sent on bottom Text Frame, send to server.
Display the data received from server on upper Text frame.

The server side, run on ESP32 (NodeMCU ESP-32S), with SPI ST7735 IPS screen. It echo back received data. ESP32 (Arduino framework) code: Arduino-er: ESP-32S as Bluetooth classic Server, bi-direction communication with Raspberry Pi/Python.

Python code, pySPPClient.py.

import sys
from tkinter import *
from bluetooth import *
from threading import Thread
import time

rqsStopBtHandler = False

buf_size = 255

def btHandler():
    global rqsStopBtHandler
    rqsStopBtHandler = False
    
    print("btHandler Started")
    
    #Set sock.settimeout(),
    #to prevent program blocked by sock.recv()
    #and cannot end btHandler
    sock.settimeout(1.0)
    while rqsStopBtHandler!=True:
        try:
            datarx = sock.recv(buf_size)
            datarxToStr = datarx.decode("utf-8")
            print(datarxToStr)
            textCenter.insert(INSERT, datarxToStr)
        except Exception:
            continue
        
    print("btHandler End")
    
def startBtHandler():
    btThread = Thread(target=btHandler)
    btThread.start()
    
def close_window():
    global rqsStopBtHandler
    rqsStopBtHandler = True
    sock.close()
    print("Socket closed")
    print("Window closed")
    root.destroy()

def cmdSend():
    stringSent = textBottom.get(1.0, END)
    print(stringSent)
    sock.send(stringSent)
    #sock.send("\n")
    print("- Sent")
    
#===============================================
#Prepare Bluetooth Classic
print("Python version: ")
print(sys.version)
print("tkinter version: ", TkVersion)
print("=============================")
print("Connect to ESP32 Bluetooth Classic SPP Server")
#addr = "24:0A:C4:E8:0F:9A"
addr = "3C:71:BF:0D:DD:6A"
print(addr)
service_matches = find_service( address = addr )

if len(service_matches) == 0:
    print("couldn't find the ESP32 Bluetooth Classic SPP service")
    sys.exit(0)
    
for s in range(len(service_matches)):
    print("\nservice_matches: [" + str(s) + "]:")
    print(service_matches[s])
    
first_match = service_matches[0]
port = first_match["port"]
name = first_match["name"]
host = first_match["host"]

port=1
print("connecting to \"%s\" on %s, port %s" % (name, host, port))

# Create the client socket
sock=BluetoothSocket(RFCOMM)
sock.connect((host, port))

print("connected")

#===============================================
#Prepare GUI
root = Tk()
root.configure(bg="darkgray") 
root.wm_title("SPP Client")
root.protocol("WM_DELETE_WINDOW", close_window)

rootFrame = Frame(root)
rootFrame.pack()

labelTitle = Label(root,
                   text="helloraspberrypi.blogspot.com",
                   font=("Helvetica", 18),
                   fg="White", bg="darkgray")
labelTitle.pack()

frameCenter = Frame(root, bg="lightgray")
frameCenter.pack()

textCenter= Text(frameCenter, width=26, height=10, font=("Helvetica", 18))
textCenter.pack(padx=10,pady=5)

frameBottom = Frame(root, bg="gray")
frameBottom.pack(expand=True, fill='both')

textBottom = Text(frameBottom, width=26, height=10, font=("Helvetica", 18))
textBottom.insert(INSERT, "Enter text here")
textBottom.pack(padx=10,pady=5)

buttonSend = Button(frameBottom, text="Send", command=cmdSend)
buttonSend.pack(padx=10,pady=5)

startBtHandler()

root.mainloop()

print("--- bye ---")

Related:

Friday, June 12, 2020

Python tkinter to detect key event

Python exercise to detect key event, for Python3 + tkinter run on Raspberry Pi OS

import tkinter as tk

def key_fun(event):
    print(event)
    key_press = event.keysym
    print(key_press)

command = tk.Tk()
command.bind_all('<Key>', key_fun)
command.mainloop()


Monday, May 29, 2017

Python to control RGB LED, with tkinter colorchooser/tkColorChooser

Python example to output PWM on GPIO of Raspberry Pi to control RGB LED, with tkinter GUI. Tkinter colorchooser/tkColorChooser is used to select color. Tested on Raspberry Pi 2 running Raspbian Jessie with PIXEL rel. 2017-04-10, work on both Python 2 and 3.


pyGuiPwm.py
#for Python 2
#from Tkinter import *   #for Python 2
#from tkColorChooser import askcolor

#for Python 3
from tkinter import *
from tkinter.colorchooser import *

import platform
import RPi.GPIO as GPIO

r = 0;
g = 0;
b = 0;

def on_closing():
    print("Clean up")
    pwmledR.stop()
    pwmledG.stop()
    pwmledB.stop()
    GPIO.cleanup()
    print("bye")
    master.destroy()

def getColor():
    global r, g, b
    color = askcolor(color=(r, g, b)) 
    print(color)
    rgb = color[0]
    colorVal = color[1]
    if rgb != None:
        r = rgb[0]
        g = rgb[1]
        b = rgb[2]
        print("set RGB LED")
        rVal = r/255.0
        gVal = g/255.0
        bVal = b/255.0
        print((7, gVal, bVal))
        pwmValue.set(colorVal)
        pwmledR.ChangeDutyCycle(rVal)
        pwmledG.ChangeDutyCycle(gVal)
        pwmledB.ChangeDutyCycle(bVal)

#mode = GPIO.BCM
#ledR = 16
#ledG = 20
#ledB = 21

mode = GPIO.BOARD
ledR = 36
ledG = 38
ledB = 40

print("Raspberry Pi board revision: "
      + str(GPIO.RPI_INFO['P1_REVISION']))
print("Machine: "
      + platform.machine())
print("Processor: "
      + platform.processor())
print("System: "
      + platform.system())
print("Version: "
      + platform.version())
print("Uname: "
      + str(platform.uname()))
print("Python version: "
      + platform.python_version())
print("RPi.GPIO version: "
      + str(GPIO.VERSION))

GPIO.setmode(mode)
GPIO.setup(ledR, GPIO.OUT)
GPIO.setup(ledG, GPIO.OUT)
GPIO.setup(ledB, GPIO.OUT)
pwmledR = GPIO.PWM(ledR, 50)
pwmledG = GPIO.PWM(ledG, 50)
pwmledB = GPIO.PWM(ledB, 50)
pwmledR.start(0)
pwmledG.start(0)
pwmledB.start(0)

master = Tk()

pwmValue = StringVar()
label = Label(master, textvariable=pwmValue, relief=RAISED )
label.pack()

Button(text='Select Color', command=getColor).pack()

master.protocol("WM_DELETE_WINDOW", on_closing)
mainloop()



Connection:

Python to output PWM to control LED brightness, with tkinter GUI

Python to generate PWM on GPIO of Raspberry Pi to control brightness of a LED, with tkinter GUI. Tested on Raspberry Pi 2 running Raspbian Jessie with PIXEL rel. 2017-04-10, work on both Python 2 (from Tkinter import *) and 3 (from Tkinter import * ).


pyGuiPwm.py
from Tkinter import *   #for Python 2
#from tkinter import *   #for Python 3

import platform
import RPi.GPIO as GPIO

def setPwm(newvalue):
    pwmValue.set(newvalue)
    pwmled.ChangeDutyCycle(float(newvalue))

def on_closing():
    print("Clean up")
    pwmled.stop()
    GPIO.cleanup()
    print("bye")
    master.destroy()

#mode = GPIO.BCM
#led = 21
mode = GPIO.BOARD
led = 40

print("Raspberry Pi board revision: "
      + str(GPIO.RPI_INFO['P1_REVISION']))
print("Machine: "
      + platform.machine())
print("Processor: "
      + platform.processor())
print("System: "
      + platform.system())
print("Version: "
      + platform.version())
print("Uname: "
      + str(platform.uname()))
print("Python version: "
      + platform.python_version())
print("RPi.GPIO version: "
      + str(GPIO.VERSION))

GPIO.setmode(mode)
GPIO.setup(led, GPIO.OUT)
pwmled = GPIO.PWM(led, 50)
pwmled.start(0)

master = Tk()

pwmValue = StringVar()
label = Label(master, textvariable=pwmValue, relief=RAISED )
label.pack()

slider = Scale(master, from_=0, to=100, orient=HORIZONTAL, command=setPwm)
slider.pack()

master.protocol("WM_DELETE_WINDOW", on_closing)
mainloop()



Next:
Python to control RGB LED, with tkinter colorchooser/tkColorChooser

Sunday, December 13, 2015

Tkinter GUI Application Development Blueprints

Master GUI programming in Tkinter as you design, implement, and deliver ten real-world applications from start to finish

Tkinter GUI Application Development Blueprints

About This Book
  • Conceptualize and build state-of-art GUI applications with Tkinter
  • Tackle the complexity of just about any size GUI application with a structured and scalable approach
  • A project-based, practical guide to get hands-on into Tkinter GUI development
Who This Book Is For
Software developers, scientists, researchers, engineers, students, or programming hobbyists with basic familiarity in Python will find this book interesting and informative. People familiar with basic programming constructs in other programming language can also catch up with some brief reading on Python. No GUI programming experience is expected.

What You Will Learn
  • Get to know the basic concepts of GUI programming, such as Tkinter top-level widgets, geometry management, event handling, using callbacks, custom styling, and dialogs
  • Create apps that can be scaled in size or complexity without breaking down the core
  • Write your own GUI framework for maximum code reuse
  • Build apps using both procedural and OOP styles, understanding the strengths and limitations of both styles
  • Learn to structure and build large GUI applications based on Model-View-Controller (MVC) architecture
  • Build multithreaded and database-driven apps
  • Create apps that leverage resources from the network
  • Learn basics of 2D and 3D animation in GUI applications
  • Develop apps that can persist application data with object serialization and tools such as config parser
In Detail
Tkinter is the built-in GUI package that comes with standard Python distributions. It is a cross-platform package, which means you build once and deploy everywhere. It is simple to use and intuitive in nature, making it suitable for programmers and non-programmers alike.

This book will help you master the art of GUI programming. It delivers the bigger picture of GUI programming by building real-world, productive, and fun applications such as a text editor, drum machine, game of chess, media player, drawing application, chat application, screen saver, port scanner, and many more. In every project, you will build on the skills acquired in the previous project and gain more expertise.

You will learn to write multithreaded programs, network programs, database driven programs and more. You will also get to know the modern best practices involved in writing GUI apps. With its rich source of sample code, you can build upon the knowledge gained with this book and use it in your own projects in the discipline of your choice.

Style and approach
An easy-to-follow guide, full of hands-on examples of real-world GUI programs. The first chapter is a must read as it explains most of the things you need to get started with writing GUI programs with Tkinter. Each subsequent chapter is a stand-alone project that discusses some aspects of GUI programming in detail. These chapters can be read sequentially or randomly depending upon the readers experience with Python.

Sunday, September 27, 2015

Capture Raspberry Pi Camera image, display on OpenCV, Matplotlib PyPlot and Tkinter GUI

This example capture photo from Raspberry Pi Camera Module, and display with OpenCV, Matplotlib PyPlot and Tkinter GUI.


usage:
python pyCV_picam.py 1 - display wiyh OpenCV window
python pyCV_picam.py 2 - display with matplotlib
python pyCV_picam.py 3 - display with Tkinter

import picamera
import picamera.array
import time
import cv2
from matplotlib import pyplot as plt
import Tkinter 
import Image, ImageTk
import sys

def capturePiCam():
    with picamera.PiCamera() as camera:
        cap=picamera.array.PiRGBArray(camera)
        camera.resolution = (640, 480)
        camera.start_preview()
        time.sleep(3)
        camera.capture(cap,format="bgr")
        global img
        img =cap.array

#- display on OpenCV window -
def displayAtOpenCV():
    cv2.namedWindow('imageWindow', cv2.WINDOW_AUTOSIZE)
    cv2.imshow('imageWindow',img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

#- display with matplotlib -
def displayAtPyplot():
    plt.figure().canvas.set_window_title("Hello Raspberry Pi")
    plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
    plt.show()
    
#- display on Tkinter -
def displayAtThinter():
    root = Tkinter.Tk() 
    b,g,r = cv2.split(img) 
    img2 = cv2.merge((r,g,b))
    img2FromArray = Image.fromarray(img2)
    imgtk = ImageTk.PhotoImage(image=img2FromArray) 
    Tkinter.Label(root, image=imgtk).pack() 
    root.mainloop()

def displayUsage():
    print("usage: ")
    print("python pyCV_picam.py 1 - display wiyh OpenCV window")
    print("python pyCV_picam.py 2 - display with matplotlib")
    print("python pyCV_picam.py 3 - display with Tkinter")

if len(sys.argv) != 2:
    displayUsage()
    sys.exit()
    
opt = sys.argv[1]

if opt=="1":
    print("display wiyh OpenCV window")
    capturePiCam()
    displayAtOpenCV()
elif opt=="2":
    print("display with matplotlib")
    capturePiCam()
    displayAtPyplot()
elif opt=="3":
    print("display with Tkinter")
    capturePiCam()
    displayAtThinter()
else:
    displayUsage()
    



To use ImageTk in your python, refer to "Install PIL (with jpg supported) and ImageTk on Raspberry Pi/Raspbian".

Install PIL (with jpg supported) and ImageTk on Raspberry Pi/Raspbian


To install PIL (with jpg supported) and ImageTk on Raspberry Pi/Raspbian, to display jpg on Python/Tkinter GUI.

$ sudo apt-get install libjpeg8-dev

Then find libjpeg.so and create link on /usr/lib/
$ find /usr/lib -name libjpeg.so
/usr/lib/arm-linux-gnueabihf/libjpeg.so
$ sudo ln -s /usr/lib/arm-linux-gnueabihf/libjpeg.so /usr/lib/

Then install PIL and python-imaging-tk
$ sudo apt-get install python-pip
$ sudo pip install PIL


If you reported with error like this:

gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_LIBJPEG -IlibImaging -I/usr/include -I/usr/local/include -I/usr/include/python2.7 -c _imaging.c -o build/temp.linux-armv7l-2.7/_imaging.o

_imaging.c:75:20: fatal error: Python.h: No such file or directory

compilation terminated.

error: command 'gcc' failed with exit status 1
----------------------------------------

Install python-dev:
$ sudo apt-get install python-dev

and re-run the command:
$ sudo pip install PIL


$ sudo apt-get install python-imaging-tk


Updated@2015-12-16 for Jessie:
Tested on Raspberry Pi 2 running Raspbian Jessie 2015-11-21, no need install PIL, but still have to install python-imaging-tk.

Sunday, April 26, 2015

Python to capture image from Raspberry Pi Camera Module

This Python 2 code run on Raspberry Pi 2 to capture image from Camera Module.


Because the preview will cover the main screen, so this example run remotely on Android tablet running Microsoft Remote Desktop Client App, login Raspberry Pi via xrdp.


myPiCam.py
import picamera
from time import sleep
import Tkinter
import time
from PIL import ImageTk, Image


def quit():
    camera.stop_preview()
    global tkTop
    tkTop.destroy()

def setBrightness(ev=None):
    global camera
    global tkScale
    camera.brightness = tkScale.get()
    
def loadJpg(file):

    JpgWin = Tkinter.Toplevel(tkTop)
    JpgWin.title('New Window')
    JpgWin.geometry('400x300')

    image = Image.open(file)
    image = image.resize((400, 300), Image.ANTIALIAS)
    img = ImageTk.PhotoImage(image)
    panel = Tkinter.Label(JpgWin, image=img)
    panel.pack(side = "bottom", fill = "both", expand = "yes")

    JpgWin.mainloop()

def capture():
    timeStamp = time.strftime("%Y%m%d-%H%M%S")
    jpgFile='img_'+timeStamp+'.jpg'
    camera.capture(jpgFile)
    loadJpg(jpgFile)

camera = picamera.PiCamera()
camera.start_preview()
camera.brightness = 50

tkTop = Tkinter.Tk()
tkTop.wm_title("Raspberry Pi Camera - Brightness")
tkTop.geometry('400x200')

tkButtonQuit = Tkinter.Button(
    tkTop, text="Quit", command=quit)
tkButtonQuit.pack()

tkButtonCapture = Tkinter.Button(
    tkTop, text="Capture", command=capture)
tkButtonCapture.pack()

tkScale = Tkinter.Scale(
    tkTop,
    from_=0, to=100,
    length=300,
    orient=Tkinter.HORIZONTAL,
    command=setBrightness)
tkScale
tkScale.set(50)
tkScale.pack(anchor=Tkinter.CENTER)

Tkinter.mainloop()



To run the Python code on Raspberry Pi, we need to install PIL with jpg supported:

$ sudo apt-get install libjpeg8-dev

Then find libjpeg.so and create link on /usr/lib/
$ find /usr/lib -name libjpeg.so
/usr/lib/arm-linux-gnueabihf/libjpeg.so
$ sudo ln -s /usr/lib/arm-linux-gnueabihf/libjpeg.so /usr/lib/

Then install PIL and python-imaging-tk
$ sudo apt-get install python-pip
$ sudo pip install PIL


If you reported with error like this:

gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DHAVE_LIBJPEG -IlibImaging -I/usr/include -I/usr/local/include -I/usr/include/python2.7 -c _imaging.c -o build/temp.linux-armv7l-2.7/_imaging.o

_imaging.c:75:20: fatal error: Python.h: No such file or directory

compilation terminated.

error: command 'gcc' failed with exit status 1
----------------------------------------

Install python-dev:
$ sudo apt-get install python-dev


$ sudo apt-get install python-imaging-tk


Updated@2015-12-13 for Jessie:
Tested on Raspberry Pi 2 running Raspbian Jessie 2015-11-21, no need install PIL, but still have to install python-imaging-tk.


Wednesday, April 22, 2015

Raspberry Pi Python to set Brightness of Camera Module and preview

Example code of Python 2, run on Raspberry Pi, to control Camera Module, set Brightness and preview. Control Camera Module with picamera, and implement GUI with Tkinter. It's a Tkinter.Scale to set brightness.


Because the preview will be shown on main display, so I run the Python code remotely on Android tablet with Microsoft Remote Desktop app.


testBrightness.py
import picamera
from time import sleep
import Tkinter

def quit():
    camera.stop_preview()
    global tkTop
    tkTop.destroy()

def setBrightness(ev=None):
    global camera
    global tkScale
    camera.brightness = tkScale.get()

camera = picamera.PiCamera()
camera.start_preview()
camera.brightness = 50

tkTop = Tkinter.Tk()
tkTop.wm_title("Raspberry Pi Camera - Brightness")
tkTop.geometry('400x200')

tkButtonQuit = Tkinter.Button(
    tkTop, text="Quit", command=quit)
tkButtonQuit.pack()

tkScale = Tkinter.Scale(
    tkTop,
    from_=0, to=100,
    length=300,
    orient=Tkinter.HORIZONTAL,
    command=setBrightness)
tkScale
tkScale.set(50)
tkScale.pack(anchor=Tkinter.CENTER)

Tkinter.mainloop()


Next:
Python to capture image from Raspberry Pi Camera Module