ESP32でマルチコアを使用する

投稿者: | 9月 15, 2022

シーリングライトや扇風機用のコントローラを作っていたところ、一つのコアで制御、もう一つのコアでHTTPリクエストの受け答えをしたい、ということが増えました。そこでサブコア(core 0)を使用してHTTPリクエストの受け答えをするサンプルプログラムを作成しました。いろいろなとことから参考にしています。

//ESP32でマルチコアでHTTPを処理
//http://IPアドレス/number/数字 でその数字を返すプログラム
#include <WiFi.h>

const int Blue_LED = 2;

//WiFi関係と固定アドレスなどの設定
const char SSID[] = "WiFiのSSID"; //SSID
const char PASSWORD[] = "WiFiのパスワード"; //WiFiパスワード
WiFiServer server(80);
IPAddress ip(192, 168, 10, 12);        // for fixed IP Address
IPAddress gateway(192,168, 10, 1);    //
IPAddress subnet(255, 255, 255, 0);  //
IPAddress DNS(192, 168, 10, 1);       //

//接続してきたクライアントのコマンドを取り込むバッファなどの用意
#define BUFFLEN 256   //length of the receive buffer
char buff[BUFFLEN]; //buffer
int count = 0;        //counter for the buffer
volatile int command = 0;      //2つのコアで同時に使用される可能性があるのでvolatile
bool isBlankLine = false; //if the last line is empty, the end of request
int number = 0;

//クライアントから受け取った1バイトをバッファに溜めてGETコマンドをチェックする
//リクエスト行が空行ならば、リクエストは終了と判断してisBlankLineに反映する
//put received char in buffer and check the GET command and empty line
void processReequest(char c) {
  if(c == '\r') return; //if the code is CR, ignore it
  if(c == '\n') {  //if the code is NL, read the GET request
    buff[count]='\0'; //put null character at the end

    String buffS = buff; //convert to String
    //Serial.print("command is: "); //for debug
    //Serial.println(bufferS);      //for degub
    if(buffS.startsWith("GET /info")){
      command = 0;
    }
    else if (buffS.startsWith("GET /number/")){
      number = buffS.substring(12).toInt();//GET /number という文字列なので先頭から12文字(GET /number/)を削除
      command = 1;
      Serial.print("number:");
      Serial.println(number);
    }
    Serial.print("command ==");
    Serial.println(command);
    isBlankLine = (count == 0); //and check if the line is empty
    count=0;
  }
  else { //if the code is not control code, record it
    isBlankLine = false;
    if(count >= (BUFFLEN - 1) ) count=0; //if almost overflow, reset the counter
      buff[count++]=c; //add char at the end of buffer
    }
  }

//最初に実行される関数
void setup() {
  int status = WL_IDLE_STATUS;
  int wifi_led_flag = 0;
  pinMode(Blue_LED, OUTPUT);
  Serial.begin(115200);               //  シリアル通信のボーレートを115200に設定
  while (!Serial) ;                   //  wait for serial port to connect.
  WiFi.config(ip, gateway, subnet, DNS);   // Set fixed IP address

  while (status != WL_CONNECTED) {
    Serial.print("\nAttempting to connect to SSID: ");
    Serial.print(SSID);
    WiFi.begin(SSID, PASSWORD);
    for (int i=0; i<15; i++) { //wait up to 15 sec to be connected
      delay(1000);
      status = WiFi.status();
      Serial.print(".");
      if(wifi_led_flag == 0){
        digitalWrite(Blue_LED, HIGH);
        wifi_led_flag = 1;}
      else{
        digitalWrite(Blue_LED, LOW);
        wifi_led_flag =0;}
      if(status == WL_CONNECTED){
        digitalWrite(Blue_LED, LOW);
        break;}
    }
  }
  
  xTaskCreatePinnedToCore(task0, "Task0", 4096, NULL, 1, NULL, 0); //core0でtask0を実行
}

//繰り返し呼び出される関数
void loop() {
  }

void task0(void* arg){
  server.begin(); //start the server
  Serial.print("\nHTTP server started at: ");
  Serial.println(WiFi.localIP());
  while(1){
  WiFiClient client = server.available();
  if (client) {
    Serial.println("new client");
    number = 0;
    while(client.connected()) {
      if(client.available()) {
        char c = client.read();
        Serial.write(c);
        processReequest(c);
        //if the line is blank, the request has ended.
        if(isBlankLine) {
          //空行ならばリクエスト終了と判断して応答
          // send a http response
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed
          client.println();
          client.println("");
          client.println("");
          if (command == 1){
            client.println(number);
            }
          else if (command == 0){
            client.print("http://");
            client.print(ip);
            client.println("/number/x (x is int) return x");
            }
          client.println("");
          break;
        }
      }
    }
  }
  delay(1);
  }
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)