Harun YenisanMehmet Emin Uğur
Published © MIT

Remote Machine Health Monitoring for Predictive Maintenance

Remote Machine Health Monitoring for Predictive Maintenance

IntermediateWork in progress24 hours52
Remote Machine Health Monitoring for Predictive Maintenance

Things used in this project

Hardware components

RAKwireless RAK3372
×1
RAKwireless RAK19003
×1
RAKwireless RAK12027
×1
RAKwireless RAK1906
×1
RAKwireless Battery Connector
×1
Hologram Global IoT SIM Card
Hologram Global IoT SIM Card
×1

Software apps and online services

Arduino IDE
Arduino IDE
Microsoft Azure IoT Hub
Microsoft Azure Stream Analytics
Microsoft Azure Logic Apps
Microsoft Power BI

Hand tools and fabrication machines

Multitool, Screwdriver
Multitool, Screwdriver

Story

Read more

Code

code

Arduino
Remote Machine Health Monitoring for Predictive Maintenance
#include <WisBlock-api.h>      // For RAK WisBlock APIs
#include <TinyGsmClient.h>     // General header for TinyGSM library
#include <TinyGsmClientSIM7600.h> // Header for SIM7600/BG77 modem family used by RAK3372
#include <PubSubClient.h>      // For MQTT communication (with Azure IoT Hub)
#include <Wire.h>              // For I2C communication (for BME680)
#include <Adafruit_Sensor.h>   // Base class for Adafruit sensor libraries
#include <Adafruit_BME680.h>   // For RAK1906 (uses BME680 sensor)

// For RAK12027 Vibration Sensor
// If RAK12027 is a specific accelerometer (e.g., LIS3DH), you'll need to include its library (e.g., Adafruit LIS3DH) and initialize it.
// In this example, a simple analog vibration sensor reading and RMS calculation is shown.
// For a real project, refer to the RAK12027 datasheet or library.
#define VIBRATION_SENSOR_PIN WB_A1 // Example analog pin connected to vibration sensor

// Azure IoT Hub Settings
// These values must be obtained from your Azure IoT Hub and device registration.
const char* IOT_HUB_HOSTNAME = "YOUR_IOT_HUB_NAME.azure-devices.net"; // <<< CHANGE THIS
const char* DEVICE_ID = "YourMachineMonitorDevice"; // <<< CHANGE THIS (Unique device ID)
// SAS Token: Shared Access Signature (SAS) token generated for your Azure IoT Hub device.
// You need to securely generate and manage this token. It is often renewed by a cloud function.
const char* SAS_TOKEN = "SharedAccessSignature sr=YOUR_SHARED_ACCESS_SIGNATURE"; // <<< CHANGE THIS
const char* MQTT_USER = IOT_HUB_HOSTNAME "/" DEVICE_ID "/api-version=2021-04-12"; // Azure IoT Hub MQTT username
const char* MQTT_PASS = SAS_TOKEN; // Azure IoT Hub MQTT password (SAS token)
const char* MQTT_TOPIC = "devices/" DEVICE_ID "/messages/events/"; // Telemetry data sending topic

// GPRS connection information
const char apn[]  = "YOUR_APN";       // <<< CHANGE THIS (Your mobile operator's APN)
const char gprsUser[] = "";           // APN username (usually left blank)
const char gprsPass[] = "";           // APN password (usually left blank)

// Hardware Objects
TinyGsm modem(Serial1); // Serial port for RAK3372 modem (UART1)
TinyGsmClient client(modem); // TinyGSM client (TCP connection via modem)
PubSubClient mqttClient(client); // MQTT client

Adafruit_BME680 bme; // RAK1906 (BME680) environmental sensor object

// Timer Variables
long lastSendTime = 0;
const long sendInterval = 60000; // Data transmission interval: 1 minute (60 * 1000 ms)

