Gyakorlat: A .NET IoT-kódtárak használata

Befejeződött

Ebben a leckében a .NET IoT-kódtárak használatával fogja írni a barlangmonitor-eszközzel interakcióba lépő kódot. Bár a .NET SDK-t a Raspberry Pi és más IoT-táblák támogatják, javasoljuk, hogy használjon számítógépet. A számítógép használatával teljes funkcionalitású azonosítókat és szerkesztőket használhat, például a Visual Studiót és a Visual Studio Code-ot.

Az alkalmazás létrehozása

Hajtsa végre a következő lépéseket a fejlesztői gépen található parancshéjból.

  1. Hozzon létre egy cheesecave.net nevű új konzolalkalmazást.

    dotnet new console -o cheesecave.net
    cd ./cheesecave.net
    

    Az előző parancsok:

    • Hozzon létre egy új .NET-konzolalkalmazást egy cheesecave.net nevű mappában.
    • Állítsa az aktuális helyet a cheesecave.net mappára.
  2. Adja hozzá a .NET IoT-kódtárakat a projekthez.

    dotnet add package System.Device.Gpio --version 2.1.0
    dotnet add package IoT.Device.Bindings --version 2.1.0
    

    Az előző parancsok:

    • Adja hozzá a csomagokat és Iot.Device.Bindings a System.Device.Gpio csomagokat a projekthez.
    • Megadja, hogy a verzió 2.1.0 mindkét csomaghoz hozzáadva legyen.

Kód hozzáadása

  1. Az előnyben részesített IDE vagy szerkesztő használatával cserélje le a Program.cs tartalmát a következő kódra:

    using System;
    using System.Device.Gpio;
    using System.Device.Gpio.Drivers;
    using System.Device.I2c;
    using Iot.Device.Bmxx80;
    using Iot.Device.Bmxx80.ReadResult;
    
    bool _fanOn = false;
    bool _exit = false;
    int _pin = 21;
    
    // Initialize the GPIO controller
    using GpioController gpio = new GpioController();
    
    // Open the GPIO pin for output
    gpio.OpenPin(_pin, PinMode.Output);
    gpio.Write(_pin, PinValue.Low);
    
    // Get a reference to a device on the I2C bus
    var i2cSettings = new I2cConnectionSettings(1, Bme280.DefaultI2cAddress);
    using I2cDevice i2cDevice = I2cDevice.Create(i2cSettings);
    
    // Create a reference to the BME280
    using var bme280 = new Bme280(i2cDevice);
    
    // Write the fan, temperature, and humidity statuses to the console
    WriteStatus();
    
    // Main control loop
    while (!_exit)
    {
        string commandText = Console.ReadLine() ?? string.Empty;
        DoCommand(commandText);
    }
    
    // Close the pin before exit
    gpio.ClosePin(_pin);
    
    // Exit
    return;
    
    void DoCommand(string commandText)
    {
        switch (commandText)
        {
            case "exit":
                Console.WriteLine("Exiting!");
                _exit = true;
                break;
    
            case "fan":
                if (!_fanOn)
                {
                    // Turn on the fan
                    gpio.Write(_pin, PinValue.High);
                    Console.WriteLine("Turned fan on!");
                }
                else 
                {
                    // Turn off the fan
                    gpio.Write(_pin, PinValue.Low);
                    Console.WriteLine("Turned fan off!");
                }
                _fanOn = !_fanOn;
                WriteStatus();
                break;
    
            case "status":
                WriteStatus();
                break;
    
            default:
                Console.WriteLine("Command not recognized! Try again.");
                return;
        }
    }
    
    void WriteStatus()
    {
        // Read the BME280
        Bme280ReadResult output = bme280.Read();
        double temperatureF = output.Temperature?.DegreesFahrenheit ?? double.NaN;
        double humidityPercent = output.Humidity?.Percent ?? double.NaN;
    
        // Print statuses
        Console.WriteLine();
        Console.WriteLine("DEVICE STATUS");
        Console.WriteLine("-------------");
        Console.WriteLine($"Fan: {(_fanOn ? "ON" : "OFF")}");
        Console.WriteLine($"Temperature: {temperatureF:0.#}°F");
        Console.WriteLine($"Relative humidity: {humidityPercent:#.##}%");
        Console.WriteLine();
        Console.WriteLine("Enter command (status/fan/exit):");
    }
    
  2. Vizsgálja meg a kódot, hogy megértse, hogyan működik együtt a GPIO pin-kóddal. A fenti kód a következőket végzi el:

    • Létrejön egy példány a GpioController GPIO-műveletekben való használatra.

    • A 21-et a 21-sel gpio.OpenPin()nyitjuk meg. A gombostű meg van nyitva a kimenethez a következővel PinMode.Output: .

    • A 21. pin értéke a következőre PinValue.Lowvan állítva: . Ez az érték a csap által kibocsátott legkisebb feszültséget jelöli. A LED PinValue.Low megvilágítása érdekében ki van kapcsolva, és PinValue.High be van kapcsolva. Ennek eredményeképpen a ventilátort képviselő LED ki van kapcsolva.

    • A kód be- és kikapcsolja a ventilátort/LED-et írással PinValue.Low és PinValue.Highki.

      Tipp.

      Sok valós relék használják PinValue.Highki és PinValue.Lowbe. Ez az ellentéte annak, amit a gyakorlatban a ventilátor továbbítóját képviselő LED-hez implementál.

    • A kód kilépése előtt a 21- es pin-kód a következővel gpio.ClosePin()lesz lezárva: .

  3. Vizsgálja meg a kódot, hogy megértse, hogyan kommunikál a BME280-nal. A fenti kód a következőket végzi el:

    • Létrejön egy I2cConnectionSettings példány. Az első konstruktorparaméter a busIdRaspberry Pi I2C-buszazonosítójára van állítva 1. A második konstruktorparaméter deviceAddressa következőre Bme280.DefaultI2cAddressvan állítva: .

      Figyelmeztetés

      Egyes BME280-mellékek az eszközcímhez használatosak Bme280.SecondaryI2cAddress . Ha az alkalmazás dob System.IO.IOException: Error 121 performing I2C data transfer., próbálkozzon ezzel az értékkel.

    • A rendszer létrehoz egy példányt I2cDevice az I2cConnectionSettings objektummal.

    • A rendszer létrehoz egy példányt Bme280 az I2cDevice objektummal. Ez az objektum a fizikai BME280-at jelöli.

    • A metódusban az WriteStatus()Bme280ReadResult objektum hívással Bme280.Read()jön létre.

    • Az Bme280ReadResult objektum tartalma Temperature és Humidity tulajdonságai.

      • A Temperature tulajdonságok Humidity és a tulajdonságok egyaránt null értékűek, ami azt jelenti, hogy tartalmazhatnak null. Ennek megfelelően a null feltételes operátort ?. használják a tagok elérésére.
      • Maguk a tulajdonságok olyan tulajdonságokat tesznek elérhetővé, amelyek automatikus egységkonvertálást végeznek, például DegreesFahrenheit és Percent.
      • Mindkét esetben a null-szenesítő operátor ?? ellenőrzi a visszatérési értéket, és ha ez nullvan, lecseréli a következőre double.NaN: .

    Tipp.

    Ha segítségre van szüksége a null biztonság megértéséhez, olvassa el a Null biztonság c#-ban című témakört.

Az alkalmazás létrehozása

Futtassa a következő parancsot az alkalmazás létrehozásához.

dotnet build

A build hibák és figyelmeztetések nélkül fejeződik be.

A következő leckében üzembe helyezi az alkalmazást a Raspberry Pi-ben, és teszteli azt.