Arduino(NANO) NRF24L01 应用实例

软件准备:
microBox 库(https://github.com/wastel7/microBox):构建一个微型的命令行系统
Mirf 库(https://github.com/E-elektronic/Mirf):提供RF相关的核心功能
以上库请自行下载

硬件准备:
Arduino NANO板 x 2; NRF24L01 x 2; Other;

开发环境:
VS2017 + Arduino IDE(1.8.4)

硬件连接:

Server、Client 与 NRF24L01模块的连接方式完全相同。接线次序:VCC:3.3V; GND:GND; CSN: 7; CE:8; MOSI:11; SCK:13; IRQ:不接; MISO:12;

Client 代码(client.ino):

#include "microBox.h"#pragma region UserDefined#define DEBUG//#undef DEBUG#ifndef FIRSWOF_ADD#define FIRSWOF_ADD#endif // !FIRSWOF_ADD#ifdef FIRSWOF_ADD/* * Hardware SPI: * MISO -> 12 * MOSI -> 11 * SCK -> 13 * * Configurable: * CE -> 8 * CSN -> 7*/#include <SPI.h>#include "Mirf.h"#include "nRF24L01.h"#include "MirfHardwareSpiDriver.h"//LED#define RED_LED_PIN 2#define GREEN_LED_PIN 3#define BLUE_LED_PIN 4#define LED_TRIGGER HIGH//BEEP#define BEEP_PIN 5#define BEEP_TRIGGER LOWuint8_t code[4] = { 0 };void RedLedLight(){ digitalWrite(RED_LED_PIN, LED_TRIGGER); delay(50); digitalWrite(RED_LED_PIN, !LED_TRIGGER);}void GreenLedLight(){ digitalWrite(GREEN_LED_PIN, LED_TRIGGER); delay(50); digitalWrite(GREEN_LED_PIN, !LED_TRIGGER);}bool RfSend_Internal(uint8_t * data){ unsigned long time = millis(); Serial.print("cmd: "); Serial.print(data[0], HEX); Serial.print(" "); Serial.print(data[1], HEX); Serial.print(" "); Serial.print(data[2], HEX); Serial.print(" "); Serial.println(data[3], HEX); Mirf.setTADDR((byte *)"serv0"); Mirf.send(data); while (Mirf.isSending()) { if ((millis() - time) > 2000) { RedLedLight(); Serial.println("timeout on send cmd!"); return false; } } while (!Mirf.dataReady()) { if ((millis() - time) > 2000) { RedLedLight(); Serial.println("timeout on response from server!"); return false; } } GreenLedLight(); Mirf.getData(data); Serial.print("ack: "); Serial.print(data[0], HEX); Serial.print(" "); Serial.print(data[1], HEX); Serial.print(" "); Serial.print(data[2], HEX); Serial.print(" "); Serial.println(data[3], HEX);}void RfSend(char **param, uint8_t parCnt){ if (parCnt == 1) { unsigned long uli = strtoul(param[0], 0, 16); code[3] = (uint8_t)(uli & 0xff); code[2] = (uint8_t)((uli & 0xff00)>>8); code[1] = (uint8_t)((uli & 0xff0000)>>16); code[0] = (uint8_t)((uli & 0xff000000)>>24); RfSend_Internal(code); } else Serial.println(F("Usage: rf-send hex-code(4 bytes), eg: rf-send AABBCCDD"));}void Test(char **param, uint8_t parCnt){ if (parCnt == 0) { ; } else Serial.println(F("Usage: test"));}void UsrInit(){ pinMode(RED_LED_PIN, OUTPUT); pinMode(GREEN_LED_PIN, OUTPUT); pinMode(BLUE_LED_PIN, OUTPUT); digitalWrite(RED_LED_PIN, !LED_TRIGGER); digitalWrite(GREEN_LED_PIN, !LED_TRIGGER); digitalWrite(BLUE_LED_PIN, !LED_TRIGGER); Mirf.spi = &MirfHardwareSpi; Mirf.init(); Mirf.setRADDR((byte *)"sndr0"); Mirf.payload = sizeof(unsigned long); //size:4 //Mirf.channel = 10; Mirf.config();}#endif // FIRSWOF_ADD#pragma endregion#pragma region InternalFuncchar historyBuf[100];char hostname[] = "tdxk";PARAM_ENTRY Params[] ={ {"hostname", hostname, PARTYPE_STRING | PARTYPE_RW, sizeof(hostname), NULL, NULL, 0}, {NULL, NULL}};void getMillis(char **param, uint8_t parCnt){ Serial.println(millis());}void freeRam(char **param, uint8_t parCnt){ extern int __heap_start, *__brkval; int v; Serial.println((int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval));}void writePin(char **param, uint8_t parCnt){ uint8_t pin, pinval; if (parCnt == 2) { pin = atoi(param[0]); pinval = atoi(param[1]); digitalWrite(pin, pinval); } else Serial.println(F("Usage: writepin pinNum pinvalue"));}void readPin(char **param, uint8_t parCnt){ uint8_t pin; if (parCnt == 1) { pin = atoi(param[0]); Serial.println(digitalRead(pin)); } else Serial.println(F("Usage: readpin pinNum"));}void setPinDirection(char **param, uint8_t parCnt){ uint8_t pin, pindir; if (parCnt == 2) { pin = atoi(param[0]); if (strcmp(param[1], "out") == 0) pindir = OUTPUT; else pindir = INPUT; pinMode(pin, pindir); } else Serial.println(F("Usage: setpindir pinNum in|out"));}void readAnalogPin(char **param, uint8_t parCnt){ uint8_t pin; if (parCnt == 1) { pin = atoi(param[0]); Serial.println(analogRead(pin)); } else Serial.println(F("Usage: readanalog pinNum"));}void writeAnalogPin(char **param, uint8_t parCnt){ uint8_t pin, pinval; if (parCnt == 2) { pin = atoi(param[0]); pinval = atoi(param[1]); analogWrite(pin, pinval); } else Serial.println(F("Usage: writeanalog pinNum pinvalue"));}#pragma endregionvoid setup(){ Serial.begin(115200); microbox.begin(&Params[0], hostname, true, historyBuf, 100); microbox.AddCommand("free", freeRam); microbox.AddCommand("millis", getMillis); microbox.AddCommand("readanalog", readAnalogPin); microbox.AddCommand("readpin", readPin); microbox.AddCommand("setpindir", setPinDirection); microbox.AddCommand("writeanalog", writeAnalogPin); microbox.AddCommand("writepin", writePin);#ifdef FIRSWOF_ADD UsrInit(); microbox.AddCommand("test", Test); microbox.AddCommand("rf-send", RfSend);#endif // FIRSWOF_ADD}void loop(){ microbox.cmdParser();}

Server 代码(Server.ino):

/** * An Mirf example which copies back the data it recives. * * Pins: * Hardware SPI: * MISO -> 12 * MOSI -> 11 * SCK -> 13 * * Configurable: * CE -> 8 * CSN -> 7 * */#include <SPI.h>#include "Mirf.h"#include "nRF24L01.h"#include "MirfHardwareSpiDriver.h"#define DEBUG//#undef DEBUG#define BEEP_PIN 2#define BEEP_TRIGGER LOW#define CHECKSUM data[0]#define DATA_SET_INTERNAL(x,y,m,n) {/*data[0]=(uint8_t)x;*/data[1]=(uint8_t)y;data[2]=(uint8_t)m;data[3]=(uint8_t)n;}#define SEND_DATA(x,y,m,n) {DATA_SET_INTERNAL(x,y,m,n);\Serial.print("ack: ");\Serial.print(data[0], HEX);\Serial.print(" ");\Serial.print(data[1], HEX);\Serial.print(" ");\Serial.print(data[2], HEX);\Serial.print(" ");\Serial.println(data[3], HEX);\Mirf.send(data); }//FLAG#define ACK_OK 0xE0#define ACK_NG 0xE1#define ACK_ERROR 0xE2unsigned long ulCode = 0ul;void beep(){ digitalWrite(BEEP_PIN, BEEP_TRIGGER); delay(10); digitalWrite(BEEP_PIN, !BEEP_TRIGGER);}//CRC-8, Widh:8, Poly:0x07, Init: 0x00//RefIn:False, RefOut:False, XorOut:0x00byte CalcCRC8(byte * pdata, unsigned int len){ byte crc = 0x00; for (int i = 0; i < len; i++) { crc ^= ((*pdata++) & 0xFF); for (byte j = 0; j < 8; j++) { if (crc & 0x80) { crc <<= 1; crc ^= 0x07; } else { crc <<= 1; } } } return crc;}void setup(){ pinMode(BEEP_PIN, OUTPUT); digitalWrite(BEEP_PIN, !BEEP_TRIGGER); Serial.begin(115200); Mirf.spi = &MirfHardwareSpi; Mirf.init(); Mirf.setRADDR((byte *)"serv0"); Mirf.payload = sizeof(unsigned long); Mirf.config(); Serial.println("Listening..."); }void loop(){ byte data[Mirf.payload]; if (!Mirf.isSending() && Mirf.dataReady()) { Mirf.getData(data); Serial.print("cmd: "); Serial.print(data[0], HEX); Serial.print(" "); Serial.print(data[1], HEX); Serial.print(" "); Serial.print(data[2], HEX); Serial.print(" "); Serial.println(data[3], HEX); Mirf.setTADDR((byte *)"sndr0"); beep(); ulCode = (unsigned long)((unsigned long)data[0]<<24|(unsigned long)data[1]<<16|(unsigned long)data[2]<<8|data[3]); CHECKSUM = CalcCRC8(data, Mirf.payload); switch (ulCode) { case 0x000000: SEND_DATA(CHECKSUM, ACK_OK, 0, 0); Serial.println("[case 0x000000]"); break; case 0x00112233: SEND_DATA(CHECKSUM, ACK_OK, 0, 0); Serial.println("[case 0x00112233]"); break; default: SEND_DATA(CHECKSUM, ACK_NG, 0, 0); Serial.println("[case default]"); break; } }}

测试图示: