474  Sensor Node Behaviors: Classification

474.1 Learning Objectives

By the end of this chapter, you will be able to:

  • Classify Node Behaviors: Categorize sensor nodes as normal, failed, or badly failed based on operational characteristics
  • Understand Failure Modes: Analyze hardware failures, battery depletion, and firmware crashes
  • Implement Recovery Mechanisms: Apply watchdog timers and redundancy strategies
  • Detect Data Integrity Issues: Identify nodes producing corrupted or erroneous data

474.2 Prerequisites

Before diving into this chapter, you should be familiar with:

474.3 Introduction: Node Behavior Categories

NoteKey Concepts
  • Duty Cycling: Alternating between active sensing/communication and low-power sleep states to conserve energy in battery-powered sensor nodes
  • Sleep Scheduling: Coordinating sleep/wake cycles across sensor nodes to maintain coverage and connectivity while minimizing energy consumption
  • Normal Operation: Nodes performing all expected functions correctly under current environmental conditions
  • Failed State: Nodes unable to perform operations due to hardware/software faults or resource exhaustion
  • Badly Failed State: Nodes that fail hardware-wise but continue sending erroneous or corrupted data

In an ideal world, every sensor in a network works perfectly 24/7. Reality is different: sensors fail, batteries die, and hardware malfunctions.

The problem: Deploy 1,000 sensors across a farm. After 6 months, some are dead (battery), some give wrong readings (hardware failure). How do you detect and handle this?

Basic behavior categories:

  1. Normal: Works perfectly, follows all rules
  2. Failed: Battery dead or hardware broken - stops working entirely
  3. Badly Failed: Can sense but gives wrong/corrupted data
Term Simple Explanation
Battery Depletion Sensor ran out of power - like a phone that needs charging
Hardware Failure Physical component broke - sensor is permanently damaged
Firmware Crash Software bug caused the sensor to freeze
Watchdog Timer Safety mechanism that resets a frozen sensor automatically
Redundant Sensing Multiple sensors measure the same thing to catch errors

Real example: Temperature sensor in a greenhouse stops reporting. Is it dead (battery), broken (hardware), or just temporarily disconnected? The network needs to figure this out and respond appropriately.

Idealized textbook diagrams show sensor networks as perfect grids of cooperative, always-functional nodes. Reality is messier:

  • Environmental challenges: Temperature extremes, rain, fog, dust
  • Hardware failures: Battery depletion, component damage, manufacturing defects
  • Software bugs: Firmware crashes, memory leaks, race conditions
  • Resource constraints: Energy, memory, processing limitations

These factors create a spectrum of node behaviors that system architects must anticipate and handle.

%% fig-alt: "Sensor node behavior classification showing normal, failed, and badly failed nodes with their characteristics and impacts on network operation"
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#2C3E50', 'primaryTextColor': '#fff', 'primaryBorderColor': '#16A085', 'lineColor': '#16A085', 'secondaryColor': '#E67E22', 'tertiaryColor': '#7F8C8D'}}}%%

graph TB
    subgraph "Node Behavior Classification"
        Normal["Normal Node<br/>Accurate sensing<br/>Reliable forwarding<br/>Protocol compliance"]
        Failed["Failed Node<br/>Battery depleted<br/>Hardware failure<br/>Cannot communicate"]
        BadlyFailed["Badly Failed Node<br/>Sends corrupted data<br/>False readings<br/>Threatens integrity"]
    end

    Normal --> |Battery dies| Failed
    Normal --> |Sensor malfunction| BadlyFailed

    style Normal fill:#16A085,stroke:#2C3E50,color:#fff
    style Failed fill:#7F8C8D,stroke:#2C3E50,color:#fff
    style BadlyFailed fill:#E67E22,stroke:#2C3E50,color:#fff

Figure 474.1: Sensor node behavior classification showing normal, failed, and badly failed nodes

474.4 Normal Nodes

Time: ~8 min | Difficulty: Intermediate | Unit: P05.C14.U01

Definition:
Nodes that perform all expected functions correctly under current environmental conditions

Behavior:

  • Accurate sensing within specified tolerance
  • Reliable packet forwarding as per routing protocol
  • Honest participation in neighbor discovery and route maintenance
  • Proper resource management (power, memory)
  • Compliance with MAC protocol (backoff, collision avoidance)

Expectations:

  • Sensing accuracy: Plus or minus 2-5% of actual value (sensor-dependent)
  • Packet delivery rate: Greater than 95% to immediate neighbors
  • Protocol compliance: 100% adherence to specifications
  • Energy consumption: Within predicted model bounds

Example IoT Scenario:

Smart Agriculture Temperature Sensor
- Measures soil temperature every 15 minutes
- Reports via LoRaWAN to gateway
- Battery: 5000 mAh, lasts ~3 years
- Accuracy: +/-0.5 degrees Celsius

%% fig-alt: "Normal sensor node operational cycle: sense environment, process data, transmit data, relay others' packets cooperatively, sleep for energy conservation, and repeat cycle"
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#2C3E50', 'primaryTextColor': '#fff', 'primaryBorderColor': '#16A085', 'lineColor': '#16A085', 'secondaryColor': '#E67E22', 'tertiaryColor': '#7F8C8D'}}}%%
graph LR
    Sense["1. Sense<br/>Environment"] --> Process["2. Process<br/>Data"]
    Process --> Transmit["3. Transmit<br/>Data"]
    Transmit --> Relay["4. Relay<br/>Others' Packets"]
    Relay --> Sleep["5. Sleep<br/>(Energy Save)"]
    Sleep --> Sense

    style Sense fill:#16A085,stroke:#2C3E50,color:#fff
    style Process fill:#16A085,stroke:#2C3E50,color:#fff
    style Transmit fill:#16A085,stroke:#2C3E50,color:#fff
    style Relay fill:#16A085,stroke:#2C3E50,color:#fff
    style Sleep fill:#2C3E50,stroke:#16A085,color:#fff

Figure 474.2: Normal sensor node operational cycle

Normal Node Code Example (ESP32):

// Normal cooperative sensor node behavior
#include <Arduino.h>
#include <LoRa.h>

const int TEMP_SENSOR_PIN = 34;
const int SENSE_INTERVAL = 900000;  // 15 minutes
const int LORA_FREQUENCY = 915E6;    // 915 MHz

struct SensorData {
    uint32_t node_id;
    float temperature;
    uint16_t battery_mv;
    uint32_t timestamp;
};

void setup() {
    Serial.begin(115200);

    // Initialize LoRa
    if (!LoRa.begin(LORA_FREQUENCY)) {
        Serial.println("LoRa initialization failed!");
        while (1);
    }

    Serial.println("Normal sensor node initialized");
}

void loop() {
    // 1. Sense environment
    float temperature = readTemperature();
    uint16_t battery = readBattery();

    // 2. Package data
    SensorData data = {
        .node_id = ESP.getEfuseMac(),
        .temperature = temperature,
        .battery_mv = battery,
        .timestamp = millis()
    };

    // 3. Transmit (cooperative behavior)
    transmitData(&data);

    // 4. Check for relay requests
    if (LoRa.parsePacket()) {
        handleRelayRequest();  // Help forward others' packets
    }

    // 5. Sleep to conserve energy
    esp_sleep_enable_timer_wakeup(SENSE_INTERVAL * 1000);
    esp_light_sleep_start();
}

float readTemperature() {
    int adcValue = analogRead(TEMP_SENSOR_PIN);
    // Convert ADC to temperature (sensor-specific)
    float voltage = adcValue * (3.3 / 4095.0);
    float temperature = (voltage - 0.5) * 100.0;  // TMP36 formula
    return temperature;
}

uint16_t readBattery() {
    // Read battery voltage via voltage divider
    return analogRead(35) * 2;  // Simplified
}

void transmitData(SensorData* data) {
    LoRa.beginPacket();
    LoRa.write((uint8_t*)data, sizeof(SensorData));
    LoRa.endPacket();

    Serial.printf("Transmitted: %.2f C, Battery: %dmV\n",
                  data->temperature, data->battery_mv);
}

