Notice
Recent Posts
Recent Comments
250x250
Creative Code
아두이노 프로젝트 최종정리(기상관측계) 본문
728x90
※마스터 보드 코드
#include <Wire.h>
#include <LiquidCrystal.h>
char receivedData[32]; //데이터를 받아온 후 저장할 배열
bool sendData = true; //데이터 송신 여부
int status; //수신한 데이터의 값 저장
const int SW_0 = 6; //스위치 0번버튼을 6번 디지털 핀에 연결
const int SW_1 = 7; //스위치 1번버튼을 7번 디지털 핀에 연결
const int SW_2 = 8; //스위치 2번버튼을 8번 디지털 핀에 연결
LiquidCrystal lcd(12, 11, 2, 3, 4, 5); //lcd 연결핀 12,11,2,3,4,5번
void SW0_Pressed(void) { //온도를 체크하는 함수 (0번 스위치)
if (sendData) { //송신을 시작할 때
Wire.beginTransmission(5); //온도를 체크하는 slave보드의 주소값은 5
Wire.write("temp"); //온도를 체크하라는 명령을 전달
Wire.endTransmission(); //전송 종료
delay(80); //통신이 얽히는 것을 방지하기 위한 delay시간 부여
sendData = false; //송신이 완료되어 false로 변경
Wire.requestFrom(9, 32); //32바이트만큼 데이터를 요청
Wire.onReceive(receiveEvent); //데이터 수신함수
delay(80); //통신 얽힘 방지를 위한 delay시간 부여
Serial.println("'C");
lcd.clear(); //lcd화면 초기화
lcd.setCursor(0, 0);
lcd.write(byte(0)); //lcd화면 글자 "온" 출력
lcd.setCursor(1, 0);
lcd.write(byte(1)); //lcd화면 글자 "도" 출력
lcd.setCursor(2, 0);
lcd.print(":");
lcd.setCursor(3, 0);
lcd.print(status / 10); //lcd화면에 온도 측정값 출력
lcd.setCursor(4, 0);
lcd.print(status % 10);
lcd.setCursor(5, 0);
lcd.print("'");
lcd.setCursor(6, 0);
lcd.print("C");
if (status >= 33 && status < 35) { //온도 측정값이 33도이상 35도 미만이면 폭염주의보 경고 메시지 출력
lcd.setCursor(0, 1);
lcd.print("heat wave 1");
} else if (status >= 35) { //온도 측정값이 35도이상이면 폭염경보 메시지 출력
lcd.setCursor(0, 1);
lcd.print("heat wave 2");
} else if (status <= -12 && status > -15) { //DHT11센서의 측정범위는 0도~50도 이지만 -12도이하 -15도 초과 일때는 한파 주의보 경고 메시지 출력
lcd.setCursor(0, 1);
lcd.print("cold wave 1");
} else if (status <= -15) { //-15도 미만일 때는 한파 경보 메시지 출력
lcd.setCursor(0, 1);
lcd.print("cold wave 2");
}
}
}
void SW1_Pressed(void) { //습도를 측정하는 함수(스위치 1번)
if (sendData) { //송신을 시작할 때
Wire.beginTransmission(5); //습도를 체크하는 slave보드의 주소값은 5
Wire.write("humid"); //습도 측정을 위한 명령어 전달
Wire.endTransmission(); //전송 종료
delay(80); //통신 얽힘 방지를 위한 delay 시간 부여
sendData = false; //송신을 종료했으므로 false로 전환
Wire.requestFrom(9, 32); //32바이트만큼 데이터를 요청
Wire.onReceive(receiveEvent); //데이터 수신함수
delay(80); //통신 얽힘 방지를 위한 delay 시간 부여
Serial.println("%");
lcd.clear(); //lcd화면 초기화
lcd.setCursor(0, 0);
lcd.write(byte(2)); //글자 "습" 출력
lcd.setCursor(1, 0);
lcd.write(byte(1)); //글자 "도" 출력
lcd.setCursor(2, 0);
lcd.print(":");
lcd.setCursor(3, 0);
lcd.print(status / 10); //수신한 습도 측정값 출력
lcd.setCursor(4, 0);
lcd.print(status % 10);
lcd.setCursor(5, 0);
lcd.print("%");
if (status <= 35 && status > 25) { //습도 측정값이 25%초과 35% 이하이면 건조 주의보 메시지 출력
lcd.setCursor(0, 1);
lcd.print("dry caution 1");
} else if (status <= 25) { //습도 측정값이 25%이하이면 건조 경보 메시지 출력
lcd.setCursor(0, 1);
lcd.print("dry caution 2");
}
}
}
void SW2_Pressed(void) { //자외선 측정을 위한 함수(스위치2번)
if (sendData) { //송신을 시작할 때
Wire.beginTransmission(6); //자외선을 측정하는 slave보드의 주소값은 6
Wire.write("UV"); //자외선을 측정하기 위한 명령 전달
Wire.endTransmission(); //전송 종료
delay(80); //통신 얽힘을 방지하기 위한 delay 시간 부여
sendData = false; //송신을 종료했으므로 false로 전환
Wire.requestFrom(9, 32); //32바이트만큼 데이터를 수신
Wire.onReceive(receiveEvent); //데이터를 수신하는 함수
delay(80); //통신 얽힘을 방지하기 위한 delay시간 부여
lcd.clear(); //lcd화면 초기화
lcd.setCursor(0, 0);
lcd.write(byte(3)); //lcd에 글자"자"출력
lcd.setCursor(1, 0);
lcd.write(byte(4)); //lcd에 글자"외"출력
lcd.setCursor(2, 0);
lcd.write(byte(5)); //lcd에 글자"선"출력
lcd.setCursor(3, 0);
lcd.print(":");
lcd.setCursor(4, 0); //lcd에 자외선 측정값 출력
lcd.print(status / 10);
lcd.setCursor(5, 0);
lcd.print(status % 10);
if (status < 3) { //자외선 지수가 3보다 낮을 때 "자외선 낮음"출력
lcd.setCursor(0, 1);
lcd.print("UV low");
} else if (status >= 3 && status < 6) { //자외선 지수가 3이상 6미만 일 때 "자외선 보통"출력
lcd.setCursor(0, 1);
lcd.print("UV normal");
}
else if (status >= 6 && status < 8) { //자외선 지수가 6이상 8미만 일 때 "자외선 높음"출력
lcd.setCursor(0, 1);
lcd.print("UV high");
}
else if (status >= 8 && status < 11) { //자외선 지수가 8이상 11미만 일 때 "자외선 매우 높음"출력
lcd.setCursor(0, 1);
lcd.print("UV very high");
}
else { //자외선 지수가 11이상일 때 "자외선 경고"출력
lcd.setCursor(0, 1);
lcd.print("UV warning");
}
}
}
byte wk[8] = //lcd에 글자 "자"를 출력하기 위한 바이트 생성
{
0b00010,
0b11110,
0b01011,
0b01010,
0b10110,
0b10110,
0b00010,
0b00000
};
byte dhl[8] = //글자 "외"
{
0b01001,
0b10101,
0b10101,
0b10101,
0b01001,
0b00001,
0b01000,
0b11110
};
byte tjs[8] = //글자 "선"
{
0b01001,
0b01001,
0b10111,
0b10101,
0b00001,
0b00000,
0b10000,
0b11111
};
byte eo[8] = //글자 "대"
{
0b00101,
0b11101,
0b10101,
0b10111,
0b10101,
0b10101,
0b11101,
0b00101
};
byte rl[8] = //글자 "기"
{
0b00001,
0b11101,
0b00101,
0b00101,
0b01001,
0b10001,
0b00001,
0b00000
};
byte dhs[8] = //글자 "온"
{
0b01110,
0b10001,
0b01110,
0b00100,
0b11111,
0b00000,
0b10000,
0b11111
};
byte eh[8] = //글자 "도"
{
0b11111,
0b10000,
0b10000,
0b11111,
0b00000,
0b00100,
0b00100,
0b11111
};
byte tmq[8] = //글자 "습"
{
0b00100,
0b01010,
0b11111,
0b00000,
0b10001,
0b11111,
0b10001,
0b11111
};
void setup() {
Wire.begin(9); //Master보드의 주소를 9로 설정
Serial.begin(9600); //시리얼 통신
pinMode(SW_0,INPUT); //SW_0의 pinmode 설정
pinMode(SW_1,INPUT); //SW_1의 pinmode 설정
pinMode(SW_2,INPUT); //SW_2의 pinmode 설정
lcd.begin(16, 2); //lcd 기본설정(16*2크기)
lcd.createChar(0, dhs); //글자 "온"
lcd.createChar(1, eh); //글자 "도"
lcd.createChar(2, tmq); //글자 "습"
lcd.createChar(3, wk); //글자 "자"
lcd.createChar(4, dhl); //글자 "외"
lcd.createChar(5, tjs); //글자 "선"
}
void loop() {
int digitalValue1 = digitalRead(SW_0); //온도 버튼을 누르면 digitalRead를 통해 1값을 받아 digitalvalue1변수에 저장
int digitalValue2 = digitalRead(SW_1); //습도 버튼을 누르면 digitalRead를 통해 1값을 받아 digitalvalue2변수에 저장
int digitalValue3 = digitalRead(SW_2); //자외선 버튼을 누르면 digitalRead를 통해 1값을 받아 digitalvalue3변수에 저장
if (digitalValue1 == HIGH) { //digitalvalue1변수가 HIGH값이면 온도를 측정하는 함수 실행
SW0_Pressed();
}
if (digitalValue2 == HIGH) { //digitalvalue2변수가 HIGH값이면 습도를 측정하는 함수 실행
SW1_Pressed();
}
if (digitalValue3 == HIGH) { //digitalvalue3변수가 HIGH값이면 자외선을 측정하는 함수 실행
SW2_Pressed();
}
}
void receiveEvent(int byteCount) { //데이터를 받아오는 함수
if (Wire.available() > 0) {
int i = 0;
while (Wire.available()) { //데이터를 모두 받아올 때 까지 반복
receivedData[i] = Wire.read(); //데이터를 1바이트씩 받아 문자열배열 receivedData에 저장
i++;
}
receivedData[i] = '\0'; //문자열의 마지막에 '\0' 문자 추가
Serial.print("status : ");
status = atoi(receivedData); //문자열로 데이터를 전송받았으므로 수신한 데이터를 숫자로 전환
Serial.print(status);
}
sendData = true; //데이터를 수신한 뒤에도 데이터를 다시 받아올 수 있게 송신모드로 전환
}
※slave보드 (온도,습도) 코드
#include <Wire.h>
#include <DHT.h>
char receivedData[32]; //master보드로 부터 수신한 명령을 저장할 배열
char tempData[32]; //측정한 온도데이터를 저장할 배열 -> master보드로 보낼 용도
char humidData[32]; //측정한 습도데이터를 저장할 배열 -> master보드로 보낼 용도
const int temp = 2; //온도측정센서와 연결할 디지털 핀
DHT dht(2,DHT11); //2번핀을 DHT11센서와 연결
const int BUZZER = 10; //부저의 연결 핀은 10번
bool sendData = false; //데이터 전송모드의 초기 설정은 false;
void setup() {
Wire.begin(5); //온도,습도를 측정하는 slave보드의 주소값을 5로 설정
Wire.onReceive(receiveEvent); //master보드로 부터 명령을 수신하는 함수
Serial.begin(9600); //시리얼 통신
dht.begin(); //센서 동작 시작
pinMode(BUZZER,OUTPUT); //부저의 pinmode를 OUTPUT으로 설정
}
void loop() {
if (sendData) { //데이터를 송신모드
if (strcmp(receivedData,"temp") == 0) { //master보드로 부터 전달받은 명령이 온도 측정일 경우
int temperature = dht.readTemperature(); //온도 측정한 값을 int형으로 저장
if (temperature >= 33 || temperature<=-12) { //온도가 33도이상이거나 영하12도 이하일 시 경고용으로 부저작동
tone(BUZZER,600,1000); //부저의 음 높낮이는 600, 지속시간은 1초로 설정
}
Serial.print(" ");
Serial.println(temperature);
Wire.beginTransmission(9); //측정한 데이터를 master보드로 보내기위해 master보드의 주소인 9로 연결
itoa(temperature,tempData,10); //측정값을 10진수형태의 문자열로 변환해 tempData배열에 저장
Wire.write(tempData); //변환한 문자열을 master보드로 전송
delay(80); //통신얽힘 방지를 위한 delay부여
Wire.endTransmission(); //전송 종료
sendData = false; //데이터를 전송했으므로 전송모드를 false로 전환
}
else { //master보드로 부터 전달받은 명령이 습도 측정일 경우
int humidity = dht.readHumidity(); //습도 측정한 값을 int형으로 저장
Serial.print(" ");
Serial.println(humidity);
Wire.beginTransmission(9); //측정한 데이터를 master보드로 보내기 위해 master보드의 주소인 9로 연결
itoa(humidity,humidData,10); //측정값을 10진수형태의 문자열로 변환해 tempData배열에 저장
Wire.write(humidData); //변환한 문자열을 master보드로 전송
delay(80); //통신얽힘 방지를 위한 delay부여
Wire.endTransmission(); //전송 종료
sendData = false; //데이터를 전송했으므로 전송모드를 false로 전환
}
}
}
void receiveEvent(int byteCount) { //master보드로 부터 명령을 받는 함수
if (Wire.available() > 0) {
int i = 0;
while (Wire.available()) { //데이터를 모두 받을때 까지 실행
receivedData[i] = Wire.read(); //수신 데이터를 배열에 저장
i++;
}
receivedData[i] = '\0'; //문자열 배열 마지막에 종료를 알리는 '\0'문자를 추가
Serial.print("Received from Master: ");
Serial.println(receivedData);
}
sendData = true; //다시 데이터를 요청받을 수 있기 때문에 전송모드를 true로 전환
}
※slave보드 (UV)코드
#include <Wire.h>
#include <math.h>
int UVOUT = A0; //A0 핀에 UV 센서 연결
int REF_3V3 = A1; //A1 핀에 3.3V 레퍼런스 연결
bool sendData = false; //데이터 전송모드 초기값 false로 설정
char receivedData[32]; //master보드로부터 수신한 데이터를 저장하는 문자 배열
char UVData[32]; //UV 센서 데이터를 저장하는 문자 배열 ->master보드로 보내기 위한 문자열
const int BUZZER = 10; // 부저를 10번핀에 연결
void setup() {
Serial.begin(9600); //시리얼 통신
Wire.begin(6); //자외선을 측정하는 slave보드의 주소값을 6으로 설정
Wire.onReceive(receiveEvent); //master보드로 부터 데이터를 수신하는 함수
pinMode(UVOUT, INPUT); //UV 센서를 INPUT 모드로 설정
pinMode(REF_3V3, INPUT); //3.3V 레퍼런스 핀을 INPUT 모드로 설정
pinMode(BUZZER, OUTPUT); //부저를 OUTPUT 모드로 설정
Serial.println("MP8511 example");
}
void loop() {
if (sendData) { //데이터 전송모드
int uvLevel = averageAnalogRead(UVOUT); //UV 센서에서 평균 아날로그 값을 읽음
int refLevel = averageAnalogRead(REF_3V3); //3.3V 레퍼런스에서 평균 아날로그 값을 읽음
float outputVoltage = 3.3 / refLevel * uvLevel; //UV 강도에 해당하는 출력 전압 계산
float uvIntensity = mapfloat(outputVoltage, 0.99, 2.9, 0.0, 15.0); //출력 전압을 UV 강도로 매핑
Wire.beginTransmission(9); //측정한 데이터를 master보드의 주소값인 9로 전송 시작
int uvint = (int)uvIntensity; //UV 강도를 정수로 변환
if (uvint >= 6) { //UV 강도가 6 이상인 경우 경고음 출력
tone(BUZZER, 600, 1000); //경고음의 높낮이는 600으로 1초동안 출력
}
Serial.print(" UV Intensity (mW/cm^2): ");
Serial.println(uvIntensity);
Serial.println(uvint);
itoa(uvint, UVData, 10); //측정한 값을 master보드로 전송하기위해 문자열로 변환하고 UVData배열에 저장
Wire.write(UVData); //master보드로 문자열 배열 전송
delay(100); //통신 얽힘 방지를 위해 delay 부여
Wire.endTransmission(); //데이터 전송 종료
sendData = false; //데이터를 보냈으므로 전송모드 false로 전환
Serial.println();
}
}
// 주어진 핀에서 여러 읽기를 평균내는 함수
// 평균값을 반환
int averageAnalogRead(int pinToRead) {
byte numberOfReadings = 8; //읽을 횟수
unsigned int runningValue = 0; //읽은 값들의 합을 저장할 변수
for (int x = 0; x < numberOfReadings; x++)
runningValue += analogRead(pinToRead); //주어진 핀에서 아날로그 값을 읽어 합산
runningValue /= numberOfReadings; //합산 값을 읽은 횟수로 나누어 평균을 계산
return (runningValue); //평균값 반환
}
// float 값에 대한 매핑 함수
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; //매핑 계산
}
void receiveEvent(int byteCount) { //master보드로 부터 명령을 받는 함수
if (Wire.available() > 0) {
int i = 0;
while (Wire.available()) { //데이터를 모두 받을 때 까지 실행
receivedData[i] = Wire.read(); //데이터를 받아 receivedData문자열 배열에 저장
i++;
}
receivedData[i] = '\0'; //문자열 종료 문자 추가
Serial.print("Received from Master : ");
Serial.println(receivedData);
}
sendData = true; //다음 데이터 요청이 있을시를 대비해 전송모드를 true로 전환
}
728x90
'Projects' 카테고리의 다른 글
Aurora-(2)서버 구축 연습 (0) | 2023.11.02 |
---|---|
Aurora-(1)로그인 UI화면 구현[클라이언트] (0) | 2023.11.01 |
Aurora-(0)준비단계 (0) | 2023.10.31 |
OneStargram(기획) (0) | 2023.10.26 |
아두이노 프로젝트 ppt(기상관측계) (0) | 2023.09.02 |