As far as i can tell, the Dragino LPS8 is very poorly designed for heat dissipation; with the ambient air at around 25 degrees Celsius the device overheats and reboots frequently. I have added a cooling fan to the front cover that is activated as soon as the temperature inside the box reaches a certain threshold (30 degC currently).

Since i installed my Dragino LPS8 LoRaWAN gateway in January 2022, it has been frequently rebooting, several times per day. I had tried different things; updating the firmware, monitoring the syslog, but could not find the cause. I installed a cron job to send the gateway’s uptime to my ThingsBoard server, and finally, when the weather started to get hotter, i recognised the pattern: the gateway is stable until around noon, when the air inside the house goes above 25 degC and overheats the gateway. Below graph shows that from around 12:00 the gateway is constantly rebooting, until about midnight after the air temperature has gone down again. The temperature graph is from my solar PV inverter on the roof (outside in the sun, inactive during the night): at the maximum outside temperature, the gateway starts rebooting.

BEFORE FIX:

AFTER FIX (uptime 27 days and counting):

TEMPERATURE SENSOR

I was hoping to identify an internal CPU temperature sensor in the AR9331 of the LPS8, but i could not find one, # find /sys -name temp did not return anything. Luckily the gateway PCB has a header where some GPIO pins are available. First i wanted to use a simple DS18B20 temperature sensor with the 1-wire protocol, but the 1-wire package could not be installed using opkg. I had an Si7021 I2C sensor available so decided to use that, as I2C is already installed by default (check with # opkg list-installed | grep i2c). I checked which GPIO pins are already in use with # cd /sys/class/gpio – that showed me 15, 21, 23 are certainly not available.

Below picture shows my first experiment, with the sensor on 3.3V, SDA on GPIO27 and SCL on GPIO26. To make the use of these I2C pins permanent, i edited /etc/modules.d/59-i2c-gpio to include i2c-gpio-custom bus0=0,27,26

The easiest way to use the sensor seems with i2c-tools, however, i was not able to install it straight from the repositories, so i had to download the package manually:

# wget https://downloads.openwrt.org/releases/18.06.2/packages/mips_24kc/packages/i2c-tools_3.1.2-1_mips_24kc.ipk
# opkg install i2c-tools_3.1.2-1_mips_24kc.ipk
# i2cdetect 0

This showed me that the sensor was found at address 0x40. I’m aware there is a module for this sensor kmod-hwmon-sht21 but it seems to need a more recent kernel version. After some fiddling, i figured out that the temperature code is available as a 16-bit unsigned integer, using this command, where 0 is the I2C bus number, 0x40 the I2C address, 0xe0 the offset, and ‘w’ to read a word (2 bytes).

# i2cget -y 0 0x40 0xe0 w

This code can be converted to degrees Celsius with a formula i got from a Sparkfun library for the Si7012.

COOLING FAN

I had a small brushless 5V fan in stock (F251R), which draws about 60mA. I decided to control it via a GPIO pin using an N channel mosfet IRLZ14SPBF (as low side switch, gate resistor 220ohm, pull-down 10Kohm, flyback diode). I use GPIO6 to control the fan, with these shell commands (declare PIN, declare OUTPUT, set HIGH):

# echo "6" > /sys/class/gpio/export
# echo "out" > /sys/class/gpio/gpio6/direction
# echo "1" > /sys/class/gpio/gpio6/value

To connect the sensor and mosfet switch to the female header on the PCB i used a perf board with a male header, and soldered the components on the top.

It seems the ICs on the left of the main PCB heat up most, so i made a hole for the fan on the central left side.

In addition to the fan, i also drilled a few 5mm holes in the top side of the gateway box; the tiny standard holes probably do not allow enough circulation.

OBSERVATIONS

Below dashboard shows that for the first time ever, my gateway has not rebooted for over 4 days. The green fan status shows that the fan is usually ON from afternoon to midnight. The first day i had set TEMP_THRESHOLD to 40 degC, which still caused frequent reboots. Also 35 degC was not low enough. Now my threshold is set to 30 degC and that seems to be stable.

It seems i should have used a larger fan: on 31/3/2022 the sensor inside the gateway reported a temperature of 35 degrees around 16:40, after a particularly hot afternoon, and the gateway rebooted after a record 6 days of stable operation. The fan had been on constantly from 9am but it was not able to bring the temperature down to the target 30 degC.

SCRIPT ON GATEWAY

This is the code that i have running on the gateway as a cron job every 5 minutes; it does the following:

  • define TEMP_THRESHOLD
  • check if GPIO6 has been initialised, if not, set as OUTPUT pin, HIGH
  • get the uptime of the gateway
  • get the temperature from the Si7012 sensor over I2C
  • compare the current temperature (converted to integer) with TEMP_THRESHOLD, switch fan on or off accordingly
  • publish the uptime, temperature, fan status to my MQTT broker (ThingsBoard)
#!/bin/sh

# install i2c-tools with
# wget https://downloads.openwrt.org/releases/18.06.2/packages/mips_24kc/packages/i2c-tools_3.1.2-1_mips_24kc.ipk 
# opkg install i2c-tools_3.1.2-1_mips_24kc.ipk

# enable I2C in nano /etc/modules.d/59-i2c-gpio with i2c-gpio-custom bus0=0,27,26
# check with dmesg | grep i2c  and  i2cdetect 0

# if temp too high, switch on fan via gpio with N channel mosfet
#################
TEMP_THRESHOLD=30
#################

# check if gpio6 directory exists, if not initialise for fan control
if test -d "/sys/class/gpio/gpio6"; then
    echo "GPIO6 already initialised"
else
    echo "initialising GPIO6 as output"
    echo "6" > /sys/class/gpio/export
    echo "out" > /sys/class/gpio/gpio6/direction
    echo "1" > /sys/class/gpio/gpio6/value
    echo "fan switched ON"
fi

# get uptime in seconds
UPTIME=$(cat /proc/uptime | awk '{print $1}')
echo "`date` uptime (sec): $UPTIME"

# get temperature
echo 'get temp over i2c'

# command to read temperature SI7021_MEASTEMP_NOHOLD_CMD
i2cset -y 0 0x40 0xF3
sleep 1

# get 2 bytes of temp code
TEMP_CODE=`i2cget -y 0 0x40 0xe0 w`
#echo $TEMP_CODE
MSB="$(($TEMP_CODE & 0x00FF))"
LSB="$(($TEMP_CODE & 0xFF00))"
#echo $MSB
#echo $LSB
#echo "$(($MSB << 8))"
#echo "$(($LSB >> 8))"
TEMP_WORD="$((($MSB << 8) + ($LSB >> 8)))"
TEMP_C=$(awk "BEGIN {print (((175.72 * $TEMP_WORD) / 65536) - 46.85); exit}")
echo "temp (degC): $TEMP_C"

# compare temp with threshold and switch fan on or off
# shell can only compare integers, so we truncate first
TEMP_C_INT=$( printf "%.0f" $TEMP_C )

if [ $TEMP_C_INT -gt $TEMP_THRESHOLD ]
then
    echo "current temp higher than threshold $TEMP_THRESHOLD so switch fan ON"
    echo "1" > /sys/class/gpio/gpio6/value
    FAN_STATUS=1
else
    echo "current temp lower than threshold $TEMP_THRESHOLD so switch fan OFF"
    echo "0" > /sys/class/gpio/gpio6/value
    FAN_STATUS=0
fi

# publish to TB gateway device: uptime, temp, fan status
mosquitto_pub -h solarmonitor.hk -p 8883 -d -u xxxx -t v1/devices/me/telemetry -m "{uptime:$UPTIME, temp:$TEMP_C, fan:$FAN_STATUS}" --cafile mqttserver.pub.pem
Dragino LPS8 LoRaWAN gateway overheating fix

Leave a Reply

Your email address will not be published. Required fields are marked *