본문 바로가기
  • 스스로 행복을 가꾸는 교육을 꿈꾸다
MAKING/우리반 쌤의 똑똑한 메이커 테이블

스테퍼 모터 연구4

by FermeH 2020. 5. 9.

지난 시간에 틴커캐드 서킷으로 만들어 보았던 회로를 직접 만들어 보았습니다. 

바로 이것인데요, 사실 서킷으로 더 만들어 보려고 했는데 오류가 생겼습니다. 

지난 시간에 찾아 놓은 스테퍼 모터의 속도 조절 함수가 말을 듣지 않았습니다. 

 

#include <Stepper.h>



int segValue[10][8] = {
  {1, 1, 1, 1, 1, 1, 0, 0}, // 0
  {0, 1, 1, 0, 0, 0, 0, 0}, // 1
  {1, 1, 0, 1, 1, 0, 1, 0}, // 2
  {1, 1, 1, 1, 0, 0, 1, 0}, // 3
  {0, 1, 1, 0, 0, 1, 1, 0}, // 4
  {1, 0, 1, 1, 0, 1, 1, 0}, // 5
  {1, 0, 1, 1, 1, 1, 1, 0}, // 6
  {1, 1, 1, 0, 0, 0, 0, 0}, // 7
  {1, 1, 1, 1, 1, 1, 1, 0}, // 8
  {1, 1, 1, 1, 0, 1, 1, 0}  // 9
};

int segPin[]={2, 3, 4, 5, 6, 7, 8, 9}; //사용핀{a,b,c,d,e,f,g,dp} 순서대로 
int UB = 10; //UpButton
int DB = 11; //DownButton
int SetSize = A5;
int StepperNUM = A4; 

int num = 0; //화면 표시 숫자 
int Size = 0; //정한 사이즈 

const int stepsPerRevolution = 200;

Stepper myStepper(stepsPerRevolution, 8, 9, 19, 11);

void setup() {
  for(int i=0;i<8;i++){
    pinMode(segPin[i], OUTPUT);
  }
  pinMode(StepperNUM, OUTPUT);
  
  pinMode(UB, INPUT_PULLUP);//UpButton 입력 
  pinMode(DB, INPUT_PULLUP);//DownButton 입력
  pinMode(SetSize, INPUT_PULLUP);//사이즈 정하기 버튼 입력
}



void loop() {   
  if(digitalRead(UB) == LOW){
  	if(num==9) num = 0;
    else num++;
    delay(150);
  }
  
  if(digitalRead(DB) == LOW){
  	if(num != 0) num--;
    delay(150);
  }
  
  segOutput(num);
  
  if(digitalRead(SetSize) == LOW){
  	Size = num;
    segClear();
    delay(100);
    segOutput(Size);
  }
  
  if(Size == 1){
  myStepper.setSpeed(100);
}
            
  
  
}

void segClear(){
  for(int i= 0; i < 8; i++){
  	digitalWrite(segPin[i], LOW);
  }
}			


void segOutput(int Number){
	segClear();
  for(int i=0; i<8; i++){
  	digitalWrite(segPin[i], segValue[Number][i]);
  }
  delayMicroseconds(1000);
}

이 코드였는데요, 문제는 Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11); 부분이었습니다. 

허허 서킷에서 이런 것도 봤습니다.

물론 괄호 안의 핀번호를 바꾸기는 해야했지만, 우선 당장 Stepper 자체를 클래스로 인식하지 못했습니다. 

다른 커뮤니티들에도 검색해본 결과, 

1) #include <Stepper.h> 를 #include "Stepper.h" 로 바꾸어라

2) Stepper.h 파일의 코드를 수정하라는 등의 방법이 있었습니다. 

 

그렇지만 첫번째 방법은 효과가 없었고, 두번째 방법은 틴커캐드 서킷으로 하기 때문에 해결 불가능한 부분이었습니다. 

그리고 어차피 오프라인으로 만들면 a4988 드라이브를 사용해야 했기에 깔끔하게 갈아탔습니다.^^


1. 7세그먼트 캐소드 문제 해결하기 

저번 시간 연구를 멈추었던 가장 큰 이유는 캐소드 문제였습니다. 

왼쪽: 일반적인 형태(0.56인치), 오른쪽: 이번 연구에서 사용한 형태(0..36인치)입니다. 

캐소드가 다른 한 자리 7세그먼트 캐소드와 달리 작은 것이었는데요, 

이 캐소드의 입력 핀 구조를 찾는 것이 너무 헷갈렸습니다. ㅠㅠ 

그런데 오늘은 이렇게 저렇게 꽂아본 결과 성공했어요! 그 결과 공유합니다. 

 

2. 버튼으로 숫자 조정하기 

파란색 버튼으로 숫자 1 더하기, 

빨간색 버튼으로 숫자  1 빼기, 

노란색 버튼으로 사이즈 정하기를 할 수 있는 구조를 만들었습니다. 사이즈가 확정되었다는 의미로 한 번 깜박 거립니다. 

 

