Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

writeRcChannel - Control CRSF Transmitters with CRSFforArduino #88

Open
1 task done
mawildoer opened this issue Mar 2, 2024 · 9 comments · May be fixed by #103
Open
1 task done

writeRcChannel - Control CRSF Transmitters with CRSFforArduino #88

mawildoer opened this issue Mar 2, 2024 · 9 comments · May be fixed by #103
Assignees
Labels
✨️ Enhancement ✨️ New feature or request ...in progress 🚧 Development on this is in progress
Milestone

Comments

@mawildoer
Copy link

mawildoer commented Mar 2, 2024

Is there already an issue for this?

  • I have searched the issues and there is no existing issue for this feature request.

Is your feature request related to a problem?

I'm working on a transmitter and CRSFforArduino seems so close.

I'm not alone: #80

Describe the solution you'd like

writeRcChannel, just like readRcChannel, but backwards!

Describe alternatives you've considered

Reading the internals of the ExpressLRS code to figure out how I might be able to jerry-rig something.
Using PPM control instead

Additional context

Great project! Thank you!

@mawildoer mawildoer added Pending 📌 This is waiting for me to check it out ✨️ Enhancement ✨️ New feature or request labels Mar 2, 2024
@ZZ-Cat
Copy link
Owner

ZZ-Cat commented Mar 2, 2024

Yea, as I said to the other guy what suggested this: This will be a fun thing to do.

Reading the internals of the ExpressLRS code to figure out how I might be able to jerry-rig something.
Using PPM control instead

Yea, nah. You definitely deserve a better implementation than CPPM (AKA PPM), that's for sure. That's a very old (and outdated) protocol, and for some, it can be unreliable.

In fact, you have given me an idea: Go the extra mile and do telemetry on the transmitter module side as well as the RC Channels.

@mawildoer
Copy link
Author

Beauty!

I'd vastly prefer a CRSF over PPM or otherwise. I came across this implementation earlier this evening, but it appears to be very early days for it and currently only supports the OG Arduino Mega2560: https://github.com/Sam4uk/CRSF

We are planning on embedding this ExpressLRS design in a project and want to control it via CRSF from a RP2040. I think this'd be the key to doing that right!

@ZZ-Cat ZZ-Cat added this to the Version 1.1.0 milestone Mar 3, 2024
@ZZ-Cat
Copy link
Owner

ZZ-Cat commented Mar 3, 2024

Beauty!

I'd vastly prefer a CRSF over PPM or otherwise.

We are planning on embedding this ExpressLRS design in a project and want to control it via CRSF from a RP2040. I think this'd be the key to doing that right!

Awesome! =^/.^=
I have added your request to the development pipeline, and it will show up in Version 1.1.0.
If you want to help out with testing this (I will tag you in the Pull Request, once it's created), you're very welcome to do so.

I have a couple of theories on how this could be implemented:

  1. New abstraction layer: serialTransmitterLayer where the API in this layer interacts with your transmitter module.
    It will be 100 % transparent with the sketchLayer, as is already the case with the existing serialReceiverLayer.
    To me, this is the most logical choice, as I am not creating any unnecessary work for myself. Plus, this option creates room for future expansion as CRSF for Arduino progresses towards its goals.
  2. Add the function you suggested to the existing serialReceiverLayer.
    This seems like the most straightforward option. However, later on, this option would wind up getting re-factored as the first option anyway, because the serialReceiverLayer is meant to (as the name suggests) interact with your ExpressLRS or TBS Crossfire receiver.

I came across this implementation earlier this evening, but it appears to be very early days for it and currently only supports the OG Arduino Mega2560: https://github.com/Sam4uk/CRSF

Interesting. 🤔
They may be targeting the legacy AVR platforms. I wish them the best of luck in their endeavours. Most AVR platforms have very tiny memory footprints (among other restrictive resource constraints). If they are able to pull that off, I have mad respect for them.
I read through their entire codebase and they have a long way to go, if their goal is similar to mine.
They may wind up facing the same challenges I faced, and arriving at similar conclusions to me. Especially if they have not (as the saying goes) "done their homework" on the protocol and its limitations... which looks to me that this is likely the case here.
I highly doubt they're aware an Arduino implementation of CRSF already exists (and has existed since January 28, 2023). They would actually see more benefit with contributing to my project instead. Especially if thar able to successfully get it to run on legacy hardware. 'Cause CRSF for Arduino could benefit from that. But, to each their own, and if their choice is to go their own way, well... more power to them.

The primary focus of CRSF for Arduino is with bringing The Crossfire Protocol in its entirety to modern Arduino targets and keeping the codebase up-to-date with the latest changes to the protocol itself and up-to-date with the latest hardware.

Quite some time ago, I wanted to look into the possibility of adding in AVR support on account of thinking that my preconceived views of the platform may either be outdated or incorrect... only to find that the minimum size of CRSF for Arduino exceeds the total available memory of most AVR platforms. As for the Arduino Mega2560, I don't have any reason to believe that a physically huge board like that (with mostly the same feature set as the ATMega328P chipset in the Arduino UNO R3) is practical for the applications that CRSF for Arduino is targeting. Especially when better alternatives for the same form factor exist, such as the Adafruit Grand Central M4 (which is based on the SAMD51P20, and is compatible with CRSF for Arduino).

While I am on the subject of AVR, here's the limitations I ran into:

  1. 16 MHz core clock.
    Right off the hob is that 16 MHz crystal oscillator. In theory, this does not seem like a limiting factor. However, in practice, it is. It affects the UART baud rate. The CRSFWG suggests a baud rate of at least 416,666. On an AVR target (say for example an Arduino UNO R3 with an ATMega328P), the actual baud rate may not be set to your requested baud rate (especially as you go higher up).
    If you set the baud rate to 416,666, your actual baud rate is significantly slower (somewhere around the 250,000~300,000 marks). This is even worse when you're using an AVR target that's operating on 3.3 volts. 3v3 AVR targets are commonly clocked at 8 MHz.
  2. Memory.
    An UNO R3 has 2 KB of RAM (for dynamic memory allocation) and 32 KB of flash memory (for firmware).
    The last time I compile-tested CRSF for Arduino on an UNO R3 (still a common target among entry-level makers, even in 2024), it well-and-truly exceeded the maximum available SRAM capacity. This is because CRSF for Arduino makes extensive use of dynamic memory allocation.

@mawildoer
Copy link
Author

All makes sense! I only suggested the writeRcChannel completely naively, what you're suggesting sounds functionally much much better.

I'm more than happy to share the debug notes from our bring up as well of course and will do my best to document it here.

I have nothing to do with Sam's CRSF project and have never interacted with him, so I'll leave that project going! I'm sure there's some reason he's doing what he's doing, but hopefully he comes across your awesome library and adopts it / contributes together as well!

@ZZ-Cat
Copy link
Owner

ZZ-Cat commented Mar 6, 2024

Sounds wonderful with what you're doing.
Yea, that would be great if he did. The more hands I can get onto this project, the better.

But, yea. In the upcoming release, there will be several refinements to my code-base in the name of improving reliability and doing away with any vulnerabilities that may be present.

I am still floating the idea of adding in AVR compatibility, because new information has come to light about CRSF for Arduino being able to successfully compile on older targets.

I tested this specifically with the Arduino Mega2560, Arduino UNO R3, and Arduino Micro.
The UNO R3 failed due to Serial1 not being present in that target, as it uses a UART-to-USB bridge on the existing HardwareSerial port. This is an easy fix, where all I need to do is tell the code-base that the default UART is Serial for the UNO R3 and not Serial1, which can be easily achieved with preprocessor defines.
The Micro was the only one that failed for the reason I thought was true for all AVR targets: Not enough memory. In the Micro's case, it was its SRAM that overflowed. Not the flash memory. Through my testing, I found that it was the Compatibility Table itself that overflowed the available SRAM by about 126 bytes.

I can see a need to get CRSF for Arduino working on legacy targets, because a lot of them are still in use today.
Since finding out that ExpressLRS gives you the ability to set a custom baudrate for your receiver, I don't see a reason why CRSF for Arduino SHOULD NOT break out the baudrate to the Sketch Layer.

@ZZ-Cat ZZ-Cat self-assigned this Mar 16, 2024
@ZZ-Cat ZZ-Cat linked a pull request Mar 19, 2024 that will close this issue
@ZZ-Cat ZZ-Cat added ...in progress 🚧 Development on this is in progress and removed Pending 📌 This is waiting for me to check it out labels Mar 19, 2024
@napowderly
Copy link

napowderly commented Mar 27, 2024

Hello! Curious how this is going and if I can lend a hand with any testing? The project we are looking to use this on is an opensource motion controller. If you are curious https://motionpilot.ch/

@ZZ-Cat
Copy link
Owner

ZZ-Cat commented Mar 27, 2024

Hello! Curious how this is going and if I can lend a hand with any testing? The project we are looking to use this on is an opensource motion controller. If you are curious https://motionpilot.ch/

I started up #103 shortly before I went on my hiatus. By the time I come back from it, this is the first thing at the top of my to-do list to get to work on.

Hardware testing is very welcome. Currently, there isn't anything in the code-base yet.
However, if your team could make yourselves known in the linked pull request, I will be able to keep you in the loop as I'm working on this.

Not gonna lie. This is going to be an amazing feature for CRSF for Arduino, and I am looking forward to implementing it and working with you to get it all working. =^/,..,^=

@DrJohannessen
Copy link

Hi, how is this going? Im working on something, and i would love to use crsf for it, and have used this wonderfull library before already to read a reciever. is there already somthing to test? and does it also support three wire crsf? as mentioned here: https://github.com/crsf-wg/crsf/wiki/Physical-Layer need to be done with this in june sadly so if this isnt done yet ill use lora, but great job! looks like an awesome library.

@ZZ-Cat
Copy link
Owner

ZZ-Cat commented Jun 23, 2024

Hi, how is this going? Im working on something, and i would love to use crsf for it, and have used this wonderfull library before already to read a reciever. is there already somthing to test? and does it also support three wire crsf? as mentioned here: https://github.com/crsf-wg/crsf/wiki/Physical-Layer need to be done with this in june sadly so if this isnt done yet ill use lora, but great job! looks like an awesome library.

Currently, I don't have anything available to test at this time.
By the way things are going, my primary focus with #103 is with the "internal transmitter module" as far as this goes.
According to my information, the physical layer there is no different to that of what's between the "receiver" and "flight controller". So, implementing the Serial Transmitter Interface for that is fairly straightforward.

I have shelved the S.Port version (AKA The "External Transmitter Module") of the Serial Transmitter Interface for the time being, until some time after I have the "internal" version working the way it's meant to. Implementing CRSF on one wire (making it half-duplex) is more involved than what I am already doing, and it could take significantly longer for me to write the code for.
So, to balance it out, that is why I have shelved it for the time being, and decided to focus on the full-duplex (AKA "internal transmitter module") version instead of trying to do both at the same time.

You have also reminded me why I do PSAs about when I need to take breaks and take time off of CRSF for Arduino (mostly to keep my mental health in check, and tending to other goings on in my personal life).
This time around, I didn't do a PSA (when I usually do), 'cause my intrusive thoughts (what were like "You don't need to write all that out. Nobody reads those anyway...") won out.

With a week left of this month, even if I picked up the project again, I would not have anything usable for anyone by the time the month is up.
It's unrealistic, at that point. It's also the reason why I don't do deadlines. No, seriously. All deadlines do for me is deadlock me (where I hyper-fixate on what little time I have left to do the thing) and by the time the deadline has passed, I have actually done nothing.

At this stage, I am picking this up again on the first Monday of July.

@ZZ-Cat ZZ-Cat added ...in progress 🚧 Development on this is in progress and removed ...in progress 🚧 Development on this is in progress labels Jul 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨️ Enhancement ✨️ New feature or request ...in progress 🚧 Development on this is in progress
Projects
Status: On hold
Development

Successfully merging a pull request may close this issue.

4 participants