Pico W 기초부터 클라우드 연동까지!
콘테스트 프로젝트완료

smart home project(온도 모니터링 및 미세먼지 데이터 모니터링 시스템)

Pico W 기초부터 클라우드 연동까지!
2022.08.14에 시작
2
좋아요
2.7K
조회
0
댓글
smart home project(온도 모니터링 및 미세먼지 데이터 모니터링 시스템)

사용 기술

ArduinoHome AutomationInternet of ThingsRaspberry Pi
Pico W 기초부터 클라우드 연동까지!완료
콘테스트 프로젝트 진행 상황

각 Quest를 단계적으로 완성하는 프로젝트입니다.

Quest 1
Quest 2
Quest 3
Quest 4
4 / 4 완료
Quest 1: 미세 미세 (미세먼지 모니터링 시스템) + 무드등
2022.08.14
완료

□ 아이디어 소개 및 개요 (개발 계획 및 과정 포함)

홈 IoT 시스템이 뜨거운 감자로 다양한 아이템이 나오고 있다. 하지만 각 센서를 모니터링 하는 시스템과 사용자가 모니터링 시스템을 선보이며 로컬 상태에서 확인 할 수 있는 LED와 DISPLAY을 이용해서 현재 대기질 상태를 원하는 구역마다 확인 할 수 있도록 한다.

로컬 상태뿐 아니라 모바일 어플리 케이션을 이용하여 미세먼지의 현황과 LED의 ON/OFF 또는 무드등 모드 변경을 통해서 사용자가 원하는 모드를 취사 선택을 할수 있도록 기획한다.

서버의 경우 자체적인 APM 서버와 TCP 통신을 통해서 센서 데이터를 DB에 저장하며 사용자는 이를 기록의 형태로 확인 할 수 있다.

 

 

□ 하드웨어 구성 다이어그램 & 전체 구조를 표현하는 블록 다이어그램

□ 소프트웨어 구성 다이어그램

Quest 2: 미세 미세 (미세먼지 모니터링 시스템) _ PART1 개발환경 구축
2022.08.29
완료

다양한 라즈베리파이 시리즈를 사용했지만 이번에 처음으로 PICO 시리즈인 W를 사용하게 되었다.

영롱하다... 늘 짜릿해...

해당 개발 보드의 환경은 arduino ide를 사용하기로 하였다. 이외에도 VSCODE나 CLION을 이용하는 방법도 있다고 한다. 이방법은 추후 추가해보고자 한다.

우선 arduino ide를 열어 pico 칩셋인 RP2040을 추가 해야 한다.

ide  파일 -> 환경 설정 -> 보드 매니저 URL에 해당 주소를 추가 한다.

https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json

툴 -> 보드 매니저 -> raspberry  를 입력하게 되면

다음 칩셋을 선택하여 설치를 진행한다.

 

선택은 다음 보드를 선택한다.

 

정상적으로 작동을 확인 하기 위해 다음 코드를 사용했다.

// Simple WiFi network scanner application
// Released to the public domain in 2022 by Earle F. Philhower, III
#include <WiFi.h>

void setup() {
  Serial.begin(115200);
}

