1
This commit is contained in:
parent
dfe2a84bb3
commit
f996a6c86f
@ -0,0 +1 @@
|
||||
idf_component_register(SRCS "zh_rf24.c" INCLUDE_DIRS "include" REQUIRES driver)
|
@ -0,0 +1,59 @@
|
||||
//Receiver program
|
||||
|
||||
#include "Mirf.h"
|
||||
#include "printf.h"
|
||||
|
||||
Nrf24l Mirf = Nrf24l(10, 9); // CE,CSN
|
||||
|
||||
union MYDATA_t {
|
||||
byte value[32];
|
||||
char now_time[32];
|
||||
};
|
||||
|
||||
MYDATA_t mydata;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Mirf.spi = &MirfHardwareSpi;
|
||||
Mirf.init();
|
||||
Mirf.payload = sizeof(mydata.value); // Set the payload size
|
||||
Mirf.channel = 90; // Set the used channel
|
||||
Mirf.config();
|
||||
|
||||
// Set my own address to RX_ADDR_P1
|
||||
Mirf.setRADDR((byte *)"1RECV");
|
||||
// Add my own address to RX_ADDR_P2
|
||||
Mirf.addRADDR(2, '2'); // 2RECV
|
||||
// Add my own address to RX_ADDR_P3
|
||||
Mirf.addRADDR(3, '3'); // 3RECV
|
||||
// Add my own address to RX_ADDR_P4
|
||||
Mirf.addRADDR(4, '4'); // 4RECV
|
||||
// Add my own address to RX_ADDR_P5
|
||||
Mirf.addRADDR(5, '5'); // 5RECV
|
||||
|
||||
// Clear RX FiFo
|
||||
while(1) {
|
||||
if (Mirf.dataReady() == false) break;
|
||||
Mirf.getData(mydata.value);
|
||||
}
|
||||
|
||||
// Print current settings
|
||||
printf_begin();
|
||||
Mirf.printDetails();
|
||||
Serial.println("Listening...");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Wait for received data
|
||||
if (Mirf.dataReady()) {
|
||||
uint8_t pipe = Mirf.getDataPipe();
|
||||
Mirf.getData(mydata.value);
|
||||
Serial.print("Got data pipe(");
|
||||
Serial.print(pipe);
|
||||
Serial.print(") is: ");
|
||||
Serial.println(mydata.now_time);
|
||||
}
|
||||
delay(1);
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
version 2 as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file printf.h
|
||||
*
|
||||
* Setup necessary to direct stdout to the Arduino Serial library, which
|
||||
* enables 'printf'
|
||||
*/
|
||||
|
||||
#ifndef __PRINTF_H__
|
||||
#define __PRINTF_H__
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
int serial_putc( char c, FILE * )
|
||||
{
|
||||
Serial.write( c );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void printf_begin(void)
|
||||
{
|
||||
fdevopen( &serial_putc, 0 );
|
||||
}
|
||||
|
||||
#else
|
||||
#error This example is only for use on Arduino.
|
||||
#endif // ARDUINO
|
||||
|
||||
#endif // __PRINTF_H__
|
@ -0,0 +1,41 @@
|
||||
//Transmitter program
|
||||
|
||||
#include "Mirf.h"
|
||||
|
||||
Nrf24l Mirf = Nrf24l(10, 9); // CE,CSN
|
||||
|
||||
union MYDATA_t {
|
||||
byte value[32];
|
||||
char now_time[32];
|
||||
};
|
||||
|
||||
MYDATA_t mydata;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Mirf.spi = &MirfHardwareSpi;
|
||||
Mirf.init();
|
||||
Mirf.payload = sizeof(mydata.value); // Set the payload size
|
||||
Mirf.channel = 90; // Set the channel used
|
||||
Mirf.config();
|
||||
|
||||
// Set destination address to TX_ADDR
|
||||
// Set ACK waiting address to RX_ADDR_P0
|
||||
Mirf.setTADDR((byte *)"1RECV");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
sprintf(mydata.now_time,"now is %lu", micros());
|
||||
Mirf.send(mydata.value);
|
||||
Serial.print("Wait for sending.....");
|
||||
// Verify send was successful
|
||||
if (Mirf.isSend()) {
|
||||
Serial.print("Send success:");
|
||||
Serial.println(mydata.now_time);
|
||||
} else {
|
||||
Serial.println("Send fail:");
|
||||
}
|
||||
delay(1000);
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
//Transmitter program
|
||||
|
||||
#include "Mirf.h"
|
||||
|
||||
Nrf24l Mirf = Nrf24l(10, 9); // CE,CSN
|
||||
|
||||
union MYDATA_t {
|
||||
byte value[32];
|
||||
char now_time[32];
|
||||
};
|
||||
|
||||
MYDATA_t mydata;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Mirf.spi = &MirfHardwareSpi;
|
||||
Mirf.init();
|
||||
Mirf.payload = sizeof(mydata.value); // Set the payload size
|
||||
Mirf.channel = 90; // Set the channel used
|
||||
Mirf.config();
|
||||
|
||||
// Set destination address to TX_ADDR
|
||||
// Set ACK waiting address to RX_ADDR_P0
|
||||
Mirf.setTADDR((byte *)"2RECV");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
sprintf(mydata.now_time,"now is %lu",micros());
|
||||
Mirf.send(mydata.value);
|
||||
Serial.print("Wait for sending.....");
|
||||
// Verify send was successful
|
||||
if (Mirf.isSend()) {
|
||||
Serial.print("Send success:");
|
||||
Serial.println(mydata.now_time);
|
||||
} else {
|
||||
Serial.println("Send fail:");
|
||||
}
|
||||
delay(1000);
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
//Transmitter program
|
||||
|
||||
#include "Mirf.h"
|
||||
|
||||
Nrf24l Mirf = Nrf24l(10, 9); // CE,CSN
|
||||
|
||||
union MYDATA_t {
|
||||
byte value[32];
|
||||
char now_time[32];
|
||||
};
|
||||
|
||||
MYDATA_t mydata;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Mirf.spi = &MirfHardwareSpi;
|
||||
Mirf.init();
|
||||
Mirf.payload = sizeof(mydata.value); // Set the payload size
|
||||
Mirf.channel = 90; // Set the channel used
|
||||
Mirf.config();
|
||||
|
||||
// Set destination address to TX_ADDR
|
||||
// Set ACK waiting address to RX_ADDR_P0
|
||||
Mirf.setTADDR((byte *)"3RECV");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
sprintf(mydata.now_time,"now is %lu",micros());
|
||||
Mirf.send(mydata.value);
|
||||
Serial.print("Wait for sending.....");
|
||||
// Verify send was successful
|
||||
if (Mirf.isSend()) {
|
||||
Serial.print("Send success:");
|
||||
Serial.println(mydata.now_time);
|
||||
} else {
|
||||
Serial.println("Send fail:");
|
||||
}
|
||||
delay(1000);
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
//Transmitter program
|
||||
|
||||
#include "Mirf.h"
|
||||
|
||||
Nrf24l Mirf = Nrf24l(10, 9); // CE,CSN
|
||||
|
||||
union MYDATA_t {
|
||||
byte value[32];
|
||||
char now_time[32];
|
||||
};
|
||||
|
||||
MYDATA_t mydata;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Mirf.spi = &MirfHardwareSpi;
|
||||
Mirf.init();
|
||||
Mirf.payload = sizeof(mydata.value); // Set the payload size
|
||||
Mirf.channel = 90; // Set the channel used
|
||||
Mirf.config();
|
||||
|
||||
// Set destination address to TX_ADDR
|
||||
// Set ACK waiting address to RX_ADDR_P0
|
||||
Mirf.setTADDR((byte *)"4RECV");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
sprintf(mydata.now_time,"now is %lu",micros());
|
||||
Mirf.send(mydata.value);
|
||||
Serial.print("Wait for sending.....");
|
||||
// Verify send was successful
|
||||
if (Mirf.isSend()) {
|
||||
Serial.print("Send success:");
|
||||
Serial.println(mydata.now_time);
|
||||
} else {
|
||||
Serial.println("Send fail:");
|
||||
}
|
||||
delay(1000);
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
//Transmitter program
|
||||
|
||||
#include "Mirf.h"
|
||||
|
||||
Nrf24l Mirf = Nrf24l(10, 9); // CE,CSN
|
||||
|
||||
union MYDATA_t {
|
||||
byte value[32];
|
||||
char now_time[32];
|
||||
};
|
||||
|
||||
MYDATA_t mydata;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Mirf.spi = &MirfHardwareSpi;
|
||||
Mirf.init();
|
||||
Mirf.payload = sizeof(mydata.value); // Set the payload size
|
||||
Mirf.channel = 90; // Set the channel used
|
||||
Mirf.config();
|
||||
|
||||
// Set destination address to TX_ADDR
|
||||
// Set ACK waiting address to RX_ADDR_P0
|
||||
Mirf.setTADDR((byte *)"5RECV");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
sprintf(mydata.now_time,"now is %lu",micros());
|
||||
Mirf.send(mydata.value);
|
||||
Serial.print("Wait for sending.....");
|
||||
// Verify send was successful
|
||||
if (Mirf.isSend()) {
|
||||
Serial.print("Send success:");
|
||||
Serial.println(mydata.now_time);
|
||||
} else {
|
||||
Serial.println("Send fail:");
|
||||
}
|
||||
delay(1000);
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
//Transmitter program
|
||||
|
||||
#include "Mirf.h"
|
||||
|
||||
Nrf24l Mirf = Nrf24l(10, 9); // CE,CSN
|
||||
|
||||
struct Pack {
|
||||
byte index;
|
||||
char payload[31];
|
||||
};
|
||||
|
||||
#define PackSize sizeof(Pack)
|
||||
|
||||
union MYDATA_t {
|
||||
byte value[PackSize];
|
||||
struct Pack pack;
|
||||
};
|
||||
|
||||
MYDATA_t mydata;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Mirf.spi = &MirfHardwareSpi;
|
||||
Mirf.init();
|
||||
Mirf.payload = sizeof(mydata.value); // Set the payload size
|
||||
Mirf.channel = 90; // Set the channel used
|
||||
Mirf.config();
|
||||
|
||||
// Set destination address to TX_ADDR
|
||||
// Set ACK waiting address to RX_ADDR_P0
|
||||
Mirf.setTADDR((byte *)"FGHIJ");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
static int payload = 0x41; // 'A'
|
||||
mydata.pack.index = payload - 0x41; // 0
|
||||
for (int i=0;i<30;i++) {
|
||||
mydata.pack.payload[i] = payload;
|
||||
}
|
||||
mydata.pack.payload[30] = 0;
|
||||
Mirf.send(mydata.value);
|
||||
Serial.print("Wait for sending.....");
|
||||
// Verify send was successfuly
|
||||
if (Mirf.isSend()) {
|
||||
Serial.print("Send success:");
|
||||
Serial.println(mydata.pack.index);
|
||||
payload++;
|
||||
if(payload == 0x7e) {
|
||||
payload = 0x41;
|
||||
}
|
||||
} else {
|
||||
Serial.println("Send fail:");
|
||||
}
|
||||
delay(1000);
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
# Peer-to-peer Communication
|
||||
|
||||
nRF24L01 can send and receive up to 32 characters, but by adding an index to the sent data, it can send and receive 256 types of data.
|
||||
|
||||
```
|
||||
Listening...
|
||||
Got index=7 payload=HHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
|
||||
Got index=8 payload=IIIIIIIIIIIIIIIIIIIIIIIIIIIIII
|
||||
Got index=9 payload=JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
|
||||
Got index=10 payload=KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
|
||||
Got index=11 payload=LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
|
||||
Got index=12 payload=MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
Got index=13 payload=NNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
|
||||
Got index=14 payload=OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
|
||||
Got index=15 payload=PPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
|
||||
Got index=16 payload=QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
|
||||
Got index=17 payload=RRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
|
||||
```
|
||||
|
@ -0,0 +1,51 @@
|
||||
//Receiver program
|
||||
|
||||
#include "Mirf.h"
|
||||
|
||||
Nrf24l Mirf = Nrf24l(10, 9); // CE,CSN
|
||||
|
||||
struct Pack {
|
||||
byte index;
|
||||
char payload[31];
|
||||
};
|
||||
|
||||
#define PackSize sizeof(Pack)
|
||||
|
||||
union MYDATA_t {
|
||||
byte value[PackSize];
|
||||
struct Pack pack;
|
||||
};
|
||||
|
||||
MYDATA_t mydata;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Mirf.spi = &MirfHardwareSpi;
|
||||
Mirf.init();
|
||||
Mirf.payload = sizeof(mydata.value); // Set the payload size
|
||||
Mirf.channel = 90; // Set the used channel
|
||||
Mirf.config();
|
||||
|
||||
// Set my own address to RX_ADDR_P1
|
||||
Mirf.setRADDR((byte *)"FGHIJ");
|
||||
|
||||
// Clear RX FiFo
|
||||
while(1) {
|
||||
if (Mirf.dataReady() == false) break;
|
||||
Mirf.getData(mydata.value);
|
||||
}
|
||||
Serial.println("Listening...");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Wait for received data
|
||||
if (Mirf.dataReady()) {
|
||||
Mirf.getData(mydata.value);
|
||||
Serial.print("Got index=");
|
||||
Serial.print(mydata.pack.index);
|
||||
Serial.print(" payload=");
|
||||
Serial.println(mydata.pack.payload);
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
//Transmitter program
|
||||
|
||||
#include "Mirf.h"
|
||||
|
||||
Nrf24l Mirf = Nrf24l(10, 9); // CE,CSN
|
||||
|
||||
union MYDATA_t {
|
||||
byte value[32];
|
||||
char now_time[32];
|
||||
};
|
||||
|
||||
MYDATA_t mydata;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Mirf.spi = &MirfHardwareSpi;
|
||||
Mirf.init();
|
||||
Mirf.payload = sizeof(mydata.value); // Set the payload size
|
||||
Mirf.channel = 90; // Set the channel used
|
||||
Mirf.config();
|
||||
|
||||
// Set destination address to TX_ADDR
|
||||
// Set ACK waiting address to RX_ADDR_P0
|
||||
Mirf.setTADDR((byte *)"FGHIJ");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
sprintf(mydata.now_time,"now is %lu",micros());
|
||||
Mirf.send(mydata.value);
|
||||
Serial.print("Wait for sending.....");
|
||||
// Verify send was successfuly
|
||||
if (Mirf.isSend()) {
|
||||
Serial.print("Send success:");
|
||||
Serial.println(mydata.now_time);
|
||||
} else {
|
||||
Serial.println("Send fail:");
|
||||
}
|
||||
delay(1000);
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
//Receiver program
|
||||
|
||||
#include "Mirf.h"
|
||||
|
||||
Nrf24l Mirf = Nrf24l(10, 9); // CE,CSN
|
||||
|
||||
union MYDATA_t {
|
||||
byte value[32];
|
||||
char now_time[32];
|
||||
};
|
||||
|
||||
MYDATA_t mydata;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Mirf.spi = &MirfHardwareSpi;
|
||||
Mirf.init();
|
||||
Mirf.payload = sizeof(mydata.value); // Set the payload size
|
||||
Mirf.channel = 90; // Set the used channel
|
||||
Mirf.config();
|
||||
|
||||
// Set my own address to RX_ADDR_P1
|
||||
Mirf.setRADDR((byte *)"FGHIJ");
|
||||
|
||||
// Clear RX FiFo
|
||||
while(1) {
|
||||
if (Mirf.dataReady() == false) break;
|
||||
Mirf.getData(mydata.value);
|
||||
}
|
||||
Serial.println("Listening...");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Wait for received data
|
||||
if (Mirf.dataReady()) {
|
||||
Mirf.getData(mydata.value);
|
||||
Serial.print("Got string: ");
|
||||
Serial.println(mydata.now_time);
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
//primary program
|
||||
|
||||
#include "Mirf.h"
|
||||
#include "printf.h"
|
||||
|
||||
Nrf24l Mirf = Nrf24l(10, 9); // CE,CSN
|
||||
|
||||
union MYDATA_t {
|
||||
byte value[32];
|
||||
char now_time[32];
|
||||
};
|
||||
|
||||
MYDATA_t mydata;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Mirf.spi = &MirfHardwareSpi;
|
||||
Mirf.init();
|
||||
Mirf.payload = sizeof(mydata.value); // Set the payload size
|
||||
Mirf.channel = 90; //Set the channel used
|
||||
Mirf.config();
|
||||
|
||||
// Set my own address to RX_ADDR_P1
|
||||
Mirf.setRADDR((byte *)"ABCDE");
|
||||
|
||||
// Set destination address to TX_ADDR
|
||||
// Set ACK waiting address to RX_ADDR_P0
|
||||
Mirf.setTADDR((byte *)"FGHIJ");
|
||||
|
||||
// Print current settings
|
||||
printf_begin();
|
||||
Mirf.printDetails();
|
||||
|
||||
// Clear RX FiFo
|
||||
while(1) {
|
||||
if (Mirf.dataReady() == false) break;
|
||||
Mirf.getData(mydata.value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
sprintf(mydata.now_time,"now is %lu",micros());
|
||||
unsigned long startMillis = millis();
|
||||
Mirf.send(mydata.value);
|
||||
Serial.print("Wait for sending.....");
|
||||
// Verify send was successful
|
||||
if (Mirf.isSend()) {
|
||||
Serial.print("Send success:");
|
||||
Serial.println(mydata.now_time);
|
||||
|
||||
// Wait for received data
|
||||
Serial.print("Wait for response.....");
|
||||
while(1) {
|
||||
if (Mirf.dataReady()) break;
|
||||
}
|
||||
Mirf.getData(mydata.value);
|
||||
unsigned long diffMillis = millis() - startMillis;
|
||||
Serial.print("Got response:");
|
||||
Serial.print(mydata.now_time);
|
||||
Serial.print(" Elapsed:");
|
||||
Serial.print(diffMillis);
|
||||
Serial.println(" mSec");
|
||||
|
||||
} else {
|
||||
Serial.println("Send fail:");
|
||||
}
|
||||
delay(1000);
|
||||
}
|
37
esp-idf-mirf-master/ArduinoCode/Ping-Pong/Primary/printf.h
Normal file
37
esp-idf-mirf-master/ArduinoCode/Ping-Pong/Primary/printf.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
version 2 as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file printf.h
|
||||
*
|
||||
* Setup necessary to direct stdout to the Arduino Serial library, which
|
||||
* enables 'printf'
|
||||
*/
|
||||
|
||||
#ifndef __PRINTF_H__
|
||||
#define __PRINTF_H__
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
int serial_putc( char c, FILE * )
|
||||
{
|
||||
Serial.write( c );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void printf_begin(void)
|
||||
{
|
||||
fdevopen( &serial_putc, 0 );
|
||||
}
|
||||
|
||||
#else
|
||||
#error This example is only for use on Arduino.
|
||||
#endif // ARDUINO
|
||||
|
||||
#endif // __PRINTF_H__
|
9
esp-idf-mirf-master/ArduinoCode/Ping-Pong/README.md
Normal file
9
esp-idf-mirf-master/ArduinoCode/Ping-Pong/README.md
Normal file
@ -0,0 +1,9 @@
|
||||
# PingPong
|
||||
|
||||
```
|
||||
Primary -----> Secondary
|
||||
Primary <----- Secondary
|
||||
```
|
||||
|
||||

|
||||
|
@ -0,0 +1,63 @@
|
||||
//secondary program
|
||||
|
||||
#include "Mirf.h"
|
||||
#include "printf.h"
|
||||
|
||||
Nrf24l Mirf = Nrf24l(10, 9); // CE,CSN
|
||||
|
||||
union MYDATA_t {
|
||||
byte value[32];
|
||||
char now_time[32];
|
||||
};
|
||||
|
||||
MYDATA_t mydata;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Mirf.spi = &MirfHardwareSpi;
|
||||
Mirf.init();
|
||||
Mirf.payload = sizeof(mydata.value); // Set the payload size
|
||||
Mirf.channel = 90; // Set the used channel
|
||||
Mirf.config();
|
||||
|
||||
// Set my own address to RX_ADDR_P1
|
||||
Mirf.setRADDR((byte *)"FGHIJ");
|
||||
|
||||
// Set destination address to TX_ADDR
|
||||
// Set ACK waiting address to RX_ADDR_P0
|
||||
Mirf.setTADDR((byte *)"ABCDE");
|
||||
|
||||
// Print current settings
|
||||
printf_begin();
|
||||
Mirf.printDetails();
|
||||
Serial.println("Listening...");
|
||||
|
||||
// Clear RX FiFo
|
||||
while(1) {
|
||||
if (Mirf.dataReady() == false) break;
|
||||
Mirf.getData(mydata.value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Wait for received data
|
||||
if (Mirf.dataReady()) {
|
||||
Mirf.getData(mydata.value);
|
||||
Serial.print("Got string: ");
|
||||
Serial.println(mydata.now_time);
|
||||
|
||||
delay(10);
|
||||
Mirf.send(mydata.value);
|
||||
Serial.print("Wait for sending.....");
|
||||
// Verify send was successful
|
||||
if (Mirf.isSend()) {
|
||||
Serial.println("Send success:");
|
||||
} else {
|
||||
Serial.println("Send fail:");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
37
esp-idf-mirf-master/ArduinoCode/Ping-Pong/Secondary/printf.h
Normal file
37
esp-idf-mirf-master/ArduinoCode/Ping-Pong/Secondary/printf.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
version 2 as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file printf.h
|
||||
*
|
||||
* Setup necessary to direct stdout to the Arduino Serial library, which
|
||||
* enables 'printf'
|
||||
*/
|
||||
|
||||
#ifndef __PRINTF_H__
|
||||
#define __PRINTF_H__
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
int serial_putc( char c, FILE * )
|
||||
{
|
||||
Serial.write( c );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void printf_begin(void)
|
||||
{
|
||||
fdevopen( &serial_putc, 0 );
|
||||
}
|
||||
|
||||
#else
|
||||
#error This example is only for use on Arduino.
|
||||
#endif // ARDUINO
|
||||
|
||||
#endif // __PRINTF_H__
|
28
esp-idf-mirf-master/ArduinoCode/README.md
Normal file
28
esp-idf-mirf-master/ArduinoCode/README.md
Normal file
@ -0,0 +1,28 @@
|
||||
# Arduino code for nRF24L01
|
||||
|
||||
### Wirering
|
||||
|
||||
|nRF24L01||ATMega328|ATMega2560|ESP8266||
|
||||
|:-:|:-:|:-:|:-:|:-:|:-:|
|
||||
|VCC|--|3.3V|3.3V|3.3V|(*1)|
|
||||
|GND|--|GND|GND|GND||
|
||||
|MISO|--|D12|IO50|IO12||
|
||||
|MOSI(*2)|--|D11|IO51|IO13||
|
||||
|SCK(*2)|--|D13|IO52|IO14||
|
||||
|CE(*2)|--|D10|IO10|IO15|(*3)|
|
||||
|CSN(*2)|--|D9|IO9|IO16|(*3)|
|
||||
|
||||
(*1)
|
||||
UNO's 3.3V output can only supply 50mA.
|
||||
In addition, the output current capacity of UNO-compatible devices is smaller than that of official products.
|
||||
__So nRF24L01 may not work normally when supplied from the on-board 3v3__.
|
||||
nRF24L01+PA+LNA(nRF24L01+RFX24C01) needs 115mA.
|
||||
You will need to power it from the 5V pin using a regulator.
|
||||
|
||||
|
||||
(*2)
|
||||
These pins are 5V Tolerant and can accept up to 5.25V.
|
||||
|
||||
|
||||
(*3)
|
||||
These pins can be changed in the sketch.
|
8
esp-idf-mirf-master/IRQ-Detection/CMakeLists.txt
Normal file
8
esp-idf-mirf-master/IRQ-Detection/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS ../components/mirf)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(mirf)
|
53
esp-idf-mirf-master/IRQ-Detection/README.md
Normal file
53
esp-idf-mirf-master/IRQ-Detection/README.md
Normal file
@ -0,0 +1,53 @@
|
||||
# IRQ Detection Example
|
||||
Use IRQ to detect transmission completion and reception completion.
|
||||
|
||||
# About the nrf24l01 assertion
|
||||
|
||||
nrf24l01 has three assertions.
|
||||
- MAX_RT
|
||||
- RX_DR
|
||||
- TX_DS
|
||||
|
||||

|
||||
|
||||
After the packet is transmitted by the PTX and received by the PRX the ACK packet with payload is transmitted from the PRX to the PTX.
|
||||
The RX_DR IRQ is asserted after the packet is received by the PRX, whereas on the PTX side the TX_DS IRQ is asserted when the ACK packet is received by the PTX.
|
||||
On the PRX side, the TX_DS IRQ for the ACK packet payload is asserted after a new packet from PTX is received.
|
||||
|
||||

|
||||
|
||||
the ACK packet is lost and a retransmission is needed before the TX_DS IRQ is asserted, but the RX_DR IRQ is asserted immediately.
|
||||
MAX_RT IRQ is asserted if the auto retransmit counter(ARC_CNT) exceeds the programmed maximum limit(ARC).
|
||||
See the nrf24l01 datasheet for more details.
|
||||
|
||||
This project treats RX_DR as received completion.
|
||||
This project treats MAX_RT as transmission failure.
|
||||
Therefore, if there is no assertion after the transmission, the transmission succeeds, and if there is an assertion, the transmission fails.
|
||||
This project does not deal with TX_DS.
|
||||
|
||||
# Configuration
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
# Wirering
|
||||
__For this project we need one more connection for IRQ detection.__
|
||||
|nRF24L01||ESP32|ESP32-S2/S3|ESP32-C2/C3/C6||
|
||||
|:-:|:-:|:-:|:-:|:-:|:-:|
|
||||
|MISO|--|GPIO19|GPIO37|GPIO4|(*1)|
|
||||
|MOSI|--|GPIO23|GPIO35|GPIO3|(*1)|
|
||||
|SCK|--|GPIO18|GPIO36|GPIO2|(*1)|
|
||||
|CE|--|GPIO16|GPIO34|GPIO1|(*1)|
|
||||
|CSN|--|GPIO17|GPIO33|GPIO0|(*1)|
|
||||
|IRQ|--|GPIO15|GPIO38|GPIO5|(*1)|
|
||||
|GND|--|GND|GND|GND||
|
||||
|VCC|--|3.3V|3.3V|3.3V||
|
||||
|
||||
(*1)You can change it to any pin using menuconfig.
|
||||
__IRQ needs to be able to use interrupts.__
|
||||
__Some GPIOs cannot use interrupts.__
|
||||
|
||||
# Communicat with Arduino Environment
|
||||
Run this sketch.
|
||||
ArduinoCode\Peer-to-peer\StringTest
|
4
esp-idf-mirf-master/IRQ-Detection/main/CMakeLists.txt
Normal file
4
esp-idf-mirf-master/IRQ-Detection/main/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
set(component_srcs "main.c")
|
||||
|
||||
idf_component_register(SRCS "${component_srcs}"
|
||||
INCLUDE_DIRS ".")
|
39
esp-idf-mirf-master/IRQ-Detection/main/Kconfig.projbuild
Normal file
39
esp-idf-mirf-master/IRQ-Detection/main/Kconfig.projbuild
Normal file
@ -0,0 +1,39 @@
|
||||
menu "Application Configuration"
|
||||
|
||||
config GPIO_RANGE_MAX
|
||||
int
|
||||
default 33 if IDF_TARGET_ESP32
|
||||
default 46 if IDF_TARGET_ESP32S2
|
||||
default 48 if IDF_TARGET_ESP32S3
|
||||
default 18 if IDF_TARGET_ESP32C2
|
||||
default 19 if IDF_TARGET_ESP32C3
|
||||
default 30 if IDF_TARGET_ESP32C6
|
||||
|
||||
choice DIRECTION
|
||||
prompt "Communication polarity"
|
||||
default SENDER
|
||||
help
|
||||
Select Communication polarity.
|
||||
config SENDER
|
||||
bool "As the sender"
|
||||
help
|
||||
As the sender.
|
||||
config RECEIVER
|
||||
bool "As the receiver"
|
||||
help
|
||||
As the receiver.
|
||||
endchoice
|
||||
|
||||
config IRQ_GPIO
|
||||
int "IRQ GPIO number"
|
||||
range 0 GPIO_RANGE_MAX
|
||||
default 15 if IDF_TARGET_ESP32
|
||||
default 38 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
|
||||
default 5 # C3 and others
|
||||
help
|
||||
GPIO number (IOxx) to IRQ.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to MISO.
|
||||
On the ESP32, GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
On the ESP32-S2, GPIO 46 is input-only so cannot be used as outputs.
|
||||
|
||||
endmenu
|
5
esp-idf-mirf-master/IRQ-Detection/main/component.mk
Normal file
5
esp-idf-mirf-master/IRQ-Detection/main/component.mk
Normal file
@ -0,0 +1,5 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
|
181
esp-idf-mirf-master/IRQ-Detection/main/main.c
Normal file
181
esp-idf-mirf-master/IRQ-Detection/main/main.c
Normal file
@ -0,0 +1,181 @@
|
||||
/* Mirf Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
#include "mirf.h"
|
||||
|
||||
static QueueHandle_t gpio_evt_queue = NULL;
|
||||
|
||||
#define GPIO_INPUT_PIN_SEL (1ULL<<CONFIG_IRQ_GPIO)
|
||||
#define ESP_INTR_FLAG_DEFAULT 0
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
void AdvancedSettings(NRF24_t * dev)
|
||||
{
|
||||
#if CONFIG_RF_RATIO_2M
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 2MBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 1);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
#if CONFIG_RF_RATIO_1M
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 1MBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 0);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
#if CONFIG_RF_RATIO_250K
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 250KBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 2);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
ESP_LOGW(pcTaskGetName(0), "CONFIG_RETRANSMIT_DELAY=%d", CONFIG_RETRANSMIT_DELAY);
|
||||
Nrf24_setRetransmitDelay(dev, CONFIG_RETRANSMIT_DELAY);
|
||||
}
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
// GPIO interrupt handler
|
||||
static void IRAM_ATTR gpio_isr_handler(void* arg)
|
||||
{
|
||||
uint32_t gpio_num = (uint32_t) arg;
|
||||
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
|
||||
}
|
||||
|
||||
|
||||
#if CONFIG_RECEIVER
|
||||
void receiver(void *pvParameters)
|
||||
{
|
||||
ESP_LOGI(pcTaskGetName(0), "Start");
|
||||
NRF24_t dev;
|
||||
Nrf24_init(&dev);
|
||||
uint8_t payload = 32;
|
||||
uint8_t channel = CONFIG_RADIO_CHANNEL;
|
||||
Nrf24_config(&dev, channel, payload);
|
||||
|
||||
// Set my own address using 5 characters
|
||||
esp_err_t ret = Nrf24_setRADDR(&dev, (uint8_t *)"FGHIJ");
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(pcTaskGetName(0), "nrf24l01 not installed");
|
||||
while(1) { vTaskDelay(1); }
|
||||
}
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
AdvancedSettings(&dev);
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
// Print settings
|
||||
Nrf24_printDetails(&dev);
|
||||
ESP_LOGI(pcTaskGetName(0), "Listening...");
|
||||
|
||||
uint8_t buf[32];
|
||||
|
||||
// Clear RX FiFo
|
||||
while(1) {
|
||||
if (Nrf24_dataReady(&dev) == false) break;
|
||||
Nrf24_getData(&dev, buf);
|
||||
}
|
||||
|
||||
uint32_t io_num;
|
||||
|
||||
while(1) {
|
||||
// Wait for assertion of RX receive complete(RX_DR)
|
||||
if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
|
||||
ESP_LOGD(pcTaskGetName(0), "GPIO[%"PRIu32"] intr, val: %d", io_num, gpio_get_level(io_num));
|
||||
Nrf24_getData(&dev, buf);
|
||||
ESP_LOGI(pcTaskGetName(0), "Got data:%s", buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_RECEIVER
|
||||
|
||||
|
||||
#if CONFIG_SENDER
|
||||
void sender(void *pvParameters)
|
||||
{
|
||||
ESP_LOGI(pcTaskGetName(0), "Start");
|
||||
NRF24_t dev;
|
||||
Nrf24_init(&dev);
|
||||
uint8_t payload = 32;
|
||||
uint8_t channel = CONFIG_RADIO_CHANNEL;
|
||||
Nrf24_config(&dev, channel, payload);
|
||||
|
||||
// Set destination address using 5 characters
|
||||
esp_err_t ret = Nrf24_setTADDR(&dev, (uint8_t *)"FGHIJ");
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(pcTaskGetName(0), "nrf24l01 not installed");
|
||||
while(1) { vTaskDelay(1); }
|
||||
}
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
AdvancedSettings(&dev);
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
//Print settings
|
||||
Nrf24_printDetails(&dev);
|
||||
|
||||
uint8_t buf[32];
|
||||
uint32_t io_num;
|
||||
while(1) {
|
||||
TickType_t nowTick = xTaskGetTickCount();
|
||||
sprintf((char *)buf, "Hello World %"PRIu32, nowTick);
|
||||
Nrf24_send(&dev, buf);
|
||||
ESP_LOGI(pcTaskGetName(0), "Wait for sending.....");
|
||||
// Wait for assertion of TX transmit retry over(MAX_RT)
|
||||
if(xQueueReceive(gpio_evt_queue, &io_num, 1000/portTICK_PERIOD_MS)) {
|
||||
ESP_LOGW(pcTaskGetName(0),"Send fail:");
|
||||
|
||||
// Assert does not occur after successful transmission
|
||||
} else {
|
||||
ESP_LOGD(pcTaskGetName(0), "GPIO[%"PRIu32"] intr, val: %d", io_num, gpio_get_level(io_num));
|
||||
ESP_LOGI(pcTaskGetName(0),"Send success:%s", buf);
|
||||
}
|
||||
vTaskDelay(1000/portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_SENDER
|
||||
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Initialize gpio
|
||||
//zero-initialize the config structure.
|
||||
gpio_config_t io_conf = {};
|
||||
//interrupt of falling edge
|
||||
io_conf.intr_type = GPIO_INTR_NEGEDGE;
|
||||
//bit mask of the pins, use GPIO4/5 here
|
||||
io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
|
||||
//set as input mode
|
||||
io_conf.mode = GPIO_MODE_INPUT;
|
||||
//enable pull-up mode
|
||||
io_conf.pull_up_en = 1;
|
||||
gpio_config(&io_conf);
|
||||
//install gpio isr service
|
||||
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
|
||||
//hook isr handler for specific gpio pin
|
||||
gpio_isr_handler_add(CONFIG_IRQ_GPIO, gpio_isr_handler, (void*) CONFIG_IRQ_GPIO);
|
||||
//create a queue to handle gpio event from isr
|
||||
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
|
||||
|
||||
|
||||
#if CONFIG_RECEIVER
|
||||
xTaskCreate(&receiver, "RECEIVER", 1024*3, NULL, 2, NULL);
|
||||
#endif
|
||||
|
||||
#if CONFIG_SENDER
|
||||
xTaskCreate(&sender, "SENDER", 1024*3, NULL, 2, NULL);
|
||||
#endif
|
||||
|
||||
}
|
21
esp-idf-mirf-master/LICENSE
Normal file
21
esp-idf-mirf-master/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 nopnop2002
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
8
esp-idf-mirf-master/Multiple-Receive/CMakeLists.txt
Normal file
8
esp-idf-mirf-master/Multiple-Receive/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS ../components/mirf)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(mirf)
|
42
esp-idf-mirf-master/Multiple-Receive/README.md
Normal file
42
esp-idf-mirf-master/Multiple-Receive/README.md
Normal file
@ -0,0 +1,42 @@
|
||||
# Multiple Receive Example
|
||||
The nRF24L01 has 6 receive data pipes (RX_ADDR_P0-P6).
|
||||
In this library, the first data pipe(RX_ADDR_P0) is used for automatic ACK reception on transmission.
|
||||
The second(RX_ADDR_P1) to sixth(RX_ADDR_P5) data pipes are used for data reception.
|
||||
Therefore, it is possible to receive from a maximum of five transmitting sides.
|
||||
This example receive from ```1RECV/2RECV/3RECV/4RECV/5RECV```.
|
||||
|
||||
# nRF24L01 Address Register Setting
|
||||
|Sender|||||Receiver||||||
|
||||
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|
||||
|#1|TX_ADDR<br>"1RECV"|RX_ADDR_P0<br>"1RECV"|RX_ADDR_P1<br>NONE||TX_ADDR<br>NONE|RX_ADDR_P0<br>NONE|RX_ADDR_P1<br>"1RECV"|RX_ADDR_P2<br>"2RECV"|RX_ADDR_P5<br>"5RECV"||
|
||||
||(Send Data)|->|->|->|->|->|(Get Data)|||Data to Receiver|
|
||||
|||(Get Ack)|<-|<-|<-|<-|(Send Ack)|||Ack to Sender|
|
||||
|#2|TX_ADDR<br>"2RECV"|RX_ADDR_P0<br>"2RECV"|RX_ADDR_P1<br>NONE||TX_ADDR<br>NONE|RX_ADDR_P0<br>NONE|RX_ADDR_P1<br>"1RECV"|RX_ADDR_P2<br>"2RECV"|RX_ADDR_P5<br>"5RECV"||
|
||||
||(Send Data)|->|->|->|->|->|->|(Get Data)||Data to Receiver|
|
||||
|||(Get Ack)|<-|<-|<-|<-|<-|(Send Ack)||Ack to Sender|
|
||||
|#5|TX_ADDR<br>"5RECV"|RX_ADDR_P0<br>"5RECV"|RX_ADDR_P1<br>NONE||TX_ADDR<br>NONE|RX_ADDR_P0<br>NONE|RX_ADDR_P1<br>"1RECV"|RX_ADDR_P2<br>"2RECV"|RX_ADDR_P5<br>"5RECV"||
|
||||
||(Send Data)|->|->|->|->|->|->|->|(Get Data)|Data to Receiver|
|
||||
|||(Get Ack)|<-|<-|<-|<-|<-|<-|(Send Ack)|Ack to Sender|
|
||||
|
||||
|
||||
# Configuration
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
# Receiver Register
|
||||
RX_ADDR_P1 is 0x3152454356.
|
||||
RX_ADDR_P2 will be 0x3252454356. The same value is used for the last 4 bytes.
|
||||

|
||||
|
||||
# Communicat with Arduino Environment
|
||||
Run this sketch.
|
||||
ArduinoCode\Multiple-Receive/EmitterX
|
||||
|
||||
|
||||
# Receiver screenshot
|
||||
|
||||
This is received from 5 units at the same time.
|
||||

|
||||
|
4
esp-idf-mirf-master/Multiple-Receive/main/CMakeLists.txt
Normal file
4
esp-idf-mirf-master/Multiple-Receive/main/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
set(component_srcs "main.c")
|
||||
|
||||
idf_component_register(SRCS "${component_srcs}"
|
||||
INCLUDE_DIRS ".")
|
47
esp-idf-mirf-master/Multiple-Receive/main/Kconfig.projbuild
Normal file
47
esp-idf-mirf-master/Multiple-Receive/main/Kconfig.projbuild
Normal file
@ -0,0 +1,47 @@
|
||||
menu "Application Configuration"
|
||||
|
||||
choice DIRECTION
|
||||
prompt "Communication polarity"
|
||||
default RECEIVER
|
||||
help
|
||||
Select Communication polarity.
|
||||
config SENDER
|
||||
bool "As the sender"
|
||||
help
|
||||
As the sender.
|
||||
config RECEIVER
|
||||
bool "As the receiver"
|
||||
help
|
||||
As the receiver.
|
||||
endchoice
|
||||
|
||||
choice TADDR
|
||||
prompt "Sender's address"
|
||||
depends on SENDER
|
||||
default TADDR1
|
||||
help
|
||||
Select sender's address.
|
||||
config TADDR1
|
||||
bool "Use 1 as sender's address"
|
||||
help
|
||||
Use 1 as sender's address
|
||||
config TADDR2
|
||||
bool "Use 2 as sender's address"
|
||||
help
|
||||
Use 2 as sender's address
|
||||
config TADDR3
|
||||
bool "Use 3 as sender's address"
|
||||
help
|
||||
Use 3 as sender's address
|
||||
config TADDR4
|
||||
bool "Use 4 as sender's address"
|
||||
help
|
||||
Use 4 as sender's address
|
||||
config TADDR5
|
||||
bool "Use 5 as sender's address"
|
||||
help
|
||||
Use 5 as sender's address
|
||||
|
||||
endchoice
|
||||
|
||||
endmenu
|
5
esp-idf-mirf-master/Multiple-Receive/main/component.mk
Normal file
5
esp-idf-mirf-master/Multiple-Receive/main/component.mk
Normal file
@ -0,0 +1,5 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
|
161
esp-idf-mirf-master/Multiple-Receive/main/main.c
Normal file
161
esp-idf-mirf-master/Multiple-Receive/main/main.c
Normal file
@ -0,0 +1,161 @@
|
||||
/* Mirf Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "mirf.h"
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
void AdvancedSettings(NRF24_t * dev)
|
||||
{
|
||||
#if CONFIG_RF_RATIO_2M
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 2MBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 1);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
#if CONFIG_RF_RATIO_1M
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 1MBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 0);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
#if CONFIG_RF_RATIO_250K
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 250KBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 2);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
ESP_LOGW(pcTaskGetName(0), "CONFIG_RETRANSMIT_DELAY=%d", CONFIG_RETRANSMIT_DELAY);
|
||||
Nrf24_setRetransmitDelay(dev, CONFIG_RETRANSMIT_DELAY);
|
||||
}
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
#if CONFIG_RECEIVER
|
||||
void receiver(void *pvParameters)
|
||||
{
|
||||
ESP_LOGI(pcTaskGetName(0), "Start");
|
||||
NRF24_t dev;
|
||||
Nrf24_init(&dev);
|
||||
uint8_t payload = 32;
|
||||
uint8_t channel = CONFIG_RADIO_CHANNEL;
|
||||
Nrf24_config(&dev, channel, payload);
|
||||
|
||||
// Set my own address using 5 characters
|
||||
esp_err_t ret = Nrf24_setRADDR(&dev, (uint8_t *)"1RECV");
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(pcTaskGetName(0), "nrf24l01 not installed");
|
||||
while(1) { vTaskDelay(1); }
|
||||
}
|
||||
|
||||
// Add my own address using 1 characters
|
||||
Nrf24_addRADDR(&dev, 2, '2'); // 2RECV
|
||||
Nrf24_addRADDR(&dev, 3, '3'); // 3RECV
|
||||
Nrf24_addRADDR(&dev, 4, '4'); // 4RECV
|
||||
Nrf24_addRADDR(&dev, 5, '5'); // 5RECV
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
AdvancedSettings(&dev);
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
// Print settings
|
||||
Nrf24_printDetails(&dev);
|
||||
ESP_LOGI(pcTaskGetName(0), "Listening...");
|
||||
|
||||
uint8_t buf[32];
|
||||
|
||||
// Clear RX FiFo
|
||||
while(1) {
|
||||
if (Nrf24_dataReady(&dev) == false) break;
|
||||
Nrf24_getData(&dev, buf);
|
||||
}
|
||||
|
||||
while(1) {
|
||||
// Wait for received data
|
||||
if (Nrf24_dataReady(&dev)) {
|
||||
uint8_t pipe = Nrf24_getDataPipe(&dev);
|
||||
Nrf24_getData(&dev, buf);
|
||||
ESP_LOGI(pcTaskGetName(0), "Got data pipe(%d):%s", pipe, buf);
|
||||
}
|
||||
vTaskDelay(1);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_RECEIVER
|
||||
|
||||
#if CONFIG_SENDER
|
||||
void sender(void *pvParameters)
|
||||
{
|
||||
ESP_LOGI(pcTaskGetName(0), "Start");
|
||||
NRF24_t dev;
|
||||
Nrf24_init(&dev);
|
||||
uint8_t payload = 32;
|
||||
uint8_t channel = CONFIG_RADIO_CHANNEL;
|
||||
Nrf24_config(&dev, channel, payload);
|
||||
|
||||
// Set destination address using 5 characters
|
||||
int sender_id;
|
||||
#if CONFIG_TADDR1
|
||||
esp_err_t ret = Nrf24_setTADDR(&dev, (uint8_t *)"1RECV");
|
||||
sender_id = 1;
|
||||
#elif CONFIG_TADDR2
|
||||
esp_err_t ret = Nrf24_setTADDR(&dev, (uint8_t *)"2RECV");
|
||||
sender_id = 2;
|
||||
#elif CONFIG_TADDR3
|
||||
esp_err_t ret = Nrf24_setTADDR(&dev, (uint8_t *)"3RECV");
|
||||
sender_id = 3;
|
||||
#elif CONFIG_TADDR4
|
||||
esp_err_t ret = Nrf24_setTADDR(&dev, (uint8_t *)"4RECV");
|
||||
sender_id = 4;
|
||||
#elif CONFIG_TADDR5
|
||||
esp_err_t ret = Nrf24_setTADDR(&dev, (uint8_t *)"5RECV");
|
||||
sender_id = 5;
|
||||
#endif
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(pcTaskGetName(0), "nrf24l01 not installed");
|
||||
while(1) { vTaskDelay(1); }
|
||||
}
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
AdvancedSettings(&dev);
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
// Print settings
|
||||
Nrf24_printDetails(&dev);
|
||||
|
||||
uint8_t buf[32];
|
||||
while(1) {
|
||||
TickType_t nowTick = xTaskGetTickCount();
|
||||
sprintf((char *)buf, "Hello World %"PRIu32" from %d", nowTick, sender_id);
|
||||
Nrf24_send(&dev, buf);
|
||||
vTaskDelay(1);
|
||||
ESP_LOGI(pcTaskGetName(0), "Wait for sending.....");
|
||||
if (Nrf24_isSend(&dev, 1000)) {
|
||||
ESP_LOGI(pcTaskGetName(0),"Send success:%s", buf);
|
||||
} else {
|
||||
ESP_LOGW(pcTaskGetName(0),"Send fail:");
|
||||
}
|
||||
vTaskDelay(1000/portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_SENDER
|
||||
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
#if CONFIG_RECEIVER
|
||||
xTaskCreate(&receiver, "RECEIVER", 1024*3, NULL, 2, NULL);
|
||||
#endif
|
||||
|
||||
#if CONFIG_SENDER
|
||||
xTaskCreate(&sender, "SENDER", 1024*3, NULL, 2, NULL);
|
||||
#endif
|
||||
}
|
8
esp-idf-mirf-master/Peer-to-peer-indexed/CMakeLists.txt
Normal file
8
esp-idf-mirf-master/Peer-to-peer-indexed/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS ../components/mirf)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(mirf)
|
17
esp-idf-mirf-master/Peer-to-peer-indexed/README.md
Normal file
17
esp-idf-mirf-master/Peer-to-peer-indexed/README.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Peer-to-peer
|
||||
One-way communication for transmission or reception with index.
|
||||
nRF24L01 can send and receive up to 32 characters, but by adding an index to the sent data, it can send and receive 256 types of data.
|
||||
|
||||
# Configuration
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
# Screen Shot
|
||||

|
||||
|
||||
|
||||
# Communicat with Arduino Environment
|
||||
Run this sketch.
|
||||
ArduinoCode\Peer-to-peer\IndexedStringTest
|
@ -0,0 +1,4 @@
|
||||
set(component_srcs "main.c")
|
||||
|
||||
idf_component_register(SRCS "${component_srcs}"
|
||||
INCLUDE_DIRS ".")
|
@ -0,0 +1,18 @@
|
||||
menu "Application Configuration"
|
||||
|
||||
choice DIRECTION
|
||||
prompt "Communication polarity"
|
||||
default SENDER
|
||||
help
|
||||
Select Communication polarity.
|
||||
config SENDER
|
||||
bool "As the sender"
|
||||
help
|
||||
As the sender.
|
||||
config RECEIVER
|
||||
bool "As the receiver"
|
||||
help
|
||||
As the receiver.
|
||||
endchoice
|
||||
|
||||
endmenu
|
@ -0,0 +1,5 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
|
144
esp-idf-mirf-master/Peer-to-peer-indexed/main/main.c
Normal file
144
esp-idf-mirf-master/Peer-to-peer-indexed/main/main.c
Normal file
@ -0,0 +1,144 @@
|
||||
/* Mirf Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "mirf.h"
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
void AdvancedSettings(NRF24_t * dev)
|
||||
{
|
||||
#if CONFIG_RF_RATIO_2M
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 2MBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 1);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
#if CONFIG_RF_RATIO_1M
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 1MBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 0);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
#if CONFIG_RF_RATIO_250K
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 250KBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 2);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
ESP_LOGW(pcTaskGetName(0), "CONFIG_RETRANSMIT_DELAY=%d", CONFIG_RETRANSMIT_DELAY);
|
||||
Nrf24_setRetransmitDelay(dev, CONFIG_RETRANSMIT_DELAY);
|
||||
}
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
#if CONFIG_RECEIVER
|
||||
void receiver(void *pvParameters)
|
||||
{
|
||||
ESP_LOGI(pcTaskGetName(0), "Start");
|
||||
NRF24_t dev;
|
||||
Nrf24_init(&dev);
|
||||
uint8_t payload = 32;
|
||||
uint8_t channel = CONFIG_RADIO_CHANNEL;
|
||||
Nrf24_config(&dev, channel, payload);
|
||||
|
||||
// Set my own address using 5 characters
|
||||
esp_err_t ret = Nrf24_setRADDR(&dev, (uint8_t *)"FGHIJ");
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(pcTaskGetName(0), "nrf24l01 not installed");
|
||||
while(1) { vTaskDelay(1); }
|
||||
}
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
AdvancedSettings(&dev);
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
// Print settings
|
||||
Nrf24_printDetails(&dev);
|
||||
ESP_LOGI(pcTaskGetName(0), "Listening...");
|
||||
|
||||
uint8_t buf[32];
|
||||
|
||||
// Clear RX FiFo
|
||||
while(1) {
|
||||
if (Nrf24_dataReady(&dev) == false) break;
|
||||
Nrf24_getData(&dev, buf);
|
||||
}
|
||||
|
||||
while(1) {
|
||||
// Wait for received data
|
||||
if (Nrf24_dataReady(&dev)) {
|
||||
Nrf24_getData(&dev, buf);
|
||||
ESP_LOGI(pcTaskGetName(0), "Got data:%d [%s]", buf[0], &buf[1]);
|
||||
//ESP_LOG_BUFFER_HEXDUMP(pcTaskGetName(0), buf, payload, ESP_LOG_INFO);
|
||||
}
|
||||
vTaskDelay(1);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_RECEIVER
|
||||
|
||||
|
||||
#if CONFIG_SENDER
|
||||
void sender(void *pvParameters)
|
||||
{
|
||||
ESP_LOGI(pcTaskGetName(0), "Start");
|
||||
NRF24_t dev;
|
||||
Nrf24_init(&dev);
|
||||
uint8_t payload = 32;
|
||||
uint8_t channel = CONFIG_RADIO_CHANNEL;
|
||||
Nrf24_config(&dev, channel, payload);
|
||||
|
||||
// Set destination address using 5 characters
|
||||
esp_err_t ret = Nrf24_setTADDR(&dev, (uint8_t *)"FGHIJ");
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(pcTaskGetName(0), "nrf24l01 not installed");
|
||||
while(1) { vTaskDelay(1); }
|
||||
}
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
AdvancedSettings(&dev);
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
// Print settings
|
||||
Nrf24_printDetails(&dev);
|
||||
|
||||
uint8_t buf[32];
|
||||
uint8_t index = 0;
|
||||
while(1) {
|
||||
TickType_t nowTick = xTaskGetTickCount();
|
||||
buf[0] = index;
|
||||
sprintf((char *)&buf[1], "Hello World %"PRIu32, nowTick);
|
||||
Nrf24_send(&dev, buf);
|
||||
vTaskDelay(1);
|
||||
ESP_LOGI(pcTaskGetName(0), "Wait for sending.....");
|
||||
if (Nrf24_isSend(&dev, 1000)) {
|
||||
ESP_LOGI(pcTaskGetName(0),"Send success:%d [%s]", buf[0], &buf[1]);
|
||||
index++;
|
||||
} else {
|
||||
ESP_LOGW(pcTaskGetName(0),"Send fail:");
|
||||
}
|
||||
vTaskDelay(1000/portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_SENDER
|
||||
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
#if CONFIG_RECEIVER
|
||||
xTaskCreate(&receiver, "RECEIVER", 1024*3, NULL, 2, NULL);
|
||||
#endif
|
||||
|
||||
#if CONFIG_SENDER
|
||||
xTaskCreate(&sender, "SENDER", 1024*3, NULL, 2, NULL);
|
||||
#endif
|
||||
|
||||
}
|
8
esp-idf-mirf-master/Peer-to-peer/CMakeLists.txt
Normal file
8
esp-idf-mirf-master/Peer-to-peer/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS ../components/mirf)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(mirf)
|
55
esp-idf-mirf-master/Peer-to-peer/README.md
Normal file
55
esp-idf-mirf-master/Peer-to-peer/README.md
Normal file
@ -0,0 +1,55 @@
|
||||
# Peer-to-peer Example
|
||||
One-way communication for transmission or reception.
|
||||
|
||||
# Configuration
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
# Parameter Setting
|
||||
The following parameters must match on the sender and receiver.
|
||||
|
||||
## Payload size & channel
|
||||
```
|
||||
uint8_t payload = 32;
|
||||
uint8_t channel = CONFIG_RADIO_CHANNEL;
|
||||
```
|
||||
|
||||
## Sender side
|
||||
```
|
||||
// Set destination address using 5 characters
|
||||
esp_err_t ret = Nrf24_setTADDR(&dev, (uint8_t *)"FGHIJ");
|
||||
```
|
||||
|
||||
## Receiver side
|
||||
```
|
||||
// Set my own address using 5 characters
|
||||
esp_err_t ret = Nrf24_setRADDR(&dev, (uint8_t *)"FGHIJ");
|
||||
```
|
||||
|
||||
# nRF24L01 Address Register Setting
|
||||
|Sender||||Receiver||||
|
||||
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|
||||
|TX_ADDR<br>"FGHIJ"|RX_ADDR_P0<br>"FGHIJ"|RX_ADDR_P1<br>NONE||TX_ADDR<br>NONE|RX_ADDR_P0<br>NONE|RX_ADDR_P1<br>"FGHIJ"||
|
||||
|(Send Data)|->|->|->|->|->|(Get Data)|Data to Receiver|
|
||||
||(Get Ack)|<-|<-|<-|<-|(Send Ack)|Ack to Sender|
|
||||
|
||||
# Setting Register
|
||||
The underlined address match on the sending and receiving sides.
|
||||
No other addresses are used.
|
||||
|
||||
### Sender Register
|
||||

|
||||
|
||||
### Receiver Register
|
||||

|
||||
|
||||
# Screen Shot
|
||||

|
||||
|
||||
|
||||
# Communicat with Arduino Environment
|
||||
Run this sketch.
|
||||
ArduinoCode\Peer-to-peer\StringTest
|
||||
|
4
esp-idf-mirf-master/Peer-to-peer/main/CMakeLists.txt
Normal file
4
esp-idf-mirf-master/Peer-to-peer/main/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
set(component_srcs "main.c")
|
||||
|
||||
idf_component_register(SRCS "${component_srcs}"
|
||||
INCLUDE_DIRS ".")
|
18
esp-idf-mirf-master/Peer-to-peer/main/Kconfig.projbuild
Normal file
18
esp-idf-mirf-master/Peer-to-peer/main/Kconfig.projbuild
Normal file
@ -0,0 +1,18 @@
|
||||
menu "Application Configuration"
|
||||
|
||||
choice DIRECTION
|
||||
prompt "Communication polarity"
|
||||
default SENDER
|
||||
help
|
||||
Select Communication polarity.
|
||||
config SENDER
|
||||
bool "As the sender"
|
||||
help
|
||||
As the sender.
|
||||
config RECEIVER
|
||||
bool "As the receiver"
|
||||
help
|
||||
As the receiver.
|
||||
endchoice
|
||||
|
||||
endmenu
|
5
esp-idf-mirf-master/Peer-to-peer/main/component.mk
Normal file
5
esp-idf-mirf-master/Peer-to-peer/main/component.mk
Normal file
@ -0,0 +1,5 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
|
141
esp-idf-mirf-master/Peer-to-peer/main/main.c
Normal file
141
esp-idf-mirf-master/Peer-to-peer/main/main.c
Normal file
@ -0,0 +1,141 @@
|
||||
/* Mirf Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "mirf.h"
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
void AdvancedSettings(NRF24_t * dev)
|
||||
{
|
||||
#if CONFIG_RF_RATIO_2M
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 2MBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 1);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
#if CONFIG_RF_RATIO_1M
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 1MBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 0);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
#if CONFIG_RF_RATIO_250K
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 250KBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 2);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
ESP_LOGW(pcTaskGetName(0), "CONFIG_RETRANSMIT_DELAY=%d", CONFIG_RETRANSMIT_DELAY);
|
||||
Nrf24_setRetransmitDelay(dev, CONFIG_RETRANSMIT_DELAY);
|
||||
}
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
#if CONFIG_RECEIVER
|
||||
void receiver(void *pvParameters)
|
||||
{
|
||||
ESP_LOGI(pcTaskGetName(0), "Start");
|
||||
NRF24_t dev;
|
||||
Nrf24_init(&dev);
|
||||
uint8_t payload = 32;
|
||||
uint8_t channel = CONFIG_RADIO_CHANNEL;
|
||||
Nrf24_config(&dev, channel, payload);
|
||||
|
||||
// Set my own address using 5 characters
|
||||
esp_err_t ret = Nrf24_setRADDR(&dev, (uint8_t *)"FGHIJ");
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(pcTaskGetName(0), "nrf24l01 not installed");
|
||||
while(1) { vTaskDelay(1); }
|
||||
}
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
AdvancedSettings(&dev);
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
// Print settings
|
||||
Nrf24_printDetails(&dev);
|
||||
ESP_LOGI(pcTaskGetName(0), "Listening...");
|
||||
|
||||
uint8_t buf[32];
|
||||
|
||||
// Clear RX FiFo
|
||||
while(1) {
|
||||
if (Nrf24_dataReady(&dev) == false) break;
|
||||
Nrf24_getData(&dev, buf);
|
||||
}
|
||||
|
||||
while(1) {
|
||||
// Wait for received data
|
||||
if (Nrf24_dataReady(&dev)) {
|
||||
Nrf24_getData(&dev, buf);
|
||||
ESP_LOGI(pcTaskGetName(0), "Got data:%s", buf);
|
||||
//ESP_LOG_BUFFER_HEXDUMP(pcTaskGetName(0), buf, payload, ESP_LOG_INFO);
|
||||
}
|
||||
vTaskDelay(1);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_RECEIVER
|
||||
|
||||
|
||||
#if CONFIG_SENDER
|
||||
void sender(void *pvParameters)
|
||||
{
|
||||
ESP_LOGI(pcTaskGetName(0), "Start");
|
||||
NRF24_t dev;
|
||||
Nrf24_init(&dev);
|
||||
uint8_t payload = 32;
|
||||
uint8_t channel = CONFIG_RADIO_CHANNEL;
|
||||
Nrf24_config(&dev, channel, payload);
|
||||
|
||||
// Set destination address using 5 characters
|
||||
esp_err_t ret = Nrf24_setTADDR(&dev, (uint8_t *)"FGHIJ");
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(pcTaskGetName(0), "nrf24l01 not installed");
|
||||
while(1) { vTaskDelay(1); }
|
||||
}
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
AdvancedSettings(&dev);
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
// Print settings
|
||||
Nrf24_printDetails(&dev);
|
||||
|
||||
uint8_t buf[32];
|
||||
while(1) {
|
||||
TickType_t nowTick = xTaskGetTickCount();
|
||||
sprintf((char *)buf, "Hello World %"PRIu32, nowTick);
|
||||
Nrf24_send(&dev, buf);
|
||||
vTaskDelay(1);
|
||||
ESP_LOGI(pcTaskGetName(0), "Wait for sending.....");
|
||||
if (Nrf24_isSend(&dev, 1000)) {
|
||||
ESP_LOGI(pcTaskGetName(0),"Send success:%s", buf);
|
||||
} else {
|
||||
ESP_LOGW(pcTaskGetName(0),"Send fail:");
|
||||
}
|
||||
vTaskDelay(1000/portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_SENDER
|
||||
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
#if CONFIG_RECEIVER
|
||||
xTaskCreate(&receiver, "RECEIVER", 1024*3, NULL, 2, NULL);
|
||||
#endif
|
||||
|
||||
#if CONFIG_SENDER
|
||||
xTaskCreate(&sender, "SENDER", 1024*3, NULL, 2, NULL);
|
||||
#endif
|
||||
|
||||
}
|
8
esp-idf-mirf-master/Ping-Pong/CMakeLists.txt
Normal file
8
esp-idf-mirf-master/Ping-Pong/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS ../components/mirf)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(mirf)
|
35
esp-idf-mirf-master/Ping-Pong/README.md
Normal file
35
esp-idf-mirf-master/Ping-Pong/README.md
Normal file
@ -0,0 +1,35 @@
|
||||
# Ping-Pong Example
|
||||
Send data from primary to secondary.
|
||||
In the secondary, sent back received data.
|
||||
|
||||
|
||||
# Configuration
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
# nRF24L01 Address Register Setting
|
||||
|Primary||||Secondary||||
|
||||
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|
||||
|TX_ADDR<br>"FGHIJ"|RX_ADDR_P0<br>"FGHIJ"|RX_ADDR_P1<br>"ABCDE"||TX_ADDR<br>"ABCDE"|RX_ADDR_P0<br>"ABCDE"|RX_ADDR_P1<br>"FGHIJ"||
|
||||
|(Send Data)|->|->|->|->|->|(Get Data)|Data to Secondary|
|
||||
||(Get Ack)|<-|<-|<-|<-|(Send Ack)|Ack to Primary|
|
||||
|||||||||
|
||||
|||(Get Data)|<-|(Send Data)|||Data to Primary|
|
||||
|||(Send Ack)|->|->|(Get Ack)||Ack to Secondary|
|
||||
|
||||
# Setting Register
|
||||
The underlined address match on the sending and receiving sides.
|
||||
|
||||
### Primary Register
|
||||

|
||||
|
||||
### Secondary Register
|
||||

|
||||
|
||||
|
||||
# Communicat with Arduino Environment
|
||||
Run this sketch.
|
||||
ArduinoCode/Ping-Pong
|
||||
|
4
esp-idf-mirf-master/Ping-Pong/main/CMakeLists.txt
Normal file
4
esp-idf-mirf-master/Ping-Pong/main/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
set(component_srcs "main.c")
|
||||
|
||||
idf_component_register(SRCS "${component_srcs}"
|
||||
INCLUDE_DIRS ".")
|
18
esp-idf-mirf-master/Ping-Pong/main/Kconfig.projbuild
Normal file
18
esp-idf-mirf-master/Ping-Pong/main/Kconfig.projbuild
Normal file
@ -0,0 +1,18 @@
|
||||
menu "Application Configuration"
|
||||
|
||||
choice POLARITY
|
||||
prompt "Communication Polarity"
|
||||
default PRIMARY
|
||||
help
|
||||
Select Communication Polarity.
|
||||
config PRIMARY
|
||||
bool "Primary"
|
||||
help
|
||||
As Echo Client.
|
||||
config SECONDARY
|
||||
bool "Secondary"
|
||||
help
|
||||
As Echo Server.
|
||||
endchoice
|
||||
|
||||
endmenu
|
5
esp-idf-mirf-master/Ping-Pong/main/component.mk
Normal file
5
esp-idf-mirf-master/Ping-Pong/main/component.mk
Normal file
@ -0,0 +1,5 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
|
178
esp-idf-mirf-master/Ping-Pong/main/main.c
Normal file
178
esp-idf-mirf-master/Ping-Pong/main/main.c
Normal file
@ -0,0 +1,178 @@
|
||||
/* Mirf Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "mirf.h"
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
void AdvancedSettings(NRF24_t * dev)
|
||||
{
|
||||
#if CONFIG_RF_RATIO_2M
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 2MBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 1);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
#if CONFIG_RF_RATIO_1M
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 1MBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 0);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
#if CONFIG_RF_RATIO_250K
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 250KBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 2);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
ESP_LOGW(pcTaskGetName(0), "CONFIG_RETRANSMIT_DELAY=%d", CONFIG_RETRANSMIT_DELAY);
|
||||
Nrf24_setRetransmitDelay(dev, CONFIG_RETRANSMIT_DELAY);
|
||||
}
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
#if CONFIG_PRIMARY
|
||||
void primary(void *pvParameters)
|
||||
{
|
||||
ESP_LOGI(pcTaskGetName(0), "Start");
|
||||
NRF24_t dev;
|
||||
Nrf24_init(&dev);
|
||||
uint8_t payload = 32;
|
||||
uint8_t channel = CONFIG_RADIO_CHANNEL;
|
||||
Nrf24_config(&dev, channel, payload);
|
||||
|
||||
// Set my own address using 5 characters
|
||||
esp_err_t ret = Nrf24_setRADDR(&dev, (uint8_t *)"ABCDE");
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(pcTaskGetName(0), "nrf24l01 not installed");
|
||||
while(1) { vTaskDelay(1); }
|
||||
}
|
||||
|
||||
// Set destination address using 5 characters
|
||||
ret = Nrf24_setTADDR(&dev, (uint8_t *)"FGHIJ");
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(pcTaskGetName(0), "nrf24l01 not installed");
|
||||
while(1) { vTaskDelay(1); }
|
||||
}
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
AdvancedSettings(&dev);
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
// Print settings
|
||||
Nrf24_printDetails(&dev);
|
||||
|
||||
uint8_t buf[32];
|
||||
while(1) {
|
||||
TickType_t nowTick = xTaskGetTickCount();
|
||||
sprintf((char *)buf, "Hello World %"PRIu32, nowTick);
|
||||
Nrf24_send(&dev, buf);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
ESP_LOGI(pcTaskGetName(0), "Wait for sending.....");
|
||||
if (Nrf24_isSend(&dev, 1000)) {
|
||||
ESP_LOGI(pcTaskGetName(0),"Send success:%s", buf);
|
||||
|
||||
// Wait for response
|
||||
//ESP_LOGI(pcTaskGetName(0), "Wait for response.....");
|
||||
bool received = false;
|
||||
for(int i=0;i<100;i++) {
|
||||
if (Nrf24_dataReady(&dev)) {
|
||||
received = true;
|
||||
break;
|
||||
}
|
||||
vTaskDelay(1);
|
||||
}
|
||||
if (received) {
|
||||
Nrf24_getData(&dev, buf);
|
||||
TickType_t diffTick = xTaskGetTickCount() - nowTick;
|
||||
ESP_LOGI(pcTaskGetName(0), "Got response:[%s] Elapsed:%"PRIu32" ticks", buf, diffTick);
|
||||
} else {
|
||||
ESP_LOGW(pcTaskGetName(0), "No response");
|
||||
}
|
||||
|
||||
} else {
|
||||
ESP_LOGW(pcTaskGetName(0),"Send fail:");
|
||||
}
|
||||
vTaskDelay(1000/portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_PRIMARY
|
||||
|
||||
#if CONFIG_SECONDARY
|
||||
void secondary(void *pvParameters)
|
||||
{
|
||||
ESP_LOGI(pcTaskGetName(0), "Start");
|
||||
NRF24_t dev;
|
||||
Nrf24_init(&dev);
|
||||
uint8_t payload = 32;
|
||||
uint8_t channel = CONFIG_RADIO_CHANNEL;
|
||||
Nrf24_config(&dev, channel, payload);
|
||||
|
||||
// Set my own address using 5 characters
|
||||
esp_err_t ret = Nrf24_setRADDR(&dev, (uint8_t *)"FGHIJ");
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(pcTaskGetName(0), "nrf24l01 not installed");
|
||||
while(1) { vTaskDelay(1); }
|
||||
}
|
||||
|
||||
// Set destination address using 5 characters
|
||||
ret = Nrf24_setTADDR(&dev, (uint8_t *)"ABCDE");
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(pcTaskGetName(0), "nrf24l01 not installed");
|
||||
while(1) { vTaskDelay(1); }
|
||||
}
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
AdvancedSettings(&dev);
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
// Print settings
|
||||
Nrf24_printDetails(&dev);
|
||||
ESP_LOGI(pcTaskGetName(0), "Listening...");
|
||||
|
||||
uint8_t buf[32];
|
||||
|
||||
// Clear RX FiFo
|
||||
while(1) {
|
||||
if (Nrf24_dataReady(&dev) == false) break;
|
||||
Nrf24_getData(&dev, buf);
|
||||
}
|
||||
|
||||
while(1) {
|
||||
// Wait for received data
|
||||
if (Nrf24_dataReady(&dev)) {
|
||||
Nrf24_getData(&dev, buf);
|
||||
ESP_LOGI(pcTaskGetName(0), "Got data:%s", buf);
|
||||
Nrf24_send(&dev, buf);
|
||||
ESP_LOGI(pcTaskGetName(0), "Wait for sending.....");
|
||||
if (Nrf24_isSend(&dev, 1000)) {
|
||||
ESP_LOGI(pcTaskGetName(0),"Send success:%s", buf);
|
||||
} else {
|
||||
ESP_LOGW(pcTaskGetName(0),"Send fail:");
|
||||
}
|
||||
}
|
||||
vTaskDelay(1);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_SECONDARY
|
||||
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
#if CONFIG_PRIMARY
|
||||
xTaskCreate(&primary, "PRIMARY", 1024*3, NULL, 2, NULL);
|
||||
#endif
|
||||
|
||||
#if CONFIG_SECONDARY
|
||||
xTaskCreate(&secondary, "SECONDARY", 1024*3, NULL, 2, NULL);
|
||||
#endif
|
||||
}
|
177
esp-idf-mirf-master/README.md
Normal file
177
esp-idf-mirf-master/README.md
Normal file
@ -0,0 +1,177 @@
|
||||
# esp-idf-mirf
|
||||
A port of the Mirf library for ESP-IDF.
|
||||
The library provides basic control of the Nordic nRF24L01/nRF24L01+ RF modules.
|
||||
|
||||
I ported from [here](https://github.com/nopnop2002/Arduino-STM32-nRF24L01).
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
# Software requirements
|
||||
ESP-IDF V4.4/V5.x.
|
||||
ESP-IDF V5.0 is required when using ESP32-C2.
|
||||
ESP-IDF V5.1 is required when using ESP32-C6.
|
||||
|
||||
# Installation
|
||||
|
||||
```Shell
|
||||
git clone https://github.com/nopnop2002/esp-idf-mirf
|
||||
cd esp-idf-mirf/Peer-to-peer
|
||||
idf.py set-target {esp32/esp32s2/esp32s3/esp32c2/esp32c3/esp32c6}
|
||||
idf.py menuconfig
|
||||
idf.py flash
|
||||
```
|
||||
|
||||
__Note for ESP32C3__
|
||||
For some reason, there are development boards that cannot use GPIO06, GPIO08, GPIO09, GPIO19 for SPI clock pins.
|
||||
According to the ESP32C3 specifications, these pins can also be used as SPI clocks.
|
||||
I used a raw ESP-C3-13 to verify that these pins could be used as SPI clocks.
|
||||
|
||||
# Configuration for Transceiver
|
||||

|
||||

|
||||
|
||||
__Note for Channel__
|
||||
Channels range from 0 to 127.
|
||||
The channel number of the sender and receiver must be the same.
|
||||
Channel = 0 uses the frequency of 2.4000GHz, channel = 127 uses the frequency of 2.4127GHz.
|
||||
The width of one channel is only 0.01GHz.
|
||||
Using multiple radio node at the same time will almost always cause interference, even if you change channels.
|
||||
|
||||
# SPI BUS selection
|
||||

|
||||
|
||||
The ESP32 series has three SPI BUSs.
|
||||
SPI1_HOST is used for communication with Flash memory.
|
||||
You can use SPI2_HOST and SPI3_HOST freely.
|
||||
When you use SDSPI(SD Card via SPI), SDSPI uses SPI2_HOST BUS.
|
||||
When using this module at the same time as SDSPI or other SPI device using SPI2_HOST, it needs to be changed to SPI3_HOST.
|
||||
When you don't use SDSPI, both SPI2_HOST and SPI3_HOST will work.
|
||||
Previously it was called HSPI_HOST / VSPI_HOST, but now it is called SPI2_HOST / SPI3_HOST.
|
||||
|
||||
# Using Advanced Settings
|
||||
When used at long distances, lowering the RF data rate stabilizes it.
|
||||
When changing the RF data rate, the sender and receiver must have the same value.
|
||||
When using 250KBps, it takes time to PAYLOAD sending and ACK PACKET receiving, so it is necessary to increase the automatic retransmission delay.
|
||||
I tested it with [this](https://github.com/nopnop2002/Arduino-STM32-nRF24L01/tree/master/example/AdvancedSetting).
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
__If you want to initialize the nRF24L01 settings after using the Advanced Settings, you need to power cycle the nRF24L01 before executing.__
|
||||
Because nRF24L01 remembers the previous setting.
|
||||
nRF24L01 does not have Software Reset function.
|
||||
|
||||
|
||||
# Wirering
|
||||
|
||||
|nRF24L01||ESP32|ESP32-S2/S3|ESP32-C2/C3/C6||
|
||||
|:-:|:-:|:-:|:-:|:-:|:-:|
|
||||
|MISO|--|GPIO19|GPIO37|GPIO4|(*1)|
|
||||
|SCK|--|GPIO18|GPIO36|GPIO3|(*1)|
|
||||
|MOSI|--|GPIO23|GPIO35|GPIO2|(*1)|
|
||||
|CE|--|GPIO16|GPIO34|GPIO1|(*1)|
|
||||
|CSN|--|GPIO17|GPIO33|GPIO0|(*1)|
|
||||
|GND|--|GND|GND|GND||
|
||||
|VCC|--|3.3V|3.3V|3.3V||
|
||||
|
||||
(*1)You can change it to any pin using menuconfig.
|
||||
|
||||
# Communicat with Arduino Environment
|
||||
I used [this](https://github.com/nopnop2002/Arduino-STM32-nRF24L01) library on Arduino environment.
|
||||
__You need to match the payload size and channel with Arduino and esp-idf.__
|
||||
|
||||
- Arduino environment
|
||||
```C++
|
||||
Mirf.payload = sizeof(mydata.value);
|
||||
Mirf.channel = 90;
|
||||
Mirf.config();
|
||||
```
|
||||
- esp-idf
|
||||
```C
|
||||
uint8_t payload = sizeof(value);
|
||||
uint8_t channel = 90;
|
||||
Nrf24_config(&dev, channel, payload);
|
||||
```
|
||||
|
||||
# Communicat with Raspberry Pi
|
||||
I used [this](https://github.com/nopnop2002/Raspberry-Mirf) library on Raspberry Pi.
|
||||
|
||||
# Using binary data
|
||||
nRF24L01 is not interested in the contents of the payload.
|
||||
Therefore, nRF24L01 can send and receive binary data.
|
||||
But the internal format of the binary data depends on the MCU architecture, so communication between different architectures is not possible.
|
||||
If you want to send or receive binary data between different architectures, you need to encode it into a CSV format string like this.
|
||||
```123,-123,1234.5,-1234.5```
|
||||
nRF24L01 can send and receive up to 32 characters, but by adding an index to the sent data, it can send and receive 256 types of data.
|
||||
|
||||
|
||||
# Important
|
||||
When changing the settings of the nRF24L01, it is necessary to power cycle the nRF24L01 before executing.
|
||||
Because nRF24L01 remembers the previous setting.
|
||||
nRF24L01 does not have Software Reset function.
|
||||
|
||||
# Enhanced ShockBurst features
|
||||
nRF24L01 has "Enhanced ShockBurst" features.
|
||||
"Enhanced ShockBurst" automatically sets the PTX(=Transmitter) in receive mode to wait for the ACK packet from PRX(=Receiver).
|
||||
|
||||
## Transmission Successful
|
||||
|ESP32||nRF24L01[PTX]||nRF24L01[PRX]||ESP32|
|
||||
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|
||||
|ESP32|-->|nRF24L01|||||
|
||||
|||nRF24L01|--(Payload Packet)-->|nRF24L01|||||
|
||||
||||wait 250uS||||||
|
||||
|||nRF24L01|<--(Ack Packet)--|nRF24L01|||||
|
||||
|ESP32|<--|nRF24L01|||||||
|
||||
|||||nRF24L01|-->|ESP32|
|
||||
|
||||
## Transmission Failure
|
||||
PTX waits for an ACK packet for 250uS and retransmits 3 times.
|
||||
|ESP32||nRF24L01[PTX]||nRF24L01[PRX]||ESP32|
|
||||
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|
||||
|ESP32|-->|nRF24L01|||||
|
||||
|||nRF24L01|--(Payload Packet)-->|nRF24L01|||||
|
||||
||||wait 250uS||||||
|
||||
|||nRF24L01|--(Payload Packet)-->|nRF24L01|||||
|
||||
||||wait 250uS||||||
|
||||
|||nRF24L01|--(Payload Packet)-->|nRF24L01|||||
|
||||
||||wait 250uS||||||
|
||||
|ESP32|<--|nRF24L01|||||||
|
||||
|
||||
|
||||
Using a data rate of 250KBps extends the range of radio waves.
|
||||
However, it takes time to send PAYLOAD and receive ACK PACKET.
|
||||
Therefore, the delay time for automatic retransmission should be longer than 250uS.
|
||||
If the delay of automatic retransmission is not increased, it is considered as a transmission failure.
|
||||
|ESP32||nRF24L01[PTX]||nRF24L01[PRX]||ESP32|
|
||||
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|
||||
|ESP32|-->|nRF24L01|||||
|
||||
|||nRF24L01|--(Payload Packet)-->|nRF24L01|||||
|
||||
||||Over 250uS||||||
|
||||
|||nRF24L01|<--(Ack Packet)--|nRF24L01|||||
|
||||
|ESP32|<--|nRF24L01|||||||
|
||||
|||||nRF24L01|-->|ESP32|
|
||||
|
||||
See the data sheet for details on Enhanced ShockBurst.
|
||||
|
||||
|
||||
# Throughput
|
||||
spi_device_transmit is executed by the SPI driver and consumes 1tick of CPU time.
|
||||
When DMA is enabled, SPI max_transfer_sz defaults to 4092(4K).
|
||||
This indicates that 4092 bytes of data can be sent in 1tick(10 millsec).
|
||||
Therefore, the SPI transmission potential of ESP-IDF is 400Kbytes/Sec.
|
||||
This has a significant impact on the nRF24L01, which has a small maximum payload size.
|
||||
|
||||
Unfortunately, nRF24L01's maximum payload size is 32 bytes.
|
||||
1 tick (10 millsec) is required to send payload and receive ack packet.
|
||||
This has nothing to do with SPI bus speed.
|
||||
The throughput of nRF24L01 is 32 bytes/10 millsec(=3,200 bytes/sec).
|
||||
RF data rate of nRF24L01 affects the radio range, but not the throughput.
|
||||
|
||||
# About Si24R1 clone
|
||||
Si24R1 is marketed as a nRF24L01 compatible.
|
||||
__Si24R1 clone cannot send and receive correctly.__
|
||||
After purchasing the nRF24L01, be sure to check the markings on the chip.
|
||||
Many suppliers sell Si24R1 as nRF24L01.
|
5
esp-idf-mirf-master/components/mirf/CMakeLists.txt
Normal file
5
esp-idf-mirf-master/components/mirf/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
set(component_srcs "mirf.c")
|
||||
|
||||
idf_component_register(SRCS "${component_srcs}"
|
||||
PRIV_REQUIRES driver
|
||||
INCLUDE_DIRS ".")
|
130
esp-idf-mirf-master/components/mirf/Kconfig.projbuild
Normal file
130
esp-idf-mirf-master/components/mirf/Kconfig.projbuild
Normal file
@ -0,0 +1,130 @@
|
||||
menu "nRF24L01 Configuration"
|
||||
|
||||
config GPIO_RANGE_MAX
|
||||
int
|
||||
default 33 if IDF_TARGET_ESP32
|
||||
default 46 if IDF_TARGET_ESP32S2
|
||||
default 48 if IDF_TARGET_ESP32S3
|
||||
default 18 if IDF_TARGET_ESP32C2
|
||||
default 19 if IDF_TARGET_ESP32C3
|
||||
default 30 if IDF_TARGET_ESP32C6
|
||||
|
||||
config RADIO_CHANNEL
|
||||
int "Channel number"
|
||||
range 0 127
|
||||
default 90
|
||||
help
|
||||
Channel number.
|
||||
|
||||
config MISO_GPIO
|
||||
int "MISO GPIO number"
|
||||
range 0 GPIO_RANGE_MAX
|
||||
default 19 if IDF_TARGET_ESP32
|
||||
default 37 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
|
||||
default 4 # C3 and others
|
||||
help
|
||||
GPIO number (IOxx) to SPI MISO.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to MISO.
|
||||
On the ESP32, GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
On the ESP32-S2, GPIO 46 is input-only so cannot be used as outputs.
|
||||
|
||||
config SCLK_GPIO
|
||||
int "SCLK GPIO number"
|
||||
range 0 GPIO_RANGE_MAX
|
||||
default 18 if IDF_TARGET_ESP32
|
||||
default 36 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
|
||||
default 3 # C3 and others
|
||||
help
|
||||
GPIO number (IOxx) to SPI SCLK.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to SCLK.
|
||||
On the ESP32, GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
On the ESP32-S2, GPIO 46 is input-only so cannot be used as outputs.
|
||||
|
||||
config MOSI_GPIO
|
||||
int "MOSI GPIO number"
|
||||
range 0 GPIO_RANGE_MAX
|
||||
default 23 if IDF_TARGET_ESP32
|
||||
default 35 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
|
||||
default 2 # C3 and others
|
||||
help
|
||||
GPIO number (IOxx) to SPI MOSI.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to MOSI.
|
||||
On the ESP32, GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
On the ESP32-S2, GPIO 46 is input-only so cannot be used as outputs.
|
||||
|
||||
config CE_GPIO
|
||||
int "CE GPIO number"
|
||||
range 0 GPIO_RANGE_MAX
|
||||
default 16 if IDF_TARGET_ESP32
|
||||
default 34 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
|
||||
default 1 # C3 and others
|
||||
help
|
||||
GPIO number (IOxx) to CE.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to CE.
|
||||
On the ESP32, GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
On the ESP32-S2, GPIO 46 is input-only so cannot be used as outputs.
|
||||
|
||||
config CSN_GPIO
|
||||
int "CSN GPIO number"
|
||||
range 0 GPIO_RANGE_MAX
|
||||
default 17 if IDF_TARGET_ESP32
|
||||
default 33 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
|
||||
default 0 # C3 and others
|
||||
help
|
||||
GPIO number (IOxx) to CSN.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to CSN.
|
||||
On the ESP32, GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
On the ESP32-S2, GPIO 46 is input-only so cannot be used as outputs.
|
||||
|
||||
choice SPI_HOST
|
||||
prompt "SPI peripheral that controls this bus"
|
||||
default SPI2_HOST
|
||||
help
|
||||
Select SPI peripheral that controls this bus.
|
||||
config SPI2_HOST
|
||||
bool "SPI2_HOST"
|
||||
help
|
||||
Use SPI2_HOST. This is also called HSPI_HOST.
|
||||
config SPI3_HOST
|
||||
depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
|
||||
bool "SPI3_HOST"
|
||||
help
|
||||
USE SPI3_HOST. This is also called VSPI_HOST
|
||||
endchoice
|
||||
|
||||
config ADVANCED
|
||||
bool "Enable Advanced Setting"
|
||||
default false
|
||||
help
|
||||
Enable Advanced Setting.
|
||||
|
||||
choice RF_RATIO
|
||||
depends on ADVANCED
|
||||
prompt "RF Data Ratio"
|
||||
default RF_RATIO_2M
|
||||
help
|
||||
Select RF Data Ratio.
|
||||
config RF_RATIO_2M
|
||||
bool "2Mbps"
|
||||
help
|
||||
RF Data Ratio is 2Mbps.
|
||||
config RF_RATIO_1M
|
||||
bool "1Mbps"
|
||||
help
|
||||
RF Data Ratio is 1Mbps.
|
||||
config RF_RATIO_250K
|
||||
bool "250Kbps"
|
||||
help
|
||||
RF Data Ratio is 250Kbps.
|
||||
endchoice
|
||||
|
||||
config RETRANSMIT_DELAY
|
||||
depends on ADVANCED
|
||||
int "Auto Retransmit Delay"
|
||||
range 0 15
|
||||
default 0
|
||||
help
|
||||
Set Auto Retransmit Delay.
|
||||
Delay = value * 250us.
|
||||
|
||||
endmenu
|
613
esp-idf-mirf-master/components/mirf/mirf.c
Normal file
613
esp-idf-mirf-master/components/mirf/mirf.c
Normal file
@ -0,0 +1,613 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include <driver/spi_master.h>
|
||||
#include <driver/gpio.h>
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "mirf.h"
|
||||
|
||||
#define TAG "NRF24"
|
||||
|
||||
// SPI Stuff
|
||||
#if CONFIG_SPI2_HOST
|
||||
#define HOST_ID SPI2_HOST
|
||||
#elif CONFIG_SPI3_HOST
|
||||
#define HOST_ID SPI3_HOST
|
||||
#endif
|
||||
|
||||
static const int SPI_Frequency = 4000000; // Stable even with a long jumper cable
|
||||
//static const int SPI_Frequency = 6000000;
|
||||
//static const int SPI_Frequency = 8000000; // Requires a short jumper cable
|
||||
//static const int SPI_Frequency = 10000000; // Unstable even with a short jumper cable
|
||||
|
||||
//const char rf24_datarates[][8] = {"1Mbps", "2Mbps", "250Kbps"};
|
||||
char rf24_datarates[][8] = {"1Mbps", "2Mbps", "250Kbps"};
|
||||
const char rf24_crclength[][10] = {"Disabled", "8 bits", "16 bits"};
|
||||
//const char rf24_pa_dbm[][8] = {"PA_MIN", "PA_LOW", "PA_HIGH", "PA_MAX"};
|
||||
char rf24_pa_dbm[][8] = {"PA_MIN", "PA_LOW", "PA_HIGH", "PA_MAX"};
|
||||
|
||||
void Nrf24_init(NRF24_t * dev)
|
||||
{
|
||||
esp_err_t ret;
|
||||
|
||||
ESP_LOGI(TAG, "CONFIG_MISO_GPIO=%d", CONFIG_MISO_GPIO);
|
||||
ESP_LOGI(TAG, "CONFIG_MOSI_GPIO=%d", CONFIG_MOSI_GPIO);
|
||||
ESP_LOGI(TAG, "CONFIG_SCLK_GPIO=%d", CONFIG_SCLK_GPIO);
|
||||
ESP_LOGI(TAG, "CONFIG_CE_GPIO=%d", CONFIG_CE_GPIO);
|
||||
ESP_LOGI(TAG, "CONFIG_CSN_GPIO=%d", CONFIG_CSN_GPIO);
|
||||
|
||||
//gpio_pad_select_gpio(CONFIG_CE_GPIO);
|
||||
gpio_reset_pin(CONFIG_CE_GPIO);
|
||||
gpio_set_direction(CONFIG_CE_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(CONFIG_CE_GPIO, 0);
|
||||
|
||||
//gpio_pad_select_gpio(CONFIG_CSN_GPIO);
|
||||
gpio_reset_pin(CONFIG_CSN_GPIO);
|
||||
gpio_set_direction(CONFIG_CSN_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(CONFIG_CSN_GPIO, 1);
|
||||
|
||||
spi_bus_config_t spi_bus_config = {
|
||||
.sclk_io_num = CONFIG_SCLK_GPIO,
|
||||
.mosi_io_num = CONFIG_MOSI_GPIO,
|
||||
.miso_io_num = CONFIG_MISO_GPIO,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1
|
||||
};
|
||||
|
||||
ret = spi_bus_initialize( HOST_ID, &spi_bus_config, SPI_DMA_CH_AUTO );
|
||||
ESP_LOGI(TAG, "spi_bus_initialize=%d",ret);
|
||||
assert(ret==ESP_OK);
|
||||
|
||||
spi_device_interface_config_t devcfg;
|
||||
memset( &devcfg, 0, sizeof( spi_device_interface_config_t ) );
|
||||
devcfg.clock_speed_hz = SPI_Frequency;
|
||||
// It does not work with hardware CS control.
|
||||
//devcfg.spics_io_num = csn_pin;
|
||||
// It does work with software CS control.
|
||||
devcfg.spics_io_num = -1;
|
||||
devcfg.queue_size = 7;
|
||||
devcfg.mode = 0;
|
||||
devcfg.flags = SPI_DEVICE_NO_DUMMY;
|
||||
|
||||
spi_device_handle_t handle;
|
||||
ret = spi_bus_add_device( HOST_ID, &devcfg, &handle);
|
||||
ESP_LOGI(TAG, "spi_bus_add_device=%d",ret);
|
||||
assert(ret==ESP_OK);
|
||||
|
||||
dev->cePin = CONFIG_CE_GPIO;
|
||||
dev->csnPin = CONFIG_CSN_GPIO;
|
||||
dev->channel = 1;
|
||||
dev->payload = 16;
|
||||
dev->_SPIHandle = handle;
|
||||
}
|
||||
|
||||
|
||||
bool spi_write_byte(NRF24_t * dev, uint8_t* Dataout, size_t DataLength )
|
||||
{
|
||||
spi_transaction_t SPITransaction;
|
||||
|
||||
if ( DataLength > 0 ) {
|
||||
memset( &SPITransaction, 0, sizeof( spi_transaction_t ) );
|
||||
SPITransaction.length = DataLength * 8;
|
||||
SPITransaction.tx_buffer = Dataout;
|
||||
SPITransaction.rx_buffer = NULL;
|
||||
spi_device_transmit( dev->_SPIHandle, &SPITransaction );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spi_read_byte(NRF24_t * dev, uint8_t* Datain, uint8_t* Dataout, size_t DataLength )
|
||||
{
|
||||
spi_transaction_t SPITransaction;
|
||||
|
||||
if ( DataLength > 0 ) {
|
||||
memset( &SPITransaction, 0, sizeof( spi_transaction_t ) );
|
||||
SPITransaction.length = DataLength * 8;
|
||||
SPITransaction.tx_buffer = Dataout;
|
||||
SPITransaction.rx_buffer = Datain;
|
||||
spi_device_transmit( dev->_SPIHandle, &SPITransaction );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t spi_transfer(NRF24_t * dev, uint8_t address) {
|
||||
uint8_t datain[1];
|
||||
uint8_t dataout[1];
|
||||
dataout[0] = address;
|
||||
//spi_write_byte(dev, dataout, 1 );
|
||||
spi_read_byte(dev, datain, dataout, 1 );
|
||||
return datain[0];
|
||||
}
|
||||
|
||||
void spi_csnHi(NRF24_t * dev) {
|
||||
gpio_set_level( dev->csnPin, 1 );
|
||||
}
|
||||
|
||||
void spi_csnLow(NRF24_t * dev) {
|
||||
gpio_set_level( dev->csnPin, 0 );
|
||||
}
|
||||
|
||||
// Sets the important registers in the MiRF module and powers the module
|
||||
// in receiving mode
|
||||
// NB: channel and payload must be set now.
|
||||
void Nrf24_config(NRF24_t * dev, uint8_t channel, uint8_t payload)
|
||||
{
|
||||
dev->channel = channel;
|
||||
dev->payload = payload;
|
||||
Nrf24_configRegister(dev, RF_CH, dev->channel); // Set RF channel
|
||||
Nrf24_configRegister(dev, RX_PW_P0, dev->payload); // Set length of incoming payload
|
||||
Nrf24_configRegister(dev, RX_PW_P1, dev->payload);
|
||||
Nrf24_powerUpRx(dev); // Start receiver
|
||||
Nrf24_flushRx(dev);
|
||||
}
|
||||
|
||||
// Sets the receiving device address
|
||||
//void Nrf24_setRADDR(NRF24_t * dev, uint8_t * adr)
|
||||
esp_err_t Nrf24_setRADDR(NRF24_t * dev, uint8_t * adr)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
Nrf24_writeRegister(dev, RX_ADDR_P1, adr, mirf_ADDR_LEN);
|
||||
uint8_t buffer[5];
|
||||
Nrf24_readRegister(dev, RX_ADDR_P1, buffer, sizeof(buffer));
|
||||
for (int i=0;i<5;i++) {
|
||||
ESP_LOGD(TAG, "adr[%d]=0x%x buffer[%d]=0x%x", i, adr[i], i, buffer[i]);
|
||||
if (adr[i] != buffer[i]) ret = ESP_FAIL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Sets the transmitting device address
|
||||
//void Nrf24_setTADDR(NRF24_t * dev, uint8_t * adr)
|
||||
esp_err_t Nrf24_setTADDR(NRF24_t * dev, uint8_t * adr)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
Nrf24_writeRegister(dev, RX_ADDR_P0, adr, mirf_ADDR_LEN); //RX_ADDR_P0 must be set to the sending addr for auto ack to work.
|
||||
Nrf24_writeRegister(dev, TX_ADDR, adr, mirf_ADDR_LEN);
|
||||
uint8_t buffer[5];
|
||||
Nrf24_readRegister(dev, RX_ADDR_P0, buffer, sizeof(buffer));
|
||||
for (int i=0;i<5;i++) {
|
||||
ESP_LOGD(TAG, "adr[%d]=0x%x buffer[%d]=0x%x", i, adr[i], i, buffer[i]);
|
||||
if (adr[i] != buffer[i]) ret = ESP_FAIL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Add the receiving device address
|
||||
void Nrf24_addRADDR(NRF24_t * dev, uint8_t pipe, uint8_t adr)
|
||||
{
|
||||
uint8_t value;
|
||||
Nrf24_readRegister(dev, EN_RXADDR, &value, 1);
|
||||
|
||||
if (pipe == 2) {
|
||||
Nrf24_configRegister(dev, RX_PW_P2, dev->payload);
|
||||
Nrf24_configRegister(dev, RX_ADDR_P2, adr);
|
||||
value = value | 0x04;
|
||||
Nrf24_configRegister(dev, EN_RXADDR, value);
|
||||
} else if (pipe == 3) {
|
||||
Nrf24_configRegister(dev, RX_PW_P3, dev->payload);
|
||||
Nrf24_configRegister(dev, RX_ADDR_P3, adr);
|
||||
value = value | 0x08;
|
||||
Nrf24_configRegister(dev, EN_RXADDR, value);
|
||||
} else if (pipe == 4) {
|
||||
Nrf24_configRegister(dev, RX_PW_P4, dev->payload);
|
||||
Nrf24_configRegister(dev, RX_ADDR_P4, adr);
|
||||
value = value | 0x10;
|
||||
Nrf24_configRegister(dev, EN_RXADDR, value);
|
||||
} else if (pipe == 5) {
|
||||
Nrf24_configRegister(dev, RX_PW_P5, dev->payload);
|
||||
Nrf24_configRegister(dev, RX_ADDR_P5, adr);
|
||||
value = value | 0x20;
|
||||
Nrf24_configRegister(dev, EN_RXADDR, value);
|
||||
}
|
||||
}
|
||||
|
||||
// Checks if data is available for reading
|
||||
extern bool Nrf24_dataReady(NRF24_t * dev)
|
||||
{
|
||||
// See note in getData() function - just checking RX_DR isn't good enough
|
||||
uint8_t status = Nrf24_getStatus(dev);
|
||||
//printf("Nrf24_dataReady status=0x%x\n", status);
|
||||
if ( status & (1 << RX_DR) ) {
|
||||
// Save status
|
||||
dev->status = status;
|
||||
return 1;
|
||||
}
|
||||
// We can short circuit on RX_DR, but if it's not set, we still need
|
||||
// to check the FIFO for any pending packets
|
||||
//return !Nrf24_rxFifoEmpty(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get pipe number for reading
|
||||
uint8_t Nrf24_getDataPipe(NRF24_t * dev) {
|
||||
//uint8_t status = Nrf24_getStatus(dev);
|
||||
//printf("dev->status=0x%x\n",dev->status);
|
||||
return ((dev->status & 0x0E) >> 1);
|
||||
}
|
||||
|
||||
extern bool Nrf24_rxFifoEmpty(NRF24_t * dev)
|
||||
{
|
||||
uint8_t fifoStatus;
|
||||
Nrf24_readRegister(dev, FIFO_STATUS, &fifoStatus, sizeof(fifoStatus));
|
||||
return (fifoStatus & (1 << RX_EMPTY));
|
||||
}
|
||||
|
||||
// Reads payload bytes into data array
|
||||
extern void Nrf24_getData(NRF24_t * dev, uint8_t * data)
|
||||
{
|
||||
spi_csnLow(dev); // Pull down chip select
|
||||
spi_transfer(dev, R_RX_PAYLOAD ); // Send cmd to read rx payload
|
||||
spi_read_byte(dev, data, data, dev->payload); // Read payload
|
||||
spi_csnHi(dev); // Pull up chip select
|
||||
// NVI: per product spec, p 67, note c:
|
||||
// "The RX_DR IRQ is asserted by a new packet arrival event. The procedure
|
||||
// for handling this interrupt should be: 1) read payload through SPI,
|
||||
// 2) clear RX_DR IRQ, 3) read FIFO_STATUS to check if there are more
|
||||
// payloads available in RX FIFO, 4) if there are more data in RX FIFO,
|
||||
// repeat from step 1)."
|
||||
// So if we're going to clear RX_DR here, we need to check the RX FIFO
|
||||
// in the dataReady() function
|
||||
Nrf24_configRegister(dev, STATUS, (1 << RX_DR)); // Reset status register
|
||||
}
|
||||
|
||||
// Clocks only one byte into the given MiRF register
|
||||
void Nrf24_configRegister(NRF24_t * dev, uint8_t reg, uint8_t value)
|
||||
{
|
||||
spi_csnLow(dev);
|
||||
spi_transfer(dev, W_REGISTER | (REGISTER_MASK & reg));
|
||||
spi_transfer(dev, value);
|
||||
spi_csnHi(dev);
|
||||
}
|
||||
|
||||
// Reads an array of bytes from the given start position in the MiRF registers
|
||||
void Nrf24_readRegister(NRF24_t * dev, uint8_t reg, uint8_t * value, uint8_t len)
|
||||
{
|
||||
spi_csnLow(dev);
|
||||
spi_transfer(dev, R_REGISTER | (REGISTER_MASK & reg));
|
||||
spi_read_byte(dev, value, value, len);
|
||||
spi_csnHi(dev);
|
||||
}
|
||||
|
||||
// Writes an array of bytes into inte the MiRF registers
|
||||
void Nrf24_writeRegister(NRF24_t * dev, uint8_t reg, uint8_t * value, uint8_t len)
|
||||
{
|
||||
spi_csnLow(dev);
|
||||
spi_transfer(dev, W_REGISTER | (REGISTER_MASK & reg));
|
||||
spi_write_byte(dev, value, len);
|
||||
spi_csnHi(dev);
|
||||
}
|
||||
|
||||
// Sends a data package to the default address. Be sure to send the correct
|
||||
// amount of bytes as configured as payload on the receiver.
|
||||
void Nrf24_send(NRF24_t * dev, uint8_t * value)
|
||||
{
|
||||
uint8_t status;
|
||||
status = Nrf24_getStatus(dev);
|
||||
while (dev->PTX) // Wait until last paket is send
|
||||
{
|
||||
status = Nrf24_getStatus(dev);
|
||||
if ((status & ((1 << TX_DS) | (1 << MAX_RT))))
|
||||
{
|
||||
dev->PTX = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Nrf24_ceLow(dev);
|
||||
Nrf24_powerUpTx(dev); // Set to transmitter mode , Power up
|
||||
spi_csnLow(dev); // Pull down chip select
|
||||
spi_transfer(dev, FLUSH_TX ); // Write cmd to flush tx fifo
|
||||
spi_csnHi(dev); // Pull up chip select
|
||||
spi_csnLow(dev); // Pull down chip select
|
||||
spi_transfer(dev, W_TX_PAYLOAD ); // Write cmd to write payload
|
||||
spi_write_byte(dev, value, dev->payload); // Write payload
|
||||
spi_csnHi(dev); // Pull up chip select
|
||||
Nrf24_ceHi(dev); // Start transmission
|
||||
}
|
||||
|
||||
// Test if chip is still sending.
|
||||
// When sending has finished return chip to listening.
|
||||
bool Nrf24_isSending(NRF24_t * dev) {
|
||||
uint8_t status;
|
||||
if (dev->PTX)
|
||||
{
|
||||
status = Nrf24_getStatus(dev);
|
||||
if ((status & ((1 << TX_DS) | (1 << MAX_RT)))) {// if sending successful (TX_DS) or max retries exceded (MAX_RT).
|
||||
Nrf24_powerUpRx(dev);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test if Sending has finished or retry is over.
|
||||
// When sending has finished return trur.
|
||||
// When reach maximum number of TX retries return false.
|
||||
bool Nrf24_isSend(NRF24_t * dev, int timeout) {
|
||||
uint8_t status;
|
||||
TickType_t startTick = xTaskGetTickCount();
|
||||
if (dev->PTX) {
|
||||
while(1) {
|
||||
status = Nrf24_getStatus(dev);
|
||||
/*
|
||||
if sending successful (TX_DS) or max retries exceded (MAX_RT).
|
||||
*/
|
||||
|
||||
if (status & (1 << TX_DS)) { // Data Sent TX FIFO interrup
|
||||
Nrf24_powerUpRx(dev);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (status & (1 << MAX_RT)) { // Maximum number of TX retries interrupt
|
||||
ESP_LOGW(TAG, "Maximum number of TX retries interrupt");
|
||||
Nrf24_powerUpRx(dev);
|
||||
return false;
|
||||
}
|
||||
|
||||
// I believe either TX_DS or MAX_RT will always be notified.
|
||||
// Therefore, it is unusual for neither to be notified for a period of time.
|
||||
// I don't know exactly how to respond.
|
||||
TickType_t diffTick = xTaskGetTickCount() - startTick;
|
||||
if ( (diffTick * portTICK_PERIOD_MS) > timeout) {
|
||||
ESP_LOGE(TAG, "Status register timeout. status=0x%x", status);
|
||||
return false;
|
||||
}
|
||||
vTaskDelay(1);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
uint8_t Nrf24_getStatus(NRF24_t * dev) {
|
||||
uint8_t rv;
|
||||
Nrf24_readRegister(dev, STATUS, &rv, 1);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void Nrf24_powerUpRx(NRF24_t * dev) {
|
||||
dev->PTX = 0;
|
||||
Nrf24_ceLow(dev);
|
||||
Nrf24_configRegister(dev, CONFIG, mirf_CONFIG | ( (1 << PWR_UP) | (1 << PRIM_RX) ) ); //set device as RX mode
|
||||
Nrf24_ceHi(dev);
|
||||
Nrf24_configRegister(dev, STATUS, (1 << TX_DS) | (1 << MAX_RT)); //Clear seeded interrupt and max tx number interrupt
|
||||
}
|
||||
|
||||
void Nrf24_flushRx(NRF24_t * dev)
|
||||
{
|
||||
spi_csnLow(dev);
|
||||
spi_transfer(dev, FLUSH_RX );
|
||||
spi_csnHi(dev);
|
||||
}
|
||||
|
||||
void Nrf24_powerUpTx(NRF24_t * dev) {
|
||||
dev->PTX = 1;
|
||||
Nrf24_configRegister(dev, CONFIG, mirf_CONFIG | ( (1 << PWR_UP) | (0 << PRIM_RX) ) ); //set device as TX mode
|
||||
Nrf24_configRegister(dev, STATUS, (1 << TX_DS) | (1 << MAX_RT)); //Clear seeded interrupt and max tx number interrupt
|
||||
}
|
||||
|
||||
void Nrf24_ceHi(NRF24_t * dev) {
|
||||
gpio_set_level( dev->cePin, 1 );
|
||||
}
|
||||
|
||||
void Nrf24_ceLow(NRF24_t * dev) {
|
||||
gpio_set_level( dev->cePin, 0 );
|
||||
}
|
||||
|
||||
void Nrf24_powerDown(NRF24_t * dev)
|
||||
{
|
||||
Nrf24_ceLow(dev);
|
||||
Nrf24_configRegister(dev, CONFIG, mirf_CONFIG );
|
||||
}
|
||||
|
||||
//Set tx power : 0=-18dBm,1=-12dBm,2=-6dBm,3=0dBm
|
||||
void Nrf24_SetOutputRF_PWR(NRF24_t * dev, uint8_t val)
|
||||
{
|
||||
if (val > 3) return;
|
||||
|
||||
uint8_t value;
|
||||
Nrf24_readRegister(dev, RF_SETUP, &value, 1);
|
||||
value = value & 0xF9;
|
||||
value = value | (val<< RF_PWR);
|
||||
//Nrf24_configRegister(dev, RF_SETUP, (val<< RF_PWR) );
|
||||
Nrf24_configRegister(dev, RF_SETUP, value);
|
||||
}
|
||||
|
||||
//Select between the high speed data rates:0=1Mbps, 1=2Mbps, 2=250Kbps
|
||||
void Nrf24_SetSpeedDataRates(NRF24_t * dev, uint8_t val)
|
||||
{
|
||||
if (val > 2) return;
|
||||
|
||||
uint8_t value;
|
||||
Nrf24_readRegister(dev, RF_SETUP, &value, 1);
|
||||
if(val == 2)
|
||||
{
|
||||
value = value | 0x20;
|
||||
value = value & 0xF7;
|
||||
//Nrf24_configRegister(dev, RF_SETUP, (1 << RF_DR_LOW) );
|
||||
Nrf24_configRegister(dev, RF_SETUP, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = value & 0xD7;
|
||||
value = value | (val << RF_DR_HIGH);
|
||||
//Nrf24_configRegister(dev, RF_SETUP, (val << RF_DR_HIGH) );
|
||||
Nrf24_configRegister(dev, RF_SETUP, value);
|
||||
}
|
||||
}
|
||||
|
||||
//Set Auto Retransmit Delay 0=250us, 1=500us, ... 15=4000us
|
||||
void Nrf24_setRetransmitDelay(NRF24_t * dev, uint8_t val)
|
||||
{
|
||||
uint8_t value;
|
||||
Nrf24_readRegister(dev, SETUP_RETR, &value, 1);
|
||||
value = value & 0x0F;
|
||||
value = value | (val << ARD);
|
||||
Nrf24_configRegister(dev, SETUP_RETR, value);
|
||||
}
|
||||
|
||||
|
||||
void Nrf24_printDetails(NRF24_t * dev)
|
||||
{
|
||||
|
||||
printf("================ SPI Configuration ================\n" );
|
||||
printf("CSN Pin \t = GPIO%d\n",dev->csnPin);
|
||||
printf("CE Pin \t = GPIO%d\n", dev->cePin);
|
||||
printf("Clock Speed\t = %d\n", SPI_Frequency);
|
||||
printf("================ NRF Configuration ================\n");
|
||||
|
||||
Nrf24_print_status(Nrf24_getStatus(dev));
|
||||
|
||||
Nrf24_print_address_register(dev, "RX_ADDR_P0-1", RX_ADDR_P0, 2);
|
||||
Nrf24_print_byte_register(dev, "RX_ADDR_P2-5", RX_ADDR_P2, 4);
|
||||
Nrf24_print_address_register(dev, "TX_ADDR\t", TX_ADDR, 1);
|
||||
|
||||
Nrf24_print_byte_register(dev, "RX_PW_P0-6", RX_PW_P0, 6);
|
||||
Nrf24_print_byte_register(dev, "EN_AA\t", EN_AA, 1);
|
||||
Nrf24_print_byte_register(dev, "EN_RXADDR", EN_RXADDR, 1);
|
||||
Nrf24_print_byte_register(dev, "RF_CH\t", RF_CH, 1);
|
||||
Nrf24_print_byte_register(dev, "RF_SETUP", RF_SETUP, 1);
|
||||
Nrf24_print_byte_register(dev, "CONFIG\t", CONFIG, 1);
|
||||
Nrf24_print_byte_register(dev, "DYNPD/FEATURE", DYNPD, 2);
|
||||
//printf("getDataRate()=%d\n",Nrf24_getDataRate(dev));
|
||||
printf("Data Rate\t = %s\n",rf24_datarates[Nrf24_getDataRate(dev)]);
|
||||
#if 0
|
||||
printf_P(PSTR("Model\t\t = "
|
||||
PRIPSTR
|
||||
"\r\n"),pgm_read_ptr(&rf24_model_e_str_P[isPVariant()]));
|
||||
#endif
|
||||
//printf("getCRCLength()=%d\n",Nrf24_getCRCLength(dev));
|
||||
printf("CRC Length\t = %s\n", rf24_crclength[Nrf24_getCRCLength(dev)]);
|
||||
//printf("getPALevel()=%d\n",Nrf24_getPALevel(dev));
|
||||
printf("PA Power\t = %s\n", rf24_pa_dbm[Nrf24_getPALevel(dev)]);
|
||||
uint8_t retransmit = Nrf24_getRetransmitDelay(dev);
|
||||
int16_t delay = (retransmit+1)*250;
|
||||
printf("Retransmit\t = %d us\n", delay);
|
||||
}
|
||||
|
||||
#define _BV(x) (1<<(x))
|
||||
|
||||
void Nrf24_print_status(uint8_t status)
|
||||
{
|
||||
printf("STATUS\t\t = 0x%02x RX_DR=%x TX_DS=%x MAX_RT=%x RX_P_NO=%x TX_FULL=%x\r\n", status, (status & _BV(RX_DR)) ? 1 : 0,
|
||||
(status & _BV(TX_DS)) ? 1 : 0, (status & _BV(MAX_RT)) ? 1 : 0, ((status >> RX_P_NO) & 0x07), (status & _BV(TX_FULL)) ? 1 : 0);
|
||||
}
|
||||
|
||||
void Nrf24_print_address_register(NRF24_t * dev, const char* name, uint8_t reg, uint8_t qty)
|
||||
{
|
||||
printf("%s\t =",name);
|
||||
while (qty--) {
|
||||
//uint8_t buffer[addr_width];
|
||||
uint8_t buffer[5];
|
||||
Nrf24_readRegister(dev, reg++, buffer, sizeof(buffer));
|
||||
|
||||
printf(" 0x");
|
||||
#if 0
|
||||
uint8_t* bufptr = buffer + sizeof buffer;
|
||||
while (--bufptr >= buffer) {
|
||||
printf("%02x", *bufptr);
|
||||
}
|
||||
#endif
|
||||
for(int i=0;i<5;i++) {
|
||||
printf("%02x", buffer[i]);
|
||||
}
|
||||
}
|
||||
printf("\r\n");
|
||||
}
|
||||
|
||||
void Nrf24_print_byte_register(NRF24_t * dev, const char* name, uint8_t reg, uint8_t qty)
|
||||
{
|
||||
printf("%s\t =", name);
|
||||
while (qty--) {
|
||||
uint8_t buffer[1];
|
||||
Nrf24_readRegister(dev, reg++, buffer, 1);
|
||||
printf(" 0x%02x", buffer[0]);
|
||||
}
|
||||
printf("\r\n");
|
||||
}
|
||||
|
||||
uint8_t Nrf24_getDataRate(NRF24_t * dev)
|
||||
{
|
||||
rf24_datarate_e result;
|
||||
uint8_t dr;
|
||||
Nrf24_readRegister(dev, RF_SETUP, &dr, sizeof(dr));
|
||||
//printf("RF_SETUP=%x\n",dr);
|
||||
dr = dr & (_BV(RF_DR_LOW) | _BV(RF_DR_HIGH));
|
||||
|
||||
// switch uses RAM (evil!)
|
||||
// Order matters in our case below
|
||||
if (dr == _BV(RF_DR_LOW)) {
|
||||
// '10' = 250KBPS
|
||||
result = RF24_250KBPS;
|
||||
} else if (dr == _BV(RF_DR_HIGH)) {
|
||||
// '01' = 2MBPS
|
||||
result = RF24_2MBPS;
|
||||
} else {
|
||||
// '00' = 1MBPS
|
||||
result = RF24_1MBPS;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
char * Nrf24_getDataRateString(NRF24_t * dev)
|
||||
{
|
||||
return rf24_datarates[Nrf24_getDataRate(dev)];
|
||||
}
|
||||
|
||||
uint8_t Nrf24_getCRCLength(NRF24_t * dev)
|
||||
{
|
||||
rf24_crclength_e result = RF24_CRC_DISABLED;
|
||||
|
||||
uint8_t config;
|
||||
Nrf24_readRegister(dev, CONFIG, &config, sizeof(config));
|
||||
//printf("CONFIG=%x\n",config);
|
||||
config = config & (_BV(CRCO) | _BV(EN_CRC));
|
||||
uint8_t AA;
|
||||
Nrf24_readRegister(dev, EN_AA, &AA, sizeof(AA));
|
||||
|
||||
if (config & _BV(EN_CRC) || AA) {
|
||||
if (config & _BV(CRCO)) {
|
||||
result = RF24_CRC_16;
|
||||
} else {
|
||||
result = RF24_CRC_8;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t Nrf24_getPALevel(NRF24_t * dev)
|
||||
{
|
||||
uint8_t level;
|
||||
Nrf24_readRegister(dev, RF_SETUP, &level, sizeof(level));
|
||||
//printf("RF_SETUP=%x\n",level);
|
||||
level = (level & (_BV(RF_PWR_LOW) | _BV(RF_PWR_HIGH))) >> 1;
|
||||
return (level);
|
||||
}
|
||||
|
||||
char * Nrf24_getPALevelString(NRF24_t * dev)
|
||||
{
|
||||
return rf24_pa_dbm[Nrf24_getPALevel(dev)];
|
||||
}
|
||||
|
||||
uint8_t Nrf24_getRetransmitDelay(NRF24_t * dev)
|
||||
{
|
||||
uint8_t value;
|
||||
Nrf24_readRegister(dev, SETUP_RETR, &value, 1);
|
||||
return (value >> 4);
|
||||
}
|
||||
|
||||
uint8_t Nrf24_getChannle(NRF24_t * dev)
|
||||
{
|
||||
return dev->channel;
|
||||
}
|
||||
|
||||
uint8_t Nrf24_getPayload(NRF24_t * dev)
|
||||
{
|
||||
return dev->payload;
|
||||
}
|
211
esp-idf-mirf-master/components/mirf/mirf.h
Normal file
211
esp-idf-mirf-master/components/mirf/mirf.h
Normal file
@ -0,0 +1,211 @@
|
||||
#ifndef MAIN_MIRF_H_
|
||||
#define MAIN_MIRF_H_
|
||||
|
||||
#include "driver/spi_master.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t PTX; //In sending mode.
|
||||
uint8_t cePin;// CE Pin controls RX / TX, default 8.
|
||||
uint8_t csnPin;//CSN Pin Chip Select Not, default 7.
|
||||
uint8_t channel;//Channel 0 - 127 or 0 - 84 in the US.
|
||||
uint8_t payload;// Payload width in bytes default 16 max 32.
|
||||
spi_device_handle_t _SPIHandle;
|
||||
uint8_t status;// Receive status
|
||||
} NRF24_t;
|
||||
|
||||
/* Memory Map */
|
||||
#define CONFIG 0x00
|
||||
#define EN_AA 0x01
|
||||
#define EN_RXADDR 0x02
|
||||
#define SETUP_AW 0x03
|
||||
#define SETUP_RETR 0x04
|
||||
#define RF_CH 0x05
|
||||
#define RF_SETUP 0x06
|
||||
#define STATUS 0x07
|
||||
#define OBSERVE_TX 0x08
|
||||
#define CD 0x09
|
||||
#define RX_ADDR_P0 0x0A
|
||||
#define RX_ADDR_P1 0x0B
|
||||
#define RX_ADDR_P2 0x0C
|
||||
#define RX_ADDR_P3 0x0D
|
||||
#define RX_ADDR_P4 0x0E
|
||||
#define RX_ADDR_P5 0x0F
|
||||
#define TX_ADDR 0x10
|
||||
#define RX_PW_P0 0x11
|
||||
#define RX_PW_P1 0x12
|
||||
#define RX_PW_P2 0x13
|
||||
#define RX_PW_P3 0x14
|
||||
#define RX_PW_P4 0x15
|
||||
#define RX_PW_P5 0x16
|
||||
#define FIFO_STATUS 0x17
|
||||
#define DYNPD 0x1C
|
||||
#define FEATURE 0x1D
|
||||
|
||||
/* Bit Mnemonics */
|
||||
#define MASK_RX_DR 6
|
||||
#define MASK_TX_DS 5
|
||||
#define MASK_MAX_RT 4
|
||||
#define EN_CRC 3
|
||||
#define CRCO 2
|
||||
#define PWR_UP 1
|
||||
#define PRIM_RX 0
|
||||
#define ENAA_P5 5
|
||||
#define ENAA_P4 4
|
||||
#define ENAA_P3 3
|
||||
#define ENAA_P2 2
|
||||
#define ENAA_P1 1
|
||||
#define ENAA_P0 0
|
||||
#define ERX_P5 5
|
||||
#define ERX_P4 4
|
||||
#define ERX_P3 3
|
||||
#define ERX_P2 2
|
||||
#define ERX_P1 1
|
||||
#define ERX_P0 0
|
||||
#define AW 0
|
||||
#define ARD 4
|
||||
#define ARC 0
|
||||
#define RF_DR_LOW 5
|
||||
#define PLL_LOCK 4
|
||||
#define RF_DR_HIGH 3
|
||||
#define RF_PWR 1
|
||||
#define LNA_HCURR 0
|
||||
#define RX_DR 6
|
||||
#define TX_DS 5
|
||||
#define MAX_RT 4
|
||||
#define RX_P_NO 1
|
||||
#define TX_FULL 0
|
||||
#define PLOS_CNT 4
|
||||
#define ARC_CNT 0
|
||||
#define TX_REUSE 6
|
||||
#define FIFO_FULL 5
|
||||
#define TX_EMPTY 4
|
||||
#define RX_FULL 1
|
||||
#define RX_EMPTY 0
|
||||
|
||||
/* Instruction Mnemonics */
|
||||
#define R_REGISTER 0x00
|
||||
#define W_REGISTER 0x20
|
||||
#define REGISTER_MASK 0x1F
|
||||
#define R_RX_PAYLOAD 0x61
|
||||
#define W_TX_PAYLOAD 0xA0
|
||||
#define FLUSH_TX 0xE1
|
||||
#define FLUSH_RX 0xE2
|
||||
#define REUSE_TX_PL 0xE3
|
||||
#define NOP 0xFF
|
||||
|
||||
/* Non-P omissions */
|
||||
#define LNA_HCURR 0
|
||||
|
||||
/* P model memory Map */
|
||||
#define RPD 0x09
|
||||
#define W_TX_PAYLOAD_NO_ACK 0xB0
|
||||
|
||||
/* P model bit Mnemonics */
|
||||
#define RF_DR_LOW 5
|
||||
#define RF_DR_HIGH 3
|
||||
#define RF_PWR_LOW 1
|
||||
#define RF_PWR_HIGH 2
|
||||
|
||||
/* Device addrees length:3~5 bytes */
|
||||
#define mirf_ADDR_LEN 5
|
||||
|
||||
/*
|
||||
enable interrupt caused by RX_DR.
|
||||
enable interrupt caused by TX_DS.
|
||||
enable interrupt caused by MAX_RT.
|
||||
enable CRC and CRC data len=1
|
||||
mirf_CONFIG = 00001000B
|
||||
*/
|
||||
//#define mirf_CONFIG ((1<<EN_CRC) | (0<<CRCO) )
|
||||
|
||||
/*
|
||||
enable interrupt caused by RX_DR.
|
||||
disable interrupt caused by TX_DS.
|
||||
enable interrupt caused by MAX_RT.
|
||||
enable CRC and CRC data len=1
|
||||
mirf_CONFIG == 00101000B
|
||||
*/
|
||||
#define mirf_CONFIG ((1<<MASK_TX_DS) | (1<<EN_CRC) | (0<<CRCO) )
|
||||
|
||||
/**
|
||||
* Power Amplifier level.
|
||||
*
|
||||
* For use with setPALevel()
|
||||
*/
|
||||
typedef enum {
|
||||
RF24_PA_MIN = 0,
|
||||
RF24_PA_LOW,
|
||||
RF24_PA_HIGH,
|
||||
RF24_PA_MAX,
|
||||
RF24_PA_ERROR
|
||||
} rf24_pa_dbm_e;
|
||||
|
||||
/**
|
||||
* Data rate. How fast data moves through the air.
|
||||
*
|
||||
* For use with setDataRate()
|
||||
*/
|
||||
typedef enum {
|
||||
RF24_1MBPS = 0,
|
||||
RF24_2MBPS,
|
||||
RF24_250KBPS
|
||||
} rf24_datarate_e;
|
||||
|
||||
/**
|
||||
* CRC Length. How big (if any) of a CRC is included.
|
||||
*
|
||||
* For use with setCRCLength()
|
||||
*/
|
||||
typedef enum {
|
||||
RF24_CRC_DISABLED = 0,
|
||||
RF24_CRC_8,
|
||||
RF24_CRC_16
|
||||
} rf24_crclength_e;
|
||||
|
||||
|
||||
void Nrf24_init(NRF24_t * dev);
|
||||
bool spi_write_byte(NRF24_t * dev, uint8_t* Dataout, size_t DataLength );
|
||||
bool spi_read_byte(NRF24_t * dev, uint8_t* Datain, uint8_t* Dataout, size_t DataLength );
|
||||
uint8_t spi_transfer(NRF24_t * dev, uint8_t address);
|
||||
void spi_csnLow(NRF24_t * dev);
|
||||
void spi_csnHi(NRF24_t * dev);
|
||||
void Nrf24_config(NRF24_t * dev, uint8_t channel, uint8_t payload);
|
||||
void Nrf24_send(NRF24_t * dev, uint8_t *value);
|
||||
esp_err_t Nrf24_setRADDR(NRF24_t * dev, uint8_t * adr);
|
||||
esp_err_t Nrf24_setTADDR(NRF24_t * dev, uint8_t * adr);
|
||||
void Nrf24_addRADDR(NRF24_t * dev, uint8_t pipe, uint8_t adr);
|
||||
bool Nrf24_dataReady(NRF24_t * dev);
|
||||
uint8_t Nrf24_getDataPipe(NRF24_t * dev);
|
||||
bool Nrf24_isSending(NRF24_t * dev);
|
||||
bool Nrf24_isSend(NRF24_t * dev, int timeout);
|
||||
bool Nrf24_rxFifoEmpty(NRF24_t * dev);
|
||||
bool Nrf24_txFifoEmpty(NRF24_t * dev);
|
||||
void Nrf24_getData(NRF24_t * dev, uint8_t * data);
|
||||
uint8_t Nrf24_getStatus(NRF24_t * dev);
|
||||
void Nrf24_configRegister(NRF24_t * dev, uint8_t reg, uint8_t value);
|
||||
void Nrf24_readRegister(NRF24_t * dev, uint8_t reg, uint8_t * value, uint8_t len);
|
||||
void Nrf24_writeRegister(NRF24_t * dev, uint8_t reg, uint8_t * value, uint8_t len);
|
||||
void Nrf24_powerUpRx(NRF24_t * dev);
|
||||
void Nrf24_powerUpTx(NRF24_t * dev);
|
||||
void Nrf24_powerDown(NRF24_t * dev);
|
||||
void Nrf24_SetOutputRF_PWR(NRF24_t * dev, uint8_t val);
|
||||
void Nrf24_SetSpeedDataRates(NRF24_t * dev, uint8_t val);
|
||||
void Nrf24_setRetransmitDelay(NRF24_t * dev, uint8_t val);
|
||||
void Nrf24_ceHi(NRF24_t * dev);
|
||||
void Nrf24_ceLow(NRF24_t * dev);
|
||||
void Nrf24_flushRx(NRF24_t * dev);
|
||||
void Nrf24_printDetails(NRF24_t * dev);
|
||||
void Nrf24_print_status(uint8_t status);
|
||||
void Nrf24_print_address_register(NRF24_t * dev, const char* name, uint8_t reg, uint8_t qty);
|
||||
void Nrf24_print_byte_register(NRF24_t * dev, const char* name, uint8_t reg, uint8_t qty);
|
||||
uint8_t Nrf24_getDataRate(NRF24_t * dev);
|
||||
char * Nrf24_getDataRateString(NRF24_t * dev);
|
||||
uint8_t Nrf24_getCRCLength(NRF24_t * dev);
|
||||
uint8_t Nrf24_getPALevel(NRF24_t * dev);
|
||||
char * Nrf24_getPALevelString(NRF24_t * dev);
|
||||
uint8_t Nrf24_getRetransmitDelay(NRF24_t * dev);
|
||||
uint8_t Nrf24_getChannle(NRF24_t * dev);
|
||||
uint8_t Nrf24_getPayload(NRF24_t * dev);
|
||||
|
||||
#endif /* MAIN_MIRF_H_ */
|
||||
|
8
esp-idf-mirf-master/http/CMakeLists.txt
Normal file
8
esp-idf-mirf-master/http/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS ../components/mirf)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(mirf)
|
78
esp-idf-mirf-master/http/README.md
Normal file
78
esp-idf-mirf-master/http/README.md
Normal file
@ -0,0 +1,78 @@
|
||||
# HTTP Example
|
||||
This is nRF24L01 and HTTP gateway application.
|
||||
```
|
||||
+-----------+ +-----------+ +-----------+
|
||||
| | | | | |
|
||||
|HTTP Client|--(HTTP)-->| ESP32 |--(SPI)--->| nRF24L01 |==(Radio)==>
|
||||
| | | | | |
|
||||
+-----------+ +-----------+ +-----------+
|
||||
|
||||
+-----------+ +-----------+ +-----------+
|
||||
| | | | | |
|
||||
==(Radio)==>| nRF24L01 |--(SPI)--->| ESP32 |--(HTTP)-->|HTTP Server|
|
||||
| | | | | |
|
||||
+-----------+ +-----------+ +-----------+
|
||||
```
|
||||
|
||||
|
||||
|
||||
# Configuration
|
||||

|
||||

|
||||
|
||||
## WiFi Setting
|
||||
|
||||

|
||||
|
||||
|
||||
## Radioi Setting
|
||||
|
||||
### HTTP to Radio
|
||||
Subscribe with HTTP and send to Radio.
|
||||
ESP32 acts as HTTP Server.
|
||||
You can use curl as HTTP Client.
|
||||
```sh ./http-client.sh```
|
||||
|
||||
```
|
||||
+-----------+ +-----------+ +-----------+
|
||||
| | | | | |
|
||||
|HTTP Client|--(HTTP)-->| ESP32 |--(SPI)--->| nRF24L01 |==(Radio)==>
|
||||
| | | | | |
|
||||
+-----------+ +-----------+ +-----------+
|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
### Radio to HTTP
|
||||
Receive from Radio and publish as HTTP.
|
||||
ESP32 acts as HTTP Client.
|
||||
You can use nc(netcat) as HTTP Server.
|
||||
```sh ./http-server.sh```
|
||||
|
||||
```
|
||||
+-----------+ +-----------+ +-----------+
|
||||
| | | | | |
|
||||
==(Radio)==>| nRF24L01 |--(SPI)--->| ESP32 |--(HTTP)-->|HTTP Server|
|
||||
| | | | | |
|
||||
+-----------+ +-----------+ +-----------+
|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
### Specifying an HTTP Server
|
||||
You can specify your HTTP Server in one of the following ways:
|
||||
- IP address
|
||||
```192.168.10.20```
|
||||
- mDNS host name
|
||||
```http-server.local```
|
||||
- Fully Qualified Domain Name
|
||||
```http-server.public.io```
|
||||
|
||||
|
||||
# Communicate with Arduino Environment
|
||||
Run this sketch.
|
||||
ArduinoCode\Peer-to-peer\StringTest
|
||||
|
32
esp-idf-mirf-master/http/http-client.py
Normal file
32
esp-idf-mirf-master/http/http-client.py
Normal file
@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import time
|
||||
import datetime
|
||||
import socket
|
||||
import requests
|
||||
|
||||
server = "esp32-server.local"
|
||||
port = 8080
|
||||
try:
|
||||
ip = socket.gethostbyname(server)
|
||||
except socket.gaierror as e:
|
||||
print(f'Invalid hostname, error raised is {e}')
|
||||
exit()
|
||||
ip = socket.gethostbyname(server)
|
||||
print("ip={}".format(ip))
|
||||
uri = "http://{}:{}/post".format(ip, port)
|
||||
print("uri={}".format(uri))
|
||||
|
||||
timezone = datetime.timedelta(hours=9)
|
||||
|
||||
while True:
|
||||
dt_now = datetime.datetime.now(datetime.timezone(timezone))
|
||||
#payload = "{}".format(datetime.datetime.now())
|
||||
#payload = "{}".format(datetime.datetime.now(datetime.timezone(timezone)))
|
||||
payload = dt_now.strftime('%Y/%m/%d %H:%M:%S')
|
||||
#print(payload)
|
||||
response = requests.post(uri, data=payload)
|
||||
#print(response.status_code)
|
||||
print("{}-->{}".format(payload, response.text))
|
||||
#print(response.text)
|
||||
time.sleep(1)
|
17
esp-idf-mirf-master/http/http-client.sh
Normal file
17
esp-idf-mirf-master/http/http-client.sh
Normal file
@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
#sudo apt install avahi-utils
|
||||
#set -x
|
||||
SERVER="esp32-server.local"
|
||||
HOST=`avahi-resolve -4 -n ${SERVER} | cut -f 2`
|
||||
echo $HOST
|
||||
URI="http://${HOST}:8080/post"
|
||||
|
||||
while :
|
||||
do
|
||||
payload=`date "+%Y/%m/%d %H:%M:%S"`
|
||||
#echo ${payload}
|
||||
echo curl -d "${payload}" ${URI}
|
||||
curl -d "${payload}" ${URI}
|
||||
echo ""
|
||||
sleep 1
|
||||
done
|
37
esp-idf-mirf-master/http/http-server.py
Normal file
37
esp-idf-mirf-master/http/http-server.py
Normal file
@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# https://qiita.com/tkj/items/210a66213667bc038110
|
||||
|
||||
from http.server import HTTPServer
|
||||
from http.server import BaseHTTPRequestHandler
|
||||
from urllib.parse import urlparse
|
||||
from urllib.parse import parse_qs
|
||||
|
||||
class class1(BaseHTTPRequestHandler):
|
||||
def do_POST(self):
|
||||
#parsed = urlparse(self.path)
|
||||
#print("parsed={}".format(parsed))
|
||||
#params = parse_qs(parsed.query)
|
||||
#print("params={}".format(params))
|
||||
content_len = int(self.headers.get("content-length"))
|
||||
#print("content_len={}".format(content_len))
|
||||
req_body = self.rfile.read(content_len).decode("utf-8")
|
||||
#print("req_body={}".format(req_body))
|
||||
print("{}".format(req_body))
|
||||
|
||||
body = "OK"
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'text/html; charset=utf-8')
|
||||
self.send_header('Content-length', len(body.encode()))
|
||||
self.end_headers()
|
||||
self.wfile.write(body.encode())
|
||||
|
||||
#host = '127.0.0.1'
|
||||
host = '0.0.0.0'
|
||||
port = 8080
|
||||
|
||||
print("Listening on port {}". format(port))
|
||||
server = HTTPServer((host, port), class1)
|
||||
|
||||
server.serve_forever()
|
12
esp-idf-mirf-master/http/http-server.sh
Normal file
12
esp-idf-mirf-master/http/http-server.sh
Normal file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
PORT=8080
|
||||
echo "Listening on port" ${PORT}
|
||||
while true
|
||||
do
|
||||
# Header & payload
|
||||
#( echo "HTTP/1.0 200 Ok"; echo; echo -n "OK") | nc -l -p ${PORT} -w 1
|
||||
|
||||
# Payload only
|
||||
( echo "HTTP/1.0 200 Ok"; echo; echo -n "OK") | nc -l -p ${PORT} -w 1 | tail -n 1
|
||||
echo ""
|
||||
done
|
4
esp-idf-mirf-master/http/main/CMakeLists.txt
Normal file
4
esp-idf-mirf-master/http/main/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
set(component_srcs "main.c" "http_client.c" "http_server.c")
|
||||
|
||||
idf_component_register(SRCS "${component_srcs}"
|
||||
INCLUDE_DIRS ".")
|
71
esp-idf-mirf-master/http/main/Kconfig.projbuild
Normal file
71
esp-idf-mirf-master/http/main/Kconfig.projbuild
Normal file
@ -0,0 +1,71 @@
|
||||
menu "Application Configuration"
|
||||
|
||||
menu "WiFi Setting"
|
||||
|
||||
config ESP_WIFI_SSID
|
||||
string "WiFi SSID"
|
||||
default "myssid"
|
||||
help
|
||||
SSID (network name) to connect to.
|
||||
|
||||
config ESP_WIFI_PASSWORD
|
||||
string "WiFi Password"
|
||||
default "mypassword"
|
||||
help
|
||||
WiFi password (WPA or WPA2) to connect to.
|
||||
|
||||
config ESP_MAXIMUM_RETRY
|
||||
int "Maximum retry"
|
||||
default 5
|
||||
help
|
||||
Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent.
|
||||
|
||||
config MDNS_HOSTNAME
|
||||
string "mDNS Hostname"
|
||||
default "esp32-server"
|
||||
help
|
||||
The mDNS host name used by the ESP32.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Radio Setting"
|
||||
|
||||
choice DIRECTION
|
||||
prompt "Communication polarity"
|
||||
default SENDER
|
||||
help
|
||||
Select Communication polarity.
|
||||
config SENDER
|
||||
bool "HTTP to Radio"
|
||||
help
|
||||
HTTP to Radio.
|
||||
config RECEIVER
|
||||
bool "Radio to HTTP"
|
||||
help
|
||||
Radio to HTTP.
|
||||
endchoice
|
||||
|
||||
config WEB_SERVER_HOST
|
||||
depends on RECEIVER
|
||||
string "server to connect to"
|
||||
default "http-server.local"
|
||||
help
|
||||
server to connect to.
|
||||
|
||||
config WEB_SERVER_PORT
|
||||
depends on RECEIVER
|
||||
int "port to connect to"
|
||||
default 8080
|
||||
help
|
||||
port to connect to.
|
||||
|
||||
config WEB_SERVER_PORT
|
||||
depends on SENDER
|
||||
int "Listening port"
|
||||
default 8080
|
||||
help
|
||||
Listening port.
|
||||
|
||||
endmenu
|
||||
|
||||
endmenu
|
5
esp-idf-mirf-master/http/main/component.mk
Normal file
5
esp-idf-mirf-master/http/main/component.mk
Normal file
@ -0,0 +1,5 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
|
195
esp-idf-mirf-master/http/main/http_client.c
Normal file
195
esp-idf-mirf-master/http/main/http_client.c
Normal file
@ -0,0 +1,195 @@
|
||||
/* ESP HTTP Client Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/message_buffer.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_tls.h"
|
||||
#include "esp_http_client.h"
|
||||
|
||||
#if CONFIG_RECEIVER
|
||||
|
||||
static const char *TAG = "CLIENT";
|
||||
|
||||
extern MessageBufferHandle_t xMessageBufferTrans;
|
||||
extern size_t xItemSize;
|
||||
|
||||
|
||||
esp_err_t _http_event_handler(esp_http_client_event_t *evt)
|
||||
{
|
||||
static char *output_buffer; // Buffer to store response of http request from event handler
|
||||
static int output_len; // Stores number of bytes read
|
||||
switch(evt->event_id) {
|
||||
case HTTP_EVENT_ERROR:
|
||||
ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
|
||||
break;
|
||||
case HTTP_EVENT_ON_CONNECTED:
|
||||
ESP_LOGI(TAG, "HTTP_EVENT_ON_CONNECTED");
|
||||
break;
|
||||
case HTTP_EVENT_HEADER_SENT:
|
||||
ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
|
||||
break;
|
||||
case HTTP_EVENT_ON_HEADER:
|
||||
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
|
||||
break;
|
||||
case HTTP_EVENT_ON_DATA:
|
||||
ESP_LOGI(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
|
||||
/*
|
||||
* Check for chunked encoding is added as the URL for chunked encoding used in this example returns binary data.
|
||||
* However, event handler can also be used in case chunked encoding is used.
|
||||
*/
|
||||
if (!esp_http_client_is_chunked_response(evt->client)) {
|
||||
// If user_data buffer is configured, copy the response into the buffer
|
||||
if (evt->user_data) {
|
||||
memcpy(evt->user_data + output_len, evt->data, evt->data_len);
|
||||
} else {
|
||||
if (output_buffer == NULL) {
|
||||
output_buffer = (char *) malloc(esp_http_client_get_content_length(evt->client));
|
||||
output_len = 0;
|
||||
if (output_buffer == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to allocate memory for output buffer");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
memcpy(output_buffer + output_len, evt->data, evt->data_len);
|
||||
}
|
||||
output_len += evt->data_len;
|
||||
}
|
||||
|
||||
break;
|
||||
case HTTP_EVENT_ON_FINISH:
|
||||
ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
|
||||
if (output_buffer != NULL) {
|
||||
// Response is accumulated in output_buffer. Uncomment the below line to print the accumulated response
|
||||
// ESP_LOG_BUFFER_HEX(TAG, output_buffer, output_len);
|
||||
free(output_buffer);
|
||||
output_buffer = NULL;
|
||||
}
|
||||
output_len = 0;
|
||||
break;
|
||||
case HTTP_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
|
||||
int mbedtls_err = 0;
|
||||
esp_err_t err = esp_tls_get_and_clear_last_error(evt->data, &mbedtls_err, NULL);
|
||||
ESP_LOGI(TAG, "Last esp error code: 0x%x", err);
|
||||
ESP_LOGI(TAG, "Last mbedtls failure: 0x%x", mbedtls_err);
|
||||
if (output_buffer != NULL) {
|
||||
free(output_buffer);
|
||||
output_buffer = NULL;
|
||||
}
|
||||
output_len = 0;
|
||||
break;
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
case HTTP_EVENT_REDIRECT:
|
||||
ESP_LOGD(TAG, "HTTP_EVENT_REDIRECT");
|
||||
esp_http_client_set_header(evt->client, "From", "user@example.com");
|
||||
esp_http_client_set_header(evt->client, "Accept", "text/html");
|
||||
esp_http_client_set_redirection(evt->client);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#define MAX_HTTP_OUTPUT_BUFFER 128
|
||||
|
||||
esp_err_t http_post_with_url(char *url, char * post_data, size_t post_len)
|
||||
{
|
||||
ESP_LOGI(TAG, "http_post_with_url url=[%s]", url);
|
||||
char local_response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
|
||||
/**
|
||||
* NOTE: All the configuration parameters for http_client must be spefied either in URL or as host and path parameters.
|
||||
* If host and path parameters are not set, query parameter will be ignored. In such cases,
|
||||
* query parameter should be specified in URL.
|
||||
*
|
||||
* If URL as well as host and path parameters are specified, values of host and path will be considered.
|
||||
*/
|
||||
|
||||
#if 1
|
||||
esp_http_client_config_t config = {
|
||||
.url = url,
|
||||
.path = "/post",
|
||||
.event_handler = _http_event_handler,
|
||||
.user_data = local_response_buffer, // Pass address of local buffer to get response
|
||||
.disable_auto_redirect = true,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
esp_http_client_config_t config = {
|
||||
.url = "http://192.168.10.46:8080",
|
||||
.path = "/post",
|
||||
.event_handler = _http_event_handler,
|
||||
.user_data = local_response_buffer, // Pass address of local buffer to get response
|
||||
.disable_auto_redirect = true,
|
||||
};
|
||||
#endif
|
||||
|
||||
esp_http_client_handle_t client = esp_http_client_init(&config);
|
||||
|
||||
// POST
|
||||
esp_http_client_set_method(client, HTTP_METHOD_POST);
|
||||
esp_http_client_set_header(client, "Content-Type", "application/json");
|
||||
//esp_http_client_set_post_field(client, post_data, strlen(post_data));
|
||||
esp_http_client_set_post_field(client, post_data, post_len);
|
||||
esp_err_t err = esp_http_client_perform(client);
|
||||
if (err == ESP_OK) {
|
||||
ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %d",
|
||||
esp_http_client_get_status_code(client),
|
||||
(int)esp_http_client_get_content_length(client));
|
||||
ESP_LOGI(TAG, "local_response_buffer=[%s]", local_response_buffer);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err));
|
||||
}
|
||||
|
||||
esp_http_client_cleanup(client);
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t query_mdns_host(const char * host_name, char *ip);
|
||||
void convert_mdns_host(char * from, char * to);
|
||||
|
||||
void http_client(void *pvParameters)
|
||||
{
|
||||
ESP_LOGI(TAG, "Start WEB_SERVER_HOST:%s WEB_SERVER_PORT:%d", CONFIG_WEB_SERVER_HOST, CONFIG_WEB_SERVER_PORT);
|
||||
|
||||
// Resolve mDNS host name
|
||||
char ip[128];
|
||||
ESP_LOGI(TAG, "CONFIG_WEB_SERVER_HOST=[%s]", CONFIG_WEB_SERVER_HOST);
|
||||
convert_mdns_host(CONFIG_WEB_SERVER_HOST, ip);
|
||||
ESP_LOGI(TAG, "ip=[%s]", ip);
|
||||
char url[142];
|
||||
sprintf(url, "http://%s:%d", ip, CONFIG_WEB_SERVER_PORT);
|
||||
ESP_LOGI(TAG, "url=[%s]", url);
|
||||
|
||||
char buffer[xItemSize];
|
||||
while (1) {
|
||||
size_t received = xMessageBufferReceive(xMessageBufferTrans, buffer, sizeof(buffer), portMAX_DELAY);
|
||||
ESP_LOGI(TAG, "xMessageBufferReceive received=%d", received);
|
||||
if (received > 0) {
|
||||
ESP_LOGI(TAG, "xMessageBufferReceive buffer=[%.*s]",received, buffer);
|
||||
//http_post_with_url("http://192.168.10.46:8000", buffer, received);
|
||||
if (http_post_with_url(url, buffer, received) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "http_post_with_url fail");
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "xMessageBufferReceive fail");
|
||||
break;
|
||||
}
|
||||
} // end while
|
||||
|
||||
// Stop connection
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
#endif
|
117
esp-idf-mirf-master/http/main/http_server.c
Normal file
117
esp-idf-mirf-master/http/main/http_server.c
Normal file
@ -0,0 +1,117 @@
|
||||
/* Simple HTTP Server Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/message_buffer.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_http_server.h"
|
||||
|
||||
#if CONFIG_SENDER
|
||||
|
||||
static const char *TAG = "SERVER";
|
||||
|
||||
extern MessageBufferHandle_t xMessageBufferRecv;
|
||||
extern size_t xItemSize;
|
||||
|
||||
/* root post handler */
|
||||
static esp_err_t root_post_handler(httpd_req_t *req)
|
||||
{
|
||||
ESP_LOGI(TAG, "root_post_handler. req->content_len=%d", req->content_len);
|
||||
|
||||
/* Allocate memory */
|
||||
char *buf = NULL;
|
||||
buf = malloc(req->content_len);
|
||||
if (buf == NULL) {
|
||||
ESP_LOGE(TAG, "malloc fail. req->content_len=%d", req->content_len);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* Read the data for the request */
|
||||
if (httpd_req_recv(req, buf, req->content_len) != req->content_len) {
|
||||
ESP_LOGE(TAG, "httpd_req_recv fail");
|
||||
free(buf);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* Log data received */
|
||||
ESP_LOGI(TAG, "%.*s", req->content_len, buf);
|
||||
size_t sended = xMessageBufferSend(xMessageBufferRecv, buf, req->content_len, portMAX_DELAY);
|
||||
if (sended != req->content_len) {
|
||||
ESP_LOGE(TAG, "xMessageBufferSend fail. sended=%d req->content_len=%d", sended, req->content_len);
|
||||
}
|
||||
free(buf);
|
||||
|
||||
/* Send response */
|
||||
httpd_resp_sendstr_chunk(req, "OK");
|
||||
|
||||
/* Send empty chunk to signal HTTP response completion */
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* favicon get handler */
|
||||
static esp_err_t favicon_get_handler(httpd_req_t *req)
|
||||
{
|
||||
ESP_LOGI(TAG, "favicon_get_handler");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Function to start the web server */
|
||||
esp_err_t start_server(int port)
|
||||
{
|
||||
httpd_handle_t server = NULL;
|
||||
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
||||
|
||||
// Purge“"Least Recently Used” connection
|
||||
config.lru_purge_enable = true;
|
||||
// TCP Port number for receiving and transmitting HTTP traffic
|
||||
config.server_port = port;
|
||||
|
||||
// Start the httpd server
|
||||
if (httpd_start(&server, &config) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to starting server!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// Set URI handlers
|
||||
httpd_uri_t _root_post_handler = {
|
||||
.uri = "/post",
|
||||
.method = HTTP_POST,
|
||||
.handler = root_post_handler,
|
||||
.user_ctx = NULL,
|
||||
};
|
||||
httpd_register_uri_handler(server, &_root_post_handler);
|
||||
|
||||
httpd_uri_t _favicon_get_handler = {
|
||||
.uri = "/favicon.ico",
|
||||
.method = HTTP_GET,
|
||||
.handler = favicon_get_handler,
|
||||
.user_ctx = NULL,
|
||||
};
|
||||
httpd_register_uri_handler(server, &_favicon_get_handler);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void http_server(void *pvParameters)
|
||||
{
|
||||
char *task_parameter = (char *)pvParameters;
|
||||
ESP_LOGI(TAG, "Start task_parameter=%s", task_parameter);
|
||||
char url[64];
|
||||
int port = CONFIG_WEB_SERVER_PORT;
|
||||
sprintf(url, "http://%s:%d", task_parameter, port);
|
||||
ESP_LOGI(TAG, "Starting HTTP server on %s", url);
|
||||
ESP_ERROR_CHECK(start_server(port));
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
#endif
|
6
esp-idf-mirf-master/http/main/idf_component.yml
Normal file
6
esp-idf-mirf-master/http/main/idf_component.yml
Normal file
@ -0,0 +1,6 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/mdns:
|
||||
version: "^1.0.3"
|
||||
rules:
|
||||
- if: "idf_version >=5.0"
|
369
esp-idf-mirf-master/http/main/main.c
Normal file
369
esp-idf-mirf-master/http/main/main.c
Normal file
@ -0,0 +1,369 @@
|
||||
/* Mirf Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "freertos/message_buffer.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "mdns.h"
|
||||
|
||||
#include "mirf.h"
|
||||
|
||||
/* FreeRTOS event group to signal when we are connected*/
|
||||
static EventGroupHandle_t s_wifi_event_group;
|
||||
|
||||
/* The event group allows multiple bits for each event, but we only care about two events:
|
||||
* - we are connected to the AP with an IP
|
||||
* - we failed to connect after the maximum amount of retries */
|
||||
#define WIFI_CONNECTED_BIT BIT0
|
||||
#define WIFI_FAIL_BIT BIT1
|
||||
|
||||
static const char *TAG = "MAIN";
|
||||
|
||||
static int s_retry_num = 0;
|
||||
|
||||
MessageBufferHandle_t xMessageBufferTrans;
|
||||
MessageBufferHandle_t xMessageBufferRecv;
|
||||
|
||||
// The total number of bytes (not single messages) the message buffer will be able to hold at any one time.
|
||||
size_t xBufferSizeBytes = 1024;
|
||||
// The size, in bytes, required to hold each item in the message,
|
||||
size_t xItemSize = 32;
|
||||
|
||||
static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
|
||||
{
|
||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
|
||||
esp_wifi_connect();
|
||||
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||
if (s_retry_num < CONFIG_ESP_MAXIMUM_RETRY) {
|
||||
esp_wifi_connect();
|
||||
s_retry_num++;
|
||||
ESP_LOGI(TAG, "retry to connect to the AP");
|
||||
} else {
|
||||
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
|
||||
}
|
||||
ESP_LOGI(TAG,"connect to the AP fail");
|
||||
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
||||
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
|
||||
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
|
||||
s_retry_num = 0;
|
||||
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool wifi_init_sta(void)
|
||||
{
|
||||
bool ret = false;
|
||||
s_wifi_event_group = xEventGroupCreate();
|
||||
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
esp_netif_create_default_wifi_sta();
|
||||
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||
|
||||
esp_event_handler_instance_t instance_any_id;
|
||||
esp_event_handler_instance_t instance_got_ip;
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
||||
ESP_EVENT_ANY_ID,
|
||||
&event_handler,
|
||||
NULL,
|
||||
&instance_any_id));
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
|
||||
IP_EVENT_STA_GOT_IP,
|
||||
&event_handler,
|
||||
NULL,
|
||||
&instance_got_ip));
|
||||
|
||||
wifi_config_t wifi_config = {
|
||||
.sta = {
|
||||
.ssid = CONFIG_ESP_WIFI_SSID,
|
||||
.password = CONFIG_ESP_WIFI_PASSWORD,
|
||||
/* Setting a password implies station will connect to all security modes including WEP/WPA.
|
||||
* However these modes are deprecated and not advisable to be used. Incase your Access point
|
||||
* doesn't support WPA2, these mode can be enabled by commenting below line */
|
||||
.threshold.authmode = WIFI_AUTH_WPA2_PSK,
|
||||
|
||||
.pmf_cfg = {
|
||||
.capable = true,
|
||||
.required = false
|
||||
},
|
||||
},
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
|
||||
ESP_ERROR_CHECK(esp_wifi_start() );
|
||||
|
||||
ESP_LOGI(TAG, "wifi_init_sta finished.");
|
||||
|
||||
/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
|
||||
* number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
|
||||
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
|
||||
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
|
||||
pdFALSE,
|
||||
pdFALSE,
|
||||
portMAX_DELAY);
|
||||
|
||||
/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
|
||||
* happened. */
|
||||
if (bits & WIFI_CONNECTED_BIT) {
|
||||
ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", CONFIG_ESP_WIFI_SSID, CONFIG_ESP_WIFI_PASSWORD);
|
||||
ret = true;
|
||||
} else if (bits & WIFI_FAIL_BIT) {
|
||||
ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", CONFIG_ESP_WIFI_SSID, CONFIG_ESP_WIFI_PASSWORD);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "UNEXPECTED EVENT");
|
||||
}
|
||||
|
||||
/* The event will not be processed after unregister */
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip));
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id));
|
||||
vEventGroupDelete(s_wifi_event_group);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t query_mdns_host(const char * host_name, char *ip)
|
||||
{
|
||||
ESP_LOGD(__FUNCTION__, "Query A: %s", host_name);
|
||||
|
||||
struct esp_ip4_addr addr;
|
||||
addr.addr = 0;
|
||||
|
||||
esp_err_t err = mdns_query_a(host_name, 10000, &addr);
|
||||
if(err){
|
||||
if(err == ESP_ERR_NOT_FOUND){
|
||||
ESP_LOGW(__FUNCTION__, "%s: Host was not found!", esp_err_to_name(err));
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_LOGE(__FUNCTION__, "Query Failed: %s", esp_err_to_name(err));
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_LOGD(__FUNCTION__, "Query A: %s.local resolved to: " IPSTR, host_name, IP2STR(&addr));
|
||||
sprintf(ip, IPSTR, IP2STR(&addr));
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void convert_mdns_host(char * from, char * to)
|
||||
{
|
||||
ESP_LOGI(__FUNCTION__, "from=[%s]",from);
|
||||
strcpy(to, from);
|
||||
char *sp;
|
||||
sp = strstr(from, ".local");
|
||||
if (sp == NULL) return;
|
||||
|
||||
int _len = sp - from;
|
||||
ESP_LOGD(__FUNCTION__, "_len=%d", _len);
|
||||
char _from[128];
|
||||
strcpy(_from, from);
|
||||
_from[_len] = 0;
|
||||
ESP_LOGI(__FUNCTION__, "_from=[%s]", _from);
|
||||
|
||||
char _ip[128];
|
||||
esp_err_t ret = query_mdns_host(_from, _ip);
|
||||
ESP_LOGI(__FUNCTION__, "query_mdns_host=%d _ip=[%s]", ret, _ip);
|
||||
if (ret != ESP_OK) return;
|
||||
|
||||
strcpy(to, _ip);
|
||||
ESP_LOGI(__FUNCTION__, "to=[%s]", to);
|
||||
}
|
||||
|
||||
void initialize_mdns(void)
|
||||
{
|
||||
//initialize mDNS
|
||||
ESP_ERROR_CHECK( mdns_init() );
|
||||
//set mDNS hostname (required if you want to advertise services)
|
||||
ESP_ERROR_CHECK( mdns_hostname_set(CONFIG_MDNS_HOSTNAME) );
|
||||
ESP_LOGI(TAG, "mdns hostname set to: [%s]", CONFIG_MDNS_HOSTNAME);
|
||||
|
||||
#if 0
|
||||
//set default mDNS instance name
|
||||
ESP_ERROR_CHECK( mdns_instance_name_set("ESP32 with mDNS") );
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
void AdvancedSettings(NRF24_t * dev)
|
||||
{
|
||||
#if CONFIG_RF_RATIO_2M
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 2MBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 1);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
#if CONFIG_RF_RATIO_1M
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 1MBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 0);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
#if CONFIG_RF_RATIO_250K
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 250KBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 2);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
ESP_LOGW(pcTaskGetName(0), "CONFIG_RETRANSMIT_DELAY=%d", CONFIG_RETRANSMIT_DELAY);
|
||||
Nrf24_setRetransmitDelay(dev, CONFIG_RETRANSMIT_DELAY);
|
||||
}
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
#if CONFIG_RECEIVER
|
||||
void receiver(void *pvParameters)
|
||||
{
|
||||
ESP_LOGI(pcTaskGetName(0), "Start");
|
||||
NRF24_t dev;
|
||||
Nrf24_init(&dev);
|
||||
uint8_t payload = 32;
|
||||
uint8_t channel = CONFIG_RADIO_CHANNEL;
|
||||
Nrf24_config(&dev, channel, payload);
|
||||
|
||||
// Set my own address using 5 characters
|
||||
esp_err_t ret = Nrf24_setRADDR(&dev, (uint8_t *)"FGHIJ");
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(pcTaskGetName(0), "nrf24l01 not installed");
|
||||
while(1) { vTaskDelay(1); }
|
||||
}
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
AdvancedSettings(&dev);
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
// Print settings
|
||||
Nrf24_printDetails(&dev);
|
||||
|
||||
uint8_t buf[xItemSize];
|
||||
|
||||
// Clear RX FiFo
|
||||
while(1) {
|
||||
if (Nrf24_dataReady(&dev) == false) break;
|
||||
Nrf24_getData(&dev, buf);
|
||||
}
|
||||
|
||||
while(1) {
|
||||
// Wait for received data
|
||||
if (Nrf24_dataReady(&dev)) {
|
||||
Nrf24_getData(&dev, buf);
|
||||
ESP_LOGI(pcTaskGetName(NULL), "Nrf24_getData buf=[%.*s]",payload, buf);
|
||||
size_t spacesAvailable = xMessageBufferSpacesAvailable( xMessageBufferTrans );
|
||||
ESP_LOGI(pcTaskGetName(NULL), "spacesAvailable=%d", spacesAvailable);
|
||||
if (spacesAvailable < xItemSize*2) {
|
||||
ESP_LOGW(pcTaskGetName(NULL), "xMessageBuffer available less than %d", xItemSize*2);
|
||||
} else {
|
||||
size_t sended = xMessageBufferSend(xMessageBufferTrans, buf, payload, portMAX_DELAY);
|
||||
if (sended != payload) {
|
||||
ESP_LOGE(pcTaskGetName(NULL), "xMessageBufferSend fail");
|
||||
}
|
||||
}
|
||||
}
|
||||
vTaskDelay(1); // Avoid WatchDog alerts
|
||||
} // end while
|
||||
}
|
||||
#endif // CONFIG_RECEIVER
|
||||
|
||||
|
||||
#if CONFIG_SENDER
|
||||
void sender(void *pvParameters)
|
||||
{
|
||||
ESP_LOGI(pcTaskGetName(0), "Start");
|
||||
NRF24_t dev;
|
||||
Nrf24_init(&dev);
|
||||
uint8_t payload = 32;
|
||||
uint8_t channel = CONFIG_RADIO_CHANNEL;
|
||||
Nrf24_config(&dev, channel, payload);
|
||||
|
||||
// Set destination address using 5 characters
|
||||
esp_err_t ret = Nrf24_setTADDR(&dev, (uint8_t *)"FGHIJ");
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(pcTaskGetName(0), "nrf24l01 not installed");
|
||||
while(1) { vTaskDelay(1); }
|
||||
}
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
AdvancedSettings(&dev);
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
// Print settings
|
||||
Nrf24_printDetails(&dev);
|
||||
|
||||
ESP_LOGI(pcTaskGetName(0), "Wait for http...");
|
||||
uint8_t buf[xItemSize];
|
||||
while(1) {
|
||||
size_t received = xMessageBufferReceive(xMessageBufferRecv, buf, sizeof(buf), portMAX_DELAY);
|
||||
ESP_LOGI(pcTaskGetName(NULL), "xMessageBufferReceive received=%d", received);
|
||||
Nrf24_send(&dev, buf);
|
||||
vTaskDelay(1);
|
||||
ESP_LOGI(pcTaskGetName(0), "Wait for sending.....");
|
||||
if (Nrf24_isSend(&dev, 1000)) {
|
||||
ESP_LOGI(pcTaskGetName(0),"Send success");
|
||||
} else {
|
||||
ESP_LOGW(pcTaskGetName(0),"Send fail");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_SENDER
|
||||
|
||||
void http_client(void *pvParameters);
|
||||
void http_server(void *pvParameters);
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Initialize NVS
|
||||
esp_err_t ret = nvs_flash_init();
|
||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ret = nvs_flash_init();
|
||||
}
|
||||
ESP_ERROR_CHECK(ret);
|
||||
|
||||
// Initialize WiFi
|
||||
if (wifi_init_sta() == false) {
|
||||
while(1) vTaskDelay(10);
|
||||
}
|
||||
|
||||
// Create MessageBuffer
|
||||
xMessageBufferTrans = xMessageBufferCreate(xBufferSizeBytes);
|
||||
configASSERT( xMessageBufferTrans );
|
||||
xMessageBufferRecv = xMessageBufferCreate(xBufferSizeBytes);
|
||||
configASSERT( xMessageBufferRecv );
|
||||
|
||||
// Initialize mDNS
|
||||
initialize_mdns();
|
||||
|
||||
// Get the local IP address
|
||||
esp_netif_ip_info_t ip_info;
|
||||
ESP_ERROR_CHECK(esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &ip_info));
|
||||
char cparam0[64];
|
||||
sprintf(cparam0, IPSTR, IP2STR(&ip_info.ip));
|
||||
ESP_LOGI(TAG, "cparam0=[%s]", cparam0);
|
||||
|
||||
#if CONFIG_SENDER
|
||||
xTaskCreate(&sender, "TX", 1024*3, NULL, 2, NULL);
|
||||
xTaskCreate(&http_server, "HTTP_SERVER", 1024*4, (void *)cparam0, 5, NULL);
|
||||
#endif
|
||||
#if CONFIG_RECEIVER
|
||||
xTaskCreate(&receiver, "RX", 1024*3, NULL, 2, NULL);
|
||||
xTaskCreate(&http_client, "HTTP_CLIENT", 1024*4, NULL, 5, NULL);
|
||||
#endif
|
||||
|
||||
while(1) {
|
||||
vTaskDelay(10);
|
||||
}
|
||||
|
||||
}
|
8
esp-idf-mirf-master/mqtt/CMakeLists.txt
Normal file
8
esp-idf-mirf-master/mqtt/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS ../components/mirf)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(mirf)
|
80
esp-idf-mirf-master/mqtt/README.md
Normal file
80
esp-idf-mirf-master/mqtt/README.md
Normal file
@ -0,0 +1,80 @@
|
||||
# MQTT Example
|
||||
This is nRF24L01 and MQTT gateway application.
|
||||
```
|
||||
+----------+ +----------+ +----------+ +----------+
|
||||
| | | | | | | |
|
||||
|Publisher |--(MQTT)-->| Broker |--(MQTT)-->| ESP32 |--(SPI)--->| nRF24L01 |==(Radio)==>
|
||||
| | | | | | | |
|
||||
+----------+ +----------+ +----------+ +----------+
|
||||
|
||||
+----------+ +----------+ +----------+ +----------+
|
||||
| | | | | | | |
|
||||
==(Radio)==>| nRF24L01 |--(SPI)--->| ESP32 |--(MQTT)-->| Broker |--(MQTT)-->|Subscriber|
|
||||
| | | | | | | |
|
||||
+----------+ +----------+ +----------+ +----------+
|
||||
```
|
||||
|
||||
|
||||
|
||||
# Configuration
|
||||

|
||||

|
||||
|
||||
|
||||
## WiFi Setting
|
||||
|
||||

|
||||
|
||||
|
||||
## Radioi Setting
|
||||
|
||||
### MQTT to Radio
|
||||
Subscribe with MQTT and send to Radio.
|
||||
You can use mosquitto_pub as Publisher.
|
||||
```sh ./mqtt_pub.sh```
|
||||
|
||||
```
|
||||
+----------+ +----------+ +----------+ +----------+
|
||||
| | | | | | | |
|
||||
|Publisher |--(MQTT)-->| Broker |--(MQTT)-->| ESP32 |--(SPI)--->| nRF24L01 |==(Radio)==>
|
||||
| | | | | | | |
|
||||
+----------+ +----------+ +----------+ +----------+
|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
### Radio to MQTT
|
||||
Receive from Radio and publish as MQTT.
|
||||
You can use mosquitto_sub as Subscriber.
|
||||
```sh ./mqtt_sub.sh```
|
||||
|
||||
```
|
||||
+----------+ +----------+ +----------+ +----------+
|
||||
| | | | | | | |
|
||||
==(Radio)==>| nRF24L01 |--(SPI)--->| ESP32 |--(MQTT)-->| Broker |--(MQTT)-->|Subscriber|
|
||||
| | | | | | | |
|
||||
+----------+ +----------+ +----------+ +----------+
|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
### Specifying an MQTT Broker
|
||||
You can specify your MQTT broker in one of the following ways:
|
||||
- IP address
|
||||
```192.168.10.20```
|
||||
- mDNS host name
|
||||
```mqtt-broker.local```
|
||||
- Fully Qualified Domain Name
|
||||
```broker.emqx.io```
|
||||
|
||||
You can use this as broker.
|
||||
https://github.com/nopnop2002/esp-idf-mqtt-broker
|
||||
|
||||
|
||||
# Communicate with Arduino Environment
|
||||
Run this sketch.
|
||||
ArduinoCode\Peer-to-peer\StringTest
|
||||
|
4
esp-idf-mirf-master/mqtt/main/CMakeLists.txt
Normal file
4
esp-idf-mirf-master/mqtt/main/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
set(component_srcs "main.c" "mqtt_pub.c" "mqtt_sub.c")
|
||||
|
||||
idf_component_register(SRCS "${component_srcs}"
|
||||
INCLUDE_DIRS ".")
|
84
esp-idf-mirf-master/mqtt/main/Kconfig.projbuild
Normal file
84
esp-idf-mirf-master/mqtt/main/Kconfig.projbuild
Normal file
@ -0,0 +1,84 @@
|
||||
menu "Application Configuration"
|
||||
|
||||
menu "WiFi Setting"
|
||||
|
||||
config ESP_WIFI_SSID
|
||||
string "WiFi SSID"
|
||||
default "myssid"
|
||||
help
|
||||
SSID (network name) to connect to.
|
||||
|
||||
config ESP_WIFI_PASSWORD
|
||||
string "WiFi Password"
|
||||
default "mypassword"
|
||||
help
|
||||
WiFi password (WPA or WPA2) to connect to.
|
||||
|
||||
config ESP_MAXIMUM_RETRY
|
||||
int "Maximum retry"
|
||||
default 5
|
||||
help
|
||||
Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Radio Setting"
|
||||
|
||||
choice DIRECTION
|
||||
prompt "Communication polarity"
|
||||
default SENDER
|
||||
help
|
||||
Select Communication polarity.
|
||||
config SENDER
|
||||
bool "MQTT to Radio"
|
||||
help
|
||||
MQTT to Radio.
|
||||
config RECEIVER
|
||||
bool "Radio to MQTT"
|
||||
help
|
||||
Radio to MQTT.
|
||||
endchoice
|
||||
|
||||
config MQTT_BROKER
|
||||
string "MQTT Broker"
|
||||
default "broker.emqx.io"
|
||||
help
|
||||
Host name or IP address of the broker to connect to
|
||||
|
||||
config BROKER_AUTHENTICATION
|
||||
bool "Server requests for password when connecting"
|
||||
default false
|
||||
help
|
||||
Server requests for password when connecting.
|
||||
|
||||
config AUTHENTICATION_USERNAME
|
||||
depends on BROKER_AUTHENTICATION
|
||||
string "Username used for connecting to the broker"
|
||||
default "user"
|
||||
help
|
||||
Username used for connecting to the broker.
|
||||
|
||||
config AUTHENTICATION_PASSWORD
|
||||
depends on BROKER_AUTHENTICATION
|
||||
string "Password used for connecting to the broker"
|
||||
default "password"
|
||||
help
|
||||
Username used for connecting to the broker.
|
||||
|
||||
config MQTT_PUB_TOPIC
|
||||
depends on RECEIVER
|
||||
string "Publish Topic"
|
||||
default "/topic/mirf/test"
|
||||
help
|
||||
Topic of publish
|
||||
|
||||
config MQTT_SUB_TOPIC
|
||||
depends on SENDER
|
||||
string "Subscribe Topic"
|
||||
default "/topic/mirf/test"
|
||||
help
|
||||
Topic of subscribe
|
||||
|
||||
endmenu
|
||||
|
||||
endmenu
|
5
esp-idf-mirf-master/mqtt/main/component.mk
Normal file
5
esp-idf-mirf-master/mqtt/main/component.mk
Normal file
@ -0,0 +1,5 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
|
6
esp-idf-mirf-master/mqtt/main/idf_component.yml
Normal file
6
esp-idf-mirf-master/mqtt/main/idf_component.yml
Normal file
@ -0,0 +1,6 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/mdns:
|
||||
version: "^1.0.3"
|
||||
rules:
|
||||
- if: "idf_version >=5.0"
|
346
esp-idf-mirf-master/mqtt/main/main.c
Normal file
346
esp-idf-mirf-master/mqtt/main/main.c
Normal file
@ -0,0 +1,346 @@
|
||||
/* Mirf Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "freertos/message_buffer.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "mdns.h"
|
||||
|
||||
#include "mirf.h"
|
||||
#include "mqtt.h"
|
||||
|
||||
/* FreeRTOS event group to signal when we are connected*/
|
||||
static EventGroupHandle_t s_wifi_event_group;
|
||||
|
||||
/* The event group allows multiple bits for each event, but we only care about two events:
|
||||
* - we are connected to the AP with an IP
|
||||
* - we failed to connect after the maximum amount of retries */
|
||||
#define WIFI_CONNECTED_BIT BIT0
|
||||
#define WIFI_FAIL_BIT BIT1
|
||||
|
||||
static const char *TAG = "MAIN";
|
||||
|
||||
static int s_retry_num = 0;
|
||||
|
||||
MessageBufferHandle_t xMessageBufferTrans;
|
||||
MessageBufferHandle_t xMessageBufferRecv;
|
||||
|
||||
// The total number of bytes (not single messages) the message buffer will be able to hold at any one time.
|
||||
size_t xBufferSizeBytes = 1024;
|
||||
// The size, in bytes, required to hold each item in the message,
|
||||
size_t xItemSize = 32;
|
||||
|
||||
static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
|
||||
{
|
||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
|
||||
esp_wifi_connect();
|
||||
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||
if (s_retry_num < CONFIG_ESP_MAXIMUM_RETRY) {
|
||||
esp_wifi_connect();
|
||||
s_retry_num++;
|
||||
ESP_LOGI(TAG, "retry to connect to the AP");
|
||||
} else {
|
||||
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
|
||||
}
|
||||
ESP_LOGI(TAG,"connect to the AP fail");
|
||||
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
||||
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
|
||||
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
|
||||
s_retry_num = 0;
|
||||
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool wifi_init_sta(void)
|
||||
{
|
||||
bool ret = false;
|
||||
s_wifi_event_group = xEventGroupCreate();
|
||||
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
esp_netif_create_default_wifi_sta();
|
||||
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||
|
||||
esp_event_handler_instance_t instance_any_id;
|
||||
esp_event_handler_instance_t instance_got_ip;
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
||||
ESP_EVENT_ANY_ID,
|
||||
&event_handler,
|
||||
NULL,
|
||||
&instance_any_id));
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
|
||||
IP_EVENT_STA_GOT_IP,
|
||||
&event_handler,
|
||||
NULL,
|
||||
&instance_got_ip));
|
||||
|
||||
wifi_config_t wifi_config = {
|
||||
.sta = {
|
||||
.ssid = CONFIG_ESP_WIFI_SSID,
|
||||
.password = CONFIG_ESP_WIFI_PASSWORD,
|
||||
/* Setting a password implies station will connect to all security modes including WEP/WPA.
|
||||
* However these modes are deprecated and not advisable to be used. Incase your Access point
|
||||
* doesn't support WPA2, these mode can be enabled by commenting below line */
|
||||
.threshold.authmode = WIFI_AUTH_WPA2_PSK,
|
||||
|
||||
.pmf_cfg = {
|
||||
.capable = true,
|
||||
.required = false
|
||||
},
|
||||
},
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
|
||||
ESP_ERROR_CHECK(esp_wifi_start() );
|
||||
|
||||
ESP_LOGI(TAG, "wifi_init_sta finished.");
|
||||
|
||||
/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
|
||||
* number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
|
||||
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
|
||||
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
|
||||
pdFALSE,
|
||||
pdFALSE,
|
||||
portMAX_DELAY);
|
||||
|
||||
/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
|
||||
* happened. */
|
||||
if (bits & WIFI_CONNECTED_BIT) {
|
||||
ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", CONFIG_ESP_WIFI_SSID, CONFIG_ESP_WIFI_PASSWORD);
|
||||
ret = true;
|
||||
} else if (bits & WIFI_FAIL_BIT) {
|
||||
ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", CONFIG_ESP_WIFI_SSID, CONFIG_ESP_WIFI_PASSWORD);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "UNEXPECTED EVENT");
|
||||
}
|
||||
|
||||
/* The event will not be processed after unregister */
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip));
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id));
|
||||
vEventGroupDelete(s_wifi_event_group);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t query_mdns_host(const char * host_name, char *ip)
|
||||
{
|
||||
ESP_LOGD(__FUNCTION__, "Query A: %s", host_name);
|
||||
|
||||
struct esp_ip4_addr addr;
|
||||
addr.addr = 0;
|
||||
|
||||
esp_err_t err = mdns_query_a(host_name, 10000, &addr);
|
||||
if(err){
|
||||
if(err == ESP_ERR_NOT_FOUND){
|
||||
ESP_LOGW(__FUNCTION__, "%s: Host was not found!", esp_err_to_name(err));
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_LOGE(__FUNCTION__, "Query Failed: %s", esp_err_to_name(err));
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_LOGD(__FUNCTION__, "Query A: %s.local resolved to: " IPSTR, host_name, IP2STR(&addr));
|
||||
sprintf(ip, IPSTR, IP2STR(&addr));
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void convert_mdns_host(char * from, char * to)
|
||||
{
|
||||
ESP_LOGI(__FUNCTION__, "from=[%s]",from);
|
||||
strcpy(to, from);
|
||||
char *sp;
|
||||
sp = strstr(from, ".local");
|
||||
if (sp == NULL) return;
|
||||
|
||||
int _len = sp - from;
|
||||
ESP_LOGD(__FUNCTION__, "_len=%d", _len);
|
||||
char _from[128];
|
||||
strcpy(_from, from);
|
||||
_from[_len] = 0;
|
||||
ESP_LOGI(__FUNCTION__, "_from=[%s]", _from);
|
||||
|
||||
char _ip[128];
|
||||
esp_err_t ret = query_mdns_host(_from, _ip);
|
||||
ESP_LOGI(__FUNCTION__, "query_mdns_host=%d _ip=[%s]", ret, _ip);
|
||||
if (ret != ESP_OK) return;
|
||||
|
||||
strcpy(to, _ip);
|
||||
ESP_LOGI(__FUNCTION__, "to=[%s]", to);
|
||||
}
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
void AdvancedSettings(NRF24_t * dev)
|
||||
{
|
||||
#if CONFIG_RF_RATIO_2M
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 2MBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 1);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
#if CONFIG_RF_RATIO_1M
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 1MBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 0);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
#if CONFIG_RF_RATIO_250K
|
||||
ESP_LOGW(pcTaskGetName(0), "Set RF Data Ratio to 250KBps");
|
||||
Nrf24_SetSpeedDataRates(dev, 2);
|
||||
#endif // CONFIG_RF_RATIO_2M
|
||||
|
||||
ESP_LOGW(pcTaskGetName(0), "CONFIG_RETRANSMIT_DELAY=%d", CONFIG_RETRANSMIT_DELAY);
|
||||
Nrf24_setRetransmitDelay(dev, CONFIG_RETRANSMIT_DELAY);
|
||||
}
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
#if CONFIG_RECEIVER
|
||||
void receiver(void *pvParameters)
|
||||
{
|
||||
ESP_LOGI(pcTaskGetName(0), "Start");
|
||||
NRF24_t dev;
|
||||
Nrf24_init(&dev);
|
||||
uint8_t payload = 32;
|
||||
uint8_t channel = CONFIG_RADIO_CHANNEL;
|
||||
Nrf24_config(&dev, channel, payload);
|
||||
|
||||
// Set my own address using 5 characters
|
||||
esp_err_t ret = Nrf24_setRADDR(&dev, (uint8_t *)"FGHIJ");
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(pcTaskGetName(0), "nrf24l01 not installed");
|
||||
while(1) { vTaskDelay(1); }
|
||||
}
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
AdvancedSettings(&dev);
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
// Print settings
|
||||
Nrf24_printDetails(&dev);
|
||||
|
||||
uint8_t buf[xItemSize];
|
||||
|
||||
// Clear RX FiFo
|
||||
while(1) {
|
||||
if (Nrf24_dataReady(&dev) == false) break;
|
||||
Nrf24_getData(&dev, buf);
|
||||
}
|
||||
|
||||
while(1) {
|
||||
// Wait for received data
|
||||
if (Nrf24_dataReady(&dev)) {
|
||||
Nrf24_getData(&dev, buf);
|
||||
ESP_LOGI(pcTaskGetName(NULL), "Nrf24_getData buf=[%.*s]",payload, buf);
|
||||
size_t spacesAvailable = xMessageBufferSpacesAvailable( xMessageBufferTrans );
|
||||
ESP_LOGI(pcTaskGetName(NULL), "spacesAvailable=%d", spacesAvailable);
|
||||
if (spacesAvailable < xItemSize*2) {
|
||||
ESP_LOGW(pcTaskGetName(NULL), "xMessageBuffer available less than %d", xItemSize*2);
|
||||
} else {
|
||||
size_t sended = xMessageBufferSend(xMessageBufferTrans, buf, payload, portMAX_DELAY);
|
||||
if (sended != payload) {
|
||||
ESP_LOGE(pcTaskGetName(NULL), "xMessageBufferSend fail");
|
||||
}
|
||||
}
|
||||
}
|
||||
vTaskDelay(1); // Avoid WatchDog alerts
|
||||
} // end while
|
||||
}
|
||||
#endif // CONFIG_RECEIVER
|
||||
|
||||
|
||||
#if CONFIG_SENDER
|
||||
void sender(void *pvParameters)
|
||||
{
|
||||
ESP_LOGI(pcTaskGetName(0), "Start");
|
||||
NRF24_t dev;
|
||||
Nrf24_init(&dev);
|
||||
uint8_t payload = 32;
|
||||
uint8_t channel = CONFIG_RADIO_CHANNEL;
|
||||
Nrf24_config(&dev, channel, payload);
|
||||
|
||||
// Set destination address using 5 characters
|
||||
esp_err_t ret = Nrf24_setTADDR(&dev, (uint8_t *)"FGHIJ");
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(pcTaskGetName(0), "nrf24l01 not installed");
|
||||
while(1) { vTaskDelay(1); }
|
||||
}
|
||||
|
||||
#if CONFIG_ADVANCED
|
||||
AdvancedSettings(&dev);
|
||||
#endif // CONFIG_ADVANCED
|
||||
|
||||
// Print settings
|
||||
Nrf24_printDetails(&dev);
|
||||
|
||||
ESP_LOGI(pcTaskGetName(0), "Wait for mqtt...");
|
||||
uint8_t buf[xItemSize];
|
||||
while(1) {
|
||||
size_t received = xMessageBufferReceive(xMessageBufferRecv, buf, sizeof(buf), portMAX_DELAY);
|
||||
ESP_LOGI(pcTaskGetName(NULL), "xMessageBufferReceive received=%d", received);
|
||||
Nrf24_send(&dev, buf);
|
||||
vTaskDelay(1);
|
||||
ESP_LOGI(pcTaskGetName(0), "Wait for sending.....");
|
||||
if (Nrf24_isSend(&dev, 1000)) {
|
||||
ESP_LOGI(pcTaskGetName(0),"Send success");
|
||||
} else {
|
||||
ESP_LOGW(pcTaskGetName(0),"Send fail");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_SENDER
|
||||
|
||||
void mqtt_pub(void *pvParameters);
|
||||
void mqtt_sub(void *pvParameters);
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Initialize NVS
|
||||
esp_err_t ret = nvs_flash_init();
|
||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ret = nvs_flash_init();
|
||||
}
|
||||
ESP_ERROR_CHECK(ret);
|
||||
|
||||
// Initialize WiFi
|
||||
if (wifi_init_sta() == false) {
|
||||
while(1) vTaskDelay(10);
|
||||
}
|
||||
|
||||
// Create MessageBuffer
|
||||
xMessageBufferTrans = xMessageBufferCreate(xBufferSizeBytes);
|
||||
configASSERT( xMessageBufferTrans );
|
||||
xMessageBufferRecv = xMessageBufferCreate(xBufferSizeBytes);
|
||||
configASSERT( xMessageBufferRecv );
|
||||
|
||||
// Initialize mDNS
|
||||
ESP_ERROR_CHECK( mdns_init() );
|
||||
|
||||
#if CONFIG_SENDER
|
||||
xTaskCreate(&sender, "TX", 1024*3, NULL, 2, NULL);
|
||||
xTaskCreate(&mqtt_sub, "SUB", 1024*4, NULL, 2, NULL);
|
||||
#endif
|
||||
#if CONFIG_RECEIVER
|
||||
xTaskCreate(&receiver, "RX", 1024*3, NULL, 2, NULL);
|
||||
xTaskCreate(&mqtt_pub, "PUB", 1024*4, NULL, 2, NULL);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
9
esp-idf-mirf-master/mqtt/main/mqtt.h
Normal file
9
esp-idf-mirf-master/mqtt/main/mqtt.h
Normal file
@ -0,0 +1,9 @@
|
||||
typedef struct {
|
||||
TaskHandle_t taskHandle;
|
||||
int32_t event_id;
|
||||
int topic_len;
|
||||
char topic[64];
|
||||
int data_len;
|
||||
char data[32];
|
||||
} MQTT_t;
|
||||
|
163
esp-idf-mirf-master/mqtt/main/mqtt_pub.c
Normal file
163
esp-idf-mirf-master/mqtt/main/mqtt_pub.c
Normal file
@ -0,0 +1,163 @@
|
||||
/* MQTT (over TCP) Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "freertos/message_buffer.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_mac.h" // esp_base_mac_addr_get
|
||||
#include "mqtt_client.h"
|
||||
|
||||
#if CONFIG_RECEIVER
|
||||
|
||||
static const char *TAG = "PUB";
|
||||
|
||||
EventGroupHandle_t mqtt_status_event_group;
|
||||
#define MQTT_CONNECTED_BIT BIT2
|
||||
|
||||
extern MessageBufferHandle_t xMessageBufferTrans;
|
||||
extern size_t xItemSize;
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
|
||||
#else
|
||||
static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
|
||||
#endif
|
||||
{
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
esp_mqtt_event_handle_t event = event_data;
|
||||
#endif
|
||||
switch (event->event_id) {
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||
xEventGroupSetBits(mqtt_status_event_group, MQTT_CONNECTED_BIT);
|
||||
break;
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||
xEventGroupClearBits(mqtt_status_event_group, MQTT_CONNECTED_BIT);
|
||||
break;
|
||||
case MQTT_EVENT_SUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_UNSUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_PUBLISHED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_DATA:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
|
||||
break;
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||
break;
|
||||
}
|
||||
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
return ESP_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t query_mdns_host(const char * host_name, char *ip);
|
||||
void convert_mdns_host(char * from, char * to);
|
||||
|
||||
void mqtt_pub(void *pvParameters)
|
||||
{
|
||||
ESP_LOGI(TAG, "Start Publish Broker:%s", CONFIG_MQTT_BROKER);
|
||||
|
||||
// Create Event Group
|
||||
mqtt_status_event_group = xEventGroupCreate();
|
||||
configASSERT( mqtt_status_event_group );
|
||||
xEventGroupClearBits(mqtt_status_event_group, MQTT_CONNECTED_BIT);
|
||||
|
||||
// Set client id from mac
|
||||
uint8_t mac[8];
|
||||
ESP_ERROR_CHECK(esp_base_mac_addr_get(mac));
|
||||
for(int i=0;i<8;i++) {
|
||||
ESP_LOGD(TAG, "mac[%d]=%x", i, mac[i]);
|
||||
}
|
||||
char client_id[64];
|
||||
sprintf(client_id, "pub-%02x%02x%02x%02x%02x%02x", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
|
||||
ESP_LOGI(TAG, "client_id=[%s]", client_id);
|
||||
|
||||
// Resolve mDNS host name
|
||||
char ip[128];
|
||||
ESP_LOGI(TAG, "CONFIG_MQTT_BROKER=[%s]", CONFIG_MQTT_BROKER);
|
||||
convert_mdns_host(CONFIG_MQTT_BROKER, ip);
|
||||
ESP_LOGI(TAG, "ip=[%s]", ip);
|
||||
char uri[138];
|
||||
sprintf(uri, "mqtt://%s", ip);
|
||||
ESP_LOGI(TAG, "uri=[%s]", uri);
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = uri,
|
||||
.broker.address.port = 1883,
|
||||
#if CONFIG_BROKER_AUTHENTICATION
|
||||
.credentials.username = CONFIG_AUTHENTICATION_USERNAME,
|
||||
.credentials.authentication.password = CONFIG_AUTHENTICATION_PASSWORD,
|
||||
#endif
|
||||
.credentials.client_id = client_id
|
||||
};
|
||||
#else
|
||||
esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.uri = uri,
|
||||
.port = 1883,
|
||||
.event_handle = mqtt_event_handler,
|
||||
#if CONFIG_BROKER_AUTHENTICATION
|
||||
.username = CONFIG_AUTHENTICATION_USERNAME,
|
||||
.password = CONFIG_AUTHENTICATION_PASSWORD,
|
||||
#endif
|
||||
.client_id = client_id
|
||||
};
|
||||
#endif
|
||||
|
||||
esp_mqtt_client_handle_t mqtt_client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
esp_mqtt_client_register_event(mqtt_client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
|
||||
#endif
|
||||
|
||||
esp_mqtt_client_start(mqtt_client);
|
||||
xEventGroupWaitBits(mqtt_status_event_group, MQTT_CONNECTED_BIT, false, true, portMAX_DELAY);
|
||||
ESP_LOGI(TAG, "Connected to MQTT Broker");
|
||||
|
||||
char buffer[xItemSize];
|
||||
while (1) {
|
||||
size_t received = xMessageBufferReceive(xMessageBufferTrans, buffer, sizeof(buffer), portMAX_DELAY);
|
||||
ESP_LOGI(TAG, "xMessageBufferReceive received=%d", received);
|
||||
if (received > 0) {
|
||||
ESP_LOGI(TAG, "xMessageBufferReceive buffer=[%.*s]",received, buffer);
|
||||
EventBits_t EventBits = xEventGroupGetBits(mqtt_status_event_group);
|
||||
ESP_LOGI(TAG, "EventBits=0x%"PRIx32, EventBits);
|
||||
if (EventBits & MQTT_CONNECTED_BIT) {
|
||||
int msg_id = esp_mqtt_client_publish(mqtt_client, CONFIG_MQTT_PUB_TOPIC, buffer, received, 1, 0);
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Disconnect to MQTT Broker. Skip to send");
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "xMessageBufferReceive fail");
|
||||
break;
|
||||
}
|
||||
} // end while
|
||||
|
||||
// Stop connection
|
||||
ESP_LOGI(TAG, "Task Delete");
|
||||
esp_mqtt_client_stop(mqtt_client);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
#endif
|
188
esp-idf-mirf-master/mqtt/main/mqtt_sub.c
Normal file
188
esp-idf-mirf-master/mqtt/main/mqtt_sub.c
Normal file
@ -0,0 +1,188 @@
|
||||
/* MQTT (over TCP) Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "freertos/message_buffer.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_event.h"
|
||||
#include "lwip/dns.h"
|
||||
#include "esp_mac.h"
|
||||
#include "mqtt_client.h"
|
||||
|
||||
#include "mqtt.h"
|
||||
|
||||
#if CONFIG_SENDER
|
||||
|
||||
static const char *TAG = "SUB";
|
||||
|
||||
extern MessageBufferHandle_t xMessageBufferRecv;
|
||||
extern size_t xItemSize;
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
|
||||
#else
|
||||
static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
|
||||
#endif
|
||||
{
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
esp_mqtt_event_handle_t event = event_data;
|
||||
MQTT_t *mqttBuf = handler_args;
|
||||
#else
|
||||
MQTT_t *mqttBuf = event->user_context;
|
||||
#endif
|
||||
ESP_LOGI(TAG, "taskHandle=0x%x", (unsigned int)mqttBuf->taskHandle);
|
||||
mqttBuf->event_id = event->event_id;
|
||||
switch (event->event_id) {
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||
xTaskNotifyGive( mqttBuf->taskHandle );
|
||||
break;
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||
xTaskNotifyGive( mqttBuf->taskHandle );
|
||||
break;
|
||||
case MQTT_EVENT_SUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_UNSUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_PUBLISHED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_DATA:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
|
||||
ESP_LOGI(TAG, "TOPIC=[%.*s] DATA=[%.*s]", event->topic_len, event->topic, event->data_len, event->data);
|
||||
|
||||
mqttBuf->topic_len = event->topic_len;
|
||||
if (mqttBuf->topic_len > sizeof(mqttBuf->topic)) {
|
||||
ESP_LOGW(TAG, "topic length too big");
|
||||
mqttBuf->topic_len = sizeof(mqttBuf->topic);
|
||||
}
|
||||
for(int i=0;i<mqttBuf->topic_len;i++) {
|
||||
mqttBuf->topic[i] = event->topic[i];
|
||||
}
|
||||
mqttBuf->data_len = event->data_len;
|
||||
if (mqttBuf->data_len > sizeof(mqttBuf->data)) {
|
||||
ESP_LOGW(TAG, "payload length too big");
|
||||
mqttBuf->data_len = sizeof(mqttBuf->data);
|
||||
}
|
||||
for(int i=0;i<mqttBuf->data_len;i++) {
|
||||
mqttBuf->data[i] = event->data[i];
|
||||
}
|
||||
xTaskNotifyGive( mqttBuf->taskHandle );
|
||||
break;
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
|
||||
xTaskNotifyGive( mqttBuf->taskHandle );
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||
break;
|
||||
}
|
||||
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
return ESP_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t query_mdns_host(const char * host_name, char *ip);
|
||||
void convert_mdns_host(char * from, char * to);
|
||||
|
||||
void mqtt_sub(void *pvParameters)
|
||||
{
|
||||
ESP_LOGI(TAG, "Start");
|
||||
ESP_LOGI(TAG, "CONFIG_MQTT_BROKER=[%s]", CONFIG_MQTT_BROKER);
|
||||
|
||||
// Set client id from mac
|
||||
uint8_t mac[8];
|
||||
ESP_ERROR_CHECK(esp_base_mac_addr_get(mac));
|
||||
for(int i=0;i<8;i++) {
|
||||
ESP_LOGD(TAG, "mac[%d]=%x", i, mac[i]);
|
||||
}
|
||||
char client_id[64];
|
||||
sprintf(client_id, "esp32-%02x%02x%02x%02x%02x%02x", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
|
||||
ESP_LOGI(TAG, "client_id=[%s]", client_id);
|
||||
|
||||
// Resolve mDNS host name
|
||||
char ip[128];
|
||||
ESP_LOGI(TAG, "CONFIG_MQTT_BROKER=[%s]", CONFIG_MQTT_BROKER);
|
||||
convert_mdns_host(CONFIG_MQTT_BROKER, ip);
|
||||
ESP_LOGI(TAG, "ip=[%s]", ip);
|
||||
char uri[138];
|
||||
sprintf(uri, "mqtt://%s", ip);
|
||||
ESP_LOGI(TAG, "uri=[%s]", uri);
|
||||
|
||||
// Initialize user context
|
||||
MQTT_t mqttBuf;
|
||||
mqttBuf.taskHandle = xTaskGetCurrentTaskHandle();
|
||||
ESP_LOGI(TAG, "taskHandle=0x%x", (unsigned int)mqttBuf.taskHandle);
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = uri,
|
||||
.broker.address.port = 1883,
|
||||
#if CONFIG_BROKER_AUTHENTICATION
|
||||
.credentials.username = CONFIG_AUTHENTICATION_USERNAME,
|
||||
.credentials.authentication.password = CONFIG_AUTHENTICATION_PASSWORD,
|
||||
#endif
|
||||
.credentials.client_id = client_id
|
||||
};
|
||||
#else
|
||||
esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.user_context = &mqttBuf,
|
||||
.uri = uri,
|
||||
.port = 1883,
|
||||
.event_handle = mqtt_event_handler,
|
||||
#if CONFIG_BROKER_AUTHENTICATION
|
||||
.username = CONFIG_AUTHENTICATION_USERNAME,
|
||||
.password = CONFIG_AUTHENTICATION_PASSWORD,
|
||||
#endif
|
||||
.client_id = client_id
|
||||
};
|
||||
#endif
|
||||
|
||||
esp_mqtt_client_handle_t mqtt_client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
esp_mqtt_client_register_event(mqtt_client, ESP_EVENT_ANY_ID, mqtt_event_handler, &mqttBuf);
|
||||
#endif
|
||||
|
||||
esp_mqtt_client_start(mqtt_client);
|
||||
|
||||
while (1) {
|
||||
ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
|
||||
ESP_LOGI(TAG, "ulTaskNotifyTake");
|
||||
ESP_LOGI(TAG, "event_id=%"PRIi32, mqttBuf.event_id);
|
||||
|
||||
if (mqttBuf.event_id == MQTT_EVENT_CONNECTED) {
|
||||
esp_mqtt_client_subscribe(mqtt_client, CONFIG_MQTT_SUB_TOPIC, 0);
|
||||
ESP_LOGI(TAG, "Subscribe to MQTT Server");
|
||||
} else if (mqttBuf.event_id == MQTT_EVENT_DISCONNECTED) {
|
||||
break;
|
||||
} else if (mqttBuf.event_id == MQTT_EVENT_DATA) {
|
||||
ESP_LOGI(TAG, "TOPIC=[%.*s] DATA=[%.*s]", mqttBuf.topic_len, mqttBuf.topic, mqttBuf.data_len, mqttBuf.data);
|
||||
size_t sended = xMessageBufferSend(xMessageBufferRecv, mqttBuf.data, mqttBuf.data_len, portMAX_DELAY);
|
||||
if (sended != mqttBuf.data_len) {
|
||||
ESP_LOGE(TAG, "xMessageBufferSend fail");
|
||||
}
|
||||
} else if (mqttBuf.event_id == MQTT_EVENT_ERROR) {
|
||||
break;
|
||||
}
|
||||
} // end while
|
||||
|
||||
ESP_LOGI(TAG, "Task Delete");
|
||||
esp_mqtt_client_stop(mqtt_client);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
#endif
|
13
esp-idf-mirf-master/mqtt/mqtt_pub.sh
Normal file
13
esp-idf-mirf-master/mqtt/mqtt_pub.sh
Normal file
@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
#set -x
|
||||
count=1
|
||||
while :
|
||||
do
|
||||
payload=`date "+%Y/%m/%d %H:%M:%S"`
|
||||
#payload="count=${count}"
|
||||
echo ${payload}
|
||||
mosquitto_pub -h broker.emqx.io -p 1883 -t "/topic/mirf/test" -m "$payload"
|
||||
count=$((++count))
|
||||
sleep 1
|
||||
done
|
||||
|
2
esp-idf-mirf-master/mqtt/mqtt_sub.sh
Normal file
2
esp-idf-mirf-master/mqtt/mqtt_sub.sh
Normal file
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
mosquitto_sub -d -h broker.emqx.io -t "/topic/mirf/test"
|
218
include/zh_rf24.h
Normal file
218
include/zh_rf24.h
Normal file
@ -0,0 +1,218 @@
|
||||
/**
|
||||
* @file
|
||||
* Header file for the zh_rf24 component.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "string.h"
|
||||
#include "esp_err.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
/**
|
||||
* @brief Unique identifier of RF24 interface events base. Used when registering the event handler.
|
||||
*
|
||||
*/
|
||||
#define ESP_EVENT_BASE ZH_RF24
|
||||
|
||||
/**
|
||||
* @brief Default values for zh_rf24_init_config_t structure for initial initialization of RF24 interface.
|
||||
*
|
||||
*/
|
||||
#define ZH_RF24_INIT_CONFIG_DEFAULT() \
|
||||
{ \
|
||||
.ce_pin = 1, \
|
||||
.csn_pin = 2, \
|
||||
.sck_pin = 3, \
|
||||
.mosi_pin = 4, \
|
||||
.miso_pin = 5, \
|
||||
.irq_pin = 6, \
|
||||
.work_mode = ZH_RF24_RECEIVER, \
|
||||
.channel = 100, \
|
||||
.pa_level = ZH_RF24_PA_MAX, \
|
||||
.data_rate = ZH_RF24_250KBPS, \
|
||||
.network_id = 0xFAFBFCFD, \
|
||||
.task_priority = 4, \
|
||||
.stack_size = 3072, \
|
||||
.queue_size = 32, \
|
||||
.max_waiting_time = 1000, \
|
||||
.id_vector_size = 100, \
|
||||
.route_vector_size = 100, \
|
||||
.wifi_interface = WIFI_IF_STA \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Structure for initial initialization of RF24 interface.
|
||||
*
|
||||
* @note Before initialize cc interface recommend initialize zh_rf24_init_config_t structure with default values.
|
||||
*
|
||||
* @code
|
||||
* zh_rf24_init_config_t config = ZH_RF24_INIT_CONFIG_DEFAULT()
|
||||
* @endcode
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t ce_pin;
|
||||
uint8_t csn_pin;
|
||||
uint8_t sck_pin;
|
||||
uint8_t mosi_pin;
|
||||
uint8_t miso_pin;
|
||||
uint8_t irq_pin;
|
||||
zh_rf24_work_mode_t work_mode;
|
||||
uint8_t channel;
|
||||
zh_rf24_pa_level_t pa_level;
|
||||
zh_rf24_data_rate_t data_rate;
|
||||
uint8_t tx_address[5];
|
||||
uint8_t rx_address_preamble[4];
|
||||
uint8_t rx_pipe_1_address;
|
||||
uint8_t rx_pipe_2_address;
|
||||
uint8_t rx_pipe_3_address;
|
||||
uint8_t rx_pipe_4_address;
|
||||
uint8_t rx_pipe_5_address;
|
||||
uint8_t task_priority; ///< Task priority for the ESP-NOW messages processing. @note It is not recommended to set a value less than 4.
|
||||
uint16_t stack_size; ///< Stack size for task for the ESP-NOW messages processing. @note The minimum size is 3072 bytes.
|
||||
uint8_t queue_size; ///< Queue size for task for the ESP-NOW messages processing. @note The size depends on the number of messages to be processed. It is not recommended to set the value less than 32.
|
||||
} __attribute__((packed)) zh_rf24_init_config_t;
|
||||
|
||||
/// \cond
|
||||
ESP_EVENT_DECLARE_BASE(ESP_EVENT_BASE);
|
||||
/// \endcond
|
||||
|
||||
/**
|
||||
* Power Amplifier level.
|
||||
*
|
||||
* For use with setPALevel()
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ZH_RF24_PA_MIN,
|
||||
ZH_RF24_PA_LOW,
|
||||
ZH_RF24_PA_HIGH,
|
||||
ZH_RF24_PA_MAX,
|
||||
} __attribute__((packed)) zh_rf24_pa_level_t;
|
||||
|
||||
/**
|
||||
* Data rate. How fast data moves through the air.
|
||||
*
|
||||
* For use with setDataRate()
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ZH_RF24_1MBPS,
|
||||
ZH_RF24_2MBPS,
|
||||
ZH_RF24_250KBPS
|
||||
} __attribute__((packed)) zh_rf24_data_rate_t;
|
||||
|
||||
/**
|
||||
* CRC Length. How big (if any) of a CRC is included.
|
||||
*
|
||||
* For use with setCRCLength()
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ZH_RF24_TRANSMITTER,
|
||||
ZH_RF24_RECEIVER
|
||||
} __attribute__((packed)) zh_rf24_work_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Enumeration of possible RF24 events.
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ZH_RF24_ON_RECV_EVENT, ///< The event when the RF24 message was received.
|
||||
ZH_RF24_ON_SEND_EVENT ///< The event when the RF24 message was sent.
|
||||
} __attribute__((packed)) zh_rf24_event_type_t;
|
||||
|
||||
/**
|
||||
* @brief Enumeration of possible status of sent ESP-NOW message.
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ZH_RF24_SEND_SUCCESS, ///< If RF24 message was sent success.
|
||||
ZH_RF24_SEND_FAIL ///< If RF24 message was sent fail.
|
||||
} __attribute__((packed)) zh_rf24_on_send_event_type_t;
|
||||
|
||||
/**
|
||||
* @brief Structure for sending data to the event handler when an ESP-NOW message was sent.
|
||||
*
|
||||
* @note Should be used with ZH_NETWORK event base and ZH_NETWORK_ON_SEND_EVENT event.
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pipe; ///< MAC address of the device to which the ESP-NOW message was sent. @note
|
||||
zh_rf24_on_send_event_type_t status; ///< Status of sent ESP-NOW message. @note
|
||||
} __attribute__((packed)) zh_rf24_event_on_send_t;
|
||||
|
||||
/**
|
||||
* @brief Structure for sending data to the event handler when an ESP-NOW message was received.
|
||||
*
|
||||
* @note Should be used with ZH_NETWORK event base and ZH_NETWORK_ON_RECV_EVENT event.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pipe; ///< MAC address of the sender ESP-NOW message. @note
|
||||
uint8_t *data; ///< Pointer to the data of the received ESP-NOW message. @note
|
||||
uint8_t data_len; ///< Size of the received ESP-NOW message. @note
|
||||
} __attribute__((packed)) zh_network_event_on_recv_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize ESP-NOW interface.
|
||||
*
|
||||
* @note Before initialize ESP-NOW interface recommend initialize zh_network_init_config_t structure with default values.
|
||||
*
|
||||
* @code
|
||||
* zh_network_init_config_t config = ZH_NETWORK_INIT_CONFIG_DEFAULT()
|
||||
* @endcode
|
||||
*
|
||||
* @param[in] config Pointer to ESP-NOW initialized configuration structure. Can point to a temporary variable.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if initialization was success
|
||||
* - ESP_ERR_INVALID_ARG if parameter error
|
||||
* - ESP_ERR_WIFI_NOT_INIT if WiFi is not initialized
|
||||
* - ESP_FAIL if any internal error
|
||||
*/
|
||||
esp_err_t zh_network_init(zh_rf24_init_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize ESP-NOW interface.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if deinitialization was success
|
||||
*/
|
||||
esp_err_t zh_network_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Send ESP-NOW data.
|
||||
*
|
||||
* @param[in] target Pointer to a buffer containing an eight-byte target MAC. Can be NULL for broadcast.
|
||||
* @param[in] data Pointer to a buffer containing the data for send.
|
||||
* @param[in] data_len Sending data length.
|
||||
*
|
||||
* @note The function will return an ESP_ERR_INVALID_STATE error if less than 50% of the size set at initialization remains in the message queue.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if sent was success
|
||||
* - ESP_ERR_INVALID_ARG if parameter error
|
||||
* - ESP_ERR_INVALID_STATE if queue for outgoing data is almost full
|
||||
* - ESP_FAIL if ESP-NOW is not initialized
|
||||
*/
|
||||
esp_err_t zh_network_send(const uint8_t *data, const uint8_t data_len, const bool confirm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1 @@
|
||||
1.0.0
|
Loading…
x
Reference in New Issue
Block a user