void handleRelayRequest() {
    // Cooperative forwarding for multi-hop network
    uint8_t buffer[256];
    int packetSize = LoRa.readBytes(buffer, sizeof(buffer));

    // Check if we should forward (not our data, within hop limit)
    if (shouldForward(buffer, packetSize)) {
        LoRa.beginPacket();
        LoRa.write(buffer, packetSize);
        LoRa.endPacket();

        Serial.println("Relayed packet for neighbor");
    }
}

bool shouldForward(uint8_t* packet, int size) {
    // Simplified forwarding logic
    // Real implementation: check routing table, hop count, etc.
    return true;  // Cooperative: always forward
}

474.5 Failed Nodes

Time: ~10 min | Difficulty: Intermediate | Unit: P05.C14.U02

Definition:
Nodes unable to perform operations due to hardware/software faults or resource exhaustion

%% fig-alt: "Battery depletion lifecycle timeline from 100% charge with normal operation through 50% charge continuing normally, degraded performance at 20% with reduced sensing and selective forwarding, emergency beacon at 5%, and complete failure at 0% charge"
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#2C3E50', 'primaryTextColor': '#fff', 'primaryBorderColor': '#16A085', 'lineColor': '#16A085', 'secondaryColor': '#E67E22', 'tertiaryColor': '#7F8C8D'}}}%%
timeline
    title Battery Depletion Lifecycle
    section Normal Operation
        100% Charge : Active sensing : Full forwarding : Normal duty cycle
        50% Charge : Active sensing : Full forwarding : Normal duty cycle
    section Degraded
        20% Charge : Reduced sensing rate : Selective forwarding : Extended sleep
    section Failed
        5% Charge : Emergency beacon only
        0% Charge : Complete failure : Node offline

Figure 474.3: Battery depletion lifecycle from normal operation through degraded and failed states

%% fig-alt: "Failed node causes: battery depletion, hardware failure, or firmware crash leading to node unable to operate"
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#2C3E50', 'primaryTextColor': '#fff', 'primaryBorderColor': '#16A085', 'lineColor': '#16A085', 'secondaryColor': '#E67E22', 'tertiaryColor': '#7F8C8D'}}}%%
graph TB
    Normal["Normal<br/>Operation"]

    Battery["Battery<br/>Depleted"] --> Failed["Failed Node<br/>Cannot operate"]
    Hardware["Hardware<br/>Failure"] --> Failed
    Firmware["Firmware<br/>Crash"] --> Failed

    Normal --> Battery
    Normal --> Hardware
    Normal --> Firmware

    style Normal fill:#16A085,stroke:#2C3E50,color:#fff
    style Failed fill:#7F8C8D,stroke:#2C3E50,color:#fff

Figure 474.4: Failed node causes: battery depletion, hardware failure, or firmware crash

474.5.1 Scenario 1: Battery Depletion

Impact:

  • Node stops transmitting data (sensing unavailable to network)
  • Multi-hop routes through this node break
  • Coverage gaps in monitored area
  • Need replacement or recharging

Detection:

  • Neighbors notice missing periodic updates
  • Routing protocols declare route timeout
  • Network management detects loss of connectivity

474.5.2 Scenario 2: Sensor Hardware Failure

Hardware failures can occur in multiple components:

  • Transceiver failure: Radio module stops working
  • Sensor element failure: Temperature, humidity, or other sensing element malfunctions
  • Memory failure: Flash or RAM corruption
  • Power regulation failure: Voltage regulator malfunction

474.5.3 Scenario 3: Firmware Crash

// Watchdog timer to detect and recover from firmware crashes
#include <esp_task_wdt.h>

const int WDT_TIMEOUT = 30;  // 30 seconds

void setup() {
    Serial.begin(115200);

    // Configure watchdog timer
    esp_task_wdt_init(WDT_TIMEOUT, true);  // Enable panic so ESP32 restarts
    esp_task_wdt_add(NULL);  // Add current thread to WDT watch

    Serial.println("Watchdog configured - node will reset if hung");
}

void loop() {
    // Reset watchdog timer (feed the dog)
    esp_task_wdt_reset();

    // Normal operations
    senseAndTransmit();

    delay(5000);

    // Simulate firmware crash (for testing)
    // while(1);  // Infinite loop - WDT will reset ESP32 after 30s
}

