Estoy intentando crear un sensor LoRa muy simple y pequeño basado en un módulo sx1276 y un ATmega328P. Mi ATmega328p se está comunicando felizmente con el módulo sx1276, pero parece que la comunicación real no funciona.
Además, he soldado dos Arduinos con módulos sx1276 como Draginos ejecutando los ejemplos del cliente y el servidor, y se comunican alegremente entre ellos. En realidad, fue muy fácil de configurar. Estoy usando estas tarjetas como ejemplos de trabajo verificados para probar los modos de transmisión y recepción de mi propia tarjeta. Por ahora solo estoy probando el modo de recepción. He configurado mi tablero para que la configuración en el chip sx1276 sea la misma que la de los tableros Dragino, y los verifiqué unos a otros al hacer que cada tablero imprima el contenido completo de sus registros en el momento de la inicialización. Los ajustes que proporciono a continuación son los ajustes del sx1276). Mientras los dos módulos de Dragino se chatean entre sí, tengo mi tarjeta en modo receptor y los escucho como un tercero. No puedo recibir ningún paquete. Mi RX simplemente se agota en cada ciclo.
He escrito mi código en una forma relativamente uniforme y abstracta para aumentar la legibilidad. Esta es mi sección de inicialización del código ...
/*------------ Hardware Settings ------------*/
// Set the sx127X to LoRa mode
sx127X_setLongRangeMode(LRM_LORA);
// 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
sx127X_setOutputPowerDBm(11);
// Set the PA ramp-up time
sx127X_setPARampTime(RAMP_50US); // LoRaWAN recommended
// Set overload current protection
sx127X_setOCP(OCP_ON);
// Set overload current protection limit
sx127X_setOCPLimit(OCP_90MA);
// 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);
// Set PaDAC to 'default' (NOT +20dBm)
sx127X_SPIWriteReg(REG_LR_PADAC, 0x84);
/*----------- Common Communication Settings -----------*/
// Set base frequency (channel) of the LoRa module
sx127X_setChannel(channel); // 915.8MHz
// Set the data rate (bandwidth and spreading factor) of the LoRa module
sx127X_setDataRate(dataRate); // SF7, BW=125,000kHz
// Set the coding rate of the LoRa module
sx127X_setCodeRate(CR_4OF5);
// 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(0x10);
// 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(0xAA);
// Select inversion of I and Q signals
sx127X_invertIQ(INVERT_IQ_OFF);
/*------------ RX Communication Settings ------------*/
// 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);
Y este es el bucle para recibir y mostrar paquetes (sobre USART) ...
while(1) {
loopFlashLED();
// Check for received packet
USARTSendString("Listening for packets...\n");
if (sx127X_RxPacket((uint8_t *)recievedData)) {
// print received string over UART
USARTSendString("Received string!!: ");
for (idx = 0; idx < 20; idx++) {
USARTSendByte(recievedData[idx]);
}
USARTSendByte('\n');
// reset received data array
for (idx = 0; idx < 20; idx++) {
recievedData[idx] = 0;
}
}
}
Y esta es la rutina de recibir paquetes del bucle principal anterior ...
uint8_t sx127X_RxPacket(uint8_t* dataPtr) {
uint8_t var = 0;
uint8_t returnValue = 0;
// Clear interrupts
sx127X_ClearIrq();
// Set to receive mode
setMode(MODE_RXSINGLE);
// 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 SPI 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
returnValue = 1;
break;
}
}
// If no packet has been retrieved this call return false
return returnValue;
}
He pasado muchas horas intentando descubrir qué he hecho mal, pero parece que no puedo resolverlo.
No quiero publicar esto como una publicación de "depuración de mi código para mí", sino más bien para ver si alguien familiarizado con los chips Semtech puede detectar problemas inmediatos en la forma en que estoy operando el módulo sx1276. Esta es mi primera incursión en el mundo de los dispositivos de RF, así que es posible que haya pasado por alto algo muy simple. Gracias de antemano por todas y cada una de las aportaciones útiles.
EDIT 1:
Para aclarar la configuración del hardware: Tanto mi placa como las tablas dragino son simplemente un ATmega328P conectado a un módulo sx1276 listo para transmitir (Dorji DRF1276G) (con antena) a través de su interfaz SPI. El único pin DIO conectado de los módulos sx1276 en AMBOS es el pin DIO0. Los Draginos están basados en Arduino, mientras que el mío es Atmel crudo. También hay algunos circuitos periféricos simples en mi placa.
EDIT 2:
Encontré un error en mi código que habría estado impidiendo una comunicación confiable; El módulo DRF1276G utiliza el pin PA_BOOST, no el pin PA_RFO como se pensaba. He actualizado mi lista de códigos para reflejar esto. El problema sigue en pie, sin embargo; No se ha logrado ninguna comunicación.
ACTUALIZACIÓN:
Soldé un nuevo módulo DRF1276G en mi placa para verificar que no fuera un problema de hardware. Agregué algo de código para imprimir a través de uart las lecturas de RSSI en mi ciclo de tiempo de espera y la siguiente imagen muestra esos valores graficados: Puede ver claramente las dos unidades Dragino hablando entre sí dos veces en la ventana de tiempo de espera. Por lo que parece que es un problema de software.