Basic Warwalking with a Raspberry

An straight an reliable way to gather field data, posting it in real time to the web and having the CSV or KML available to download.

Basic Warwalking with a Raspberry

Let’s make it easy yet powerful: To have a working case we will look how many wifi networks are detected in eachpoint ofa path using a Raspberry Pi and coding in JAVA.

The things you need

  • Raspberry: I am using Raspberry 3, but there is no reason why you could not use another model (I didn’t try yet), while it has a wlan interface to detect networks and to reach the web using the connection shared by your cell phone.
Raspberry Pi model 3
  • A cell phone: Any with data connection that can share a wifi… in other words: any.
  • USB external battery: Any that can power you Raspberry, like the ones used as extra external batteries for the cell phones. Used to move freely in the field. It should be 5-6V. Please note that with a supply of 1000mA I had some trouble for the Pi to recognize the USB connection, but with one of 4000mA (reasonably charged) it worked well.
Portable phone battery
  • A GPS receiver: I am using Globalsat BU-353S4. Is a bullet proof old friend and is not expensive at all. It communicates by USB at 4800bauds and provides NMEA frames containing the GPS information. I will provide a library, so you only have to carry about the coordinates and you don’t have to study NMEA frames, nevertheless if you want to dive in take a look to this handy resource. While it is USB and NMEA there is no reason you can not use another receiver (I didn’t try yet).
GPS receiver
  • A free account at circusofthings.com: What can I say about my beloved community where easily interconnect your inventions. But let’s focus on the fact that you will have a dashboard ready-to-use and you won’t have to worry about the server side. You only need to create a free account.

Creating a signal to handle information at server

Create a free account at Circus:

Landing at Circus

Once inside, go to the “Workshop” where you will create a signal to handle the data:

Sight of the Community feed

Create a signal:

A workshop with user's signals
Once signal is created

Just give it a name, the description you think will fit to your signal, add tags, set visibility whether you want to show it or not, set the parameters (Note: those are only static information for people that will watch the signal, not actual variables):

A signal ready to work :)

Now you have set the signal. It has only static information right now, but soon your hardware will be feeding the changing value and the changing location.

Take note of the “key” displayed under the signal title, it will identify your signal when communicating with server.

One more thing: Also take note of the “token”, it will identify you when accessing the server. Find it clicking on your image, in the top-right corner, then “account”.

Setting up the software in the Raspberry

The JAVA code

I made a simple executable JAVA program called CircusField. It goes through a loop doing this tasks:

  • Takes GPS latitude, longitude, altitude coordinates (in decimal degrees). I use a library I made called jaumemirallesisern-gps.jar to read NMEA data from a GPS receiver through USB port. The object GPSNMEAserial needs two parameters: serial baud rate and USB port descriptor. In my case where 4800 and “/dev/ttyUSB0”.
  • Executes a Linux command (sudo iw dev wlan0 scan) to get the number of SSIDs detected. If you don’t have this command in your system, just install it: sudo apt-get update and sudo apt-get install iw.
  • Reporting to Circus Of Things the latitude, longitude, altitude coordinates, and the value (for us is the number of SSID read above). It is made through the Write command defined in the REST API of the Circus. You don’t have to code the API commands in JAVA as you can take profit of the ready-to-use library called circusofthings.jar.

And looks like this:

package circusfield;
  
import com.circusofthings.api.ver110.CircusLib;
import com.jaumemirallesisern.hardware.GPSNMEAserial;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
  
public class CircusField {
  
   private static final String KEY = "your_key_signal_at_circus_here";
   private static final String TOKEN = "your_circus_token_here";
   private static final int FREC = 10000; // as set in signal's parameters
   private static GPSNMEAserial gpsnmea;
  
   private static void mountGPS() {
       try {
           gpsnmea = new GPSNMEAserial(4800,"/dev/ttyUSB0");
       } catch (Exception e) {
           System.out.println("Error reaching gpsnmeaserial");
       }
   }
  
