Map My LTE is a surveying tool for 2G/3G/4G/5G cellular network information using both consumer Android and Firstnet Android devices. Allowing data being recorded and displayed over the heatmaps. The same app platform can be used for surveying air quality, radiation, noise level and many other through IoT add ons.
The current app is ready for LTE/5G survey mapping, it can be directly stored into the firebase and retrieved with heat map using sensors equipped with Android Phone itself. Additionally, we allow custom indoor mapping onto multi floor units.
While we have been successful mapping out the LTE data over the phone sensors, we want to be able to map out additional informations using phone's capability of connectivity, via IoT sensor data.
In this article, we will be using the existing app that we've created to map out the CO2 data around, same method can be used with Air quality sensor, sound sensor, and many others.
Hardware requirements:We would need following to get this work
- Android Phone (So yon download MapMyLTE)
- DFDuino
- DFRobot CO2 sensor
We will be connecting the sensor to DFDuino and CO2 sensor via following
int sensorIn = A1;
void setup(){
Serial.begin(9600);
// Set the default voltage of the reference voltage
analogReference(DEFAULT);
}
void loop(){
//Read voltage
int sensorValue = analogRead(sensorIn);
// The analog signal is converted to a voltage
float voltage = sensorValue*(5000/1024.0);
if(voltage == 0)
{
Serial.println("Fault");
}
else if(voltage < 400)
{
Serial.println("preheating");
}
else
{
int voltage_diference=voltage-400;
float concentration=voltage_diference*50.0/16.0;
// Print Voltage
//Serial.print("voltage:");
//Serial.print(voltage);
//Serial.println("mv");
//Print CO2 concentration
Serial.print(concentration);
Serial.println("ppm");
}
delay(100);
}
When this is done we should have something like this based on ppm
Overall it looks like following
Step 2: Compile Android App for MapMyLTE
We've built out Map My LTE on https://github.com/cbonoz/LTECoverageTool
You can run following command
git clone https://github.com/cbonoz/LTECoverageTool
Once loaded you should have following
Next is to create a firebase database storage via firebase.com
Step 3: Transfer Data from Arduino to Android via USBWe are going to use USB Serial library https://github.com/felHR85/UsbSerial/ to transfer data
Make sure you have
<uses-feature android:name="android.hardware.usb.host"
android:required="true"/>
in your manifest.
/*
* This software was developed by employees of the National Institute of Standards and Technology (NIST), an agency of the Federal Government
* and is being made available as a public service. Pursuant to title 17 United States Code Section 105, works of NIST employees are not
* subject to copyright protection in the United States. This software may be subject to foreign copyright. Permission in the United States
* and in foreign countries, to the extent that NIST may hold copyright, to use, copy, modify, create derivative works, and distribute
* this software and its documentation without fee is hereby granted on a non-exclusive basis, provided that this notice and disclaimer of
* warranty appears in all copies.
*
* THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO,
* ANY WARRANTY THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
* AND FREEDOM FROM INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL
* BE ERROR FREE. IN NO EVENT SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL
* DAMAGES, ARISING OUT OF, RESULTING FROM, OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, CONTRACT, TORT, OR OTHERWISE,
* WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT OF THE RESULTS OF,
* OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER.
*/
package com.lte.mapmylte;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.hardware.usb.UsbDevice;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.lang.ref.WeakReference;
import java.util.Set;
import androidx.appcompat.app.AppCompatActivity;
public class SensorActivity extends AppCompatActivity {
/*
* Notifications from UsbService will be received here.
*/
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case UsbService.ACTION_USB_PERMISSION_GRANTED: // USB PERMISSION GRANTED
Toast.makeText(context, "USB Ready", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_USB_PERMISSION_NOT_GRANTED: // USB PERMISSION NOT GRANTED
Toast.makeText(context, "USB Permission not granted", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_NO_USB: // NO USB CONNECTED
Toast.makeText(context, "No USB connected", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_USB_DISCONNECTED: // USB DISCONNECTED
Toast.makeText(context, "USB disconnected", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_USB_NOT_SUPPORTED: // USB NOT SUPPORTED
Toast.makeText(context, "USB device not supported", Toast.LENGTH_SHORT).show();
break;
}
}
};
private UsbService usbService;
private TextView display;
private MyHandler mHandler;
private final ServiceConnection usbConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
usbService = ((UsbService.UsbBinder) arg1).getService();
usbService.setHandler(mHandler);
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
usbService = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sensor);
mHandler = new MyHandler(this);
display = (TextView) findViewById(R.id.textView1);
}
@Override
public void onResume() {
super.onResume();
setFilters(); // Start listening notifications from UsbService
startService(UsbService.class, usbConnection, null); // Start UsbService(if it was not started before) and Bind it
}
@Override
public void onPause() {
super.onPause();
unregisterReceiver(mUsbReceiver);
unbindService(usbConnection);
}
private void startService(Class<?> service, ServiceConnection serviceConnection, Bundle extras) {
if (!UsbService.SERVICE_CONNECTED) {
Intent startService = new Intent(this, service);
if (extras != null && !extras.isEmpty()) {
Set<String> keys = extras.keySet();
for (String key : keys) {
String extra = extras.getString(key);
startService.putExtra(key, extra);
}
}
startService(startService);
}
Intent bindingIntent = new Intent(this, service);
bindService(bindingIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}
private void setFilters() {
IntentFilter filter = new IntentFilter();
filter.addAction(UsbService.ACTION_USB_PERMISSION_GRANTED);
filter.addAction(UsbService.ACTION_NO_USB);
filter.addAction(UsbService.ACTION_USB_DISCONNECTED);
filter.addAction(UsbService.ACTION_USB_NOT_SUPPORTED);
filter.addAction(UsbService.ACTION_USB_PERMISSION_NOT_GRANTED);
registerReceiver(mUsbReceiver, filter);
}
/*
* This handler will be passed to UsbService. Data received from serial port is displayed through this handler
*/
private static class MyHandler extends Handler {
private final WeakReference<SensorActivity> mActivity;
public MyHandler(SensorActivity activity) {
mActivity = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UsbService.MESSAGE_FROM_SERIAL_PORT:
String data = (String) msg.obj;
mActivity.get().display.append(data);
break;
case UsbService.CTS_CHANGE:
Toast.makeText(mActivity.get(), "CTS_CHANGE",Toast.LENGTH_LONG).show();
break;
case UsbService.DSR_CHANGE:
Toast.makeText(mActivity.get(), "DSR_CHANGE",Toast.LENGTH_LONG).show();
break;
}
}
}
}
With code above we can gather data information from the usb itself transfered through arduino
Now that we have the data from the sensor, we can modify the application to send data along with LTE signal to Firebase. For this sample we will hard code the sensor, in the future when we have more partnerships we will be able to support more sensors.
this.usesensor = false;
this.sensorvalue = -1;
this.sensortype = "Carbon";
this.sensorMetric = "ppm";
Similar to LTE data, we would capture these in another set
SensorCollections= mFirestore.collection("SensorCoordinates/" + Calendar.getInstance().getTime().toString() + "/Carbon");
When user click stop we would be able to capture all the carbon data in addition to LTE data.
Step 6: Partnership with MapMyLTE
For partnership on making sensors please feel free to message us here. Currently DFRobot and arm can produce the sensor and chipset for you.
Comments