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.
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.
- 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.
- 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).
- 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:
Once inside, go to the “Workshop” where you will create a signal to handle the data:
Create a signal:
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):
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 objectGPSNMEAserial
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
andsudo 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:
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:
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).
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.
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
Create a panel
Choose add a view
Select your signal
Change to map 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:
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.