Arduino
OKUDUĞUNUZ KONU
Arduino Saati Yazan Robot Kol / PlotClock
19

Arduino Saati Yazan Robot Kol / PlotClock

Yazar : Murat Duran25 Haziran 2015

Arduino saati yazan robot kol projemizde 3 adet servo motor ve 1 adet arduino kullanılmış çalışma mantığı ise basittir.O anki saati kalem yardımıyla mekanizmanın üzerine yazıp silmektir.Projenin tüm kodları ve 3d yazıcı için çıktı dosyaları aşağıdaki linkte mevcuttur.İsterseniz pdf içerisindeki çizimleri yazıcıdan bastırıp plastikten kesebilirsiniz.3d yazıcı ile çıkarma imkanınız varsa bu iş daha kolay olacaktır.

Bu proje ister makine mühendisliği ister elektrik-elektronik mühendisliği isterse bilgisayar mühendisliği olsun bu gruplara yönelik bitirme projesi niteliğinde olabilir.Buradaki mantığı kullanarak daha farklı projeler yapabilirsiniz.Bu sizin hayal gücünüze kalmış.

Projemizin Malzemeleri

1- Servo motor ( 3 adet )
2- Arduino UNO
3- Mekanik parçalar
4- Kalem
5- Jumper Kablo

Projenin Malzemelerini Satın Al

Bu proje için gerekli malzemeleri Proje Hocam garantisi ile tek sepette satın alabilirsiniz.İstenilmesi halinde arduino içerisine kodlar yüklenerek gönderilir.“Satın Almak İçin Yukarıda Butona Basınız”

Projenin bağlantı şeması aşağıdaki gibidir.

Projenin Dosyalarını İndir

Projede gelişmiş bir algoritma kullanılmaktadır.Kodlarda başlangıç saatini yazacağınız bir bölüm mevcut oraya şuan ki saati yazmanız gerekiyor.Daha sonra arduino nun enerjisi kesilinceye kadar dakikada bir defa olacak şekilde saati yazıp silmeye başlayacak.Eğer arduino enerjisi kesilirse saat sıfırlanıyor ve yazdığınız başlangıç saatinde başlıyor.Buna dikkat etmeniz gerekir.Kodlarda saati yazacağınız kısım,

setTime(19,38,0,0,0,0); // Saat : 19:38

Proje dosyasında hem 3D printer , hemde pleksi kesim dosyası mevcut.Böyle bir parçayı 3D printer ile basmak zahmetli olacabilir.Lazer kesimle kestirirseniz daha hızlı ve ucuz olacaktır.

 // Saati Yazan Robot Arduino Kodları
#define CALIBRATION     
#define SERVOFAKTORLEFT 650
#define SERVOFAKTORRIGHT 650

#define SERVOLEFTNULL 2250
#define SERVORIGHTNULL 920

#define SERVOPINLIFT  2
#define SERVOPINLEFT  3
#define SERVOPINRIGHT 4


#define LIFT0 1080 
#define LIFT1 925  
#define LIFT2 725 

#define LIFTSPEED 1500

#define L1 35
#define L2 55.1
#define L3 13.2

#define O1X 22
#define O1Y -25
#define O2X 47
#define O2Y -25

#include <Time.h>
#include <Servo.h>

#ifdef REALTIMECLOCK

  #include <Wire.h>
  #include <DS1307RTC.h> 
#endif

int servoLift = 1500;

Servo servo1;  // 
Servo servo2;  // 
Servo servo3;  // 

volatile double lastX = 75;
volatile double lastY = 47.5;

int last_min = 0;

void setup() 
{ 
#ifdef REALTIMECLOCK
  Serial.begin(9600);

tmElements_t tm;
  if (RTC.read(tm)) 
  {
    setTime(tm.Hour,tm.Minute,tm.Second,tm.Day,tm.Month,tm.Year);
    Serial.println("DS1307 time is set OK.");
  } 
  else 
  {
    if (RTC.chipPresent())
    {
      Serial.println("DS1307 is stopped.  Please run the SetTime example to initialize the time and begin running.");
    } 
    else 
    {
      Serial.println("DS1307 read error!  Please check the circuitry.");
    } 
    // Set current time only the first to values, hh,mm are needed
    setTime(19,38,0,0,0,0);
  }
#else  
  // Set current time only the first to values, hh,mm are needed
  setTime(19,38,0,0,0,0);
#endif

  drawTo(75.2, 47);
  lift(0);
  servo1.attach(SERVOPINLIFT);  //  lifting servo
  servo2.attach(SERVOPINLEFT);  //  left servo
  servo3.attach(SERVOPINRIGHT);  //  right servo
  delay(1000);

} 

