ge0rg/aprsdroid

PTT by RTS or CAT?

yeti7 opened this issue ยท 64 comments

yeti7 commented

Hi, I'm Denis (K0TX) - a ham behind digirig project.
The interface's sound card works with APRSDrooid, but there is also a serial COM port that allows PTT by RTS signal or CAT with the capable radios. My question is if it would be possible to modify the code to allow these additional more reliable PTT methods?

skuep commented

A +1 from me as well... As far as I know, android has support at least for CDC ACM USB serial ports, but FTDI should work too!

I would just like to +1 this as well. It would be great to use aprsdroid without VOX.

+1 As well. If we could be pointed in the right direction I would love to help make this a reality.

+1 Just got my digirig and can now use my old Yaesu FT-60 as an APRS device with my Samsung Galaxy. Having to key the transmit manually is goofy when the digirig is exposing a COM port for PTT. Not sure if this is helpful, but the SoundModem software on Windows simply requires the PTT port to be selected and is able to key for APRS transmissions. Not sure if this is as simple to implement on Android but maybe it is?

I would be very happy to try and actually make this change if someone can point me in the right direction.

there 13 A pretty good write up in THE Read me file in the code repository. I've done some android dev work using the standard IDE but this app was written in SCALA which I haven't dug into.

@barryshaffer Can you link me the write up you're talking about. I'm probably being dense but I can't find it.

My naive guess is that we'd want to inherit from this object
https://github.com/ge0rg/aprsdroid/blob/master/src/backend/AfskUploader.scala#L66
and just wrap this one call in PTT on, PTT off. I'm sure there's a lot more housekeeping that would need to be done but in the spirit of ignorant hubris, it doesn't look that hard.

Hereโ€™s the read me:
https://github.com/ge0rg/aprsdroid#readme

I do tend to agree with you that the solution should be fairly straightforward. However, I donโ€™t have a scala environment set up to give it a try.

I compiled and ran it with android studio out of the box. Nothing external needed for adding scala.

ge0rg commented

Denis kindly sent me a digirig adapter that's currently on its way. From a practical point of view, @charlieb you are right, except for the housekeeping:

  1. you need to know when to use USB RTS, probably based on the vendor+device ID of the adapter or based on a setting value
  2. you need to connect via USB serial, which means you have to follow Android's USB attachment callbacks in the beginning, like done in https://github.com/ge0rg/aprsdroid/blob/master/src/backend/UsbTnc.scala#L55
  3. you need to track when the async audio output starts and stops, and trigger RTS accordingly

All in all I think this will become an ugly frankensteined combo of USB and AFSK backends, but I'll keep you updated :)

skuep commented

Thanks for all the effort. I kept thinking, maybe it would be easier to ditch PTT by RTS and settle on CM108-style PTT? It would involve sending USB HID Reports. That could be way more streamlined to implement, but I guess it's not compatible to the digirig?

@ge0rg are we to take it that you're going to take this ticket on yourself before us amateurs start deluging you with poorly thought out, half working, unformatted pull requests?

ge0rg commented

@charlieb I've been ultra-busy in the last *checks calendar* years, so I'm not going to promise an ETA on this feature. After all, I'm lagging behind fixing the OSM rendering since Android 12, and then some more. If you want to give it a try, or need advice, feel free to do so and to bug me with any issues you encounter. Fastest response times will happen on the APRSdroid xmpp room aprsdroid@chat.yax.im (webchat) btw.

@ge0rg Was never going to ask for a timeline, that's just rude. OK, so I'll take a stab at it. With you backing me up I feel a lot more optimistic about it. Thank you!

I compiled and ran it with android studio out of the box. Nothing external needed for adding scala.

Well dang, that just highlights my pedestrian level coding ability lol. Maybe I can just help Beta testโ€ฆ

Here is the src for a GPL licensed app that does RTS PTT for an example/ideas??
https://bitbucket.org/VK2ETA/radiomsg/downloads/
No idea if that would be remotely useful, but seeing as I'd also love to see PTT control in Aprsdroid, I'll risk it:)

