본문 바로가기
대한상공회의소 스마트팩토리 교육/IoT 디바이스 개발

[IoT 디바이스 개발] 아두이노«평가» : Arduino Mega 2560를 활용한 과목 최종 평가

by 나는영하 2022. 3. 13.

※ 주의사항 

본 블로그는 수업 내용을 바탕으로 제가 이해한 부분을 정리한 블로그입니다.
본 내용을 참고로만 보시고, 틀린 부분이 있다면 지적 부탁드립니다!

감사합니다😁

 

안녕하세요!!

최근에 Arduino Mega 2560을 이용하여 본 과목의 최종 평가를 진행하였습니다.

진행 과정과 제가 작성한 코드 및 하드웨어 동작을 설명하는 내용을 담아보았습니다.


1. 평 가 문 항

❗ 오픈 플랫폼인 아두이노(MEGA 2560)을 활용하여 다음 센서의 값을 주기적으로 PC 터미널, Text LCD에 출력하고, IoT Cloud Platform인 Thingspeak로 전송하여 모니터링 할 수 있도록 구현하시오.

✅ 기능 1. ·습도, 조도, 수위 측정 센서값 정보를 PC 터미널로 주기적으로(30) 전송하여 출력하고,

온도, 습도 센서값 정보는 Text LCD로도 출력하시오 (수위측정센서값은 0~40mm, 조도값은 0~1000lux로 변환)

✅ 기능 2. ESP8266-01 WIFI 모듈을 활용하여 학습실 내의 WIFI 망에 접속하여 상기 센서값을 IoT Cloud Platform인 Thingspeak에 전송하여 모니터링 하도록 구현하시오.

 


 

2. 회로 및 동작 사진

2-1. 회로 구성 사진

 

- A4 PIN : 온·습도 모듈(DHT-11) 결선

- A5 PIN : 조도 센서(포토 다이오드) 결선

- A6 PIN : 수위 측정 센서 결선

- 18, 19 PIN : UART1번(TX, RX)핀, WIFI 모듈(ESP8266)에 Corss 결선

- 20, 21 PIN : I2C 통신(SDA,SCL) 관련 핀, Text LCD의 후면 I2C 핀에 1:1 결선

- WIFI를 위한 전원 3.3V는 별도의 Atmega128A의 전원부에서 공급.

(아두이노에서 3.3V 까지 공급시 전원 부족현상 발생, 통신오류 및 불량)

 

2-2. PC 터미널 및 IoT Cloud Platform 모니터링 사진

PC 터미널(좌) / IoT Cloud Platform(우)

 

- 조도센서, 온습도센서, 수위측정센서를 통해 받은 값을 WIFI 모듈을 통해 IoT Cloud Platform에 데이터 전달

- 조도 값이나 수위 측정 센서값의 데이터는 해당 센서의 Datasheet를 참고하지 않고 임의로 산출한 값으로, 정확한 값을 구하고 싶으면 DataSheet를 참고해서 데이터 가공이 필요함.

- "ThingSpeak"의 내 채널에서 API Key를 확인해서 Wifi 모듈을 통해 센서 Data값을 전송

(ThingSpeak의 Free버전은 보낼 수 있는 Data의 갯수와 생성할 수 있는 Channel이 한정되어 있기때문에 확인 필요. 또한 전송 주기에도 제한이 있기 때문에(약 15초 이상) 충분한 시간을 가지고 DATA 전송 필요, 본 코드에서는 delay를 30초를 설정하였습니다.)

 


 

3. Source Code

3-1. 전처리문(WIFI 설정부)

String ssid = "KCCI_STC_S";
String pwd = ********* // 비밀번호 입력
String API = "030677JJJBENA3XR"; // 개인 채널의 write API KEY
String HOST = "api.thingspeak.com"; // site URL
String PORT = "80";
String field = "field1"; //조도 센서 저장 필드
String field_2 = "field2"; // 온도 센서 저장 필드
String field_3 = "field3"; // 습도 센서 저장 필드
String field_4 = "field4"; // 수위 센서 저장 필드

int Txcount;
int countTimeCommand;
boolean found = false;
int LightSensorVal = 1;
int TempSensorVal = 1;
int HumiSensorVal = 1;
int WaterSensorVal = 1;
- 학습실 내에서 사용하는 WIFI ID 및 PW를 변수에 저장 (추후 WIFI 모듈 초기 설정시 필요)
- IoT Cloud Platform인 Thingspeak내 나의 채널의 API Key 값과 각 센서값, 필드를 저장할 변수 설정
 

3-2. 전처리문(Sensor 및 LCD 설정부)

#include <DHT.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

#define Water_sensor A6
#define Light_sensor A5
#define DHTPIN A4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
int humi, temp, LightValue2, WaterLevel2;

// "°C" 기호 만들어서 출력
byte customCharA[] = {
	B01000,
	B10100,
	B01000,
	B00010,
	B00101,
	B00100,
	B00101,
	B00010
};
- LCD뒤 I2C칩 주소에 해당되는 값(0x27) 확인 후 LCD_I2C 라이브러리를 통해 초기화 설정
- DHT-11 모듈(온습도센서)은 DHT.h 라이브러리를 활용해서 초기화 설정
- LCD 출력시 사용할 "°C" 기호를 커스트마이징해서 행렬형태로 저장

 

