PyFirmata Button Doesnt Change Values - python

Im Using Pyfirmata For A While, And I Want To Connect A Joystick Button On It, I Made The Code (AI) And It Didnt Work, It Keeps Changing Like "True, False, False, True, True..." and doesnt do nothing, heres my python code (PS: im using standart_firmata)
from pyfirmata import *
import time
import speech_recognition as sr
import random
from math import *
class IA:
def __init__(self, board, maquina, analogx, analogy) -> None:
self.board = board
self.maquina = maquina
self.analogx = analogx
self.analogy = analogy
self.button = self.board.get_pin("d:8:i")
self.previous_button_state = 0
self.sr = sr.Recognizer()
def record(self):
with self.sr.Microphone() as source:
print("gravando")
self.sr.adjust_for_ambient_noise(source)
audio = self.sr.listen(source)
try:
frase = sr.recognize_google(audio,language='pt-BR')
frase = frase.lower()
pass
except sr.UnkownValueError:
self.maquina.say("Não Entendi")
self.maquina.runAndWait()
self.main()
if (frase == "olá"):
sentences = ["Olá","Opa","Eae","Oi","Haha Eae"]
sentence = random.choice(tuple(sentences))
self.maquina.say(sentence)
self.maquina.runAndWait()
def main(self):
while True:
print(floor(self.button.read()))
time.sleep(1)
def greet(self):
self.board.digital[2].write(135)
self.maquina.say("Olá! Sou Jesse, Bem Vindo Ao Meu Sistema")
self.maquina.runAndWait()
self.board.digital[2].write(90)
self.maquina.say("Posso Fazer Varias Coisas")
self.maquina.runAndWait()
self.board.digital[2].write(135)
self.maquina.say("Apenas Aperte No Botão Do Joystick E Fale Oque Quer! Divirta-se")
self.maquina.runAndWait()
self.board.digital[2].write(90)
self.board.digital[3].write(75)
self.main()
If anyone can help me, i will be grateful, thanks.

Related

"Table" widget doesn't work when I turn the application to android

I created a button that when pressed, it shows a single database record in the Table, it works perfectly on the desktop version, but when I compile for android it doesn't work, can you help me?
This is the code:
"""
O aplicativo de teste
"""
import toga
from toga.style import Pack
from toga.style.pack import COLUMN, ROW
import sqlite3
import asyncio
class KaiqueTeste(toga.App):
def startup(self):
main_box = toga.Box()
self.label = toga.Label(text="Kaique Teste")
self.lista = toga.Table(['Cod', 'Nome', 'CPF/CNPJ', 'RG/IE', 'Endereço', 'Cplt/Ende', 'Pont Ref', 'Bairro', 'Cidade', 'UF'], missing_value="")
self.lista.MIN_HEIGHT = 180
self.btn = toga.Button('CONFIRMA', style=Pack(padding=5), on_press=self.confirmar_cli)
pasta = toga.Box(style=Pack(direction=COLUMN, padding=5))
pasta.add(self.label)
pasta.add(self.lista)
pasta.add(self.btn)
main_box.add(pasta)
self.main_window = toga.MainWindow(title=self.formal_name)
self.main_window.content = main_box
self.main_window.show()
async def confirmar_cli(self, widget):
try:
conn = sqlite3.connect(self.paths.app/'banco.db')
c = conn.cursor()
c.execute("SELECT cod, nome, cpf_cnpj, rg_ie, endereco, cplt_ende, pont_ref, bairro, cidade, uf FROM clientes WHERE cod = 1")
dados_lidos = c.fetchall()
await asyncio.sleep(0.1)
self.lista.data = dados_lidos
except Exception as ERROR:
print(ERROR)
def main():
return KaiqueTeste()

Serial Communication breaks down when threading

I am using a USB microwave source, which communicates via a virtual COM port.
Communication is done via python. Everything works fine, as long as I am executing the code blockingly.
However, as soon as any communication is done in a thread
I get a SerialException: Attempting to use a port that is not open. Is there an obvious reason, why this is happening? Nothing else, at least originating from my software, is trying to communicate with the port during that time.
The highest level script:
from serial import SerialException
import deer
import windfreak_usb
try:
deer.mw_targets = windfreak_usb.WindfreakSynthesizer()
except SerialException:
deer.mw_targets.port.close()
deer.mw_targets = windfreak_usb.WindfreakSynthesizer()
deer_mes = deer.DeerMeasurement(f_start=0.9e9,
f_end=1.2e9,
df=3e6,
f_nv=1.704e9,
seq=["[(['mw'],28),([],tau),(['mw', 'mwy'],56),([],tau),(['mw'],28),([],100)]",
"[(['mw'],28),([],tau),(['mw', 'mwy'],56),([],tau),(['mw'],84),([],100)]"],
power_nv=10,
power_targets=3,
tau=700
)
deer_mes.run(10e6) # <- this works perfectly, as it is the blocking version
# deer_mes.start(10e6) # <- raises the SerialException at the line indicated below
deer.mw_targets.port.close()
A reduced form of the microwave source (windfreak_usb.py):
import serial
import synthesizer
class WindfreakSynthesizer(synthesizer.Synthesizer):
def __init__(self):
synthesizer.Synthesizer.__init__(self)
self.port = serial.Serial(
port='COM14',
baudrate=9600,
timeout=10
)
self.off()
def __del__(self):
self.port.close()
def off(self):
self.port.write('o0')
def power(self, p):
p = int(p)
self.port.write('a{}'.format(p))
A reduced form of the measurement class (deer.py):
import threading
import time
import numpy
import os
from PyQt4 import QtCore
from PyQt4.QtCore import QObject
import matplotlib.pyplot as plt
import hardware
import matpickle
import pulsed
import pulser
import savepath
import synthesizer
if 'pg' not in globals():
pg = pulser.Pulser()
if 'mw_targets' not in globals():
mw_targets = synthesizer.Synthesizer()
timeout = 30
CurrentMeasurement = None # global variable pointing to the currently active measurement
class DeerMeasurement(QObject):
update = QtCore.pyqtSignal()
def __init__(self, f_start, f_end, df, f_nv, seq, power_nv, power_targets, tau, sweeps_per_iteration=50e3,
switching_time=300e-6):
super(QObject, self).__init__()
""" setting all parameters as self.parameter """
self.power_targets = power_targets
self.fs = numpy.arange(f_start, f_end + df, df)
self.abort = threading.Event()
self.save_deer()
def run(self, sweeps):
global CurrentMeasurement
if CurrentMeasurement is not None:
print('Deer Warning: cannot start measurement while another one is already running. Returning...')
return
CurrentMeasurement = self
# Start measurement
print('Deer measurement started.')
mw_targets.power(self.power_targets) # <- This causes the SerialException.
""" Here comes the actual measurement, that is never executed, as the line above kills the thread already with the SerialException. """
def start(self, sweeps, monitor=None):
"""Start Measurement in a thread."""
if monitor is not None:
monitor.register(self)
if not hasattr(self, 'mes_thread'):
# noinspection PyAttributeOutsideInit
self.mes_thread = threading.Thread(target=self.run, args=(sweeps,))
self.mes_thread.start()
else:
print('Already threading')
Any help is highly appreciated, as running the measurement outside a thread is not an option.
Best regards!

Using asyncio to read the output of a serial port