@charlieb thanks for taking a crack at this. This is exciting as it will open up a lot of devices that don't have VOX for use with both APRSDroid and digirig. This is the one thing holding me back from purchasing the digirig mobile from @yeti7.

Edit: looks like somebody may have started this already? Not sure if it's useful or not: https://github.com/Swissman1/aprsdroid

Thanks, those links may turn out to be useful. I'm still at the "this looks like something I might need, I'll copy it, change the name and see if it still builds" stage, otherwise known as flailing.
I have forked and I'll probably make a commit tonight if I can get DigiRig to show up in the menus.
https://github.com/charlieb/aprsdroid

If RTS is problematic, a useful hack is to output a constant tone on one audio channel for PTT control, as implemented in FLDIGI for example. A circuit is required on the hardware side but it gets you real PTT control.

@charlieb I saw your fork, grabbed the code and put it in Android Studio to try an build an APK to test out. Ran into some errors trying that (Deprecated Gradle stuff). Admittedly I am way out of my lane with this stuff but wanted to give it a shot and see if it was functional enough to test. When it is ready, maybe I can help test since I am out of my depth with the rest.

Soo... sorry/not sorry for necroing this but would love to see this feature in a future release. (Not a coder so can't contribute that way but I have been told I give good shoulder massages!)

I wrote a POC commit to enable PTT via RTS in a forked repo here:

https://github.com/bxlentpartyon/aprsdroid/tree/usbtnc-ptt-rts

This is definitely not "good code" yet, and shouldn't be merged even if it works, but I think it does the right thing to some degree. My Digirig will get here tomorrow, so hopefully I can get this properly tested and write a real commit then.

As I review stuff here, I'm seeing that the audio output is probably asynchronous (decoupled from the packet send path), so my idea might be correct in spirit, but also might not actually work reliably/at all. The 50ms padding that I added might be enough to paper over my misunderstanding, but that doesn't make it correct.

Anyway, I'll look at this more when I can actually test it. Just wanted to point out my own mistake :)

I got my Digirig today and tried this out. With one more small tweak, I was able to eliminate the the behavior where the radio is keyed contintuously after the Digirig is initialized, and I'm able to see it key the radio when packets are transmitted. However, my traffic doesn't seem to be making it to the nearby digipeater.

To be clear, I'm doing this on a Baofeng, so it's super hard to say if the radio is the problem. I can say that I had APRSDroid working quite well on VOX mode with the BTECH APRS cable, but yesterday when I was playing with it, it was barely hearing any packets off the digipeater, and transmission was spotty/not working at all. FYI I do have a fairly decent homemade half-wave antenna hooked up, which the guys on the local repeater say sounds fine.

I did a bit of troubleshooting here on my own, by plugging earbuds into the audio port on the Digirig, and I'm not getting any sound when packets are transmitted. However, I don't know if this is even a valid test. I did get sound during transmission when I plugged my earbuds into the serial jack, but, again, I have no idea if that is a valid test.

Anyway, I'm pretty confident I can get this working, but I think I need a little help with troubleshooting here. @yeti7 @ge0rg is it appropriate to have that conversation here, or should I maybe post on the Digirig forum?

I'll add an additional note that when I tried hooking the radio up to the serial port jack on the Digirig (using the appropriate cable) the radio did key up during transmission, but it keyed off and on rapidly during transmission. If the serial jack/cable are the ones I should be using, then there might just be another layer of issues to debug here.

I did some more testing today, and I think (unsurprisingly) that something has gone funky with the radio. It was transmitting packets reliably with the AFSK/VOX setup last week, and nothing is making it out now, even when sitting right next to a local digipeater. I'm going to upgrade to a new HT and continue working there. Hopefully more to come in a week or so.

I got my new radio yesterday and got to work on this. It's ended up being a bit more complicated than I initially realized, but should be totally do-able. I worked on top of @charlieb's commit to produce this branch:

https://github.com/bxlentpartyon/aprsdroid/tree/digirig

I was able to get it to transmit packets, but RX isn't working yet. Probably partially because the code and branch are both super sloppy right now. Anyway, it's working to some degree. More soon.

Any progress on getting APRSDroid working with DigiRig?

I think my most recent branch actually works, but I was having a lot of problems with getting it properly tested. I had a few issues with my radios and the DigiRig, plus the nearest digipeater that I could hit isn't active any more, so I have to run my own in order to test this. I did get a setup working with a PC/direwolf, but I haven't quite gotten around to re-testing my APRSDroid build now that that stuff is working.

Anyway, if you are able to build my branch yourself, I'd encourage you to give it a try. If you can't build yourself, I might be able to get you an APK to test out - just let me know. Either way, I will try to put in some more time on this here soon, since there's still some interest in it.

If an APK is created, I would be very interested in joining the testing.. I don't have the capability to build the repo, but I do have a background in software testing, a digirig, and a strong interest in seeing this work!

+1 on the APK for testing.

Coming back to this with renewed interest after +1 the post back in 2022. Trying to get my Android Phone to link to the IC705 for SOTA spotting while on remote mountains. The IC705 USB sound interface just works on RX and works on TX too (if I manually press the PTT in FM-D mode) but the IC705 doesn't support DATA VOX so really keen to see a USB PTT of any kind (CAT or RTS/DTR). Thanks for the continued work! George M1GEO.

I have uploaded a test release APK here:

https://github.com/bxlentpartyon/aprsdroid/releases/tag/digirig-test-release-1

This code is still in WIP state, since I've not been working on it lately. Since there seems to be renewed interest in this, I'll try to get the branch cleaned up and into a merge-able state soon.

Tried to install the test release on my tablet and smartphone. Install starts, progress bar went up. Then it quit with "was not installed" message. No further info.
Is some additional library or something needed on the device? The latest version from Google Play Store installs and works perfectly.

Interest has always been here, we just thought it was being worked on and didn't wanna keep asking.. Tried the apk, and it won't download. Says package is invalid.

I think you need to allow your device to install unsigned APKs:

https://stackoverflow.com/questions/15743391/i-want-to-install-an-unsigned-apk-file-on-my-mobile-what-to-do

You'll also need to remove the original APRSDroid APK before trying to install this one. Note that if you have a bunch of settings configured in your app these might get wiped, so you might want to do this on an old phone or something just for testing.

I can (and will) generate a signed APK at some point, but this will only avoid the issue of needing to allow unsigned apps to be installed. Even if I provide a signed version, I believe you'll still have to remove the "official" version, as mine will be signed with a different key.

I did that. Did not work. I granted permissions to chrome and a local file browser to install unsigned .apk on two different devices. Downloaded the .apk on the Android device itself and tried to install a version, I downloaded on my computer and transferred via USB to the tablet and phone. Both without success.

Also tried to set up a working Android Studio to compile the code myself. But it seems to use a lot of old libs/tools, so it did not work either.

Yeah, building it locally wasn't trivial. IIRC the main thing is installing the older (Android 30?) SDK, but there were probably other things I did to get it to build. I could have sworn that I wrote a document about it, but I can't find it right now.

Anyway, I've uploaded a signed version of the APK to that release page for you to try. I don't know that it will work any different though, as it seems like there might be something else going on for you. Worth a shot at least. If the signed one (i.e. the one with the -release suffix) doesn't work, I imagine you'll have to check logcat to see what the actual install error is. We'll cross that bridge when we get to it though.

Screenshot_20240722_190142_Package installer.jpg

Gah! I have the paid Google Play option, so I suspect that this causes an issue, too.

George M1GEO.

The signed version installed like a charm and the Digirig seems to work with it now. Will test it on air now and give feedback later.

Gah! I have the paid Google Play option, so I suspect that this causes an issue, too.

Yeah, you will have to remove the official version to install my development version, as I can't sign my builds with the same key that ge0rg uses for the production builds. You can always go back to the official version later, but, as I mentioned, this will probably wipe your current config settings.

Great, thanks. I'll learn to read one day ;) Thanks for this, I'll try it out when I get home!๐Ÿ‘

It works! Did a quick local test from HT with Mobilinkd to FTM-6000 with digirig. Works reliable. Reached local digipeaters as well and received some position reports. Next up: APRS beacon over ISS. Wish me luck.

Is there an option to configure the delay between RTS/PTT and the actual transmission? It seems a bit long to me. The Frame-Sync-Prefix seems not to work. Is set to 200 (ms) and the radio is triggered ~1s ahead of the audio, I guess.

Very glad to hear it's working for you! I was fairly sure that it was actually working right, but my test setup has proven unreliable, and my nearest digipeater is no longer active, so I haven't been able to get solid confirmation on that.

Anyway, since it seems to be working for you, I'll clean up the branch a bit and submit a pull request sometime this week.

Is there an option to configure the delay between RTS/PTT and the actual transmission? It seems a bit long to me. The Frame-Sync-Prefix seems not to work. Is set to 200 (ms) and the radio is triggered ~1s ahead of the audio, I guess.

I feel like I might have hard-coded that because of some issues I was having (likely due to testing on a garbage radio). It should be easy enough to make it use the existing prefix delay. I'll definitely look at that before I submit a PR.

Thank you! This is a great improvement to APRSDroid!
I'm really really happy to have the setup working. Will use it in a ham radio course next week with some youngsters.

This works great on the IC705, too, And means that it is possible to send APRS frames JUST using a USB cable.

There is about 2.5 second of dead time before the AFSK starts and about 750ms after the AFSK finishes. It seems to miss transmitting any of the preamble (frame sync prefix). Changing the preamble time from between 0 and 1000 (milliseconds) doesn't change the length of the TX packet, so something isn't quite right there. Changing the preamble time does change length of the packet if you restart the tracking. But too short results in broken (missing the beginning) packets. If you make it too long (say, 1000ms), you loose the end of the packet. At least on an IC705. The trailing dead carrier confuses other stations since they think the channel is clear and TX over you - if the station replying is an ACK for a message, this does cause some protocol confusion. Around 750ms for me seems to make the AFSK payload end just before the carrier drops, resulting in all message ACKs being received.

That said, it's absolutely a great improvement. Thank you so much! This is super helpful, and I'll be giving it a blast on the weekend on my next SOTA :)

