Slave 코드설명

/*
 * I2c Slave 모듈 코드
 * version 0.0.1
*/
#include <Wire.h>
#include <EEPROM.h>
#include <Servo.h>

//#define BEEP_PIN 12 // 능동부저
#define BEEP_PIN 11 // 수동부저

//#define BUTTON1 8 // 스위치1
#define BUTTON1 12
//#define BUTTON2 9 // 스위치2
int BUTTON2;
int BUTTON3;
int BUTTON4;


// 서보모터(PWM)
Servo servo_motor1, servo_motor2, servo_motor3, servo_motor4, servo_motor5, servo_motor6;
int server1_angle=0;
int server2_angle=0;
int server3_angle=0;
int addr_servo[6]={6,7,8,9,10,11};
int servo_enable[6]={0,0,0,0,0,0};

int time_blank_delay[19] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

int timedelay = 0;
int time_led_toggle = 0;
int time_beep_toggle = 0;

/**
 * 내부 LED 깜빡임 (초기값 1초)
*/
void builtin_led_blank(int time=1000) {
  digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on (HIGH is the voltage level)
  delay(time);                      // wait for a second
  digitalWrite(LED_BUILTIN, LOW);   // turn the LED off by making the voltage LOW
  delay(time);                      // wait for a second
}


void start_beep() {
  tone(BEEP_PIN,1046); // 도
  delay(200);
  noTone(BEEP_PIN);

  tone(BEEP_PIN,1046); // 도
  delay(200);
  noTone(BEEP_PIN);
}

void ready_beep() {
  /*
  tone(BEEP,523); // 도
  delay(500);
  
  
  tone(BEEP,587); // 레
  delay(500);
  */
  
  tone(BEEP_PIN,660); // 미
  delay(100);
  
  
  /*
  tone(BEEP,698); // 파
  delay(500);
  */
  
  tone(BEEP_PIN,784); // 솔
  delay(300);
  

  /*
  tone(BEEP,880); // 라
  delay(500);
  */
  
  tone(BEEP_PIN,988); // 시
  delay(500);
  
  /*
  tone(BEEP,1046); // 도
  delay(500);
  */

  noTone(BEEP_PIN);
 
}

void beep(int time)
{
  // 초기화2 : 비프 소리
  digitalWrite(BEEP_PIN, HIGH);
  delay(time);
  digitalWrite(BEEP_PIN, LOW);
  delay(time);
}

int status = 0;
int slave_num;

void setup() {
  int btn1, btn2, btn3, btn4;

  // 초기화: 시리얼
  Serial.begin(2000000);          // start serial for output

  // 초기화1 : 내부 LED, Beep
  pinMode(LED_BUILTIN, OUTPUT);
  time_blank_delay[12] = 500;

  pinMode(BEEP_PIN,OUTPUT); // 수동부저 출력 11핀
  start_beep();


  // 버튼 초기화
  pinMode(BUTTON1, INPUT);
  btn1 = digitalRead(BUTTON1);


  BUTTON2 = EEPROM.read(3);
  if(BUTTON2<0 || BUTTON2>19) {
    BUTTON2 = 9; // 초기화
  }
  pinMode(BUTTON2, INPUT);
  btn2 = digitalRead(BUTTON2);

  BUTTON3 = EEPROM.read(4);
  if(BUTTON3<0 || BUTTON3>19) {
    BUTTON3 = 10; // 초기화
  }
  pinMode(BUTTON3, INPUT);
  btn3 = digitalRead(BUTTON3);

  BUTTON4 = EEPROM.read(5);
  if(BUTTON4<0 || BUTTON4>19) {
    BUTTON3 = 11; // 초기화
  }
  pinMode(BUTTON4, INPUT);
  btn4 = digitalRead(BUTTON4);
  

  // 초기화: I2C 설정
  Serial.print("button1=");
  Serial.println(btn1);
  Serial.print("button2=");
  Serial.println(btn2);
  if(btn1 == 0 && btn2 == 0) {
    status = 1; // I2c 노드설정
    slave_num = 127; // 임시설정
  } else {
    slave_num = EEPROM.read(0);
    //Serial.println(slave_num);
  }

  // 강제지정
  // 1:servo1=0
  // 1:servo1=180
  slave_num = 1; 

  if(slave_num>0 && slave_num <=127) {
    Wire.begin(slave_num);  
    Wire.onReceive(receiveEvent); // register event
    Wire.onRequest(requestEvent); // register event
  }

  Serial.println("servo1 init");
  servo_motor1.attach(3);
  servo_motor1.write(0);
  delay(20);

  Serial.println("servo2 init");
  servo_motor2.attach(5);
  servo_motor2.write(0);
  delay(20);

  Serial.println("servo3 init");
  servo_motor3.attach(6);
  servo_motor3.write(0);
  delay(20);

  /*
  // 서보모터
  if(status == 1) {
    //초기화
    for(int i=0;i<6;i++) {
      EEPROM.write(addr_servo[i],0);
    }
  } else {
    for(int i=0;i<6;i++) {
      servo_enable[i] = EEPROM.read(addr_servo[i]);
    }

    if(servo_enable[0]) {
      Serial.println("servo1 init");
      servo_motor1.attach(3);
      servo_motor1.write(0);
      delay(20);
    }

    if(servo_enable[1]) {
      servo_motor2.attach(5);
      servo_motor2.write(0);
      delay(20);
    }  

    if(servo_enable[2]) {
      servo_motor3.attach(6);
      servo_motor3.write(0);
      delay(20);
    } 
  }
  */

  Serial.println("Slave Ready");
  Serial.print("Slave_Num = "); Serial.println(slave_num);
}

String wire_input;

/**
 * I2C를 통하여 데이터 값을 전달 받음
*/
void receiveEvent(int howMany) {
  while (1 < Wire.available()) { // loop through all but the last
    char c = Wire.read(); // receive byte as a character
    wire_input += c;
    Serial.print(c);         // print the character
  }
  
  char c = Wire.read(); // receive byte as a character
  wire_input += c;
  Serial.println(c); 

  //int x = Wire.read();    // receive byte as an integer
  //Serial.println(x);         // print the integer
}

void requestEvent() {
  Wire.write("hello "); // respond with message of 6 bytes
  // as expected by master
}

void loop() {
  /*
  for(int position=0; position<180;position+=2) {
    servo_motor1.write(position);
    delay(20);
  }

  for(int position=180; position>=0;position-=2) {
    servo_motor1.write(position);
    delay(20);
  }*/
 

  if(wire_input.length()>0){
    Serial.print("M>");
    Serial.println(wire_input);

    command_parser(wire_input);  
    wire_input = "";
  }

  //char cmd; // 지역변수, loop 함수에서만 사용 가능
  if(Serial.available()>0){
    String serial_input = Serial.readStringUntil('\n'); //엔터까지 입력받기
    Serial.println("> INPUT : " + serial_input);
    command_parser(serial_input);  
  }


  // builtin_led_blank(500); // 0.5초 깜빡임
  time_led_blank(time_blank_delay[12], LED_BUILTIN);
  //time_beep_blank(500, 12);

  // 타임딜레이 5초간격 초기화
  if(timedelay > 5000) {
    timedelay = 0; //
  }
  timedelay++; delay(1);
  
} /* --- loop end ---*/


// 명령어 분석
void command_parser(String input) {


  //문자의 첫번째 위치부터 다음 토큰까지 읽어낸다
  int space_idx = input.indexOf("="); 

  //첫번째 인자의 경우, 공백을 만나지못하면 인자 딱 하나만 입력한 경우이므로 처음부터 끝까지 읽고,
  //공백을 만나면 그 공백 전까지 짤라서 읽어내면 됨. (인자가 2개 이상인 경우)
  String cmd = space_idx == -1 ? input.substring(0, input.length()) : input.substring(0, space_idx);

  if(space_idx == -1) {
    cmd = input.substring(0, input.length());
    command(cmd, ""); // 명령어 분석
  } else {
    command(cmd, input.substring(space_idx+1, input.length()) );
  }
}

