shihaipeng04 发表于 2014-5-28 17:22:19

plotclock 小贱钟的套件基本完毕

本帖最后由 shihaipeng04 于 2014-6-20 11:26 编辑

最新出锅链接淘宝网 http://item.taobao.com/item.htm?id=39370904218


目前套件基本准备完毕了。还有几个小障碍。

1.自己做的一套,始终没有能写出个完整的时间来。可能是因为安装的问题,写出来的字总是歪歪扭扭的。

2.整体结构不是很稳定,因为支撑的部分是T型,当摆臂剧烈摇晃的时候,可能会倒掉。也许是我的笔太重了。

3.虽然做了一个很不错的舵机连接的摆臂,但是发现不同的舵机,主轴直径还不一样。目前已经见到2种舵机了。

4.架子用亚克力胶粘接会更好。但是,这种胶又不太好运输。也许用502可以替代。还没有试验。

5.笔擦找朋友做3d打印去了,还没有出锅。



#define CALIBRATION      



#define SERVOFAKTORLEFT 650
#define SERVOFAKTORRIGHT 650


#define SERVOLEFTNULL 2250
#define SERVORIGHTNULL 920

#define SERVOPINLIFT2
#define SERVOPINLEFT3
#define SERVOPINRIGHT 4


#define LIFT0 1080 // on drawing surface
#define LIFT1 925// between numbers
#define LIFT2 725// going towards sweeper


#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>
#include <Wire.h>
#include <DS3231.h>


int servoLift = 1500;

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

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

int last_min = 0;

void setup()
{

Serial.begin(9600);
Wire.begin();

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()
{




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();
}



}

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));

}


程序粘贴如上,希望有高人能对代码加以完善。
时钟模块,我用的是DS3231,如果是其他的时钟模块,修改一下.h文件就可以了,读取时间的代码没什么变化。


L1 L2 L3 是按照图纸的尺寸量的。不需要修改。
面板的左下角是坐标0,0,笔擦的位置是 75.2,47 单位是毫米,(因为摆臂的安装位置,可能需要再调节一下)
drawto函数是从当前笔位置,移动到相应的坐标。
程序很简单,调试很麻烦。
基础版本一套20¥,大家一起happy一下,目前在制作高阶版本,预计6.1上市。





Super169 发表于 2014-5-28 23:20:30

老兄真勤力, 遲下我又印個玩下先.你係做呢個 (http://www.thingiverse.com/thing:248009) 版本?

shihaipeng04 发表于 2014-5-29 00:36:13

Super169 发表于 2014-5-28 23:20 static/image/common/back.gif
老兄真勤力, 遲下我又印個玩下先.你係做呢個 (http://www.thingiverse.com/thing:248009) 版本?

呵呵,就是这个版本的。不过我怀疑,他发出的程序,和他拍照的不是一个代码,因为下载的代码,写出的字比照片里的大很多。
主体的结构我也改了一些,悬臂和舵机的链接改的很完美。 呵呵

mxhhaixin 发表于 2014-5-29 11:58:57

让这个钟写数码字,不知效果会不会好点。

沧海笑1122 发表于 2014-5-29 15:28:06

请问套件购买传送门?

shenandyu 发表于 2014-5-29 18:50:30

楼主 素描纸上的图片是用什么软件画的

ChunYong 发表于 2014-5-29 22:06:02

加以那方面的完善呢?

philhoo 发表于 2014-5-30 16:52:03

这个很好玩啊

Tonycxc122 发表于 2014-5-31 16:51:51

求LZ的淘宝网址啊!

Tonycxc122 发表于 2014-5-31 17:01:15

用的什么舵机?

shihaipeng04 发表于 2014-5-31 23:04:33

Tonycxc122 发表于 2014-5-31 17:01 static/image/common/back.gif
用的什么舵机?

就是普通的9克舵机

那一小撮人 发表于 2014-7-25 20:10:09

你好问一下 bogenUZS函数中。start,sqee,ende代表什么啊

shihaipeng04 发表于 2014-7-25 21:41:09

那一小撮人 发表于 2014-7-25 20:10 static/image/common/back.gif
你好问一下 bogenUZS函数中。start,sqee,ende代表什么啊

你研究的还真细致,我粗略看了看,好像是画了一个弧线,那些参数好像是角度和位置什么的。

那一小撮人 发表于 2014-7-26 08:16:33

shihaipeng04 发表于 2014-7-25 21:41 static/image/common/back.gif
你研究的还真细致,我粗略看了看,好像是画了一个弧线,那些参数好像是角度和位置什么的。

我这个明白了,UZS表示顺时针画,GZS、逆时针画

那一小撮人 发表于 2014-7-26 15:06:31

楼主知道怎么可以让字写得好看些嘛
页: [1] 2
查看完整版本: plotclock 小贱钟的套件基本完毕