来自Jack's Lab
跳转到: 导航, 搜索




struct pack {
#ifdef W_NET_KEY
    uint8_t netkey[NET_KEY_LENGTH];
    uint8_t dst;
    uint8_t type;
    uint8_t src;
    uint8_t packnum;
    uint8_t length;
    uint8_t *data;
    uint8_t retry;  /* retry number */

struct pack packet_tx;


write_reg(REG_FIFO, packet_tx.dst);   // Writing the destination in FIFO
write_reg(REG_FIFO, packet_tx.type);  // Writing the packet type in FIFO
write_reg(REG_FIFO, packet_tx.src);   // Writing the source in FIFO
write_reg(REG_FIFO, packet_tx.packnum);   // Writing the packet number in FIFO

 * 数据域是一个字符串:
 *   温度传感器:\!U/4.02/T/28.36
 *   温度湿度传感器:\!U/4.02/T/28.36/H/57.0
 *   压力传感器(单位百帕):\!U/4.02/P/3707.07
 *   温度湿度CO2(单位 ppm):\!U/3.76/T/29.38/H/57.0/CO2/448
 * 字符串第一、二字节固定为:'\!'
 * U 表示电池电压
 * T 表示温度
 * H 表示湿度
 * P 表示压力
for (int i = 0; i < data_len; i++) {
    write_reg(REG_FIFO,[i]);   // Writing the payload in FIFO

REG_FIFO 是 FIFO 的统一读写口,SPI 读写 REG_FIFO,就会去 FIFO 内部地址为 Reg_FifoAddrPtr 的位置取放数据

TX_Modem 直接去 FIFO 地址为 Reg_FifoTxBaseAddr 的位置,取 PayloadLength 字节的数据发射

2 PKT Type

#define PKT_TYPE_MASK   0xF0
#define PKT_FLAG_MASK   0x0F

#define PKT_TYPE_DATA   0x10
#define PKT_TYPE_ACK    0x20

#define PKT_FLAG_ACK_REQ            0x08
#define PKT_FLAG_DATA_ENCRYPTED     0x04
#define PKT_FLAG_DATA_WAPPKEY       0x02
#define PKT_FLAG_DATA_DOWNLINK      0x01
  • 高 4 位,pkt Type,两种: DATA 和 ACK
  • 低 4 位,pkt Flag,四种:ACK_Req, Data_Encrypted, Data_WAPPKey, Data_Downlink

3 Node Addr

#define        REG_NODE_ADRS                    0x33
#define        REG_BROADCAST_ADRS               0x34

const uint8_t BROADCAST_0 = 0x00;

# FSK 相关。LowCostLoRa 是写在数据包的第一个字节。。。
writeRegister(REG_NODE_ADRS, node_addr);


#LoRaWAN uses the MHDR(1B) as the PKT Type
#| 7  6  5 | 4  3  2 | 1  0 |
#  0  1  0   0  0  0   0  0     unconfirmed data up
#  1  0  0   0  0  0   0  0     confirmed data up
#   MType      RFU     major
#the main MType is unconfirmed data up b010 or confirmed data up b100
#and packet format is as follows, payload starts at byte 9
#MHDR[1] | DevAddr[4] | FCtrl[1] | FCnt[2] | FPort[1] | EncryptedPayload | MIC[4]
        #LoRaWAN (so encrypted packet)
        #or encapsulated encrypted
        if ptype & 0x40 == 0x40 or ptype & 0x80 == 0x80 or ptype & 0x04 == 0x04:


Channel Activity Detection. It's designed to detect a LoRa preamble on the radio channel with the best possible power efficiency.

Once in CAD mode, the SX127x will perform a very quick scan of the band to detect a LoRa packet preamble.

During CAD, the following operation take place:

  • The PLL locks
  • The radio receiver captures LoRa preamble symbol of data from the channel. The radio current consumption during that phase is approximately 10mA.
  • The radio receiver and the PLL turn off and the modem digital processing starts.
  • The modem searches for a correlation between the Radio captured samples and the ideal preamble waveform. This correlation process takes a little bit less than a symbol period toperform. The radio current consumption during that phase is greatly reduced.
  • Once the calculation is finished the modem generates the CadDone interrupt. If the correlation was successful, the CadDetected is generated simultaneously.
  • The chip goes back to stand-by mode.
  • If a preamble was detected, clear the interrupt, then initiate the reception by putting the radio in RX single mode or RX continuous mode.

The typical CAD detection time:

 SymbolTime = (2^SF + 32) / BW seconds

Refer to: Reading channel RSSI during a CAD


Received Signal Strength Indication,接收信号强度指示

Antenna Diversity,天线分集

The RSSI information is available during CAD and there is no need to leave the receiver on for some additional time

During a CAD, The device is effectively in Reception mode for the duration of one LoRa symbol. It is therefore possible to read the RSSI of the signal present within the LoRa bandwidth.

While in reception, the RSSI is sample every 8uS and is asymptotically analyzed. This means that the RSSI value is being calculated along the length of the symbol duration and is directly related to the number of point previously analyzed.

 symbolTime = (pow((float)2, (float)LORA_SPREADING_FACTOR)) + 32) / 125000; // SF7 and BW = 125 KHz
 symbolTime = symbolTime * 1000000; // symbol Time is in us

