This project creates a Smart Equipment Vibration & Tilt Monitor to be attached to machines, lab benches, or structures. It detects:
Seismic/vibration intensity and quake alarms using RAK12027 (D7S)
Acceleration and orientation using RAK12033 (IMU)
This combines ideas from:
Vibration & safety monitoring with RAK12027:https://www.hackster.io/user2702447/rak12027-guide-vibration-sensing-for-safety-monitoring-0e3889
Motion/orientation tracking with RAK12033:https://www.hackster.io/user2702447/rak12033-motion-monitoring-76f349
The node sends vibration and tilt data over LoRaWAN (RAK4631) to The Things Network (TTN) and forwards it to Ubidots for dashboards and alerting.
ObjectivesBuild a WisBlock-based vibration and tilt monitoring node.
Measure seismic intensity and vibration events (RAK12027).
Measure acceleration/tilt for machine movement (RAK12033).
Encode these values into a compact LoRaWAN payload.
Use TTN + Ubidots to visualize vibration history and trigger alerts.
Target LevelIntermediate:
Makers, students, and engineers who already worked with WisBlock + TTN, as in:https://www.hackster.io/user2702447/getting-started-with-wisblock-and-the-things-network-ttn-0a7b84
Prerequisite KnowledgeArduino IDE basics (board selection, compile, upload)
I²C sensor basics
LoRaWAN concepts: DevEUI, JoinEUI/AppEUI, AppKey
Reading Serial Monitor output
Required Materials & SoftwareHardware1 × RAK4631 WisBlock Core
1 × RAK19007 WisBlock Base Board
1 × RAK12027 seismic/vibration sensor– from: https://www.hackster.io/user2702447/rak12027-guide-vibration-sensing-for-safety-monitoring-0e3889
1 × RAK12033 6-axis motion sensor (IMU)– from: https://www.hackster.io/user2702447/rak12033-motion-monitoring-76f349
1 × LoRaWAN gateway (e.g. WisGate Edge Lite 2)
1 × LoRa antenna
1 × USB-C cable
Optional: enclosure + mounting hardware for attaching to a machine or structure
Software / Online ServicesArduino IDE
WisBlock board support, as in:https://www.hackster.io/user2702447/getting-started-with-wisblock-and-the-things-network-ttn-0a7b84
Arduino libraries:
RAK12027 D7S library (same one used in your RAK12027 project)– project ref: https://www.hackster.io/user2702447/rak12027-guide-vibration-sensing-for-safety-monitoring-0e3889
RAK12033 IMU library (same one used in your RAK12033 project)– project ref: https://www.hackster.io/user2702447/rak12033-motion-monitoring-76f349
The Things Network / The Things Stack
Ubidots account for dashboards & alerts– integration pattern: https://www.hackster.io/user2702447/set-up-ttn-webhooks-integrate-with-ubidots-a-guide-b715d9
Estimated DurationApprox. 2–3 hours including assembly, firmware, TTN + Ubidots setup, and tests.
Learning OutcomesParticipants will:
Assemble a WisBlock vibration + motion monitoring node.
Read vibration intensity and earthquake state from RAK12027.
Read acceleration and tilt from RAK12033.
Encode the data into a binary LoRaWAN payload and decode it in TTN.
Visualize vibration/tilt data and configure alerts in Ubidots.
Steps for Configuration & ImplementationStep 1 – Hardware AssemblyMount RAK4631 onto the RAK19007 base board.
Plug RAK12027 into the correct WisBlock slot as shown in your D7S project:https://www.hackster.io/user2702447/rak12027-guide-vibration-sensing-for-safety-monitoring-0e3889
Plug RAK12033 into the appropriate slot as you did in:https://www.hackster.io/user2702447/rak12033-motion-monitoring-76f349
Attach the LoRa antenna.
Connect the USB-C cable to your PC.
Step 2 – Arduino IDE & BoardsSame as your WisBlock + TTN setup:https://www.hackster.io/user2702447/getting-started-with-wisblock-and-the-things-network-ttn-0a7b84
Open Arduino IDE.
Make sure the WisBlock board support is installed.
Select the RAK4631 board and the right COM port.
Step 3 – Install LibrariesUse Sketch → Include Library → Manage Libraries… and install:
The RAK12027 D7S library you used in:https://www.hackster.io/user2702447/rak12027-guide-vibration-sensing-for-safety-monitoring-0e3889
The RAK12033 IMU library you used in:https://www.hackster.io/user2702447/rak12033-motion-monitoring-76f349
(If you previously installed them by ZIP, they’re already available in Arduino IDE.)
Step 4 – Full Arduino Sketch (Sensors + Payload)This sketch:
Initializes RAK12027 and RAK12033
Reads seismic intensity & earthquake state from RAK12027
Reads acceleration from RAK12033
Encodes a 16-byte payload
Prints both values and hex payload (ready to plug into your LoRaWAN sketch)
LoRaWAN sending is left to your existing TTN project:https://www.hackster.io/user2702447/getting-started-with-wisblock-and-the-things-network-ttn-0a7b84
#include <Arduino.h>
#include <Wire.h>
// Include the same libraries you used in your original projects
// RAK12027 (D7S) and RAK12033 (IMU)
// For example:
// #include <RAK_D7S.h> // Example name for RAK12027 library
// #include <RAK_IIM42652.h> // Example name for RAK12033 IMU library
// Replace these includes with the *actual* ones you used in:
// - https://www.hackster.io/user2702447/rak12027-guide-vibration-sensing-for-safety-monitoring-0e3889
// - https://www.hackster.io/user2702447/rak12033-motion-monitoring-76f349
// Here we'll assume generic class names:
#include <RAK_D7S.h>
#include <RAK_IIM42652.h>
// --------- Sensor objects ----------
RAK_D7S d7s;
RAK_IIM42652 imu;
// Data structure
struct SensorData {
float si; // Seismic Intensity
float pga; // Peak Ground Acceleration or similar metric
uint8_t quake; // Earthquake detected flag
float accX; // g
float accY; // g
float accZ; // g
};
SensorData data;
// ------------- Helpers for payload --------------
void putInt16(uint8_t *buf, int16_t value, uint8_t index) {
buf[index] = (uint8_t)((value >> 8) & 0xFF);
buf[index + 1] = (uint8_t)(value & 0xFF);
}
void putUInt16(uint8_t *buf, uint16_t value, uint8_t index) {
buf[index] = (uint8_t)((value >> 8) & 0xFF);
buf[index + 1] = (uint8_t)(value & 0xFF);
}
// Payload layout (16 bytes):
// 0–1: si * 100 -> uint16
// 2–3: pga * 100 -> uint16
// 4: quake flag -> uint8 (stored in high byte)
// 5: reserved -> uint8
// 6–7: accX * 1000 -> int16
// 8–9: accY * 1000 -> int16
// 10–11: accZ * 1000 -> int16
// 12–15: reserved (0)
void encodePayload(uint8_t *buffer, const SensorData &d) {
uint16_t si_scaled = (uint16_t)(d.si * 100.0f);
uint16_t pga_scaled = (uint16_t)(d.pga * 100.0f);
int16_t ax_scaled = (int16_t)(d.accX * 1000.0f);
int16_t ay_scaled = (int16_t)(d.accY * 1000.0f);
int16_t az_scaled = (int16_t)(d.accZ * 1000.0f);
putUInt16(buffer, si_scaled, 0);
putUInt16(buffer, pga_scaled, 2);
// quake flag in byte 4, byte 5 reserved
buffer[4] = d.quake;
buffer[5] = 0;
putInt16(buffer, ax_scaled, 6);
putInt16(buffer, ay_scaled, 8);
putInt16(buffer, az_scaled, 10);
buffer[12] = 0;
buffer[13] = 0;
buffer[14] = 0;
buffer[15] = 0;
}
// ------------- Init sensors ----------------
bool initSensors() {
bool ok = true;
// RAK12027 - D7S
if (!d7s.begin()) {
Serial.println("RAK12027 (D7S) init failed");
ok = false;
} else {
Serial.println("RAK12027 (D7S) initialized");
}
// RAK12033 - IMU
if (!imu.begin()) {
Serial.println("RAK12033 IMU init failed");
ok = false;
} else {
Serial.println("RAK12033 IMU initialized");
}
return ok;
}
// ------------- Read sensors ----------------
bool readSensors(SensorData &d) {
// D7S seismic data
d.si = d7s.getSI(); // needs to match your D7S example
d.pga = d7s.getPGA(); // same as used in your project
d.quake = d7s.isEarthquake() ? 1 : 0;
// IMU acceleration
float ax, ay, az;
imu.getAcceleration(ax, ay, az); // typical IMU API: g units
d.accX = ax;
d.accY = ay;
d.accZ = az;
return true;
}
// ------------- Debug printing --------------
void printSensorData(const SensorData &d) {
Serial.print("D7S -> SI: ");
Serial.print(d.si);
Serial.print(", PGA: ");
Serial.print(d.pga);
Serial.print(", Quake: ");
Serial.println(d.quake ? "YES" : "NO");
Serial.print("IMU -> ax: ");
Serial.print(d.accX); Serial.print(" g, ay: ");
Serial.print(d.accY); Serial.print(" g, az: ");
Serial.print(d.accZ); Serial.println(" g");
}
void printPayload(const uint8_t *payload, size_t len) {
Serial.print("Payload [");
Serial.print(len);
Serial.print(" bytes]: ");
for (size_t i = 0; i < len; i++) {
if (payload[i] < 16) Serial.print("0");
Serial.print(payload[i], HEX);
Serial.print(" ");
}
Serial.println();
}
// ------------- Arduino setup/loop ----------
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(10);
}
Serial.println("Smart Equipment Vibration & Tilt Monitor");
Serial.println("RAK4631 + RAK12027 + RAK12033");
Wire.begin();
if (!initSensors()) {
Serial.println("One or more sensors failed to initialize.");
} else {
Serial.println("All sensors initialized successfully.");
}
// Initialize LoRaWAN using your WisBlock + TTN guide:
// https://www.hackster.io/user2702447/getting-started-with-wisblock-and-the-things-network-ttn-0a7b84
}
void loop() {
if (readSensors(data)) {
printSensorData(data);
uint8_t payload[16];
encodePayload(payload, data);
printPayload(payload, sizeof(payload));
// Integrate with LoRaWAN uplink logic from your TTN project:
// https://www.hackster.io/user2702447/getting-started-with-wisblock-and-the-things-network-ttn-0a7b84
//
// Example concept:
// g_lora_app_data.buffer = payload;
// g_lora_app_data.buffsize = sizeof(payload);
// lmh_send(&g_lora_app_data, LORAWAN_PORT);
} else {
Serial.println("Sensor reading failed.");
}
// Send every 60 seconds (adjust for your use case)
delay(60000);
}
Important: the class names / method names (RAK_D7S, RAK_IIM42652, getSI(), getPGA(), getAcceleration(), etc.) should be adjusted to match exactly the libraries and examples you used in:– RAK12027: https://www.hackster.io/user2702447/rak12027-guide-vibration-sensing-for-safety-monitoring-0e3889– RAK12033: https://www.hackster.io/user2702447/rak12033-motion-monitoring-76f349
Important: the class names / method names (RAK_D7S,RAK_IIM42652,getSI(),getPGA(),getAcceleration(), etc.) should be adjusted to match exactly the libraries and examples you used in:– RAK12027: https://www.hackster.io/user2702447/rak12027-guide-vibration-sensing-for-safety-monitoring-0e3889– RAK12033: https://www.hackster.io/user2702447/rak12033-motion-monitoring-76f349
(But the structure, payload format, and decoder below stay the same.)
Step 5 – TTN Uplink Decoder (JavaScript)In TTN Console → Application → Payload formatters → Uplink:
function decodeUInt16(bytes, index) {
return (bytes[index] << 8) | bytes[index + 1];
}
function decodeInt16(bytes, index) {
var value = (bytes[index] << 8) | bytes[index + 1];
if (value & 0x8000) {
value = value - 0x10000;
}
return value;
}
function decodeUplink(input) {
var bytes = input.bytes;
if (!bytes || bytes.length < 16) {
return { errors: ["Invalid payload length"] };
}
var si = decodeUInt16(bytes, 0) / 100.0;
var pga = decodeUInt16(bytes, 2) / 100.0;
var quakeFlag = bytes[4];
var ax = decodeInt16(bytes, 6) / 1000.0;
var ay = decodeInt16(bytes, 8) / 1000.0;
var az = decodeInt16(bytes, 10) / 1000.0;
return {
data: {
si: si,
pga: pga,
earthquake_flag: quakeFlag,
acc_x_g: ax,
acc_y_g: ay,
acc_z_g: az
}
};
}
These fields will appear in TTN Live Data and will be forwarded to Ubidots via webhook as described in:https://www.hackster.io/user2702447/set-up-ttn-webhooks-integrate-with-ubidots-a-guide-b715d9
Step 6 – Ubidots Integration & DashboardIn TTN, create a Webhook → Ubidots for this application (same pattern as your webhook guide above).
In Ubidots, create a Plugin for The Things Stack / TTN.
Confirm that Ubidots is receiving:
si
pga
earthquake_flag
acc_x_g, acc_y_g, acc_z_g
Build a Vibration & Tilt dashboard:
Line charts for si and pga over time.
Gauge widget for si to show intensity level.
Chart for acc_z_g to detect tilts or large movements.
- Build a Vibration & Tilt dashboard:Line charts for
siandpgaover time.Gauge widget forsito show intensity level.Chart foracc_z_gto detect tilts or large movements.
Configure alerts:
“Earthquake detected” when earthquake_flag == 1.
Excess vibration alarm when si or pga exceeds a chosen threshold.
Movement alert when acc_x_g or acc_y_g is above a limit (e.g. machine moved).
D7S / RAK12027 not responding– Verify slot orientation exactly as in:https://www.hackster.io/user2702447/rak12027-guide-vibration-sensing-for-safety-monitoring-0e3889
IMU / RAK12033 not responding– Check wiring/slot as in:https://www.hackster.io/user2702447/rak12033-motion-monitoring-76f349
Payload decodes incorrectly in TTN– Make sure the encoder layout in encodePayload() matches the TTN decoder exactly.
Ubidots not receiving data– Re-check TTN webhook + Ubidots plugin settings using:https://www.hackster.io/user2702447/set-up-ttn-webhooks-integrate-with-ubidots-a-guide-b715d9
LoRaWAN join issues– Confirm DevEUI, JoinEUI/AppEUI, AppKey using:https://www.hackster.io/user2702447/getting-started-with-wisblock-and-the-things-network-ttn-0a7b84









Comments