Categories
Connected Farm

Remote 3G MySensors Gateway using Raspberry Pi Zero.

In order to monitor sensors a long way from the main farm I’ve built a remote sensor gateway using a Raspberry Pi Zero, an old 3G dongle and an NRF24 radio. I’m only using the NRF24 radio as I had some spare here along with some old sensors from previous projects. These can easily be replaced with the RFM95 LoRa radios with only minor software changes.

I purchased the Raspberry Pi Zero W from thepihut.com, the W comes with no pin headers so I had so solder some on, the WH model however comes with them pre-soldered.

For the 3G dongle I’m using an old Huawei e3131, this dongle can be configured for the necessary network APN settings using a windows PC and then transferred to the PI Zero as plug and play with no need for any more configuration. The 3G dongle shows up as LAN adaptor ETH0 on the Pi with an address of 192.168.1.100 and gateway address of 192.168.1.1 . A female USB A to male USB micro B adapter is also required for connection.

The NRF24 or RFM95 radio is connected as per the build instructions on mysensors.org.

Raspberry Pi Zero W has same pin layout as Raspberry Pi 2/3/4

NRF24L01+ Radio

RaspberryNRF24L01+Color
GNDGNDBlack
3.3V*()**VCCRed
22CEOrange
24CSN/CSYellow
23SCKGreen
19COPI/MOSIBlue
21CIPO/MISOViolet
15*(\*)**IRQGray

RFM95 Radio

RaspberryRFM69Color
GNDGNDBlack
3.3VVCCRed
24NSSYellow
23SCKGreen
19COPI/MOSIBlue
21CIPOMISOViolet
22DI00Gray
ANAAntenna*
RSTNot used
* Solder a piece of wire, more info here

At the moment I have just one sensor connected to the MySensors gateway, it’s a liquid level monitor I had made previously and it is monitoring water available from my solar well pump.

The Pi Zero has gotten a very special custom case and is powered from a USB port on the charge controller of my Solar Pump.

Raspberry Pi OS Install:

The OS install is the same as the Home Assistant install in my previous post.

First download the Raspberry Pi OS Lite from: https://www.raspberrypi.org/software/operating-systems/#raspberry-pi-os-32-bit and write to an SD card using imager software on your PC such as BalenaEtcher https://www.balena.io/etcher/.

Next remove the SD card from the PC and then re-insert, (don’t click on format if prompted by windows). To enable SSH create a new text file with notepad, in the new file put in one space and nothing more, call the file ssh and save and close it.

WiFi is needed as there is no LAN adapter on the Raspberry Pi Zero, so you need to create a second file called wpa_supplicant.conf and paste in the contents below adjusting for the country code, your WiFi name and password. If using Ethernet you can skip.

  country=IE
  ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
  update_config=1

  network={
      ssid="NETWORK-NAME"
      psk="NETWORK-PASSWORD"
  }Code language: JavaScript (javascript)

Windows may add .txt to the end of the file names and hide it, which will need to be removed. So click view at the top of the folder window and tick the box for file name extensions. Then right click on each file and rename without the .txt, ignore any warning about changing file name extensions.

With file name extension view on and the files renamed correctly they should look like below. The icons have changed from the Notepad icon to a blank page icon.

Next place both files in the root directory of the boot SD card. The SD card can now be removed from the PC and inserted into the Raspberry Pi. The Raspberry Pi can now be booted up for the first time, there is no need for a keyboard mouse or monitor as we will be using Putty to access the OS.

Install Putty from https://www.putty.org/ on your PC if you don’t already have it. You will now need the IP address of your Raspberry Pi, which you may be able to find through your router by checking for connected clients, but I like an app called Fing available as a phone app and on PC https://www.fing.com/, the free versions are more than enough.

Once you have Putty installed and the IP address entered click open. You should be prompted for a login, the username is pi and password is raspberry.

Next we run a script included with the OS to change some system settings:

sudo raspi-config

Go into System Options and set a new password and change the hostname to RemoteGateway. Next go to Advanced options and expand filesystem to make use of the entire SD card. Then Finish and reboot.

VPN Install and configuration:

Next is the WireGuard Client setup, run the following commands one at a time.

sudo apt update && sudo apt upgrade -y

sudo apt install raspberrypi-kernel-headers libmnl-dev libelf-dev build-essential git -y

git clone https://git.zx2c4.com/WireGuard

cd WireGuard/src

sudo make

sudo make install

sudo systemctl enable wg-quick@wg0Code language: PHP (php)

Then copy the contents of the WireGuard client config files created during the Home Assistant install in the previous post need to be copied to the Raspberry Pi Zero.

sudo nano /etc/wireguard/wg0.conf

The format should look like:

[Interface]
PrivateKey = privatekeygoeshere
Address = 10.6.0.2/24

MTU - 1420
DNS = 8.8.8.8