void loop() 
{ 

#ifdef CALIBRATION

  // Servohorns will have 90° between movements, parallel to x and y axis
  drawTo(-3, 29.2);
  delay(500);
  drawTo(74.1, 28);
  delay(500);

#else 


  int i = 0;
  if (last_min != minute()) {

    if (!servo1.attached()) servo1.attach(SERVOPINLIFT);
    if (!servo2.attached()) servo2.attach(SERVOPINLEFT);
    if (!servo3.attached()) servo3.attach(SERVOPINRIGHT);

    lift(0);

    hour();
    while ((i+1)*10 <= hour())
    {
      i++;
    }

    number(3, 3, 111, 1);
    number(5, 25, i, 0.9);
    number(19, 25, (hour()-i*10), 0.9);
    number(28, 25, 11, 0.9);

    i=0;
    while ((i+1)*10 <= minute())
    {
      i++;
    }
    number(34, 25, i, 0.9);
    number(48, 25, (minute()-i*10), 0.9);
    lift(2);
    drawTo(74.2, 47.5);
    lift(1);
    last_min = minute();

    servo1.detach();
    servo2.detach();
    servo3.detach();
  }

#endif

} 

// Writing numeral with bx by being the bottom left originpoint. Scale 1 equals a 20 mm high font.
// The structure follows this principle: move to first startpoint of the numeral, lift down, draw numeral, lift up
void number(float bx, float by, int num, float scale) {

  switch (num) {

  case 0:
    drawTo(bx + 12 * scale, by + 6 * scale);
    lift(0);
    bogenGZS(bx + 7 * scale, by + 10 * scale, 10 * scale, -0.8, 6.7, 0.5);
    lift(1);
    break;
  case 1:

    drawTo(bx + 3 * scale, by + 15 * scale);
    lift(0);
    drawTo(bx + 10 * scale, by + 20 * scale);
    drawTo(bx + 10 * scale, by + 0 * scale);
    lift(1);
    break;
  case 2:
    drawTo(bx + 2 * scale, by + 12 * scale);
    lift(0);
    bogenUZS(bx + 8 * scale, by + 14 * scale, 6 * scale, 3, -0.8, 1);
    drawTo(bx + 1 * scale, by + 0 * scale);
    drawTo(bx + 12 * scale, by + 0 * scale);
    lift(1);
    break;
  case 3:
    drawTo(bx + 2 * scale, by + 17 * scale);
    lift(0);
    bogenUZS(bx + 5 * scale, by + 15 * scale, 5 * scale, 3, -2, 1);
    bogenUZS(bx + 5 * scale, by + 5 * scale, 5 * scale, 1.57, -3, 1);
    lift(1);
    break;
  case 4:
    drawTo(bx + 10 * scale, by + 0 * scale);
    lift(0);
    drawTo(bx + 10 * scale, by + 20 * scale);
    drawTo(bx + 2 * scale, by + 6 * scale);
    drawTo(bx + 12 * scale, by + 6 * scale);
    lift(1);
    break;
  case 5:
    drawTo(bx + 2 * scale, by + 5 * scale);
    lift(0);
    bogenGZS(bx + 5 * scale, by + 6 * scale, 6 * scale, -2.5, 2, 1);
    drawTo(bx + 5 * scale, by + 20 * scale);
    drawTo(bx + 12 * scale, by + 20 * scale);
    lift(1);
    break;
  case 6:
    drawTo(bx + 2 * scale, by + 10 * scale);
    lift(0);
    bogenUZS(bx + 7 * scale, by + 6 * scale, 6 * scale, 2, -4.4, 1);
    drawTo(bx + 11 * scale, by + 20 * scale);
    lift(1);
    break;
  case 7:
    drawTo(bx + 2 * scale, by + 20 * scale);
    lift(0);
    drawTo(bx + 12 * scale, by + 20 * scale);
    drawTo(bx + 2 * scale, by + 0);
    lift(1);
    break;
  case 8:
    drawTo(bx + 5 * scale, by + 10 * scale);
    lift(0);
    bogenUZS(bx + 5 * scale, by + 15 * scale, 5 * scale, 4.7, -1.6, 1);
    bogenGZS(bx + 5 * scale, by + 5 * scale, 5 * scale, -4.7, 2, 1);
    lift(1);
    break;

  case 9:
    drawTo(bx + 9 * scale, by + 11 * scale);
    lift(0);
    bogenUZS(bx + 7 * scale, by + 15 * scale, 5 * scale, 4, -0.5, 1);
    drawTo(bx + 5 * scale, by + 0);
    lift(1);
    break;

  case 111:

    lift(0);
    drawTo(70, 46);
    drawTo(65, 43);

    drawTo(65, 49);
    drawTo(5, 49);
    drawTo(5, 45);
    drawTo(65, 45);
    drawTo(65, 40);

    drawTo(5, 40);
    drawTo(5, 35);
    drawTo(65, 35);
    drawTo(65, 30);

    drawTo(5, 30);
    drawTo(5, 25);
    drawTo(65, 25);
    drawTo(65, 20);

    drawTo(5, 20);
    drawTo(60, 44);

    drawTo(75.2, 47);
    lift(2);

    break;

  case 11:
    drawTo(bx + 5 * scale, by + 15 * scale);
    lift(0);
    bogenGZS(bx + 5 * scale, by + 15 * scale, 0.1 * scale, 1, -1, 1);
    lift(1);
    drawTo(bx + 5 * scale, by + 5 * scale);
    lift(0);
    bogenGZS(bx + 5 * scale, by + 5 * scale, 0.1 * scale, 1, -1, 1);
    lift(1);
    break;

  }
}



