Skip to content

Commit 0276d95

Browse files
committed
Initial version
0 parents  commit 0276d95

File tree

3 files changed

+380
-0
lines changed

3 files changed

+380
-0
lines changed

MeshBase.cpp

+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
#include <Arduino.h>
2+
#include <RF24.h>
3+
#include "MeshBase.h"
4+
5+
// -- Broadcast addresses --
6+
#define PEER_DISCOVERY 1
7+
8+
// -- Helpers --
9+
#define TO_BROADCAST(x) (0xBB00000000LL + x)
10+
#define TO_ADDRESS(x) (0xAA00000000LL + x)
11+
12+
#define PEER_DISCOVERY_TIME 3000
13+
#define PEER_CHECK_TIME 4000
14+
#define PEER_TIMEOUT 2
15+
16+
MeshBase::MeshBase(uint8_t ce, uint8_t cs)
17+
: radio(ce, cs)
18+
, address(0)
19+
, last_broadcast_time(0)
20+
, last_peer_check_time(0)
21+
{}
22+
23+
void MeshBase::Begin()
24+
{
25+
radio.begin();
26+
radio.enableDynamicPayloads();
27+
radio.setRetries(2,1);
28+
//radio.openReadingPipe(0, TO_ADDRESS(address));
29+
radio.openReadingPipe(1, TO_BROADCAST(PEER_DISCOVERY));
30+
radio.setAutoAck(0, true);
31+
radio.setAutoAck(1, false);
32+
radio.startListening();
33+
}
34+
35+
void MeshBase::Update()
36+
{
37+
// Periodic sends
38+
if (millis() - last_broadcast_time > PEER_DISCOVERY_TIME)
39+
{
40+
if (!IsReady())
41+
ChooseAddress();
42+
SendPeerDiscovery();
43+
}
44+
45+
// Recieve
46+
uint8_t pipe_num;
47+
if (radio.available(&pipe_num))
48+
{
49+
bool done = false;
50+
do {
51+
uint8_t len = radio.getDynamicPayloadSize();
52+
uint8_t buff[40];
53+
done = radio.read(buff, min(len, sizeof(buff)));
54+
if (pipe_num == 0)
55+
{
56+
HandleMessage(0, buff, len);
57+
} else if (pipe_num == 1) {
58+
HandlePeerDiscovery(buff, len);
59+
}
60+
} while (!done);
61+
}
62+
63+
// Update peers
64+
if (millis() - last_peer_check_time > PEER_CHECK_TIME)
65+
{
66+
Peer* current = first;
67+
while(current != NULL)
68+
{
69+
current->time += 1;
70+
if (current->time >= PEER_TIMEOUT)
71+
{
72+
current = RemovePeer(current);
73+
} else {
74+
current = current->next;
75+
}
76+
}
77+
last_peer_check_time = millis();
78+
}
79+
}
80+
81+
void MeshBase::HandlePeerDiscovery(void* buff, uint8_t length)
82+
{
83+
if (length != sizeof(uint32_t))
84+
return;
85+
uint32_t from = *(uint32_t*)buff;
86+
// Dont know why, but this keeps happening?
87+
if (from == 0)
88+
return;
89+
90+
Peer* peer = GetPeer(from);
91+
if (peer == NULL)
92+
{
93+
// Found a new peer
94+
AddPeer(from);
95+
} else {
96+
// Existing peer, reset timer
97+
peer->time = 0;
98+
}
99+
}
100+
101+
void MeshBase::SendPeerDiscovery()
102+
{
103+
last_broadcast_time = millis();
104+
SendBroadcastMessage(PEER_DISCOVERY, &address, sizeof(address));
105+
}
106+
107+
void MeshBase::SendBroadcastMessage(uint32_t to, const void* data, uint8_t length)
108+
{
109+
radio.stopListening();
110+
radio.openWritingPipe(TO_BROADCAST(to));
111+
radio.write(data, length);
112+
radio.startListening();
113+
}
114+
115+
void MeshBase::SendMessage(uint32_t to, const void* data, uint8_t length)
116+
{
117+
radio.stopListening();
118+
radio.openWritingPipe(TO_ADDRESS(to));
119+
radio.write(data, length);
120+
radio.startListening();
121+
}
122+
123+
void MeshBase::ChooseAddress()
124+
{
125+
do {
126+
address = random(0xFFFF);
127+
} while(GetPeer(address) != NULL);
128+
129+
radio.openReadingPipe(0, TO_ADDRESS(address));
130+
Serial.print("Chose address: ");
131+
Serial.println(address, DEC);
132+
}
133+
134+
void MeshBase::AddPeer(uint32_t a)
135+
{
136+
Serial.print("New Peer: ");
137+
Serial.println(a, DEC);
138+
Peer* n = new Peer(a);
139+
if (last == NULL)
140+
{
141+
// Empty list.
142+
first = n;
143+
last = n;
144+
} else {
145+
// Attach onto end
146+
last->next = n;
147+
n->prev = last;
148+
last = n;
149+
}
150+
OnNewPeer(n);
151+
}
152+
153+
MeshBase::Peer* MeshBase::GetPeer(uint32_t a)
154+
{
155+
Peer* current = first;
156+
while(current != NULL)
157+
{
158+
if (current->address == a)
159+
return current;
160+
current = current->next;
161+
}
162+
// Could not find..
163+
return NULL;
164+
}
165+
166+
MeshBase::Peer* MeshBase::RemovePeer(MeshBase::Peer* p)
167+
{
168+
Serial.print("Lost Peer: ");
169+
Serial.println(p->address, DEC);
170+
OnLostPeer(p);
171+
Peer* next = p->next;
172+
if (first == p)
173+
first = p->next;
174+
if (last == p)
175+
last = p->prev;
176+
if (p->prev)
177+
p->prev->next = p->next;
178+
if (p->next)
179+
p->next->prev = p->prev;
180+
delete p;
181+
return next;
182+
}
183+

MeshBase.h

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#ifndef MESH_BASE_H
2+
#define MESH_BASE_H
3+
4+
#include <stdint.h>
5+
#include "RF24.h"
6+
7+
class MeshBase
8+
{
9+
public:
10+
MeshBase(uint8_t ce, uint8_t cs);
11+
12+
struct Peer {
13+
uint32_t address;
14+
uint16_t time;
15+
Peer* next;
16+
Peer* prev;
17+
Peer(uint32_t address) : address(address), time(0), next(0), prev(0) {}
18+
};
19+
20+
void Begin();
21+
void Update();
22+
void SendMessage(uint32_t address, const void* data, uint8_t length);
23+
uint32_t GetAddress() const { return address; }
24+
bool IsReady() const { return address != 0; }
25+
protected:
26+
virtual void HandleMessage(uint32_t sender, const void* data, uint8_t length) = 0;
27+
virtual void OnNewPeer(Peer*) {}
28+
virtual void OnLostPeer(Peer*) {}
29+
private:
30+
uint32_t address;
31+
RF24 radio;
32+
unsigned long last_broadcast_time;
33+
unsigned long last_peer_check_time;
34+
35+
void SendPeerDiscovery();
36+
void SendBroadcastMessage(uint32_t address, const void* data, uint8_t length);
37+
void HandlePeerDiscovery(void* buff, uint8_t length);
38+
void ChooseAddress();
39+
40+
Peer* first;
41+
Peer* last;
42+
43+
Peer* GetPeer(uint32_t address);
44+
void AddPeer(uint32_t address);
45+
Peer* RemovePeer(Peer* peer);
46+
47+
};
48+
49+
#endif

RF_test.ino