3-3. LCD Setup 및 출력 함수부

void lcd_setup() {
	lcd.init();
	lcd.backlight();
	lcd.print("Arduino Test!!");
	lcd.setCursor(0, 1);
	lcd.print("2022.03.10");
	delay(2000);
	lcd.clear();
	lcd.print("Temp : ");
	lcd.createChar(1, customCharA);
	lcd.setCursor(11, 0);
	lcd.write(1);
	lcd.setCursor(0, 1);
	lcd.print("Humi : %");
}

void lcd_loop() {
	lcd.setCursor(8, 0);
	lcd.print(temp);
	lcd.setCursor(8, 1);
	lcd.print(humi);
}
- 온도와 습도의 값을 저장하는 변수는 주기적으로 변하기 때문에 loop함수에 넣어주고 그외의 글자는 setup함수부에서 서 출력
- "°C" 기호를 커스트마이징한 행렬형태의 변수를 createChar 명령어를 통해 1번 버퍼에 저장 및 출력

 

3-4. Sensor 출력 함수부

void light_loop() {
	int LightValue = analogRead(Light_sensor);
	LightValue2 = map(LightValue, 0, 1023, 0, 1000);
	Serial.print("조도값(lux) : ");
	Serial.println(LightValue2);
}

void humitemp_loop() {
	humi = dht.readHumidity();
	temp = dht.readTemperature();
	Serial.print("습도(%) : ");
	Serial.println(humi);
	Serial.print("온도(°C) : ");
	Serial.println(temp);
}

void waterLevel_loop() {
	int WaterLevel = analogRead(Water_sensor);
	WaterLevel2 = map(WaterLevel, 0, 1023, 0, 40);
	Serial.print("수위값(mm) : ");
	Serial.println(WaterLevel2);
}

- map 함수로 Analog 핀을 통해 받은 값(0~1023)을 각 센서의 수치에 알맞은 범위로 변경

 

3-5. Main Setup 함수부

void setup() {
	dht.begin();
	lcd_setup();
	Serial.begin(115200);//Serial --> uart00 즉, 컴퓨터
	Serial1.begin(115200); //Serial1 --> uart1 즉,WIFI
	sendCommand("AT", 5, "OK");
	sendCommand("AT+CWMODE=1", 5, "OK");
	sendCommand("AT+CWJAP=\"" + ssid + "\",\"" + pwd + "\"", 20, "OK");
}
- UART0과 UART1 통신속도 설정(115200Buadrate)
- WIFI 모듈과 초기 설정, 전처리문에서 등록한 WIFI ID 및 PW를 입력해서 연결 완료
- sendCommand 함수는 아래의 3-7. 함수 설명부 참고
(sendCommand(A, B, C) → A문구를 B회 만큼 전송하고 C의 문구가 수신되면 "OK"를 출력하고 다음 문장 수행)

 

3-6. Main Loop 함수

void loop() {
	Serial.println("");
	Serial.println("************ Sensor Value's ************");
	light_loop();
	humitemp_loop();
	lcd_loop();
	waterLevel_loop();
	Serial.println("****************************************");

	LightSensorVal = LightValue2;
	TempSensorVal = temp;
	HumiSensorVal = humi;
	WaterSensorVal = WaterLevel2;

	String getData = "GET /update?api_key=" + API + "&" + field + "=" + String(LightSensorVal) + "&" + field_2 + "=" + String(TempSensorVal) + "&" + field_3 + "=" + String(HumiSensorVal) + "&" + field_4 + "=" + String(WaterSensorVal);
	Serial.print("\nTransmitting Data ");
	Serial.println(++Txcount);
	sendCommand("AT+CIPMUX=1", 5, "OK");
	sendCommand("AT+CIPSTART=0,\"TCP\",\"" + HOST + "\"," + PORT, 15, "OK");
	sendCommand("AT+CIPSEND=0," + String(getData.length() + 4), 4, ">");
	Serial1.println(getData);
	Serial.println(getData);

	sendCommand("AT+CIPCLOSE=0", 5, "OK");
	delay(30000);
}

- 각 센서의 값을 출력하고 해당 센서의 Data를 IoT Cloud Platform에 저장하는 과정

 

3-7. sendCommand 함수부(WIFI모듈을 통해 DATA 전송)

void sendCommand(String command, int maxTime, char readReplay[]) {
	Serial.print("AT command : ");
	Serial.print(command);
	Serial.print(" ");
	while (countTimeCommand < (maxTime * 1)) {
		Serial1.println(command);
		if (Serial1.find(readReplay)) {
			found = true;
			break;
		}
		countTimeCommand++;
	}

	if (found == true) {
		Serial.println("OK");
		countTimeCommand = 0;
	}
	if (found == false) {
		Serial.println("Fail");
		countTimeCommand = 0;
	}
	found = false;
}

- sendCommand(A, B, C)

→ A문구를 B회 만큼 전송하고 C의 문구가 수신되면 "OK"를 출력하고 다음 문장 수행

- Serial = UART0, 즉 PC터미널 / Serial1 = UART1, 즉 WIFI 통신 

→ Serial과 Serial1을 구분해서 코드 확인 요망.

 

댓글