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

Lines changed: 183 additions & 0 deletions
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

Lines changed: 49 additions & 0 deletions
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

Lines changed: 148 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy