Arduino(NANO) NRF24L01 應用實例git
軟件準備:
microBox 庫(https://github.com/wastel7/microBox):構建一個微型的命令行系統
Mirf 庫(https://github.com/E-elektronic/Mirf):提供RF相關的核心功能
以上庫請自行下載github
硬件準備:
Arduino NANO板 x 2; NRF24L01 x 2; Other;ide
開發環境:
VS2017 + Arduino IDE(1.8.4)oop
硬件鏈接:
Server、Client 與 NRF24L01模塊的鏈接方式徹底相同。接線次序:VCC:3.3V; GND:GND; CSN: 7; CE:8; MOSI:11; SCK:13; IRQ:不接; MISO:12;測試
Client 代碼(client.ino):ui
#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 LOW uint8_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 InternalFunc char 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 endregion void 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 0xE2 unsigned 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:0x00 byte 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; } } }
測試圖示:
code