Using libusb async bulk transfer, device stops receiving if we go idle - qt

I'm writing a Linux program (using Qt 4.8 and libusb 1.0) which will communicate with a custom USB device (currently being programmed by a co-worker).
Step 1 is to have a "heartbeat" going back and forth over USB at regular intervals.
I'm currently using asynchronous bulk transfer.
For testing, I've put my "Send_Heartbeat()" on a button click. If I click on the button a LOT and queue up a number of messages to send, as long as I keep my queue busy, the messages keep sending and my USB device keeps receiving them.
If I stop for a few seconds, then resume and add more messages to the queue, the USB device stops receiving them.
BUT, my program's Transfer Callback DOES return with a transfer status code of 0, indicating success, even though my USB device isn't receiving them.
My questions:
Why does the callback's transfer status indicate success if my USB device appears to have stopped receiving them?
Has anyone heard of this type of behaviour?
It's worth noting that if I disconnect the USB device, I get proper status codes returned in my callback indicating that the device has gone away.
If the USB Device is left connected and running, and I "Detatch" and then again "Attach" to force a re-connection and try sending more test heartbeats, it works! The USB device starts receiving messages again.
My "Detatch" is the following calls:
libusb_release_interface()
libusb_reset_device()
libusb_close()
Then my "Attach" is:
libusb_get_device_list()
libusb_get_device_descriptor()
libusb_open()
libusb_set_configuration()
libusb_claim_interface()
My next step is to narrow down which of the libusb commands is re-establishing the communication.
Meanwhile, I'm hoping someone recognizes these symptoms and has a suggestion.
As it's my first time programming USB communication, I'm wondering if there is some fundamental which I've missed.
Thanks!

The issue is here I guess:
My "Detatch" is the following calls:
libusb_release_interface();
In your detatch, you need to attach kernel driver
detatch_kernel_driver();
libusb_reset_device();
libusb_close();
Then my "Attach" is:
libusb_get_device_list();
libusb_get_device_descriptor();
libusb_open();
libusb_set_configuration();
Here you need to check if the kernel driver is active or not. So,
check what attach_kernel_driver(); returns, and call detatch_kernel_driver(); if needed
libusb_claim_interface();

Related

SIM800L incoming sms stuck in memory

I hit a deadened trying to receive sms on the SIM800L module with Arduino Uno.
I'm using the Receive sms sketch on the IDE, the module does not receive incoming messages and just keeps displaying one sms over and over, this message is the first one I sent to the module, and somehow it's stuck in memory. the sms.flush() method does't erase the message, how do I go about clearing memory to create space for incoming messages ? Thanks
The SIM800L has a vendor specific command to delete all messages, this may clear up enough space for it to receive additional messages.
Run AT+CMGDA=? to find out which mode you need to use. The modem responds with (1-6) or lists the responses in text mode.
Then run AT+CMGDA=6 if the modem responded with numbers, or AT+CMGDA="DEL ALL".
To avoid overflowing the storage, using AT+CNMI=2,2 you can tell the modem to always forward incoming messages to the terminal and avoid storing them in the SIM card or modem memory.

Serial communication crashes in LabVIEW

I am controlling a device over serial connection using LabVIEW (version 7.0). It is connected using USB, and is installed as a virtual serial port on the computer (running Windows XP). Every now and then my device crashes when my program sends a command, and it is unable to accept any more input (the device itself also stops working) until it has timed out.
I've looked at the serial port traffic using Portmon. Whenever the device crashes the serial driver sends the command I send using my program four times instead of just once, with an IOCTL_SERIAL_GET_COMMSTATUS command in between. I cannot see what this last command returns, but I assume something happens in the communication earlier on. I'm thinking my configuration of the port is not entirely right, but I have no idea how or why. I open and close the connection to my device every time I want to write something to it.
For completeness' sake: it has a baud rate of 9600, 8 bits, no parity, 1 stop bit, and no flow control. I'm aware that the correct settings of these parameters depend on the device, but the manufacturer has not supplied any recommended settings.
The driver is a DLL of some sort? If so, this is the most likely source of your problem, and you likely will need to contact the author of the driver. LabVIEW does have crashing bugs, but by far the most common source of crashes in simple communications apps is a buggy third-party DLL.
In other words, I doubt this is a LabVIEW problem at all and that you would have the same difficulty if you wrote a C program to talk to this driver. I only know what you've posted here about your system, but after many years of chasing down such issues, I would start with the device manufacturer/driver author.
If you have evidence to the contrary, please share.

Regarding CAN bus

I am using a 16-bit MCU PIC24HJ64GP504 to write a CAN based application. Basically it is communication between my board and one another node which continuously keeps on sending data to my board using CAN at 1 Mbit/s. I am configuring the ECAN module in my PIC24 to work at 1 Mbit/s. I have written the code in such a way that for the first 10 ms the ECAN module will accept all messages coming in from the other side and after that I have re-configured the ECAN module to accept only those messages with message ID 0x13.
Now here comes the issue... The other node and my board are powered up at the same instant. The other node starts transmitting messages after 40 ms or so after powerup. But I am not able to get any message from it on my board. Now if I power up my board first, give it some time to reconfigure the ECAN module with new filters and settle down and then power up the other node, then everything works perfectly.
Now the strangest part... If I have a CAN bus analyzer connected between my board and the other node and even if I power up both the nodes at the same time, everything works fine... No need to power up my board first. I have tried this with three different bus analyzers from different manufacturers and got the same results.
To me it appears that during re-configuration of the ECAN module, it takes some time to settle down. And with the introduction of the bus analyzer in the bus, this time is somehow cut short so that everything works perfectly. But I am not sure what exactly the problem might be.
The problem might be a missing ACK. The CAN-Analyzer might acknowledge frames and the device does not switch to error passive.
I would hold off sending until the whole bus is initialized.
Also sounds like missing ACKs to me.
Are you seeing any error frames (get the scope to trigger off 6 consecutive dominant bits) - the Tx node might be going off the bus or even into some application-error mode if it doesn't get acknowledged enough.
You might be able to coax it back on bus by transmitting a dummy message on the bus.
I've found a Saleae Logic very useful in these circumstances (as well as a scope) - hang it off the Rx pin of your physical layer (or even wire up a standalone PHY that you can use to monitor the bus). The Saleae software will interpret the CAN and show you what's happening. Sometimes it's useful to use the scope trigger out to trigger the Logic.
CAN Communication requires at least two active devices on bus to have successful communication. This is because, a CAN frame is not completed unless someone acknowledges it.
When you power up your board and other node, it seems your board is not getting ready in 40msec. If it is not ready, it leaves "Other node" to be the only member on the bus and voilates above stated rule. Other node will get Tx error and after 128 erros, That other node will go in error mode and stop sending messages -- Hence you are not getting anything.
When you power up your board first, give it time - your board is ready and will ACK every message sent by other node -- Hence communication is good!
When you add CANalyzer, even if your board is not powered up, there are two active nodes on the bus -- Hence communication is good!

Access COMPORT 1 through three different applications

I have an SMS Appliaction, which receives the messages through GPS Modem and revert back through GPS Modem. The Modem is using COM1.
Now, i need two more appliactions which can send messages through the same GPS Modem. I tried making a webservice which can access the COM1 to send data, but when i try to connect through webService, it throw an error saying, 'COM1 is already occupied, Access denied.'.
Can anybody help me to connect through the modem in above scenario.
Khushi
You have to make sure only 1 connection is made.
Easiest (and most low-tech, but probably most flexible) is having a script checking a directory for files regularly and sending the messages in the file to the modem. The webservice then just writes a file for every SMS it received. (this can be trivially extended to accept emails, web requests, etc, ...)
A bit more sophistacated is to start a thread to do the communication and push the messages on a FIFO like datastructure provided by your favorite programming platform. A BlockinQueue would be perfect. The thread reads the messages from the queue and sends them to the GSM modem.
If you want to have confirmation the SMS is sent (which in my experience does not mean anything and certainly not that the recipient actually received it) you'll need to find a way to return feedback to the caller. This can be as simple a setting a boolean flag in the message to sending another message or performing a callback. But I would not bother. I had situations where 30% of messages dissapeared even when we had confirmation of the message central.

Check if serial port is listening

I have an Arduino sending and receiving instructions with a Python script via a serial port.
The Arduino takes a button state and when it is pushed, it will send a message via the serial port to a Python script and await a response. (via Serial.available()). It works well enough.
However, if the Python script has crashed for whatever reason (ideally it will run in the background, so it can't be easily checked), the Arduino will wait forever and will be unavailable even on a script restart.
Is there a way for my Arduino to check if there is something listening on the serial port? (and alert me with flashing lights, etc. if not) or is this not how serial works? Worst case I guess I could use a timeout, although that is not ideal.
You have a limited ability to detect if there is something listening on the other side by using the DSR/DTR pins.
When you open the serial port on the machine your scripts runs on, it should raise its DTR pin (or you should be able to convince it to do so: the documentation of the library you use to drive the COM port should tell you how).
Then, on your Arduino, you can check its DSR pin (assuming null-modem wiring with handshaking, where the PC DTR pin is wired to DSR+CD on the Arduino) at regular intervals, and handle the 'nobody connected' scenario in any way you see fit.
One problem with this approach is that your PC script may not close the serial port when it crashes/stops responding, leaving the DTR pin enabled as if everything is still OK. Also, your script may simply miss the message from the Arduino due to errors on the serial line.
For that reason, you should always implement a timeout in your receive routines: even if there is a party listening at the other end, there is no guarantee it has received your message (or that its response will reach you intact).
Re-sending the message at least once (assuming DSR is raised) if a timeout occurs makes your protocol more reliable.
The Arduino doesn't use the DSR line or any other handshaking line, so you can't do what you suggest.
I agree with mdb that timeouts are necessary, but would also add that you might want to implement simple challenge/response system that periodically checks if anyone is listening. (I like ircd's Ping-Pong analogy).

Resources