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

[Request] Simplify Examples #658

Closed
2bndy5 opened this issue Oct 19, 2020 · 67 comments · Fixed by #691
Closed

[Request] Simplify Examples #658

2bndy5 opened this issue Oct 19, 2020 · 67 comments · Fixed by #691
Assignees

Comments

@2bndy5
Copy link
Member

2bndy5 commented Oct 19, 2020

Complex = overwhelming

Most people getting started with the nRF24L01 just need it to send data from 1 endpoint to another. The most basic GettingStarted.ino example does it both ways despite what the role variable is set to. This quickly leads to confusion about how the library should be used and how the transceiver actually works (especially since ACK payloads could be used to do the same exact thing only simpler).

Names are a guessing game

PingPair is not the most descriptive prefix to use in the example names. The first time I read it, I thought: "'pair' like in Bluetooth?" -- nope, its 'pair' like 2 devices used for 1 sketch. In fact, the most identifying part of the examples' names are abridged suffixes that require more intimate knowledge of the nRF24L01 features. e.g. "dyn" for dynamic payloads, "int"/"irq" for interrupt requests, "ack" for acknowledgment payloads... The names should be changed so that anyone can accurately guess what they're clicking on in Arduino IDE's example menu. e.g. "pingpair_dyn" to "RF24_dynamic_payloads", "pingpair_ack" to "RF24_acknowledgment_payloads"...

Laziness over physical interaction

Some examples use a digital input pin to manipulate the role variable (or even a specific feature like multicasting). Most programmers would rather be lazy (myself included). Getting up and walking over to a breadboard that's connected to the computer just to plug or unplug a wire connected to the role_pin is counterproductive. We should stick to adjusting a variable in code (or via a Serial Monitor applet) rather than using a physical GPIO pin. I understand Arduino IDE doesn't allow saving changes to examples, but it does instantly offer the option to save any modifications to an example in the default "sketches" folder (which actually helps the end-user start adapting examples to fit their desired application).

Quantity is harder to maintain

There's soooo many examples. I tried to start formatting them according to this repo's contributing guidelines, but it is overwhelming how much work needs to be done. I think there are actual duplicate examples (and even outdated file formats like *.pde files) that could be deprecated or consolidated. I can appreciate the separate folder for Linux examples, but the same problems discussed above still apply.

Inconsistencies

I found an example with different pin numbers used (as compared to most of the others). Obviously, it would be easier to upload/try different examples without having to change the wiring.

@Avamander
Copy link
Member

I understand Arduino IDE doesn't allow saving changes to examples, but it does instantly offer the option to save any modifications to an example in the default "sketches" folder (which actually helps the end-user start adapting examples to fit their desired application).

There's always serial communication that can be used for on-the-fly configuration. If written well, it's very nice to use.

@2bndy5
Copy link
Member Author

2bndy5 commented Oct 19, 2020

Yes. I agree entirely. I just mentioned that as the IDE hasn't always offered to save the modifications to the sketches folder

@2bndy5
Copy link
Member Author

2bndy5 commented Oct 20, 2020

Big thanks to @per1234 for leading me to a GitHub workflow we can use to compile all the examples for multiple boards. I made a preliminary attempt to test most of the boards in the AVR architecture, and here are the results. All boards failed compiling some examples while they succeeded compiling most of the examples. I will create another issue to discuss the development of the workflow(s), but I'm posting the first results here to show which examples need attention.

@per1234
Copy link
Contributor

per1234 commented Oct 20, 2020

I'm glad if it is able to be of use!

This type of failed compilation:
https://github.com/2bndy5/RF24/runs/1279647104#step:4:51

  Error during build: opening sketch: no valid sketch found in /github/workspace/examples/Usage/led_remote: missing led_remote.ino

Is caused by a bug in Arduino CLI. Evidently there was a regression that caused support for the .pde sketch extension to be lost. I've submitted a bug report about that. Until the bug is fixed, you could work around it by specifying the 0.12.1 Arduino CLI version via the arduino/compile-sketches action's cli-version input (Arduino CLI 0.12.1 was the last version that supported the .pde sketch extension).

- name: Compile examples
  uses: arduino/compile-sketches@main
  with:
    fqbn: ${{ matrix.fqbn }}
    cli-version: 0.12.1

I didn't take a close look at the other failed compilations. If you discover any issues, please let me know. I am also happy to provide some advice on how to configure workflows if you need to exclude some sketches from compilation from some boards. I seem to run into that challenge in most of the workflows I've set up.

@2bndy5
Copy link
Member Author

2bndy5 commented Oct 20, 2020

If you discover any issues, please let me know. I am also happy to provide some advice on how to configure workflows if you need to exclude some sketches from compilation from some boards.

@per1234 It was a tremendous lead! I'll try my best not to abuse you on that offer (definitely going to check the applicable docs first).

@2bndy5
Copy link
Member Author

2bndy5 commented Oct 21, 2020

Ok, I fixed all the build errors, but I had to move the "rf24tiny" folder out of the examples into the root (renamed it "examples_attiny"). I also had to move the "pingpair_maple" into its own folder named "examples_maple" (also located at root directory). I also changed the pde file types to ino instead of rolling back the version for the Arduino CLI per @per1234 suggestion (these now compile successfully).

Time to start actually addressing this issue...

EDIT: I found a way to specify certain examples within the arduino build job's compile-sketches action. So, I reverted the structure to what it was originally, but pde files are still ino files. The only examples having trouble compiling are still maniacBug's "pingpair_maple" & tong67's "timingSearch3pin" which are both board-dependent anyway.

@2bndy5
Copy link
Member Author

2bndy5 commented Oct 21, 2020

here is what I'd like to reduce the numerous examples to:

  • GettingStarted
    • using only library defaults
    • TX: ping slave repeatedly with an incrementing float (using a float will also demonstrate the platform's capability of handling floats)
    • RX: dump received data to serial monitor
    • roles reversed via serial monitor
  • AcknowledgementPayloads
    • TX: "Hello<counter>"
    • RX: "World<counter>"
    • roles reversed via serial monitor
  • StreamingData
    • TX: stream 32 payloads at a time, each with lengths' maxed out; use partial blocking to fill FIFO -- I'm picturing an ASCII art hour glass as payloads
    • RX: dump received data to serial monitor
    • roles reversed via serial monitor
  • InterruptConfigure
    • TX: use ACK payloads to demonstrate IRQ "data sent", IRQ "data ready", & IRQ "data fail"
    • RX: fill FIFO then stopListening() & dump FIFO to serial monitor
    • roles reversed via serial monitor
  • MulticeiverDemo
    • TX: let payloads carry an identifying "origin ID"; specify a node number in range [0, 6] from serial monitor -- think "star" configuration.
    • RX: dump received payloads to serial monitor. Use char "Q" to exit role from serial monitor; selectively send payloads tally as ACK to node 1.

All examples' TX nodes should print a transmission time result (when successful), except for InterruptConfigure & MulticeiverDemo example.

All library-specific code gets explanatory comments as terse as necessary -- loops, global functions, and if statements also get a brief description if not painfully obvious from scoped comments or typical program structure (like setup() & loop()).

A link to the docs should always be provided as a general reference, but only following copyright/author/license info.

### Less is More
In the introductory comment block that explains the example purpose, each example should pose a [singular] challenge for the user to solve. As programmers, we should all be familiar with this method of learning (either through school/work assignments or insatiable curiosity).

@2bndy5
Copy link
Member Author

2bndy5 commented Oct 24, 2020

@Avamander you still interested in that BLE example? Just thought about it while I'm writing the new ones. Remember the payloads are limited to 18 bytes max.

Your broadcast options are:

  1. A URL (6 bytes + URL length). Eddystone protocol is typically used to reduce some URL parts to 1 byte. e.g. http://www.google.com gets reduced to 0x00google0x07
  2. A battery service (5 bytes)
  3. A temperature service (8 bytes)
  4. A device name (2 bytes + name length)
  5. The nRF24L01's PA level (3 bytes) -- only useful for BLE scanner apps to calculate proximity

If you find a GATT service that doesn't need to be claimed by a GATT property and doesn't require GATT characteristics, let me know. I'm ruling out location/navigation because the service data won't fit. And I've already tried the Time service (needs to be claimed by a GATT property).

Please don't say "all of the above"; that would require a full fledged class. I'm not supporting receiving BLE payloads either.

@Avamander
Copy link
Member

Implementing one is good enough as an example.

@2bndy5
Copy link
Member Author

2bndy5 commented Oct 24, 2020

Ok, a name of "nRF" with a battery and temperature data should max out the payload's size. This would also be the most useful configuration for those "copy-and-paste kings/queens" out there.

@2bndy5
Copy link
Member Author

2bndy5 commented Oct 28, 2020

@Avamander I am at my wit's end with the CRC24 calculation for the BLE example. The result doesn't match with what I'm expecting (comparing to my python's crc24_ble() output which does work). I've literally copied from the article posted by Dmitri and also tried copying the code from BTLE library. But, no joy with either. I think I'm fighting an endianness problem, and I'm not above asking for help (this was the toughest part when implementing fake BLE in circuitpython). If you want to look at it, I can give you the code. Otherwise, I'm putting the BLE example on the backburner for a while...

@2bndy5
Copy link
Member Author

2bndy5 commented Oct 28, 2020

