Raspberry Pi OPC-UA Server


I built a very simple OPC-UA server that exposes the Raspberry Pi GPIO this afternoon… thought some of you might get a kick out of it. It’s just for the GPIO - there’s no free PLC drivers or anything like that, so don’t get your hopes up :wink:

I’ve got 4 LEDs hooked up that I can toggle on and off via Ignition. Kinda neat.

You can download the source and/or binaries here: github.com/kevinherron/pi-server



It runs smoothly on both Rpi and ARMV7 platforms. Let’s hope for the drivers soon.

This is the output from my test machine:

alam@debian-armhf:~$ uname -a
Linux debian-armhf 3.2.0-4-vexpress #1 SMP Debian 3.2.51-1 armv7l GNU/Linux

alam@debian-armhf:~/pi-server-1.0.0$ sudo tail -f logs/wrapper.log | cut -d ‘|’ -f 4

17:00:14.923 [WrapperSimpleAppMain] INFO c.i.opcua.sdk.server.OpcUaServer - Binding endpoint opc.tcp:// [None/None]

BTW when i tried to connect from Ignition, i get this error message. Not sure what i missed.

RaspberryPi OPC-UA Server:
Faulted Error: show details
Server did not return any endpoints matching the current criteria: SecurityPolicy=Basic128Rsa15, MessageSecurityMode=SignAndEncrypt, TransportProfileUri=http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary

Port: 12685



In Ignition you need to configure SecurityPolicy and MessageSecurityMode to both be ‘None’



It gets connected to ignition perfectly on ARMV7 platform. even with 256mb RAM. On Rpi which is ARMV6 with 256mb RAM, doesn’t get connected to Ignition. I think, it’s better to focus on ARMV7 and Rpi will catch up in next release.

HP had released ARM64-bit moonshot servers. Very interesting things are happening.



