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

Promiscuous scanners #955

Merged
merged 66 commits into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
2b1f4e5
adjust scanner examples as discussed in #852
2bndy5 Jul 12, 2022
28979ed
ran clang-format on scanner changes
2bndy5 Jul 12, 2022
7fe365d
overhaul C++ scanners
2bndy5 Jul 12, 2022
49a1a57
trim trailing whitespace and fix a string's init
2bndy5 Jul 12, 2022
eb6258c
minor updates to C++ scanners
2bndy5 Jul 13, 2022
4c14c47
add new curses python scanner
2bndy5 Jul 13, 2022
98f6edf
replace scanner.py w/ curses implementation
2bndy5 Jul 13, 2022
d9bab34
add more informative output
2bndy5 Jul 13, 2022
9e6b879
fix scanner data rate option input
2bndy5 Jul 13, 2022
7df0d17
fix logic about normalizing user input
2bndy5 Jul 13, 2022
b005f99
remove typehints related to the curses wrapper
2bndy5 Jul 13, 2022
334a43b
show signal counts on scanner exit; not curses buf
2bndy5 Jul 13, 2022
f72dd3e
don't serialize signal counts as json
2bndy5 Jul 13, 2022
79101f4
remove misleading output prompt
2bndy5 Jul 13, 2022
debdf5d
echo user input on scanner exit
2bndy5 Jul 13, 2022
16416fa
re-remove misleading output
2bndy5 Jul 13, 2022
08ea0a0
only update channel widget if any signal found
2bndy5 Jul 13, 2022
237306c
count & output spectrum passes
2bndy5 Jul 14, 2022
f9e190a
show an overall percentage
2bndy5 Jul 14, 2022
10b879d
oops, use stand-alone wrapper (not pyrf24 pkg)
2bndy5 Jul 14, 2022
24ac44e
update pico scanner example
2bndy5 Jul 14, 2022
ebfe187
[pico scanner] only send char* to printf()
2bndy5 Jul 14, 2022
e75dc79
update pico & arduino scanner
2bndy5 Jul 14, 2022
2c9446b
add new C++ curses scanner example
2bndy5 Jul 15, 2022
c038d67
ran clang-format on new scanner_curses.cpp
2bndy5 Jul 15, 2022
6d3a5ce
let Linux CI run on examples nested in folders
2bndy5 Jul 15, 2022
94f2e3b
begin debugging scanner_curses.cpp
2bndy5 Jul 15, 2022
228b98a
simplify the progress bars' init
2bndy5 Jul 15, 2022
55fb24e
[C++ curses scanner] show sig counts on exit; display countdown timer
2bndy5 Jul 15, 2022
e3568be
reduce nested loops during scan
2bndy5 Jul 15, 2022
08cacdb
getting closer to finishing C++ curses scanner
2bndy5 Jul 15, 2022
f23a8b9
something wrong with curses C++ scanner
2bndy5 Jul 15, 2022
c8cfd61
Call available
TMRh20 Jul 17, 2022
2b4de3e
Add additional 'noise' addys
TMRh20 Jul 17, 2022
debed43
use available() in arduino & pico scanners
2bndy5 Jul 17, 2022
3440bc9
remove call to curses.subpad() in python scanner
2bndy5 Jul 17, 2022
56b2f55
remove use of queue in C++ scanner
2bndy5 Jul 17, 2022
b14cd0c
introducing a rough draft of Arduino scannerGraphic
2bndy5 Jul 17, 2022
690b4ed
ran clang-format
2bndy5 Jul 17, 2022
9ed9011
fix and cast datatype for recent change in C++ curses scanner
2bndy5 Jul 17, 2022
b47d377
include iomanip for `setprecision`
2bndy5 Jul 17, 2022
2c4aaec
ran clang-format on linux ncurses scanner example
2bndy5 Sep 18, 2022
5a89b9c
change filled bar char for better visual distinction
2bndy5 Dec 3, 2023
3cb8324
reviewed examples
2bndy5 Mar 3, 2024
e779879
revised the pico scanner example
2bndy5 Mar 3, 2024
1755503
ran clang-format
2bndy5 Mar 3, 2024
2ec4620
use single-byte chars for py example progress bars
2bndy5 Mar 3, 2024
b6088f0
tested arduino scanner and pico scanner
2bndy5 Mar 3, 2024
49a1f13
reviewed and tested scannerGraphic with I2C display
2bndy5 Mar 4, 2024
23ee59a
[scannerGraphic] make X_OFFSET calc agnostic of display type
2bndy5 Mar 4, 2024
0791b37
[scannerGraphic] draw graph based on screen dimensions; add max peak …
2bndy5 Mar 4, 2024
aa9c670
tested scannerGraphic with ST7789 display
2bndy5 Mar 5, 2024
42b95ba
ensure radio is not stuck with CONT_WAVE flag asserted after MCU reset
2bndy5 Mar 5, 2024
9174559
reviewed files' doc comment at beginning of examples
2bndy5 Mar 5, 2024
e0c5168
arduino scanner discard CRLF from Serial input
2bndy5 Mar 6, 2024
795d0fb
fix address assignment to pipes in python scanner
2bndy5 Mar 6, 2024
3fa016d
add push() to ChannelHistory structs
2bndy5 Mar 6, 2024
0f4c0ce
more review changes
2bndy5 Mar 6, 2024
2d74467
format examples_linux/ncurses/scanner_curses.cpp
2bndy5 Mar 6, 2024
2c6d0f4
fix ncurses scanner incrementing total signal counts
2bndy5 Mar 7, 2024
936eafe
fix py scanner countdown timer prompt formatting
2bndy5 Mar 7, 2024
056b80a
proofreading scannerGraphic
2bndy5 Mar 7, 2024
5fea46f
use pins defined as macros in scanner_curses.cpp
2bndy5 Mar 7, 2024
fcad232
adjust python curses usage to reflect C++ curses usage
2bndy5 Mar 7, 2024
0cf9bed
adjust scanner.py string formatting
2bndy5 Mar 7, 2024
3fda357
use uint8_t iter when printing vertical header (non-curses examples)
2bndy5 Mar 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build_linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ on:
- "utility/MRAAA/*"
- "utility/SPIDEV/*"
- "utility/pigpio"
- "examples_linux/*"
- "examples_linux/**"
- "!examples_linux/*.py"
- "!examples_linux/*.md"
- "pyRF24/setup.py"
Expand All @@ -39,7 +39,7 @@ on:
- "utility/MRAAA/*"
- "utility/SPIDEV/*"
- "utility/pigpio"
- "examples_linux/*"
- "examples_linux/**"
- "!examples_linux/*.py"
- "!examples_linux/*.md"
- "pyRF24/setup.py"
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ Session.vim
.DS_Store
Makefile.inc
utility/includes.h
!examples_linux/
examples_linux/*
examples_linux/**/*
!examples_linux/**/
!examples_linux/*.cpp
!examples_linux/*.py
!examples_linux/**/*.cpp
Expand Down
201 changes: 143 additions & 58 deletions examples/scanner/scanner.ino
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,36 @@
* This is a good diagnostic tool to check whether you're picking a
* good channel for your application.
*
* Run this sketch on two devices. On one device, start CCW output by sending a 'g'
* character over Serial. The other device scanning should detect the output of the sending
* device on the given channel. Adjust channel and output power of CCW below.
* Run this sketch on two devices. On one device, start emitting a constant carrier wave
* by sending a channel number in the Serial Monitor. The other device scanning should
* detect the constant carrier wave from the sending device on the given channel.
* Send a negative number in the Serial Monitor to stop emitting a constant carrier wave
* and resume scanning.
*
* Inspired by cpixip.
* See http://arduino.cc/forum/index.php/topic,54795.0.html
* See https://forum.arduino.cc/t/poor-mans-2-4-ghz-scanner/54846
*
* See documentation at https://nRF24.github.io/RF24
*/

/*
* How to read the output:
* - The header is a list of supported channels in decimal written vertically.
* - Each column corresponding to the vertical header is a hexadecimal count of
* detected signals (max is 15 or 'f').
*
* The following example
* 000
* 111
* 789
* ~~~ <- just a divider between the channel's vertical labels and signal counts
* 1-2
* can be interpreted as
* - 1 signal detected on channel 17
* - 0 signals (denoted as '-') detected on channel 18
* - 2 signals detected on channel 19
*
* Each line of signal counts represent 100 passes of the supported spectrum.
*/

#include "RF24.h"
Expand All @@ -38,76 +62,112 @@ RF24 radio(CE_PIN, CSN_PIN);
// Channel info
//

const uint8_t num_channels = 126;
uint8_t values[num_channels];
const uint8_t num_channels = 126; // 0-125 are supported
uint8_t values[num_channels]; // the array to store summary of signal counts per channel

// To detect noise, we'll use the worst addresses possible (a reverse engineering tactic).
// These addresses are designed to confuse the radio into thinking
// that the RF signal's preamble is part of the packet/payload.
const uint8_t noiseAddress[][2] = { { 0x55, 0x55 }, { 0xAA, 0xAA }, { 0xA0, 0xAA }, { 0xAB, 0xAA }, { 0xAC, 0xAA }, { 0xAD, 0xAA } };

const int num_reps = 100; // number of passes for each scan of the entire spectrum
bool constCarrierMode = 0; // this flag controls example behavior (scan mode is default)

void printHeader(); // prototype function for printing the channels' header

//
// Setup
//

void setup(void) {
//
// Print preamble
//

// Print preamble
Serial.begin(115200);
printf_begin();
Serial.println(F("\n\rRF24/examples/scanner/"));
while (!Serial) {
// some boards need this to wait for Serial connection
}
Serial.println(F("RF24/examples/scanner/"));

//
// Setup and configure rf radio
//
if (!radio.begin()) {
Serial.println(F("radio hardware not responding!"));
while (true) {
// hold in an infinite loop
}
}
radio.stopConstCarrier(); // in case MCU was reset while radio was emitting carrier wave
radio.setAutoAck(false); // Don't acknowledge arbitrary signals
radio.disableCRC(); // Accept any signal we find
radio.setAddressWidth(2); // A reverse engineering tactic (not typically recommended)
for (uint8_t i = 0; i < 6; ++i) {
radio.openReadingPipe(i, noiseAddress[i]);
}

radio.begin();
radio.setAutoAck(false);
// set the data rate
Serial.print(F("Select your Data Rate. "));
Serial.print(F("Enter '1' for 1 Mbps, '2' for 2 Mbps, '3' for 250 kbps. "));
Serial.println(F("Defaults to 1Mbps."));
while (!Serial.available()) {
// wait for user input
}
uint8_t dataRate = Serial.parseInt();
if (dataRate == 50) {
Serial.println(F("Using 2 Mbps."));
radio.setDataRate(RF24_2MBPS);
} else if (dataRate == 51) {
Serial.println(F("Using 250 kbps."));
radio.setDataRate(RF24_250KBPS);
} else {
Serial.println(F("Using 1 Mbps."));
radio.setDataRate(RF24_1MBPS);
}
Serial.println(F("***Enter a channel number to emit a constant carrier wave."));
Serial.println(F("***Enter a negative number to switch back to scanner mode."));

// Get into standby mode
radio.startListening();
radio.stopListening();
radio.printDetails();

//delay(1000);
// Print out header, high then low digit
int i = 0;
while (i < num_channels) {
Serial.print(i >> 4, HEX);
++i;
}
Serial.println();
i = 0;
while (i < num_channels) {
Serial.print(i & 0xf, HEX);
++i;
}
Serial.println();
//delay(1000);
}
radio.flush_rx();

//
// Loop
//
// printf_begin();
// radio.printPrettyDetails();
// delay(1000);

const int num_reps = 100;
bool constCarrierMode = 0;
// Print out vertical header
printHeader();
}

void loop(void) {
/****************************************/
// Send g over Serial to begin CCW output
// Configure the channel and power level below
// Send a number over Serial to begin Constant Carrier Wave output
// Configure the power amplitude level below
if (Serial.available()) {
char c = Serial.read();
if (c == 'g') {
int8_t c = Serial.parseInt();
TMRh20 marked this conversation as resolved.
Show resolved Hide resolved
if (c >= 0) {
c = min(125, max(0, c)); // clamp channel to supported range
constCarrierMode = 1;
radio.stopListening();
delay(2);
Serial.println("Starting Carrier Out");
radio.startConstCarrier(RF24_PA_LOW, 40);
} else if (c == 'e') {
Serial.print("\nStarting Carrier Wave Output on channel ");
Serial.println(c);
// for non-plus models, startConstCarrier() changes address on pipe 0 and sets address width to 5
radio.startConstCarrier(RF24_PA_LOW, c);
} else {
constCarrierMode = 0;
radio.stopConstCarrier();
Serial.println("Stopping Carrier Out");
radio.setAddressWidth(2); // reset address width
radio.openReadingPipe(0, noiseAddress[0]); // ensure address is looking for noise
Serial.println("\nStopping Carrier Wave Output");
printHeader();
}

// discard any CR and LF sent
while (Serial.peek() != -1) {
if (Serial.peek() == '\r' || Serial.peek() == '\n') {
Serial.read();
} else { // got a charater that isn't a line feed
break; // handle it on next loop() iteration
}
}
}

/****************************************/

if (constCarrierMode == 0) {
Expand All @@ -125,27 +185,52 @@ void loop(void) {
// Listen for a little
radio.startListening();
delayMicroseconds(128);
bool foundSignal = radio.testRPD();
radio.stopListening();

// Did we get a carrier?
if (radio.testCarrier()) {
// Did we get a signal?
if (foundSignal || radio.testRPD() || radio.available()) {
++values[i];
radio.flush_rx(); // discard packets of noise
}
}
}


// Print out channel measurements, clamped to a single hex digit
int i = 0;
while (i < num_channels) {
for (int i = 0; i < num_channels; ++i) {
if (values[i])
Serial.print(min(0xf, values[i]), HEX);
else
Serial.print(F("-"));

++i;
}
Serial.println();

} //If constCarrierMode == 0
}
} // if constCarrierMode == 0
else {
// show some output to prove that the program isn't bricked
Serial.print(F("."));
delay(1000); // delay a second to keep output readable
}
} // end loop()

void printHeader() {
// Print the hundreds digits
for (uint8_t i = 0; i < num_channels; ++i)
Serial.print(i / 100);
Serial.println();

// Print the tens digits
for (uint8_t i = 0; i < num_channels; ++i)
Serial.print((i % 100) / 10);
Serial.println();

// Print the singles digits
for (uint8_t i = 0; i < num_channels; ++i)
Serial.print(i % 10);
Serial.println();

// Print the header's divider
for (uint8_t i = 0; i < num_channels; ++i)
Serial.print(F("~"));
Serial.println();
}
Loading