搜尋此網誌

2025年2月26日 星期三

ASP .net core 接收 Esp32 資料

緣起:


    目前回歸社會,到公司後,我的主管請我先研究 Esp32,看這禮拜能不能先弄個簡單的成果出來,傳簡單的資料到後台。由於我那四個月沒什麼碰程式,而且對 dotnet core 其實沒到很熟,所以一開始在開發時碰上好多問題,我只憑著在小哈那最後幾個月的 dotnet core 知識在摸索。

    第一天主要在弄環境,還有研究 Esp32 跟 ASP 的 Web API,第二天中午前有把東西給做出來,這邊想要把結果紀錄下來。


ESP32 開發:


    原本想用 Arduino IDE 來開發 (我也只會用這個),後來我旁邊的同事跟我說,可以用 VS Code 的 PlatformIO 來開發,它有比較多好用的功能。所以我就裝了那個 PlatformIO 的套件,然後用它來寫 Esp32。

    載完套件後,你 vscode 的側邊工具列就會出現 PlatformIO 的選單


    然後去 PIO Home 來新增專案,在建專案時就能先選好你要的開發板


    建好專案後,等它下載完開發所需的套件後就能開始寫程式做開發。專案的架構長這樣,程式寫在 src 的 main.cpp 裡


    它會自動偵測你 usb 連接的板子,也能到 PIO Home 的 Devices 來選擇,程式寫好後,右上方有 Uploadd 的功能來傳程式碼到板子上


    我的這個專案會需要處理 Json 格式的資料,所以有用到 ArduinoJson lib,想新增 lib 可以修改 platformio.ini 檔,加入

lib_deps = 
ArduinoJson

    存檔後,它會開始下載 lib,之後就能在你的程式中引用該 lib。我去四處找範例 code,然後東拼西湊地寫好了一個程式,功能是連接 wifi,然後每隔 5 秒向目標網址 POST Esp32 Mac 位置與隨機浮點的 Json 資料。



#include <Arduino.h>
#include <Wifi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>

char * readMacAddress(){
  uint8_t baseMac[6];
  // Get MAC address for WiFi station
  esp_err_t ret = esp_read_mac(baseMac, ESP_MAC_WIFI_STA);
  char *mac = (char *)malloc(18);
  if(ret == ESP_OK)
    sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]);
  else mac = "Failed to read MAC";
    return mac;
}

const char ssid[]="{ssid}";
const char pwd[]="{pwd}";

const char* serverName = "http://{ip}:5001/api/Esp32/Upload";

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastTime = 0;
unsigned long timerDelay = 5000;
char *MAC;

void setup() {
  Serial.begin(9600);
  MAC = readMacAddress();
  WiFi.begin(ssid, pwd);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  if ((millis() - lastTime) > timerDelay) {
    //Check WiFi connection status
    if(WiFi.status()== WL_CONNECTED){
      WiFiClient client;
      HTTPClient http;
    
      // Your Domain name with URL path or IP address with path
      http.begin(client, serverName);
      
      // Specify content-type header
      http.addHeader("Content-Type", "application/json");
      String httpRequestData;
      JsonDocument exp32Data;
      exp32Data["temperature"] = random(0, 1000)/100.0;
      exp32Data["Esp32Mac"] = MAC;
      serializeJson(exp32Data, httpRequestData);        
      // Send HTTP POST request
      int httpResponseCode = http.POST(httpRequestData);
     
      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
      // Free resources
      http.end();
    }
    else {
      Serial.println("WiFi Disconnected");
    }
    lastTime = millis();
  }
}


ASP Web API:


    再來是開 visual studio,建立一個新的專案,選擇 ASP.NET Core Web API


    修改 Program.cs,我就多加了一行 builder.Services.AddLogging(); 需要 Console 打印資料。

    我那時在測試專案的啟動時,發現沒辨法用區網訪問站台,後來才知道要去改 applicationUrl,它原本是 http://localhost:5001,把它改成 http://*:5001


    有新增一個 class 來接收 Esp32 傳來的 Json 資料
namespace Esp32_Test.Model
{
    public class EspData
    {
        public double? Temperature { get; set; }
        public string? Esp32MAC { get; set; }
    }
}

    然後在 Controllers 資料夾下新增一個 Esp32Controller.cs,把接收到的資料印出來

using Microsoft.AspNetCore.Mvc;
using Esp32_Test.Model;

namespace Esp32_Test.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class Esp32Controller : ControllerBase
    {
        private ILogger<Esp32Controller> _logger;
        public Esp32Controller( ILogger<Esp32Controller> logger)
        {
            _logger = logger;
        }

        [HttpPost(Name ="Upload")]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public IActionResult Upload([FromBody] EspData data)
        {
            if (data == null || data.Temperature == null) return BadRequest();
            _logger.LogInformation($"temperature : {data.Temperature}, MAC : {data.Esp32MAC}");
            //pretend sql update success......
            return Ok();
        }
    }
}

    啟動站台,也給 Esp32 供電,就能看到 Console 印出 Esp32 傳來的資料了。



沒有留言:

張貼留言