我正在帮助建造一个原型农业机器。它使用Adafruit无线电模块进行无线电控制:
https://learn.adafruit.com/adafruit-feather-32u4-radio-with-rfm69hcw-module/overview
系统工作正常,但接收器间歇性冻结,需要关闭/打开电源或复位才能恢复活力。由于系统是远程控制的,这是不可接受的,并且鉴于机器的性质,可能会有潜在的危险。
下面是接收器的代码。基本上是一长串"if"语句,带有适当的数字写入命令来关闭/打开各种输出。
我对编写这样的软件相当陌生,所以我相信还有很多可以改进的地方。但是,当务之急是找出模块不时冻结的原因。
任何帮助感激地收到!谢谢。
// INCLUDE PACKAGES
#include <SPI.h>
#include <RH_RF69.h>
// DEFINE RADIO FREQUENCY
#define RF69_FREQ 433.0
// DEFINE OUTPUTS
#define A_UP 13
#define A_DOWN 12
#define B_UP 11
#define B_DOWN 10
#define D_DOWN 18
#define E_UP 9
#define E_DOWN 6
#define F_UP 5
#define F_DOWN 19
#define C_1 20
#define C_2 21
#define C_3 22
// DEFINE RADIO PINS
#define RFM69_CS 8
#define RFM69_INT 7
#define RFM69_RST 4
// LOAD RADIO DRIVER
RH_RF69 rf69(RFM69_CS, RFM69_INT);
// CREATE GLOBAL VARIABLES
int16_t packetnum = 0;
void setup()
{
Serial.begin(9600);
pinMode(RFM69_RST, OUTPUT);
digitalWrite(RFM69_RST, LOW);
Serial.println("Feather RFM69 RX Test!");
Serial.println();
// manual reset
digitalWrite(RFM69_RST, HIGH);
delay(10);
digitalWrite(RFM69_RST, LOW);
delay(10);
if (!rf69.init()) {
Serial.println("RFM69 radio init failed");
while (1);
}
Serial.println("RFM69 radio init OK!");
// Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM (for low power module)
// No encryption
if (!rf69.setFrequency(RF69_FREQ)) {
Serial.println("setFrequency failed");
}
// If you are using a high power RF69 eg RFM69HW, you *must* set a Tx power with the
// ishighpowermodule flag set like this:
rf69.setTxPower(20, true); // range from 14-20 for power, 2nd arg must be true for 69HCW
// The encryption key has to be the same as the one in the server
uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
rf69.setEncryptionKey(key);
pinMode(A_UP, OUTPUT);
pinMode(A_DOWN, OUTPUT);
pinMode(B_UP, OUTPUT);
pinMode(B_DOWN, OUTPUT);
pinMode(D_DOWN, OUTPUT);
pinMode(E_UP, OUTPUT);
pinMode(E_DOWN, OUTPUT);
pinMode(F_UP, OUTPUT);
pinMode(F_DOWN, OUTPUT);
pinMode(C_1, OUTPUT);
pinMode(C_2, OUTPUT);
pinMode(C_3, OUTPUT);
digitalWrite(A_UP,HIGH);
digitalWrite(A_DOWN,HIGH);
digitalWrite(B_UP,HIGH);
digitalWrite(B_DOWN,HIGH);
digitalWrite(D_DOWN,HIGH);
digitalWrite(E_UP,HIGH);
digitalWrite(E_DOWN,HIGH);
digitalWrite(F_UP,HIGH);
digitalWrite(F_DOWN,HIGH);
digitalWrite(C_1,HIGH);
digitalWrite(C_2,HIGH);
digitalWrite(C_3,HIGH);
Serial.print("RFM69 radio @"); Serial.print((int)RF69_FREQ); Serial.println(" MHz");
}
void loop() {
if (rf69.available()) {
// Should be a message for us now
uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
if (rf69.recv(buf, &len)) {
if (!len) return;
buf[len] = 0;
Serial.println((char*)buf);
if (strstr((char *)buf, "A UP ON")) {
digitalWrite(A_UP,LOW);
}else if (strstr((char *)buf, "A UP OFF")) {
digitalWrite(A_UP,HIGH);
}else if (strstr((char *)buf, "A DOWN ON")) {
digitalWrite(A_DOWN,LOW);
}else if (strstr((char *)buf, "A DOWN OFF")) {
digitalWrite(A_DOWN,HIGH);
}else if (strstr((char *)buf, "B UP ON")) {
digitalWrite(B_UP,LOW);
}else if (strstr((char *)buf, "B UP OFF")) {
digitalWrite(B_UP,HIGH);
}else if (strstr((char *)buf, "B DOWN ON")) {
digitalWrite(B_DOWN,LOW);
}else if (strstr((char *)buf, "B DOWN OFF")) {
digitalWrite(B_DOWN,HIGH);
}else if (strstr((char *)buf, "D ON")) {
digitalWrite(D_DOWN,LOW);
}else if (strstr((char *)buf, "D OFF")) {
digitalWrite(D_DOWN,HIGH);
}else if (strstr((char *)buf, "E UP ON")) {
digitalWrite(E_DOWN,HIGH);
digitalWrite(E_UP,LOW);
delay(3000);
digitalWrite(E_UP,HIGH);
}else if (strstr((char *)buf, "E UP OFF")) {
digitalWrite(E_UP,HIGH);
}else if (strstr((char *)buf, "E DOWN ON")) {
digitalWrite(E_UP,HIGH);
digitalWrite(E_DOWN,LOW);
delay(3000);
digitalWrite(E_DOWN,HIGH);
}else if (strstr((char *)buf, "E DOWN OFF")) {
digitalWrite(E_DOWN,HIGH);
}else if (strstr((char *)buf, "F UP ON")) {
digitalWrite(F_UP,LOW);
}else if (strstr((char *)buf, "F UP OFF")) {
digitalWrite(F_UP,HIGH);
}else if (strstr((char *)buf, "F DOWN ON")) {
digitalWrite(F_DOWN,LOW);
}else if (strstr((char *)buf, "F DOWN OFF")) {
digitalWrite(F_DOWN,HIGH);
}else if (strstr((char *)buf, "SPEED 0")) {
digitalWrite(C_1,HIGH);
digitalWrite(C_2,HIGH);
digitalWrite(C_3,HIGH);
}else if (strstr((char *)buf, "SPEED 1")) {
digitalWrite(C_1,LOW);
digitalWrite(C_2,HIGH);
digitalWrite(C_3,HIGH);
}else if (strstr((char *)buf, "SPEED 2")) {
digitalWrite(C_1,LOW);
digitalWrite(C_2,LOW);
digitalWrite(C_3,HIGH);
}else if (strstr((char *)buf, "SPEED 3")) {
digitalWrite(C_1,LOW);
digitalWrite(C_2,HIGH);
digitalWrite(C_3,LOW
);
}else if (strstr((char *)buf, "SPEED 4")) {
digitalWrite(C_1,LOW);
digitalWrite(C_2,LOW);
digitalWrite(C_3,LOW);
}
} else {
Serial.println("Receive failed");
}
}
}
更新:
- 该程序似乎完全在我正在使用的 Adafruit 板的范围内 - Arduino IDE 在我编译程序时报告了这一点:
Sketch使用10612字节(37%(的程序存储空间。最大值为 28672 字节。 全局变量使用 663 字节的动态内存。
- 我已经声明buf是静态的:
静态uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];
- 我已经注释掉了所有 Serial.print(( 行,因为它们不是必需的(无法在设备中监控它们(
- 尝试将所有字符串括在 F(( 宏中,例如 F("blablabla"(。也许您的RAM即将用完,这很常见。
- 检查程序的链接并查找潜在的内存不足:
Sketch使用3776字节(1%(的程序存储空间。最大值为 253952 字节。
全局变量使用 646 字节 (7%( 的动态内存,为局部变量留下 7546 字节。最大值为 8192 字节。
- 您在堆栈中声明了一个缓冲区,我不知道RH_RF69_MAX_MESSAGE_LEN的大小,但这可能是问题的原因之一。Delcare it static uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];