ok I've added another example called ManualAcknowledgements in which it uses a call-and-respond paradigm without using ACK payloads. This new example and the MulticeiverDemo demonstrate the use of different addresses on different pipes.

I'm ready to call this issue satisfied... PR is coming soon.

@2bndy5
Copy link
Member Author

2bndy5 commented Oct 28, 2020

Damn I forgot about the Linux examples. I should test that my changes still work on the RPi (just received an RPi4 -- so I may have to bug hunt some of the issues for that hardware) before the PR. I'm assuming there's no objection to re-writing the python and other examples in the Linux folder.

@TMRh20
Copy link
Member

TMRh20 commented Oct 28, 2020 via email

@2bndy5
Copy link
Member Author

2bndy5 commented Oct 29, 2020

Sounds great. I also have a RPi2 (why I updated), but the radio is hardwired to different pins. 1 reason I don't like this library on Linux is the requirement to use one of the CE pins for the nRF CSN pins...

@TMRh20
Copy link
Member

TMRh20 commented Oct 29, 2020 via email

@2bndy5
Copy link
Member Author

2bndy5 commented Oct 30, 2020

ok, let me say that I'm just now realizing that I've never actually written a C++ program for linux. The main reason I got drawn to this project is so I could use my knowledge about the nRF24L01 to brush up on my C++ skills (assuming that wasn't obvious 😟 ).

I added a micros() function to the "compatibility.h" & "compatibility.c" files for several drivers that already offered millis(). I'm doing some preliminary testing on the RPi4 using the SPIDEV driver, and it compiles and executes without complaints. However, I noticed that the github workflow that builds the library (& also Linux examples now 😄 ) is complaining about my micros() call. It suggests micros (without parenthesis) as an alternative, so I think I'm just not #includeing the right source file(s) to "scope" the new micros() function. Is there something I'm missing? I don't see where millis() is declared in the "utility//RF24_arch_config.h" file (the ATXMegaD3, MRAA, SPIDEV, & template drivers now have a micros() defined).

p.s. I needed the micros() function to adequately measure the transmission time in my new gettingstarted.cpp example for linux; otherwise transmission times would report 0-2 ms (which is so much less accurate than the Arduino GettingStarted example). I looked into hardcoding a micros() based on "sys/time.h" for Linux, so I guess I could try that. But I just thought micros() would be a good idea to provide via the build process; I'm not against undo-ing the micros() addition in this regard as it is only needed for the exeample(s).

@Avamander
Copy link
Member

You declare only long __micros(); in compatibility.h when you're calling micros(), that's why.

@2bndy5
Copy link
Member Author

2bndy5 commented Oct 30, 2020

but I've got #define micros() __micros() in "RF24_arch_config.h" or does that not matter?

@Avamander
Copy link
Member

Depends on the order you include files. It's the reason why it's usually not a fun idea to rename functions like that.

@2bndy5
Copy link
Member Author

2bndy5 commented Oct 30, 2020

usually not a fun idea to rename functions like that.

you ain't kidding.

just to clarify, I haven't renamed anything. I just copied the millis() definitions and adjusted them to output microseconds instead. Notice that the old linux example gettingstarted_call_response.cpp also called millis() and that has no problems.

Should I start tracing the include order or just custom define micros() within the examples?

@Avamander
Copy link
Member

Avamander commented Oct 30, 2020

Should I start tracing the include order or just custom define micros() within the examples?

Option B is more reasonable assuming you can't just define micros() in the compatibility file. If micros() is a taken name, you could use rf24_micros() and be done with it.

@2bndy5
Copy link
Member Author

2bndy5 commented Oct 30, 2020

thanks (as always). As a side note, it turns out the delay() call in the old gettingstarted.cpp example was what was throwing errors in the build_linux workflow for wiringPi. As I'm re-writing the examples for linux, I can probably close #669 as it no longer applies with the new examples 😄

@Avamander
Copy link
Member

Yeah, just write "Fixes #669" in your PR and when it gets merged, the issue gets closed.

@Avamander
Copy link
Member

I'm currently on my phone and can't check, but this is also a perfect moment to fix any -Wall -Wpedantic errors.

@2bndy5
Copy link
Member Author

2bndy5 commented Oct 30, 2020

?? in the makefile? or the configure file? are you trying to reference #642? I am so bad when it comes to the gcc flags (why I fell completely silent in #642 )

@2bndy5
Copy link
Member Author

2bndy5 commented Nov 25, 2020

I'm in the process of adding CLI args -r/--role & -n/--node to the Linux examples (C++ & Python).

Question: Do we want to exit example after specified role is complete?

  • Currently the examples' roles returns to setRole() when the role expires
    • TX role stops after 6 non-consecutive failures (streamingData example stops at 100 non-consecutive failures)
    • RX role stops after 6 consecutive seconds of no incoming payloads

If unanswered, I'll assume the answer is "yes", but the startup time for the examples is significant (> 100 ms).
BTW, if only the -n/--node arg option is specified, then the example simply skips the "Which radio is this?" prompt and goes straight to setRole().

@2bndy5
Copy link
Member Author

2bndy5 commented Nov 26, 2020

ok I'm think my fork's master branch is ready for a PR. All examples seem to be working on arduino, python, and Linux. I just want to test on more devices. So far I've been developing on an arduino nano & RPi4. I want to try the Digispark ATTiny85 (examples for the rf24_ATTiny folder now compile for the SpenceKonde ATTinyCore), Adafruit Feather M0, and my RPi2B+.

HINT: Use -h or --help to see the manpage for examples. All examples use the same arguments (-n/--node & -r/--role) except the MulticeiverDemo (which only takes a -n/--node arg). The manpage should be explanatory enough, but I'm open to expanding on details if needed.

@TMRh20
Copy link
Member

TMRh20 commented Nov 27, 2020

Just running the c++ gettingstarted sketch on Arduino and RPi3 and am noticing a few issues:

  1. Over SSH, (only when receiving) the call to radio.powerDown(); seems to cause the call to exit(0); to hang? Removing it clears up the problem. No idea why.
  2. The output on RPi seems messed up, shouldn't it be 4-bytes and the payload value?:
Received 6 bytes on pipe 1: 0
Received 6 bytes on pipe 1: 0
Received 6 bytes on pipe 1: 0.175778
Received 6 bytes on pipe 1: 0.476555
Received 6 bytes on pipe 1: 0.499785
Received 6 bytes on pipe 1: 0.703111
Received 6 bytes on pipe 1: 0.933333
Received 6 bytes on pipe 1: 0.99957
Received 6 bytes on pipe 1: 1.62104

Arduino:

21:11:51.970 -> *** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK
21:12:07.071 -> Received 4 bytes on pipe 1: 0.00
21:12:08.062 -> Received 4 bytes on pipe 1: 0.01
21:12:09.101 -> Received 4 bytes on pipe 1: 0.02
21:12:10.088 -> Received 4 bytes on pipe 1: 0.03
21:12:11.111 -> Received 4 bytes on pipe 1: 0.04
21:12:12.102 -> Received 4 bytes on pipe 1: 0.05

  1. The RPi in RX mode was skipping ahead, receiving many payloads at once. I haven't diagnosed the problem, just going through some of the tests.
Received 2 bytes on pipe 3: 6.46721e+19
Received 2 bytes on pipe 3: 6.46721e+19
Received 2 bytes on pipe 3: 6.45998e+19
Received 6 bytes on pipe 3: 6.46721e+19
  1. I'm not so sure about the cli args, especially being used in the gettingstarted sketch. It kind of seems like a beautiful "hello world" sketch that is 1000 lines long. It seems neat enough in python, but in C it seems kind of ugly!?

I think there is still a bit of debugging and testing needed.

@TMRh20
Copy link
Member

TMRh20 commented Nov 27, 2020

Err, #s 2 and 3 appear due to a loose connection. Disregard.
Will continue playing around with these examples.

@2bndy5
Copy link
Member Author

2bndy5 commented Nov 27, 2020

I was going to suggest trying a slower SPI speed on your RPi. I've seen a similar problem using jumper cables that were longer than 3 in (or > 76 mm) and resulted in receiving "ghost" bytes that were never sent.

Removing it clears up the problem. No idea why.

I don't get this problem on RPi4, so I'm totally reliant on your advice here. Does it still exit the program when you removed exit(0)? I'm also using SSH.

About problem 4: I looked into argp.h getopt(), and getopt_long(), but the code to use just 2 args was A LOT more. Python looks neat because its using a std python library to handle parsing the cmd args. Suggestions?

@TMRh20
Copy link
Member

TMRh20 commented Nov 27, 2020

I'm using a small adapter with no wires for the RPi3, (unplugged it to reset the radio) and I assumed it was on there tight.

Removing the powerDown command is waht does it... the SSH session keeps accepting input, but I can't CTRL+C out of it or anything, so I'm thinking something about unfinished tasks or something I read regarding the exit() command.

I don't know about problem 4. My original suggestion was to use args only for one example for testing purposes, kind of a single example that does everything depending on what commands it is given. That would leave the main examples a bit simpler, but alternately we could just use the args in the examples other than the main gettingstarted sketch too. Not sure, just that it definitely overcomplicates gettingstarted and we should leave at least one as simple as possible.

@2bndy5
Copy link
Member Author

2bndy5 commented Nov 27, 2020

If you look at multiceiverDemo.cpp, you'll see that it only takes 1 arg (which simplified the code a bit), but the expected -n/--node arg needs to be the first arg specified. I'm ok with removing cmd args from all but streamingData and multiceiverDemo examples. It would mean less maintenance that way also. Would you want me to remove args from corresponding python examples too?

@2bndy5
Copy link
Member Author

2bndy5 commented Nov 27, 2020

what SSH app are you using? I use the openSSH console app installed in windows (or maybe it was added with visual studio).

@TMRh20
Copy link
Member

TMRh20 commented Nov 27, 2020

I'm still going through the examples one at a time. I'd like to see how it all works together before trying to decide.

Using Putty. Still does it if I SSH in from another RPi:

*** PRESS 'T' to begin transmitting to the other node
*** PRESS 'R' to begin receiving from the other node
*** PRESS 'Q' to exit
r
^C Interrupt signal 2 detected. Exiting...
^CsrfasdfWTF OVER???

@2bndy5
Copy link
Member Author

2bndy5 commented Nov 27, 2020

the whole point of catching the keyboard interrupt was to keep the radio from listening when running the same examples (using the same addresses) on another pair of radios. What RPi version is this happening on? It probably isn't putty, rather more specific to the SSH target device.

@TMRh20
Copy link
Member

TMRh20 commented Nov 27, 2020

Replicated on Pi 3 Model B Rev 1.2 and Pi Model B Rev 2, both are up-to-date on software etc.

@TMRh20
Copy link
Member

TMRh20 commented Nov 27, 2020

I put a radio.isChipConnected(); call before the cout command, and it doesn't print anything, leaving me to believe it is the call to the radio in the interruptHandler that hangs the program. The exit(0); command isn't even being called.

@TMRh20
Copy link
Member

TMRh20 commented Nov 27, 2020

With the AcknowledgementPayloads example, could it be made more like the ManualAcknowledgements example in the counting? Like the receiver increments along with the sender?

I noticed on Arduino so far, the first payload is blank, which shouldn't be the case if the ack payload is written before receiving happens, which it appears to be? I'll look closer at that one later. It looks like just putting the startListening call before writing the ack payload is all that is needed:

https://github.com/2bndy5/RF24/blob/master/examples/AcknowledgementPayloads/AcknowledgementPayloads.ino#L102
https://github.com/2bndy5/RF24/blob/master/examples/AcknowledgementPayloads/AcknowledgementPayloads.ino#L204

The other examples all work seamlessly on Arduino, I didn't really look too closely at the code because they just worked exactly as expected.

@TMRh20
Copy link
Member

TMRh20 commented Nov 27, 2020

I guess I forgot the InterruptConfigure example which also needs radio.startListening(); called before writing teh ack payloads

@2bndy5
Copy link
Member Author

2bndy5 commented Nov 27, 2020

It looks like just putting the startListening call before writing the ack payload is all that is needed

Is this behavior from the Si24R1? I don't have this problem with the nRF24L01. If so, I wonder if flush_tx() actually works from RX mode (or vice versa) because of the diligent copy from datasheet misprints when cloning the OG.

With the AcknowledgementPayloads example, could it be made more like the ManualAcknowledgements example in the counting? Like the receiver increments along with the sender?

I tried to do this, but it seems as though the incrementing lags behind a couple tranmissions when the incoming counter differs from the initial outgoing counter. This is a change I tried to do recently. Last time you tested it the AckPl example actually incremented separate counters (without saving the incoming counter at all). I'm rather inclined to leave this flaw as is to demonstrate the 1 major disadvantage of using AckPls.

leaving me to believe it is the call to the radio in the interruptHandler that hangs the program

This makes me think it is a threading issue. I will remove the use of signal.h, but if one does ctrl+c during the linux examples' RX role, it would be preferable to run the example again (without args), then ctrl+c when prompted with the "Which radio is this?" prompt to ensure the radio is not in RX mode any more.

@TMRh20
Copy link
Member

TMRh20 commented Nov 27, 2020

As far as I know I don't have any Si24R1, just nrf24 clones. The payloads should be flushed during a call to startListening(), so if it works for you calling startListening() after writing the acks, then I suspect your devices are behaving oddly. The flush_tx() call should clear them all.

@2bndy5
Copy link
Member Author

2bndy5 commented Nov 27, 2020

Notice that I removed that limitation on startListening() per #654 proposal. I've never had a problem loading ACK payloads while still in TX mode (before calling startListening()). I will make the changes to the examples if that solves the problem.

another reason I like developing from python is so I can test this problem in realtime

@TMRh20
Copy link
Member

TMRh20 commented Nov 27, 2020

Hmm, there was a reason for it that was exposed using the previous examples if I remember correctly. I think the tx payload buffer should be flushed for some reason when switching between modes. I'll have to "play around" some to see if this is still an issue.

Hmm, I guess I neglected to update the library itself on Arduino, I've just been running the examples, so I'll have to get everything in order for more testing with all of your code.

@2bndy5
Copy link
Member Author

2bndy5 commented Nov 27, 2020

BTW, stopListening() still flushes the TX FIFO if AckPls are enabled (as it always has). Previously, startListening() only flushed the TX FIFO if AckPls were enabled, so I assumed it was because the datasheet said the SPI cmd W_ACK_PAYLOAD is meant to be used only in RX mode. However I found it beneficial to be able to "prime" the TX FIFO before switching into RX mode. If there was another reason for this limitation, I'm open to reverting the limitation.

@2bndy5
Copy link
Member Author

2bndy5 commented Nov 27, 2020

old examples now reside in my fork's "examples/old_backups" folder. The following old examples have been removed as duplicates:

  1. GettingStarted_CallResponse (duplicate of ManualAcknowledgements)
  2. GettingStarted_HandlingData (duplicate of ManualAcknowledgements & the main idea is also used in MulticeiverDemo & AcknowledgementPayloads)
  3. Transfer (duplicate of StreamingData - though Transfer uses randomly generated 32-byte payloads and different settings like channel 1, 2 Mbps, & CRC8)
  4. pingpair_ack (duplicate of AcknowledgementPayloads)
  5. pingpair_irq_simple (duplicate of InterruptConfigure, but not as insightful about maskIRQ())
  6. starping (duplicate of MulticeiverDemo)

The "examples/Usage" folder has been renamed to "examples/old_backups/recipes" as the sketches in this folder were more hardware dependent rather than focusing on just library usage. Additionally, most of the store links to the hardware referenced in ManiacBug's blog posts say that the hardware isn't offered anymore. Also, I've never heard of a "Maple" MCU board, so I'm not sure if that's still a thing...

The following old examples still reside (in "examples/old_backups" folder) because they still seem somewhat relevant:

  1. GettingStarted_HandlingFailures
  2. TransferTimeouts
  3. pingpair_dyn
  4. pingpair_irq (also fixed this one to address pinMode(IRQ_PIN, INPUT) needed in examples #680 )
  5. pingpair_multi_dyn
  6. pingpair_sleepy
  7. scanner

I didn't do an example about dynamic payloads (except for when ACK payloads are used) because usually a programmer knows what to expect in the payloads' content (including the length required to contain the contents). Nonetheless, pingpair_dyn (basic dynamic payloads) & pingpair_multi_dyn (multicasted dynamic payloads) are still available.

MulticeiverDemo is the only new example that uses a uint64_t address instead of c-strings. You may actually recognize the addresses in MulticeiverDemo from those used the datasheet's figure 10 & 12 (about multiceiving with ShockBurst & EnhancedShockBurst respectively).

@TMRh20
Copy link
Member

TMRh20 commented Nov 28, 2020

If there was another reason for this limitation, I'm open to reverting the limitation.

I can't seem to easily identify any issues with not flushing the tx fifo on startListening(). I'll just keep this in mind in case anything comes up, but I'm good with it as you have it.

I think that clears up most issues with the examples. I've run through a bunch in c++ and python in Linux and am having problems finding anything else to complain about.

@TMRh20
Copy link
Member

TMRh20 commented Nov 28, 2020

I'm ok with removing cmd args from all but streamingData and multiceiverDemo examples. It would mean less maintenance that way also. Would you want me to remove args from corresponding python examples too?

Ok, lets do that to keep things simple as possible. I'll leave it up to you on the python examples, I'm good either way.

@2bndy5
Copy link
Member Author

2bndy5 commented Nov 28, 2020

Done.

I have to admit, I immediately liked the ability to skip past the prompts & get straight to testing the behavior I wanted. I'll leave the python examples as is (they'll probably get touched up again when pyRF24 repo gets more attention). Maybe in the future we can devise a header file that does what python's std lib argparse does but for the cpp examples. Like I mentioned before, GNU C library's argp.h lacks the intuition to make it a useful tool. (e.g. auto-generated man page & automatic handling of invalid options).

I'll give the examples another round of testing and then open a PR 🎉 that summarizes all the issues I've addresses.

@2bndy5
Copy link
Member Author

2bndy5 commented Nov 29, 2020

@TMRh20 did the manualAcknowledgements example work reliably on the RPi for you? My RPi4 is still having trouble. All the other examples work well, and it doesn't seem like a power problem (some acks get through; most don't in either direction). The python example manual_acknowledgements.py works fine, so I think it might be a timing problem. Tell me its just me and I'll move on.

@2bndy5 2bndy5 linked a pull request Nov 29, 2020 that will close this issue
@TMRh20
Copy link
Member

TMRh20 commented Nov 30, 2020 via email

@2bndy5
Copy link
Member Author

2bndy5 commented Nov 30, 2020

ok I'll move on for now and chalk it up to a problem specific to my radio module... Unless we get reports of similar problem from someone else.

2bndy5 added a commit that referenced this issue Dec 14, 2020
* don't hide EN_ACK_PAY reqs; adjust examples & docs

* removed duplicated calls in examples/tests

* too many examples

* update docs about reUseTx()

* deprecate enableDynamicAck()

* clarify reUseTx()

* typo in func ref

* append setAutoAck() about pipe 0

* consistent casing in "auto-ack"

* fix typo

* revert this "see also" changes

* use ack_payloads_enabled to full potential

* undeprecate flush_rx()

* isPVariant return internal var; default dyn_pl on

addresses the following issues:
- #401
- #641
- #660

* oops, readdress #401 #641 #660

* address #640

* deprecate isAckPayloadAvailable() #664

* try to ignore return value; trigger forked actions

attempting to address #636

* this is why I can't have nice things

* retrying to ignore return value; fix init order

* add CI for avr compiling examples

* build doxygen with latest release ver number

