Nothing of the things described below would not be possible without the help of Pawel. Thanks to him the startup, plugging, installation and basic coding took us 1 evening. Seeing him I understood why “Windows limits efficiency”. When he sits at a linux console, he grows additional pair of hands with 8 fingers each. Pawel - many thanks to you!
The first impression after unpacking RPi is being surprised with its miniscule size. The computer is not much bigger than a credit card. That is really not much when you compare it with all the expectations ;)
In order to start working with the RPi you need to:
1. Plug in the SD card with an image of the operating system. At http://www.raspberrypi.org/downloads you will find the latest compilation of Raspbian (a system based on Debian). The downloaded zip file needs to be unpacked and transferred to the SD cards with Win32DiskImager. I used a 8GB put into a dedicated port of my laptop. It all took me 15 minutes.
Source: https://wiki.ubuntu.com/Win32DiskImager
2. Plug in the Ethernet cable (connected on the other side to your switch)
3. Plug in the power cable (5V) ended with a microUSB plug.
All the above-presented steps are well described in the Getting Started instruction available at the web page of the Raspberry Foundation.
Since I do not have a TV or a computer screen with a HDMI input, I wanted to do everything through a console launched at my laptop with Windows 7. I needed to find the IP number of the RPi. After logging into my router (working under Tomato 1.27) I clicked the “Device List” command and found my Raspberry Pi with the IP equal to 192.168.1.164.
Next, you need to run Putty, enter the found IP and change the Window, Translation, Remato character to UTF-8. Its best to save the session for the future use. After clicking Open the communication with your RPi should be launched. The standard user is “pi”, the password “raspberry”. Here it is, blinking nicely at you!
To see the configuration menu, which you would normally see on the screen/TV (if such was plugged), type the command “sudo raspi-config”.
From the available configuration options it is enough to run the ‘expand_rootfs’ to extend the preloaded system image onto the whole SD and ‘change_timezone’ to correct the time settings.
One little comment to the ‘sudo’ command, which I understand as „execute the following as the super user”. It might sound like heresy but I consider the repetitive typing of ‘sudo’ to be a complete nonsense. Sudo here and sudo there, every tutorial repeats sudo. To be able to drop it you need to become the super user, which is possible in 2 steps:
"sudo passwd" - which should change the super user (root) password. For now enter a single space or a letter “x”.
"su" – mening – become the super user. Enter the password defined a second ago and here it is, you can forget the ‘sudo’. Just remember to change the password once you are done playing…
It is no time to connect the sensors. Adafruit presents a very detailed description on how it should be done. The pictures below should help to remove all doubts:
In my case the connections were as follows:
You can see 4 DS18B20 sensors and – since we did not have a 4.7K resistor, 2 9K resistors were used.
It is time to write commands. In your putty enter the following:
modprobe w1-gpio
modprobe w1-therm
what should start the processes responsible for the 1-wire sensors. To check the if everything works type:
cd /sys/bus/w1/devices
ls
which changes the current directory to /sys/bus/w1/devices, where all the detected sensors and hubs are ‘mounted’ and lists the directory content.
I my case I saw:
root@raspberrypi:/sys/bus/w1/devices# ls
28-00000067a748 28-00000067ba5a 28-000002ff861f 28-000002fg961f w1_bus_master1
If you see the above on your RPi it means that your device is ready to read temperatures. In order to make the information accessible for the PLC with POST/GET queries it is necessary to run a www server with PHP. If you are interested in details, run a google search (Raspberry Pi webserver PHP). Those who like shortcuts should type:
apt-get install php5
Which should install and launch all that is needed. To check if you were successful, enter in the address bar of your browser the IP of the RPi and you should see the standard Apache message:
Any future content should be saved in the /var/www directory. For now place there 2 files:
1. test.php
<?php require_once('OWireTherm.class.php'); error_reporting(E_ALL); ini_set('display_errors', '1'); $SlaveFile = file("/sys/bus/w1/devices/w1_bus_master1/w1_master_slaves"); if (!$SlaveFile) { echo "ERROR with slave-list file"; } else { foreach ($SlaveFile as $line){ $t1 = new OWireTherm(trim($line)); if (($temp = $t1->readTemp()) !== false){ echo $temp.";"; } else { echo "ERROR"; } } }
2. OWireTherm.class.php
<?php class OWireTherm { protected $id; public function __construct($id) { $this->id = $id; } protected function openFile() { return fopen("/sys/bus/w1/devices/$this->id/w1_slave", 'r'); } public function readTemp() { $fp = $this->openFile(); if (!$fp) { echo "Nie moge otworzyc pliku dla $this->id"; return false; } $buff = fgets($fp); if (!preg_match('/YES$/', $buff)) { echo "Bledna suma CRC podczas odczytu"; return false; } $buff = fgets($fp); if (!preg_match('/t=(-?[0-9]+)$/', $buff, $matches)) { echo "Niepoprawny odczyt temperatury ($buff)"; return false; } return $matches[1]/1000; } }
If both the files (test.php i OWireTherm.class.php) are placed in /var/www entering in your browser the following: http://192.168.1.164/test.php should let you see the temperatures of all your sensors separated by a colan (i.e. 14.875;14.75;14.437;).... Now we will reach out for the data from the PLC side.
I added 2 libraries to my CoDeSys project: WagoLibHttp_02.lib and WagoLibBase64_01.lib. Both can be downloaded from the WAGO web page. There are also interesting expamples of using the WagoLibHttp, which in details show what (and how much) is possible.
I created a new process in my program (Resources->Task configuration, right-click in the new window - > Append Task). It received a low priority and a “freewheeling” type. Then I added a program call of HttpComm(), which is in 95% based on Example 1 coming with the WagoLibHttp_02.lib. Here is the code:
- in variable definitions:
PROGRAM HttpComm VAR xDoIt : BOOL; (*to initiate communication*) wState : WORD; (*storing the communication status*) (* HTTP_GET *) oHttpGet: HTTP_GET; (*the main function block*) sUrl : STRING(250):= '/test.php'; xHttpSend : BOOL; diError : DINT; sStatus : STRING; abResponse : ARRAY [0..MAX_RECEIVE_TCP_CLIENT] OF BYTE; uiResponse : UINT; (* Parsing response data *) sTemperature : STRING; Temperatues : ARRAY [0..15] OF REAL; (*for storing received temperatures*) (* Helpers *) i : INT; TempCount : INT; iHelp : INT; abHelp : ARRAY [0..180] OF BYTE; psHelp : POINTER TO STRING(180); END_VAR
- in the program:
oHttpGet(sServerName:= '192.168.1.164', wServerPort:= 80, pabUrlData:= ADR(sUrl), uiUrlLength:= LEN(sUrl), tTimeOut:= t#3s, xSend:= xHttpSend, diError=> diError, sStatus=> sStatus, abContentData=> abResponse, uiContentLength=> uiResponse); CASE wState OF 0: (* IDLE - wait for something to do *) IF xDoIt THEN xHttpSend := TRUE; (* Send HTTP-GET request *) wState := 10; END_IF 10: (* Wait for HTTP-GET response data *) IF NOT xHttpSend THEN IF diError = 0 THEN (* Success *) wState := 20; (* Parse response data *) ELSE (* Error *) wState := 999; (* Try again next time *) END_IF END_IF 20: (* Parse response data for 'Temperature:'*) i:=0; (*Counter of fields in adResponse array*) TempCount:=0; (*Counter of found temperatures->fields in Temperatures array*) iHelp:=0; (*counter for supportive*) WHILE (abResponse[i]>0) DO (*meaning as long as there is data in the adResponse table*) IF (abResponse[i]<>59) THEN (*meaning if response char is not = „;”*) abHelp[iHelp]:=abResponse[i]; iHelp:=iHelp+1; ELSE (*here is the conversion of data stored in abHelp array to STRING and then to REAL*) psHelp := ADR(abHelp); sTemperature := psHelp^; Temperatues[TempCount]:=STRING_TO_REAL(sTemperature); TempCount:=TempCount+1; iHelp:=0; END_IF i:=i+1; END_WHILE wState := 999; 999: (* *) xDoIt := FALSE; wState := 0; END_CASE
A simple visualization with a button and 4 text fields can be used to test the program:
Communication between PLC and RPi and reading temperatures at the presented configuration and with the shown scripts is by all means imperfect. The Apache server at its default configuration is slow and might need to be replaced by another, lighter solution. The scripts – both on the side of the server as well as the PLC – are lacking any proper error handling. Additionally, what might even be most important, connecting the 1-wire sensor as presented in this article is not feasible in case of an extensive network – many cables arranged in a star, placed close to 230VC wires. It is just a proof of a concept to show if at all those things can be done.
Since this simple test ended with a success, the following actions are needed: