Estoy intentando implementar comunicaciones LoRa utilizando un módulo SX1276 (DRF1276G) y un ATmega328P en una PCB personalizada. Lo tengo funcionando principalmente, pero tengo un problema extraño con la interrupción del tiempo de espera. Lo he configurado para usar el modo RX-Single, con un tiempo de espera para los 1023 símbolos completos, pero A VECES, el tiempo de espera se agota antes de eso.
EDITAR: tenga en cuenta que para las pruebas que se muestran a continuación, SF = 7 y BW = 125kHz, por lo que el período del símbolo es ~ 1.02ms, por lo que la ventana de tiempo de espera debe ser ~ 1043ms. La ventana de tiempo de espera informada en las capturas de pantalla es solo una aproximación, ya que estoy dividiendo estos valores con números enteros. Aquí no hay puntos flotantes. Pero puede suponer que si es algo así como 643 ms o 27 ms, es un período de tiempo más corto antes de que se active el indicador de tiempo de espera.
Vea la imagen a continuación, donde 1023 símbolos se indican mediante el uso de "~ 1026 ms" para el tiempo de espera. Cualquier cosa mucho menor que esa cantidad de tiempo es un período más corto para que la función de recepción regrese, indicó que el indicador de tiempo de espera de RX se activó antes de la ventana de 1023sym / "~ 1026ms" esperada. [EDITAR: ignore el texto "TX ...", el programa no transmite nada, simplemente olvidé cambiar eso en mi impresión]
Laconfiguracióndemipruebaessimplementeescucharlospaquetesentrantes.Noseestántransmitiendopaquetes.
SOLOUNAVEZ,enlas(estoyestimando)4horasdetiempodeejecucióntotaldeestasplacas,estosucedió...
Aquíhayunresumendemispruebas:
- Ocurreentodosmisdispositivos,porloquenoesunhardwaredefectuoso
- ProbandotablasDraginoenelmismoentorno,losDraginosfuncionanperfectamente.Indicaquenoesruido/transmisionesdelentorno(aunquelosDraginosutilizanelmodocontinuodeRXnoelúnicodeRX).
- UnprogramaparagenerarlecturasdeRSSImuestraunasalidaconstantede~-100dBm.Noparecequeseaelruidodelentorno.
- Agregardemorasde5segundosentrelasllamadasdelafunciónderecepciónnoayuda.
- Loscambiosenlaconfiguración,comolavelocidaddedatos,lafrecuencia,lavelocidaddecodificación,lapalabradesincronización,lalongituddelpreámbulo,etc.noafectansucomportamiento.
- LapruebademúltiplesconfiguracionesdeenergíaylaspruebasdeCROdemuestranquenoesunproblemadeenergía.
- LaspruebasdemostraronquenoesruidoenelbusSPIquecausalecturasincorrectasdelregistrodeindicadordeinterrupción.
Googlenohadadoningunarespuesta,yloúnicoquedeboeliminardelahojadedatoseselsiguientefragmento...
Loquepasaesquenoestoytransmitiendonadaparaqueretire.
Aquíestáelcódigorelevante.
Bucleprincipal
//mainloopwhile(1){USARTSendString("RX...\n");
rxPktNo = sx127X_RxPacket((uint8_t *)localDataBuffer);
USARTSendString("timeout: ~");
USARTSendString(itoa(sx127X_lastPacketDurationMilli(),string,10));
USARTSendString("ms\n");
// if data was received, print stuff
if (rxPktNo) {
printMessageContentsAndStats(rxPktNo);
resetContentsOfDataBuffer();
}
}
Rutina de recepción
/* ------------------------------------------/
Set to single receive mode and poll for
the reception of a single packet of data.
Upon reception write data from FIFO
buffer to the given array.
------------------------------------------*/
uint8_t sx127X_RxPacket(uint8_t* dataPtr) {
uint8_t var = 0; // dual-purpose variable
uint8_t returnValue = 0;
// Enter standby mode
setMode(MODE_STDBY);
// Configure for RX if not done already
if (rxtxConfig != CONFIGGED_FOR_RX) {
sx127X_ConfigRX();
}
// Poll for RX-ongoing status, wait till stopped
//while (sx127X_SPIReadReg(LR_RegModemStat) & 0x04);
// Clear interrupts
sx127X_ClearIrq();
// Set to receive mode
setMode(MODE_RXSINGLE);
// Start timer
TCNT1 = 0;
// Poll for timeout, sx127x will go to MODE_STDBY upon timeout
while (!(sx127X_SPIReadReg(LR_RegIrqFlags) & 0x80)) {
// Poll for the RX-done flag
if (sx127X_SPIReadReg(LR_RegIrqFlags) & 0x40) {
// Read starting address of the last received packet...
var = sx127X_SPIReadReg(LR_RegFifoRxCurrentaddr);
// ... Write it to the address pointer for the FIFO buffer
sx127X_SPIWriteReg(LR_RegFifoAddrPtr, var);
// Retrieve packet size of last received packet
var = sx127X_SPIReadReg(LR_RegRxNbBytes);
// Use packet size and FIFO to read RX packet
sx127X_SPIBurstRead(LR_RegFifo, dataPtr, var);
// If successfully retrieved a packet, return true with number of bytes
returnValue = var;
break;
}
}
// give timer value to global variable
lastTimeoutDuration = TCNT1;
// If no packet has been retrieved this call return false
return returnValue;
}
Configuraciones
/* -------------------------------------------------------- /
Configuration settings common to both the receiver and
transmitter modes of operation.
------------------------------------------------------- */
void sx127X_ConfigCommon(void) {
/*------------ Hardware Settings ------------*/
// Set the access-shared-registers mode
sx127X_setASRMode(ASR_LORA);
// Set low or high frequency mode
sx127X_setFrequencyMode(LFM_HF);
// Set either PA_RFO (+14dB) or PA_BOOST (+20dB)
sx127X_setPaSelect(PA_BOOST);
// Set the output power in dBm (PA_BOOST 2 to 17)
sx127x_SetPowerDBm(14);
// Set the PA ramp-up time
sx127X_setPARampTime(RAMP_40US);
// Set overload current protection
sx127X_setOCP(OCP_ON);
// Set overload current protection limit
sx127X_setOCPLimit(OCP_100MA);
// Set the low noise amp gain
sx127X_setLNAGain(LNA_GAIN_G1);
// set LNA boost for low frequency
sx127X_setLNABoostLF(LNA_BOOST_LF_DEFAULT);
// set LNA boost for high frequency
sx127X_setLNABoostHF(LNA_BOOST_HF_DEFAULT);
// Set LNA gain manual or auto
sx127X_setLNAGainAuto(LNA_GAIN_AUTO_ON);
/*----------- Communication Settings -----------*/
// Set base frequency (channel) of the LoRa module
sx127X_setChannel(channel);
// Set the data rate (bandwidth and spreading factor) of the LoRa module
sx127X_setDataRate(dataRate);
// Set the coding rate of the LoRa module
sx127X_setCodeRate(CR_4OF8);
// Set the toggle for implicit header
sx127X_setImplHeaderMode(IHM_OFF); // Explicit
// Set TX continuous mode on or off(normal/packet mode)
sx127X_setTXContMode(TXCM_NORM);
// Set RX payload CRC mode on or off
sx127X_setRXPayloadCRC(RXPL_CRC_ON);
// Set the RX symbol timeout in symbols
sx127X_setRXSymbolTimeout(SYMB_TIMEOUT_1023SYM);
// Set preamble length in symbols
sx127X_setPreambleLength(8);
// Set the payload length in bytes
sx127X_setPayloadLength(0x01); // default
// Set payload maximum length in bytes
sx127X_setPayloadMaxLength(0x80);
// Set the frequency hopping period (0=disable)
sx127X_setFreqHopPeriod(0);
// Set Sync Word
sx127X_setSyncWord(0xF3);
// Select inversion of I and Q signals
sx127X_invertIQ(INVERT_IQ_OFF);
}
/* -------------------------------------------------------- /
Configure the sx127x module for receiver operation.
Use entire FIFO.
------------------------------------------------------- */
void sx127X_ConfigRX(void) {
uint8_t addr;
// Set DIO0 for the RX done flag
sx127X_SPIWriteReg(REG_LR_DIOMAPPING1, 0x00);
// Set interrupt mask for RX timeout and RX done
sx127X_SPIWriteReg(LR_RegIrqFlagsMask, 0x3F);
// Set the RX base address to bottom of FIFO
sx127X_SPIWriteReg(LR_RegFifoRxBaseAddr, 0x00);
// Set address pointer to bottom of FIFO as well
sx127X_SPIWriteReg(LR_RegFifoAddrPtr, 0x00);
// locally store RX mode config flag
rxtxConfig = CONFIGGED_FOR_RX;
}
Si alguien sabe cuál podría ser el problema, o me puede dar más ideas para probar, sería muy apreciado.