* revert doxyfile, fix doxygen.yml, make2 = install

* build examples changes, doxygen.yml bad indent

* remove unnecessary pipe chars in doxygen.yml

* linux CI changed, pde->ino files

* platform specific examples; fix WiringPi build

* fix using void return value

* remove gemma & lilypad; fix certain example vars

* wiringPi may be broken #669

* 8 paragraphs that say keep auto-ack enabled

#667

* reverted examples folders; exclude maple & 3pin

* exclude didn't work

* trigger arduino build on workflow changes

* explicit examples' paths

* no wildcards in explicit paths

* no quotes in yaml sequence

* try using a pipe char

* arduino build "needs" A-style check

* applied arduino IDE's auto formatting

* remove format checker

* fine let the example terminate

* all official arduino cores to build_arduino.yml

* backup examples; new GettingStarted

* no explicit examples; compile all

* new InterruptConfigure example

* // about when IRQ flags get cleared; & a fix typo

* new StreamingData & MulticeiverDemo examples

* reduce streamData compilation size

* tested GetStarted, AckPayloads, Streaming

* IRQ & Multicceiver examples tested

* undo #646; add broken FakeBLE example

* fix arduino build CI

* forgot to use pipe char

* typo

* 2nd job should run on ubuntu-latest

* fqbn arch-type is wrong?!