[color=#0040BF]How to emulate ARM V7 with “Ubuntu+QEMU” on x86 machines:[/color]

This is to help those who do NOT have ARM harware for cross platform testing and development.

[color=#0000FF]Step 1: Requirements:[/color]

  1. Ubuntu 14.04 desktop
  2. Install QEMU from Ubuntu software centre.

[color=#0040FF]Check QEMU with these commands:[/color]

$ qemu-system-arm -version
QEMU emulator version 2.0.0 (Debian 2.0.0+dfsg-2ubuntu1.6), Copyright © 2003-2008 Fabrice Bellard

$ qemu-system-arm --machine help
Supported machines are:
versatileab ARM Versatile/AB (ARM926EJ-S)
versatilepb ARM Versatile/PB (ARM926EJ-S)
lm3s811evb Stellaris LM3S811EVB
z2 Zipit Z2 (PXA27x)
connex Gumstix Connex (PXA255)
sx1 Siemens SX1 (OMAP310) V2
realview-eb ARM RealView Emulation Baseboard (ARM926EJ-S)
cubieboard cubietech cubieboard
vexpress-a9 ARM Versatile Express for Cortex-A9

midway Calxeda Midway (ECX-2000)
virt ARM Virtual Machine
borzoi Borzoi PDA (PXA270)

[color=#0040FF]Step 2: To quckly start ARM Debian VM under QEMU follow these steps:[/color]

  1. $ sudo mkdir emulator
  2. Download and copy all these files into emulator folder from this link:

[color=#0040FF]README.txt 06-Jan-2014 18:29 3.4K
debian_wheezy_armhf_desktop.qcow2 17-Dec-2013 02:43 1.7G
debian_wheezy_armhf_standard.qcow2 17-Dec-2013 00:04 229M
initrd.img-3.2.0-4-vexpress 17-Dec-2013 01:57 2.2M
vmlinuz-3.2.0-4-vexpress 20-Sep-2013 18:33 1.9M [/color]

[color=#0040FF]To start Debian headless server:[/color]
$ qemu-system-arm -M vexpress-a9 -kernel vmlinuz-3.2.0-4-vexpress -initrd initrd.img-3.2.0-4-vexpress -drive if=sd,file=debian_wheezy_armhf_standard.qcow2 -append “root=/dev/mmcblk0p2” -m 512 -no-reboot -serial stdio

[color=#0040FF]To start Debian desktop:[/color]
$ qemu-system-arm -M vexpress-a9 -kernel vmlinuz-3.2.0-4-vexpress -initrd initrd.img-3.2.0-4-vexpress -drive if=sd,file=debian_wheezy_armhf_desktop.qcow2 -append “root=/dev/mmcblk0p2” -m 512 -no-reboot -serial stdio

  • Hostname: debian-armel
  • Root password: root
  • User account: user
  • User password: user

To install Java 8 on debian ARM follow this link or download the attached pdf:[/color]
webupd8.org/2014/03/how-to-i … ebian.html

user@debian-armhf:~$ java -version
java version “1.8.0_06”
Java™ SE Runtime Environment (build 1.8.0_06-b23)
Java HotSpot™ Client VM (build 25.6-b23, mixed mode)

user@debian-armhf:~$ sudo ifconfig
eth0 Link encap:Ethernet HWaddr 52:54:00:12:34:56
inet addr: Bcast: Mask:
RX packets:2 errors:0 dropped:0 overruns:0 frame:0
TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1180 (1.1 KiB) TX bytes:684 (684.0 B)

lo Link encap:Local Loopback
inet addr: Mask:
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

user@debian-armhf:~$ sudo route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface UG 0 0 0 eth0 U 0 0 0 eth0

With this default subnet 10.0.2.x, we can update and install software on the Debian VM from the internet. But it’s NOT possible to ssh or ftp from the host or any other machine. For that, we must assign static ip as explained below.
Install Java 8 on Debian ARM.pdf (900 KB)



Establishing an ethernet/wifi bridge network between the Ubuntu host and the Debian ARM VM on QEMU:

This is very useful for transfering files between the host and the VM. You can follow these 2 links to understand it better.
mediaonfire.com/tech_tips/QE … rking.html
blog.ericwhite.ca/articles/2011/ … ss-bridge/

edit these 2 files on the Debian ARM VM:

[color=#0000FF]1. $ sudo nano /etc/network/interfaces[/color]

The loopback network interface

auto lo
iface lo inet loopback

This is for static ip. If you do NOT want static ip, uncomment the 2 lines. If you uncomment, DHCP will allocate

#allow-hotplug eth0
#iface eth0 inet dhcp

This is for static ip. If you do NOT want static ip, comment out all the 8 lines.

auto eth0
iface eth0 inet static

[color=#0040FF]2. sudo nano /etc/resolv.conf[/color]

For a quick setup of “tapo” bridge via “wlan0” on your laptop, just download the “QEMU wlan.zip” file, unzip and copy the “kvm_networking” script file into the emulator folder, edit the user name and ip addresses as per the comments and enter the command

[color=#0000FF]On Ubuntu host:[/color]

$ sudo modprobe tun
$ echo tun >> /etc/modules
$ sudo apt-get install uml-utilities
$ sudo kvm_networking start

user@ubuntult:~/emulator$ ifconfig

eth0 Link encap:Ethernet HWaddr 00:1e:68:5f:e4:23
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

lo Link encap:Local Loopback
inet addr: Mask:
inet6 addr: ::1/128 Scope:Host
RX packets:155919 errors:0 dropped:0 overruns:0 frame:0
TX packets:155919 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:32861159 (32.8 MB) TX bytes:32861159 (32.8 MB)

tap0 Link encap:Ethernet HWaddr e2:09:90:1a:bf:05
inet addr: Bcast: Mask:
inet6 addr: fe80::e009:90ff:fe1a:bf05/64 Scope:Link
RX packets:579 errors:0 dropped:0 overruns:0 frame:0
TX packets:688 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:74293 (74.2 KB) TX bytes:81324 (81.3 KB)

wlan0 Link encap:Ethernet HWaddr 00:1f:3b:9c:a0:cd
inet addr: Bcast: Mask:
inet6 addr: fe80::21f:3bff:fe9c:a0cd/64 Scope:Link
RX packets:81656 errors:0 dropped:1 overruns:0 frame:0
TX packets:37944 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:38401362 (38.4 MB) TX bytes:5183650 (5.1 MB)

[color=#0000FF]Launch Debian arm with tap0:[/color]

user@ubuntult:~/emulator$ sudo qemu-system-arm -M vexpress-a9 -net tap,ifname=tap0,script=no,downscript=no -net nic -kernel vmlinuz-3.2.0-4-vexpress -initrd initrd.img-3.2.0-4-vexpress -drive if=sd,file=debian_wheezy_armhf_standard.qcow2 -append “root=/dev/mmcblk0p2” -m 512 -no-reboot -serial stdio

user@debian-armhf:~$ sudo ifconfig

eth0 Link encap:Ethernet HWaddr 52:54:00:12:34:56
inet addr: Bcast: Mask:
RX packets:108 errors:0 dropped:0 overruns:0 frame:0
TX packets:80 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:12577 (12.2 KiB) TX bytes:9911 (9.6 KiB)

lo Link encap:Local Loopback
inet addr: Mask:
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

[color=#0040FF]Now we can do ssh from the host and trasfer files between the host and VM using the “Filezilla FTP” software.[/color]

$ sudo ssh -X -Y user@
Change the “user” and IP address as per your etho “inet addr” as shown above.

With tap0 bridge on wlano, it may NOT be possible to connnet the Debian VM to the internet and update. In this case, we must remove “tap0” bridge and disable static ip on the VM by editing the “/etc/network/interfaces” file as explained above.

To remove “tapo” bridge from the host:
$ sudo kvm_networking stop

If you want to emulate Raxpberry pi on QEMU, follow this link:
xecdesign.com/qemu-emulating-ras … -easy-way/
QEMU wlan.zip (411 KB)



I have a brand new Model B+ to play with your server. Its loaded from github.
After sudo/bin/pi-server.sh start
it shows waiting for about 5 seconds

Raspberry Pi OPC-UA Server may have failed to start.
Question: On a fresh raspbian install what are the pre-requisites?

Maybe I need to update or install something additional?



You need to have Java 8 installed. I typically get it from the webupd8team repository: webupd8.org/2012/09/install- … a-ppa.html

If that’s not the issue then upload your log files and I can take a look.



looks like the java install did it!!

running: PID:24873
I am assuming this is good??!!

I have to wait till Monday to give the PI an ip address that can connect to my main gateway.
Or maybe I will take it home with me for the weekend!!!
I did notice with the gpio.json that it does not exist in the config directory but the example does.
Do I need to create one that correlates with my breadboard derived from the example?
I am super excited to see this work!!

From the posts the security settings in the gateway also need modified.

I do realize that this only offers up the gpio.
The main ignition gateway will ‘poll’ the pi for inputs and outputs right?
Since it is opc ua I just create tags? or is that what the gpio.json is doing?
When the gateway browses the rpi what ‘tags’ will be visible…

I guess I am over stimulate. I better get back to work. :slight_smile:



gpio.json will create tags based on its contents. You must configure the GPIO pins in this config file because it’s impossible for the serve to know ahead of time which pins you’re using and whether you’re using the for input or output, pull-up/pull-down, etc…

Once it’s configured, you should see the tags in Ignition’s OPC browser and just be able to drag them in.

Keep in mind this is just a toy server built on a snapshot of the development version of the new UA SDK I’m building… so what I’m saying is don’t be surprised if there are bugs :thumb_right:



I have the eth0 setup but I have a couple more questions.
What is the port value in the ignition configuration?
I set the security policies to none so I should not have any username/password data to enter?

the wrapper log says 'unable to bind listener to any port in range 32000 to 32999 (cannot assign requested address)
wrapper stopped.
I created the gpoi.json which other than configuring the eth0 with an address is the only thing that has changed since it worked on last friday…



update-- after restarting my Pi the server appears to be running.
PID 2324
I still cannot get connected through the gateway- it faults immediately after configuring.
I tried port 12685 and that seems to be what faults it. I also set the security to none.



error details from gateway—
UAException: Bad_NotConnected…
com.inductiveautomation.xopc.client.stack.TCPClientChannel.stopIOAndShutdown(TCPClientChannel.java:303)com.inductiveautomation.xopc.client.stack.TCPClientChannel.notifyChannelError(TCPClientChannel.java:684)com.inductiveautomation.xopc.common.stack.UAChannel$1.deliver(UAChannel.java:790)com.inductiveautomation.xopc.common.stack.UAChannel$DeliverToDelegate.run(UAChannel.java:1592)com.inductiveautomation.xopc.client.stack.SerialExecutionQueue$RunnableExecutor.execute(SerialExecutionQueue.java:100)com.inductiveautomation.xopc.client.stack.SerialExecutionQueue$RunnableExecutor.execute(SerialExecutionQueue.java:97)com.inductiveautomation.xopc.client.stack.SerialExecutionQueue$PollAndExecute.run(SerialExecutionQueue.java:75)java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)java.util.concurrent.FutureTask.run(Unknown Source)java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Unknown Source)java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)java.lang.Thread.run(Unknown Source)



12:01:02 PM GetEndpoints TCPClientChannel Channel error, closing connection.

StatusCode[Severity=Bad, Subcode=Bad_TcpSecureChannelUnknown]: Channel expired. Created at Fri Nov 21 18:08:41 CST 2014, lifetime=30000

this is from the system console



edited the name servers to point to my dns

I am able to browse the RPi but no gpio are showing up.
After tailing the log it looks like gpio 3 does not support analog output like the example implies.
I modified the config. also I created 2 json files.
gpio.json and

according to the git hub writeup it uses gpio-config.json.
My problem could have been the analog bit. not sure…
I also like that pi-server.sh has a “restart” command



I just wanted to give a quick update after the wonderful holiday! I hope everyone had a good thanksgiving.
I did get the UA Server working on the raspberry Pi. I do have an application where I need to detect 5v and I thought the Pi or arduino would be suited for the task.
I found the server to be a bit un-reliable. as Kevin stated it could be. I had several time out errors and issues throughout the log. It did successfully turn on an led on my test becnch however
It does have some cool factor but is is far away from being a ‘reliable appliance type solution’.
It will be nicely suited for my home automation projects but not useful at the widget factory.
I was thinking about giving the modbus tcp route a try and there is a really nice codesys ui that is affordable.
store.codesys.com/codesys-contro … pi-sl.html
Its quite nice! It might serve as a nice modbus tcp solution that i could connect to ignition.
Anyway; :exclamation:
I just wanted to thank Kevin for sharing and send happy holiday wishes to everyone!
Also wanted to say thanks to Jordan Clark for being a dedicated Ignition enthusiast and helping so much on the forum!



Not surprised about the timeouts… the thing is super slow. I have some updates that hopefully I can push to github later this week that might improve the stability a bit. It will definitely cut the startup time to something reasonable, if nothing else.



Hello Kevin

First I would like to say that this is a very nice test edition of an OPC-UA server.
Currently I’m am doing a project were I’m very keen to learn how to use OPC-UA servers on small embedded systems like a Raspberry Pi.

First off I would like to ask if I understand your setup right:

On a Raspberry Pi (installed with Linux Ubuntu Mate and Java8 ) I launch the PI-Server.sh as described in your “guide lines”.

Then I have connect this Raspberry to a router in order to give the Raspberry a TCP IP Address.

When this done I should be able to locate (if everything is setup right) my GPIO inputs in Ignition Client on another e.g. Windows computer were I have Ignition installed.

Is that understand correctly?

If so, then I think I’m on the right track. Though I believe that my OPC-UA server doesn’t startup correctly. I get following error when executing the $ sudo ./bin/pi-server.sh command in linux:

$ c.i.opcua.sdk.server.OpcUaServer - Binding endpoint opc.tcp:// [None/None]
$ JVM exited unexpectedly.
$ Aug 24, 2015 12:19:12 PM com.pi4j.util.NativeLibraryLoader loadLibraryFromResource
$ WARNING: The temporary file already exists [/tmp/libpi4j.so]; attempting to delete it now.
$ wiringPiSetup: mmap (GPIO) failed: Operation not permitted
$ There were 5 failed launches in a row, each lasting less than 300 seconds. Giving up.
$ There may be a configuration problem: please check the logs.
$ <-- Wrapper Stopped

I have attached my wrapper.log in windows format if you want to take a look at it. Maybe I get this error because I haven’t changed the IP adress in the ./config/wrapper.confile ?! :confused:

Secondly I would like to ask you, do you think that this IP-Server could run on an ARM9 processorlike the LEGO Mindstorm EV3?

Looking forward to here from you!
wrapper_windows.log (67.3 KB)



It looks like the pi4j library might be crashing. Give me a day or so and I’ll release a new build of pi-server that updates both the OPC-UA libraries and the pi4j stuff. This should mean it supports the new RPi 2 as well.



Great, sounds fantastic. It is actually also that version I’m using.