I'm remembering what the issue is here now. I hadn't quite figured out how to sync the RTS signal to the audio playback of the packet, so I've got this ugly code to calculate the length of time it'll take to play the packet, padded by two 1.5s sleeps:

DigiRig.scala:
	override def update(packet: APRSPacket): String = {
...
		ser.setRTS(true)
		val bits_per_byte = 8
		val bits_in_frame = packet.toAX25Frame().length / bits_per_byte
		val ms_per_s = 1000
		val sleep_ms = bits_in_frame * ms_per_s / 1200 // aprs is 1200 baud
		val sleep_pad_ms = 1500
		Thread.sleep(sleep_ms + sleep_pad_ms)
		val result = sendMessage(msg)
		Thread.sleep(sleep_ms + sleep_pad_ms)
		ser.setRTS(false)
...

This is sloppy but it does work (sort of). The main problem with this approach is that if your digipeater responds too quickly, you might miss the ACK of your packet. IIRC this was a big problem during my testing, as my personal digipeater (Baofeng in VOX mode with direwolf on a laptop) was reliably ACKing so quickly that my APRSDroid test rig would miss the ACK and keep retransmitting packets. So, it ultimately works, but you sometimes make a bunch of noise on the APRS frequency until you actually hear the ACK.

I really think I should fix this before merging. Otherwise, I'm going to be indirectly responsible for a bunch of noise on the APRS frequency. I'm going to look at this in the coming days and hopefully come up with a solution. Hopefully this will be a lot easier now that I have some testers to help out :)