* uncomment #define IRQ_PIN from testing artifacts

* use SpenceKonde core released zip file

* use SpenceKonde board definitions

* use correct vendor name?!

* use lower case?!

* platform name should match the fqbn

* what am I doing wrong? use SpenceKonde attiny core

* under "platforms" not "with"

* yml formatted "platforms" options

* "with: platforms:"

* source-path uses relative path

* use trailing / in source-path

* clear advice from per1234 about yml syntax

* fixing source-path and version number

* use direct download link to SpenceKonde release

* adjust source-path again

* no source-path

* redo-ing #646

* timingSearch3pin includes stdio

* don't ignore rf24_ATTiny examples

* separate job for separate ATTiny examples

* timingSearch3pin uses redefined spi funcs

* drop testing on attiny43, install core from json

* keywords updated removed duplicate examples

* CallResponse was duplicate; (+) ManualAck example

* doc updates #671 tested new manAck example

* FakeBLE crc calc not checking out

* add per1234's action to check formatting

* did not find expected alphanumeric char?!

* add manualAcknowledgements example to docs

* don't remove comment block prefix

* restored comment prefix in old examples also

* less confusing comments about addresses

* clarify docs on return value for all write-related

* remove broken fakeBLE example

* forgot to remove fakeBLE from arduino workflow