void time_led_blank(int time, int pin) {
  if(timedelay % time == 0) {
    if(time_led_toggle == 0) {
      time_led_toggle = 1;
    } else {
      time_led_toggle = 0;
    }
    digitalWrite(pin, time_led_toggle);    
  }
}

void time_beep_blank(int time, int pin) {
  if(timedelay % time == 0) {
    if(time_beep_toggle == 0) {
      time_beep_toggle = 1;
    } else {
      time_beep_toggle = 0;
    }
    digitalWrite(pin, time_beep_toggle);    
  }
}




int command(String cmd, String str) {
  int module_idx = 0;

  Serial.println("command = " + cmd);

  // command prefix check
  // 커멘드에 번호가 있는지?
  //문자의 첫번째 위치부터 다음 토큰까지 읽어낸다
  int space_idx = cmd.indexOf(":");
  if(space_idx!= -1) {
    module_idx = cmd.substring(0, space_idx).toInt();;
    Serial.print("module = ");
    Serial.print(module_idx);

    cmd = cmd.substring(space_idx+1, cmd.length());
    Serial.print(", command = ");
    Serial.println(cmd);

    Wire.write('=');

    Wire.beginTransmission(module_idx);
    for(int n=0; n<str.length(); n++) {
      Wire.write(str.charAt(n));
    }

    for(int n=0; n<cmd.length(); n++) {
      Wire.write(cmd.charAt(n));
    }  
    Wire.endTransmission();
    
    return 0; //함수 중단
  } 
  

  
  // local 커멘드

  if (cmd == "beep") {
    parser_beep(str);
  }

  if (cmd == "led") {
    parser_led(str);
  }

  if (cmd == "slave") {
    int num = str.toInt();
    EEPROM.write(0,num);
  
    slave_num = num;
    Wire.begin(slave_num); 

    beep(500);
    Serial.print("I2C Slave num = ");
    Serial.println(num);
  }

  /* 서보모터 명령어 */
  if (cmd == "servo1") {
    int position = str.toInt();  
    
    if(server1_angle <= position) {
      for(int i=server1_angle; i<=position;i+=2) {
        servo_motor1.write(i);
        delay(5);
      }
    } else {
      for(int i=server1_angle; i>position;i-=2) {
        servo_motor1.write(i);
        delay(5);
      }
    }

    server1_angle = position;
    Serial.print("servo1 angle = ");
    Serial.println(server1_angle);
  }
  


  if (cmd == "servo2") {
    int position = str.toInt();  
    
    if(server2_angle <= position) {
      for(int i=server2_angle; i<=position;i+=2) {
        servo_motor2.write(i);
        delay(5);
      }
    } else {
      for(int i=server2_angle; i>position;i-=2) {
        servo_motor2.write(i);
        delay(5);
      }
    }

    server2_angle = position;
    Serial.print("servo2 angle = ");
    Serial.println(server2_angle);
  } 

  if (cmd == "servo3") {
    int position = str.toInt();  
    
    if(server3_angle <= position) {
      for(int i=server3_angle; i<=position;i+=2) {
        servo_motor3.write(i);
        delay(5);
      }
    } else {
      for(int i=server3_angle; i>position;i-=2) {
        servo_motor3.write(i);
        delay(5);
      }
    }

    server3_angle = position;
    Serial.print("servo3 angle = ");
    Serial.println(server3_angle);
  } 
  


  







}



void parser_beep(String str) {
  int time = str.toInt();
  beep(time);
}

void parser_led(String str) {
  time_blank_delay[12] = str.toInt();
}


/* =====
 * command
   ===== */




서브목차