본문 바로가기

[Portenta H7] Wi-Fi Access Point로 사용하기

by rudals.kim 2021. 10. 20. 댓글 개
반응형

Arduino Portenta H7 보드는 무선 통신을 위해 Murata 1DX 칩을 사용하여 WIFI 기능이 내장되어 있습니다.

이 칩은 Wi-Fi 802.11b/g/n + Bluetooth® 5.1 BR/EDR/LE를 모두 지원하며 WIFI의 경우 최대 65Mbps를 Bluetooth의 경우 최대 3Mbps의 속도를 지원합니다.

 

이번에는 WIFI를 사용하여 간단한 웹서버를 만들어서 핸드폰으로 Portenta 보드에 접속하여 LED를 켜고 끄는 테스트를 해 보았습니다.  동작은 아래 그림을 참고 하시기 바랍니다.

 

우선 서버용 소스를 아래와 같이 작성한 후 SimpleWebServer.ino로 저장합니다.

#include <WiFi.h>
#include "arduino_secrets.h"

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;    // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;             // your network key Index number (needed only for WEP)

int status = WL_IDLE_STATUS;

WiFiServer server(80);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  
  Serial.println("Access Point Web Server");

  pinMode(LEDR,OUTPUT);
  pinMode(LEDG,OUTPUT);
  pinMode(LEDB,OUTPUT); 

  // by default the local IP address of will be 192.168.3.1
  // you can override it with the following:
  // WiFi.config(IPAddress(10, 0, 0, 1));

  if(strlen(pass) < 8){    
    Serial.println("Creating access point failed");
    Serial.println("The Wi-Fi password must be at least 8 characters long");
    // don't continue
    while(true);
  }
    
  // print the network name (SSID);
  Serial.print("Creating access point named: ");
  Serial.println(ssid);

  //Create the Access point
  status = WiFi.beginAP(ssid,pass);
  if(status != WL_AP_LISTENING){
    Serial.println("Creating access point failed");
    // don't continue
    while (true);
  }

  // wait 10 seconds for connection:
  delay(10000);

  // start the web server on port 80
  server.begin();

  // you're connected now, so print out the status
  printWiFiStatus();
  
}

void loop() {

 // compare the previous status to the current status
  if (status != WiFi.status()) {
    // it has changed update the variable
    status = WiFi.status();

    if (status == WL_AP_CONNECTED) {
      // a device has connected to the AP
      Serial.println("Device connected to AP");
    } else {
      // a device has disconnected from the AP, and we are back in listening mode
      Serial.println("Device disconnected from AP");
    }
  }

  WiFiClient client = server.available();   // listen for incoming clients

  if (client) {                             // if you get a client,
    Serial.println("new client");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
  
    while (client.connected()) {            // loop while the client's connected
     
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            // the content of the HTTP response follows the header:
            client.print("<html><head>");
            client.print("<style>");
            client.print("* { font-family: sans-serif;}");
            client.print("body { padding: 2em; font-size: 2em; text-align: center;}");            
            client.print("a { -webkit-appearance: button;-moz-appearance: 
            	button;appearance: button;text-decoration: none;color: initial; 
                padding: 25px;} #red{color:red;} #green{color:green;} #blue{color:blue;}");
            client.print("</style></head>");
            client.print("<body><h1> LED CONTROLS </h1>");
            client.print("<h2><span id=\"red\">RED </span> LED </h2>");
            client.print("<a href=\"/Hr\">ON</a> <a href=\"/Lr\">OFF</a>");
            client.print("<h2> <span id=\"green\">GREEN</span> LED </h2>");
            client.print("<a href=\"/Hg\">ON</a> <a href=\"/Lg\">OFF</a>");
            client.print("<h2> <span id=\"blue\">BLUE</span> LED </h2>");
            client.print("<a href=\"/Hb\">ON</a> <a href=\"/Lb\">OFF</a>");
            client.print("</body></html>");

            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          } else {      // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        } else if (c != '\r') {    // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }

        // Check to see if the client request was "GET /H" or "GET /L":
        if (currentLine.endsWith("GET /Hr")) {
          digitalWrite(LEDR, LOW);               // GET /Hr turns the Red LED on
        }
        if (currentLine.endsWith("GET /Lr")) {
          digitalWrite(LEDR, HIGH);                // GET /Lr turns the Red LED off
        }
        if (currentLine.endsWith("GET /Hg")){
          digitalWrite(LEDG, LOW);                // GET /Hg turns the Green LED on
        }
        if (currentLine.endsWith("GET /Lg")){
          digitalWrite(LEDG, HIGH);                // GET /Hg turns the Green LED on
        }
        if (currentLine.endsWith("GET /Hb")){
          digitalWrite(LEDB, LOW);                // GET /Hg turns the Green LED on
        }
        if (currentLine.endsWith("GET /Lb")){
          digitalWrite(LEDB, HIGH);                // GET /Hg turns the Green LED on
        } 
        
      }
    }
    // close the connection:
    client.stop();
    Serial.println("client disconnected");
  }
  
}

void printWiFiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your Wi-Fi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print where to go in a browser:
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
}

 

Portenta 보드가 AP로 동작되므로 스마트폰에서 접속시 사용될 SSID와 PASS를 설정한 파일을 arduino_secrets.h로 저장합니다.

#define SECRET_SSID "PortentaAccessPoint"
#define SECRET_PASS "123Qwerty"

 

M7 Core를 선택한 후 업로드를 합니다. 

만약 업로드시 아래와 같은 메시지가 발생된다면 아래 게시글을 참고하시기 바랍니다.

Access Point Web Server
Creating access point named: PortentaAccessPoint
Failed to mount the filesystem containing the WiFi firmware.
Usually that means that the WiFi firmware has not been installed yet or was overwritten with another firmware.

 

정상적으로 업로드가 되었다면 보드의 LED가 보라색으로 켜지며 시리얼 창을 열면 아래와 같은 메시지가 나옵니다.

메시지에 적힌 대로 스마트폰을 사용하여 192.168.3.1로 접속을 해 봅니다.

핸드폰에서 WIFI를 새로 검색 해 보면 PortentaAccessPoint가 검색됩니다.

선택하면 접속 암호를 넣는 창이 나옵니다. 위 arduino_secrets.h에서 적은 123Qwerty를 입력합니다.

정상적으로 연결이 되었다면 웹브라우저를 사용하여 192.168.3.1로 접속 해 봅니다.

그러면 아래와 같이 LED를 켜고 끌수 있는 웹페이지가 보여집니다.

해당 LED의 ON/OFF를 터치하면 시리얼 창에 아래와 같은 GET /Lg, /Lb 등의 로그가 찍히고 동시에 RGB LED가 켜지고 꺼지는 동작을 합니다.

Portenta H7 보드와 사용 중인 갤럭시 S20을 사용하여 테스트되었습니다.

반응형

댓글