3. 입력한 수치 만큼만 스테퍼 모터가 작동하도록 하기 

이것을 위해서 위에서 조립한 부분에 스테퍼 모터를 연결했습니다. 

아까 맨 처음에 설명한 문제를 드디어 해결해야하는 부분이었습니다. 

 

저번에 모터를 작동시킬 때 만들어 놓은 코드와 합쳐서 코드를 새로 구성해보았습니다. 

그런데 드라이버를 만져보고서는 너무 뜨거워서 깜짝 놀랐어요! 

무엇을 잘못 연결했는지 드리이버가 열만 받으면서 사망하고 말았습니다.. ㅠㅠ 

 

아아.. 녹아버린 그대여..ㅠㅠ 

그래서 다시 연결을 하고 점퍼선 연결을 고쳤습니다. 

알고 보니 dirPin 을 아날로그 핀에, stepPin을 디지털 핀에 연결해야 하는데 바꾸어 연결한 것이 화근이었습니다. 

일단 모터를 움직이는 코드만 다시 실행해보면서 문제를 해결했습니다. 

 

그 후에, 입력한 값 = 1, 2, 3에 따라 서로 다른 시간 동안 움직이도록 하는 코드로 넘어갔습니다. 

millis() 함수를 사용해서 다음과 같은 코드를 짰습니다.

#include <Stepper.h>



int segValue[10][8] = {
  {1, 1, 1, 1, 1, 1, 0, 0}, // 0
  {0, 1, 1, 0, 0, 0, 0, 0}, // 1
  {1, 1, 0, 1, 1, 0, 1, 0}, // 2
  {1, 1, 1, 1, 0, 0, 1, 0}, // 3
  {0, 1, 1, 0, 0, 1, 1, 0}, // 4
  {1, 0, 1, 1, 0, 1, 1, 0}, // 5
  {1, 0, 1, 1, 1, 1, 1, 0}, // 6
  {1, 1, 1, 0, 0, 0, 0, 0}, // 7
  {1, 1, 1, 1, 1, 1, 1, 0}, // 8
  {1, 1, 1, 1, 0, 1, 1, 0}  // 9
};

int segPin[]={2, 3, 4, 5, 6, 7, 8, 9}; //사용핀{a,b,c,d,e,f,g,dp} 순서대로 
int UB = 10; //UpButton
int DB = 11; //DownButton
int SetSize = A5;

int num = 0; //화면 표시 숫자 
int Size = 0; //정한 사이즈 

const int stepsPerRevolution = 200;

int dirPin = A4; 
int stepPin = 12;

unsigned long period=0; //이전시간
unsigned long millisTime = 0; //현재시간
unsigned long countTime = 0; //카운트시작시간

void setup() {
  for(int i=0;i<8;i++){
    pinMode(segPin[i], OUTPUT);
  }
  
  pinMode(UB, INPUT_PULLUP);//UpButton 입력 
  pinMode(DB, INPUT_PULLUP);//DownButton 입력
  pinMode(SetSize, INPUT_PULLUP);//사이즈 정하기 버튼 입력

  pinMode(dirPin, OUTPUT);
  pinMode(stepPin, OUTPUT);


  Serial.begin(115200);
}



void loop() {   
  if(digitalRead(UB) == LOW){
  	if(num==9) num = 0;
    else num++;
    delay(150);
  }
  
  if(digitalRead(DB) == LOW){
  	if(num != 0) num--;
    delay(150);
  }
  
  segOutput(num);
  
  if(digitalRead(SetSize) == LOW){
  	Size = num;
    segClear();
    delay(100);
    segOutput(Size);

   millisTime=millis();
   digitalWrite(dirPin, HIGH);
    
    if(Size == 1){
      period = 500;
      while(millis() < millisTime+period){
       
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(200);
        digitalWrite(stepPin, LOW);
        delay(1);
      }
    }else if(Size == 2){
        period = 1000;
      while(millis() < millisTime+period){
       
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(200);
        digitalWrite(stepPin, LOW);
        delay(1);
      }    
    }else if(Size == 3){
      period = 1500;
      while(millis() < millisTime+period){
       
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(200);
        digitalWrite(stepPin, LOW);
        delay(1);
      }   
    }
  }
}

void segClear(){
  for(int i= 0; i < 8; i++){
  	digitalWrite(segPin[i], LOW);
  }
}			


void segOutput(int Number){
	segClear();
  for(int i=0; i<8; i++){
  	digitalWrite(segPin[i], segValue[Number][i]);
  }
  delayMicroseconds(1000);
}

 

 

사이즈 1, 2, 3 순서대로 작은 사이즈부터 큰 사이즈가 되도록 했습니다. 

사이즈가 작으면 모터가 그만큼 조금 움직여야 하니 움직이는 시간을 조정했습니다. 

움직이는 시간은 period 변수로 설정했습니다. 

 

다음에 모터에 바퀴를 달고 period 만 적절하게 조절하면 잘 움직일 것 같습니다. 

 

바퀴를 구해서 컴백하겠습니다!ㅎㅎ

댓글