const char *macToString(uint8_t mac[6]) {
  static char s[20];
  sprintf(s, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  return s;
}

const char *encToString(uint8_t enc) {
  switch (enc) {
    case ENC_TYPE_NONE: return "NONE";
    case ENC_TYPE_TKIP: return "WPA";
    case ENC_TYPE_CCMP: return "WPA2";
    case ENC_TYPE_AUTO: return "AUTO";
  }
  return "UNKN";
}

void loop() {
  delay(5000);
  Serial.printf("Beginning scan at %d\n", millis());
  auto cnt = WiFi.scanNetworks();
  if (!cnt) {
    Serial.printf("No networks found\n");
  } else {
    Serial.printf("Found %d networks\n\n", cnt);
    Serial.printf("%32s %5s %17s %2s %4s\n", "SSID", "ENC", "BSSID        ", "CH", "RSSI");
    for (auto i = 0; i < cnt; i++) {
      uint8_t bssid[6];
      WiFi.BSSID(i, bssid);
      Serial.printf("%32s %5s %17s %2d %4d\n", WiFi.SSID(i), encToString(WiFi.encryptionType(i)), macToString(bssid), WiFi.channel(i), WiFi.RSSI(i));
    }
  }
  Serial.printf("\n--- Sleeping ---\n\n\n");
  delay(5000);
}

해당 코드를 업로드 한뒤 ide의 serial monitor을 확인 해보면 다음과 같이 네트워크를 스캔하는 것을 확인 할 수 있다.

 

이후 mysql에 센서 데이터를 받아서 기록 할 수 있는 데이터 베이스를 생성 하였다.

해당 db에 접속하여 각 센서 데이터를 연동하는 것을 다음 과정에서 진행하고자 한다.

Quest 3: Pico W - 클라우드 연결
2022.09.11
완료

이번에는 저번 주차에서 연결한 wifi를 기반으로 HTTP GET 통신을 이용하여 본 프로젝트에서 사용할 데이터를 연결해보고자 한다.

 

GET 통신을 위해서는 클라우드 서버에 다음과 같은 PHP 구문을 작성해준다.

<?php
// DB 접속
$con=mysqli_connect("127.0.0.1","ID","PW","DB_NAME");
// 접속 실패 시 메시지 나오게 하기
if (mysqli_connect_errno($con))
{ echo "MySQL접속 실패: " . mysqli_connect_error(); }

// 기본 클라이언트 문자 집합 설정하기
mysqli_set_charset($con,"utf8");
// 쿼리문 실행, 결과를 res에 저장
$res = mysqli_query($con, "select * from `project_status`");
// 결과를 배열로 변환하기 위한 변수 정의
$result = array();
// 쿼리문의 결과(res)를 배열형식으로 변환(result)
while($row = mysqli_fetch_array($res))
{ array_push($result, array('status'=>$row[0],'R'=>$row[1],'G'=>$row[2],'B'=>$row[3])); }
// 배열형식의 결과를 json으로 변환
echo json_encode(array("result"=>$result),JSON_UNESCAPED_UNICODE);
// DB 접속 종료
mysqli_close($con);
?>

해당 코드는 URL상에서 http://cloud.park-cloud.co19.kr/project/view_status.php 링크를 통해 접속하게 되면 DB에 연결되어 최신데이터 값을 조회할 수 있도록 하였다.

 

다음은 아두이노 코드이다.

//insert 관련
//http://cloud.park-cloud.co19.kr/project/insert.php?temp=45&hum=25&pm1=150&pm2=200&pm3=20 다음과 같은 주소 형식으로 데이터를 보낼 예정

//status 관련
//INSERT INTO `project_status` (`status`, `R`, `G`, `B`) VALUES ('0', '255', '255', '255');
//UPDATE `project_status` SET `status`=1,`R`=255,`G`=250,`B`=250 WHERE 1
//http://cloud.park-cloud.co19.kr/project/update_status.php?status=0&R=200&G=100&B=20

//view 관련
//http://cloud.park-cloud.co19.kr/project/view.php
//http://cloud.park-cloud.co19.kr/project/view_status.php

#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>

#ifndef STASSID
#define STASSID "iptime_projecter"
#define STAPSK "134625wo"
#endif

const char *ssid = STASSID;
const char *pass = STAPSK;

WiFiMulti WiFiMulti;

String sta, R, G, B;
int count = 0;
int mode_number = 0;

//----------------------------LED---------------------------------
#include <NeoPixelConnect.h>
#define MAXIMUM_NUM_NEOPIXELS 16

// Create an instance of NeoPixelConnect and initialize it
// to use GPIO pin 4 (D12) as the control pin, for a string
// of 8 neopixels. Name the instance p

NeoPixelConnect p(4, MAXIMUM_NUM_NEOPIXELS, pio0, 0);
//----------------------------LED---------------------------------

void setup() {

  Serial.begin(115200);
  // Serial.setDebugOutput(true);

  Serial.println();
  Serial.println();
  Serial.println();

  WiFiMulti.addAP(ssid, pass);
}

void loop() {
  // wait for WiFi connection
  if ((WiFiMulti.run() == WL_CONNECTED)) {

    HTTPClient http;

    Serial.print("[HTTP] begin...\n");
    if (http.begin("http://cloud.park-cloud.co19.kr/project/view_status.php")) {  // HTTP


      Serial.print("[HTTP] GET...\n");
      // start connection and send HTTP header
      int httpCode = http.GET();

      // httpCode will be negative on error
      if (httpCode > 0) {
        // HTTP header has been send and Server response header has been handled
        Serial.printf("[HTTP] GET... code: %d\n", httpCode);

        // file found at server
        if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
          String payload = http.getString();
          Serial.println(payload);
        }
      } else {
        Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
      }

      http.end();
    } else {
      Serial.printf("[HTTP} Unable to connect\n");
    }
  }

  delay(10000);
}

 

아직 LED 부품이 오지 못하여 미리 코드 선언부만 작성된 상태이지만 HTTP  연동 코드만 작성되었다. 본 코드는 HTTP Respone 구문을 통해서 자신의 mode를 결정 하고 결정된 모드를 통해서 RGB  데이터를 수신 하거나 미세먼지 센서를 받아오는 역활을 수행하게 된다.

 

작동 결과는 다음과 같다.

다음 차시에는 업로드 가능한 페이지와 flutter앱과 dust센서의 업로드  PHP를 작성하고자 한다.

Quest 4: Quest4: 최종 결과물 완성 (RPI Pico W와 클라우드를 연동한 미세먼지 무드등)
2022.10.02
완료

이번에는 기초적인 회로 동작을 확인 하고 이에 맞춰서 케이스를 설계하며 프로젝트를 마무리해보고자 합니다.

Raspberry Pi Pico W Pinout, Datasheet, Features, Specs

회로 결선은 pico의 pinmap을 참고 하면 다음과 같이 핀들의 기능이 분포 되어 있는 것을 확인 할 수 있습니다.