* test deploy to gh-pages

* bad yml format

* something's wrong with the doxygen build CI

* lack of new line in end of  doxyfile

* remove debug prompt; deploy on publish released

* deploy on any release event

* fix main page useful links

* only clear RX_DR flag in read()

* typo

* doc updates; new python examples

* new gettingstarted example for linux

* add micros() to applicable utilities compatiblity

* define micros() in arch_config.h

* printDetails() in linux

* pipe number not printing correctly

* oops it was a non-printable char

* avoid keyboard interrupt

* build wiringPi examples also

* linux build CI for SPIDEV

* ignore return value in utilty/SPIDEV/interrupt.c

* trying rf24_micros()

* ammend example to use rf24_micros()

* let micros() be defined in examples for linux

* need cstdio

* ported arduino examples to linux (& python)

* oops

* should probably declare i huh

* copy n paste much?

* don't use stoi for a char

* typo, expose digitalRead(), ifdef RF24_WIRINGPI

* ifdef WIRINGPI didn't help, fix inline condition

* testing round 1; fix pyRf24/setup.py

* bug fixes in py examples prompt fixes in linux

* fix irqConf for arduino, rename stream_data.py

* copy n paste artifact

* debugging streamingData

* testing round 2

* oops

* timing output changes; printDetails() also