void lift(char lift) {
  switch (lift) {
    // room to optimize  !

  case 0: //850

      if (servoLift >= LIFT0) {
      while (servoLift >= LIFT0) 
      {
        servoLift--;
        servo1.writeMicroseconds(servoLift);				
        delayMicroseconds(LIFTSPEED);
      }
    } 
    else {
      while (servoLift <= LIFT0) {
        servoLift++;
        servo1.writeMicroseconds(servoLift);
        delayMicroseconds(LIFTSPEED);

      }

    }

    break;

  case 1: //150

    if (servoLift >= LIFT1) {
      while (servoLift >= LIFT1) {
        servoLift--;
        servo1.writeMicroseconds(servoLift);
        delayMicroseconds(LIFTSPEED);

      }
    } 
    else {
      while (servoLift <= LIFT1) {
        servoLift++;
        servo1.writeMicroseconds(servoLift);
        delayMicroseconds(LIFTSPEED);
      }

    }

    break;

  case 2:

    if (servoLift >= LIFT2) {
      while (servoLift >= LIFT2) {
        servoLift--;
        servo1.writeMicroseconds(servoLift);
        delayMicroseconds(LIFTSPEED);
      }
    } 
    else {
      while (servoLift <= LIFT2) {
        servoLift++;
        servo1.writeMicroseconds(servoLift);				
        delayMicroseconds(LIFTSPEED);
      }
    }
    break;
  }
}


void bogenUZS(float bx, float by, float radius, int start, int ende, float sqee) {
  float inkr = -0.05;
  float count = 0;

  do {
    drawTo(sqee * radius * cos(start + count) + bx,
    radius * sin(start + count) + by);
    count += inkr;
  } 
  while ((start + count) > ende);

}

void bogenGZS(float bx, float by, float radius, int start, int ende, float sqee) {
  float inkr = 0.05;
  float count = 0;

  do {
    drawTo(sqee * radius * cos(start + count) + bx,
    radius * sin(start + count) + by);
    count += inkr;
  } 
  while ((start + count) <= ende);
}


void drawTo(double pX, double pY) {
  double dx, dy, c;
  int i;

  // dx dy of new point
  dx = pX - lastX;
  dy = pY - lastY;
  //path lenght in mm, times 4 equals 4 steps per mm
  c = floor(4 * sqrt(dx * dx + dy * dy));

  if (c < 1) c = 1;

  for (i = 0; i <= c; i++) {
    // draw line point by point
    set_XY(lastX + (i * dx / c), lastY + (i * dy / c));

  }

  lastX = pX;
  lastY = pY;
}

double return_angle(double a, double b, double c) {
  // cosine rule for angle between c and a
  return acos((a * a + c * c - b * b) / (2 * a * c));
}

void set_XY(double Tx, double Ty) 
{
  delay(1);
  double dx, dy, c, a1, a2, Hx, Hy;

  // calculate triangle between pen, servoLeft and arm joint
  // cartesian dx/dy
  dx = Tx - O1X;
  dy = Ty - O1Y;

  // polar lemgth (c) and angle (a1)
  c = sqrt(dx * dx + dy * dy); // 
  a1 = atan2(dy, dx); //
  a2 = return_angle(L1, L2, c);

  servo2.writeMicroseconds(floor(((a2 + a1 - M_PI) * SERVOFAKTORLEFT) + SERVOLEFTNULL));

  // calculate joinr arm point for triangle of the right servo arm
  a2 = return_angle(L2, L1, c);
  Hx = Tx + L3 * cos((a1 - a2 + 0.621) + M_PI); //36,5°
  Hy = Ty + L3 * sin((a1 - a2 + 0.621) + M_PI);

  // calculate triangle between pen joint, servoRight and arm joint
  dx = Hx - O2X;
  dy = Hy - O2Y;

  c = sqrt(dx * dx + dy * dy);
  a1 = atan2(dy, dx);
  a2 = return_angle(L1, (L2 - L3), c);

  servo3.writeMicroseconds(floor(((a1 - a2) * SERVOFAKTORRIGHT) + SERVORIGHTNULL));

}