+148
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#include <SPI.h>
2+
#include "RF24.h"
3+
#include "MeshBase.h"
4+
5+
class App : public MeshBase
6+
{
7+
public:
8+
App() : MeshBase(9, 10) {}
9+
protected:
10+
virtual void HandleMessage(uint32_t sender, const void* data, uint8_t length)
11+
{
12+
Serial.println("Got Message");
13+
}
14+
virtual void OnNewPeer(Peer* p)
15+
{
16+
SendMessage(p->address, "Hello", 6);
17+
}
18+
};
19+
20+
App app;
21+
22+
void setup()
23+
{
24+
Serial.begin(9600);
25+
Serial.println("Starting RF_TEST");
26+
//randomSeed(analogRead(0));
27+
app.Begin();
28+
}
29+
30+
void loop()
31+
{
32+
app.Update();
33+
delay(100);
34+
}
35+
/*#include <SPI.h>
36+
//#include "RF24.h"
37+
//#include "printf.h"
38+
39+
40+
//RF24 radio(9,10);
41+
42+
typedef enum
43+
{
44+
BROADCAST_PEER_DISCOVERY = 1,
45+
BROADCAST_MISC,
46+
47+
BROADCAST_MAX,
48+
} broadcast_chanel;
49+
50+
const uint64_t broadcast_addresses[BROADCAST_MAX] = { 0, 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
51+
const uint64_t client_addresses[4] = { 0x112100000F0LL, 0x11210000F1LL, 0x11210000F2LL, 0x11210000F3LL };
52+
const uint8_t client_num = 1;
53+
54+
unsigned long last_broadcast;
55+
56+
struct Peer
57+
{
58+
uint64_t address;
59+
uint32_t last_seen;
60+
boolean used;
61+
Peer() : address(0), last_seen(0), used(false) {}
62+
};
63+
64+
Peer peers[20];
65+
66+
67+
void setup(void)
68+
{
69+
Serial.begin(9600);
70+
Serial.println("RF_TEST");
71+
Serial.print("ADDRESS: ");
72+
Serial.print(client_num, DEC);
73+
Serial.print(" - ");
74+
Serial.print((uint32_t)(client_addresses[client_num] >> 32), HEX);
75+
Serial.print((uint32_t)(client_addresses[client_num] ), HEX);
76+
Serial.println("");
77+
78+
radio.begin();
79+
radio.enableDynamicPayloads();
80+
radio.setRetries(2,1);
81+
//radio.openWritingPipe(client_addresses[client_num]);
82+
radio.openReadingPipe(0, client_addresses[client_num]);
83+
radio.openReadingPipe(BROADCAST_PEER_DISCOVERY,broadcast_addresses[BROADCAST_PEER_DISCOVERY]);
84+
radio.openReadingPipe(BROADCAST_MISC,broadcast_addresses[BROADCAST_MISC]);
85+
radio.setAutoAck(0, true);
86+
radio.setAutoAck(BROADCAST_PEER_DISCOVERY, false);
87+
radio.setAutoAck(BROADCAST_MISC, false);
88+
89+
// Im here!
90+
sendPD();
91+
}
92+
93+
bool doPD()
94+
{
95+
return millis() - last_broadcast > 3000;
96+
}
97+
98+
void sendPD()
99+
{
100+
radio.stopListening();
101+
radio.openWritingPipe(broadcast_addresses[BROADCAST_PEER_DISCOVERY]);
102+
radio.write(&client_addresses[client_num], sizeof(client_addresses[client_num]));
103+
last_broadcast = millis();
104+
radio.startListening();
105+
}
106+
107+
void sendMessage(uint64_t address, const void* message, uint8_t length)
108+
{
109+
radio.stopListening();
110+
radio.openWritingPipe(address);
111+
radio.write(message, length);
112+
radio.startListening();
113+
}
114+
115+
116+
void loop(void)
117+
{
118+
uint8_t pipe_num;
119+
if (radio.available(&pipe_num))
120+
{
121+
uint8_t len = radio.getDynamicPayloadSize();
122+
123+
if (pipe_num == BROADCAST_PEER_DISCOVERY)
124+
{
125+
uint64_t payload;
126+
radio.read( &payload, len );
127+
Serial.print("Found client: ");
128+
Serial.print((uint32_t)(payload >> 32), HEX);
129+
Serial.print((uint32_t)(payload ), HEX);
130+
Serial.println("");
131+
sendMessage(payload, "Hello there.", 12);
132+
}
133+
else //if (pipe_num == 0)
134+
{
135+
char payload[33];
136+
radio.read(payload, len);
137+
payload[len] = 0;
138+
Serial.print("Got packet. Message: ");
139+
Serial.println(payload);
140+
}
141+
}
142+
143+
// Periodically send a PD broadcast.
144+
if (doPD()) { sendPD(); }
145+
146+
delay(10);
147+
148+
}*/

0 commit comments

Comments
 (0)