Adventure Design

본 토픽은 현재 준비중입니다. 공동공부에 참여하시면 완성 되었을 때 알려드립니다.

9. 시리얼 머신 V1의 완성

평일에 시간 날때마다 조금씩하고 수정하다 보니,

대강 시리얼 머신의 첫번째 버전을 완성할 수 있었습니다.

 

코드에서도 대폭 수정된 부분이 있었습니다.

이전까지 모터의 움직임을 delay() 함수로 제어하는 코드를 짰는데,

이렇게 하면 delay() 함수에서 아두이노가 동작을 멈추기 때문에

아두이노 간 UART 통신이 제대로 이루어 지지 않았습니다.

( delay() 에 들어가는 순간, 첫번째 아두이노에서 두번째 아두이노로 보내야할 신호를

보내지 못하는 현상을 발견함 )

그래서 아두이노의 millis() 함수를 이용해 delay()와 비슷한 효과를 내면서도,

아두이노는 멈추지 않는 코드로 코드 작성 방향을 바꾸었습니다.

이렇게 바꾸고 나니 장치가 전체적으로 매우 안정해졌다는 장점은 있었는데요.

코드 길이가... 정말 길어졌습니다!

그래도 delay() 함수를 사용하지 않는 만큼, 더 안정적인 코드를 구현하게 된 것 같아 뿌듯합니다.

영상 보면 약간의 실수하는 부분이 있는데

( topping 선택에서 서보모터가 움직이지 않는다던가, 우유 모터가 작동하는데 컨베이어도 같이 움직인다던지 하는 등...)

몇시간만 잡고 있으면 바로 해결될 것 같습니다.

일을 많이 진행시킨 것 같아 뿌듯한 마음입니다.


송신부


//코드 안정화 삭제
// 초음파 센서 2개
// 서보모터랑 uart 통신까지
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

LiquidCrystal_I2C lcd(0x3F, 16, 2);

int switch_ = 0; // while 문 탈출을 위한 변수
unsigned long previousMillis = 0; //delay를 쓰지 않으려는 발악
long interval = 5000; //delay를 쓰지 않으려는 발악

int IN1 = 3;
int IN2 = 4;
int ENA = 5;
int trig_1 = 7;
int echo_1 = 6;

int trig_2 = 9;
int echo_2 = 8;

int trig_3 = 10;
int echo_3 = 11;

int button_a = 12;
int button_b = 13;

int a_status = 0;
int b_status = 0;
int preva_status = 0;
int prevb_status = 0;

long distance_return(int trig, int echo);
void motor_go(int IN1, int IN2, int ENA);
void motor_go_slow(int IN1, int IN2, int ENA);
void motor_stop(int IN1, int IN2);
void sensor_Print(long distance);

void setup() 
{

Serial.begin(9600);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(trig_1, OUTPUT);
pinMode(echo_1, INPUT);
pinMode(trig_2, OUTPUT);
pinMode(echo_2, INPUT);
pinMode(trig_3, OUTPUT);
pinMode(echo_3, INPUT);
pinMode(ENA, OUTPUT);

pinMode(button_a, INPUT);
pinMode(button_b, INPUT);

lcd.init();
lcd.backlight();
}