Thanks for the tests and feedback so far. I'll be back with a new build sometime soon!

I edited my original message. Adding a TX preamble of 700ms ends the AFSK payload as the PTT de-keys, and even the fast digipeater works. However, this isn't the ideal solution and the code you have ignores the preamble time? Many soft modems just listen for the AFSK so dead carrier confuses them and they assume its CTS.

Very happy to test future builds - Feel free to ping me an email if you want a debug chat. Email on QRZ.com.

I have a CM108 adapter and hope to help enabling it for PTT by RTS control. I've tested the APK you published and, while it sees the USB adapter to connect, it doesn't seem to be working on my setup. I have testing the CM108 with a separate USB Serial App for Android and confirms that the RTS signal is working so it may just be a difference in the supporting library which I hope to investigate. I am able to compile your branch so I'll try working from there.

I've released a build of a significantly cleaned up version of my branch, with a first-draft attempt at syncing the RTS signal to the audio playback to avoid many of the issues encountered with my original build. This build runs on my device, but I probably won't be able to properly test it for a couple days. Thought I'd throw it out here for others with more reliable rigs to give it a try:

https://github.com/bxlentpartyon/aprsdroid/releases/tag/digirig-test-release-2

BTW, I looked into the issue with the frame prefix not getting transmitted properly: I double checked my code for that stuff and I think it's correct, but I hadn't really been paying attention to that in my previous testing, so it's totally possible something is actually wrong. Let me know if there still seem to be issues with that on this build and I'll look into it further.