I have been doing some port-reading for work, and I need to know if I should use asyncIO to read the data that comes in from this port.
Here's some details about the way in which the system is constructed.
Multiple sensors are being read at the same time and might produce output that goes in at the same time. (all data comes in through a probee ZU10 connected to a usb port) All data must be timestamped as soon as it comes in.
The data is supposed to be processed and then sent to a django webapp through a REST API.
The thing Is, it's really important not to lose any data, I'm asking about this because I believe there must be an easier way to do this than the one I'm thinking of.
The way I want the data to come in is through an asyncronous process that takes in the data into a queue and timestamps it, this way there is no way in which loss of data is present, and timestamping may be no more than a few fractions of a second off, which is not a problem.
If anyone has got any ideas I would be thankful for them
Here's the code I'm using to open the port, take the data in and what I've got so far on the actually reading the meaningful data.
Here's the reading part:
import serial #for port opening
import sys #for exceptions
#
#configure the serial connections (the parameters differs on the device you are connecting to)
class Serializer:
def __init__(self, port, baudrate=9600, timeout=.1):
self.port = serial.Serial(port = port, baudrate=baudrate,
timeout=timeout, writeTimeout=timeout)
def open(self):
''' Abre Puerto Serial'''
self.port.open()
def close(self):
''' Cierra Puerto Serial'''
self.port.close()
def send(self, msg):
''' envía mensaje a dispositivo serial'''
self.port.write(msg)
def recv(self):
''' lee salidas del dispositivo serial '''
return self.port.readline()
PORT = '/dev/ttyUSB0' #Esto puede necesitar cambiarse
# test main class made for testing
def main():
test_port = Serializer(port = PORT)
while True:
print(test_port.recv())
if __name__ == "__main__":
main()
And a bit of what I'm going to be using to filter out the meaningful reads (bear with it, it might be full of awful errors and maybe a terrible RegEx):
import re
from Lector import ChecaPuertos
from Lector import entrada
patterns = [r'^{5}[0-9],2[0-9a-fA-F] $'] #pattern list
class IterPat:
def __init__(self, lect, pat = patterns):
self.pat = pat # lista de patrones posibles para sensores
self.lect = lect # lectura siendo analizada
self.patLen = len(pat) #Largo de patrones
def __iter__(self):
self.iteracion = 0 #crea la variable a iterar.
def __next__(self):
'''
Primero revisa si ya pasamos por todas las iteraciones posibles
luego revisa si la iteración es la que pensabamos, de ser así regresa una
tupla con el patrón correspondiente, y la lectura
de otra forma para el valor de ser mostrado
'''
pattern = re.compile(self.pat[self.iteracion])
comp = pattern.match(self.lect)
if comp == True:
re_value = (self.pattern, self.lect)
return re_value
else:
self.iteración += 1
def main():
puerto = ChecaPuertos.serial_ports()
serial = entrada.Serializer(port = puerto[0])
if serial != open:
serial.open()
while True:
iter = IterPat()
#This is incomplete right here.
I am using asyncio to read/write a serial port with pyserial. I am having my device on the other end of the serial connection write a single byte when it is ready to receive a payload. Asyncio watches for that byte then sends the payload. It looks something like this:
serial_f = serial.Serial(port=dev, baudrate=BAUDRATE, timeout=2)
def write_serial():
status = serial_f.read(1)
serial_f.write(buffer)
loop = asyncio.get_event_loop()
loop.add_reader(serial_f.fileno(), write_serial)

Tkinter window not playing well with threads

I've got a program that will eventually receive data from an external source over serial, but I'm trying to develop the display-side first.
I've got this "main" module that has the simulated data send and receive. It updates a global that is used by a Matplotlib stripchart. All of this works.
#-------------------------------------------------------------------------------
# Name: BBQData
# Purpose: Gets the data from the Arduino, and runs the threads.
#-------------------------------------------------------------------------------
import time
import math
import random
from threading import Thread
import my_globals as bbq
import sys
import BBQStripChart as sc
import serial
import BBQControl as control
ser = serial.serial_for_url('loop://', timeout=10)
def simData():
newTime = time.time()
if not hasattr(simData, "lastUpdate"):
simData.lastUpdate = newTime # it doesn't exist yet, so initialize it
simData.firstTime = newTime # it doesn't exist yet, so initialize it
if newTime > simData.lastUpdate:
simData.lastUpdate = newTime
return (140 + 0.05*(simData.lastUpdate - simData.firstTime), \
145 + 0.022*(simData.lastUpdate - simData.firstTime), \
210 + random.randrange(-10, 10))
else:
return None
def serialDataPump():
testCtr = 0;
while not bbq.closing and testCtr<100:
newData = simData()
if newData != None:
reportStr = "D " + "".join(['{:3.0f} ' for x in newData]) + '\n'
reportStr = reportStr.format(*newData)
ser.write(bytes(reportStr, 'ascii'))
testCtr+=1
time.sleep(1)
bbq.closing = True
def serialDataRcv():
while not bbq.closing:
line = ser.readline()
rcvdTime = time.time()
temps = str(line, 'ascii').split(" ")
temps = temps[1:-1]
for j, x in enumerate(temps):
bbq.temps[j].append(float(x))
bbq.plotTimes.append(rcvdTime)
def main():
sendThread = Thread(target = serialDataPump)
receiveThread = Thread(target = serialDataRcv)
sendThread.start()
receiveThread.start()
# sc.runUI()
control.runControl() #blocks until user closes window
bbq.closing = True
time.sleep(2)
exit()
if __name__ == '__main__':
main()
## testSerMain()
However, I'd like to add a SEPARATE tkinter window that just has the most recent data on it, a close button, etc. I can get that window to come up, and show data initially, but none of the other threads run. (and nothing works when I try to run the window and the plot at the same time.)
#-------------------------------------------------------------------------------
# Name: BBQ Display/Control
# Purpose: displays current temp data, and control options
#-------------------------------------------------------------------------------
import tkinter as tk
import tkinter.font
import my_globals as bbq
import threading
fontSize = 78
class BBQControl(tk.Tk):
def __init__(self,parent):
tk.Tk.__init__(self,parent)
self.parent = parent
self.labelFont = tkinter.font.Font(family='Helvetica', size=int(fontSize*0.8))
self.dataFont = tkinter.font.Font(family='Helvetica', size=fontSize, weight = 'bold')
self.makeWindow()
def makeWindow(self):
self.grid()
btnClose = tk.Button(self,text=u"Close")
btnClose.grid(column=1,row=5)
lblFood = tk.Label(self,anchor=tk.CENTER, text="Food Temps", \
font = self.labelFont)
lblFood.grid(column=0,row=0)
lblPit = tk.Label(self,anchor=tk.CENTER, text="Pit Temps", \
font = self.labelFont)
lblPit.grid(column=1,row=0)
self.food1Temp = tk.StringVar()
lblFoodTemp1 = tk.Label(self,anchor=tk.E, \
textvariable=self.food1Temp, font = self.dataFont)
lblFoodTemp1.grid(column=0,row=1)
#spawn thread to update temps
updateThread = threading.Thread(target = self.updateLoop)
updateThread.start()
def updateLoop(self):
self.food1Temp.set(str(bbq.temps[1][-1]))
def runControl():
app = BBQControl(None)
app.title('BBQ Display')
app.after(0, app.updateLoop)
app.mainloop()
bbq.closing = True
if __name__ == '__main__':
runControl()
Your title sums up the problem nicely: Tkinter doesn't play well with threads. That's not a question, that's the answer.
You can only access tkinter widgets from the same thread that created the widgets. If you want to use threads, you'll need your non-gui threads to put data on a queue and have the gui thread poll the queue periodically.
One way of getting tkinter to play well with threads is to modify the library so all method calls run on a single thread. Two other questions deal with this same problem: Updating a TKinter GUI from a multiprocessing calculation and Python GUI is not responding while thread is executing. In turn, the given answers point to several modules that help to solve the problem you are facing. Whenever I work with tkinter, I always use the safetkinter module in case threads appear to be helpful in the program.

How to draw lines in IronPython with Winforms?

I've started working with IronPython in #Develop, and i love the integration with IronPython and Windows Forms, it lets you create the GUI like is were Visual Basic or C#
The question i have is simple, how to draw a line into a PictureBox when it's clicked? I've found this code about drawing lines, but i know how to adapt it to a PictureBox.
This is the code i've found:
http://www.zetcode.com/tutorials/ironpythontutorial/painting/
So, what should i put in "def PictureBox1Click(self, sender, e):"?
Any help or guide would be gratly appreciated.
Here is a simple example that draws a line on a picture box when it is clicked.
import System.Drawing
import System.Windows.Forms
from System.Drawing import *
from System.Windows.Forms import *
class MainForm(Form):
def __init__(self):
self.InitializeComponent()
self.pen = System.Drawing.Pen(System.Drawing.Color.Black);
def InitializeComponent(self):
self._pictureBox1 = System.Windows.Forms.PictureBox()
self._pictureBox1.BeginInit()
self.SuspendLayout()
#
# pictureBox1
#
self._pictureBox1.Location = System.Drawing.Point(13, 13)
self._pictureBox1.Name = "pictureBox1"
self._pictureBox1.Size = System.Drawing.Size(259, 237)
self._pictureBox1.TabIndex = 0
self._pictureBox1.TabStop = False
self._pictureBox1.Click += self.PictureBox1Click
#
# MainForm
#
self.ClientSize = System.Drawing.Size(284, 262)
self.Controls.Add(self._pictureBox1)
self.Name = "MainForm"
self.Text = "PyWinForm"
self._pictureBox1.EndInit()
self.ResumeLayout(False)
def PictureBox1Click(self, sender, e):
g = self._pictureBox1.CreateGraphics()
g.DrawLine(self.pen, 10, 10, 400, 200)

Categories