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

TODAY9,537 TOTAL3,602,035
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

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


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

페이지 정보

작성자 매드닥터 작성일2023-08-12 20:07 조회9,580회 댓글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

조회수 9,580

알토이드님의 댓글

알토이드 작성일

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 23829
공지 사이트 이용 안내댓글[31] master 17-10-29 37831
질문 STM32F429ZIT6보드와 lcm1602 이용한 알람시계 질문 (사용자 지정 알람 값에 알람 인터럽트 반… 새글 aaahhhj 00:51 13
답변 답변글 답변 : STM32F429ZIT6보드와 lcm1602 이용한 알람시계 질문 (사용자 지정 알람 값에 알람 인…댓글[1] 새글 master 06:37 15
질문 16bit DAC와 ADC 연결댓글[1] JMLew 24-07-19 40
질문 아두이노 초음파센서 연결 + 컴퓨터 연결 제발 도와주세요댓글[1] 이미지첨부파일 pinkpong 24-07-14 46
질문 아두이노 여러 센서 연결댓글[4] 이미지첨부파일 공수백자 24-07-09 286
질문 기어드 모터 외부인터럽트 사용하여 1초 동안 펄스 세는 법댓글[3] 바밤 24-07-04 149
질문 STM32F429ZIT6 rtc alarm 인터럽트 i2c lcd에 구현하는 방법댓글[5] aaahhhj 24-06-29 253
질문 Atmega128 LCD 출력이 나오지 않습니다, 코드 확인 부탁드립니다. 이미지첨부파일 코드에막혀 24-06-25 62
답변 답변글 답변 : Atmega128 LCD 출력이 나오지 않습니다, 코드 확인 부탁드립니다.댓글[1] master 24-06-25 76
질문 atmega128 recipe for target 'main.o ' failed 오류댓글[3] hhhyyyeee 24-06-19 216
질문 atmega128 코드 합치기 앗메 24-06-18 101
답변 답변글 답변 : atmega128 코드 합치기 master 24-06-19 51
질문 아두이노 파력발전댓글[1] sighn 24-06-16 93
질문 ATmega4809 nRF24L01 모듈을 이용한 무선 통신댓글[3] Ahri 24-06-12 167
질문 atmega128에 dht11 왜 측정을 못하죠?댓글[1] 탈북한시민 24-06-11 113
질문 atmega128이 실행이 되지 않습니다댓글[1] 이미지첨부파일 니굴 24-06-10 80
질문 아트메가 128 쓰는디 while 문이 안먹혀요댓글[1] 수히 24-06-09 85
질문 atmega128 UART통신으로 FND출력 Rion 24-06-09 114
답변 답변글 답변 : atmega128 UART통신으로 FND출력댓글[1] master 24-06-10 120
질문 atmega128 라인트레이서 코드와 회로도 질문...몇일 째 머리아파 죽겠네요ㅠ댓글[2] 이미지첨부파일 왕두일 24-06-06 268
답변 답변글 답변 : atmega128 라인트레이서 코드와 회로도 질문...몇일 째 머리아파 죽겠네요ㅠ master 24-06-07 138
질문 atmega128을 이용한 LCD 사용에 문제가 발생했습니다.댓글[3] 이미지 네넴 24-06-05 842
질문 Co 센서 값에 따른 ppm을 계산하려는데댓글[1] 라칸 24-06-05 190
질문 17HS4401, A4988 스텝모터 제어댓글[1] 이미지 jhbaik 24-06-03 191
질문 코드비전avr을 이용한 아두이노 우노 제어댓글[1] gkstntjd 24-05-29 204
질문 Energia 시리얼 모니터에 아무것도 출력되지않습니다.댓글[1] 김의공 24-05-22 223
질문 아두이노 스위치, 에어펌프 연결댓글[1] 이미지첨부파일 존존 24-05-20 385
질문 MSP430런치패드를 이용한 LCD 코딩 관련 질문댓글[1] 뀨쥰이 24-05-16 263
게시물 검색

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
모바일버전으로보기