납땜
드디어 주문한 재료들이 모두 도착해서 PCB 제작에 들어갔다.
여기서 미처 생각하지 못한 것이 있는데, BMP280, MPU6500은 내 상각보다 진짜 엄청 작았다.
그리고 0402 캐패시터는 정망 엄청나게 작아서 핀셋으로 겨우겨우 붙였다.
납땜은 열풍기가 없어서 대안으로 생명과학실의 교반기를 이용해서 납을 녹여주었다..
그런데 교반기 가운데에 자석이 있는 것을 모르고 가운데에 올렸다가 부품들이 날아가서 다시 올려줘야 했다.
저항 수를 잘못 주문하여 3개밖에 만들지 못했는데, 암 해더핀 사용시 ATMEGA328P의 다리가 짧아서 연결이 되지 않는 문제가 있었다. 그래서 한개를 버렸다...
결론적으로 두개의 보드를 완성.. 했는데 실수로 가운에 아래쪽 보드의 다운로드 쪽에 GND가 연결되지 않아서 사실상 수율이 20%이다..
코딩
이제 코딩을 해보자.
아두이노 UNO의 ATMEGA328P칩을 때와서 붙였기 때문에, 부트로더를 구울 필요 없이 USB to TTL모듈을 연결해서 바로 사용하면 된다.
여기서 문제가 발생 했는데, 코드 업로드시 자동으로 리셋을 시켜주는(업로드시 1초안에 리셋 버트을 눌러야 코드가 업로드된다.) DTR이 작동하지 않았다. 아래는 그 회로도인데, 이게 거의 한달 전에 그린 회로도인데.. 캐패시터로 연결되어 있어서 그런 것 같다..(정확한 원인을 알면 댓글을 달아주세요)
그래서 코드 업로드시에 수동으로 리셋 버튼을 눌러주기로 했다. 이게 그렇게 귀찮은 일도 아니고 어차피 한번 코드를 업로드해서 계속 쓸 것이기 때문에 상관없다.
우선 간단하게 센서 데이터값을 읽어서 시리얼로 출력하는 코드를 넣어보았다.
#include <Wire.h>
#include <math.h>
#define MPU6050_ADDR 0x69
#define BMP280_ADDR 0x77
#define ACCEL_SENS 16384.0 // 16g -> 16384 LSB/g
#define GYRO_SENS 131.0 // 250 deg/s -> 131 LSB/(deg/s)
#define GRAVITY 9.80665
#define SAMPLE_TIME 0.01 // 10ms
float lastTime = 0;
void setup() {
Serial.begin(115200);
Wire.begin();
// MPU6050 초기화
Wire.beginTransmission(MPU6050_ADDR);
Wire.write(0x6B); // PWR_MGMT_1 레지스터
Wire.write(0x00); // 슬립 모드 해제
Wire.endTransmission();
// 가속도 감도 설정 (±16g)
Wire.beginTransmission(MPU6050_ADDR);
Wire.write(0x1C);
Wire.write(0x18);
Wire.endTransmission();
// 자이로 감도 설정 (±250°/s)
Wire.beginTransmission(MPU6050_ADDR);
Wire.write(0x1B);
Wire.write(0x00);
Wire.endTransmission();
// BMP280 초기화 (기본 설정 사용)
Wire.beginTransmission(BMP280_ADDR);
Wire.write(0xF4);
Wire.write(0x27);
Wire.endTransmission();
lastTime = millis();
}
void loop() {
float accel[3], gyro[3];
readMPU6050(accel, gyro);
float pressure, temperature;
readBMP280(pressure, temperature);
if (millis() - lastTime >= 100) {
Serial.print("Accel (m/s^2): ");
Serial.print(round(accel[0] * 10) / 10.0); Serial.print(", ");
Serial.print(round(accel[1] * 10) / 10.0); Serial.print(", ");
Serial.print(round(accel[2] * 10) / 10.0);
Serial.print(" | Pressure (Pa): ");
Serial.print(pressure);
Serial.print(" | Temp (C): ");
Serial.println(temperature);
lastTime = millis();
}
}
void readBMP280(float &pressure, float &temperature) {
Wire.beginTransmission(BMP280_ADDR);
Wire.write(0xF7);
Wire.endTransmission(false);
Wire.requestFrom(BMP280_ADDR, 6);
uint32_t rawPress = (Wire.read() << 16) | (Wire.read() << 8) | Wire.read();
uint32_t rawTemp = (Wire.read() << 16) | (Wire.read() << 8) | Wire.read();
rawPress >>= 4;
rawTemp >>= 4;
pressure = rawPress / 256.0/1000;
temperature = rawTemp / 5120.0;
}
void readMPU6050(float* accel, float* gyro) {
Wire.beginTransmission(MPU6050_ADDR);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU6050_ADDR, 14);
int16_t rawAcc[3], rawGyro[3];
rawAcc[0] = (Wire.read() << 8 | Wire.read());
rawAcc[1] = (Wire.read() << 8 | Wire.read());
rawAcc[2] = (Wire.read() << 8 | Wire.read());
Wire.read(); Wire.read(); // 온도 데이터 스킵
rawGyro[0] = (Wire.read() << 8 | Wire.read());
rawGyro[1] = (Wire.read() << 8 | Wire.read());
rawGyro[2] = (Wire.read() << 8 | Wire.read());
for (int i = 0; i < 3; i++) {
accel[i] = (rawAcc[i]);
gyro[i] = rawGyro[i];
}
}
2025.03.05 - [발사체] - Kicad로 PCB 제작하기 (1) 에서 BMP280와 MPU6500의 주소를 각각 0x77, 0x69로 설정해 줬기 때문에(3.3v 풀업) GPT가 짠 코드를 조금 수정해서 업로드 하였다.
그랬더니...
센서값을 읽는데 성공했다 ㅠㅠㅠ
솔직히 만들면서 I2C통신이니 SPI통신이니, 점퍼선으로 연결해 본 기억은 있었지만 이렇게 다이렉트로 센서를 연결해서 써본적이 없어서 될지 안될지 확신이 없었는데 한번에 되어서 기분이 너무 좋다 ㅎㅎㅎ
문제가 하나 있다면 BMP280이 납땜이 살짝 떠 있는 것 같은데 그 때문에 사진에 온도가 ㅎㅎㅎ 5만도이다 그리고 툭툭 건들이면 값이 정상적으로 출력되지 않는데 이건 내일 학교가서 땠다가 붙여봐야 겠다.
'발사체' 카테고리의 다른 글
400Ns High-power 로켓모터 개발일지 : 2주 연속 불발하다(3) (0) | 2025.03.23 |
---|---|
400Ns High-power 로켓모터 개발일지 (2) (0) | 2025.03.17 |
400Ns High-power 로켓모터 개발일지 (1) (0) | 2025.03.09 |
Kicad로 PCB 제작하기 : 설계부터 주문까지 (1) (0) | 2025.03.05 |