void senseAndTransmit() {
    // ... sensor reading and transmission ...
    Serial.println("Normal operation");
}

Benefits of Watchdog:

  • Automatic recovery from firmware hangs
  • Node self-heals without human intervention
  • Improves network reliability in remote deployments

474.6 Badly Failed Nodes

Time: ~8 min | Difficulty: Intermediate | Unit: P05.C14.U03

Definition:
Nodes that fail hardware-wise but continue sending erroneous or corrupted data, threatening network integrity

Characteristics:

  • Faulty sensor readings: Stuck-at values, random noise, out-of-range readings
  • Corrupted packet transmission: Bit errors, malformed headers
  • False routing information: Advertising non-existent routes, incorrect costs
  • Timing violations: Missing deadlines, desynchronized clocks

474.7 Why Badly Failed Nodes Are Dangerous

Unlike completely failed nodes (which are detected by silence), badly failed nodes actively contribute bad data that can:

  1. Corrupt analytics and decision-making
  2. Trigger false alarms in monitoring systems
  3. Pollute training data for ML models
  4. Cause control systems to make incorrect actuations

Danger:

Mitigation Strategies:

  1. Redundant sensing: Multiple sensors for critical parameters
  2. Outlier detection: Statistical filtering at aggregation points
  3. Consistency checking: Cross-validation with neighbor readings
  4. Reputation systems: Track node reliability over time

1. Range Checking

def validate_temperature(reading):
    """Reject physically impossible readings"""
    if reading < -50 or reading > 150:  # Celsius
        return False, "Out of physical range"
    return True, "Valid"

2. Rate of Change Checking

def validate_change_rate(current, previous, max_rate=5.0):
    """Reject unrealistic sudden changes"""
    change = abs(current - previous)
    if change > max_rate:  # Max 5 degrees per minute
        return False, f"Change too rapid: {change}"
    return True, "Valid"

3. Neighbor Correlation

def validate_with_neighbors(reading, neighbor_readings, tolerance=3.0):
    """Compare with nearby sensors"""
    neighbor_avg = sum(neighbor_readings) / len(neighbor_readings)
    deviation = abs(reading - neighbor_avg)
    if deviation > tolerance:
        return False, f"Deviates from neighbors by {deviation}"
    return True, "Consistent with neighbors"

474.8 Knowledge Check

Question 1: A node continues forwarding packets normally, but its sensor readings become corrupted after a hardware fault (e.g., impossible values). How should it be classified?

A “badly failed” node can still communicate, but its sensing/data becomes unreliable and can poison analytics or control loops. A fully failed node typically cannot communicate at all.

Question 2: What is the primary benefit of using a watchdog timer in sensor nodes?

A watchdog timer monitors the firmware execution and automatically resets the node if it detects a hang or crash. This self-healing capability is crucial for remote deployments where manual intervention is impractical.

Question 3: Which detection method compares a sensor reading against readings from nearby sensors to identify badly failed nodes?

Neighbor correlation checking compares a sensor’s readings with those from nearby sensors. Since nearby sensors should measure similar values (for parameters like temperature), significant deviations indicate a potentially badly failed node.

474.9 Summary

This chapter covered the classification of sensor node behaviors focusing on operational status:

  • Normal Nodes: Fully functional nodes performing accurate sensing, reliable packet forwarding, and proper protocol compliance with typical sensing accuracy of plus or minus 2-5% and delivery rates above 95%
  • Failed Nodes: Nodes that have stopped operating due to battery depletion, hardware failure, or firmware crashes, requiring detection through neighbor monitoring and route timeouts
  • Badly Failed Nodes: Dangerous nodes that continue transmitting corrupted or erroneous data, requiring outlier detection, consistency checking, and redundant sensing for mitigation
  • Recovery Mechanisms: Watchdog timers for automatic firmware crash recovery, enabling self-healing in remote deployments

Understanding these failure modes is essential for designing robust WSN systems that can detect problems early and maintain data integrity.

474.10 What’s Next

The next chapter explores Selfish and Malicious Node Behaviors, covering nodes that intentionally misbehave: selfish nodes conserving energy at the expense of network cooperation, and malicious nodes actively attacking the network through black hole, sinkhole, wormhole, and Sybil attacks.