BASIC4MCU | 질문게시판 | 아두이노로 kineteic timer 만드려는데 도움이 필요합니다...
페이지 정보
작성자 Helloworld 작성일2022-11-30 08:08 조회890회 댓글0건본문
https://www.instructables.com/Kinetic-Digital-Clock-Arduino-3D-Print/
여가 나오는 거 그대로 따라서 만들어봤어요.
서보모터 28개를 돌려야 되다 보니 쉽지 않은 것 같네요..
아두이노도 잘 연결되고 업로드에는 문제없고, 외부전원도 연결했는데 모터가 전혀 돌아가지 않아요.
아래 사진과 같이 서보모터 28개를 아두이노 메가 2560에 센서 확장 쉴드를 통해서 연결한 상태이고
rtc(DS3231) 모듈의 sda, scl 각각 쉴드의 20번, 21번 핀에 연결된 상태입니다.
(서보모터는 세그먼트 자릿수 하나당 7개씩 4자리로 되어있고 각각 2번, 7번, 22번 29번 핀부터 서보모터 7개씩 순서대로 연결했습니다.)
코드는 위 링크의 코드 세 개 중에 마지막 두 코드로 Servo, DS3231를 calibration 한 뒤 첫 번째 코드로 작동시키려고 합니다.
아래 링크의 DS3231의 모듈을 library로 추가해둔 상태입니다.
http://www.rinkydinkelectronics.com/library.php?id=73
아마 코드 실행 상에 오류가 있었던 것 같은데 어떤 이유인지 모르겠습니다...
아니면 서보모터, DS32321, 외부전원만 연결해서는 작동할 수 없는 걸까요?
혹시 예상할 수 있는 이유가 있을까요..?
아두이노에 대한 지식이 많지 않아 질문 드립니다.....
아래에 코드 3개 각각 첨부합니다.
Step 7: Programming
String input;
#include
#include
DS3231 rtc(SDA, SCL);
const int DIGIT_TO_SEGMENT_MAPPING[10][7] = {
{ 1, 1, 1, 1, 1, 1, 0 }, // 0
{ 0, 1, 1, 0, 0, 0, 0 }, // 1
{ 1, 1, 0, 1, 1, 0, 1 }, // 2
{ 1, 1, 1, 1, 0, 0, 1 }, // 3
{ 0, 1, 1, 0, 0, 1, 1 }, // 4
{ 1, 0, 1, 1, 0, 1, 1 }, // 5
{ 1, 0, 1, 1, 1, 1, 1 }, // 6
{ 1, 1, 1, 0, 0, 0, 0 }, // 7
{ 1, 1, 1, 1, 1, 1, 1 }, // 8
{ 1, 1, 1, 1, 0, 1, 1 } // 9
};
const int SEGMENT_INTERVALS[4][7][2] = {
{
{141, 54},
{155, 69},
{150, 73},
{151, 70},
{159, 75},
{159, 75},
{125, 40}
},
{
{164, 76},
{155, 76},
{138, 61},
{180, 87},
{151, 63},
{145, 57},
{165, 78}
},
{
{157, 73},
{156, 70},
{165, 85},
{137, 52},
{133, 50},
{133, 50},
{168, 73}
},
{
{131, 52},
{147, 61},
{131, 51},
{158, 69},
{155, 73},
{116, 28},
{137, 60}
}
};
const int COLON_INTERVAL[2][2] = {
{141, 62},
{137, 30},
};
const int DIGIT_STARTING_SEGMENT_INDEX[4] = {2, 9, 22, 29};
const int COLON_STARTING_INDEX = 16;
const int START_POS = 0;
const int COLON = 2;
const int DIGITS = 4;
const int SEGMENTS_PER_DIGIT = 7;
const int STEP_MS = 20;
const int COUNT_MS = 2000;
const int NUM_SERVOS = DIGITS * SEGMENTS_PER_DIGIT;
int servoTargetDestination[DIGITS][NUM_SERVOS];
int servoTargetDestinationColon[COLON];
int count = 1200;
int timeMS = 0;
Servo servos[DIGITS][SEGMENTS_PER_DIGIT];
Servo colonServos[COLON];
void setup() {
rtc.begin();
for (int i = 0; i < DIGITS; i++) {
for (int j = 0; j < SEGMENTS_PER_DIGIT; j++) {
int offset = DIGIT_STARTING_SEGMENT_INDEX[i];
servoTargetDestination[i][j] = SEGMENT_INTERVALS[i][j][START_POS];
servos[i][j].attach(j + offset);
servos[i][j].write(servoTargetDestination[i][j]);
}
}
delay(500);
for (int i = 0; i < DIGITS; i++) {
for (int j = 0; j < SEGMENTS_PER_DIGIT; j++) {
servos[i][j].detach();
}
}
for (int i = 0; i < COLON; i++) {
colonServos[i].attach(i + COLON_STARTING_INDEX);
colonServos[i].write(COLON_INTERVAL[i][START_POS]);
}
delay(500);
for (int i = 0; i < COLON; i++) {
colonServos[i].detach();
}
for (int i = 0; i < COLON; i++) {
colonServos[i].attach(i + COLON_STARTING_INDEX);
colonServos[i].write(COLON_INTERVAL[i][1]);
}
delay(500);
for (int i = 0; i < COLON; i++) {
colonServos[i].detach();
}
}
void loop() {
// Retrieve and cleanup RTC string. "12:45" -> "1245"
String timeStr = rtc.getTimeStr();
String timeString = timeStr.substring(0, 2) + timeStr.substring(3, 5);
for (int activeDigit = 0; activeDigit < 4; activeDigit++) {
// Step 1: Set servoTargetDestination
String stringCount = String(count); // Swap to timeString to use the clock.
for (int i = 0; i < SEGMENTS_PER_DIGIT; i++)
{
int displayNumber = stringCount.charAt(timeString.length() - 1 - activeDigit) - '0';
int placement = (activeDigit == 3 && displayNumber == 0) ? 0 : DIGIT_TO_SEGMENT_MAPPING[displayNumber][i];
servoTargetDestination[activeDigit][i] = SEGMENT_INTERVALS[activeDigit][i][placement];
}
// Step 2: Increment Segments
for (int i = 0; i < SEGMENTS_PER_DIGIT; i++)
{
Servo servo = servos[activeDigit][i];
int pos = servo.read();
int dest = servoTargetDestination[activeDigit][i];
if (pos != dest) {
if (pos < dest) {
pos++;
} else {
pos--;
}
if (!servo.attached()) {
int offset = DIGIT_STARTING_SEGMENT_INDEX[activeDigit];
servo.attach(i + offset);
}
servo.write(pos);
}
}
}
// Step 3: Wait
delay(STEP_MS);
timeMS = timeMS + STEP_MS;
// Step 4A: Countdown
if (timeMS >= COUNT_MS) {
timeMS = 0;
count = count + 1;
}
// Step 5: Detach anything that is at its destination
for (int i = 0; i < DIGITS; i++) {
for (int j = 0; j < NUM_SERVOS; j++) {
Servo servo = servos[i][j];
int pos = servo.read();
int destination = servoTargetDestination[i][j];
if (pos == destination && servo.attached()) {
servos[i][j].detach();
}
}
}
}
Step 8: Calibration & Setup
DS3231
// DS3231_Serial_Easy
// Copyright (C)2015 Rinky-Dink Electronics, Henning Karlsen. All right reserved
// web: http://www.RinkyDinkElectronics.com/
//
// A quick demo of how to use my DS3231-library to
// quickly send time and date information over a serial link
//
// To use the hardware I2C (TWI) interface of the Arduino you must connect
// the pins as follows:
//
// Arduino Uno/2009:
// ----------------------
// DS3231: SDA pin -> Arduino Analog 4 or the dedicated SDA pin
// SCL pin -> Arduino Analog 5 or the dedicated SCL pin
//
// Arduino Leonardo:
// ----------------------
// DS3231: SDA pin -> Arduino Digital 2 or the dedicated SDA pin
// SCL pin -> Arduino Digital 3 or the dedicated SCL pin
//
// Arduino Mega:
// ----------------------
// DS3231: SDA pin -> Arduino Digital 20 (SDA) or the dedicated SDA pin
// SCL pin -> Arduino Digital 21 (SCL) or the dedicated SCL pin
//
// Arduino Due:
// ----------------------
// DS3231: SDA pin -> Arduino Digital 20 (SDA) or the dedicated SDA1 (Digital 70) pin
// SCL pin -> Arduino Digital 21 (SCL) or the dedicated SCL1 (Digital 71) pin
//
// The internal pull-up resistors will be activated when using the
// hardware I2C interfaces.
//
// You can connect the DS3231 to any available pin but if you use any
// other than what is described above the library will fall back to
// a software-based, TWI-like protocol which will require exclusive access
// to the pins used, and you will also have to use appropriate, external
// pull-up resistors on the data and clock signals.
//
#include
// Init the DS3231 using the hardware interface
DS3231 rtc(SDA, SCL);
void setup()
{
// Setup Serial connection
Serial.begin(115200);
// Uncomment the next line if you are using an Arduino Leonardo
//while (!Serial) {}
// Initialize the rtc object
rtc.begin();
// The following lines can be uncommented to set the date and time
// rtc.setDOW(FRIDAY); // Set Day-of-Week to SUNDAY
rtc.setTime(23, 05, 0); // Set the time to 12:00:00 (24hr format)
rtc.setDate(7, 19, 2021); // Set the date to January 1st, 2014
}
void loop()
{
// Send time
Serial.println(rtc.getTimeStr());
// Wait one second before repeating :)
delay (1000);
}
Servo
/*
Controlling a servo position using a potentiometer (variable resistor)
by Michal Rinott < http://www.arduino.cc/en/Tutorial/Knob
>
modified on 8 Nov 2013
by Scott Fitzgerald
http://www.arduino.cc/en/Tutorial/Knob
*/
#include
Servo myservo; // create servo object to control a servo
int potpin = 0; // analog pin used to connect the potentiometer
int val; // variable to read the value from the analog pin
const int SEGMENT_INTERVALS[4][7][2] = {
{
{146, 57},
{147, 62},
{138, 51},
{160, 88},
{135, 64},
{149, 70},
{139, 58}
},
{
{131, 45},
{150, 53},
{138, 52},
{146, 61},
{151, 70},
{140, 57},
{137, 48}
},
{
{157, 73},
{156, 70},
{135, 50},
{137, 52},
{133, 50},
{133, 50},
{168, 73}
},
{
{131, 52},
{147, 61},
{131, 51},
{128, 43},
{125, 41},
{104, 24},
{137, 60}
}
};
const int COLON_INTERVAL[2][2] = {
{127, 45},
{156, 81},
};
const int DIGIT_STARTING_SEGMENT_INDEX[4] = {2, 9, 22, 29};
const int COLON_STARTING_INDEX = 16;
const int SEGMENTS_PER_DIGIT = 7;
const int DIGITS = 4;
const int START_POS = 1;
const int COLON = 2;
int segment = 12;
void setup() {
Servo servos[DIGITS][SEGMENTS_PER_DIGIT];
Servo colonServos[COLON];
for (int i = 0; i < DIGITS; i++) {
for (int j = 0; j < SEGMENTS_PER_DIGIT; j++) {
int offset = DIGIT_STARTING_SEGMENT_INDEX[i];
servos[i][j].attach(j + offset);
servos[i][j].write(SEGMENT_INTERVALS[i][j][START_POS]);
}
delay(1000);
for (int j = 0; j < SEGMENTS_PER_DIGIT; j++) {
servos[i][j].detach();
}
}
for (int i = 0; i < COLON; i++) {
colonServos[i].attach(i + COLON_STARTING_INDEX);
colonServos[i].write(COLON_INTERVAL[i][START_POS]);
}
delay(1000);
for (int i = 0; i < COLON; i++) {
colonServos[i].detach();
}
myservo.attach(segment); // attaches the servo on pin 9 to the servo object
Serial.begin(9600); // open the serial port at 9600 bps:
}
int inputParse(String input) {
// Clean number
int angle = input.toInt();
if (angle > 180 || angle < 0) {
angle = 0;
}
return angle;
}
void loop() {
if (Serial.available()) {
segment = inputParse(Serial.readString());
Serial.print("Attaching: " );
Serial.println(segment);
myservo.detach();
myservo.attach(segment);
}
if (myservo.attached()) {
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180)
myservo.write(val); // sets the servo position according to the scaled value
Serial.print("Seg: " );
Serial.print(segment);
Serial.print(" Pot: " );
Serial.println(val);
delay(15); // waits for the servo to get there
}
}
댓글 0
조회수 890등록된 댓글이 없습니다.