I got too interested and decided to get out of bed to actually test this. I don't have my digipeater set up tonight, so I was just listening for the packet to come through with a different radio, but I can confirm two things: The RTS signal seems to actually be raised for the appropriate amount of time now (i.e. only during audio playback), and the preamble/prefix length seems to actually be respected now, so good news on both known issues at this point, AFAICT.

I'll try to test this more thoroughly on my own in the next week, but it would be great to get input from someone else too. The branch needs a bit more cleanup, but I think this is close to ready for a pull request ๐Ÿคž

I have this working perfectly with the digirig. Has anyone got it working with the AIOC?

Watching with interest. Does the APK have the latest updates?
Idle curiosity: wonder if yeti7 knows progress is being made relevant to their product..

Watching with interest. Does the APK have the latest updates?

Yes.

Idle curiosity: wonder if yeti7 knows progress is being made relevant to their product..

He has reacted to a few of the comments on here, so I think he's aware.

I broke down and ordered a second digirig so that I can actually test this myself, as my direwolf setup is not working very well with the clunky VOX solution. I think the new digirig will be here today, so I should be able to test it properly soon.

I trust @TheTypicalHam that it works, but I was seeing problems with my Yaesu HT that I want to debug a bit before merging. I'll likely submit a PR in the next few days.

I received my second Digirig today and did a good amount of testing. I believe this is in good enough shape to check in now, so I've opened the PR:

#382

I've also posted a build of the most recent code here:

https://github.com/bxlentpartyon/aprsdroid/releases/tag/digirig-v1

It's almost identical to the previous release I posted, so no need to re-test it if you'd already done so.

Briefly looking through the USB Serial library from felHR85 that is used by APRSdroid, I don't see any mention of ACM support which is the interface that the CM108 uses for AIOC. It's possible I missed it or am misunderstanding how it works, but that might explain why my earlier test of the pre-release APK published above was not able to control the RTS signal on my AIOC adapter. I took a look at the USB Serial Terminal app from the Play Store that I've confirmed does work with it and can toggle the PTT switch on my radio and it uses a different USB serial library at mik3y/usb-serial-for-android which clearly calls out CDC/ACM support in the README and driver source. Also the current library hasn't had a release for 5 years and only a small handful of unreleased changes since then. I might try swapping libraries and see if that improves support or not.

The AIOC supports either RTS&DTR or CM108 for PTT. ACM is the USB class for a serial adapter and on its own has nothing to do with CM108 (which is HID and not ACM).

Yes, I am aware that the HID interface can be used to control the PTT on the AIOC, but so can the RTS&DTR signals and those are provided by the ACM interface. That offers two different ways to control the PTT, but there is zero support for HID in APRSdroid and there is support for RTS&DTR being added to APRSdroid, it makes more sense to go for the latter in supporting for the control interface for PTT. CM108 actually has 4 different USB interfaces that it presents, USB Audio, HID, DFU for firmware updates, and ACM for serial port control. Finally, ACM is a standard interface used by a number of other serial adapters besides the mainstream FTDI and Prolific chips so this will increase the number of devices supportable than just the CM108 which using a unique HID interface as an alternative and not supported by anything else.

