안녕하세요? 턴테이블 플래터 속도 측정만 해보려던 일이 조금 커져서
다음과 같은 기능을 만들어 보게 되어 소개드립니다.
1. 모터(플래터) START/STOP(기동/정지)
2. 회전수 표시
3. 회전수 선택(33 1/3, 45)
속도 제어는 직류 브러쉬리스 모터(BLDC) 콘트롤러 부위에 있는 엔코더를 좌우로 돌려서 수동으로 조정하는 방식입니다.
동작화면입니다.사진을 누르면 재생됩니다.
참고로 상용화된 AC 싱크로(Synchronized AC) 모터 제어용 Falcon 의 전원부와 RoadRunner 라고하는 Tachometer 의 동작 동영상입니다. 사진을 누르면 재생됩니다.
동작 사용 사례입니다.
작동 순서는 아래와 같습니다.
1. 전원 on -> 환영 banner, 제 이름
2. start ( 왼쪽 버튼) -> start banner
3. LCD display off ( 가운데 버튼)
4. LCD display on ( 가운데 버튼)
5. 33.3 -> 45 회전 변경 ( 오른쪽 버튼)
6. display off ( 가운데 버튼)
7. 33.3, 45 회전 변경 ( 오른쪽 버튼)
8. display on ( 가운데 버튼)
9. stop( 왼쪽 버튼) -> Good Bye^^ banner
사진을 누르면 재생됩니다.
사용된 MCU는 요즘 아주 구하기 쉬워진 아두이노 우노 또는 나노( 두가지 모두 아주 잘 동작됩니다.)를
이용하였습니다.
사용된 모듈과 연결선, 그리고 아두이노에서 스케치라고 부르는 소스코드를 아래와 같이 구현하였습니다.
구현하시고 싶으신 분은 이대로 만드시면 똑 같이 동작합니다.
먼저 연결선 다이어그램입니다.
제가 하드웨어 디자이너는 아니어서, 엑셀 파일로 그린 내용입니다.
사용된 릴레이 모듈입니다. (사진은 1개의 모듈이고 사용된 모듈은 릴레이 2개짜리입니다.
릴레이 모듈은 찍어놓은 사진이 없어서 인테넷에서 빌려왔습니다.
사진 출처는 http://www.3egadgets.com/66-ttl-to-relay-control-250vac-10a-no-nc-1-channels-with-indicator-
led.html 입니다. 저작권 문제시 삭제 하겠습니다.)
Hall Effect Sensor 입니다. 플래터 하부의 적당한 위치에 직경 2mm 의 네오디움 자석을 붙이고
센서가 자석이 1회 지날때를 측정하는 방식으로 RPM을 구하게 됩니다.
박스에 보여질 LCD 창입니다. 2행의 16자를 표현할 수 있습니다.
MCU와 4개의 선만으로 연결가능한 I2C 모듈이 있어서 연결이 아주 쉽습니다.
제가 만든 스케치입니다. 저작권에 관계없이 필요하신 분은 드래그해서 가져다 사용하시면 됩니다.
커멘트 부분에 간단한 결선 내용이 있어서 위의 와이어링 도면이 없어도 구성은 가능하십니다.
#include <Timer.h>
//#include <Event.h>
//#include <PWM.h>
#include <LiquidCrystal_I2C.h>
//#include <PinChangeInt.h>
#include <Button.h>
// Don"t change these.
#define FIRST_ANALOG_PIN 14
#define TOTAL_PINS 19
// Modify these at your leisure.
//#define sensorPin A3 // Hall Effect Sensor Pin
//#define startstop A0 // Mortor start/stop, monitor start/stop,lcd on/off, timer(Elapsed reset)
//#define rpm33 A1 // set target RPM to 33 1/3
//#define rpm45 A2 // set target RPM to 45
//#define pwmPin A3 // analogue Pin for PWM
LiquidCrystal_I2C lcd(0x3f,16,2);
#define TRUE 1
#define FALSE 0
#define ON LOW
#define OFF HIGH
// Sensor & control part
// Hall sensor Effect wiring
// pin 3 --------------- Digital Out, Arduino input from Hall effect sensor
// Vcc --------------- Vcc input, Hall sensor effect sensor
// GND --------------- GND Hall sensor effect sensor
const byte sensorPin = 3; // Arduino input, Hall Effect Sensor Pin, use interrupt Timer
// 2 Relay Module wiring
// Power Vcc --------------- Vcc, Relay Module
// pin 9 -------------- In1, Relay module
// pin 8 -------------- In2, Relay module
// GND -------------- Power GND to Relay module
// external 5V VCC -------------- JD VCC to Relay module
const byte RelayPin1 = 9; // Arduino output, Relay In1. startstop, relay to power part of motor module
const byte RelayPin2 = 8; // Arduino output, Relay in2, Speed select , 33.3 / 45, connect to motor mudule selector
// Switch part
// switch wiring information-internal pullup, without pullup register from GND to inernal register, initial value needed.
// pin 10 ______/ ------ pin 10 Speed 33 1/3 , 45 selector switch
// pin 11 ------/ ______ pin 11 LCD on/off switch,
// pin 12 ______/ ------ pin 12 Motor start / stop switch
// GND -------------- bridge all 3 switch" other pins
const byte speedPin = 10; // Arduino input, 33, 45 select toggle switch
const byte LCDonoffPin = 11; // Arduino input, LCD on off toggle swicth
const byte startstopPin = 12; // Arduino input, start stop toggle switch
const byte ledpin = 13; // Arduino output, LED Pin
const byte PowerLED = 4; // Arduino output, Power-on LED
Button LcdButton = Button ( LCDonoffPin, BUTTON_PULLUP_INTERNAL ); // add Switch Lcd on/ff button
Button SpeedButton = Button ( speedPin, BUTTON_PULLUP_INTERNAL ); // add Speed selection button
Button StartButton = Button ( startstopPin, BUTTON_PULLUP_INTERNAL ); // add Motor start/stop button
bool LastLCD, LastSPEED, LastSTARTSTOP; // button status
bool LCDON = TRUE; // lcd button event value
bool SPEED = FALSE; // SPEED selection event value
bool STARTSTOP = FALSE; // Motor stop/start event button
bool outputStatus = FALSE;
char rpmstr[8];
char microsecstr[8];
float StartPoint, Finished;
float Elapsed;
float RPM;
volatile uint8_t latest_interrupted_pin;
volatile uint8_t interrupt_count[TOTAL_PINS]={0}; // possible arduino pins
volatile uint8_t pin3Count=0;
/*
* LCD RS pin to digital pin 8
* LCD Enable pin to digital pin 9
* LCD D0 pin to digital pin 1
* LCD D1 pin to digital pin 10
* LCD D2 pin to digital pin 11
* LCD D3 pin to digital pin 12
* LCD D4 pin to digital pin 4
* LCD D5 pin to digital pin 5
* LCD D6 pin to digital pin 6
* LCD D7 pin to digital pin 7
* LCD R/W pin to ground
* 10K resistor:
* ends to +5V and ground
* wiper to LCD VO pin (pin 3)
*/
/*
* Turntable motor TM-R501
* Platter 33.3 RPM
* Motor 1034 RPM
* motor tacho 6204
* Platter 45 RPM
* Motor 1386 RPM
* motor tacho 8316
*/
void tick()
{
Elapsed=micros()-StartPoint;
StartPoint=micros();
digitalWrite(PowerLED,LOW);
outputStatus = TRUE;
}
void setup()
{
int iPos=0;
//setup lcd
//digitalWrite(pannelLED, LOW);
pinMode(PowerLED, OUTPUT);
digitalWrite(PowerLED, HIGH);
lcd.init();
lcd.noCursor();
//lcd.noBacklight();
lcd.clear();
//delay(400);
lcd.backlight();
lcd.noAutoscroll();
// start banner
lcd.setCursor (1,0);
lcd.print("Hello, Dooyoung");
lcd.setCursor (1,1);
lcd.print("Enjoy Music");
for (iPos=1;iPos<=16;iPos++)
{
lcd.scrollDisplayRight();
delay(400);
}
// Display Default speed with 33.3
lcd.clear();
lcd.setCursor(1,0);
lcd.print ("33.3 ");
lcd.setCursor(3, 1);
lcd.print("RPM ");
Serial.begin(115200);
// setup pins
//setup relay pins yo be "HIGH" as default. do not remove initial digitalwrite before pinMode.
digitalWrite(RelayPin1, OFF);
digitalWrite(RelayPin2, OFF);
//initialize variables
LastLCD=FALSE; // OFF
LastSPEED = FALSE; // 33.3
LastSTARTSTOP = FALSE; // STOP
Elapsed = StartPoint = micros();
delay(100);
//setup Pin Mode
pinMode(ledpin, OUTPUT);
digitalWrite(ledpin, LOW);
pinMode(RelayPin1, OUTPUT);
pinMode(RelayPin2, OUTPUT);
// input mode with VCC with pullup register
pinMode(sensorPin, INPUT);
// setup interript
//attachInterrupt(digitalPinToInterrupt(sensorPin), tick, FALLING);
// original psuedo interrupt
//attachPinChangeInterrupt(sensorPin, RPM, FALLING);
//pinMode(sensorPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(sensorPin), tick, FALLING);
//attachPinChangeInterrupt(sensorPin, tick, FALLING);
//StartingPoint=millis();
//ending = millis();
delay(1000);
lcd.clear();
lcd.noBacklight();
}
void loop()
{
//int sensorValue = digitalRead(sensorPin);
float oldRPM=0.0;
int icnt;
if (LcdButton.isPressed())
{
if ( LastLCD )
{
lcd.noBacklight();
lcd.clear();
LastLCD = FALSE;
}
else
{
lcd.clear();
lcd.backlight();
LastLCD = TRUE;
lcd.setCursor(1,0);
if (LastSPEED)
{
lcd.print(" 45 ");
}
else
{
lcd.print("33.3 ");
}
lcd.setCursor(3,1);
lcd.print("RPM ");
if (LastSTARTSTOP)
{
RPM = 60000000.0/Elapsed;
dtostrf(RPM, 8,4, rpmstr);
lcd.setCursor(6,0);
//dtostrf(Elapsed/1000.0, 8,4, microsecstr);
lcd.print (Elapsed/1000.0);
lcd.print("mS");
lcd.setCursor(7,1);
lcd.print(rpmstr);
oldRPM = RPM;
}
}
delay(300);
}
if (SpeedButton.isPressed())
{
if (!LastLCD)
{
lcd.clear();
lcd.backlight();
}
if ( !LastSPEED )
{
LastSPEED = TRUE; //45
digitalWrite ( RelayPin2, ON);
lcd.setCursor(1,0);
lcd.print (" 45 ");
}
else
{
LastSPEED = FALSE; // 33.3
digitalWrite ( RelayPin2, OFF);
lcd.setCursor(1,0);
lcd.print ("33.3 ");
}
lcd.setCursor(3,1);
lcd.print("RPM ");
delay(1000);
if (!LastLCD)
{
lcd.clear();
lcd.noBacklight();
}
}
if (StartButton.isPressed())
{
if (LastSTARTSTOP) // start -> stop
{
Elapsed = StartPoint = micros();
digitalWrite (RelayPin1, OFF);
lcd.clear();
if (!LastLCD)
{
lcd.backlight();
}
lcd.setCursor(5,1);
lcd.print("Good Bye^^");
for(icnt=0;icnt<16;icnt++)
{
lcd.scrollDisplayLeft();
delay(400);
}
lcd.noBacklight ();
lcd.clear();
LastSTARTSTOP=FALSE;
LastLCD = FALSE;
}
else // stop -> start
{
digitalWrite (RelayPin1, ON);
lcd.clear();
lcd.backlight();
lcd.setCursor(6,0);
lcd.print("Music Start!!");
lcd.setCursor(3,1);
lcd.print("Enjoy Music...");
//1234567890123456
for(icnt=0;icnt<16;icnt++)
{
lcd.scrollDisplayLeft();
delay(400);
}
lcd.clear();
lcd.setCursor(1,0);
if (LastSPEED)
{
lcd.print(" 45 ");
}
else
{
lcd.print("33.3 ");
}
lcd.setCursor(3,1);
lcd.print("RPM ");
LastSTARTSTOP=TRUE;
LastLCD = TRUE;
}
}
if ((outputStatus) && (LastSTARTSTOP) && (LastLCD))
{
RPM = 60000000.0/Elapsed;
dtostrf(RPM, 8,4, rpmstr);
lcd.setCursor(6,0);
//dtostrf(Elapsed/1000.0, 8, 4, microsecstr);
//lcd.print (microsecstr);
lcd.print (Elapsed/1000.0);
lcd.print("mS");
lcd.setCursor(7,1);
lcd.print(rpmstr);
Serial.print(Elapsed);
Serial.print(" micro sec, ");
//Serial.print(revolution);
//Serial.print(" SEC,");
Serial.print(rpmstr);
Serial.println(" RPM");
/*
printDouble (revs, 10000);
Serial.print(" RPM\n");
*/
//Serial.print(millis() );
//Serial.print(" ");
//Serial.println(StartingPoint);
//Serial.print("Hall Effect Sensor value:");
//Serial.println(sensorValue);
}
if (outputStatus)
{
delay(50);
digitalWrite(PowerLED, HIGH);
outputStatus = FALSE;
}
}
오랜만에 깡통이랑 코딩 비슷하게 해서,기록차 남겨 봅니다.
없는 부품구하고 케이스 구하고, 이래 저래 소소한 공이 들어간 작업이었습니다.
혹시 궁금하신 내용 있으시면, 아는 한도에서 같이 말씀드릴 수 있도록 하겠습니다.
재미없는 글 읽어 주셔서 다시 한번 감사드립니다.
- 2016. .12. 2 추가 내용입니다.
아래 전영진님을 위한 내용입니다.
지금 부품이 수급되고 있습니다. 저는 만능 기판에 점퍼를 연결하여 만들었는데요. 뜨개질이라 부르시더군요.ㅎㅎ
속도 기능만 넣는다면 차후에 올려드리는 하드웨어 만으로 간단하게 결선하고 케이스에 넣을 수 있도록 사진
으로 추가 안내 드리겠습니다.
연결 선은 아주 단순해 졌습니다.
속도 측정 기능만 넣은 소스입니다.
#include <Timer.h>
//#include <Event.h>
#include <PWM.h>
#include <LiquidCrystal_I2C.h>
#include <PinChangeInt.h>
// Don"t change these.
#define FIRST_ANALOG_PIN 14
#define TOTAL_PINS 19
// Modify these at your leisure.
//#define sensorPin A3 // Hall Effect Sensor Pin
#define startstop A0 // Mortor start/stop, monitor start/stop,lcd on/off, timer(elapsed reset)
#define rpm33 A1 // set target RPM to 33 1/3
#define rpm45 A2 // set target RPM to 45
//#define pwmPin A3 // analogue Pin for PWM
LiquidCrystal_I2C lcd(0x3f,16,2);// Or LCD display address can be 0x27, it should be found while scanning
//int tachPin = 3; //monitor Motor RPM
const byte sensorPin = 3; // Hall Effect Sensor Pin
const byte PowerLED = 4; // Power on Indicator LED
const byte ledpin = 13;
float StartPoint, finished;
float elapsed, time;
float revs;
float revolution;
float RPM;
volatile uint8_t latest_interrupted_pin;
volatile uint8_t interrupt_count[TOTAL_PINS]={0}; // possible arduino pins
volatile uint8_t pin3Count=0;
/*
* LCD RS pin to digital pin 8
* LCD Enable pin to digital pin 9
* LCD D0 pin to digital pin 1
* LCD D1 pin to digital pin 10
* LCD D2 pin to digital pin 11
* LCD D3 pin to digital pin 12
* LCD D4 pin to digital pin 4
* LCD D5 pin to digital pin 5
* LCD D6 pin to digital pin 6
* LCD D7 pin to digital pin 7
* LCD R/W pin to ground
* 10K resistor:
* ends to +5V and ground
* wiper to LCD VO pin (pin 3)
*/
/*
* Turntable motor TM-R501
* Platter 33.3 RPM
* Motor 1034 RPM
* motor tacho 6204
* Platter 45 RPM
* Motor 1386 RPM
* motor tacho 8316
*/
char strrpm[8];
int outputStatus=0;
#define TRUE 1
#define FALSE 0
void tick()
{
elapsed=(micros()-StartPoint);
StartPoint=micros();
outputStatus = 1;
digitalWrite(PowerLED,LOW);
}
void setup()
{
//setup lcd
lcd.init();
lcd.noCursor();
lcd.noBacklight();
delay(500);
lcd.backlight();
lcd.noAutoscroll();
lcd.setCursor(1,0);
lcd.print ("33.3 ");
lcd.setCursor(3, 1);
lcd.print("RPM ");
Serial.begin(115200);
// setup pins
pinMode(ledpin,OUTPUT); //debug to led 13
pinMode(sensorPin, INPUT);
//pinMode(tachPin, INPUT);
//Power on indictor
pinMode(PowerLED, OUTPUT);
digitalWrite(PowerLED,HIGH);
pinMode(ledpin, OUTPUT);
// setup interript
//attachInterrupt(digitalPinToInterrupt(sensorPin), tick, FALLING);
// original psuedo interrupt
//attachPinChangeInterrupt(sensorPin, RPM, FALLING);
//pinMode(sensorPin, INPUT_PULLUP);
pinMode(sensorPin, INPUT);
attachInterrupt(digitalPinToInterrupt(sensorPin), tick, FALLING);
//attachPinChangeInterrupt(sensorPin, tick, FALLING);
//StartingPoint=millis();
//ending = millis();
elapsed = StartPoint = micros();
}
void loop()
{
float oldRPM=0.0;
if (outputStatus == 1)
{
//detachInterrupt(digitalPinToInterrupt(sensorPin));
//digitalWrite(RelayPin1, HIGH);
//digitalWrite(RelayPin2, HIGH);
RPM = 60000000.0/elapsed;
if (elapsed >= 2000000.0)
{
lcd.setCursor(6,0);
lcd.print(" ");
elapsed = 0.0;
oldRPM = RPM = 0.0;
}
lcd.setCursor(6,0);
lcd.print (elapsed/1000.0);
lcd.print("ms");
if ( elapsed >= 2000000.0)
{
lcd.setCursor(7,1);
lcd.print(" ");
}
dtostrf(RPM, 8,4, strrpm);
lcd.setCursor(7,1);
lcd.print(strrpm);
//lcd.print(strrpm);
outputStatus = 0;
//dtostrf(revs, 8,4, strrpm);
Serial.print(elapsed);
Serial.print(" micro seconds, ");
//Serial.print(revolution);
//Serial.print(" SEC ");
Serial.print(strrpm);
Serial.print(" RPM, ");
delay(20);
digitalWrite(PowerLED,HIGH);
/*
printDouble (revs, 10000);
Serial.print(" RPM\n");
*/
//Serial.print(millis() );
//Serial.print(" ");
//Serial.println(StartingPoint);
//Serial.print("Hall Effect Sensor value:");
//Serial.println(sensorValue);
//attachInterrupt(digitalPinToInterrupt(sensorPin), tick, FALLING);
}
delay(300);
}
2016.12.8 추가 내용입니다.
말씀드렸던 프로토 타입 형태의 기판과 결합된 6~9v 대응의 Nano 입니다.
같은 Nano 보드를 만능기판으로 구성한 내용입니다.
먼저 전면입니다.
뒷면 배선내용입니다.
동작 시험입니다.
감사합니다.