질문게시판 > I2C통신 연결 시리얼값오류 도와주세요

TODAY492 TOTAL2,925,355
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

아두이노 센서 ATMEGA128 PWM LED 초음파 AVR 블루투스 LCD UART 모터 적외선


BASIC4MCU | 질문게시판 | I2C통신 연결 시리얼값오류 도와주세요

페이지 정보

작성자 매드닥터 작성일2023-08-12 20:07 조회1,736회 댓글12건

본문

	

현재 저는 마이크로아두이노를사용하여 통신을하고있습니다 현재 마스터쪽과 슬레이브는 서로같은 I2C핀인 0번과 1번을 연결해놓았고 저항을 5K옴으로 풀업을주었습니다 물론 마스터와 슬레이브가 같은 곳에  GND를연결해주었습니다. 그리고 슬레이브쪽은 현제 초음파센서와 서보모터를연결해놓았습니다 밑에 현재사용중인 마스터아두이노의코딩과 슬레이브아두이노코딩을 오려두겠습니다 그리고 각자의 시리얼모니터로 어떻게 출력되고있는지 올려드리겠습니다.원인을아시는분은 알려주세요

 

마스터아두이노코딩

#include <Wire.h>

#define SLAVE_ADDRESS 10

int startAngle;
int endAngle;
float objectSize;
float averageDistance;

void setup() {
  Wire.begin();
  Serial.begin(9600);
}

void loop() {
  Wire.requestFrom(SLAVE_ADDRESS, sizeof(startAngle) + sizeof(endAngle) + sizeof(objectSize) + sizeof(averageDistance));

  if (Wire.available() >= (sizeof(startAngle) + sizeof(endAngle) + sizeof(objectSize) + sizeof(averageDistance))) {
    Wire.readBytes((uint8_t *)&startAngle, sizeof(startAngle));
    Wire.readBytes((uint8_t *)&endAngle, sizeof(endAngle));
    Wire.readBytes((uint8_t *)&objectSize, sizeof(objectSize));
    Wire.readBytes((uint8_t *)&averageDistance, sizeof(averageDistance));

    Serial.print("Start Angle: ");
    Serial.print(startAngle);
    Serial.print(" degrees, End Angle: ");
    Serial.print(endAngle);
    Serial.print(" degrees, Object Size: ");
    Serial.print(objectSize);
    Serial.print(" cm, Average Distance: ");
    Serial.print(averageDistance);
    Serial.println(" cm");
  }
}

 

 

슬레이브아두이노 코딩

#include <Wire.h>
#include <Servo.h>

#define TRIGGER_PIN 6
#define ECHO_PIN 7
#define SERVO_PIN 9
#define SLAVE_ADDRESS 10

Servo servo;
long duration;
int distance;
float objectSize;
float averageDistance;
int startAngle;
int endAngle;
bool detectionStarted = false;
bool objectDetected = false;

const int maxDetectedAngles = 50;
int detectedAngles[maxDetectedAngles];
int detectedAngleCount = 0;

void setup() {
  pinMode(TRIGGER_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  servo.attach(SERVO_PIN);
  servo.write(0);

  Wire.begin(SLAVE_ADDRESS);
  Serial.begin(9600);
}

void loop() {
  for (int angle = 0; angle <= 90; angle += 5) {
    servo.write(angle);
    delay(1000);

    if (angle >= 0 && angle <= 90) {
      distance = measureDistance();

      if (distance <= 150) {
        if (!detectionStarted) {
          startAngle = angle;
          detectionStarted = true;
          objectDetected = true;
        }

        if (detectedAngleCount < maxDetectedAngles) {
          detectedAngles[detectedAngleCount] = distance;
          detectedAngleCount++;
        }
      } else {
        if (detectionStarted) {
          endAngle = angle - 5;
          detectionStarted = false;
          measureObjectSize();
          sendInformation();
          objectDetected = false;
        }
      }
    }
  }
}

int measureDistance() {
  digitalWrite(TRIGGER_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIGGER_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGGER_PIN, LOW);
  duration = pulseIn(ECHO_PIN, HIGH);
  distance = duration * 0.034 / 2;
  return distance;
}

void measureObjectSize() {
  float totalDistance = 0;

  for (int i = 0; i < detectedAngleCount; i++) {
    totalDistance += detectedAngles[i];
  }

  if (detectedAngleCount > 0) {
    averageDistance = totalDistance / detectedAngleCount;
    objectSize = averageDistance * (endAngle - startAngle) / 150.0;
  } else {
    objectSize = 0;
  }

  detectedAngleCount = 0;
}

void sendInformation() {
  Wire.beginTransmission(0); // 0은 브로드캐스트 주소
  Wire.write((uint8_t *)&startAngle, sizeof(startAngle));
  Wire.write((uint8_t *)&endAngle, sizeof(endAngle));
  Wire.write((uint8_t *)&objectSize, sizeof(objectSize));
  Wire.write((uint8_t *)&averageDistance, sizeof(averageDistance));
  Wire.endTransmission();

  Serial.print("Start Angle: ");
  Serial.print(startAngle);
  Serial.print(" degrees, End Angle: ");
  Serial.print(endAngle);
  Serial.print(" degrees, Object Size: ");
  Serial.print(objectSize);
  Serial.print(" cm, Average Distance: ");
  Serial.print(averageDistance);
  Serial.println(" cm");
}

 

마스터시리얼모니터

19:59:43.929 -> nan cm

19:59:43.929 -> Start Angle: -256 degrees, End Angle: -1 degrees, Object Size: nan cm, Average Distance: nan cm

19:59:43.929 -> Start Angle: -256 degrees, End Angle: -1 degrees, Object Size: nan cm, Average Distance: nan cm

이러한값이 꾸준히반복되면서 오라오는중

 

슬레이브시리얼모니터

19:23:30.481 -> Name: 오른쪽, Start Angle: 5 degrees, End Angle: 5 degrees, Object Size: 0.00 cm, Average Distance: 124.00 cm

19:23:43.638 -> Name: 오른쪽, Start Angle: 70 degrees, End Angle: 70 degrees, Object Size: 0.00 cm, Average Distance: 72.00 cm

19:23:47.671 -> Name: 오른쪽, Start Angle: 90 degrees, End Angle: -5 degrees, Object Size: -58.27 cm, Average Distance: 92.00 cm

19:37:30.733 -> Start Angle: 20 degrees, End Angle: 20 degrees, Object Size: 0.00 cm, Average Distance: 7.00 cm

19:37:37.796 -> Start Angle: 55 degrees, End Angle: 55 degrees, Object Size: 0.00 cm, Average Distance: 4.00 cm

19:37:42.855 -> Start Angle: 80 degrees, End Angle: 80 degrees, Object Size: 0.00 cm, Average Distance: 5.00 cm

19:46:32.921 -> Start Angle: 40 degrees, End Angle: 40 degrees, Object Size: 0.00 cm, Average Distance: 65.00 cm

19:47:09.320 -> Start Angle: 30 degrees, End Angle: 30 degrees, Object Size: 0.00 cm, Average Distance: 7.00 cm

 

슬레이브쪽은 초음파센서에 사물이탐지될때마다 저렇게 시리얼모니터에 값이 뜹니다

 

 

 

  • BASIC4MCU 작성글 SNS에 공유하기
  • 페이스북으로 보내기
  • 트위터로 보내기
  • 구글플러스로 보내기

댓글 12

조회수 1,736

알토이드님의 댓글

알토이드 작성일

0,1번핀은 serial 통신에 사용되고
2,3 번핀이 i2c 통신에 사용되는 것이 아닌가요?

매드닥터님의 댓글

매드닥터 작성일

아죄송합니다 제가 글을잘못올렸습니다 말씀하신대로 연결되어있습니다. 현재 2번 3번이 연결되어있습니다.

master님의 댓글

master 작성일

아두이노 예제는 돌려보셨겠죠?
동작을 확인한 예제를 첨부하든지 링크 적어보세요

매드닥터님의 댓글

매드닥터 작성일

i2c 통신이 재대로 이루어지고 있는지는 다음 코딩으로 확인했습니다.


I2C통신 확인코딩

마스터
#include <Wire.h>

void setup() {
  Wire.begin(); // I2C 통신 초기화
  Serial.begin(9600); // 시리얼 통신 시작
}

void loop() {
  if (Serial.available()) {
    char command = Serial.read(); // 시리얼 입력 읽기
    if (command == 'M') {
      Wire.beginTransmission(8); // 슬레이브의 I2C 주소 8로 시작
      Wire.write('M'); // 명령 전송
      Wire.endTransmission(); // 전송 완료
      Serial.println("Sent command 'M' to slave."); // 디버그용 메시지 출력
    }
  }
}



슬레이브

#include <Wire.h>
#include <Servo.h>

Servo servoMotor;
int targetAngle = 0; // 서보 모터의 목표 각도
bool commandReceived = false; // 명령을 받았는지 확인하는 플래그

void setup() {
  Wire.begin(8); // 슬레이브의 I2C 주소를 8로 설정
  Wire.onReceive(receiveI2CEvent); // 함수 이름 변경
  servoMotor.attach(9); // 서보 모터 핀을 9번에 연결 (예시 핀 번호)
  servoMotor.write(90); // 초기 각도 설정 (90도)
  Serial.begin(9600); // 시리얼 통신 시작
}

void loop() {
  if (commandReceived) {
    for (int angle = 0; angle <= 90; angle += 5) {
      Serial.println("Moving servo to angle: " + String(angle));
      servoMotor.write(angle); // 각도로 서보 모터 움직이기
      delay(1000); // 1초 대기
    }
    commandReceived = false; // 명령 수행 완료
  }
}

void receiveI2CEvent(int bytes) { // 함수 이름 변경
  while (Wire.available()) {
    char command = Wire.read(); // 받은 명령 읽기
    if (command == 'M') { // "M" 명령인 경우
      Serial.println("Received command 'M'."); // 디버그용 메시지 출력
      commandReceived = true; // 명령을 받았음을 표시
    }
  }
}

매드닥터님의 댓글

매드닥터 작성일

재대로 마스터의명령을듣고 슬레이브가 작동하는것을 확인했습니다 물론 코딩의 내용처럼 디버깅을하여 시리얼모니터로 명령을 수신하는것과 송신받고 움직일때마다 해당각도를 시리얼모니터에 뜨는것도확인이 되었습니다.

master님의 댓글

master 댓글의 댓글 작성일

1바이트 송수신에는 문제가 없다는 것을 확인 했군요

매드닥터님의 댓글

매드닥터 작성일

현재 슬레이브쪽은 제가원하는값을아주잘띄우고있습니다. 이걸마스터가 i2c통신으로받기만하면되는데 뭐가 문제인지 모르겠습니다 코딩의  문제가 있는것같은데 오류는 안뜨는상태이니 모르겠습니다. ㅠㅠ
마스터코딩이 전부다 바뀌어도상관없으니 누가 도와주십시오 이걸해결하고나면  현재 emic2모듈을 마스터한테 연결시켜 시리얼모니터에나오는값을 음성출력하는것이 최종목적입니다.

master님의 댓글

master 댓글의 댓글 작성일

슬레이브에서 측정한 후, 측정값을 마스터로 보내지말고
슬레이브에서 측정하고, 측정값으로 음성출력 종류까지 계산 한 후, 마스터로 음성 출력 종류를 보내세요
음성 출력의 종류가 수십개 이상 되지는 않을테니 1바이트면 충분합니다.
즉, 마스터에서 처리하던 (거리값->음성출력) 계산을 슬레이브에서 하는 겁니다.
마스터에서는 단순히 슬레이브에서 출력해달라는 음성만 출력해주는 것이죠

매드닥터님의 댓글

매드닥터 작성일

감사합니다 한번그렇게 시도해보겠습니다.

매드닥터님의 댓글

매드닥터 작성일

말씀하신대로하니 반대로 오류가 많이 생기고 i2c통신이 안되어 마스터는 어떠한 시리얼모니터도 뜨지않습니다 그래서 지금 이러한 마스터아두이노 코딩을 업로드하고 사용해보았습니다

#include <Wire.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // 소리 출력을 위한 소프트웨어 시리얼 통신 객체 생성

#define SLAVE1_ADDRESS 9 // 첫 번째 슬레이브 아두이노 주소
#define SLAVE2_ADDRESS 10 // 두 번째 슬레이브 아두이노 주소

void setup() {
  Wire.begin(); // 마스터 아두이노 통신 시작

  mySerial.begin(9600); // 소리 출력을 위한 소프트웨어 시리얼 통신 시작
  Serial.begin(9600); // 시리얼 통신 시작
}

void loop() {
  // 첫 번째 슬레이브에 대한 정보 수신 및 출력
  Wire.requestFrom(SLAVE1_ADDRESS, 8); // 5바이트 데이터 요청
  if (Wire.available() >= 8) {
    String receivedData = "";
    while (Wire.available()) {
      char receivedChar = Wire.read();
      receivedData += receivedChar;
    }

    String name = receivedData.substring(0, receivedData.indexOf(',')); // 이름 추출
    int startAngleIndex = receivedData.indexOf(',') + 1; // 시작 각도 인덱스
    int startAngle = receivedData.substring(startAngleIndex, receivedData.indexOf(',', startAngleIndex)).toInt(); // 시작 각도 추출
    int endAngleIndex = receivedData.indexOf(',', startAngleIndex) + 1; // 끝 각도 인덱스
    int endAngle = receivedData.substring(endAngleIndex, receivedData.indexOf(',', endAngleIndex)).toInt(); // 끝 각도 추출
    int objectSizeIndex = receivedData.indexOf(',', endAngleIndex) + 1; // 사물 크기 인덱스
    float objectSize = receivedData.substring(objectSizeIndex).toFloat(); // 사물 크기 추출

    // 평균 거리 정보 추출
    int averageDistanceIndex = receivedData.indexOf(',', objectSizeIndex) + 1; // 평균 거리 인덱스
    float averageDistance = receivedData.substring(averageDistanceIndex).toFloat(); // 평균 거리 추출

    // 데이터 출력
    Serial.print("Slave 1 - Name: ");
    Serial.print(name);
    Serial.print(", Start Angle: ");
    Serial.print(startAngle);
    Serial.print(" degrees, End Angle: ");
    Serial.print(endAngle);
    Serial.print(" degrees, Object Size: ");
    Serial.print(objectSize);
    Serial.print(" cm, Average Distance: ");
    Serial.print(averageDistance);
    Serial.println(" cm");

    // 소리 출력 (TTS 모듈 사용)
    String ttsMessage = "Slave 1 - Name: " + name + ", Start Angle: " + String(startAngle) + " degrees, End Angle: " + String(endAngle) + " degrees, Object Size: " + String(objectSize) + " cm, Average Distance: " + String(averageDistance) + " cm";
    mySerial.println(ttsMessage); // TTS 메시지 출력
  }

  // 두 번째 슬레이브에 대한 정보 수신 및 출력
  Wire.requestFrom(SLAVE2_ADDRESS, 8); // 5바이트 데이터 요청
  if (Wire.available() >= 8) {
    String receivedData = "";
    while (Wire.available()) {
      char receivedChar = Wire.read();
      receivedData += receivedChar;
    }

    String name = receivedData.substring(0, receivedData.indexOf(',')); // 이름 추출
    int startAngleIndex = receivedData.indexOf(',') + 1; // 시작 각도 인덱스
    int startAngle = receivedData.substring(startAngleIndex, receivedData.indexOf(',', startAngleIndex)).toInt(); // 시작 각도 추출
    int endAngleIndex = receivedData.indexOf(',', startAngleIndex) + 1; // 끝 각도 인덱스
    int endAngle = receivedData.substring(endAngleIndex, receivedData.indexOf(',', endAngleIndex)).toInt(); // 끝 각도 추출
    int objectSizeIndex = receivedData.indexOf(',', endAngleIndex) + 1; // 사물 크기 인덱스
    float objectSize = receivedData.substring(objectSizeIndex).toFloat(); // 사물 크기 추출

    // 평균 거리 정보 추출
    int averageDistanceIndex = receivedData.indexOf(',', objectSizeIndex) + 1; // 평균 거리 인덱스
    float averageDistance = receivedData.substring(averageDistanceIndex).toFloat(); // 평균 거리 추출

    // 데이터 출력
    Serial.print("Slave 2 - Name: ");
    Serial.print(name);
    Serial.print(", Start Angle: ");
    Serial.print(startAngle);
    Serial.print(" degrees, End Angle: ");
    Serial.print(endAngle);
    Serial.print(" degrees, Object Size: ");
    Serial.print(objectSize);
    Serial.print(" cm, Average Distance: ");
    Serial.print(averageDistance);
    Serial.println(" cm");

    // 소리 출력 (TTS 모듈 사용)
    String ttsMessage = "Slave 2 - Name: " + name + ", Start Angle: " + String(startAngle) + " degrees, End Angle: " + String(endAngle) + " degrees, Object Size: " + String(objectSize) + " cm, Average Distance: " + String(averageDistance) + " cm";
    mySerial.println(ttsMessage); // TTS 메시지 출력
  }
}

이코딩을사용하니
18:04:42.549 -> Slave 2 - Name: , Start Angle: 0 degrees, End Angle: 0 degrees, Object Size: 0.00 cm, Average Distance: 0.00 cm
18:04:42.672 -> Slave 2 - Name: , Start Angle: 0 degrees, End Angle: 0 degrees, Object Size: 0.00 cm, Average Distance: 0.00 cm
이러한 값이 시리얼모니터에 뜨는것을확인했습니다. 시리얼모니터를 보았을때분명 요구하고있는것같은데 정보를받지못해서 이러한값이 뜨는건지 잘모르겠습니다.

매드닥터님의 댓글

매드닥터 작성일

값이 마스터쪽에 저렇게 뜨고있어도 i2c통신이 되고있다고 생각한 이유는 i2c통신선을하나라도 빼면 더이상 값을 시리얼모니터에 만들지않기 때문입니다

master님의 댓글

master 댓글의 댓글 작성일

슬레이브가 2개 인가요?
아두이노 예제처럼 심플한 코드를 만들어서 테스트 하세요

질문게시판HOME > 질문게시판 목록

MCU, AVR, 아두이노 등 전자공학에 관련된 질문을 무료회원가입 후 작성해주시면 전문가가 답변해드립니다.
ATMEGA128PWMLED초음파
아두이노AVR블루투스LCD
UART모터적외선ATMEGA
전체 스위치 센서
질문게시판 목록
제목 작성자 작성일 조회
공지 MCU, AVR, 아두이노 등 전자공학에 관련된 질문은 질문게시판에서만 작성 가능합니다. 스태프 19-01-15 21054
공지 사이트 이용 안내댓글[29] master 17-10-29 34900
질문 질문있습니다ㅠㅠ 부탁드려요 새글 keldeo 02:57 5
질문 0 ~ 99 이중 for문으로 작성하는법!댓글[2] 새글 상어 23-09-26 11
질문 리튬배터리로 화면 출력 질문드립니다 !댓글[1] 이미지새글 멘탈나간다 23-09-26 9
질문 lcd,바코드,서보모터, 아두이노 질문 드립니다. ㅠㅠ댓글[1] 새글 아두이노개발자 23-09-26 20
질문 stm32에서 변수 값을 유지하는 방법댓글[1] 새글 라칸 23-09-26 15
질문 안녕하세요 스위치로 led 제어 관련 질문이 있습니다댓글[1] 새글 노형빈 23-09-25 17
질문 16X16 도트 매트릭스 구동방법 질문입니다.댓글[1] 새글첨부파일 맹균 23-09-25 16
질문 stm32에서 RTC 시간 함수 쓰는데 의문점댓글[1] 새글 라칸 23-09-25 22
질문 GPS 모듈 관련 질문입니다.댓글[3] 지구과학 23-09-22 29
질문 아두이노 블루투스와 초음파센서를 이용한 장애물 정지댓글[2] 둘둘이 23-09-22 57
답변 답변글 답변 : 아두이노 블루투스와 초음파센서를 이용한 장애물 정지댓글[1] 새글 master 23-09-25 19
질문 stm32 보드에서 시간설정과 불러오기를 하는데댓글[5] 라칸 23-09-22 41
질문 아두이노 인터럽트 질문입니다.댓글[2] Tell 23-09-21 45
답변 답변글 답변 : 아두이노 인터럽트 질문입니다.댓글[1] master 23-09-22 54
질문 아두이노와 거리 감지 센서의 전류 관련댓글[1] hmkim 23-09-21 65
질문 아두이노 코딩 질문있습니다. 도와주세요....댓글[1] 이미지첨부파일 vnpaz 23-09-20 70
질문 아두이노를 사용한 dc모터 위치제어댓글[2] 모터위치 23-09-20 62
질문 stm32 디버깅이나 rst버튼 없이 하는 방법좀댓글[1] 라칸 23-09-20 53
질문 LCD에 숫자 표기법을 바꾸고 싶습니댓글[2] Bs드리프터 23-09-19 125
질문 알코올 측정기(MQ-3) 관련 질문 이미지 소오금 23-09-18 61
답변 답변글 답변 : 알코올 측정기(MQ-3) 관련 질문 master 23-09-19 112
질문 스텝모터 제어하는 소스파일 수정방법 질문드립니다. Bs드리프터 23-09-15 75
답변 답변글 답변 : 스텝모터 제어하는 소스파일 수정방법 질문드립니다.댓글[1] master 23-09-15 109
질문 atmega 128을 이용한 악기 튜너기댓글[1] 아두이노짱 23-09-15 315
질문 stm32 보드 ip주소 찾는법댓글[1] 라칸 23-09-13 67
질문 마이컴 종류 질문댓글[2] stevie8 23-09-12 122
질문 주파수 실수배 체배 관련문의댓글[6] 스쳐두임신 23-09-11 151
질문 스마트 창문 제작 중에 질문 있습니다!댓글[1] 이미지첨부파일 N8008 23-09-09 118
게시물 검색

2022년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2021년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2020년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2019년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2018년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
Privacy Policy
MCU BASIC ⓒ 2020
모바일버전으로보기