Proje malzemelerini market bölümümüzden temin edebilirsiniz.

 

SİZCE NASIL OLMUŞ?
Beğendim
74%
İlginç
13%
Eh İşte
6%
Anlamadım
3%
Kötü
0%
Berbat
3%
YAZAR HAKKINDA
Murat Duran
Murat Duran
Açık kaynak donanım ve yazılım geliştiricisiyim , mekanik ve robotik sistemler üzerinde çalışmalar yapmaktayım.Ayrıca bir start-up firması olan Proje Hocam 'ın kurucuyum.
19 YORUMLAR
  • Basri Ergüdek
    18 Eylül 2015 at 00:09

    Merhaba ben bunu yapmak istiyorum ama malzemeleri nereden temin edebilirim, bu plastikleri felanda lazım , yardımcı olurmusunuz ?

  • Leyla Koç
    15 Mart 2016 at 11:12

    merhaba bende yapmak istiyorum.ama tecrübesizim.malzemelerini buldum.3d yazıcıdan çıkardım.ardunioya kabloları nasıl bağlayacağım konusunda yardımcı olur musunuz?bağlantı şeması veya fotoğrafınıda ekleyebilirmisiniz.teşekkürler

  • Ayşe Zengin
    14 Nisan 2016 at 18:48

    merhaba bütün gerekli parçaları aldım montajını tamamladım arduino ya kodu yükleyip çalıştırdığımda videodaki gibi olmuyor kalibrasyon ve diğer ayarlar için detaylı bilgi verirseniz çok sevinirim
    teşekkürler

    • 30 Eylül 2016 at 01:10

      Zaten kodlama kalibrasyon modunda, sola dönen motoru solda en sonda durdurup sol kolu bağlamalı, sağa dönen sağ motoruda en sonda durdurup sağ kolu takmalısınız. lütfen resim 5 i inceleyin. iki kol arası 90 derece olacak. işlem tamam sa kodtaki 2. satırdaki #define CALIBRATION önüne “//” koyup kodun saati yazmasını sağlayın bu kadar.

  • Süleyman Çeşme
    19 Nisan 2016 at 20:54

    merhaba bütün gerekli parçaları aldım montajını tamamladım arduino ya kodu yükleyip çalıştırdığımda videodaki gibi olmuyor kalibrasyon ve diğer ayarlar için detaylı bilgi verirseniz çok sevinirim
    teşekkürler

  • Mehmet
    25 Nisan 2016 at 14:25

    Bende yukarıdaki arkadaşların yorumunu paylaşıyorum. Başka kaynaklardan kopyala-yapıştır ile olmuyor. Açıklama bekliyoruz

    merhaba bütün gerekli parçaları aldım montajını tamamladım arduino ya kodu yükleyip çalıştırdığımda videodaki gibi olmuyor kalibrasyon ve diğer ayarlar için detaylı bilgi verirseniz çok sevinirim
    teşekkürler.

  • sefa karabaki
    3 Mayıs 2016 at 13:58

    merhaba arduıno yukluyorum boyle bi hata veriyor C:\Users\sefa\Desktop\arduino-uno-ile-ilginc-saat-projesi\plotclock\plotclock.ino:49:65: fatal error: Time.h: No such file or directory

    #include // see http://playground.arduino.cc/Code/time

    ^

    compilation terminated.

    exit status 1
    Error compiling for board Arduino/Genuino Uno. bunu vermemesı ıcın ne yapmalıyom

  • hakan barutçu
    29 Kasım 2016 at 18:57

    hocam mrb. ben time.h kütüphanesi indiriyorum gene aynı hatayı veriyor elinizdeki kütüphaneleri paylaşabilirmisiniz.

  • Yusuf
    20 Ocak 2017 at 19:30

    Hocam kodu arduino ya yüklerken else deki setTime hata veriyo sebebi ne yardımcı olurmusun?

  • ONUR
    8 Mart 2017 at 00:23

    istediğimiz bir yazıyı yazdıramaz mıyız buna? illa ki saati mi yazabiliyor?

  • Salih
    29 Mart 2017 at 20:33

    Merhaba,paylaşım için tesekkür ederim.Servoların kalibrasyonu konusunda sıkıntı yasıyorum.Sag ve sol servoları 90 derece ayarladım,servo konumları fena degil ama silme işlemini yapıyor sadece,saati yazarken sadece karalıyor.Yardımcı olursanız sevinirim.

  • Hazal Karaaliler
    18 Kasım 2017 at 14:43

    Merhabalar
    Bütün bağlantıları yaptım, kodu yükledim hata da vermiyor fakat z ekseni çalışmıyor sadece x, y ekseninde sağa sola hareket ediyor. Yardımcı olursanız çok sevinirim. Teşekkürler

YORUM YAP