회로도 설계

여기서 제가 사용하고자 하는 미세먼지 센서 PMS7003A와 WS2812B 의 필요 핀맵인 GP1(UART RX), GP2(PWM)을 선정하였습니다.

이외에도 VCC와 GND를 참고하여 다음과 같은 간이 배선도를 제작 하였습니다.

배선도를 바탕으로 각 부품들이 원하는 위치에 고정 될 수 있도록 설계를 진행 합니다.

기구 설계 (3D)

fusion 360을 이용하여 각 부품들의 거치 여부를 확인 했습니다. 렌더링 결과물은 다음과 같습니다.

센서에 흡기가 정상적으로 이루어 질 수 있도록 배기 구멍을 반영하여 설계 하였습니다.

 

설계가 완성 된후 부품들의 가조립을 위해 다음과 3D printing을 진행합니다.

 

가조립과 납땜을 동시에 진행 했습니다.

정상적으로 각 파츠들이 거치된 상태로 문제 없이 고정되는 것을 확인 하였습니다.

 

이후 최종적으로 APM server와 정상적으로 통신하여 동작하는 코드를 작성합니다.

간략하게 동작에 관여하는 부분을 살펴 보면 PICO에서는 미세먼지,  HTTP로 크게 2단계로 나눌 수 있습니다.

미세먼지 센서 처리

미세먼지 센서로 사용하는 PMS7003M의 경우 UART 통신을 지원하며 센서에 전원이 인가되면 주기적으로 센싱 데이터를 송출하는 방식을 이용합니다.

데이터는 다음과 같이 32byte이며 9600의 보더 레이트를 사용합니다. 

우선 pms 센서와 UART 통신을 위한 class를 선언 하고 위 데이터 시트에서 확인 한 보더레이트 속도를 맞춥니다.

응답 데이터는 총 32 Byte의 데이터가 들어오므로 데이터가 들어오게 되면 조건문을 이용해 총 32개의 데이터를 행렬에 대입합니다.

각 대입된 위치는 정해져 있으므로 각 위치 행렬을 8bit shfit 연산과 OR연산을 통해서 정수형으로 데이터를 받아 옵니다.

이 데이터를 통해서 APM server에 업로드 하거나, LED의 상태를 제어하는데 사용합니다.

 

HTTP 통신

 

2개의 주소를 통해서 현재 모드(미세먼지 감지모드, 무드등 모드)를 판별한후

미세먼지 감지 모드에서는 이전에 측정된 센서 데이터를 HTTP통신을 통해서 데이터를 업로드 합니다.

무드등 모드에서는사용자가 지정해둔 R G B 데이터를 받아와 LED의 색상 데이터로 사용합니다.

 

APPLICATION(FLUTTER)

어플리 케이션의 경우 위 PICO와 유사하게 HTTP를 통해서 저장된 데이터를 받아오거나, COLOR 선택을 APM server에 업로드를 진행합니다.

Main page에서는 주기적인 시간동안 지정된 주소에 접속하여 미세먼지 농도 데이터를 받아오고 이를 chart 위젯에 하나씩 추가합니다. 이때 업데이트 시간은 PICO 업데이트와 동일한 시간대를 사용하여 실시간으로 데이터를 확인 합니다.

 

두번째 색상 선택기에서는 지정된 색을 사용자가 취사 선택한후 적용 버튼을 입력하였을때 선택된 색의 RGB 데이터를 추출하여 서버에 색상을 업데이트 하는 경로에 접속합니다.

이를 통해서 사용자가 기기의 모드와 색상을 취사 선택할 수 있는 어플 또는 인터페이스를 획득 할 수 있습니다.

 

위 작품들의 동작 결과는 다음과 같이 확인 할 수 있습니다.

 

혹 코드나 데이터가 필요하실 분들을 위해서 github link를 같이 첨부 합니다.

https://github.com/MAKER-park/PICOW_MINI_PROJECT.git

 

-후기 ...

본 프로젝트를 통해서 PICO 시리즈를 처음 다뤄 보게 되었는데.. 다양한 PICO board의 특성들을 파악 할 수 있었습니다.

CORTEX M 포지션에서 저렴한 보드로써 ESP32와 비슷한 포지션에 있다는 느낌을 많이 받을 수 있었습니다. 약간 사적으로 보면 ESP8266 과 ESP32 사이 느낌이 강하게 들었습니다.

짧은 기간 PICO 보드를 사용해본것이 생각보다 인상 깊었고 이과정에서 부족했던 부분을 보완해서 다른 프로젝트에서도 다양하게 활용해보고 싶어졌습니다.

 

프로젝트 자료실

프로젝트를 재현하거나 학습하는데 필요한 모든 자료를 제공합니다.

등록된 자료가 없습니다.

프로젝트 소개

사용 기술
ArduinoHome AutomationInternet of ThingsRaspberry Pi

코드 & 회로도

등록된 코드/회로 자료가 없습니다.

댓글 0

아직 댓글이 없습니다. 첫 댓글을 남겨보세요!