void setup() {
  // Start serial communication (for debug messages)
  Serial.begin(115200);
  while (!Serial); // Wait for serial port to be ready
  Serial.println("Machine Health Monitoring Starting...");

  // Set vibration sensor pin as input
  pinMode(VIBRATION_SENSOR_PIN, INPUT);

  // Initialize RAK1906 (BME680) sensor
  Wire.begin(); // Start I2C communication
  if (!bme.begin(0x76)) { // I2C address is typically 0x76 or 0x77.
    Serial.println("RAK1906 BME680 not found, check connection!");
    while (1); // Stay in infinite loop if initialization fails
  }
  // Temperature oversampling setting for BME680
  bme.setTemperatureOversampling(BME680_OS_8X);
  Serial.println("RAK1906 BME680 successfully initialized.");

  // Initialize RAK3372 modem
  Serial1.begin(115200); // Set UART1 speed for RAK3372
  delay(100); // Small delay for modem to start
  Serial.println("Modem initializing...");
  modem.restart(); // Restart modem
  Serial.print("Modem Info: ");
  Serial.println(modem.getModemInfo()); // Get modem information

  // Try to connect to GPRS network
  Serial.print("Connecting to GPRS network...");
  if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
    Serial.println("GPRS connection failed! Please check APN settings and SIM card.");
    while (true); // Stay in infinite loop if connection fails
  }
  Serial.println("GPRS connection successful!");

  // Set MQTT Callback (for Cloud-to-Device (C2D) messages)
  mqttClient.setCallback(mqttCallback);
  // Set MQTT server connection details (Azure IoT Hub)
  mqttClient.setServer(IOT_HUB_HOSTNAME, 8883); // TLS port for Azure IoT Hub is typically 8883

  connectMqtt(); // Try to connect to MQTT broker
  lastSendTime = millis(); // Initialize timer
}

void loop() {
  modem.maintainConnections(); // Keep GPRS connection active
  
  // Run MQTT client loop (to send and receive messages)
  if (!mqttClient.connected()) {
    connectMqtt(); // Try to reconnect if disconnected
  }
  mqttClient.loop();

  // Check if it's time to send data
  if (millis() - lastSendTime > sendInterval) {
    sendData();       // Send sensor data
    lastSendTime = millis(); // Reset timer
  }
}

// Function to manage connecting to MQTT broker
void connectMqtt() {
  Serial.print("Connecting to MQTT...");
  // Stay in loop until connection is successful
  while (!mqttClient.connected()) {
    // Connect to MQTT with device ID, username, and password (SAS token)
    // Username and password are in the format required by Azure IoT Hub.
    if (mqttClient.connect(DEVICE_ID, MQTT_USER, MQTT_PASS)) {
      Serial.println("connected.");
      // Subscribe to the relevant topic for Cloud-to-Device (C2D) messages
      mqttClient.subscribe("devices/" DEVICE_ID "/messages/devicebound/#"); 
    } else {
      Serial.print("failed, rc=");
      Serial.print(mqttClient.state()); // Print error code
      Serial.println(" trying again in 5 seconds");
      delay(5000); // Wait before retrying
    }
  }
}

// Callback function to process incoming messages (downlink) via MQTT
void mqttCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message Received from Cloud - Topic: ");
  Serial.println(topic);
  Serial.print("Message: ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
  // You can add code here to make the device (e.g., relay, LED) react to incoming commands.
}

// Function to collect sensor data and send it to Azure IoT Hub
void sendData() {
  // Get temperature reading from RAK1906
  bme.performReading();
  float temperature = bme.temperature; // Temperature value

  // Read vibration data and calculate RMS value (simple example)
  // For a real vibration sensor (RAK12027), more advanced signal processing or
  // direct use of data provided by the sensor might be necessary.
  int numSamples = 100; // Number of samples
  long sumSq = 0;      // Sum of squares
  for (int i = 0; i < numSamples; i++) {
    int rawValue = analogRead(VIBRATION_SENSOR_PIN); // Read analog vibration value
    sumSq += (long)rawValue * rawValue; // Sum their squares
    delay(1); // Small delay between readings
  }
  float rmsVibration = sqrt((float)sumSq / numSamples); // Calculate RMS (Root Mean Square)

  // Print read data to Serial Monitor
  Serial.printf("Temperature: %.2f C, RMS Vibration: %.2f\n", temperature, rmsVibration);

  // Create a JSON formatted payload
  // This format can be easily processed by Azure IoT Hub.
  String jsonPayload = "{\"temperature\":";
  jsonPayload += String(temperature, 2); // 2 decimal places
  jsonPayload += ",\"rms_vibration\":";
  jsonPayload += String(rmsVibration, 2); // 2 decimal places
  jsonPayload += "}";

  Serial.print("Sending Data: ");
  Serial.println(jsonPayload);

  // Publish the created JSON payload to the relevant topic in Azure IoT Hub
  if (mqttClient.publish(MQTT_TOPIC, jsonPayload.c_str())) {
    Serial.println("Data successfully sent to Azure IoT Hub.");
  } else {
    Serial.println("Data sending failed!");
  }
}

Credits

Harun Yenisan
8 projects • 7 followers
Electronic engineer, working as an IT teacher at the Ministry of National Education.
Mehmet Emin Uğur
9 projects • 9 followers
Computer engineer, working as an IT teacher at the Ministry of National Education.

Comments