I was just trying to clear up some confusion in your earlier post:

Briefly looking through the USB Serial library from felHR85 that is used by APRSdroid, I don't see any mention of ACM support which is the interface that the CM108 uses for AIOC.

I have no experience with Android but given it is based on a Linux kernel, it shouldn't be hard to implement HID control. But that is beside the point here.

CM108 actually has 4 different USB interfaces that it presents, USB Audio, HID, DFU for firmware updates, and ACM for serial port control.

I am pretty sure that the CM108 has neither DFU not ACM. Are you confusing this with my AIOC project?

Finally, ACM is a standard interface used by a number of other serial adapters besides the mainstream FTDI and Prolific chips

I am pretty sure that FTDI serial devices have their own kernel driver and don't use the ACM kernel driver, thus I don't expect them to be supported by this. Correct me if i am wrong.

Btw, In terms of breadth of support, it would be wiser to implement CM108 style PTT via HID, because a lot of people are using this solution with the actual CMedia devices. And best part is, the AIOC would be supported as well, because it implements the same interface. (Other than the differing USB VID:PID of course).

The Linux kernel has support for HID but that doesn't mean that it's exposed in a way Android Apps can just use. I did not see anything in the Android API that would offer access to HID Raw devices, which is what would be needed here. That leaves implementing HID in userspace and using the barebones USB interfaces to control the device. While HID is pretty simple, it's not dead simple with the complexity of the HID Report parser that's needed and adds a bit of complexity over just extending RTS/DTR to one more device, in my perhaps not-so-humble opinion. :-)

As for the CM108, maybe I am confusing things. I thought the AIOC board is based on the CM108 chip. Maybe it's just implementing the interface that was created by the CM108, but in all my comments, I am referring to the AIOC board which is what I am trying to get working with this. The AIOC does implement all those interfaces I mentioned whether the CM108 does or not. If the goal is to just add AIOC support to this request, then implementing ACM seems to be the most straight-forward to me so it's just another serial port interface. I have already confirmed that I can control my radio via the AIOC using the RTS with a different USB Serial library that was developed for Android.

In my last comment, I was say to support ACM in addition to the main stream serial adapters that implement their own proprietary interfaces like FTDI and Prolific. I am well-aware that the USB-IF was slow on getting a standard out and we ended up with a bunch of common proprietary interfaces along with a vendor-neutral standard to deal with. The current USB Serial library in APRSdroid only seems to include support for these earlier, but well-established proprietary interfaces at the moment.

I have never heard of CMedia devices or CM108 prior to discovering the AIOC. But, I can imagine others implementing other devices that require ACM. There are a number of Arduino board with native USB (not FTDI) and therefore implement ACM so support for ACM, regardless of whether the AIOC uses HID or ACM, could be useful. Also, even if not for Audio+PTT control, the TNC interfaces can benefit from ACM support and be used with a full Arduino TNC.

The AIOC is much different than Digirig devices. Digirig offers the Digirig Mobile with a CM108 chip alongside a Serial Chip that are combined into one USB port. It's a great tool offering soundcard and Cat/Rig control over one USB port. There is also the digirig lite wich is only a cm108 chip with reliance on GPIO 3 for ptt. I have both as well as a homebrew of the digirig lite(basically a bare PCB with a transistor connected to gpio 3 and the ptt circuit of my radio) both work well with this cli utility on Linux (https://github.com/twilly/cm108)
This is a basic c implementation of hidraw write which might prove to be a fabulous starting point on how to add this functionality to APRS Droid. This would only fix compatibility with digirig lite and not the serial rts of the digirig mobile. That would still need another solution to add support for serial rts. There is already a branch (or fork? I can't quite remember.) of APRS Droid that supports this functionality and works quite well. I am testing it on my device now.

AIOC is an STM chip the emulates the hidraw support of gpio 3 that many other software supports. This means that if your software supports cm108 sound cards for ptt than the AIOC will work identically. It's a really smart way to bake in additional support for a new hardware standard by emulating a common homebrew/commercial product with more support.