geoloc-cellules.ino
Sin GPS, la célula de radio suele bastar: el MKR NB 1500 lee su TAC, identidad de célula y nivel de señal y los envía a un servicio de geolocalización por células. Ideal para seguir un activo fijo o validar cobertura.
Hardware
Una Arduino MKR NB 1500 (microcontrolador SAMD21, módem u-blox LTE-M/NB-IoT, antena externa, alimentación LiPo en J6 o USB). SIM IoT registrada en la red, antena; cuenta gratuita en OpenCelliD para la conversión.
Cableado
Sin cableado; funciona con la placa sola, en movimiento lento (peatón, contenedor).
Funcionamiento
CEREG expone el Tracking Area Code y el CellIdentity de la célula servidora; CESQ detalla RSRP/RSRQ. Estos pares coinciden con las claves de las bases de datos de torres.
Ejecución
Instala el paquete Arduino SAMD Boards y la librería MKRNB, selecciona la placa y carga. Prevé una SIM IoT (LTE-M o NB1) activada y buena recepción: la conexión a la red puede tardar varios minutos.
Variantes
Completa con un escáner de células vecinas (CEREG opción 2) para afinar, o añade un pequeño GPS por I2C cuando la precisión sea crítica.
geoloc-cellules.ino
// Geolocalisation par cellule : LAC/CI + RSSI via le modem SARA-R4.
// Utile quand le GPS n'est pas alimente/couvert : precision 100 m - km.
#include <MKRNB.h>
const char PIN_SIM[] = "0000";
NB nb;
void setup() {
Serial.begin(9600);
while (!Serial);
if (nb.begin(PIN_SIM) != NB_READY) while (true);
while (nb.getStatus() != NETWORK_JOINED) delay(2000);
}
void loop() {
// Le core MKRNB expose l'operateur ; les infos fines de cellule
// passent par les commandes AT dediees du SARA-R4 :
nb.sendCheckConfig("COPS?"); // operateur + MCC/MNC
nb.sendCheckConfig("CEREG?"); // LAC/TAC + CellId enregistree
nb.sendCheckConfig("CESQ?"); // RSSI/RSRP detailles
// CEREG renvoie par ex : +CEREG: 0,1,"812F","0A3B5C2",7
// -> TAC 0x812F, CellID 0x0A3B5C2, niveau 7
// Transmettez ce couple a un service de localisation par cellules
// (OpenCelliD, Google Geolocation) pour obtenir lat/lon.
Serial.print(F("RSSI module : "));
Serial.println(nb.signalQuality());
delay(300000); // un point toutes les 5 min
}