* debugging IRQ configure example

* debugging IRQ_config.py also

* declare timer stuff for micros in manACK example

* typo

* doc read() for python; add flush_rx() to py wrap

* remove cap on how many bytes to read in python!!!

* don't cap bytes read() from RX FIFO in C++

* supposed to be decode() not encode()

* fix typos; better python doc about read()

* py wrapper omits len args for buf-related funcs

* fix streaming_data.py master()

* duplicate prompt in ackPay.py

* prompt format changes

* big commit

- reverted defaults about Dynamic Payloads and Dynamic ACKs per @TMRh20 suggestions about Si24R1 in #658. This reverts #660 & #661
- ammended docs & all examples about above suggestions
- re-wrote InterruptConfigure examples to use attachInterrupt(); py example uses RPi.GPIO equivalant.
- removed MKR-based boards from Arduino build CI as pin 2 on those boards don't support interrupt requests, and InterruptConfigure.ino uses pin 2 for exactly that.
- added building of python wrapper to Linux workflow; it now also runs pylint on python examples
- removed my attempt to port digitalRead() to various Linux drivers as it is no longer needed in the interruptConfigure.cpp example.
- addressed #674 about RX_PW_Px registers manipulation.
- remove and ignore my VSCode folder as it is machine-specific
- removed contradicting "examples_linux" ignores and added "examples_linux/__pycache__"  folder
- RF24::begin() now brute forces a soft reset. It does not reset addresses set to the pipes, but it does close all pipes. This helps address #401
- fixed some typos/copy-n-paste issues in the docs.
- added instructions on how to run the python example scripts

* Linux build CI use pip3 to install RPi.GPIO

* workflow uses python 3.7 x86

* workflow uses python 3.x x86

* python needs x32 called in workflow

* fix address assignment in linux examples

* don't check python examples in workflow

* define INPUT in RPi-BCM driver

* remove GPIO.cleanup() from py examples

* payloadSize is an attribute in python

* fix python examples about getPLsize()

* use RuntimeError in python examples when begin() is false

* testing round 3

* streamData uses write(); python examples need 3.7+

* fix ellapsedTime in streamingData

* status byte saved as private member

addresses #678 #679 #677

removed comments in build_linux.yml about building/testing the python wrapper

added a fail fast prompt to the streaming examples when failures >= 100

* simplify logic about _is_p_variant

* testing round 4 & address #680

* fix irq examples

* fix compilation errors for IRQ examples

* fix irq example for linux

* tweak IRQ py example; writeAckPayload returns bool

* final tweaks to IRQ examples; some doc updates

* leave closeReadingPipe(0) in startListening()

* arduino examples work

address 2 new issues
1. #687 added printPrettyDetails(); updated python wrapper and keywords.txt
2. #686 centralizing all SPI access to write_*() and read_*() functions

Also reverted changes to gitignore about examples_linux folder while adding/ignoring some things about building the python wrapper (venv, *.pyc, __pycache__)

* remove volatile from radio declaration

* datasheets; fix man_ack.py example

updated comment proceeding radio object in python examples

documented enums and linked references to them. Also linked references in COMMON_ISSUES.md & main page's changelog.

* ATTiny examples should work on SpenceKonde core

* exclude ATTinyx313 from timingSearch3pin example

* oops, bad indent

* Astyle indent for #ifdef is 0

* (+) CLI args to examples. pwr down radio on ctrl+c

* fail if no valid arg is specified

* fix parsing args in python examples

* make py examples behave like c++ examples

* found a bug in py examples' -r arg

* testing round 5

* adjust manpage descriptions

* don't use signal.h in cpp examples

* del cli args from all linux examples except 2

* edit doxyfile OUTPUT_DIR

* only run doxygen on master branch

* redirect doc links to nRF24 org

* missed a link

* remove use of timeout bool in manAck.ino

* self-reviewed PR changes

* ATTinyCore adjustments

- use macros from SpenceKonde ATTinyCore
- add macros for CSN settling times for when using the ATTinyCore

* some more self-reviewed PR changes

* exclude root README from doxygen output

* exclude GPIO & SPI classes from doc'd classes

* add Arduino & Linux build badges to readme

* Change link to docs in readme
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants