Different number of incoming bytes from STM on Windows and Ubuntu - python

I have a code, which sending a message to usb device. It returns me the correct answer on Windows, but on ubuntu it gives wrong result. Why is that?
import hid
import time
try:
print("Opening the device")
h = hid.device()
h.open(0x0483, 0x5750) # TREZOR VendorID/ProductID
print("Manufacturer: %s" % h.get_manufacturer_string())
print("Product: %s" % h.get_product_string())
print("Serial No: %s" % h.get_serial_number_string())
print("Write the data")
time.sleep(0.05)
h.write(([1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]))
d = h.read(19)
print(d)
except IOError as ex:
print(ex)
print("You probably don't have the hard-coded device.")
print("Update the h.open() line in this script with the one")
print("from the enumeration list output above and try again.")
print("Done")
result on Windows:
Opening the device
Manufacturer: STMicroelectronics
Product: STM32 Custom Human interface
Serial No: 00000000001A
Write the data
[2, 1, 255, 0, 0, 1, 0, 0, 0, 0, 0, 2, 1, 2, 0, 1, 0, 0, 1]
Done
result on Ubuntu:
sudo python3 main.py
Opening the device
Manufacturer: STMicroelectronics
Product: STM32 Custom Human interface
Serial No: 00000000001A
Write the data
Read the data
[2, 1]
Done

Related

Trouble in manipulating the data for treeview in tkinter

everyone. Let me first paste the code.
c.execute("SELECT * FROM c20 WHERE Position = 'chain';")
data1 = c.fetchall()
c.execute("SELECT * FROM c20 WHERE Position = 'center';")
data2 = c.fetchall()
c.execute("SELECT * FROM c20 WHERE Position = 'Total';")
data3 = c.fetchall()
data1 = p_mod.list_multiply(data, copies_data)
data2 = p_mod.list_multiply(data2, copies_data)
data3 = p_mod.list_multiply(data3, copies_data)
meta_data = [data1, data2, data3]
n = 0
while n != 3:
for i in meta_data:
my_tree.insert(parent="", index="end", iid=n, text=f"{n + 1}", values=i)
n += 1
if n == 3:
my_tree.pack(pady=20)
root1.mainloop()
This is the code where I need to fetch queries regarding a requirement and the output required is as follows:
conn = sqlite3.connect("userdata.db")
>>> c = conn.cursor()
>>> c.execute("SELECT * FROM c20 WHERE Position = 'chain';")
<sqlite3.Cursor object at 0x00000221DA432F80>
>>> data1 = c.fetchall()
>>> data1
[('chain', 100, 350, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)]
I have also used a remote function named p_mod.list_multiply().
The function looks like this:
def list_multiply(list_input, number):
new_list = []
list_input = list(list_input)[0]
list_input1 = list_input[1 : -1]
for i in list_input1:
data = int(i) * number
new_list.append(data)
if list_input[0] == 'chain':
new_list.insert(0, 'chain')
elif list_input[0] == 'center':
new_list.insert(0, 'center')
elif list_input[0] == 'Total':
new_list.insert(0, 'Total')
new_list = tuple(new_list)
return new_list
Now the problem arises...
Whenever I try to run the code with same outputs(data1, data2,...) using the function remotely from the main code,
it runs successfully, but whenever I am trying to run the script inside the main program it gives me an error.
Error is as follows:
PS D:\RM INCORPORATION\RM Software DEV Company Pvt\Jewellery App> & C:/Users/ONE/AppData/Local/Programs/Python/Python39/python.exe "d:/RM INCORPORATION/RM Software DEV Company Pvt/Jewellery App/contact.py"
h
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\ONE\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1884, in __call__
return self.func(*args)
File "d:\RM INCORPORATION\RM Software DEV Company Pvt\Jewellery App\contact.py", line 53, in select
data1 = p_mod.list_multiply(data, copies_data)
File "d:\RM INCORPORATION\RM Software DEV Company Pvt\Jewellery App\p_mod.py", line 15, in list_multiply
data = int(i) * number
ValueError: invalid literal for int() with base 10: 'h'
Let me show you the output used with the function remotely, from the main code...
PS D:\RM INCORPORATION\RM Software DEV Company Pvt\Jewellery App> & C:/Users/ONE/AppData/Local/Programs/Python/Python39/python.exe "d:/RM INCORPORATION/RM Software DEV Company Pvt/Jewellery App/p_mod.py"
('chain', 200, 700, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) ('center', 222, 826, 82, 124, 98, 70, 756, 2, 2, 6, 8, 24, 24, 16, 0, 0) ('Total', 422, 1526, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1878, 70)
Then what is the problem dude?
Eagerly waiting someone's reply
You have overwritten list_input by the following line in list_multiply():
list_input = list(list_input)[0]
Therefore, list_input will be a string after that.
Just remove this line will solve the issue.
Also the following line:
list_input1 = list_input[1 : -1]
will not copy the last item of list_input into list_input1.
It should be
list_input1 = list_input[1:]
list_multiply() can be simplified as below:
def list_multiply(list_input, number):
new_list = tuple(int(x)*number for x in list_input[1:])
return (list_input[0],) + new_list

