mangOH Red

Produktbeschreibung

Das mangOH™ Red ist eine energiesparende IoT-Plattform, die mit Batteriestrom bis zu 10 Jahre betrieben werden kann.  Laut mangoh.io zeichnet sie sich durch folgende Merkmale aus:

  • Kreditkartenformat, ideal für die schnelle Erstellung einer Machbarkeitsstudie;
  • Schnappsockel zum Hinzufügen beliebiger CF3™-kompatibler Module (einschließlich Module für die drahtlose Vernetzung – 2G bis 4G und LTE-M/NB-IoT), um eine Batterielebensdauer von bis zu 10 Jahren zu erzielen (das für diesen Artikel verwendete CF3-Modul war das WP8548_1103113 (DigiKey-Teile-Nr. 1645-1022-1-ND));
  • Steckplatz für IoT-Erweiterungskarten zum Einstecken von Technologien, die auf dem offenen Standard für IoT-Erweiterungskarten basieren;
  • Integrierte Smart SIM von Sierra Wireless mit bis zu 100 MB kostenlosen Daten, je nach Region; auch mit jeder anderen handelsüblichen SIM verwendbar;
  • Integriert mit der IoT-Plattform AirVantage, um Lösungen in der Cloud zu erstellen, zu implementieren und zu verwalten;
  • Integriertes Wi-Fi b/g/n und Bluetooth 4.2 BLE mit einem Cortex-M4, für den Echtzeitzugriff auf I/O; und
  • Integrierte Sensoren, wie Beschleunigungsmesser/Gyroskop, Druck- und Lichtsensoren, sowie ein Raspberry-Pi-kompatibler 26-Pin-Steckverbinder (das Steckverbinderkabel hat die DigiKey-Teile-Nr. 1597-1065-ND).

    (Bildquelle: Talon Communications Inc.)

    Was ist im Lieferumfang enthalten?

    Das von uns geöffnete Paket enthielt:

    • mangOH Red
    • CF3-Modul (in unserem Fall WP8548_1103113)
    • Mikro-USB-Kabel
    • 2 Antennen (1 Haupt- und 1 GNSS-Antenne (Global Navigation Satellite System))
    • Micro-SIM-Karte von Sierra Wireless mit Anfangsdatenbelegung

    Hardware-Einrichtung

    Wir sind entsprechend den Anweisungen im Benutzer- und Einrichtungshandbuch für das mangOH Red vorgegangen.

    Das mangOH Red verfügt über zwei Micro-USB-Anschlüsse.

    Die Hardware-Einrichtung war sehr einfach: das mangOH und einen Computer mit einem Micro-USB-Kabel verbinden, Antennen anschließen und SIM-Karte in den Steckplatz an der Rückseite des mangOH einstecken. Die folgende Abbildung zeigt die Hardware-Architektur laut Entwicklerhandbuch für das mangOH Red:

    (Bildquelle: Talon Communications Inc.)

    Anschluss des Raspberry Pi

    Die DigiKey Teilenummer für den Flachbandkabel-Steckverbinder ist 1597-1065-ND. Die folgenden Bilder zeigen die Pinbelegung der Raspberry-Pi-Steckleiste (in der Raspberry-Pi-Abbildung sind die vom MangOH Red nicht genutzten Pins grau schattiert) und des MangOH Red:  Die Verbindung erfolgt von Pin 1 zu Pin 1, von Pin 2 zu Pin 2 usw.

    (Bildquelle: pinout.xyz)

    (Bildquelle: Talon Communications Inc.)

    Software-Einrichtung

    Die Software-Einrichtung erforderte etwas mehr Aufwand.  Bevor es an den Einsatz dieses Geräts geht, sollte man sich noch einmal vor Augen führen, dass das endgültige mangOH-Produkt drei Einheiten umfasst.  Zum einen das Board MangOH Red, Sierra Wireless steuert das CF3-Modul bei und ist auch Eigentümer von AirVantage, der IoT-Coud, in der die Daten vom mangOH gespeichert werden und schließlich Legato, die Linux-basierte Befehlszeilenoberfläche (CLI), die zur Verbindung mit dem mangOH verwendet wird. Ich werde später einzeln auf jede davon eingehen und erläutern, wie ihre Foren erreichbar sind.

    Die erste Website, die wir besuchen müssen, ist die Website Erste Schritte mit mangOH (auf Englisch). Dort haben Sie die Wahl zwischen Windows und Linux als Betriebssystem (das System ist auch Mac-OS-kompatibel, aber dazu komme ich später). Ganz gleich, welches Betriebssystem Sie wählen, Sie müssen immer die Legato-CLI integrieren, entweder über eine virtuelle Maschine (VirtualBox von Oracle) auf Windows oder über ein Linux-Add-on zur Legato-Entwicklung. Das Windows-Setup-Handbuch und das Linux-Setup-Handbuch sind hervorragende Quellen für die Einrichtung Ihres Computers, weshalb ich hier nicht weiter darauf eingehen möchte.

    Wenn Sie einen 64-Bit-Linux-Rechner verwenden, sollten Sie Punkt Nr. 6 auf Seite 16 des Linux-Setup-Handbuchs beachten.

    Sie sollten auch Developer Studio herunterladen. Es ist für die Betriebssysteme Windows, Linux und Mac verfügbar. Laut Sierra-Wireless-Website „ist Developer Studio die Sierra Wireless-Entwicklungsumgebung (IDE) für das Legato Application Framework“.  Das bedeutet, dass Sie zum Erstellen Ihrer eigenen Anwendungen zwei Optionen haben. Sie können einen einfachen Texteditor verwenden, oder Sie können Developer Studio nutzen, ein grafikbasiertes Porgramm, das einige der Vorgänge zur Datei-/Ordnererstellung automatisiert. Ich habe Developer Studio für jedes Betriebssystem heruntergeladen, und das einzige kleine Problem, das ich hatte, war die Java-8-Anforderung bei Mac OS – aus irgendeinem Grund reichte die Standardinstallation von Java 8 nicht aus, um Developer Studio auszuführen, also musste ich letztlich das Java SE Development Kit 8u151 von Oracle herunterladen und installieren.

    Beispielanwendungen und Dateistruktur

    Der beste Ausgangspunkt, nachdem Sie die Einrichtung des mangOH abgeschlossen haben, ist Legato auf Github. Laden Sie dort den Legato-Ordner herunter, oder klonen Sie ihn. Auf der Website Sample Apps von Legato finden Sie Erläuterungen (auf Englisch) zu einigen der Beispiele, die Sie von Github heruntergeladen haben. Die Sample-Apps-Website von Legato ist auch eine hervorragende Quelle für schrittweise Anleitungen.

    Die Dateistruktur muss ebenfalls beachtet werden. Jede Anwendung hat die folgende Verzeichnis-/Dateistruktur:

    Je nach Anwendung kann die Dateistruktur auch die Dateitypen .API und .h umfassen. Das Kernstück der Programmierung liegt in der .c-Datei, während die anderen Dateien Anweisungen für den Compiler zur Erstellung der Anwendung enthalten.

    Beispiel: GNSS Location Text App

    Die Beispielanwendung zeigt einen Großteil dessen, was mit dem mangOH Red möglich ist. Sie sendet eine SMS mit den GNSS-Koordinaten des mangOH Red an den Benutzer. Die Dateistruktur entspricht der obigen Abbildung.

    Der Code der textLoc.c-Datei ist unten abgebildet. Klicken Sie hier, um sich das Video New Product Discovery von Randall Restle anzusehen, wo er das mangOH Red erstmals vorstellt.

    Kopieren
    textLoc.c
        //--------------------------------------------------------------------------------------------------
    /** @file textLoc.c
    *
    * This app illustrates a sample usage of ultra low power mode API. This app reads the current gps
    * location and then sends it as a text message to a destination cell phone number. Once the text
    * message has been sent, the device enters ultra low power mode. The device will wake up from
    * ultra low power mode after a configurable delay.
    *
    * @note This app expects destination cell number to be specified in environment variable section
    * of adef file. If nothing specified in environment variable, it will send message to a default
    * non-existent phone number.
    *
    * Copyright (C) Sierra Wireless Inc.
    */
    //--------------------------------------------------------------------------------------------------
    
    #include "legato.h"
    /* IPC APIs */
    #include "interfaces.h"
    
    //--------------------------------------------------------------------------------------------------
    /**
    * GPS timeout interval in minutes
    *
    * @note Please change this timeout value as needed.
    */
    //--------------------------------------------------------------------------------------------------
    #define GPSTIMEOUT 15
    
    //--------------------------------------------------------------------------------------------------
    /**
    * Default phone number to send location information.
    *
    * @note This is a non-existent phone number (ref:
    * https://en.wikipedia.org/wiki/Fictitious_telephone_number).
    */
    //--------------------------------------------------------------------------------------------------
    #define DEFAULT_PHONE_NO "8005550101"
    
    //--------------------------------------------------------------------------------------------------
    /**
    * Timer interval(in seconds) to exit from shutdown/ultralow-power state.
    *
    * @note Please change this interval as needed.
    */
    //--------------------------------------------------------------------------------------------------
    #define ULPM_EXIT_INTERVAL 30
    
    //--------------------------------------------------------------------------------------------------
    /**
    * Gpio used to exit from shutdown/ultralow-power state.
    *
    * @note Please change gpio number as needed.
    */
    //--------------------------------------------------------------------------------------------------
    #define WAKEUP_GPIO_NUM 38
    
    //--------------------------------------------------------------------------------------------------
    /**
    * Pointer to the null terminated string containing the destination phone number.
    */
    //--------------------------------------------------------------------------------------------------
    static const char *DestPhoneNumberPtr;
    
    //--------------------------------------------------------------------------------------------------
    /**
    * Attempts to use the GPS to find the current latitude, longitude and horizontal accuracy within
    * the given timeout constraints.
    *
    * @return
    * - LE_OK on success
    * - LE_UNAVAILABLE if positioning services are unavailable
    * - LE_TIMEOUT if the timeout expires before successfully acquiring the location
    *
    * @note
    * Blocks until the location has been identified or the timeout has occurred.
    */
    //--------------------------------------------------------------------------------------------------
    static le_result_t GetCurrentLocation(
    int32_t *latitudePtr, ///< [OUT] latitude of device - set to NULL if not needed
    int32_t *longitudePtr, ///< [OUT] longitude of device - set to NULL if not needed
    int32_t *horizontalAccuracyPtr, ///< [OUT] horizontal accuracy of device - set to NULL if not
    ///< needed
    uint32_t timeoutInSeconds ///< [IN] duration to attempt to acquire location data before
    ///< giving up. A value of 0 means there is no timeout.
    )
    {
    le_posCtrl_ActivationRef_t posCtrlRef = le_posCtrl_Request();
    if (!posCtrlRef)
    {
    LE_ERROR("Can't activate the Positioning service");
    return LE_UNAVAILABLE;
    }
    
    le_result_t result;
    const time_t startTime = time(NULL);
    LE_INFO("Checking GPS position");
    while (true)
    {
    result = le_pos_Get2DLocation(latitudePtr, longitudePtr, horizontalAccuracyPtr);
    if (result == LE_OK)
    {
    break;
    }
    else if (
    (timeoutInSeconds != 0) &&
    (difftime(time(NULL), startTime) > (double)timeoutInSeconds))
    {
    result = LE_TIMEOUT;
    break;
    }
    else
    {
    // Sleep for one second before requesting the location again.
    sleep(1);
    }
    }
    
    le_posCtrl_Release(posCtrlRef);
    
    return result;
    }
    
    //--------------------------------------------------------------------------------------------------
    /**
    * Sends an SMS text message to the given destination with the given message content.
    *
    * @return
    * - LE_OK on success
    * - LE_FAULT on failure
    */
    //--------------------------------------------------------------------------------------------------
    static le_result_t SendTextMessage(
    const char *destinationNumberPtr, ///< [IN] Phone number to send the text message to as ASCII
    ///< values
    const char *messageBodyPtr ///< [IN] Text message body content
    )
    {
    le_result_t result = LE_OK;
    LE_INFO("Sending SMS");
    
    le_sms_MsgRef_t sms = le_sms_Create();
    
    if (le_sms_SetDestination(sms, destinationNumberPtr) != LE_OK)
    {
    result = LE_FAULT;
    LE_ERROR("Could not set destination phone number");
    goto sms_done;
    }
    
    if (le_sms_SetText(sms, messageBodyPtr) != LE_OK)
    {
    result = LE_FAULT;
    LE_ERROR("Could not set text message body");
    goto sms_done;
    }
    
    if (le_sms_Send(sms) != LE_OK)
    {
    result = LE_FAULT;
    LE_ERROR("Could not send SMS message");
    goto sms_done;
    }
    
    LE_INFO("SMS Message sent");
    
    sms_done:
    le_sms_Delete(sms);
    return result;
    }
    
    //--------------------------------------------------------------------------------------------------
    /**
    * Send the device location as a text message
    *
    * Attempts to send an SMS text message containing the current device location to the destination
    * phone number.
    *
    * @note
    * No failure notification is provided if location services or SMS send are unsuccessful.
    */
    //--------------------------------------------------------------------------------------------------
    static void SendSmsCurrentLocation(
    void
    )
    {
    char smsBody[LE_SMS_TEXT_MAX_LEN];
    int32_t latitude;
    int32_t longitude;
    int32_t horizontalAccuracy;
    
    const le_result_t result =
    GetCurrentLocation(&latitude, &longitude, &horizontalAccuracy, GPSTIMEOUT * 60);
    if (result == LE_OK)
    {
    snprintf(smsBody, sizeof(smsBody), "Loc:%d,%d", latitude, longitude);
    }
    else
    {
    strncpy(smsBody, "Loc:unknown", sizeof(smsBody));
    }
    SendTextMessage(DestPhoneNumberPtr, smsBody);
    }
    
    //--------------------------------------------------------------------------------------------------
    /**
    * Configure the boot source and shutdown MDM.
    */
    //--------------------------------------------------------------------------------------------------
    static void CfgShutDown
    (
    void
    )
    {
    // Boot after specified interval.
    if (le_ulpm_BootOnTimer(ULPM_EXIT_INTERVAL) != LE_OK)
    {
    LE_ERROR("Can't set timer as boot source");
    return;
    }
    
    // Boot on gpio. Please note this is platform dependent, change it when needed.
    if (le_ulpm_BootOnGpio(WAKEUP_GPIO_NUM, LE_ULPM_GPIO_LOW) != LE_OK)
    {
    LE_ERROR("Can't set gpio: %d as boot source", WAKEUP_GPIO_NUM);
    return;
    }
    
    // Initiate shutdown.
    if (le_ulpm_ShutDown() != LE_OK)
    {
    LE_ERROR("Can't initiate shutdown.");
    }
    }
    
    //--------------------------------------------------------------------------------------------------
    /**
    * Callback function to handle change of network registration state.
    */
    //--------------------------------------------------------------------------------------------------
    static void RegistrationStateHandler
    (
    le_mrc_NetRegState_t state, ///< [IN] Network registration state.
    void *contextPtr ///< [IN] Context pointer.
    )
    {
    switch(state)
    {
    case LE_MRC_REG_HOME:
    case LE_MRC_REG_ROAMING:
    LE_INFO("Registered");
    SendSmsCurrentLocation();
    LE_INFO("Now configure boot source and shutdown MDM");
    CfgShutDown();
    break;
    case LE_MRC_REG_SEARCHING:
    LE_INFO("Searching...");
    break;
    case LE_MRC_REG_NONE:
    LE_INFO("Not registered");
    break;
    case LE_MRC_REG_DENIED:
    LE_ERROR("Registration denied");
    break;
    case LE_MRC_REG_UNKNOWN:
    LE_ERROR("Unknown registration state");
    break;
    }
    }
    
    //--------------------------------------------------------------------------------------------------
    /**
    * Simulate entry into the current NetReg state by calling RegistrationStateHandler
    *
    * RegistrationStateHandler will only be notified of state change events. This function exists to
    * simulate the change into the current state.
    */
    //--------------------------------------------------------------------------------------------------
    static void SimulateNetRegStateChangeToCurrentState(
    void *ignoredParam1, ///< Only exists to allow this function to conform to the
    ///< le_event_DeferredFunc_t declaration
    void *ignoredParam2 ///< Only exists to allow this function to conform to the
    ///< le_event_DeferredFunc_t declaration
    )
    {
    le_mrc_NetRegState_t currentNetRegState;
    LE_FATAL_IF(le_mrc_GetNetRegState(¤tNetRegState) != LE_OK, "Couldn't get NetRegState");
    RegistrationStateHandler(currentNetRegState, NULL);
    }
    
    //--------------------------------------------------------------------------------------------------
    /**
    * Get the destination phone number.
    **/
    //--------------------------------------------------------------------------------------------------
    static void GetDestinationCellNo
    (
    void
    )
    {
    DestPhoneNumberPtr = getenv("DEST_CELL_NO");
    if (!DestPhoneNumberPtr)
    {
    LE_WARN(
    "No destination cell number is specified. Using a default non-existent number");
    DestPhoneNumberPtr = DEFAULT_PHONE_NO;
    }
    
    LE_INFO("Destination phone number = %s", DestPhoneNumberPtr);
    }
    
    
    COMPONENT_INIT
    {
    char version[LE_ULPM_MAX_VERS_LEN + 1];
    
    LE_INFO("TextLoc started");
    
    // Get ultra low power manager firmware version
    LE_FATAL_IF(
    le_ulpm_GetFirmwareVersion(version, sizeof(version)) != LE_OK,
    "Failed to get ultra low power firmware version");
    LE_INFO("Ultra Low Power Manager Firmware version: %s", version);
    
    // Now check whether boot was due to timer expiry.
    if (le_bootReason_WasTimer())
    {
    LE_INFO("Booted from timer, not sending another text message.");
    }
    else if (le_bootReason_WasGpio(WAKEUP_GPIO_NUM))
    {
    LE_INFO("Booted from GPIO, not sending another text message.");
    }
    else
    {
    // Get the destination phone number
    GetDestinationCellNo();
    
    // Register a callback handler for network registration state.
    le_mrc_AddNetRegStateEventHandler(
    (le_mrc_NetRegStateHandlerFunc_t)RegistrationStateHandler, NULL);
    le_event_QueueFunction(&SimulateNetRegStateChangeToCurrentState, NULL, NULL);
    }
    }
    The textLoc.adef file is:
    textLoc.adef  
    sandboxed: false
    
    version: 1.0.0
    maxFileSystemBytes: 512K
    
    executables:
    {
    textloc = ( textLocComponent )
    }
    
    processes:
    {
    envVars:
    {
    LE_LOG_LEVEL = DEBUG
    // This is a non-existent fictitious phone number. Change it to a valid phone number.
    DEST_CELL_NO = 8005550101
    }
    run:
    {
    ( textloc )
    }
    maxCoreDumpFileBytes: 512K
    maxFileBytes: 512K
    }
    
    bindings:
    {
    textloc.textLocComponent.le_mrc -> modemService.le_mrc
    textloc.textLocComponent.le_posCtrl -> positioningService.le_posCtrl
    textloc.textLocComponent.le_pos -> positioningService.le_pos
    textloc.textLocComponent.le_sms -> modemService.le_sms
    textloc.textLocComponent.le_ulpm -> powerMgr.le_ulpm
    textloc.textLocComponent.le_bootReason -> powerMgr.le_bootReason
    }
    
    The Component.cdef:
    Component.cdef  
    requires:
    {
    api:
    {
    modemServices/le_mrc.api
    modemServices/le_sms.api
    positioning/le_posCtrl.api
    positioning/le_pos.api
    le_ulpm.api
    le_bootReason.api
    }
    }
    
    sources:
    {
    textLoc.c
    }
    Makefile:
    Makefile  
    TARGETS := $(MAKECMDGOALS)
    
    .PHONY: all $(TARGETS)
    all: $(TARGETS)
    
    $(TARGETS):
    mkapp -v -t $@ \
    textLoc.adef
    
    clean:
    rm -rf _build_* *.update
    

Über den Autor

Image of Curtis Johnson

Curtis Johnson, ein „Associate Applications Engineering Technician“ bei DigiKey, hilft Kunden seit 2017 bei technischen Fragen und ist seit 2015, nach einer 15-jährigen Tätigkeit als Banker, bei DigiKey. Curtis hat einen AAS in „Electronics Technology Automated Systems“, einen BA in Psychologie (ich weiß, keine Verbindung zu Banken oder Elektronik), einen MBA mit Schwerpunkt Buchhaltung, ein abgeschlossenes Postgraduiertenstudium in Wirtschaft und Finanzen und ist ab Herbst 2018 in einem BS-Studiengang für Informatik eingeschrieben. Curtis arbeitet daran, sein Verständnis unter anderem in den Bereichen eingebettete Systeme, HF und Mobilfunkkommunikation zu erweitern. In seiner Freizeit verbringt Curtis gerne Zeit mit seiner Familie, liest und lernt.

More posts by Curtis Johnson
 TechForum

Have questions or comments? Continue the conversation on TechForum, Digi-Key's online community and technical resource.

Visit TechForum