   private static int runLinuxCommand(){
       String s;
       Process p;
       int counter = 0;
       try {
           p = Runtime.getRuntime().exec("sudo iw dev wlan0 scan ");
           BufferedReader br = new BufferedReader(
               new InputStreamReader(p.getInputStream()));
           while ((s = br.readLine()) != null) {
               if(s.contains("SSID")){
               System.out.println("line: " + s);
               counter++;}
           }
           p.waitFor();
           System.out.println ("exit: " + p.exitValue());
           p.destroy();
           return counter;
       } catch (IOException | InterruptedException e) {return counter;}
   }
   protected static void delay(int t) {
       try {   
           Thread.sleep(t);
       } catch(InterruptedException e) {
       }
   }
   public static void main(String[] args) {
       mountGPS();
       CircusLib commands = new CircusLib(TOKEN);
       double lat;
       double lon;
       double alt;
       int nsats;
       double value;
       for (;;) {
           try {
               gpsnmea.receiveUARTData();
           } catch(Exception e){System.out.println("Error reading serial");}
           delay(100);
           value = runLinuxCommand();
           lat = gpsnmea.getLat();
           lon = gpsnmea.getLon();
           alt = gpsnmea.getAlt();
           nsats = gpsnmea.getNsats();
           if (!(lat==0&&lon==0)) {
               System.out.println("Write to Circus: "+KEY);
               System.out.println(lat+" - "+lon+" - "+alt+" - "+nsats);
               JSONObject obj = commands.writeValue(KEY, value, lat, lon, alt);
               System.out.println("Circus response: "+obj.toString());
           }
           delay(FREC);
       }
   }
}

Remember to replace the “key” and “token” from Circus for the “KEY” and “TOKEN” values respectively in the code above.

It can be executed in command line with:

sudo java -cp .:/home/pi/dtest:/home/pi/javalibs/* circusfield.CircusField

Libraries needed to be placed in your libraries folder:

circusofthings.com.jar

jaumemirallesisern-gps.jar

org.json.jar

rxtx-2.1.7.jar

Executing on boot

I do like this because I want to be sure that in the field I just need to power on the raspberry for the data to be gathered.

Place the above execution command in /ect/rc.local

Connecting the GPS

Just plug the GPS receiver in the USB. No further configurations or set up are needed.

Share your cell connection

In your cell share your data connection as a Wifi access point. So you will define a SSID name and a password.

In your Raspberry, connect and check to this SSID normally. You can do it in your Raspbian desktop or via commands. There is plenty of documentation to do this in the net, so I won’t stop on this.

Check it all

If everything goes right the JAVA program CircusField (executed manually or on boot) should throw an output like this:

Execution of JAVA code

And in your Workshop at Circus you should see the same signal you defined but now with value and geolocation changing (it may take some seconds as it needs time to write, time to poll in the app… be patient).

Signal completed

When you are outside you can watch this screen (always selecting the option “request desktop page” in your cell as we don’t have a working responsive version) to see if the values are varying as they should. You can also monitor the track in real-time setting a panel-map as described in next points.

Pack it

I can’t believe I never though about a rigid folder to chase my developments. It’s easy, the excess of cables is tidied up and you can file your gadgets in the shelf. An absolute win-win.

Ready to go

Going for a walk

Walk out the door, greet your neighbours ( a geek is never impolite 😐 ), enjoy the walk, come back…

Back at home

Now you gathered the data, you may want to set up a panel in your dashboard to monitor a handle the data. To do so, follow this simple steps:

Go to dashboard

Again in Circus

Create a panel

Dashboard

Choose add a view

New Panel

Select your signal

Adding view

Change to map mode

SCADA mode

Now that you successfully got the map to display your path, it’s time to recall the samples. Press recall and select the period of time when you went for the walk, and there you have it:

Track plot

Now you can:

  • Label this track for the next time have it easier to recall, pressing “save as”
  • Download it in KML or CSV
  • Share your track on map with other users
  • Among other features

If you want to see my walk, this is the signal. Once you add it to one of your panels recall it with the label I gave to it: “wifi-walk”.

Note: This will a particular case (counting SSIDs / Raspberry / JAVA), but you could use Circus for any value you can measure in the field, with whatever sensor you may think, with any hardware capable to reach the web, with any coding language…

Hope it helped and thanks for reading! Please, let us know your feedback.

Leave a Reply

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