제조공정
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
| ||||
|
2019년 중국-미국 영 메이커 대회 업데이트
소개
정원 가꾸기는 어떤 사람들에게는 재미있는 취미일 수 있지만 많은 사람들에게는 다루기 힘든 일입니다. 이 기사에서는 센서 데이터를 Azure IoT Hub로 보내고 Azure 기능을 통해 Azure SQL을 통해 저장하는 동시에 플랜트의 물을 자동 및 원격으로 제어하는 스마트 IoT 플랜트를 구축하는 방법에 대한 간단한 가이드를 작성하고 있습니다.
Helium IoT Hub는 원활한 방식으로 Azure IoT Hub에 연결됩니다. 이 문서에서는 전체 프로세스가 어떻게 작동하는지 설명합니다. 전체 프로젝트가 서버리스이기 때문에 전체 프로세스가 작동하는 데 필요한 유일한 코드는 Azure Function과 Arduino 코드뿐입니다.
1단계:구성 요소 수집
우리는
를 사용하여 간단한 제품을 만들고 있습니다. <울>
2단계:헬륨 및 센서로 Arduino 설정
이 기사에서는 Arduino를 앱으로 사용하는 데 중점을 둘 것입니다. 가장 먼저 Helium Atom에서 Helium Hub로 데이터를 푸시할 것입니다. 먼저 Helium Network Dashboard에 Atom을 등록해야 합니다.
Atom을 설정한 후에는 Element를 액세스 포인트로 등록해야 합니다(셀룰러 버전이 전원을 켜는 경우 가능).
요소를 활성화하면 액세스 포인트에서 볼 수 있습니다.
다음으로 모든 센서와 Helium Atom을 연결해야 합니다. 모든 작업이 완료되면 다음과 같이 보일 것입니다. 약간 지저분하지만 나중에 정리할 수 있습니다.
다음 코드를 실행하여 프로그램이 실행 중인지 알 수 있습니다.
#include "Arduino.h#include "Board.h#include "Helium.h#include "HeliumUtil.h#include #include "Arduino.h#include "Wire.h#include #include #define CHANNEL_NAME "Azure IoT App"Helium helium(&atom_serial);채널 채널(&helium);int relay =5;void setDisplayToOriginalState() { SeeedGrayOled.init(SSD1327);}void setup() { // 여기에 설정 코드를 넣어 한 번만 실행합니다. Serial.begin(9600); 핀모드(릴레이, 출력); 지연(150); /* HP20x_dev 재설정 */ TH02.begin(); 지연(100); Serial.println("TH02_dev를 사용할 수 있습니다.\n"); DBG_PRINTLN(F("시작 중")); // Helium Atom과 통신 시작 // baud rate는 지원되는 보드에 따라 다릅니다. // 이는 Board.h에 설정되어 있습니다. helium.begin(HELIUM_BAUD_RATE); // Atom을 헬륨 네트워크에 연결합니다. helium_connect(&helium); // 채널과 통신을 시작합니다. // 한 번만 수행하면 됩니다. HeliumUtil 함수는 연결이 끊긴 경우 채널을 다시 생성하기 위해 // 간단한 재시도 논리를 추가합니다. channel_create(&채널, CHANNEL_NAME); Wire.begin();}void loop() { //음향 오염 int 수분 =0; for (int i =0, i <32, i++) { 수분 +=analogRead(A0); } int 자외선 =0; for (int i =0, i <32, i++) { uvlight +=analogRead(A1); } 플로트 템퍼 =TH02.ReadTemperature(); 부동 습도 =TH02.ReadHumidity(); 문자열 dataString ="수분=" + 문자열(수분) + "&UVLight=" + 문자열(자외선) + "&Temperature=" + 문자열(온도) + "&습도=" + 문자열(습도); 문자 데이터[dataString.length()]; dataString.toCharArray(데이터, dataString.length()); channel_send(&채널, CHANNEL_NAME, 데이터, strlen(데이터)); Serial.println(데이터); setDisplayToOriginalState(); SeeedGrayOled.clearDisplay(); //디스플레이 지우기. SeeedGrayOled.setNormalDisplay(); //일반 디스플레이 모드 설정 SeeedGrayOled.setVerticalMode(); // 텍스트 표시를 위해 세로 모드로 설정 SeeedGrayOled.setTextXY(0, 0); //커서를 0번째 줄, 0번째 Column으로 설정 String 습기 string ="Moisture:" + String(moisture); char moibuffer[moisturestring.length()]; 수분 스트링.toCharArray(모이버퍼, 수분 스트링.길이()); SeeedGrayOled.putString(모이버퍼); SeeedGrayOled.setTextXY(2, 0); 문자열 uvstring ="자외선:" + 문자열(자외선); char uvbuffer[uvstring.length()]; uvstring.toCharArray(uv버퍼, uvstring.length()); SeeedGrayOled.putString(uvbuffer); SeeedGrayOled.setTextXY(4, 0); 문자열 온도 문자열 =문자열(성미) + " C"; 문자 임시 버퍼[온도 문자열.길이()]; temperaturestring.toCharArray(tempbuffer, temperaturestring.length()); SeeedGrayOled.putString(임시 버퍼); SeeedGrayOled.setTextXY(6, 0); 문자열 습도 문자열 ="습도:" + 문자열(습도); char 습도 버퍼[온도 문자열.길이()]; 습기 문자열.toCharArray(습습 버퍼, 습기 문자열.길이()); SeeedGrayOled.putString(습도 버퍼); if(수분 <100) { digitalWrite(릴레이, 높음); 지연(5000); digitalWrite(릴레이, LOW); } 지연(60000);}
워터 펌프는 12V가 필요하지만 일반적인 Arduino는 최대 5V만 출력하므로 잠금 장치가 작동하려면 아래 이미지와 같이 전원에 두 개의 와이어를 납땜하여 전원에 연결할 수 있습니다. 빨간색 선을 12V로 사용하고 검정색 선을 접지로 사용합니다.
릴레이는 언제 물을 펌핑할지 여부를 제어하는 역할을 합니다.
3단계:Helium Hub 및 Azure IoT Hub 설정
먼저 모든 서비스에서 IoT Hub를 생성합니다. IoT Hub를 즐겨찾기로 이동하여 훨씬 더 쉽게 액세스할 수 있도록 하는 것이 좋습니다. 무료 평가판 $200 평가판 크레딧으로 표준 등급을 사용할 수 있습니다. 프리 티어를 사용하도록 선택할 수도 있습니다.
이름을 선택한 후 크기 및 크기로 이동할 수 있습니다.
생성된 후에는 공유 액세스 정책->RegistryReadWrite 항목-> 연결 문자열 -- 기본 키로 이동해야 합니다. , 또한 레지스트리 읽기 및 레지스트리 쓰기가 선택되어 있는지 확인하십시오(기본값이어야 함).
연결을 테스트하기 위해 프로토타입을 위한 첫 번째 장치를 만들 수 있습니다.
기본 연결 문자열을 얻은 후 Helium 대시보드로 이동하여 Helium 연결을 생성합니다. 연결 문자열을 연결 필드에 붙여넣은 후 나머지는 모두 자동으로 채워집니다.
이것을 설정하면 Helium Hub에서 자동으로 생성되는 모든 MQTT 문자열을 얻을 수 있습니다. 채널을 통해 쉽게 접근할 수 있습니다.
Azure에서는 고정 MQTT 주제를 게시하고 구독하는 디바이스가 필요하므로 이를 통해 Helium Atom이 이를 수행할 수 있을 뿐만 아니라 IoT Hub가 Helium Atom에 메시지를 푸시할 수 있습니다. Azure로 보내는 것을 테스트하기 위해 다음을 수행할 수 있습니다.
git clone https://github.com/helium/helium-cli.gitcd helium-climake./helium -p /dev/
헬륨이 올바르게 설치되었는지 확인합니다.
./helium -p /dev/serial0 channel "Azure IoT App" 생성./helium -p /dev/serial0 channel send 1 "Hello Azure"
이렇게 하면 Atom에서 Azure로 직접 정보가 전송됩니다. Helium 대시보드와 Azure IoT Hub 개요에서 모두 확인해야 합니다.
그리고 아래의 Azure IoT Hub에서도 동일한 결과가 표시되어야 합니다.
장치는 X509를 통해 인증되며 Helium 플랫폼이 모든 것을 처리합니다. 간단하고 깔끔하게 만듭니다.
5단계:Azure SQL 데이터베이스 설정
다음으로 IoT 장치에서 오는 데이터를 저장할 수 있어야 합니다. 이에 대한 훌륭한 가이드가 https://blogs.msdn.microsoft.com/sqlserverstorageengine/2018/01/23/working-with-azure-iot-data-in-azure-sql-database/에 자세히 작성되어 있습니다. 이 기사에서는 이러한 일이 어떻게 일어나는지에 대한 빠른 통합에 중점을 둘 것입니다. 먼저 SQL 데이터베이스로 이동하여 아래 이미지와 같은 데이터베이스를 생성합니다. 앱을 시작할 때만 기본 계층을 선택할 수 있습니다. 무료 평가판 크레딧으로 이를 커버할 수 있습니다. 이것은 가장 저렴한 옵션입니다. 프로토타이핑의 경우 확장함에 따라 Cosmos의 최소 가격이 $25이므로 향후 Azure Cosmos로 이전할 수 있습니다.
그런 다음 쿼리 편집기를 사용하여 다음 테이블을 생성할 수 있습니다. 우선 Smart Plant IoT의 간단한 데이터 구조를 사용하여 시작하겠습니다.
CREATE TABLE SmartPlant (id bigint IDENTITY (1,1) NOT NULL, 온도 int NOT NULL, 습도 int NOT NULL, 수분 int NOT NULL, UVLight int NOT NULL, DateCreated datetime default CURRENT_TIMESTAMP)
이제 데이터를 저장할 테이블이 있으므로 데이터를 저장할 수 있도록 이 테이블을 eventhub에 연결해야 합니다. 연결 문자열로 이동하여 다음 단계를 위해 연결 문자열을 가져옵니다.
4단계:Azure 함수 앱 만들기
기능에 연결하기 위해 Event Hub를 사용합니다. 먼저 서버리스 구조를 허용하는 Azure Function App을 만들어야 합니다. 이는 더 이상 유지 관리할 필요가 없기 때문에 IoT 애플리케이션에 적합합니다. 시작하려면 먼저 계산 중인 함수 앱을 만들어야 합니다.
이 설정에서 함수를 만들 수 있습니다.
몇 분 정도 시간을 주시면 알림을 통해 알려드리겠습니다.
함수 앱 배포
이제 함수가 있으므로 이벤트 허브를 실행할 수 있도록 IoT Hub(Event Hub) 트리거 아래에 함수를 만듭니다. 기능->플랫폼 기능->애플리케이션 설정
으로 이동합니다.여기에 이전 단계에서 만든 연결 문자열을 추가합니다. 생성 후 저장
다음 단계는 Event Hub 함수를 만드는 것입니다. 이 예에서는 C#을 사용합니다. 새 연결을 클릭하면 항목이 자동으로 채워집니다.
함수를 다음으로 변경합니다. Azure SQL Database에 데이터를 직접 삽입하기 위한 것입니다.
System.Configuration 사용, System.Data.SqlClient 사용, System.Threading.Tasks 사용, public static async Task Run(string myIoTHubMessage, TraceWriter log){var map =myIoTHubMessage.Split('&'). Select(x => x.Split('=')).ToDictionary(x => x[0], x => x[1]); 문자열 온도 =map["온도"]; 문자열 H 문자열 수분 =map["수분"]; 문자열 UVLight =map["UVLight"];var str =ConfigurationManager.ConnectionStrings["sqldb_connection"].ConnectionString;using (SqlConnection conn =new SqlConnection(str)) { conn.Open();var text ="INSERT INTO dbo. SmartPlant(Temperature, using (SqlCommand cmd =new SqlCommand(text, conn)) {// 명령을 실행하고 # 행의 영향을 받은 행을 기록합니다.var rows =await cmd.ExecuteNonQueryAsync(); log.Info($"{rows} rows 업데이트되었습니다"); } } log.Info($"C# IoT Hub 트리거 함수가 메시지를 처리했습니다:{myIoTHubMessage}");}
성공하면 볼 수 있어야 합니다.
이 시점에서 Azure IoT Hub를 통해 Helium에서 Azure SQL로 보내는 전체 종단 간 데이터가 있습니다. 다음으로 Azure Function API를 통해 HTTP 트리거를 만드는 데 필요한 데이터를 검색해야 합니다.
/api/smartplant에 액세스할 수 있도록 라우팅을 /data로, 익명으로 인증 수준을, GET 전용 HTTP 메서드를 사용하여 몇 가지 값을 변경합니다.
코드의 경우 주소에 액세스하여 테스트할 수 있습니다.
http://
이것은 결과를 테스트하고 "hello foobar"를 반환합니다. 이 작업이 완료되면 다음 코드를 사용하여 실제 데이터를 반환할 수 있습니다. 다음으로 다음 코드를 사용하여 전체 앱을 테스트할 수 있습니다. 이것은 더 복잡한 쿼리를 작성하여 추가 정보를 수집할 수 있는 가장 간단한 쿼리이지만 프로토타입의 경우 하나의 레코드를 얻는 데만 집중할 것입니다.
#r "System.Configuration#r "System.Data"#r "Newtonsoft.Json" 사용 System; 사용 System.Net 사용; System.Configuration 사용; System.Data.SqlClient 사용; System. Threading.Tasks, System.Text 사용, Newtonsoft.Json 사용, public static async Task Run(HttpRequestMessage req, TraceWriter log){ log.Info("C# HTTP 트리거 함수가 요청을 처리했습니다.");var str =ConfigurationManager .ConnectionStrings["sqldb_connection"].ConnectionString;using (SqlConnection conn =new SqlConnection(str)) { conn.Open();var text ="SELECT Top 100 온도, 수분, UVLight SmartPlant ret =new SmartPlant();using( SqlCommand cmd =new SqlCommand(text, conn)) { SqlDataReader 판독기 =대기 cmd.ExecuteReaderAsync();try {while (reader.Read()) { ret.Temperature =(int)reader[0]; ret.Moisture =( int)reader[1]; ret.UVLight =(int)reader[2]; ret.Humidity =(int)reader[3]; } }finally {// 읽기가 끝나면 항상 Close를 호출합니다.reader.Close(); }var json =JsonConvert.SerializeObject(ret, 양식 atting.Indented);return new HttpResponseMessage(HttpStatusCode.OK) { 콘텐츠 =new StringContent(json, Encoding.UTF8, "application/json") }; } }}public class SmartPlant{ public float Temperature { get; 세트; } public float 수분 { get; 세트; } 공개 float UVLight { get; 세트; } public float 습도 { get; 세트; }}
모든 작업이 완료되면 최신 레코드에 대한 결과를 산출해야 합니다.
5단계:출력용 UI
이제 모든 것이 끝에서 끝까지 연결되었으므로 식물의 전반적인 상태를 확인할 수 있는 간단한 Android 애플리케이션을 빌드할 수 있습니다. 이 경우 매우 간단한 Android 앱을 사용하여 식물 주변에 있는 4개의 센서를 모니터링하고 필요한 경우 식물에 물을 주기 위해 연동 펌프를 트리거합니다. 아래와 같이 정보를 표시하고 업데이트 해야 합니다. 데이터는 60초마다(또는 원하는 대로) 전달되어야 합니다.
다른 쪽에서는 Arduino 인클로저를 닫을 수 있으므로 공장 옆에서 훨씬 더 잘 볼 수 있습니다.
자체 펌핑을 쉽게 시뮬레이션할 수 있습니다.
추가 사항:Alexa 통합 섹션> <섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드">
#r "System.Configuration#r "System.Data#r "Newtonsoft.Json" 호출에서 편안한 호출, System.Net 사용, System.Configuration 사용, System.Data 사용. SqlClient, System.Threading.Tasks 사용, System.Text 사용, Newtonsoft.Json 사용, public static async TaskRun(HttpRequestMessage req, TraceWriter log){ log.Info("C# HTTP 트리거 함수가 요청을 처리했습니다.");var str =ConfigurationManager.ConnectionStrings["sqldb_connection"].ConnectionString;using (SqlConnection conn =new SqlConnection(str)) { conn.Open();var text ="dbo.IoTData 순서에서 상위 100개 온도, 수분, UVLight 선택 DateCreated DESC에 의해"; EventData ret =new EventData();using(SqlCommand cmd =new SqlCommand(text, conn)) { SqlDataReader 리더 =cmd.ExecuteReaderAsync()를 기다립니다.{while(reader.Read()) { ret.Temperature =(int) 리더[0]; ret.Moisture =(int)reader[1]; ret.UVLight =(int)reader[1]; } }finally {// 읽기가 끝나면 항상 Close를 호출합니다. 독자.닫기(); }var json =JsonConvert.SerializeObject(ret, Formatting.Indented); return new HttpResponseMessage(HttpStatusCode.OK) { 콘텐츠 =new StringContent(json, Encoding.UTF8, "응용 프로그램/json") }; } }}public class SmartPlant{ public float Temperature { get; 세트; } public float 수분 { get; 세트; } 공개 float UVLight { get; 세트; }}
#r "System.Configuration#r "System.Data"에 직접 삽입, System.Configuration 사용, System.Data.SqlClient 사용, System.Threading.Tasks 사용, System.Net 사용, public static async TaskRun(HttpRequestMessage req, TraceWriter 로그){ string Temperature =req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "Temperature", true) ==0) .Value; 문자열 수분 =req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "수분", true) ==0) .Value; 문자열 UVLight =req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "UVLight", true) ==0) .Value; if (Temperature ==null || Moisture ==null || UVLight ==null) { // 요청 본문 가져오기 return req.CreateResponse(HttpStatusCode.BadRequest, "쿼리 문자열 또는 요청 본문에 이름을 전달하세요"); } var str =ConfigurationManager.ConnectionStrings["sqldb_connection"].ConnectionString; 사용 (SqlConnection conn =new SqlConnection(str)) { conn.Open(); var text ="INSERT INTO dbo.SmartPlant (온도, 수분, UVLight) VALUES(" + 온도 + ", " + 수분 + ", " + UVLight + ");"; using (SqlCommand cmd =new SqlCommand(text, conn)) { // 명령을 실행하고 영향을 받은 # 행을 기록합니다. var 행 =cmd.ExecuteNonQueryAsync()를 기다립니다. log.Info($"{rows}개의 행이 업데이트되었습니다."); } } 반환 req.CreateResponse(HttpStatusCode.OK, "성공");}
#include "Arduino.h#include "Board.h#include "Helium.h#include "HeliumUtil.h#include#include "Arduino.h#include "Wire.h#include #include #define CHANNEL_NAME "Azure IoT App"Helium helium(&atom_serial);채널 채널(&helium);int relay =5;void setDisplayToOriginalState(){ SeeedGrayOled.init(SSD1327);}void setup() { // 여기에 설정 코드를 입력하여 한 번 실행:Serial.begin(9600); 핀모드(릴레이, 출력); 지연(150); /* HP20x_dev 재설정 */ TH02.begin(); 지연(100); Serial.println("TH02_dev를 사용할 수 있습니다.\n"); DBG_PRINTLN(F("시작 중")); // Helium Atom과 통신 시작 // baud rate는 지원되는 보드에 따라 다릅니다. // 이는 Board.h에 설정되어 있습니다. helium.begin(HELIUM_BAUD_RATE); // Atom을 헬륨 네트워크에 연결합니다. helium_connect(&helium); // 채널과 통신을 시작합니다. // 한 번만 수행하면 됩니다. HeliumUtil 함수는 연결이 끊긴 경우 채널을 다시 생성하기 위해 // 간단한 재시도 논리를 추가합니다. channel_create(&채널, CHANNEL_NAME); Wire.begin();}void loop() { //음향 오염 int 수분 =0; for (int i =0, i <32, i++) { 수분 +=analogRead(A0); } int 자외선 =0; for (int i =0, i <32, i++) { uvlight +=analogRead(A1); } 플로트 템퍼 =TH02.ReadTemperature(); 부동 습도 =TH02.ReadHumidity(); 문자열 dataString ="수분=" + 문자열(수분) + "&UVLight=" + 문자열(자외선) + "&Temperature=" + 문자열(온도) + "&습도=" + 문자열(습도); 문자 데이터[dataString.length()]; dataString.toCharArray(데이터, dataString.length()); channel_send(&채널, CHANNEL_NAME, 데이터, strlen(데이터)); Serial.println(데이터); setDisplayToOriginalState(); SeeedGrayOled.clearDisplay(); //디스플레이 지우기. SeeedGrayOled.setNormalDisplay(); //일반 디스플레이 모드 설정 SeeedGrayOled.setVerticalMode(); // 텍스트 표시를 위해 세로 모드로 설정 SeeedGrayOled.setTextXY(0, 0); //커서를 0번째 줄, 0번째 Column으로 설정 String 습기 string ="Moisture:" + String(moisture); char moibuffer[moisturestring.length()]; 수분 스트링.toCharArray(모이버퍼, 수분 스트링.길이()); SeeedGrayOled.putString(모이버퍼); SeeedGrayOled.setTextXY(2, 0); 문자열 uvstring ="자외선:" + 문자열(자외선); char uvbuffer[uvstring.length()]; uvstring.toCharArray(uv버퍼, uvstring.length()); SeeedGrayOled.putString(uvbuffer); SeeedGrayOled.setTextXY(4, 0); 문자열 온도 문자열 =문자열(성미) + " C"; 문자 임시 버퍼[온도 문자열.길이()]; temperaturestring.toCharArray(tempbuffer, temperaturestring.length()); SeeedGrayOled.putString(임시 버퍼); SeeedGrayOled.setTextXY(6, 0); 문자열 습도 문자열 ="습도:" + 문자열(습도); char 습도 버퍼[온도 문자열.길이()]; 습기 문자열.toCharArray(습습 버퍼, 습기 문자열.길이()); SeeedGrayOled.putString(습도 버퍼); if(수분 <100) { digitalWrite(릴레이, 높음); 지연(5000); digitalWrite(릴레이, LOW); } 지연(60000);}
제조공정
다양한 도시와 마을에 걸쳐 물의 수요는 다양한 소비 요인에 따라 달라지고 물 공급업체는 수요와 공급의 격차를 채우기 위해 실시간으로 물 공급을 유지해야 하기 때문에 물 공급이 큰 문제였습니다. 그러나 문제는 소비 추세를 계산하는 것입니다. 물 소비량을 추적하고 물을 낭비하지 않고 물 과소비를 감지하는 등 다양한 방법이 도시 주변의 물 소비량을 줄이기 위해 많이 시행되었습니다. 다행히도 Smart Water Meters는 급변하는 물 수요를 충족시키기 위해 물 유통업체와 소비자에게 완벽한 솔루션을 제공하고 있습니다. 많은 회사에서
UN은 2025년까지 전 세계적으로 약 18억 명의 사람들이 절대적인 물 부족 지역에 살게 될 것이라고 보고합니다. 현재의 물 시나리오에서 미국 정부는 향후 20년 동안 기존 기반 시설을 재건하고 업그레이드하는 데 거의 40억 달러를 지출할 것입니다. 최종 사용자가 사용할 수 있는 담수는 지구의 1%에 불과하고 대부분의 사람들은 외풍으로 고통 받고 있습니다. 이러한 희소성을 끝내고 재난을 예방하기 위해서는 급증하는 기술이 절실히 필요합니다. 수질 모니터링 시 중점을 두는 4가지 주요 영역이 있습니다. 식수의 품질, 환경 정