Senden von Raumumgebungsdaten des Azure RTOS-Echtzeitsensors an IoT Hub

Abgeschlossen

Der aktualisierte Temperatur-, Luftdruck- und Luftfeuchtigkeitssensor im Mikrobiologielabor funktioniert problemlos auf dem Azure Sphere-Echtzeitkern. Der Kunde ist zufrieden und kann seine Experimente durchführen. Er möchte die Bedingungen im Labor auch remote überwachen.

In dieser Lerneinheit erfahren Sie, wie Sie die Daten des aktualisierten Laborsensors lesen und an IoT Hub senden, damit diese überwacht werden können.

Lösungsarchitektur

Im Folgenden wird beschrieben, wie eine allgemeine Azure Sphere-Anwendung Daten des aktualisierten Laborsensors lesen kann, der auf einem der Azure Sphere-Echtzeitkerne ausgeführt wird. Die allgemeine Anwendung sendet diese Daten dann sicher an IoT Hub.

Inter-core communications architecture.

Zusammenfassung der im Azure RTOS-Labor eingeführten Lösungsarchitektur:

  1. Der Azure RTOS-Echtzeitumgebungssensorthread wird alle zwei Sekunden ausgeführt. Der Thread speichert die neuesten Umgebungstemperatur-, Luftfeuchtigkeits- und Luftdruckdaten im Arbeitsspeicher.
  2. Die Streaming-App für allgemeine Telemetriedaten fordert vom Echtzeitkern die neuesten Umgebungsdaten an.
  3. Der Azure RTOS-Echtzeitumgebungsdienstthread sendet die neuesten Umgebungsdaten als Antwort.
  4. Die allgemeine Anwendung serialisiert die Umgebungsdaten als JSON und sendet die Telemetriedatennachricht an IoT Hub.
  5. Azure IoT-Explorer abonniert die Telemetrienachrichten, die vom Gerät an IoT Hub gesendet werden, und zeigt die Telemetriedaten an.
  6. Sie können die gewünschte Raumtemperatur auch bestimmen, indem Sie eine Eigenschaft festlegen. Die Eigenschaft wird auf dem Gerät über eine IoT Hub-Gerätezwillingsnachricht festgelegt.
  7. Das Azure Sphere-Gerät legt dann den Betriebsmodus der HVAC-Einheit in Abhängigkeit von der gewünschten Temperatur fest.

Vertrag für kernübergreifende Nachrichten

Es muss ein gemeinsamer Vertrag vorhanden sein, der die Form der Daten beschreibt, die zwischen den Kernen weitergegeben werden. Die folgende Struktur deklariert den kernübergreifenden Vertrag, der in dieser Lerneinheit verwendet wird. Sie finden diesen Vertrag im Verzeichnis IntercoreContract.

typedef enum
{
    LP_IC_UNKNOWN,
    LP_IC_HEARTBEAT,
    LP_IC_ENVIRONMENT_SENSOR,
    LP_IC_SAMPLE_RATE
} LP_INTER_CORE_CMD;

typedef struct
{
    LP_INTER_CORE_CMD cmd;
    float temperature;
    float pressure;
    float humidity;
    int sample_rate;
} LP_INTER_CORE_BLOCK;

Kernübergreifende Sicherheit

Für die Kommunikation müssen kernübergreifend ausgeführte Anwendungen mit den entsprechenden Komponenten-IDs konfiguriert werden.

Die Komponenten-ID für die Echtzeitanwendung befindet sich in der app_manifest.json-Datei.

{
  "SchemaVersion": 1,
  "Name": "AzureSphereIoTCentral",
  "ComponentId": "25025d2c-66da-4448-bae1-ac26fcdd3627",
  ...
}

Allgemeine kernübergreifende Funktionen

Die AllowedApplicationConnections-Eigenschaft in der allgemeinen app_manifest.json-Datei wird auf die Komponenten-ID der Azure RTOS-Echtzeitanwendung festgelegt.

{
    ...
    "AllowedApplicationConnections": [ "6583cf17-d321-4d72-8283-0b7c5b56442b" ]
    ...
}

Initialisieren der kernübergreifenden Kommunikation

In InitPeripheralAndHandlers wird ein Aufruf von lp_interCoreCommunicationsEnable durchgeführt. Dabei wird die Komponenten-ID der Echtzeitanwendung und die kernübergreifende Rückruffunktion übergeben.

Die kernübergreifende Rückruffunktion wird aufgerufen, wenn eine Nachricht vom Echtzeitkern empfangen wird.

lp_interCoreCommunicationsEnable(REAL_TIME_COMPONENT_ID, InterCoreHandler);  // Initialize Inter Core Communications

Senden einer Anforderung an die Echtzeitkernanwendung

Führen Sie die folgenden Schritte aus, um die Umgebungsdaten vom Echtzeitkern anzufordern:

  1. Legen Sie den kernübergreifenden Steuerungsblockbefehl auf LP_IC_ENVIRONMENT_SENSOR fest.
  2. Senden Sie die Anforderungsnachricht, indem Sie lp_interCoreSendMessage aufrufen und den kernübergreifenden Steuerungsblock übergeben.
/// <summary>
/// Read sensor and send to Azure IoT
/// </summary>
static void MeasureSensorHandler(EventLoopTimer* eventLoopTimer)
{
    if (ConsumeEventLoopTimerEvent(eventLoopTimer) != 0)
    {
        lp_terminate(ExitCode_ConsumeEventLoopTimeEvent);
    }
    else {
        // send request to Real-Time core app to read temperature, pressure, and humidity
        ic_control_block.cmd = LP_IC_ENVIRONMENT_SENSOR;
        lp_interCoreSendMessage(&ic_control_block, sizeof(ic_control_block));
    }
}

Empfangen kernübergreifender Nachrichten

Wenn die allgemeine Anwendung eine Nachricht empfängt, wird die kernübergreifende Rückruffunktion aufgerufen, die einen Verweis auf den kernübergreifenden Steuerungsblock übergibt, der die Umgebungsdaten enthält. Die Anwendung serialisiert die Daten als JSON, und sendet die Telemetriedatennachricht an IoT Hub, und die Status-LED für die HVAC-Einheit wird aktualisiert.

/// <summary>
/// Callback handler for Inter-Core Messaging - Does Device Twin Update, and Event Message
/// </summary>
static void InterCoreHandler(LP_INTER_CORE_BLOCK* ic_message_block)
{
    static int msgId = 0;

    switch (ic_message_block->cmd)
    {
    case LP_IC_ENVIRONMENT_SENSOR:
        if (snprintf(msgBuffer, JSON_MESSAGE_BYTES, msgTemplate, ic_message_block->temperature,
            ic_message_block->humidity, ic_message_block->pressure, msgId++) > 0) {

            Log_Debug("%s\n", msgBuffer);
            lp_azureMsgSendWithProperties(msgBuffer, telemetryMessageProperties, NELEMS(telemetryMessageProperties));

            SetHvacStatusColour((int)ic_message_block->temperature);

            // If the previous temperature not equal to the new temperature then update ReportedTemperature device twin
            if (previous_temperature != (int)ic_message_block->temperature) {
                lp_deviceTwinReportState(&dt_reportedTemperature, &ic_message_block->temperature);
                previous_temperature = (int)ic_message_block->temperature;
            }
        }
        break;
    default:
        break;
    }
}