void loop() 
{
  while (switch_ == 0)
  {
  /* ♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥ 거리 받아오는 코드 ♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥*/
  long new_distance_1 = distance_return(trig_1, echo_1);
  long new_distance_2 = distance_return(trig_2, echo_2);
  long new_distance_3 = distance_return(trig_3, echo_3);

  /* ♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥ 거리 받아오는 코드 ♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥*/

  /* ♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥ if 문 1번 ♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥*/
  if (new_distance_1 < 50)
  {

    lcd.setCursor(0,0); 
    lcd.print("  a) chocolate  ");     // 문구를 출력합니다.

    lcd.setCursor(0,1);
    lcd.print(" b) berry");
    
    unsigned long currentMillis = millis(); 
    previousMillis = currentMillis;
    char num;
    a_status = digitalRead(12);
    b_status = digitalRead(13);
    
    
    
    while (currentMillis - previousMillis <= 10000)
    { 
      
      a_status = digitalRead(12);
      b_status = digitalRead(13);

      delay(100);
      motor_stop(IN1, IN2);
      
      if(a_status > preva_status)
      {
        lcd.clear();
        lcd.setCursor(0,0);           // 1번째 줄 0번째 셀부터 입력하게 합니다.
        lcd.print("Your Choice: ");

        lcd.setCursor(0,1);           // 1번째 줄 0번째 셀부터 입력하게 합니다.
        lcd.print("   chocolate   ");
        Serial.print("A");
        
      }

      else if(b_status > prevb_status)
      {
        lcd.clear();
        lcd.setCursor(0,0);           // 1번째 줄 0번째 셀부터 입력하게 합니다.
        lcd.print("Your Choice: ");

        lcd.setCursor(0,1);           // 1번째 줄 0번째 셀부터 입력하게 합니다.
        lcd.print("   berry   ");
        Serial.print("B");
        
      }
      
      currentMillis = millis(); 

      
    }
  
    if (currentMillis - previousMillis >= 10000)
    { 
      lcd.clear(); 
      motor_go(IN1, IN2, ENA);
      delay(1000);
      
    }
    
  }
/* ♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥ 두번째 if 문 ♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥*/


  else if (new_distance_2 < 50)
  {

    lcd.setCursor(0,0); 
    lcd.print("  topping?   ");     // 문구를 출력합니다.

    lcd.setCursor(0,1);
    lcd.print(" a) YES b) NO ");
    
    unsigned long currentMillis = millis(); 
    previousMillis = currentMillis;
    a_status = digitalRead(12);
    b_status = digitalRead(13);
    
    char num;

       
    while (currentMillis - previousMillis <= 10000)
    { 
      a_status = digitalRead(12);
      b_status = digitalRead(13);

      delay(100);
      motor_stop(IN1, IN2);
      if(a_status > preva_status)
      {
        lcd.clear();
        lcd.setCursor(0,0);           // 1번째 줄 0번째 셀부터 입력하게 합니다.
        lcd.print("Your Choice: ");

        lcd.setCursor(0,1);           // 1번째 줄 0번째 셀부터 입력하게 합니다.
        lcd.print("   YES   ");
        Serial.print("a");
        
      }

      else if(b_status > prevb_status)
      {
        lcd.clear();
        lcd.setCursor(0,0);           // 1번째 줄 0번째 셀부터 입력하게 합니다.
        lcd.print("Your Choice: ");

        lcd.setCursor(0,1);           // 1번째 줄 0번째 셀부터 입력하게 합니다.
        lcd.print("   NO   ");
        Serial.print("b");
        
      }

    currentMillis = millis();
    
      
    }
  
    if (currentMillis - previousMillis >= 10000)
    { 
      lcd.clear();
      motor_go(IN1, IN2, ENA);
      delay(1000);
    }
    
  }

/* ♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥ 세번째 if 문 ♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥*/


  else if (new_distance_3 < 50)
  {

    lcd.setCursor(0,0); 
    lcd.print("  a) Cow milk   ");     // 문구를 출력합니다.

    lcd.setCursor(0,1);
    lcd.print(" b) Soy Milk  ");
    
    unsigned long currentMillis = millis(); 
    previousMillis = currentMillis;
    
    char num;
    a_status = digitalRead(12);
    b_status = digitalRead(13);
    
    
    while (currentMillis - previousMillis <= 10000)
    { 

      a_status = digitalRead(12);
      b_status = digitalRead(13);

      delay(100);
      motor_stop(IN1, IN2);
      if(a_status > preva_status)
      {
        lcd.clear();
        lcd.setCursor(0,0);           // 1번째 줄 0번째 셀부터 입력하게 합니다.
        lcd.print("Your Choice: ");

        lcd.setCursor(0,1);           // 1번째 줄 0번째 셀부터 입력하게 합니다.
        lcd.print("   Cow Milk   ");
        Serial.print("c");
        
      }

      else if(b_status > prevb_status)
      {
        lcd.clear();
        lcd.setCursor(0,0);           // 1번째 줄 0번째 셀부터 입력하게 합니다.
        lcd.print("Your Choice: ");

        lcd.setCursor(0,1);           // 1번째 줄 0번째 셀부터 입력하게 합니다.
        lcd.print("   Soy Milk   ");
        Serial.print("d");
        
      }
      currentMillis = millis(); 
       

      
    }
  
    if (currentMillis - previousMillis >= 10000)
    { 
      lcd.clear();
      switch_ = 1;
      // previousMillis = 0;
      motor_go_slow(IN1, IN2, ENA);
      break;
    }
    
  }


 //마지막 센서 달아서는 거기서 완전히 끝나게 하기
 // 아마 while이랑 break를 쓰면 될것같긴함...
 prevb_status = b_status;
 preva_status = a_status;
 motor_go(IN1, IN2, ENA);
 

 /* ♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥ while 문 끝났다 ♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥*/
}

}

/* ♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥사랑이 넘치는 함수 정의 파트♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥*/
/* ♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥사랑이 넘치는 함수 정의 파트♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥*/
/* ♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥사랑이 넘치는 함수 정의 파트♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥*/

long distance_return(int trig, int echo)
{
  long duration, distance;

  digitalWrite(trig, LOW);
  delayMicroseconds(2);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);

  duration = pulseIn(echo, HIGH);

  distance = duration * 170 / 1000 ;


  return distance;
  
  
}

void sensor_Print(long distance)
{
  Serial.print("거리: ");
  Serial.print(distance);
  Serial.println("mm");
  delay(100);
}

void motor_go(int IN1, int IN2, int ENA)
{
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW); 
  analogWrite(ENA, 150); 
}

void motor_go_slow(int IN1, int IN2, int ENA)
{
    
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  for(int pwm =100; pwm>=1; pwm-=0.5)
  {
     analogWrite(ENA, pwm);
     delay(100);
  }

  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
}

void motor_stop(int IN1, int IN2)
{
  
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  
}

하트 달린 주석은, 코드를 좀 더 사랑스럽게 꾸며보고 싶었던 제 발악입니다.


수신부


//받아오는 부분
#include <Servo.h>
Servo servo;
Servo servo2;

int IN1 = 3;
int IN2 = 4;

int IN3 = 5;
int IN4 = 6;


void setup() {
  Serial.begin(9600);
  servo.attach(13);
  servo2.attach(12);

  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  
}

void loop() {
  if(Serial.available())
  {

  char Data = (char)Serial.read();

  if(Data == 'A')
  {
  
    servo.write(180);
    delay(1000);
    
  }
  else if (Data == 'B')
  {
    
    servo.write(0);
    delay(1000);
  }

  else if (Data == 'a')
  {
    servo2.write(0);
    delay(1000);
  }

  else if (Data == 'b')
  {
    servo2.write(90);
    
  }

else if (Data == 'c')
  {
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);

    delay(5000);
    
  }

  else if (Data == 'd')
  {
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);

    delay(5000);
    
  }

  servo.write(90);
  servo2.write(90);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);
  
}

}

 

댓글

댓글 본문
graphittie 자세히 보기