BASIC4MCU | 질문게시판 | 답변 : 보드레이트 관련 질문
페이지 정보
작성자 죠르디 작성일2022-06-07 17:09 조회1,462회 댓글0건본문
소스코드 첨부합니다. 칼만필터를 적용한 자이로센서로 일정이상 기울어지게 되면 부저가 울리는 코드(좀 길어요ㅜㅜ)와 온습도센서를 이용하여 아이가 기저귀에 배변했는지 블루투스 모듈을 사용하여 앱에 표시하게끔 했는데 이 두 코드를 한번에 구현할 수 있도록 코드를 합칠 수 있나요? 보드레이트가 달라서 되는지 안되는지 모르겠어서 질문드립니다.
#include<Wire.h>
const int MPU_ADDR = 0x68; // I2C통신을 위한 MPU6050의 주소
int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ; // 가속도(Acceleration)와 자이로(Gyro)
double angleAcX, angleAcY, angleAcZ;
double angleGyX, angleGyY, angleGyZ;
double angleFiX, angleFiY, angleFiZ;
const double RADIAN_TO_DEGREE = 180/ 3.14159;
const double DEG_PER_SEC = 32767 / 250; // 1초에 회전하는 각도
const double ALPHA = 1 / (1 + 0.04);
// GyX, GyY, GyZ 값의 범위 : -32768 ~ +32767 (16비트 정수범위)
unsigned long now = 0; // 현재 시간 저장용 변수
unsigned long past = 0; // 이전 시간 저장용 변수
double dt = 0; // 한 사이클 동안 걸린 시간 변수
double averAcX, averAcY, averAcZ;
double averGyX, averGyY, averGyZ;
void setup() {
initSensor();
Serial.begin(115200);
caliSensor(); // 초기 센서 캘리브레이션 함수 호출
past = millis(); // past에 현재 시간 저장
pinMode(13,OUTPUT);
}
void loop() {
getData();
getDT();
angleAcX = atan(AcY / sqrt(pow(AcX, 2) + pow(AcZ, 2)));
angleAcX *= RADIAN_TO_DEGREE;
angleAcY = atan(-AcX / sqrt(pow(AcY, 2) + pow(AcZ, 2)));
angleAcY *= RADIAN_TO_DEGREE;
// 가속도 센서로는 Z축 회전각 계산 불가함.
// 가속도 현재 값에서 초기평균값을 빼서 센서값에 대한 보정
angleGyX += ((GyX - averGyX) / DEG_PER_SEC) * dt; //각속도로 변환
angleGyY += ((GyY - averGyY) / DEG_PER_SEC) * dt;
angleGyZ += ((GyZ - averGyZ) / DEG_PER_SEC) * dt;
// 상보필터 처리를 위한 임시각도 저장
double angleTmpX = angleFiX + angleGyX * dt;
double angleTmpY = angleFiY + angleGyY * dt;
double angleTmpZ = angleFiZ + angleGyZ * dt;
// (상보필터 값 처리) 임시 각도에 0.96가속도 센서로 얻어진 각도 0.04의 비중을 두어 현재 각도를 구함.
angleFiX = ALPHA * angleTmpX + (1.0 - ALPHA) * angleAcX;
angleFiY = ALPHA * angleTmpY + (1.0 - ALPHA) * angleAcY;
if(abs(angleFiX) >= 50) {
tone(13,261.6,1000);}
angleFiZ = angleGyZ; // Z축은 자이로 센서만을 이용하열 구함(가속도센서 z축 회전 감지 불가)
//Serial.print("AngleAcX:");
//Serial.print(angleAcX);
Serial.print("\t FilteredX:");
Serial.print(angleFiX);
//Serial.print("\t AngleAcY:");
// Serial.print(angleAcY);
Serial.print("\t FilteredY:");
Serial.println(angleFiY);
//Serial.print("\t AngleGyZ:");
//Serial.print(angleGyZ);
//Serial.print("\t FilteredZ:");
//Serial.println(angleFiZ);
// Serial.print("Angle Gyro X:");
// Serial.print(angleGyX);
// Serial.print("\t\t Angle Gyro y:");
// Serial.print(angleGyY);
// Serial.print("\t\t Angle Gyro Z:");
// Serial.println(angleGyZ);
// delay(20);
}
void initSensor() {
Wire.begin();
Wire.beginTransmission(MPU_ADDR); // I2C 통신용 어드레스(주소)
Wire.write(0x6B); // MPU6050과 통신을 시작하기 위해서는 0x6B번지에
Wire.write(0);
Wire.endTransmission(true);
}
void getData() {
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x3B); // AcX 레지스터 위치(주소)를 지칭합니다
Wire.endTransmission(false);
Wire.requestFrom(MPU_ADDR, 14, true); // AcX 주소 이후의 14byte의 데이터를 요청
AcX = Wire.read() << 8 | Wire.read(); //두 개의 나뉘어진 바이트를 하나로 이어 붙여서 각 변수에 저장
AcY = Wire.read() << 8 | Wire.read();
AcZ = Wire.read() << 8 | Wire.read();
Tmp = Wire.read() << 8 | Wire.read();
GyX = Wire.read() << 8 | Wire.read();
GyY = Wire.read() << 8 | Wire.read();
GyZ = Wire.read() << 8 | Wire.read();
}
// loop 한 사이클동안 걸리는 시간을 알기위한 함수
void getDT() {
now = millis();
dt = (now - past) / 1000.0;
past = now;
}
// 센서의 초기값을 10회 정도 평균값으로 구하여 저장하는 함수
void caliSensor() {
double sumAcX = 0 , sumAcY = 0, sumAcZ = 0;
double sumGyX = 0 , sumGyY = 0, sumGyZ = 0;
getData();
for (int i=0;i<10;i++) {
getData();
sumAcX+=AcX; sumAcY+=AcY; sumAcZ+=AcZ;
sumGyX+=GyX; sumGyY+=GyY; sumGyZ+=GyZ;
delay(50);
}
averAcX=sumAcX/10; averAcY=sumAcY/10; averAcZ=sumAcY/10;
averGyX=sumGyX/10; averGyY=sumGyY/10; averGyZ=sumGyZ/10;
}
----------------------------------------------------------------------------------------------------------------------------
#include <Wire.h>
#include "DHT.h"
#include <SoftwareSerial.h>
#define DHTPIN 4 // SDA 핀의 설정
#define DHTTYPE DHT22 // DHT22 (AM2302) 센서종류 설정
DHT dht(DHTPIN, DHTTYPE);
SoftwareSerial BTserial(8,9); //블루투스 연결
void setup() {
Serial.begin(9600);
dht.begin();
BTserial.begin(9600);
}
void loop() {
float t = dht.readTemperature(); //온도 읽어옴
float h = dht.readHumidity(); //습도 읽어옴
if (isnan(t) || isnan(h)) { //값 읽기 실패시 시리얼 모니터 출력
Serial.println("Failed to read from DHT");
} else { //온도, 습도 표시 시리얼 모니터 출력
Serial.print("Temperature: ");
Serial.print(t);
Serial.print(" ºC\t");
Serial.print("Humidity: ");
Serial.print(h);
Serial.println(" % rH");
}
BTserial.print(t);
BTserial.println(" ºC");
BTserial.print(h);
BTserial.println(" %");
if(t >=29 and h >= 80) { //온도가 29도가 넘고 습도가 80%가 넘을시
BTserial.println("기저귀를 확인하세요."); //출력
} else{
BTserial.println("기저귀가 뽀송합니다.");
}
delay(1000);
}
댓글 0
조회수 1,462등록된 댓글이 없습니다.