MineSight: Rover for Open-Cast Mining
by SiyaArora26 in Circuits > Robots
21 Views, 0 Favorites, 0 Comments
MineSight: Rover for Open-Cast Mining
Opencast coal mining involves continuous movement of heavy machinery, including haul trucks, dumpers, excavators and support vehicles. These operations may involve safety risks such as vehicle collisions, restricted visibility during night shifts, obstacles along transport routes and hazardous gases associated with blasting activities.
MineSight is an embedded systems project designed to investigate these challenges through a mobile robotic platform that combines sensor-based hazard detection, movement monitoring and Internet of Things (IoT) technologies.
The project uses an Arduino Nano 33 IoT for sensor acquisition and motor control, together with a Raspberry Pi 4 for higher-level processing, visual monitoring, communication and data management.
The sensing system consists of:
- An HC-SR04 ultrasonic sensor for detecting obstacles in the rover's forward path.
- An MQ-7 carbon monoxide sensor for experimental monitoring of CO, one of the gases that can be produced during blasting.
- Two LM393 optical wheel encoder sensors for estimating wheel rotation, speed and movement.
- The Arduino's built-in accelerometer and gyroscope for monitoring motion and orientation.
- A Raspberry Pi camera for remote visual observation of the experimental environment.
The proposed software architecture uses MQTT for transferring monitoring data, Firebase for cloud-based historical records and webhooks for transmitting selected safety notifications. A graphical user interface allows observations, warnings and recorded events to be reviewed.
The initial development focuses on obstacle detection and motor stopping, followed by the integration and testing of the additional sensors and IoT functions.
This tutorial explains the hardware design, connections, programming, communication architecture and testing methodology for MineSight.
Supplies
Hardware Components
1. Arduino Nano 33 IoT
The primary microcontroller responsible for collecting sensor measurements, monitoring movement and controlling the rover's motors. Its built-in inertial measurement unit (IMU) provides acceleration and angular-velocity measurements.
2. Raspberry Pi 4
Used for high-level processing, communication, local data storage and hosting the monitoring interface. It receives telemetry from the Arduino over a USB serial connection.
3. L298N Motor Driver
Controls the direction and speed commands sent to the DC motors. The motor driver's current and temperature limits must be checked against the connected motors.
4. Four-Wheel-Drive Robotic Chassis
Provides the mechanical platform for MineSight, including four DC gear motors and wheels.
5. HC-SR04 Ultrasonic Sensor
Measures the distance to an object in front of the rover, supporting local obstacle detection and automatic stopping.
6. MQ-7 Carbon Monoxide Gas Sensor
Provides a gas-sensitive analog signal for experimental CO monitoring. Accurate CO concentration measurements require a suitable heater-control circuit, calibration and validation.
7. Two LM393 Wheel Encoder Sensors
Read pulses from the wheel encoder discs to estimate rotation and movement.
8. Raspberry Pi Camera Module
Supports visual monitoring of the simulated mining area. Camera-based nighttime observation requires suitable low-light capability or additional illumination.
9. Power Supply
A suitable protected battery arrangement, regulated power converters, switch and fuse are required to supply the motors and electronics safely.
Software Requirements
- Arduino IDE
- Arduino Nano 33 IoT board package
- Arduino_LSM6DS3 library
- Python 3 on Raspberry Pi OS
- PySerial library
- Paho MQTT Python library
- Firebase Admin SDK
- Python-based monitoring GUI
- A configured MQTT broker
Make the Required Connections
The Arduino Nano 33 IoT acts as the central controller of MineSight. It receives input from the sensors and controls motor movement through the L298N motor driver.
L298N Motor Driver Connections
L298N Pin - Arduino Nano 33 IoT
ENA - D5
IN1 - D2
IN2 - D3
IN3 - D7
IN4 - D8
ENB - D6
The two left-side motors are connected to one motor-driver channel, while the two right-side motors are connected to the other. The combined current requirement must remain within the motor driver's safe operating limits.
HC-SR04 Ultrasonic Sensor
Sensor Pin Connection
VCC - Regulated 5V
GND - Common GND
TRIG - D11
ECHO - D12
The ultrasonic sensor operates using sound-wave reflection. The Arduino sends a trigger pulse, measures the returning echo and calculates the distance to an object.
MQ-7 Gas Sensor
MQ-7 Pin Connection
VCC - Appropriate 5V supply
GND - Common GND
AO - A0
The MQ-7 is sensitive to carbon monoxide. It is included as an experimental sensor for investigating a gas associated with some blasting operations.
Reliable CO measurements require proper heater cycling, calibration and evaluation of interference from other gases. The inexpensive MQ-7 breakout is not a certified mine gas detector.
LM393 Wheel Encoder Sensors
Encoder Arduino Pin
Left encoder OUT - D9
Right encoder OUT - D10
VCC - 3.3V
GND - Common GND
The encoder readers detect pulses generated when the slotted encoder discs rotate. These pulses can be used to estimate wheel speed and movement.
Setting Up Firebase for Data Storage
Firebase is included to maintain remotely accessible historical monitoring records.
While the Arduino collects measurements, the Raspberry Pi organises the received information and uploads selected data to a Firebase database.
Setting Up Firebase
- Visit the Firebase Console at https://console.firebase.google.com.
- Create a new project named MineSight.
- Open the Firestore Database section.
- Create a database in a suitable region.
- Configure database access and authentication.
- Install the Firebase Admin SDK on the Raspberry Pi.
- Configure secure credentials for the Pi application.
Data Stored in Firebase
Data - Purpose
Timestamp - Identify when the observation occurred
Rover ID - Identify the reporting device
Obstacle distance - Record nearby-object measurements
Wheel encoder pulses - Track wheel movement
Estimated speed - Analyse vehicle movement
IMU measurements - Record acceleration and orientation-related motion
MQ-7 analog output - Record experimental gas sensor observations
Safety event - Identify warnings and motor-stop events
Sensor status - Identify disconnected or unreliable sensors
Operating condition - Distinguish daytime, nighttime and controlled test scenarios
A unique experiment or event identifier allows records to be associated with individual tests.
Firebase is used for remote monitoring and historical analysis, not for making immediate motor-stopping decisions.
Setting Up MQTT Communication Using Node-RED
MineSight uses MQTT (Message Queuing Telemetry Transport) and Node-RED to enable real-time communication, processing and visualisation of sensor data.
Node-RED is a flow-based programming platform that allows different hardware devices, communication services and applications to be connected using a visual interface.
In this project, the Arduino Nano 33 IoT collects measurements from the ultrasonic sensor, MQ-7 gas sensor, wheel encoders and built-in IMU. The measurements are sent to the Raspberry Pi 4 through USB serial communication.
The Raspberry Pi publishes these readings to an MQTT broker, while Node-RED subscribes to the relevant MQTT topics to process and display the information.
Setting Up Node-RED
- Install Node-RED on the Raspberry Pi 4 using the official Raspberry Pi installation instructions.
- Install and configure an MQTT broker
- Start Node-RED and open its editor at http://localhost:1880.
- Create a new flow for MineSight sensor monitoring.
- Add an MQTT Input node and configure it to connect to the broker.
- Subscribe to the required MineSight MQTT topics.
- Add a JSON node to convert incoming messages into structured data.
- Connect Debug, Switch, Function and dashboard nodes as required.
- Deploy the flow and verify that published sensor readings appear correctly.
MQTT Topics Used in MineSight
MQTT Topic - Purpose
minesight/rover01/telemetry - General sensor readings and rover status
minesight/rover01/obstacle - Ultrasonic distance measurements
minesight/rover01/gas - Experimental MQ-7 sensor data
minesight/rover01/motion - Wheel encoder and IMU measurements
minesight/rover01/alerts - Obstacle-stop events and system warnings
minesight/rover01/health - Sensor availability and communication status
Only topics actually published by the Raspberry Pi will receive data. Separate topics can be added as individual sensing functions are integrated.
Creating the Node-RED Flow
The basic MineSight monitoring flow consists of:
MQTT Input → JSON → Function / Switch → Dashboard / Alerts
The MQTT Input node receives sensor readings published by the Raspberry Pi.
The JSON node converts the received message into a format that can be processed by the other nodes.
Function and Switch nodes are used to evaluate selected readings and route messages according to their contents.
The dashboard nodes provide a visual representation of sensor readings, system status and alerts.
Safety Alerts Using Node-RED
Node-RED can be configured to respond to specific events, including:
- An obstacle-stop event detected by the Arduino.
- An invalid or disconnected sensor.
- An abnormal wheel movement condition.
- A simulated elevated-gas warning.
- Loss of expected telemetry from the rover.
For example, when the Arduino reports that the rover has stopped because of an obstacle, Node-RED can display a warning and record the event.
If an external notification is required, Node-RED can send an HTTPS request using an HTTP Request node.
The Arduino stops the motor immediately locally, rather than relying on the MQTT broker or Node-RED.
Programming the Arduino Nano 33 IoT
The Arduino is programmed using the Arduino IDE.
The embedded program is responsible for collecting local sensor data and controlling the motors without depending on an internet connection.
A. Ultrasonic Obstacle Detection
The HC-SR04 measures the distance to an object in front of the rover.
The prototype uses a configurable stopping threshold, initially tested at approximately 25 cm.
When an obstacle enters the configured range, the Arduino commands the motor driver to stop.
A measurement timeout is also used so that an absent ultrasonic echo is not incorrectly interpreted as a clear path.
B. Motor Control
The Arduino controls the L298N motor driver using the defined digital and PWM pins.
Basic functions include:
- Moving the rover forward
- Stopping the motors
- Responding to a detected obstacle
- Limiting motor runtime during testing
C. Wheel Encoder Monitoring
The wheel encoder readers produce pulses as their respective encoder discs rotate.
The Arduino can use interrupts to count pulses without repeatedly checking the encoder outputs.
The pulse counts provide information about wheel rotation. With a known pulse count per revolution and wheel circumference, the system can estimate rotational speed and travelled distance.
D. MQ-7 Sensor Reading
The Arduino samples the analog output from the MQ-7 module.
The reading is recorded as an experimental gas-sensor value. Converting this into reliable carbon monoxide concentration requires appropriate sensor operation and calibration.
E. Serial Communication
The Arduino periodically sends measurement records to the Raspberry Pi.
The records include the latest available measurements, data validity indicators and motor status.
The Arduino also monitors safety conditions locally so that an internet failure does not prevent the rover from stopping.
Arduino IDE Code
#include <Arduino_LSM6DS3.h>
const int ENA = 5, IN1 = 2, IN2 = 3;
const int IN3 = 7, IN4 = 8, ENB = 6;
const int TRIG = 11, ECHO = 12;
const int MQ7 = A0, LEFT_ENC = 9, RIGHT_ENC = 10;
volatile unsigned long leftPulses = 0;
volatile unsigned long rightPulses = 0;
bool armed = false;
bool distanceValid = false;
bool imuValid = false;
float distanceCm = 0;
unsigned long startTime = 0;
unsigned long lastDistanceRead = 0;
unsigned long lastReport = 0;
void leftPulse() { leftPulses++; }
void rightPulse() { rightPulses++; }
void stopMotors() {
analogWrite(ENA, 0);
analogWrite(ENB, 0);
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
}
void forward() {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(ENA, 140);
analogWrite(ENB, 140);
}
void readObstacle() {
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
unsigned long echoUs = pulseIn(ECHO, HIGH, 25000UL);
distanceValid = echoUs > 0;
if (distanceValid) {
distanceCm = echoUs * 0.0343f / 2.0f;
}
// Stop and require a new start command if data is unsafe.
if (!distanceValid || distanceCm <= 25.0f) {
armed = false;
}
}
void setup() {
Serial.begin(115200);
int outputs[] = {ENA, IN1, IN2, IN3, IN4, ENB, TRIG};
for (int p : outputs) pinMode(p, OUTPUT);
pinMode(ECHO, INPUT);
pinMode(LEFT_ENC, INPUT_PULLUP);
pinMode(RIGHT_ENC, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(LEFT_ENC),
leftPulse, RISING);
attachInterrupt(digitalPinToInterrupt(RIGHT_ENC),
rightPulse, RISING);
analogReadResolution(12);
imuValid = IMU.begin();
stopMotors();
}
void loop() {
unsigned long now = millis();
while (Serial.available()) {
char command = Serial.read();
if (command == 'g') {
armed = true;
startTime = now;
}
if (command == 's') {
armed = false;
}
}
if (now - lastDistanceRead >= 100) {
lastDistanceRead = now;
readObstacle();
}
if (armed && now - startTime >= 15000UL) {
armed = false;
}
bool moving = armed && distanceValid &&
distanceCm > 25.0f &&
now - lastDistanceRead < 200;
if (moving) forward();
else stopMotors();
if (now - lastReport >= 500) {
lastReport = now;
noInterrupts();
unsigned long left = leftPulses;
unsigned long right = rightPulses;
interrupts();
float ax = 0, ay = 0, az = 0;
float gx = 0, gy = 0, gz = 0;
bool accelReady = imuValid && IMU.accelerationAvailable();
bool gyroReady = imuValid && IMU.gyroscopeAvailable();
if (accelReady) IMU.readAcceleration(ax, ay, az);
if (gyroReady) IMU.readGyroscope(gx, gy, gz);
Serial.print("{\"time_ms\":");
Serial.print(now);
Serial.print(",\"distance_cm\":");
if (distanceValid) Serial.print(distanceCm, 2);
else Serial.print("null");
Serial.print(",\"mq7_raw_adc\":");
Serial.print(analogRead(MQ7));
Serial.print(",\"left_pulses\":");
Serial.print(left);
Serial.print(",\"right_pulses\":");
Serial.print(right);
Serial.print(",\"imu_valid\":");
Serial.print(accelReady && gyroReady ? "true" : "false");
Serial.print(",\"ax_g\":");
if (accelReady) Serial.print(ax, 3);
else Serial.print("null");
Serial.print(",\"gyro_x_dps\":");
if (gyroReady) Serial.print(gx, 2);
else Serial.print("null");
Serial.print(",\"motor_command\":\"");
Serial.print(moving ? "FORWARD" : "STOP");
Serial.println("\"}");
}
}
Raspberry Pi Integration and Data Processing
Raspberry Pi, MQTT, Node-RED and Firebase Integration
The Raspberry Pi 4 acts as the main processing and communication unit for MineSight. It receives sensor readings from the Arduino Nano 33 IoT through USB serial communication and processes the incoming data using Python.
The Raspberry Pi stores sensor measurements and system events locally using SQLite. Selected measurements are published to an MQTT broker using the Paho MQTT library.
Node-RED subscribes to the MQTT topics and processes the received messages to display real-time information, monitor system status and generate selected alerts.
Firebase Firestore is used to maintain historical monitoring records. The Raspberry Pi can synchronise locally stored data with Firebase when network connectivity is available.
This architecture separates real-time motor control, data transmission, visual monitoring and historical storage, supporting modularity and fault tolerance.
Data flow:
Sensors → Arduino Nano 33 IoT → Raspberry Pi 4 → MQTT Broker → Node-RED → Dashboard and Alerts
Raspberry Pi → SQLite → Firebase Firestore (historical records)
Raspberry Pi Code:
import os
import json
import sqlite3
import serial
import requests
import paho.mqtt.client as mqtt
from datetime import datetime, timezone
import firebase_admin
from firebase_admin import firestore
# Change the serial port to match your Raspberry Pi.
arduino = serial.Serial("/dev/ttyACM0", 115200, timeout=1)
# Local database
db = sqlite3.connect("minesight.db")
db.execute("""
CREATE TABLE IF NOT EXISTS telemetry (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp_utc TEXT,
payload TEXT
)
""")
db.commit()
# MQTT broker running locally on the Raspberry Pi
mqtt_client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
mqtt_client.connect("localhost", 1883, 60)
mqtt_client.loop_start()
# Configure GOOGLE_APPLICATION_CREDENTIALS securely.
firebase_admin.initialize_app()
cloud_db = firestore.client()
# Store this URL in an environment variable, never in public code.
webhook_url = os.getenv("MINESIGHT_WEBHOOK_URL")
previous_stop_reason = None
while True:
try:
line = arduino.readline().decode("utf-8").strip()
if not line:
continue
record = json.loads(line)
record["timestamp_utc"] = (
datetime.now(timezone.utc).isoformat()
)
record["rover_id"] = "MS-01"
record["data_origin"] = "MEASURED_RAW"
# Preserve original data first.
db.execute(
"INSERT INTO telemetry(timestamp_utc, payload) VALUES (?, ?)",
(record["timestamp_utc"], json.dumps(record))
)
db.commit()
# Publish live telemetry.
try:
mqtt_client.publish(
"minesight/rover01/telemetry",
json.dumps(record),
qos=1
)
except Exception as error:
print("MQTT unavailable:", error)
# Upload to Firestore when the network is available.
try:
cloud_db.collection("telemetry").add(record)
except Exception as error:
print("Cloud upload pending:", error)
# Event notification (example only).
obstacle = (
record.get("distance_cm") is not None
and record["distance_cm"] <= 25
)
current_reason = "OBSTACLE" if obstacle else None
if current_reason and current_reason != previous_stop_reason:
if webhook_url:
try:
requests.post(
webhook_url,
json={
"event": "OBSTACLE_STOP",
"rover_id": "MS-01",
"timestamp": record["timestamp_utc"]
},
timeout=5
)
except requests.RequestException as error:
print("Webhook unavailable:", error)
previous_stop_reason = current_reason
except (ValueError, UnicodeDecodeError) as error:
print("Invalid sensor record:", error)
Raspberry Pi Camera and Monitoring Dashboard
The Raspberry Pi camera is included for visual observation of the simulated mining environment.
The camera provides additional context for understanding rover movement, obstacle encounters and experimental conditions.
Camera Monitoring
The camera can be used to:
- Observe the rover's movement.
- View objects in the testing area.
- Record visual evidence associated with an experiment.
- Support analysis of obstacle encounters.
- Compare observations in different lighting conditions.
Monitoring Dashboard
A Python-based GUI can be used to display real-time and historical MineSight data.
Proposed Dashboard Sections
1. Live Rover Status
Displays whether the rover is moving, stopped or reporting a fault.
2. Obstacle Monitoring
Displays the most recent ultrasonic distance measurement and obstacle-stop status.
3. Vehicle Movement Monitoring
Displays encoder pulse counts, estimated speed and relevant IMU readings.
4. Gas Monitoring
Displays the MQ-7 sensor's raw output, measurement status and any separately simulated gas-warning events.
5. Camera View
Displays the available camera image or video stream.
6. Incident History
Allows users to review previous warnings, sensor faults and stopping events.
7. System Health
Displays communication availability, sensor errors and data synchronisation status.
Historical Data Analysis
Historical records can be used to create graphs showing:
- Obstacle distance versus time
- Rover speed versus time
- Wheel pulse counts
- MQ-7 output versus time
- Safety-event frequency
- Communication interruptions
The purpose of the dashboard is to make observations and embedded-system responses easier to understand, test and analyse.
Final Assembly, Testing and Future Improvements
The MineSight hardware is assembled onto a four-wheel-drive chassis with sensors positioned according to their functions.
The HC-SR04 is mounted at the front for obstacle detection. The wheel encoder readers are positioned beside the rotating encoder discs, while the Arduino and motor driver are secured to the chassis.
The MQ-7 should be mounted in a suitable location that allows representative air sampling while protecting the heated sensor and surrounding components. Sampling location, airflow, sensor warm-up and calibration all affect the interpretation of readings.
The Raspberry Pi and camera are positioned to support data processing and visual monitoring.
Experimental Testing
The final system will be evaluated using controlled laboratory scenarios representing selected opencast coal-mining hazards.
Test 1: Obstacle Detection
Move the rover towards an obstacle and record the measured distance, stopping response and outcome.
Test 2: Model Vehicle Encounter
Place another miniature vehicle in the rover's direction of travel to demonstrate local vehicle-obstacle detection and stopping.
Test 3: Nighttime Operation
Repeat obstacle-detection tests under reduced illumination and compare the measurements and stopping behaviour against normal lighting.
Test 4: Wheel Speed and Movement
Record encoder pulses at different motor commands and compare the movement estimates with measured travel distances.
Test 5: Gas Sensor Integration
Record MQ-7 output under safe ambient conditions. Use a clearly labelled simulated gas event to evaluate alert handling. Actual CO measurement accuracy requires supervised calibration and validation.
Test 6: Data Storage and Communication
Confirm that sensor records reach the Raspberry Pi, are stored locally and are transmitted through MQTT.
Test 7: Cloud and Webhook Operation
Verify that selected records appear in Firebase and that a configured test event triggers the external notification.
Test 8: Fault Tolerance
Disconnect a non-critical sensor or interrupt network connectivity to evaluate error reporting, local record retention and recovery.
Project Limitations
MineSight is a laboratory-scale prototype. The initial ultrasonic sensor detects objects only within its effective sensing region and does not identify every nearby vehicle.
The MQ-7 is an experimental CO sensor, not a certified post-blast gas detector, and it does not detect NO₂ specifically.
Wheel encoder measurements may be affected by slip, while visual observations depend on camera capability and lighting.
Industrial deployment would require validated sensing technologies, appropriate electrical protection, rugged hardware, mine-specific operational assessment and applicable safety certification.
Future Improvements
Future development may include:
- Improved multi-directional vehicle detection
- Validated vehicle-to-vehicle collision-risk assessment
- Enhanced nighttime sensing
- Dedicated NO₂ sensing for post-blast investigations
- More advanced local positioning
- Improved sensor calibration and diagnostics
- Automated inspection reports and long-term data analysis
Conclusion
MineSight brings together embedded systems, mobile robotics, environmental sensing and IoT communication to investigate selected safety challenges relevant to opencast coal mines.
The project combines local obstacle detection and motor control with an architecture for movement monitoring, experimental gas sensing, visual observation and historical data storage.
By separating real-time embedded control from higher-level monitoring and communication, MineSight provides a foundation for further experiments in reliable mine-safety assistance.
The system is intended for educational research and controlled demonstrations rather than direct deployment as an industrial mine-safety device.
References
- Arduino Nano 33 IoT Documentation: https://store.arduino.cc/products/arduino-nano-33-iot
- Arduino LSM6DS3 Library: https://docs.arduino.cc/libraries/arduino_lsm6ds3/
- Raspberry Pi Camera Documentation: https://www.raspberrypi.com/documentation/accessories/camera-software.html
- Firebase Documentation: https://firebase.google.com/docs/firestore/quickstart
- Eclipse Paho MQTT Documentation: https://eclipse.dev/paho/clients/python/docs/