forked from lumapu/ahoy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdiscover.cpp
139 lines (111 loc) · 3.89 KB
/
discover.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* 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;
}