-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathZigbee.cpp
More file actions
121 lines (99 loc) · 3.78 KB
/
Zigbee.cpp
File metadata and controls
121 lines (99 loc) · 3.78 KB
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
#include "Zigbee.h"
Zigbee::Zigbee(PinName tx, PinName rx) : serial(tx, rx) {
serial.set_baud(115200); // Set baud rate as per your Zigbee module configuration
}
Zigbee::~Zigbee() {
// Destructor
}
bool Zigbee::sendMessage(const char* message) {
int length = strlen(message);
if (length > 0xFF) {
return false; // Message too long
}
sendFrame(message, length);
return true;
}
void Zigbee::sendFrame(const char* message, int length) {
char ChksmPreamble[] = {0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00};
char txBuffer[256]; // Adjust the buffer size as per your requirement
txBuffer[0] = 0x7E; // Start delimiter
uint16_t frameLength = length + 14; // Data length + frame type
txBuffer[1] = (frameLength >> 8) & 0xFF; // MSB of frame length
txBuffer[2] = frameLength & 0xFF; // LSB of frame length
txBuffer[3] = 0x10; // Frame type (Transmit Request)
txBuffer[4] = 0x01; // Frame ID (set to 0 for no response)
txBuffer[5] = 0x00; // 64-bit Destination Address
txBuffer[6] = 0x00;
txBuffer[7] = 0x00;
txBuffer[8] = 0x00;
txBuffer[9] = 0x00;
txBuffer[10] = 0x00;
txBuffer[11] = 0xFF;
txBuffer[12] = 0xFF;
txBuffer[13] = 0xFF; // 16-bit Destination Address
txBuffer[14] = 0xFE;
txBuffer[15] = 0x00; // Broadcast Radius
txBuffer[16] = 0x00; // Options
memcpy(&txBuffer[17], message, length); // Copy message to buffer
int finalLen = 17+length+1;
char chksum = calculateChecksum(txBuffer, finalLen);
txBuffer[finalLen-1] = chksum;
serial.write(txBuffer, finalLen); // Send the frame
}
bool Zigbee::receiveMessage(char* receivedMessage) {
enum ReceiveState {
WaitingForStart,
ReadingFrame,
ReadingPayload
};
static ReceiveState state = WaitingForStart;
static int idx = 0;
static int frameLength = 0;
static char rxBuffer[256]; // Adjust the buffer size as per your requirement
while (serial.readable()) {
char byte;
serial.read(&byte, 1);
switch (state) {
case WaitingForStart:
if (byte == 0x7E) {
idx = 0;
rxBuffer[idx++] = byte;
state = ReadingFrame;
}
break;
case ReadingFrame:
rxBuffer[idx++] = byte;
if (idx == 3) {
frameLength = (rxBuffer[1] << 8) | rxBuffer[2];
state = ReadingPayload;
}
break;
case ReadingPayload:
rxBuffer[idx++] = byte;
if (idx == frameLength + 4) {
if(rxBuffer[3] == 0x90)
{
int messageLength = frameLength - 12;
for (int i = 0; i < messageLength; ++i) {
receivedMessage[i] = rxBuffer[15 + i];
}
receivedMessage[messageLength] = '\0'; // Null-terminate the received message
state = WaitingForStart;
return true;
} else {
state = WaitingForStart;
}
}
break;
}
}
return false;
}
char Zigbee::calculateChecksum(const char* message, int length) {
int temp = 0;
for(int i=3;i<length-1;i++)
{
temp += message[i];
}
return (0xFF - temp) & 0xFF;
}