[Peer]
PublicKey = publickeygoeshere
Endpoint = YourHostName@Duckdns.org
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25Code language: PHP (php)

Finally we can start the VPN service

sudo wg-quick up wg0

MySensors Gateway Configuration:

Enter the following commands one at a time:

git clone https://github.com/mysensors/MySensors.git --branch master

cd MySensors

Code language: PHP (php)

If using the RFM95 LoRa Radios enter the following:


./configure --my-transport=rfm95 --my-rfm95-frequency=868 --my-gateway=ethernet --my-port=5003

If using the NRF24 radios:

./configure --my-transport=rf24 --my-rf24-channel=91 --my-gateway=ethernet --my-port=5003

To test run:


sudo ./bin/mysgw

The following message indicates that communication with the radio module failed:

mysgw: Starting gateway...
mysgw: Protocol version - 2.3.0-beta
mysgw: MCO:BGN:INIT GW,CP=RNNG---,VER=2.3.0-beta
mysgw: TSM:INIT
mysgw: TSF:WUR:MS=0
mysgw: !TSM:INIT:TSP FAIL
mysgw: TSM:FAIL:CNT=1
mysgw: TSM:FAIL:PDTCode language: HTTP (http)

A success message would be:

Jun 21 06:36:58 INFO  Starting gateway...
Jun 21 06:36:58 INFO  Protocol version - 2.3.0
Jun 21 06:36:58 DEBUG MCO:BGN:INIT GW,CP=RPNGL---,VER=2.3.0
Jun 21 06:36:58 DEBUG TSF:LRT:OK
Jun 21 06:36:58 DEBUG TSM:INIT
Jun 21 06:36:58 DEBUG TSF:WUR:MS=0
Jun 21 06:36:58 DEBUG TSM:INIT:TSP OK
Jun 21 06:36:58 DEBUG TSM:INIT:GW MODE
Jun 21 06:36:58 DEBUG TSM:READY:ID=0,PAR=0,DIS=0
Jun 21 06:36:58 DEBUG MCO:REG:NOT NEEDED
Jun 21 06:36:58 DEBUG Listening for connections on 0.0.0.0:5003
Jun 21 06:36:58 DEBUG MCO:BGN:STP
Jun 21 06:36:58 DEBUG MCO:BGN:INIT OK,TSP=1

To install:


sudo make install

To start service automatically when the Raspberry boots:

sudo systemctl enable mysgw.serviceCode language: CSS (css)

Now either reboot the Pi, or run this command to start the gateway:

sudo systemctl start mysgw.serviceCode language: CSS (css)

For more information and troubleshooting see https://www.mysensors.org/build/raspberry

Setup Home Assistant MySensors integration:

Log into your Home Assistant via its web browser address, then go to configuration and select integrations then click the add integration button on the bottom right.

Fill in MySensors version and IP address.

If you haven’t taken control of your layout on the overview screen then any sensors picked up by the gateway should start showing up automatically. If you have taken control of the layout then you need to add them manually. First click the three dots on top right hand corner and choose edit dashboard, next click add card on bottom right then add an entity or gauge card. In the entity field you can scroll through all available entities or search using the name of sensor and address set in its sketch during programming with the Arduino IDE.

Example sketch for my liquid level/distance sensor:

#define SENSOR_NAME "Distance Sensor"
#define SENSOR_VERSION "1.1"

#define CHILD_ID 1  // Each radio node can report data for up to 254 different child sensors. You are free to choose the child id yourself. 
                    // You should avoid using child-id 255 because it is used for things like sending in battery level and other (protocol internal) node specific information.
#define TRIGGER_PIN  6  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     5  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 300 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
unsigned long SLEEP_TIME = 3600000; // Sleep time between reads (in milliseconds)


NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
MyMessage msg(CHILD_ID, V_DISTANCE);
int lastDist;
bool metric = true;

void setup()  
{ 
  metric = getControllerConfig().isMetric;
}

void presentation() {
  // Send the sketch version information to the gateway and Controller
  sendSketchInfo(SENSOR_NAME, SENSOR_VERSION);

  // Register all sensors to gw (they will be created as child devices) by their ID and S_TYPE
  present(CHILD_ID, S_DISTANCE);
}

void loop()      
{ 
  // use the build-in digital filter to discard out of range pings
  int echoTime = sonar.ping_median(10);
  int dist = (metric?sonar.convert_cm(echoTime):sonar.convert_in(echoTime))*2;
  Serial.print("Ping: ");
  Serial.print(dist);
  Serial.println(metric?" cm":" in");

  if (dist != lastDist) {
      send(msg.set(dist));
      lastDist = dist;
  }

  sleep(SLEEP_TIME);Code language: PHP (php)

Any questions on this or any other post please feel free to ask in the comments section.

Facebook Comments