Since the RF_RH24 library use the interrupt, when I decode the PPM by interrupt, there will be a disturb. So I want to alter RF_RH24 library to not use the interrupt. I found the corresponding code in RF_RH24 as picture below. In fact, I want to do it in main(). For example, I will check the electrical level of D2 (the interrupt pin of interrupt 0) of Arduino pro mini, if it is low, I will do the program in handleInterrupt(). But when I write it in main function. There are many errors. How should I do it ?
void RH_RF24::handleInterrupt()
{
uint8_t status[8];
command(RH_RF24_CMD_GET_INT_STATUS, NULL, 0, status, sizeof(status));
// Decode and handle the interrupt bits we are interested in
// if (status[0] & RH_RF24_INT_STATUS_CHIP_INT_STATUS)
if (status[0] & RH_RF24_INT_STATUS_MODEM_INT_STATUS)
{
// if (status[4] & RH_RF24_INT_STATUS_INVALID_PREAMBLE)
if (status[4] & RH_RF24_INT_STATUS_INVALID_SYNC)
{
// After INVALID_SYNC, sometimes the radio gets into a silly state and subsequently reports it for every packet
// Need to reset the radio and clear the RX FIFO, cause sometimes theres junk there too
_mode = RHModeIdle;
clearRxFifo();
clearBuffer();
}
}
if (status[0] & RH_RF24_INT_STATUS_PH_INT_STATUS)
{
if (status[2] & RH_RF24_INT_STATUS_CRC_ERROR)
{
// CRC Error
// Radio automatically went to _idleMode
_mode = RHModeIdle;
_rxBad++;
clearRxFifo();
clearBuffer();
}
if (status[2] & RH_RF24_INT_STATUS_PACKET_SENT)
{
_txGood++;
// Transmission does not automatically clear the tx buffer.
// Could retransmit if we wanted
// RH_RF24 configured to transition automatically to Idle after packet sent
_mode = RHModeIdle;
clearBuffer();
}
if (status[2] & RH_RF24_INT_STATUS_PACKET_RX)
{
// A complete message has been received with good CRC
// Get the RSSI, configured to latch at sync detect in radio_config
uint8_t modem_status[6];
command(RH_RF24_CMD_GET_MODEM_STATUS, NULL, 0, modem_status, sizeof(modem_status));
_lastRssi = modem_status[3];
_lastPreambleTime = millis();
// Save it in our buffer
readNextFragment();
// And see if we have a valid message
validateRxBuf();
// Radio will have transitioned automatically to the _idleMode
_mode = RHModeIdle;
}
if (status[2] & RH_RF24_INT_STATUS_TX_FIFO_ALMOST_EMPTY)
{
// TX FIFO almost empty, maybe send another chunk, if there is one
sendNextFragment();
}
if (status[2] & RH_RF24_INT_STATUS_RX_FIFO_ALMOST_FULL)
{
// Some more data to read, get it
readNextFragment();
}
}
}
Below is the errors and my program:
C:\Users\Administrator\Desktop\DianZi\Ricci433\V7\M7\M7.ino: In function 'void RF24_Interrupt()':
M7:74: error: 'command' was not declared in this scope
command(RH_RF24_CMD_GET_INT_STATUS, NULL, 0, status, sizeof(status));
^
M7:85: error: '_mode' was not declared in this scope
_mode = RHModeIdle;
^
M7:85: error: 'RHModeIdle' was not declared in this scope
_mode = RHModeIdle;
^
M7:86: error: 'clearRxFifo' was not declared in this scope
clearRxFifo();
^
M7:87: error: 'clearBuffer' was not declared in this scope
clearBuffer();
^
M7:96: error: '_mode' was not declared in this scope
_mode = RHModeIdle;
^
M7:96: error: 'RHModeIdle' was not declared in this scope
_mode = RHModeIdle;
^
M7:97: error: '_rxBad' was not declared in this scope
_rxBad++;
^
M7:99: error: 'clearRxFifo' was not declared in this scope
clearRxFifo();
^
M7:100: error: 'clearBuffer' was not declared in this scope
clearBuffer();
^
M7:104: error: '_txGood' was not declared in this scope
_txGood++;
^
M7:108: error: '_mode' was not declared in this scope
_mode = RHModeIdle;
^
M7:108: error: 'RHModeIdle' was not declared in this scope
_mode = RHModeIdle;
^
M7:109: error: 'clearBuffer' was not declared in this scope
clearBuffer();
^
M7:117: error: '_lastRssi' was not declared in this scope
_lastRssi = modem_status[3];
^
M7:118: error: '_lastPreambleTime' was not declared in this scope
_lastPreambleTime = millis();
^
M7:121: error: 'readNextFragment' was not declared in this scope
readNextFragment();
^
M7:123: error: 'validateRxBuf' was not declared in this scope
validateRxBuf();
^
M7:125: error: '_mode' was not declared in this scope
_mode = RHModeIdle;
^
M7:125: error: 'RHModeIdle' was not declared in this scope
_mode = RHModeIdle;
^
M7:130: error: 'sendNextFragment' was not declared in this scope
sendNextFragment();
^
M7:135: error: 'readNextFragment' was not declared in this scope
readNextFragment();
^
exit status 1
'command' was not declared in this scope
my program:
#include<SPI.h>
#include<RH_RF24.h>
#include<avr/io.h>
#include<avr/interrupt.h>
#include <RH_RF24.h>
#include "RF24configs/radio_config_Si4464_30_434_2GFSK_5_10.h"
#include <RHGenericSPI.h>
#include <RHSPIDriver.h>
//用于PPM解析的变量
unsigned long PWM[10], SPWM[5][10], SPWM_SUM;
unsigned long T0, T1;
int PWM_i;
int PWM_Last;
//收发的数据
uint8_t S_Data[10];
uint8_t R_Data[10];
RH_RF24 rf24;
void Send();
void Recieve();
void RF24_Interrupt();
void setup()
{
Serial.begin(115200);
if (!rf24.init())
{
Serial.println("initfailed");
}
else
{
Serial.println("initsuccess");
}
//设置定时器,用于提供精确时间。
TCCR1A = 0;
TCCR1B = (1 << CS11); //8分频
TCNT1 = 0; //最大是65535,在8分频下相当于262.14ms,每一下相当于0.5us
// pinMode(3, INPUT); //设置中断引脚为输入模式
attachInterrupt(1, Interrupt_function, FALLING); //开启外部中断1,中断引脚为3,电平下落触发。
detachInterrupt(0);
pinMode(2, INPUT);
}
void loop()
{
//那个干扰确实和发射有关,但是不是来自于电磁波的干扰,应该是发射这个函数占用了定时器或者是外部中断等,具体不清楚,从而导致时间不对。
Send();
delay(100);
if (digitalRead(2) == 0)
{
void RF24_Interrupt();
}
}
void RF24_Interrupt()
{
uint8_t status[8];
command(RH_RF24_CMD_GET_INT_STATUS, NULL, 0, status, sizeof(status));
// Decode and handle the interrupt bits we are interested in
// if (status[0] & RH_RF24_INT_STATUS_CHIP_INT_STATUS)
if (status[0] & RH_RF24_INT_STATUS_MODEM_INT_STATUS)
{
// if (status[4] & RH_RF24_INT_STATUS_INVALID_PREAMBLE)
if (status[4] & RH_RF24_INT_STATUS_INVALID_SYNC)
{
// After INVALID_SYNC, sometimes the radio gets into a silly state and subsequently reports it for every packet
// Need to reset the radio and clear the RX FIFO, cause sometimes theres junk there too
_mode = RHModeIdle;
clearRxFifo();
clearBuffer();
}
}
if (status[0] & RH_RF24_INT_STATUS_PH_INT_STATUS)
{
if (status[2] & RH_RF24_INT_STATUS_CRC_ERROR)
{
// CRC Error
// Radio automatically went to _idleMode
_mode = RHModeIdle;
_rxBad++;
clearRxFifo();
clearBuffer();
}
if (status[2] & RH_RF24_INT_STATUS_PACKET_SENT)
{
_txGood++;
// Transmission does not automatically clear the tx buffer.
// Could retransmit if we wanted
// RH_RF24 configured to transition automatically to Idle after packet sent
_mode = RHModeIdle;
clearBuffer();
}
if (status[2] & RH_RF24_INT_STATUS_PACKET_RX)
{
// A complete message has been received with good CRC
// Get the RSSI, configured to latch at sync detect in radio_config
uint8_t modem_status[6];
command(RH_RF24_CMD_GET_MODEM_STATUS, NULL, 0, modem_status, sizeof(modem_status));
_lastRssi = modem_status[3];
_lastPreambleTime = millis();
// Save it in our buffer
readNextFragment();
// And see if we have a valid message
validateRxBuf();
// Radio will have transitioned automatically to the _idleMode
_mode = RHModeIdle;
}
if (status[2] & RH_RF24_INT_STATUS_TX_FIFO_ALMOST_EMPTY)
{
// TX FIFO almost empty, maybe send another chunk, if there is one
sendNextFragment();
}
if (status[2] & RH_RF24_INT_STATUS_RX_FIFO_ALMOST_FULL)
{
// Some more data to read, get it
readNextFragment();
}
}
}
void Interrupt_function()
{
T1 = TCNT1;
if (T1 > T0)
{
PWM[PWM_i] = T1 - T0;
}
else
{
PWM[PWM_i] = T1 + 65536 - T0;
}
T0 = T1;
//调整PPM_i的值,找到最后一个通道。
if (PWM[PWM_i] > 4200) //某个通道大于2ms,只要大于4000就行了,用保守的数据4200.
{
PWM_Last = PWM_i;
PWM_i = 0;
}
else
{
PWM_i++;
}
//当最后一个通道开始时,由于时间比较多,发射等都在这个里面完成。
//但是不知道为什么,发射不能放在里面,可能发射太慢了,放在中断里面耗费太多的时间了。
if (PWM_i == PWM_Last)
{
//调整范围
for (int i = 0; i < PWM_Last + 1; i++)
{
if (PWM[i] > 4030)
{
PWM[i] = 4030;
}
if (PWM[i] < 1970)
{
PWM[i] = 1970;
}
S_Data[i] = map(PWM[i], 1970, 4030, 0, 255);
}
//移动数据
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 10; j++)
{
SPWM[i][j] = SPWM[i + 1][j];
}
}
for (int i = 0; i < 10; i++)
{
SPWM[4][i] = PWM[i];
}
for (int i = 0; i < 10; i++)
{
}
//这个滤波不好,有延迟,而且不能消除窜动那一下的影响。
// for (int i = 0; i < 10; i++)
// {
// SPWM_SUM = 0;
// for (int j = 0; j < 5; j++)
// {
// SPWM_SUM = SPWM_SUM + SPWM[j][i];
// }
// SPWM_SUM = SPWM_SUM / 5;
// S_Data[i] = map(SPWM_SUM, 1970, 4030, 0, 255);
// }
Serial.println(S_Data[1]);
// 打印相应的通道,用于上位机测试,实际时候不使用。
// for (int i = 0; i < 10; i++)
// {
// Serial.print(PWM[i]);
// Serial.print(" ");
// }
// Serial.println(PWM_Last);
}
}
void Send()
{
rf24.send(S_Data, sizeof(S_Data));
rf24.waitPacketSent();
}
void Recieve()
{
uint8_t buf[RH_RF24_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
if (rf24.waitAvailableTimeout(50))
{
// Should be a reply message for us now
if (rf24.recv(buf, &len))
{
for (int i = 0; i < 10; i++)
{
R_Data[i] = buf[i];
}
//测试接收的数据
// Serial.print("Send: ");
// for (int i = 0; i < 10; i++)
// {
// Serial.print(S_Data[i]);
// Serial.print(" ");
// }
// Serial.println();
//
// Serial.print("Recieve: ");
// for (int i = 0; i < 10; i++)
// {
// Serial.print(R_Data[i]);
// Serial.print(" ");
// }
// Serial.println();
}
}
}