You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

139 lines
3.9 KiB

/* based on "gettingstarted.cpp" by 2bdy5 */
/**
* "PING" all known microinverters (serial numbers) on all
* known channels.
* Use a "known good" master (DTU) address.
* Keep track of the inverters as they frequency-hop.
*
* Test this tool by setting up an instance of "gettingstarted.cpp"
* with address setting '0' (default) as a test receiver.
*/
#include <ctime> // time()
#include <iostream> // cin, cout, endl
#include <iomanip>
#include <string> // string, getline()
#include <vector>
#include <sstream>
#include <time.h> // CLOCK_MONOTONIC_RAW, timespec, clock_gettime()
#include <RF24/RF24.h> // RF24, RF24_PA_LOW, delay()
#include <time.h>
#include <stdlib.h>
#include "common.hpp"
using namespace std;
// connection to our radio board
RF24 radio(22, 0, 1000000);
// See http://nRF24.github.io/RF24/pages.html for more information on usage
/** Ping the given address.
* @returns true if we received a reply, otherwise false.
*/
bool doPing(int ch, string src, string dst)
{
const int payloadsize = 12;
char payload[20];
radio.enableDynamicPayloads();
radio.setChannel(ch);
radio.setPALevel(RF24_PA_MAX); // RF24_PA_MAX is default.
radio.setDataRate(RF24_250KBPS);
// set the RX address of the TX node into a RX pipe
radio.openReadingPipe(1, (const uint8_t *)src.c_str());
// ...not that this matters for simple ping/ack
radio.stopListening(); // put radio in TX mode
// set the TX address of the RX node into the TX pipe
radio.openWritingPipe((const uint8_t *)dst.c_str());
// We need to modify the payload every time otherwise recipients
// will detect packets as 'duplicates' and silently ignore them
// (although they will still auto-ack them).
unsigned int r = rand();
snprintf(payload, sizeof(payload), "ping%08ud", r);
bool report = radio.write(payload, payloadsize);
if (report) {
// payload was delivered
return true;
}
return false; // no reply received
}
int main(int argc, char** argv)
{
srand(time(NULL)); // Initialization, should only be called once.
if (!radio.begin()) {
cout << "radio hardware is not responding!!" << endl;
return 0; // quit now
}
if(!radio.isPVariant())
{
printf("not nRF24L01+\n");
return 0;
}
if(!radio.isChipConnected())
{
printf("not connected\n");
return 0;
}
// TODO
// we probably want
// - dynamic payloads (check in rf logs)
// - do we need/want "custom ack payloads"?
// - use isAckPayloadAvailable() once we've actually contacted an inverter successfully!
//radio.printPrettyDetails();
// well-known valid DTU serial number
// just in case the inverter only responds to addresses
// that fulfil certain requirements.
//string masteraddr = serno2shockburstaddrbytes(99912345678);
string masteraddr = serno2shockburstaddrbytes(999970535453);
// serial numbers of all inverters that we are trying to find
vector<string> dstaddrs;
dstaddrs.push_back(string("1Node"));
dstaddrs.push_back(string("2Node"));
dstaddrs.push_back(serno2shockburstaddrbytes(114174608145));
dstaddrs.push_back("\x45\x81\x60\x74\x01");
dstaddrs.push_back(serno2shockburstaddrbytes(114174608177));
// channels that we will scan
vector<int> channels{1, 3, 6, 9, 11, 23, 40, 41, 61, 75, 76, 99};
for(auto & ch : channels)
{
cout << "ch " << setw(2) << ch << " ";
for(auto & a : dstaddrs)
{
cout << prettyPrintAddr(a);
bool success = doPing(ch, masteraddr, a);
if(success) {
cout << " XXX";
} else {
cout << " - ";
}
cout << " " << flush;
//delay(10);
}
cout << endl;
}
//radio.printPrettyDetails();
return 0;
}