Closed ElDonad closed 4 years ago
Please verify whether you have most recent software downloaded, if so let's have a look. Quite some error handling has been improved lately.
Hello, thanks for your reply ! Yes, I git clone whenever I need a new copy of the software.
Do you use .exe (is older) or .py?
The .py one. python FortiusAnt.py -s -a.
Ok will check later. Please send logfile of the version you run -d127
Done, thank you much ! FortiusANT.2020-04-27 15-17-33.log
(sorry for the french Windows error messages)
Hi Elie, bon jour!
It's strange you have an error on Linux AND windows. I understand the logfile is from Windows
Detecting the ANT-dongle goes well; Tacx trainer is irrelevant (-s flag). I did not see a manufacturer=CYCPLUS ANT-dongle before, but that is not necessarily an issue.
The dongle responds normally untill 15:17:35,153 and then the message 15:17:35,627: devAntDongle.write exception: [Errno None] b'libusb0-dll:err [_usb_reap_async] reaping request failed, win error: Un périphérique attaché au système ne fonctionne pas correctement.' (Device does not work correctly)
Since some commands are received and responded correctly, basically your FortiusANT installation is OK and therefore it sounds like a driver issue. Cannot help you right now with this, perhaps somebody else following FortiusANT has a clue?
Just for my information; where are you located?
Hmmm... I read Iainhay's note on CYPLUS ANT-sticks: https://github.com/WouterJD/FortiusANT/issues/45#issuecomment-620065659 seems like bad news on this kind of dongles.
Just to jump in, I had similar issues as referenced by @WouterJD - it was an issue with the CYCPLUS dongles, I ordered these to help confirm it was or wasnt the issue and these worked straight away.
Not sure why the CYCPLUS ones don't work, I'm going to try and find out why and what the difference is but changing the dongles should solve the issue.
Alright, merci de vos réponses !
So the ant dongle are causing the issue, weird... Something I noticed is that the driver of the linux version of antifier is working properly (that said, is able to communicate with the other dongle). I will check tomorrow if the windows version works as well, if so we might have the beginning of an answer, if not I will have either to implement the serial interface for FortiusANT, or the 1902 head unit support for antifier. Probably which one is the simplest, I don't have much knowledge about ant or serial drivers tough ...
Anyway, if you want to experiment with these devices, I could get you an ssh server running, tell me if you're intrested !
EDIT : an article I got from googling a bit, for what it's worth 😄 : https://tacxfaqx.com/knowledge-base/cycplus-ant-stick/
The antifier code contains solutions for a serial interface (see antifier.py and search for posix). Since FortiusANT works on windows, linux, macOS, etc I am not very inclined to restore the serial interface because some dongles do not work correctly...
Unless somebody has a clear reason to do that and a solid condition when that interface should be used...
Yes, I can understand that. But anyway, following what was being said by the article, the dongle "zwift-side" may cause the same kind of issue, even if they seem to connect. I will try to investigate a bit further, since these little pieces of scrap aren't cheap nor quick to deliver ^^ but I might eventually end up buying another model...
I understand Elie, and I understand that ANT+ dongles may be difficult to get. I leave you to it to resolve the issue, but will limit effort for this issue.
Alright, thank you again for your advice ! I will try to post here the eventual results of my investigations, but for now I think I can consider this thread closed.
Just a thought: several ANT+ implementations add two (or more) '0x00' bytes after the checksum. Maybe some dongles need these additional dummy bytes?
I have just received two of these dongles.
The error I get is: 23:17:15,413: devAntDongle.read exception: [Errno None] b'libusb0-dll:err [submit_async] submitting request failed, win error: The device does not recognize the command.\r\n' 23:17:15,415: devAntDongle.write exception: [Errno None] b'libusb0-dll:err [submit_async] submitting request failed, win error: The device does not recognize the command.\r\n'
Adding the two null bytes after checksum (in ComposeMessage()) didn't help in my case.
Just a thought: several ANT+ implementations add two (or more) '0x00' bytes after the checksum. Maybe some dongles need these additional dummy bytes?
Antifier had two 0x00 bytes in every message and these did not make it to ComposeMessage() because there was no indication whatsoever why these 0x00's were there. Perhaps not smart after all; they will there for a reason. @totalreverse would you recommend to add these padding bytes? I have experience (and others) that ANT dongles "hang" and need full power-down-restart to get working properly again. Could that be related? Do 0x00 bytes give the dongles "space to breathe"?
Suggestions and hints welcome, and yes @mattipee I have read your test-result. Thanks guys!
FortiusANT.2020-04-28 06-53-43.log @WouterJD for visibility, here's the log from the start.
@WouterJD subject line to "CYCPLUS"
On Linux, I see "Pipe error" followed by many "No such device" errors. Note that in /var/log/messages, I see the ANT+ adapter reconnecting with a different numeric id. Also note that I appear to be able to restart FortiusANT repeatedly and it looks very much like every second attempt will succeed, and every other attempt will fail. I haven't checked that another device can read what the is being sent using the CYCPLUS, but FortiusANT doesn't always fail.
I wonder perhaps if it's worth implementing a three-retries approach to starting ANT+, certainly being defensive and failing and stopping automatically if there's nothing but exceptions.
Be my guest for a code-suggestion. It feels like programming around a faulty device, however, but I'm OK to adopt code when suggested.
PS. Perhaps an idea to log an issue in pyusb; I have the impression that they respond pretty fast. Perhaps they have a suggestion...
Hello again !
I have done some debugging on my side, and after having butchered your code to work with linux's serial interface, I was able to determine that the device return an error upon sending the event 4e (broadcast message). Here is the error message I got (deciphered with the ANT+ specification, not exactly sure of what I'm doing here...)
a4 : start
03 : size
40 : message channel
01 : channel number
01 : message id
09 : message code : EVENT_CHANNEL_COLLISION
ee : checksum
EDIT : it appears that the problem is found also with antifier, so I'm assuming that even if I was able to connect the two dongles using antifier, I wouldn't have been able to get them to run, since this message come after all the channel setup, and is used to broadcast data.... Again I'm not a specialist, this is only blind guesses and I might be wrong.
Please send the logfile as generated with -d127
PS, where are you from Elie? I like to know about the spread of FortiusANT and if you can, give me a ping on Strava: https://www.strava.com/athletes/2885978
@martingeraghty please join this issue (#67 closed)
Thanks for adding me to this thread @WouterJD,
It certainly looks certain that the CYPLUS ANT+ dongle has issues but it would be good to confirm that there isn't anything else under the covers related to the i-magic. I have attached a log file where I ran FortiusANT.py -m -d 127, my ANT+ dongle was not connected to the computer. You'll note that no speed or cadence info is received from the trainer. Have you tried to run in manual mode without the dongle Elie? FortiusANT.2020-04-30 09-11-26.log
Just to prove my point that the CYCPLUS dongle appears to be capable of working...
$ python3 pythoncode/FortiusAnt.py -s
14:23:51,803: Dongle - Using CYCPLUS dongle
14:23:51,803: Tacx - Simulated Trainer
14:23:51,804: AntHRM - Heartrate expected from Tacx Trainer
14:23:52,308: devAntDongle.write exception: [Errno 32] Pipe error
14:23:52,308: Tacx2Dongle() raised an exception, retries remaining: 3
14:23:54,853: Dongle - Using CYCPLUS dongle
14:23:56,886: devAntDongle.write exception: [Errno 32] Pipe error
14:23:56,887: Tacx2Dongle() raised an exception, retries remaining: 2
14:23:59,434: Dongle - Using CYCPLUS dongle
14:24:00,919: Ctrl-C to exit
14:24:00,919: Tacx - Simulated Trainer
14:24:00,966: Target=100W Speed=31.2kmh hr= 92 Current= 12W Cad= 89 r= 0 15
14:24:01,968: Target=100W Speed=32.9kmh hr= 88 Current= 48W Cad= 94 r= 0 15
14:24:02,970: Target=100W Speed=33.8kmh hr= 88 Current= 68W Cad= 96 r= 0 15
14:24:03,971: Target=100W Speed=34.1kmh hr= 92 Current= 75W Cad= 97 r= 0 15
14:24:04,972: Target=100W Speed=34.7kmh hr= 91 Current= 85W Cad= 99 r= 0 15
14:24:05,975: Target=100W Speed=34.2kmh hr= 88 Current= 87W Cad= 97 r= 0 15
14:24:06,977: Target=100W Speed=35.1kmh hr= 86 Current= 94W Cad=100 r= 0 15
14:24:07,977: Target=100W Speed=35.7kmh hr= 92 Current=103W Cad=102 r= 0 15
14:24:08,979: Target=100W Speed=35.0kmh hr= 85 Current= 98W Cad=100 r= 0 15
This retry-and-eventually-it-works approach works on my MX-19 Linux VM running on a server, but appears not to work on Raspberry PI 3 B+, or on Windows 7 Pro.
My CYCPLUS branch is here: https://github.com/mattipee/FortiusANT/tree/issue_65_cycplus
Edit: and it absolutely works, running GoldenCheetah on laptop with another dongle proves the CYCPLUS dongle on Linux server is connecting.
Wow, that is odd ! I never got it to work properly. Here is some more logging I have done, hope it helps...
So, I got a fresh install of FortiusANT on linux, and run it with -s -a -d 127
. What I got is
that. So the problem seems to be that Ubuntu tries to interfere with the device by binding it to the simple_serial driver. I had to disconnect it of the kernel by code, and even doing so the device becomes unresponsive after a reset (as shown in the previous log).
So I commented the reset happening during the calibration phase, and I got a
much better result. Unfortunately, as shown in the log file, the device stops sending back data after having received the first 4e
command (broadcast data), except for a weird error message (a4 03 40 01 01 09 ee
, which seems to be related to frequence overlapping, absolutely no idea what it means).
My guess was that the reset I removed had a functional utility, so I tried to get it back without causing the device to disconnect.
My solution was to connect to the dongle by using the serial interface it provided, which is exactly the same as the usb interface, only there is no collision with the driver anymore and a reset don't cause it to disconnect from the program. So here is the log I got. The format is different, I couldn't get the classic debug functions to work with serial, but we can observe the same behaviour as before : the dongle hangs after being sent the first 4e
instruction...
As know next to nothing about ant, I wouldn't try make conclusions, but I would guess either there is something that has to be taken care of about this instruction, that this device is requiring, or this instruction on this specific device is faulty. Honestly no idea :sweat_smile:
Yes, I tried to run FortiusANT with a simulated dongle and my real trainer, everything works perfectly, which is to be expected : I already coded some small games to work with the bike ^^
I am from France @WouterJD (which explain my poor english ^^) , and never heard about Strava. I will definitively take a look at it !
@mattipee have you been able to connect to zwift or similar application ? I also got the two dongles to connect in zwift, but since all the channel and connection stuff is already configured when the first call to 4e is done in code, it might be that the device is able to connect, but not to send data. I will check that since now I am able to reach this point too ^^
And here I am, hope some of that will be useful to you !
EDIT : Actually there is two similar error messages being sent back : a4 03 40 01 01 09 ee
and a4 03 40 00 01 09 ef
. Apparently the only thing that differs is the fourth byte, which is the channel number, following the doc. So maybe these to channels are conflicting each other. Not sure why this would happen since I don't know why there would be two channels in the first place, maybe you will be able to tell...
Great guys! Thanks for working on the FortiusANT software to get your trainer and dongle working!
Matty I gave your code a quick check; as soon as tested an OK I will certainly adopt. Let's discuss then, I see your fork and https://github.com/mattipee/FortiusANT/tree/issue_65_cycplus/pythoncode we'll have to dicuss how to integrate lateron!
Also I can post here the small code snipped to detach the kernel drivers from the dongle :
for config in devAntDongle:
for i in range(config.bNumInterfaces):
if devAntDongle.is_kernel_driver_active(i):
devAntDongle.detach_kernel_driver(i)
@ElDonad I didn't know there was a way to detach the driver in code - I've been moving kernel module .ko files out of the way so that they don't load. I'll give that snippet a try.
Have you got your serial code committed onto a branch?
When I got the CYCPLUS dongle working, I managed to get it hooked up to both SimulANT+ and GoldenCheetah. So it would definitely have worked in Zwift. Unfortunately now, on my server, every time it fails and before my retry, the USB redirection into the VM is throwing an error. Frustrating, but glad I recorded my partial success earlier... it IS possible... we WILL crack it... :)
Would be good to see the changes you're trying and the code you're testing out, Elie.
@ElDonad When I look in /var/log/messages (or similar), I see that the USB device disconnects and reconnects - and gets a different device ID each time. That used to happen inside my VM, it's now happening on my hosting server, which means the USB redirection fails because the device gets a new ID. I'm frustrated.
Oh ! Forget everything I said before, it totally works !
Seeing that you achieved to get it to work, I tried to connect it to zwift, and the usb version with the reset disabled totally works ! It eventually crashes at some point, not sure why, I will study the logs to try understanding more, but it totally works !
I would be glad to share with you my poorly written code of mine, give me some time to tidy it up a little bit and I publish my branch right away. Now I go back to log-studying, I get back to you when I have news.
@ElDonad Splendid!!! I made ResetDongle() do nothing and results were much better! No failures on six starts, but an eventual crash on the last when I left it for a bit.
Okay, so here is the first log I've got :
FortiusANT.2020-04-30 18-14-29.log
We can see that everything is doing fine until line 4697, where an Errno 32
spawns from nowhere and hangs the device. Absolutely no idea why it does that, but I will try to find out.
To cope with spurious errors, I guess my catch->raise->retry implementation on my branch could be used... the dongle will change device ID I think, and therefore you need to re-find it and re-initialise it... that should be able to be done during runtime, even if it requires some decoupling of stuff in Tacx2Dongle(). Good progress, though.
Ok, so as I suspected, the device eventually resets itself, we can see it through dmesg
. Not sure if it is software induced or a behaviour of the device itself, but when it happens it don't reconnect on the same usb pipe it was previously, which causes the program to crash. My guess is that we could detect theses disconnections with libusb and reinitialize the device on the fly.
So, same conclusions ! Perfect, the solution is near :smile:
I will take a look at pyusb, to see if there isn't a way to detect these crashes. We can however only hope that the setup process will be quick enough for the user not to notice the discontinuity...
Ok, so as I suspected, the device eventually resets itself, we can see it through
dmesg
. Not sure if it is software induced or a behaviour of the device itself, but when it happens it don't reconnect on the same usb pipe it was previously, which causes the program to crash. My guess is that we could detect theses disconnections with libusb and reinitialize the device on the fly.
Precisely what my retry loop does.
Using command line parameter -s (and no -g) as a quick way to test on multiple systems where I don't have real Fortius connected, I get the following good results:
With the Fortius attached to the Raspberry PI:
PS. A fairly comprehensive page on USB resetting, though I appreciate it's NOT resetting that we care about. Useful link perhaps anyway... https://askubuntu.com/questions/645/how-do-you-reset-a-usb-device-from-the-command-line, particularly as, if there's a device that seems to be locked and unable to be picked up when starting FortiusANT, then the .c program near the top works well to free it up and carry on... particularly as I'm in the house and my trainer/FortiusANT are running in the garage, and I don't want to go out just to unplug and re-plug a dongle.
Back, after I got my ubuntu screen back in the right oritentation (didn't tough there was an accelerometer in laptops :sweat_smile: )
Calibration with reset ? I noticed that the reset in the calibration made the device to hang...
By the way, I just tried to run the program without any sort of endpoint for the dongle (so it is emitting in the void), and it never crashes ! I don't know exactly what causes that, but it is definitely something weird...
Guys, just a thought:
SendToDongle(messages, ...): sends/receives messages to the dongle in a loop. Could it be that a short sleep(0.1) or so would give the dongle time and that the error would not occur?
I've just done a 40 minute test with CYCPLUS on a Raspberry PI 3 B+ probably crashed a dozen or more times - I was running my branch with a 3-retry loop, but if FortiusANT terminated completely, I could just run it again on the command line and keep riding. A little wobble as the 100W default kicks in and I guess it needs to wait for the next grade instruction from the controlling software.
But very happy that.
@WouterJD - I was wondering about whether a sleep would help - certainly the Reset() doesn't play nicely with the CYCPLUS - it may be that a strategic sleep might help but is it not on a 0.25 second period anyway?
Yes, there is a.25s cadence. But at times there are more messages to be sent and those are sent one-after-the-other. The messages are gathered in a list and the list is processed by SendToDongle() after every send a receive is done of which the answers are gathered in a list again. This is the original antifier setup and avoids that a series of 6 messages would cost seconds
In tehe CYCPLUS case it might be too fast
@WouterJD Not sure about this... I modified SendToDongle() to write each message multiple times in a row and it didn't seem to mind.
I'll see about doing some USB or ANT+ capture and see if there's anything peculiar around the times it drops.
Was just a thought
Could you please summarize what has been changed, retyr + detach etc. I've been looking through the issue but don't find it; I see antDongle.py is changed in your fork, please help forward so we can merge these solutions.
Note that I cannot test, not having this dongle nor unix.
The retry thing I'm not sure about yet.
The basic is to suppress ResetDongle() which I don't think I've committed yet.
Soon...
Wouldn't that be a simple solution!
After a solid afternoon of rounding up small issues, now going for some food :-)
Hello ! I have in mind since a few days to connect my old i-magic trainer to Zwyft, and I have bought two ant+ dongle (from Amazon, labelled CYCPLUS, id 0fcf:1008, Dynastream Innovation Inc.) and tried to run FortiusANT as well as antifier both on my linux and windows machine.
So far I haven't been able to run it successfully as I encountered several problems. Maybe would you have a clue about what it is ?
So, on linux the ANT didn't allow connection (errno 16: Busy) and I managed to overcome that by disabling the kernel drivers on code (basically copy-paste of https://stackoverflow.com/a/36505328). Now the ANT device is recognized as well as the trainer, but as soon as I click "Start" the console get flooded with read/write error (errno 30), happening directly after the dongle reset, from what I have been able to debug.
On windows the situation is the same, the ANT device is recognized as well as the trainer, but on clicking start I get this :
and then `SendToDongle write error, reaping request failed, win error : a device attached to the system is not functionning, and multiple ReadFromDongle read error.
So the problem seems to come from the dongle, however running antifier from linux, which from what I understand uses instead the serial interface of the dongle, I was able to connect from Zwyft to antifier (even if the head unit wasn't supported).
So here I am. I don't know what I could try next or event where the problem come from. Has someone any clue ? Thanks a lot in advance...