Function setting enable to False only works on some buttons?

I am working on setting up a controls dashboard for operators. whenever a heartbeat stops incrementing, after 5 seconds, the LED changes to red. This also enables the acknowledge buttons. When I click them, the LED chages to yellow and I would like to disable the button again. The issue is that it only works for some of the buttons in my code for some reason. any idea why that might be? It only works for the buttons on the left side and not the right side. I am sure that the error is happening at "heartbeats[string][5].setEnabled(False)"
def ack_thread(string):
ack = threading.Thread(target=acknowledge, args=(string,))
ack.start()
def acknowledge(string):
global heartbeats
rowcount = ui.tableWidget.rowCount()
for x in range(0, rowcount, 1):
if ui.tableWidget.item(x,0).text() == string:
print(ui.tableWidget.item(x,0).text())
if ui.tableWidget.item(x,4).text() == 'False':
ui.tableWidget.setItem(x, 4, QtWidgets.QTableWidgetItem("True"))
ui.tableWidget.viewport().update()
heartbeats[string][3].setPixmap(ui.yellowled)
print(heartbeats[string][5])
# heartbeats[string][5].setEnabled(True)
heartbeats[string][5].setEnabled(False)
def gettime():
import datetime
currentDT = datetime.datetime.now()
return currentDT.strftime("%Y-%m-%d %H:%M:%S")
def alarm_handler(source):
rowPosition = ui.tableWidget.rowCount()
ui.tableWidget.insertRow(rowPosition)
ui.tableWidget.setItem(rowPosition, 0, QtWidgets.QTableWidgetItem(source))
ui.tableWidget.setItem(rowPosition, 1, QtWidgets.QTableWidgetItem("text1"))
ui.tableWidget.setItem(rowPosition, 2, QtWidgets.QTableWidgetItem("text2"))
ui.tableWidget.setItem(rowPosition, 3, QtWidgets.QTableWidgetItem(gettime()))
ui.tableWidget.setItem(rowPosition, 4, QtWidgets.QTableWidgetItem("False"))
def heartbeat():
import mhs2
from time import sleep
global heartbeats
mhs2.DB_CONFIG['host'] = '192.168.1.79'
# old value, new value, number of failures, LED object, checkbutton object, Acknowledge object,acknowledged
heartbeats = {
'pd1_hb': [0, 0, 0, ui.label_26, ui.checkBox_7, ui.pushButton_11, True],
'pd9_hb': [0, 0, 0, ui.label_20, ui.checkBox_12, ui.pushButton_13, True],
'pd11_hb': [0, 0, 0, ui.label_21, ui.checkBox_11, ui.pushButton_12, True],
'pd13_hb': [0, 0, 0, ui.label_22, ui.checkBox_13, ui.pushButton_2, True],
'irr1_hb': [0, 0, 0, ui.label_25, ui.checkBox_8, ui.pushButton_5, True],
'irr2_hb': [0, 0, 0, ui.label_24, ui.checkBox_9, ui.pushButton_4, True],
'irr5_hb': [0, 0, 0, ui.label_23, ui.checkBox_10, ui.pushButton_3, True],
'kyledata_hb': [0, 0, 0, ui.label_14, ui.checkBox, ui.pushButton, True],
'standata_hb': [0, 0, 0, ui.label_19, ui.checkBox_3, ui.pushButton_10, True],
'kennydata_hb': [0, 0, 0, ui.label_18, ui.checkBox_4, ui.pushButton_9, True],
'cartmandata_hb': [0, 0, 0, ui.label_17, ui.checkBox_6, ui.pushButton_8, True],
'chefdata_hb': [0, 0, 0, ui.label_16, ui.checkBox_5, ui.pushButton_6, True],
'buttarsdata_hb': [0, 0, 0, ui.label_15, ui.checkBox_2, ui.pushButton_7, True]
}
for item in heartbeats:
heartbeats[item][3].setPixmap(ui.offled)
query = "SELECT * FROM Heartbeat"
enable = mhs2.exec_query(query)
for row in enable:
if row['enable'] == 1:
heartbeats[row['parameter']][4].setChecked(True)
else:
heartbeats[row['parameter']][4].setChecked(False)
while 1:
command = "SELECT * FROM Heartbeat"
hb = mhs2.exec_query(command)
for row in hb:
if heartbeats[row['parameter']][4].isChecked():
heartbeats[row['parameter']][1] = row['value']
if heartbeats[row['parameter']][1] != heartbeats[row['parameter']][0]:
heartbeats[row['parameter']][2] = 0
heartbeats[row['parameter']][3].setPixmap(ui.greenled)
heartbeats[row['parameter']][6] = True
else:
heartbeats[row['parameter']][2] += 1
if heartbeats[row['parameter']][2] > 5 and heartbeats[row['parameter']][6]:
heartbeats[row['parameter']][3].setPixmap(ui.redled)
heartbeats[row['parameter']][5].setEnabled(True)
heartbeats[row['parameter']][6] = False
alarm = threading.Thread(target=alarm_handler,args=(row['parameter'],))
alarm.start()
heartbeats[row['parameter']][0] = heartbeats[row['parameter']][1]
else:
heartbeats[row['parameter']][3].setPixmap(ui.offled)
sleep(1)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
hb = threading.Thread(target=heartbeat)
hb.start()
sys.exit(app.exec_())

python3.6 asyncio future done() never returns True when called from nested ThreadPoolExecutor (thread within a thread)

Can anyone please help understand why a future's done() never returns True (even when future is complete) when created from nested thread (i.e. using ThreadPoolExecutor within another ThreadPoolExecutor, which is required in my business usecase), but
a future's done() returns True when created one one level ThreadPoolExecutor
Here is the common code that is used for getting metrics of ThreadPoolExecutor (primarily looking at completed_tasks_cnt which is equal to number of futures with done() = True:
import time
from typing import Callable, Tuple
from concurrent.futures.thread import ThreadPoolExecutor
import logging
import asyncio
import pprint
import traceback
from asyncio.futures import Future
log = logging.getLogger(__name__)
logging.basicConfig(format='[%(asctime)s][%(threadName)s][%(process)d][%(name)s][%(levelname)s] %(message)s', level=logging.NOTSET)
def run_fnc_in_background_thread(executor: ThreadPoolExecutor, fnc: Callable, fnc_args: Tuple=(), loop=None) -> Future:
"""Run fnc (performing a IO bound task) in a daemon Thread
Args:
executor: ThreadPoolExecutor (see https://pymotw.com/3/asyncio/executors.html)
fnc: Callable function to run in thread
fnc_args: (Tuple): List of function args
loop: Event loop (Get loop from `asyncio.get_event_loop()` or `asyncio.new_event_loop()`)
Returns:
Future: A future object of the task. You can cancel/stop the future
(https://docs.python.org/3/library/asyncio-future.html#asyncio.Future)
"""
loop = loop or asyncio.get_event_loop()
f: Future = loop.run_in_executor(executor, fnc, *fnc_args)
asyncio.ensure_future(f)
return f
def slow_running_task(taskid):
log.info(f"[{taskid}]slow_running_task sleeping for 2sec")
time.sleep(2)
log.info(f"[{taskid}]slow_running_task COMPLETED")
def check_status(executor, futures):
while True:
# https://stackoverflow.com/a/25474898/558397
pending_tasks_to_be_started = executor._work_queue.qsize()
active_threads_cnt = len(executor._threads)
active_tasks_cnt = 0
completed_tasks_cnt = 0
cancelled_tasks_cnt = 0
exception_raised_tasks_cnt = 0
for f in futures:
if f.done():
completed_tasks_cnt += 1
if f.cancelled():
cancelled_tasks_cnt += 1
if f.exception():
exception_raised_tasks_cnt += 1
else:
active_tasks_cnt += 1
thread_pool_metrics = {
"pending_tasks_to_be_started": pending_tasks_to_be_started,
"active_threads_cnt": active_threads_cnt,
"active_tasks_cnt": active_tasks_cnt,
"completed_tasks_cnt": completed_tasks_cnt,
"cancelled_tasks_cnt": cancelled_tasks_cnt,
"exception_raised_tasks_cnt": exception_raised_tasks_cnt
}
log.info(f"thread_pool_metrics:\n{pprint.pformat(thread_pool_metrics)}")
time.sleep(1)
executor = ThreadPoolExecutor(max_workers=3, thread_name_prefix="MyThread")
def big_thread():
# run_fnc_in_background_thread(executor, slow_running_task)
futures = []
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
f1 = run_fnc_in_background_thread(executor, check_status, fnc_args=(executor, futures), loop=loop)
for taskid in range(2):
futures.append(run_fnc_in_background_thread(executor, slow_running_task, fnc_args=(taskid,), loop=loop))
As you can see, when I use nested ThreadPoolExecutor (because of my requirement), I get the following output (i.e. completed_tasks_cnt is never incremented: 'completed_tasks_cnt': 0,):
def main():
run_fnc_in_background_thread(executor, big_thread)
# big_thread()
loop = asyncio.get_event_loop()
loop.run_forever()
main()
Logs:
[2019-08-19 13:42:02,187][MainThread][32025][asyncio][DEBUG] Using selector: EpollSelector
[2019-08-19 13:42:02,189][MyThread_0][32025][asyncio][DEBUG] Using selector: EpollSelector
[2019-08-19 13:42:02,189][MyThread_1][32025][__main__][INFO] thread_pool_metrics:
{'active_tasks_cnt': 0,
'active_threads_cnt': 1,
'cancelled_tasks_cnt': 0,
'completed_tasks_cnt': 0,
'exception_raised_tasks_cnt': 0,
'pending_tasks_to_be_started': 0}
[2019-08-19 13:42:02,190][MyThread_2][32025][__main__][INFO] [0]slow_running_task sleeping for 2sec
[2019-08-19 13:42:02,190][MyThread_0][32025][__main__][INFO] [1]slow_running_task sleeping for 2sec
[2019-08-19 13:42:03,195][MyThread_1][32025][__main__][INFO] thread_pool_metrics:
{'active_tasks_cnt': 2,
'active_threads_cnt': 3,
'cancelled_tasks_cnt': 0,
'completed_tasks_cnt': 0,
'exception_raised_tasks_cnt': 0,
'pending_tasks_to_be_started': 0}
[2019-08-19 13:42:04,195][MyThread_2][32025][__main__][INFO] [0]slow_running_task COMPLETED
[2019-08-19 13:42:04,196][MyThread_0][32025][__main__][INFO] [1]slow_running_task COMPLETED
[2019-08-19 13:42:04,199][MyThread_1][32025][__main__][INFO] thread_pool_metrics:
{'active_tasks_cnt': 2,
'active_threads_cnt': 3,
'cancelled_tasks_cnt': 0,
'completed_tasks_cnt': 0,
'exception_raised_tasks_cnt': 0,
'pending_tasks_to_be_started': 0}
[2019-08-19 13:42:05,203][MyThread_1][32025][__main__][INFO] thread_pool_metrics:
{'active_tasks_cnt': 2,
'active_threads_cnt': 3,
'cancelled_tasks_cnt': 0,
'completed_tasks_cnt': 0,
'exception_raised_tasks_cnt': 0,
'pending_tasks_to_be_started': 0}
[2019-08-19 13:42:06,209][MyThread_1][32025][__main__][INFO] thread_pool_metrics:
{'active_tasks_cnt': 2,
'active_threads_cnt': 3,
'cancelled_tasks_cnt': 0,
'completed_tasks_cnt': 0,
'exception_raised_tasks_cnt': 0,
'pending_tasks_to_be_started': 0}
[2019-08-19 13:42:07,214][MyThread_1][32025][__main__][INFO] thread_pool_metrics:
{'active_tasks_cnt': 2,
'active_threads_cnt': 3,
'cancelled_tasks_cnt': 0,
'completed_tasks_cnt': 0,
'exception_raised_tasks_cnt': 0,
'pending_tasks_to_be_started': 0}
[2019-08-19 13:42:08,220][MyThread_1][32025][__main__][INFO] thread_pool_metrics:
{'active_tasks_cnt': 2,
'active_threads_cnt': 3,
'cancelled_tasks_cnt': 0,
'completed_tasks_cnt': 0,
'exception_raised_tasks_cnt': 0,
'pending_tasks_to_be_started': 0}
[2019-08-19 13:42:09,225][MyThread_1][32025][__main__][INFO] thread_pool_metrics:
{'active_tasks_cnt': 2,
'active_threads_cnt': 3,
'cancelled_tasks_cnt': 0,
'completed_tasks_cnt': 0,
'exception_raised_tasks_cnt': 0,
'pending_tasks_to_be_started': 0}
But when I call the future from just one level depth of ThreadPoolExecutor, it works: (see 'completed_tasks_cnt': 2,):
def main():
# run_fnc_in_background_thread(executor, big_thread)
big_thread()
loop = asyncio.get_event_loop()
loop.run_forever()
main()
[2019-08-19 13:43:49,709][MainThread][32239][asyncio][DEBUG] Using selector: EpollSelector
[2019-08-19 13:43:49,710][MyThread_0][32239][__main__][INFO] thread_pool_metrics:
{'active_tasks_cnt': 0,
'active_threads_cnt': 0,
'cancelled_tasks_cnt': 0,
'completed_tasks_cnt': 0,
'exception_raised_tasks_cnt': 0,
'pending_tasks_to_be_started': 0}
[2019-08-19 13:43:49,711][MyThread_1][32239][__main__][INFO] [0]slow_running_task sleeping for 2sec
[2019-08-19 13:43:49,711][MyThread_2][32239][__main__][INFO] [1]slow_running_task sleeping for 2sec
[2019-08-19 13:43:50,715][MyThread_0][32239][__main__][INFO] thread_pool_metrics:
{'active_tasks_cnt': 2,
'active_threads_cnt': 3,
'cancelled_tasks_cnt': 0,
'completed_tasks_cnt': 0,
'exception_raised_tasks_cnt': 0,
'pending_tasks_to_be_started': 0}
[2019-08-19 13:43:51,719][MyThread_0][32239][__main__][INFO] thread_pool_metrics:
{'active_tasks_cnt': 2,
'active_threads_cnt': 3,
'cancelled_tasks_cnt': 0,
'completed_tasks_cnt': 0,
'exception_raised_tasks_cnt': 0,
'pending_tasks_to_be_started': 0}
[2019-08-19 13:43:51,719][MyThread_2][32239][__main__][INFO] [1]slow_running_task COMPLETED
[2019-08-19 13:43:51,719][MyThread_1][32239][__main__][INFO] [0]slow_running_task COMPLETED
[2019-08-19 13:43:52,724][MyThread_0][32239][__main__][INFO] thread_pool_metrics:
{'active_tasks_cnt': 0,
'active_threads_cnt': 3,
'cancelled_tasks_cnt': 0,
'completed_tasks_cnt': 2,
'exception_raised_tasks_cnt': 0,
'pending_tasks_to_be_started': 0}
[2019-08-19 13:43:53,730][MyThread_0][32239][__main__][INFO] thread_pool_metrics:
{'active_tasks_cnt': 0,
'active_threads_cnt': 3,
'cancelled_tasks_cnt': 0,
'completed_tasks_cnt': 2,
'exception_raised_tasks_cnt': 0,
'pending_tasks_to_be_started': 0}
[2019-08-19 13:43:54,735][MyThread_0][32239][__main__][INFO] thread_pool_metrics:
{'active_tasks_cnt': 0,
'active_threads_cnt': 3,
'cancelled_tasks_cnt': 0,
'completed_tasks_cnt': 2,
'exception_raised_tasks_cnt': 0,
'pending_tasks_to_be_started': 0}
Your code calls loop.run_in_executor, but doesn't run the event loop. More precisely, main runs one event loop, but big_thread creates a new one, and run_in_executor gets invoked on the latter. This is a problem because updates to the future objects returned by run_in_executor are applied by callbacks run by the event loop scheduler.
The purpose of run_in_executor is to provide a bridge between concurrent.futures and asyncio. Since you're not using asyncio, you don't need the bridge; instead of loop.run_in_executor(executor, fn, *args) you can simply call executor.submit(fn, *args) and get back a native concurrent.futures future which you can poll without an asyncio event loop.
In other words, define run_fnc_in_background_thread like this, and you will see completed futures:
def run_fnc_in_background_thread(executor, fnc, fnc_args, loop=None):
return executor.submit(fnc, *fnc_args)
With this change you no longer need main() to run the event loop, so you can replace loop.run_forever() with time.sleep(3600) or whatever.
Note that your code is accessing private attributes of the executor, such as _work_queue and _threads. Doing that is an extremely bad idea because such attributes can be deleted, renamed, or change meaning without prior notice.

Python NRF24 convert Payload

since some days I try to connect an Arduino with a Raspberry by an NRF24 module.
By the examples i got some working code in C (#raspberry) but I want to use python due to the web app.
The problem is I can't interpret the msq send by the Arduino. The Arduino should send 8 times uint32_t in one payload. After receive in Raspberry I got 8 times 4 uint8_t.
Arduino MSG:
uint32_t SendMsg[8] = {222, micros(), 10, 20, 30, 40, 50, 60};
Raspberry RCV:
Received: [222, 0, 0, 0, 24, 22, 97, 210, 10, 0, 0, 0, 20, 0, 0, 0, 30, 0, 0, 0, 40, 0, 0, 0, 50, 0, 0, 0, 60, 0, 0, 0]
The Raspberry "destroy" the int32 to 4 times int8 ... how I may combine them again?
The RCV is a list of int.
Here the complete code:
Raspberry:
import RPi.GPIO as GPIO
from lib_nrf24 import NRF24
import time
import spidev
GPIO.setmode(GPIO.BCM)
pipes = [0xAB, 0xCD, 0xAB, 0xCD, 0x71]
radio = NRF24(GPIO, spidev.SpiDev())
radio.begin(0, 22)
radio.setPayloadSize(32)
radio.setChannel(77)
radio.setDataRate(NRF24.BR_1MBPS)
radio.setPALevel(NRF24.PA_MIN)
radio.setAutoAck(True)
radio.enableDynamicPayloads()
radio.enableAckPayload()
radio.openReadingPipe(1,pipes)
radio.printDetails()
radio.startListening()
while(1):
# ackPL = [1]
while not radio.available(0):
time.sleep(1 / 100)
receivedMessage = []
radio.read(receivedMessage, radio.getDynamicPayloadSize())
print("Received: {}".format(receivedMessage))
Arduino
//Send.ino
#include<SPI.h>
#include<RF24.h>
// ce, csn pins
RF24 radio(6, 10);
uint32_t RcvMsg[8] = {0, 0, 0, 0, 0, 0, 0, 0};
void setup(void){
radio.begin();
radio.setPALevel(RF24_PA_MAX);
radio.setChannel(77);
radio.openWritingPipe(0xABCDABCD71LL);
radio.enableDynamicPayloads();
radio.powerUp();
}
void loop(void){
const char text[] = "Hello World is awe DOAs";
uint32_t SendMessage;
uint32_t SendMsg[8] = {222, micros(), 10, 20, 30, 40, 50, 60};
radio.write(&SendMsg, sizeof(SendMsg));
if ( radio.isAckPayloadAvailable() ) {
radio.read(&RcvMsg, sizeof(RcvMsg));
}
Serial.print(" SendMsg[0]: ");Serial.print(SendMsg[0]); Serial.print(" SendMsg[1]: ");Serial.print(SendMsg[1]); Serial.print(" SendMsg[2]: ");Serial.print(SendMsg[2]); Serial.print(" SendMsg[3]: ");Serial.print(SendMsg[3]); Serial.print(" SendMsg[4]: ");Serial.print(SendMsg[4]);Serial.print(" SendMsg[5]: ");Serial.print(SendMsg[5]);Serial.print(" SendMsg[6]: ");Serial.print(SendMsg[6]); Serial.print(" SendMsg[7]: ");Serial.println(SendMsg[7]);
Serial.print(" RcvMsg[0] : ");Serial.print(RcvMsg[0]);Serial.print(" RcvMsg[1] : ");Serial.print(RcvMsg[1]);Serial.print(" RcvMsg[2] : ");Serial.print(RcvMsg[2]);Serial.print(" RcvMsg[3] : ");Serial.print(RcvMsg[3]); Serial.print(" RcvMsg[4] : ");Serial.print(RcvMsg[4]);Serial.print(" RcvMsg[5] : ");Serial.print(RcvMsg[5]);Serial.print(" RcvMsg[6] : ");Serial.print(RcvMsg[6]);Serial.print(" RcvMsg[7] : ");Serial.println(RcvMsg[7]);
delay(1000);
}
I found a solution:
#============================================================================#
#============================================================================#
# translate radio Msq from byte to int
#============================================================================#
def translate_from_radio(msg, size):
translated_msg=[]
for i in range (0, size, 4):
translated_msg.append(int.from_bytes([msg[i+3], msg[i+2], msg[i+1], msg[i]], byteorder='big'))
#print("Translate FROM Radio: " + str(msg) + " --> " + str(translated_msg))
return translated_msg
#============================================================================#
#============================================================================#
# Split the msg element in 4 bytes and add it to translated msg
#============================================================================#
def translate_to_radio(msg):
translated_msg=[]
for i in range (0, len(msg)):
x=msg[i].to_bytes(4, byteorder='big')
for g in reversed(x):
translated_msg.append(g)
#print("Translate TO Radio: " + str(msg) + " --> " + str(translated_msg))
return translated_msg

how to debug midi output device using pygames

I'm using a BCF2000 Behringer fader as input to control a robot using ROS. Everything was working fine, but suddenly it stopped working. By suddenly I mean after I got to word after a week off. I need to know if it's a hardware or software problem (maybe somebody drop it off while I was gone? I don't think so but I cannot find a bug). I'm running only a python module that reads the data from the fader and publishes it in ROS to find the problem, which is that I cannot make the sliders of the fader move.
Basically, the python module reads two integers from the argument list. If a third one is given, all values of the fader should be put to 0 (sliders and buttons). The first integer is the input device id, and the second is the output device id. This is:
if len(sys.argv) > 1:
input_dev = int(sys.argv[1])
else:
input_dev = pygame.midi.get_default_input_id()
print "Using DEFAULT input device %d" % input_dev
if input_dev == -1:
print "No default MIDI input device"
exit(-1)
print "Using input device %d" % input_dev
if len(sys.argv) > 2:
output_dev = int(sys.argv[2])
else:
output_dev = pygame.midi.get_default_output_id()
print "Using DEFAULT output device %d" % input_dev
if output_dev == -1:
print "No default MIDI output device"
exit(-1)
print "Using output device %d" % output_dev
controller = pygame.midi.Input(input_dev)
controller_input = pygame.midi.Output(output_dev)
The thing is that I don't know how to find the correct input device number. For the last month I was calling it using '3' and '2', meaning:
me#mycpu:ros$ rosrun bcf2000 bcf2000_driver.py 3 2
if I make an echo of the published data, I get all the data published when I move any slider or press a button. For example:
me#mycpu:ros$ rostopic echo /bcf2000/joy
header:
seq: 1
stamp:
secs: 1441969279
nsecs: 677656888
frame_id: ''
axes: [21.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 69.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
buttons: [127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
but if I write to the fader, the sliders won't move. Again, this code was working a few days ago. I'm 100% sure is the same code according to the GIT repository log. For example, putting everything to 0:
for i in range(1,93):
controller_input.write([[[176, i, 0, 0], 0]])
where the fader has 93 channels.
It may be that I'm using the wrong output device number. I've changed the number between 0 and 10 and nothing. How do I find out what is the correct device number? How do I debug that is actually a software issue (maybe a OS issue, I don't know) or a hardware issue? The last is very unlikely, since it would be a very selective hardware issue. But I may be mistake.
UPDATE: This only happens on my computer, so it's not a hardware issue.
UPDATE 2: This is the output of aseqdump -l
me#mycpu:ros$ aseqdump -l
Port Client name Port name
0:0 System Timer
0:1 System Announce
14:0 Midi Through Midi Through Port-0
24:0 BCF2000 BCF2000 MIDI 1
24:1 BCF2000 BCF2000 MIDI 2
I can listen to the input using aseqdump -p 24:0.
Listing the info from all devices using get_device_info gives:
('ALSA', 'Midi Through Port-0', 0, 1, 0)
('ALSA', 'Midi Through Port-0', 1, 0, 0)
('ALSA', 'BCF2000 MIDI 1', 0, 1, 0)
('ALSA', 'BCF2000 MIDI 1', 1, 0, 0)
('ALSA', 'BCF2000 MIDI 2', 0, 1, 0)
('ALSA', 'BCF2000 MIDI 2', 1, 0, 0)
('ALSA', 'BCF2000 MIDI 3', 0, 1, 0)
('ALSA', 'aseqdump', 0, 1, 0)
For devices 2, 4 and 6 I cannot write to the device. I'm trying to write to each output device using:
#!/usr/bin/env python
import pygame
import pygame.midi
import sys
import time
def main():
pygame.midi.init()
devices = pygame.midi.get_count()
if devices < 1:
print "No MIDI devices detected"
exit(-1)
print "Found %d MIDI devices" % devices
print("id -- interface -- name -- input -- ouput -- opened")
for ii in range(devices):
ll = pygame.midi.get_device_info(ii)
bool1 = bool(ll[2])
bool2 = bool(ll[3])
bool3 = bool(ll[4])
print(str(ii) + " -- " + str(ll[0]) + " -- " + str(ll[1]) + " -- " + str(bool1) + " -- " + str(bool2) + " -- " + str(bool3))
if (bool2):
value = 0
if ii%2 == 0:
value = 127
controller = pygame.midi.Output(ii)
controller.write([[[176, 48, 0, 0], value]])
time.sleep(2)
which should print the device info for each device, and if its an output device, it should move the first slider. It doesn't move for any device.

Categories