 while( 1 )
     t.reset( ); // Reset the Timer
     Radio.StartCad( ); // Set the device into CAD mode
     t.start( ); // Start the Timer
     while( t.read_us ( ) < 240 ); // 240us are needed for the device to go into CAD Mode from Sleep Mode
     while( t.read_us ( ) < symbolTime + 240); // We wait for Symbol Time and 240 us to be at the very end of
     // the symbol duration
     rssi[i++] = Radio.GetRssi( MODEM_LORA ); // We can now read the RSSI
     t.stop( ); // Stop the Timer
     while( State != CAD_DONE ); // Wait for the end of the CAD process

7 Preamble

LoRa 数据包前导码,用于接收机辩识 rx data flow。内容固定,长度可选。

默认 12 个 symbol(Bytes?), 0x8 (RegPreambleLsb) + 4

可写 RegPreambleMsb 和 RegPreambleLsb 这两个寄存器,将其改为 6 +4 ~ 65535 +4

10 symbol 的短前导码,通信够用但具有更短的接收周期。。。

当前系统一般皆适用 12 (4 + 8) 的长度:

^$Get Preamble Length: state 0
^$Preamble Length: 8

8 Sync word

  • 0x12 by default
  • 0x34 for LoRaWAN


9 Header

Explicit Header & Implicit Header

可通过寄存器 RegModemConfig1 内的位 ImplicitHeaderModeOn 来控制

Explicit Header:

Reset 默认的模式。其能提供的信息:

  • Payload 长度
  • The forward error correction code rate
  • The presence of an optional 16-bits CRC for the payload

The head is transmitted with maximum error correction code (4/8). It also has its own CRC to allow the receiver to discard invalid headers.

Implicit Header:

Header is removed from the LoRa Packet.

Payload, Coding Rate and CRC presence are fixed.

Be advantageous to reduce transmission time

10 CRC

RegPayloadCrcOn: RegModemConfig2[2:2]

  • 0 ---> CRC disable
  • 1 ---> CRC enable

In Implicit Header Mode: must be set on Tx and Rx side

In Explicit Header Mode: on the Tx side alone (recovered from the header in Rx side)

Explicit Header Mode Checking process:

Rx 用户负责检查 CrcOnPayload (RegHopChannel[6:6], CRC information extracted from the rx packet header)

如果 CrcOnPayload == 1,需要检查 IRQ 标志位 PayloadCrcError,以确保没有 CRC 错误

Implicit Header Mode 则直接去检查 IRQ 标志位 PayloadCrcError,以确保没有 CRC 错误

11 Testing Note

  • NO LOW_POWER:闲时 10.5 mA,发射 19.5mA、40mA、85mA
  • LOW_POWER: 睡眠 1.7mA,发射 50mA、87mA

05/30 23:55:54:

  • LOW_POWER: 睡眠 1.7mA,power_off_dev() 后,睡眠电流居然猛增到 54mA 左右。。。夜深明日再战。。。

05/31 11:40

  • 增加 SPI.end(); digitalWrite(SPI_CS, LOW),睡眠电流降到 115uA 左右。必须两个都有,只有其中一个,睡眠电流都在 34mA 左右
  • powerDown(SLEEP_FOREVER, ...) 电流在 111uA 左右

  • 增加 Wire.end(); 电流还是在 115uA 左右。再增加 SDA (A4), SCL (A5) ---> LOW,电流还是在 115uA 左右。

  • 使用另外一片 Quark,power_switch 换成 SI2301,移除 AP2112,直接 Vbat (3.3V) 供电,移除 SX1278,同样的代码(移除 LoRa 相关),睡眠电流为 4.3uA 左右,即: Atmega328p + SI2301 的消耗在 4.3uA 左右。。。
    • 固件没动,焊上一片 SX1278,睡眠电流一样
    • 固件和另一片一样,则睡眠电流也变为 109 uA 左右。因此貌似关 SX1278 的电源并不能显著降低睡眠电流,难道应该就用其的 power down 模式?!
    • 改为 sx1272.OFF() (其实就是 SPI.end()),不设 setSleepMode(),电流 2mA;再 digitalWrite(SPI_CS=10, LOW),电流变为 65uA
    • OFF() 前 reset() 一下,不设 setSleepMode(),digitalWrite(SPI_CS=10, LOW),还是 65uA
    • 设 setSleepMode(),OFF() ,digitalWrite(SPI_CS=10, LOW),还是 65uA
    • 设 setSleepMode(),no OFF() ,no digitalWrite(SPI_CS=10, LOW),电流变为 750uA
    • 设 setSleepMode(),no OFF() ,SPI.end(), digitalWrite(SPI_CS=10, LOW),58uA
    • 将 RST 拉低,4.4uA !泪流满面。。。 05/31 16:16

  • quark-t 新驱动 qsetup(),20dbm,最大发射电流实测 134mA, 2019/06/26 09:54
  • quark-t 新驱动 qsetup(),17dbm,最大发射电流实测 85mA, 2019/06/26 17:17
  • quark-t 新驱动 qsetup(),14dbm,最大发射电流实测 79mA, 2019/06/26 17:20
    • REG_OCP = 0x21(即:限流 50mA ),最大发射电流实测 71mA, 2019/06/26 18:18
    • REG_OCP = 0x20(即:限流 45mA ),最大发射电流实测 63mA, 2019/06/26 18:39
  • quark-t 新驱动 qsetup(),11dbm,最大发射电流实测 60.8mA, 2019/06/26 20:40

  • quark-th, old driver, with GPS, 42mA/154mA
    • new driver, with GPS, 41mA/47mA/172mA
  • quark-p 新驱动 qsetup(),11dbm,最大发射电流实测 39mA, 15/36/37/39mA, 2019/07/04 10:20


  • 绿、巧克力色线 18650 电池: 20190903.11:44 ~ 20190915.21:52

12 Reference