digi.xbee module is really slow when using threading - python

I have two devices connected to my pc, and I want to configure my DigiMesh device (one is on transparent mode and one is on API mode) I want to send Remote AT commands to the transparent device and AT commands to the API mode device.
In my system I first open the connection to classify the devices to find the MAC address and COM automatically for this, I open a connection to them, get the data and close it.
when I run my test script that configures them, after opening a couple of threads, the time of the AT and Remote AT commands increases drastically, and also is not very stable and sometimes doesn't work, in addition to the opening of the device (DigiMeshDevice.open()) takes a long time and most of the time, timeouts.
When I run it before the threads it works perfectly.
When looking in the task manager before running the threads and after, the CPU usage didn't go up by much, so I don't think it's a resource problem, do you have any idea what can cause this? Do I need to move to multiprocessing instead? Can this be related to the USB drivers or something like that?

Related

Is there a way to force close an opened COM port device?

Using Python, I need to force close a COM port which was opened using a different program. I can't close the COM port because I can't initiate a session with it since its already opened somewhere else.
import visa
rm = visa.ResourceManager()
# list all the COM ports connected to PC
print(rm.list_resources())
# open a device session on one COM port
dev = rm.open_resource('COM12')
# this can't be done if the 'COM12' is already opened somewhere else
# I need to close 'COM12' like this
# but can't access it because its already opened
dev.close()
Is there a way to force close a session like 'COM12' if it was opened in a different program? When other software (LabVIEW) encounters an error, it crashes and often leaves COM ports open, which then prevent me from accessing them without manually shutting down the physical device. It would be nice to force them to close so that they can be opened again properly.
I'm pretty sure that if LabVIEW crashes, the operating system releases all hardware resources on its behalf.
But keep in mind that LabVIEW is a runtime environment in which child programs run. So if the child program aborted, the LabVIEW process itself might still be running. It would be easy to write a small LabVIEW program that calls VISA Close on COM12 within the LabVIEW environment and that should do the trick. You could also quit the LabVIEW process.
Finally, I've occasionally seen serial device drivers (especially for non-standard serial ports, such as those that use USB or Ethernet) that run into problems if you the program doesn't do everything perfectly, such as gracefully call close. In those cases, sometimes you have to reboot to get the device driver into the right state.
While I don't have a definitive answer, I'm pretty sure it's: No. As in, there's no good way to accomplish that.
Hardware resources are handled by the operating system. And if one process opens a resource and does not release it, you cannot just go and steal it "without consent". That would crash the other process. Which the operating system is tasked to prevent.
You may be able to "kill" the other process, using the operating system's API. But you would first have to identify it as the one holding the lock on the given resource — which would be the topic of another question.

Raspberry pi - AdaFruit DHT in wsgi script (non-root)

Using the ADAFRUIT_DHT python library from https://github.com/adafruit/Adafruit_Python_DHT and a DHT22 temp/humidity sensor (https://www.adafruit.com/products/393) I'm able to easily read temperature and humidity values.
The problem is, that I need to run my script as root, in order to interact with the GPIO pins. This is simply not possible, when running my script through a website, via wsgi, as apache will not let me (for good reason) set the WSGIDaemonProcess's user to root.
I've got pigpiod running which allows me to interact with the GPIO through it, as a non-root user, however, the ADAFRUIT_DHT doesn't go through the daemon, and interacts directly with the GPIO. I'm not 100% sure the pigpio daemon would be fast enough for the bit-banging, required to decode the response from the DHT22 unit, but, perhaps.
So, is there a way for me to coerce the ADAFRUIT_DHT library to not require being run as root, or, are there alternatives to the library available that might accomplish what I'm looking for?
Create a small server that runs as root and listens on a local Unix or TCP socket. When another process connects, your server reads the data from sensor and returns it.
Now your WSGI process only needs permissions to connect to the listening socket, which can be easily managed either via permissions on a Unix socket, or simply throwing access control to the wind and opening a TCP socket bound to the localhost address (so that only processes on the local machine can connect).
There are several advantages to doing this...for example, you can now have multiple programs consuming the temperature data at the same time, and not need to worry about device contention (because only the temperature server is actually reading the data). You can even implement short-term caching to provide faster responses.
Also, note that there is a raspberry pi specific stackexchange.
pigpio can certainly read the DHT11/22 etc. sensors.
There are two examples using the daemon (which means root privileges are not required).
DHT11/21/22/33/44 Sensor written in C which auto detects the model.
DHT22 written in Python which only handles the DHT22 (the github has a DHT11 example).
Both examples are likely to give reliable results (read error rates of better than 1 in 10 thousand rather than worse than 1 in 10).

Crashing MR-3020

I've got several MR-3020's that I have flashed with OpenWRT and mounted a 16GB ext4 USB drive on it. Upon boot, a daemon shell script is started which does two things:
1) It constantly looks to see if my main program is running and if not starts up the python script
2) It compares the lasts heartbeat timestamp generated by my main program and if it is older than 10 minutes in the past kills the python process. #1 is then supposed to restart it.
Once running, my main script goes into monitor mode and collects packet information. It periodically stops sniffing, connects to the internet and uploads the data to my server, saves the heartbeat timestamp and then goes back into monitor mode.
This will run for a couple hours, days, or even a few weeks but always seems to die at some point. I've been having this issue for nearly 6 months (not exclusively) I've run out of ideas. I've got files for error, info and debug level logging on pretty much every line in the python script. The amount of memory used by the python process seems to hold steady. All network calls are encapsulated in try/catch statements. The daemon writes to logread. Even with all that logging, I can't seem to track down what the issue might be. There doesn't seem to be any endless loops entered into, none of the errors (usually HTTP request when not connected to internet yet) are ever the final log record - the device just seems to freeze up randomly.
Any advice on how to further track this down?
It could be related to many things: things that I had to fix also: check the external power supply of the router, needs to be stable, the usb drives could drain too much current than the port can handle, a simple fix is to add a externally powered usbhub or the same port but with capacitors in parallel to the powerline and at the beginning of the usb port where the drive is, maybe 1000uF

Serial communication over USB converter in Python - how to aproach this?

A python program needs to accept a string every second from a serial port. I plan on using a RS-232 to USB converter. The application is going to work under Ubuntu 10.04.
How do I approach this? Do I use pySerial or libusb?
There needs to be done some processing in the meantime, so synchronous communication is not viable. Do I use some kind of interrupts or do I need to open separate threads? Or do I use blocking reads, believing that 1s is enough for my computations (it is plenty ... for now)?
I know, RTFM, but heading in the correct direction from the start will save me a lot of time! Thanks for bearing with me.
If your RS232-USB converter has a driver in Ubuntu that makes it look like a COM port then you will want to use pySerial (the interface is the same as any other COM port). If there is no driver for your device then you might have to use libusb and find the protocol for your specific device. Most major RS232-USB converters these days have usbserial based drivers committed and maintained in the Linux kernel. Simply check with your vendor for this.
There are many ways to do parallel processing but typically I write my applications in two ways:
Have a read thread that does nothing but read and fill a local thread safe buffer so data is ready for other threads when needed.
Have a read thread that reads data, determines where it goes and delivers it via messaging/event processing to the component that needs it.
The decisions here will depend on what your goals are, and how much processing is needed outside the reading.

Serial Communication one to one

If this is a stupid question, please don't mind me. But I spent some time trying to find the answer but I couldn't get anything solid. Maybe this is a hardware question, but I figured I'd try here first.
Does Serial Communication only work one to one? The reason this came up is because I had an arduino board listening for communication on its serial port. I had a python script feed bytes to the port as well. However, whenever I opened up the arduino's serial monitor, the connection with the python script failed. The serial monitor also connects to the serial port for communication for its little text input field.
So what's the deal? Does serial communication only work between a single client and a single server? Is there a way to get multiple clients writing to the server? I appreciate your suggestions.
Multiple clients (e.g. Arduinos) communicating with one server (e.g. a desktop computer) is commonly done with the serial variant:
RS-485
This is a simple method widely used in industrial settings where you want to have many devices connected to one computer via one serial port. This type of arrangement is also called multi-drop, because one cable strings around a building with Tees that tap in and drop lines to each device.
The hardware for this is widely available. You can buy USB serial adapters that provide the hardware interface for a computer. Programmatically the port looks just like an RS232 port. For the Arduino you would just add a transceiver chip. A sea of serial transceivers exists, e.g.
Example computer USB adapter with 485 interface
Sample RS485 transceiver chip from Element14
All the devices hang on the same bus listening at the same time. A simple communication protocol used is just add a device address before every command. For example:
001SETLIGHT1 <- tells Arduino "001" to turn on the light
013SETLIGHT0 <- tells "013" to turn off the light
Any device hanging on the cable ignores commands that do not start with their address. When a device responds, it prepends its address.
001SETLIGHT1DONE <- response from device "001" that the command has been received and executed
The address in the response lets the receiving party know which device was talking.
Well, your question can be quite wide, so I'm going to layer my answer:
On the hardware side, the same pair of wires can work be shared with many devices. It is mostly a question of electronics (maintaining the signal in the good voltage range), and not having all devices writing to the serial port at the same time (or you'll get wreckage).
On the software side, on the host, yes you can share the same serial connection to a device with multiple processes. But that's not straight forward. I'll assume you're using an unix (macos or linux):
in unix, everything is a file, your serial connection is one too: /dev/ttyACM0 on linux, for example.
When you have a process opening that file, it will block it (using ioctl, iirc) so no other process can mess with that file too.
Then, you can input and output to that file using the process that opened it, that's all.
But hopefully, it is still possible to share the connection between processes. One of them would simply be to use the tee command, that will be able to get input from one process, and give it back output, and copy the output to another process. You can also do it from within python, by duplicating the file descriptor.
To easily output stuff that can be redirected the unix way (using pipes), you can use socat: http://www.dest-unreach.org/socat/
here's an usage example:
socat -,raw,echo=0,escape=0x0f /dev/ttyACM0,raw,echo=0,crnl
you may want to tweak it for your needs.
Edit:
I forgot about RS-485, which 'jdr5ca' was smart enough to recommend. My explanation below is restricted to RS-232, the more "garden variety" serial port. As 'jdr5ca' points out, RS-485 is a much better alternative for the described problem.
Original:
To expand on zmo's answer a bit, it is possible to share serial at the hardware level, and it has been done before, but it is rarely done in practice.
Likewise, at the software driver level, it is again theoretically possible to share, but you run into similar problems as the hardware level, i.e. how to "share" the link to prevent collisions, etc.
A "typical" setup would be two serial (hardware) devices attached to each other 1:1. Each would run a single software process that would manage sending/receiving data on the link.
If it is desired to share the serial link amongst multiple processes (on either side), the software process that manages the link would also need to manage passing the received data to each reading process (keeping track of which data each process had read) and also arbitrate which sending process gets access to the link during "writes".
If there are multiple read/write processes on each end of the link, the handshaking/coordination of all this gets deep as some sort of meta-signaling arrangement may be needed to coordinate the comms between the process on each end.
Either a real mess or a fun challenge, depending on your needs and how you view such things.

Categories

Resources