Loading
Hey! This thing is still a Work in Progress. Files, instructions, and other stuff might change!

Plotclock

by joo, published

Plotclock by joo Feb 12, 2014

Featured Thing!

Description

A clock that plots time. Designed with makeability in a fablab/makerspace/hackerspace in mind.

You need:

  • Laser cutter or 3D printer
  • 1 Arduino
  • 3 servos
  • 1 dry wipe pen
  • M3 nuts, bolts, thread tap

Update to V1.01:
added calibration routine and documentation to arduino code

see the instruction tab above for building instructions

http://wiki.fablab-nuernberg.de/w/Ding:Plotclock (german)
http://www.youtube.com/watch?v=iOLFP90DneY
https://github.com/9a/plotclock

Recent Comments

view all

Hello ! I am a teacher in Brazil and I'm learning a lot from you! Only I'm nõ programmer and my schedule is as follows:

include <Time.h>

// Plotclock // cc - by Johannes Heberlein 2014 // v 1.0 // thingiverse.com/joo wiki.fablab-nuernberg.de

// units: mm; microseconds; radians // origin: bottom left of drawing surface (see sketchUp file)

// todo detail m3, info grafik winkel, kalibr

// #define kalibration

define SERVOFAKTOR 650

// comprimento de braços

define L1 35

define L2 55.1

define L3 13.2

// pontos de origem de servo esquerda e direita

define O1X 22

define O1Y -25

define O2X 47

define O2Y -25

// Zero- posição de servo esquerda e direita

define SERVOLEFTNULL 1890

define SERVORIGHTNULL 960

// levantar posições de elevação do servo

define LIFT0 1600// sobre a superfície do desenho

define LIFT1 925// entre os números

define LIFT2 725

// indo em direção a vassoura

// velocidade de braço liftimg , maior é mais lento

define LIFTSPEED 500

// largura servo:

// Servo1 : Escreve : 1080ms ; Elevador de varredura : 724 ; Número Elevador: 924 // Servo2: 0.65-1.98 // Servo3: 1.1-1.8ms

include <Time.h>

include <Servo.h>

include <LiquidCrystal.h>

int servoLift = 1500;

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

int val; // variável para ler o valor do pino analógico

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

int last_min = 0;

// inicializar a biblioteca com os números dos pinos de interface //LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup() { // Definir o tempo atual setTime(19,24,0,0,0,0);

drawTo(75, 44); lift(0); servo1.attach(2); // levantamento servo servo2.attach(3); // servo esquerda servo3.attach(4); // servo direita delay(1000);

}

void loop() {

//servo2.writeMicroseconds(M_PI *SERVOFAKTOR + SERVOLEFTNULL);

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

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(75, 47.5);
lift(1);
last_min = minute();

}

}

// Escrevendo numeral com bx por ser o originpoint canto inferior esquerdo. Escala 1 é igual a 20 mm de altura fonte. // A estrutura segue este princípio : a primeira jogada startpoint do numeral, levantar -se, 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:

//elevador(2);
//drawTo(75, 47.5);
lift(0);
//velocidade = 0;
drawTo(75, 43);
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(77, 44);
drawTo(78, 44);
lift(2);
//velocidade = 3;

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

// OPTIMIEREN  !

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 do novo ponto dx = pX - lastX; dy = pY - lastY; //caminho comprimento em mm , é igual a 4 vezes 4 passos por milímetro c = floor(4 sqrt(dx dx + dy * dy));

if (c < 1) c = 1;

for (i = 0; i <= c; i++) {

// desenhar linha ponto a ponto
set_XY(lastX + (i * dx / c), lastY + (i * dy / c));

}

lastX = pX; lastY = pY; }

double return_angle(double a, double b, double c) { // regra coseno para ângulo entre c e uma 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;

// calcular triângulo entre caneta, servoLeft e braço conjunta // cartesiano 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);

//lcd.setCursor(0, 0); servo2.writeMicroseconds(floor(((a2 + a1 - M_PI) SERVOFAKTOR) + SERVOLEFTNULL)); //lcd.print(floor(((a2 + a1 - M_PI) 750) + SERVOLEFTNULL));

// calcular joinr ponto braço para triângulo do braço direito servo a2 = return_angle(L2, L1, c); Hx = Tx + L3 cos((a1 - a2 + 0.637) + M_PI); //36,5° Hy = Ty + L3 sin((a1 - a2 + 0.637) + 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);

//lcd.setCursor(0, 1); servo3.writeMicroseconds(floor(((a1 - a2) SERVOFAKTOR) + SERVORIGHTNULL)); // lcd.print(floor(((a1 - a2) 750) + SERVORIGHTNULL)); }

My watch is mounted ... I know little miss , but I can not . They could help me ? I thank you ! hugs !! Professor Michelle

have you tried version 1.02 from github? https://raw.githubusercontent.com/9a/plotclock/master/plotclock.ino

// lift positions of lifting servo

define LIFT0 1080 // on drawing surface

define LIFT1 925 // between numbers

define LIFT2 725 // going towards sweeper

These numbers define the positions of the "lift servo", if these are too far off it could be a problem

Hi Joo, I am referring to the movement of the servos without any part of the plot clock setup attached to the servos. Do you think it will help, if I could sent a photo of my wired setup to you?

I have tried basic trouble shooting like changing the servo, the cables, and even signal output slot on the Uno.. Can't figure out the issue.

More from DIY

view more

Liked By

view all

Tags

License

Plotclock by joo is licensed under the Creative Commons - Attribution license.

Give a Shout Out

If you print this Thing and display it in public proudly give attribution by printing and displaying this tag. Print Thing Tag

Instructions

Materials I used:

  • Arduino uno
  • Tower Pro 9g servos (those cheap ones from ebay)
  • WB SL DRYWIPE MARKER, bullet tip
  • A small custom servo adapter, there are shields or servo-arduinos that also can be used. You can also just use jumper wires: 5V to red servo wire, GND to brown or black servo wire and the arduino servopins connected to the yellow or orange servo wire

Building instructions:
(for version 1.01!)

  1. Lasercut plotclock_beta1.pdf from 3mm material or 3D print plotclock_SUP7.skp

    • the black areas in the pdf on the servo arms should be used to engrave some material away, so the servohorns settle in
    • use http://www.thingiverse.com/thing:250204 for single STL files if you 3D print the clock (Thanks corben33!)
  2. 3D print swee.stl or reuse some other cylindrical part for the sweeper

  3. Tap 2.5mm holes with M3 thread

  4. Assemble arms with M3 screws, gently adjust the counternuts so that the joints under the screw heads just have enough play for smooth movement (see joint picture).

  5. load Arduino sketch plotclock_V1, see code comments for further information

  6. Add some sort of cloth with double sided tape to sweeper

  7. Attach servos to digital pin 2, 3 and 4, according to arduino sketch, test them without anything attached by plugging in the arduino (the photos show it being connected to 1, 2 and 3, which isn't optimal since 1 is also the TX pin, so during arduino startup the lifting servo jumps around)

  8. Put everything together

    • You may have to redrill the holes that are used for securing the servos, since some servo screws are a tight fit.
      Acrylic is brittle and easily breaks wen the mounting holes are to small. Only push the servo arms onto their hubs, don't secure them with screws! For initial calibration do not mount the resting clip for the wiper (danger of collision with the pen). Glue or screw the servo arms to the acrylic parts.
  9. When attaching the servo arms, make sure they can turn enough to reach every point on the drawing surface by manually turning them

  10. Power the arduino, it should start a calibration cycle where every second the position of both servos changes by rotating exactly 90 degrees (see last image in gallery)

  11. Change the SERVOFAKTOR, SERVOLEFTNULL and SERVORIGHTNULL values until everything matches up (see code for more information)

  12. Attach the pen and the sweeper holder only after testing everything else

This description is still a bit of a WIP, so comment if you have any questions!

Hello ! I am a teacher in Brazil and I'm learning a lot from you! Only I'm nõ programmer and my schedule is as follows:

include <Time.h>

// Plotclock // cc - by Johannes Heberlein 2014 // v 1.0 // thingiverse.com/joo wiki.fablab-nuernberg.de

// units: mm; microseconds; radians // origin: bottom left of drawing surface (see sketchUp file)

// todo detail m3, info grafik winkel, kalibr

// #define kalibration

define SERVOFAKTOR 650

// comprimento de braços

define L1 35

define L2 55.1

define L3 13.2

// pontos de origem de servo esquerda e direita

define O1X 22

define O1Y -25

define O2X 47

define O2Y -25

// Zero- posição de servo esquerda e direita

define SERVOLEFTNULL 1890

define SERVORIGHTNULL 960

// levantar posições de elevação do servo

define LIFT0 1600// sobre a superfície do desenho

define LIFT1 925// entre os números

define LIFT2 725

// indo em direção a vassoura

// velocidade de braço liftimg , maior é mais lento

define LIFTSPEED 500

// largura servo:

// Servo1 : Escreve : 1080ms ; Elevador de varredura : 724 ; Número Elevador: 924 // Servo2: 0.65-1.98 // Servo3: 1.1-1.8ms

include <Time.h>

include <Servo.h>

include <LiquidCrystal.h>

int servoLift = 1500;

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

int val; // variável para ler o valor do pino analógico

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

int last_min = 0;

// inicializar a biblioteca com os números dos pinos de interface //LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup() { // Definir o tempo atual setTime(19,24,0,0,0,0);

drawTo(75, 44); lift(0); servo1.attach(2); // levantamento servo servo2.attach(3); // servo esquerda servo3.attach(4); // servo direita delay(1000);

}

void loop() {

//servo2.writeMicroseconds(M_PI *SERVOFAKTOR + SERVOLEFTNULL);

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

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(75, 47.5);
lift(1);
last_min = minute();

}

}

// Escrevendo numeral com bx por ser o originpoint canto inferior esquerdo. Escala 1 é igual a 20 mm de altura fonte. // A estrutura segue este princípio : a primeira jogada startpoint do numeral, levantar -se, 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:

//elevador(2);
//drawTo(75, 47.5);
lift(0);
//velocidade = 0;
drawTo(75, 43);
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(77, 44);
drawTo(78, 44);
lift(2);
//velocidade = 3;

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

// OPTIMIEREN  !

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 do novo ponto dx = pX - lastX; dy = pY - lastY; //caminho comprimento em mm , é igual a 4 vezes 4 passos por milímetro c = floor(4 sqrt(dx dx + dy * dy));

if (c < 1) c = 1;

for (i = 0; i <= c; i++) {

// desenhar linha ponto a ponto
set_XY(lastX + (i * dx / c), lastY + (i * dy / c));

}

lastX = pX; lastY = pY; }

double return_angle(double a, double b, double c) { // regra coseno para ângulo entre c e uma 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;

// calcular triângulo entre caneta, servoLeft e braço conjunta // cartesiano 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);

//lcd.setCursor(0, 0); servo2.writeMicroseconds(floor(((a2 + a1 - M_PI) SERVOFAKTOR) + SERVOLEFTNULL)); //lcd.print(floor(((a2 + a1 - M_PI) 750) + SERVOLEFTNULL));

// calcular joinr ponto braço para triângulo do braço direito servo a2 = return_angle(L2, L1, c); Hx = Tx + L3 cos((a1 - a2 + 0.637) + M_PI); //36,5° Hy = Ty + L3 sin((a1 - a2 + 0.637) + 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);

//lcd.setCursor(0, 1); servo3.writeMicroseconds(floor(((a1 - a2) SERVOFAKTOR) + SERVORIGHTNULL)); // lcd.print(floor(((a1 - a2) 750) + SERVORIGHTNULL)); }

My watch is mounted ... I know little miss , but I can not . They could help me ? I thank you ! hugs !! Professor Michelle

Hi Joo, I am referring to the movement of the servos without any part of the plot clock setup attached to the servos. Do you think it will help, if I could sent a photo of my wired setup to you?

I have tried basic trouble shooting like changing the servo, the cables, and even signal output slot on the Uno.. Can't figure out the issue.

Jun 11, 2015 - Modified Jun 11, 2015
joo - in reply to chlee1911

have you tried version 1.02 from github? https://raw.githubusercontent.com/9a/plotclock/master/plotclock.ino

// lift positions of lifting servo

define LIFT0 1080 // on drawing surface

define LIFT1 925 // between numbers

define LIFT2 725 // going towards sweeper

These numbers define the positions of the "lift servo", if these are too far off it could be a problem

After much work, I have setup the plot clock, except for 1 (one) major issue. The lift servo vibrates, but does not move! I am going to list out what I am using, hoping that joo or someone can enlighten me what might be wrong; which I believe has to do with the compiler or plotclock codes.

  • Windows 8.1 laptop
  • Arduino compiler version 1.0.5
  • 1x Uno with USB to computer as power source
  • ran plotclock_V1.01
  • tried system with 3.3V and also tried with 5V

Troubleshooting steps taken are below:

  • replace all cables connected the lift servo
  • tested the lift servo with signals from left and right servo (ports 3,4) and the lift servo is functioning properly
  • even tried changing the codes to signal ports 5,6 and 7 (instead of 2,3 and 4) However, the lift servo keeps having the same issue -> vibrates showing that it is receiving electricity, but it doesn't move.

Please could someone with experience let me know what is wrong and how to address the issue? Appreciate it.

could it be that there is too much mechanical resistance? It is the servo needing the biggest "force", so if either the joints of the connecting rod or the joint of the "main assembly" is too tight, it will have trouble moving it.

I am receiving the following error message when I try to upload my sketch, can anyone tell me what's wrong? Thanks!

Arduino: 1.6.4 (Mac OS X), Board: "Arduino Uno"

Sketch uses 6,554 bytes (20%) of program storage space. Maximum is 32,256 bytes. Global variables use 107 bytes (5%) of dynamic memory, leaving 1,941 bytes for local variables. Maximum is 2,048 bytes. avrdude: stk500_recv(): programmer is not responding avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00 avrdude: stk500_recv(): programmer is not responding avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00 avrdude: stk500_recv(): programmer is not responding avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00 avrdude: stk500_recv(): programmer is not responding avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00 avrdude: stk500_recv(): programmer is not responding avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00 avrdude: stk500_recv(): programmer is not responding avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00 avrdude: stk500_recv(): programmer is not responding avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00 avrdude: stk500_recv(): programmer is not responding avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00 avrdude: stk500_recv(): programmer is not responding avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00 avrdude: stk500_recv(): programmer is not responding avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00 Problem uploading to board. See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

This report would have more information with "Show verbose output during compilation" enabled in File > Preferences.

This comment has been deleted.

for laser cutting, what are the dimensions that i need to get the appropriate size? (Length/Width) Thanks

I used a 3mm acrylic and an area of 150mmx130mm~ on my laser cut and it works for me

May 13, 2015 - Modified May 13, 2015

This is awesome! Anybody knows why my clock only draw lines? My calibration is ok, it clean always fine grabbing the swee* but then only draw a few lines like trying to make numbers...

i have the same problem...

What do you have plugged into the ICSP port with the ribbon wire? Is it needed?

joo - in reply to MaxR91

It is not needed, it was only used before i ported everything from GCC/WinAVR to Arduino

This comment has been deleted.

Hi there joo, we are some students from a Spanish high school and we were planning to build this plot clock but we'd like to know if there is any way of writing the numbers upside down in order to put the plotclock at the top of the whiteboard, just as this example: https://www.youtube.com/watch?v=4QgeQAiSmM8.

Sorry about my English and thanks!

joo - in reply to Lletfrix

see at that videos description or look down this comment section to the comment by MrOrsh

Hello Dear joo. I have some problem this project. Please Help me. My robots is here: https://youtu.be/QFhg5Uvy-aQ

Thank you

try adding a capacitor to the supply rail, like 47µF or 100µF. Also make sure, every hinge can move freely

absolutely Every hinge can move freely. And I tried capacitor 100uF. But Doesn't matter.

This comment has been deleted.

I improved this great thing and give it a new feature: Drawing Replicator! Check it out here https://www.youtube.com/watch?v=asZtNeiSG_w

Mar 22, 2015 - Modified Mar 22, 2015

Everything is working for me except the BOTTOM MOTOR (servo 2)... I have removed '#define CALIBRATION'... but for some reason its not moving!!! switched the motors and it works, tested m points with an LED ad they're fine. Please help!

Where can you buy the servos adapter or something similar? Thanks

Mar 13, 2015 - Modified Mar 13, 2015

I keep getting this error message, please help:

=============== Arduino: 1.6.1 (Mac OS X), Board: "Arduino Uno"

In file included from DateStrings.cpp:10:0: DateStrings.cpp:18:18: error: variable 'monthStr1' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr1[] PROGMEM = "January";

              ^

DateStrings.cpp:19:18: error: variable 'monthStr2' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr2[] PROGMEM = "February";

              ^

DateStrings.cpp:20:18: error: variable 'monthStr3' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr3[] PROGMEM = "March";

              ^

DateStrings.cpp:21:18: error: variable 'monthStr4' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr4[] PROGMEM = "April";

              ^

DateStrings.cpp:22:18: error: variable 'monthStr5' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr5[] PROGMEM = "May";

              ^

DateStrings.cpp:23:18: error: variable 'monthStr6' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr6[] PROGMEM = "June";

              ^

DateStrings.cpp:24:18: error: variable 'monthStr7' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr7[] PROGMEM = "July";

              ^

DateStrings.cpp:25:18: error: variable 'monthStr8' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr8[] PROGMEM = "August";

              ^

DateStrings.cpp:26:18: error: variable 'monthStr9' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr9[] PROGMEM = "September";

              ^

DateStrings.cpp:27:19: error: variable 'monthStr10' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr10[] PROGMEM = "October";

               ^

DateStrings.cpp:28:19: error: variable 'monthStr11' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr11[] PROGMEM = "November";

               ^

DateStrings.cpp:29:19: error: variable 'monthStr12' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr12[] PROGMEM = "December";

               ^

DateStrings.cpp:31:22: error: variable 'monthNames_P' must be const in order to be put into read-only section by means of 'attribute((progmem))' PGM_P monthNames_P[] PROGMEM =

                  ^

DateStrings.cpp:37:26: error: variable 'monthShortNames_P' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthShortNames_P[] PROGMEM = "ErrJanFebMarAprMayJunJulAugSepOctNovDec";

                      ^

DateStrings.cpp:39:16: error: variable 'dayStr0' must be const in order to be put into read-only section by means of 'attribute((progmem))' char dayStr0[] PROGMEM = "Err";

            ^

DateStrings.cpp:40:16: error: variable 'dayStr1' must be const in order to be put into read-only section by means of 'attribute((progmem))' char dayStr1[] PROGMEM = "Sunday";

            ^

DateStrings.cpp:41:16: error: variable 'dayStr2' must be const in order to be put into read-only section by means of 'attribute((progmem))' char dayStr2[] PROGMEM = "Monday";

            ^

DateStrings.cpp:42:16: error: variable 'dayStr3' must be const in order to be put into read-only section by means of 'attribute((progmem))' char dayStr3[] PROGMEM = "Tuesday";

            ^

DateStrings.cpp:43:16: error: variable 'dayStr4' must be const in order to be put into read-only section by means of 'attribute((progmem))' char dayStr4[] PROGMEM = "Wednesday";

            ^

DateStrings.cpp:44:16: error: variable 'dayStr5' must be const in order to be put into read-only section by means of 'attribute((progmem))' char dayStr5[] PROGMEM = "Thursday";

            ^

DateStrings.cpp:45:16: error: variable 'dayStr6' must be const in order to be put into read-only section by means of 'attribute((progmem))' char dayStr6[] PROGMEM = "Friday";

            ^

DateStrings.cpp:46:16: error: variable 'dayStr7' must be const in order to be put into read-only section by means of 'attribute((progmem))' char dayStr7[] PROGMEM = "Saturday";

            ^

DateStrings.cpp:48:20: error: variable 'dayNames_P' must be const in order to be put into read-only section by means of 'attribute((progmem))' PGM_P dayNames_P[] PROGMEM = { dayStr0,dayStr1,dayStr2,dayStr3,dayStr4,dayStr5,dayStr6,dayStr7};

                ^

DateStrings.cpp:49:24: error: variable 'dayShortNames_P' must be const in order to be put into read-only section by means of 'attribute((progmem))' char dayShortNames_P[] PROGMEM = "ErrSunMonTueWedThrFriSat";

                    ^

Error compiling.

This report would have more information with "Show verbose output during compilation" enabled in File > Preferences.

as far as I know, there seems to be a problem with newer Arduino IDE Versions and the time.h library. Try using 1.0.5 http://arduino.cc/en/Main/OldSoftwareReleases preferably on a windwos machine

Sorry for all the questions. I´m having trouble with the resting position of the sweeper.

When it starts it pushes the sweeper down as it should (that is the "LIFT0"-value). It writes fine and lifts up to LIFT2 (going going towards sweeper). It moves in over the sweeper and decents a bit, however not at all as far as it needs to actually reach the sweeper. And stops about 1 cm above it and waits for one min. Then when the next round starts it pushes itself down into the sweeper and cleans everything away.

How do I make it go down in the sweeper after the program is finished? :-/

Well, found something that solved it a little I think. On row 122 i changed lift(1); to lift(0); and now it goes all the way down to the sweeper.

I do still have a little problem though. It seems that the robot is dropping the sweeper to close to the numbers that it writes. I have been trying to change the L1, L2 and L3 values thinking it maybe have something to do with the length of the arms. However there isn´t documented anywhere what the values indicate. I´m guessing that the L1 is the length of the servo center till the first joint of the arms, but them I´m lost.

Also seems that if I do put in the actuall length of my first arm the robot pushes my right servo to the right as much as physically possible. And all I´m doing is changing the value from 35 to 34mm. Could there be something else that is off?

joo - in reply to MrOrsh

http://wiki.fablab-nuernberg.de/w/Ding:Plotclock#Inverse_Kinematik_.28Mathematik_zur_Armbewegung.29 L1 to 3 described.

when changeing the arm lengths, you may create problems with coordinates that cannot be calculated. You may want to look into serial communication with arduino to easily see variables changing in real time

So very cool.

it’d be interesting to replace the laser cut bits with printed parts too. Lasers are so expensive.

Have everything set up and working now. However I was wondering if there is a way to make the clock write the numbers upsidedown (the thought is to have it up on the wall with the arms hanging downwards). And in it´s current shape that will make the time being written upside down :-) Any ideas?

joo - in reply to MrOrsh

a quick hack to completly rotate all of the movement: add at the start of the set_XY(double Tx, double Ty) function the lines "Tx = ### - Tx;" and "Ty = ### - Ty;" where ### are values you have to try out. Probably about 80 for x and 40 for y.

Havn't tried it for myself but that could work. The cleaning position would also be 'rotateted', so that also must be changed

It seems I get everything working as it is supposed to. However the processes never repeats!

Starts out with sweeping, reaching for the pen, writing and putting the pen back. Then it stops.

Have I missed out on setting something up? I´m going through the code but can´t really seem to find any option to change the intervals of the whole program. On the youtube-videos it looks like it updates automaticly every one-minute. But mine is completely dead. Have to upload the code to Arduino again to make it repeat the process :-(

Nevermind :-) Figured it out. Turns out i didn´t change the pins to which the servos are connected under the void_loop-segment. Now it´s all updating every minute :-)

Feb 20, 2015 - Modified Feb 20, 2015

Could anyone help me? here is a video: https://www.youtube.com/watch?v=ab57ASSUnhI

To pickup the sweeper it doesn't go to the correct position. I've tried 1.01 and 1.02 here are my values:

  • SERVOFAKTORLEFT 900
  • SERVOFAKTORRIGHT 900
  • SERVOLEFTNULL 1850
  • SERVORIGHTNULL 920
Feb 20, 2015 - Modified Feb 20, 2015
joo - in reply to JayMc

possible problems:

servo left and right connected to the wrong pins

too big a servofaktor: a faktor between 500 and 650 is normal

servoXXXXnull too big or too small: The null value describes the initial rotation of the arm on the servo, try moving the servohorn manually to another start position, so it doesn't rotate to the servo endstops

JayMc - in reply to joo

It was the wrong pins! Thought I had checked them, argh!

This is a fantastic project, I would love to send you a tip! Give me your bitcoin address.

First off thanks for sharing such a cool project! I'm still waiting on ebay servos to come in the mail but I started going through your code and was trying to figure out how your formulas work. I've since learned this is called inverse kinematics right? Fascinating field btw especially for more elaborate robotics. Is there any way you could elaborate on the kinematic formula section of the code a bit more? When I build a project I really like to learn all that is going on but so far that part is a black box for me. Also what are the x/y limits for the workspace? I grasp how you're drawing a number 1 with lines and a 5 with an arc and then two lines but I don't know what the xy limits are. I would eventually like to try and modify this to do current weather (pulling data via an ethernet shield) then drawing say a cloud or a sun and then the temperature inside. Sorry for all the questions :)

First off thanks for sharing such a cool project! I'm still waiting on ebay servos to come in the mail but I started going through your code and was trying to figure out how your formulas work. I've since learned this is called inverse kinematics right? Fascinating field btw especially for more elaborate robotics. Is there any way you could elaborate on the kinematic formula section of the code a bit more? When I build a project I really like to learn all that is going on but so far that part is a black box for me. Also what are the x/y limits for the workspace? I grasp how you're drawing a number 1 with lines and a 5 with an arc and then two lines but I don't know what the xy limits are. I would eventually like to try and modify this to do current weather (pulling data via an ethernet shield) then drawing say a cloud or a sun and then the temperature inside. Sorry for all the questions :)

the kinematics aren't that difficult, but you got to get your head around it once :) Best is to read backwards from servo2.writeMicroseconds(floor(((a2 + a1 - M_PI) * SERVOFAKTORLEFT) + SERVOLEFTNULL)); while looking at http://wiki.fablab-nuernberg.de/w/Datei:erklaerung.jpg The return_angle functions only returns the cosine rule http://en.wikipedia.org/wiki/Law_of_cosines solved for angle a1 For the second arm the same procedure repeats but not with the pen as the endpoint, but the joint beneath the pen. For me the easiest way was to draw lots of triangles on paper and figure out how they interact ;)

A different and maybe easier way to see the kinematics could be this (may help you understand the x/y maximums): take a piece of paper, draw 2 circles with the radius 35mm (servoarmlength) 25mm apart (distance between servos). Now cut a circle with the radius 55 (pen-arm) out of paper, the center of the cut out circle represents the pen position. When you overlay the cut out cirlcle with the two drawn ones, you can see the position of the armjoint where the "pen" circle crosses the drawn ones. As long the cut out circle intersects or touches both drawn circles, the x/y posistion would be possible. So the max x/y boundaries aren't a box, but a rather weired round cornerd pillow like structure.

I have a couple of questions:

  1. There is quite a bit of info on attaching the left/right servo arms and calibrating the servos. No problem there. But I can't find any information about how to set up the lift servo ... how to attach the servo arm etc. Is there any advice on that anywhere? It's presumably interactive with the lift settings in the code but there must be some mechanical requirement on servo-arm position.

  2. My marker consistently misses the wiper. It's always to close to the top of the clock (farthest from the left-right servos). I'm not a programmer but have been trying to figure out, in the code, where this position is set. So far without success. Could someone point me to it please?
joo - in reply to dnaman
  1. https://raw.githubusercontent.com/9a/plotclock/master/plotclock.ino where it says "// lift positions of lifting servo" the three digits are the values you need to set for the different pen heights. For the initial height, attach the servohorn only after the servos have run at least one time with the arduino.

  2. play around with the SERVOFAKTOR values, sometimes it's better to use values that are a bit off from the calibration
dnaman - in reply to joo

It was the physical position of the servohorn on the lift-servo that was confusing me (and the resulting position of the linkage). I looked more closely at the video and saw that there is a brief side-view showing the lift servo action. I had my servo-horn 180 deg out of position (with the link attaching below the servo shaft). Once I fixed that, everything started to work much better.

I did manage to break the sweeper-clip while I was experimenting - bit fragile. I've been playing with a magnetic retention idea which looks very promising ..... rare-earth disc magnet glued under the table with a (smaller) disc magnet, or a piece of steel, inset into the bottom of the sweeper. Seems to be working OK and is much more tolerant of crashes.

Dear All,

I appreciate some help here to get started, as a first time Arduino builder here.

Can I get some help with selecting the equipment to get this started. I have already gotten a set of the 3D arms and 3 servos. What about the following:

(1) Uno arduino. Do I need a full starter kit with wires cables and such? Saw a few on eBay for US$50. Any suggestion?

(2) Exactly how many M3 10mm bolt and nut do I need?

(3) What kind of cables or wires do I need for the setup and how many?

(4) What about the power source? Do I need to get separate battery source/ casing?

1: If you are a first time Arduino/Microcontroller user, a starter kit usually isn't that bad an idea :) But it will work with just an Arduino

2: Packs of 100 M3 screws cost less then 3€ here, so i just bought one pack of screws and nuts.

3: If you look at the 4th pic in the description (the arduino) you see that you only need 2 wires if you connect the servos like I did. If you buy a starterkit you usually have a breadboard and a couple of jumper wires that would work as well.

  1. The Arduino runs with USB power (eg phone charger)
Dec 29, 2014 - Modified Dec 29, 2014

This looks like a very well designed project that has been made and remixed by a lot of people. We will be trying this out soon in preparation to build it in a workshop at our maker space. Maybe joo or someone else who has made this can comment on these questions before we start prototyping: 1) It looks like there are 9 screws (not including the servo mounting screws). Are all these M3 screws 10mm or are other screw lengths recommended? (and if there is a more precise part list somewhere, could someone please point me to it? ;) ) 2) I've watched some videos of other people's builds in action and none of them write quite as neatly as the main video here. Is there an obvious reason why the drawing is not as precise for other people's builds? Is this an issue of the code or the build? Or both? Thanks! I'm sure I'll have more questions as we start to build, but any comments about these questions would be great!

I am fighting the arduino sketch. I have the time.h library imported into the Arduino IDE and it can find the file time.h .. but it throws all these erros I am unsure how to resolve:

Arduino: 1.5.8 (Windows 8), Board: "Arduino Uno"

In file included from C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:10:0: C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:18:18: error: variable 'monthStr1' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr1[] PROGMEM = "January";

              ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:19:18: error: variable 'monthStr2' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr2[] PROGMEM = "February";

              ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:20:18: error: variable 'monthStr3' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr3[] PROGMEM = "March";

              ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:21:18: error: variable 'monthStr4' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr4[] PROGMEM = "April";

              ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:22:18: error: variable 'monthStr5' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr5[] PROGMEM = "May";

              ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:23:18: error: variable 'monthStr6' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr6[] PROGMEM = "June";

              ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:24:18: error: variable 'monthStr7' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr7[] PROGMEM = "July";

              ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:25:18: error: variable 'monthStr8' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr8[] PROGMEM = "August";

              ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:26:18: error: variable 'monthStr9' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr9[] PROGMEM = "September";

              ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:27:19: error: variable 'monthStr10' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr10[] PROGMEM = "October";

               ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:28:19: error: variable 'monthStr11' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr11[] PROGMEM = "November";

               ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:29:19: error: variable 'monthStr12' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthStr12[] PROGMEM = "December";

               ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:31:22: error: variable 'monthNames_P' must be const in order to be put into read-only section by means of 'attribute((progmem))' PGM_P monthNames_P[] PROGMEM =

                  ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:37:26: error: variable 'monthShortNames_P' must be const in order to be put into read-only section by means of 'attribute((progmem))' char monthShortNames_P[] PROGMEM = "ErrJanFebMarAprMayJunJulAugSepOctNovDec";

                      ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:39:16: error: variable 'dayStr0' must be const in order to be put into read-only section by means of 'attribute((progmem))' char dayStr0[] PROGMEM = "Err";

            ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:40:16: error: variable 'dayStr1' must be const in order to be put into read-only section by means of 'attribute((progmem))' char dayStr1[] PROGMEM = "Sunday";

            ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:41:16: error: variable 'dayStr2' must be const in order to be put into read-only section by means of 'attribute((progmem))' char dayStr2[] PROGMEM = "Monday";

            ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:42:16: error: variable 'dayStr3' must be const in order to be put into read-only section by means of 'attribute((progmem))' char dayStr3[] PROGMEM = "Tuesday";

            ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:43:16: error: variable 'dayStr4' must be const in order to be put into read-only section by means of 'attribute((progmem))' char dayStr4[] PROGMEM = "Wednesday";

            ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:44:16: error: variable 'dayStr5' must be const in order to be put into read-only section by means of 'attribute((progmem))' char dayStr5[] PROGMEM = "Thursday";

            ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:45:16: error: variable 'dayStr6' must be const in order to be put into read-only section by means of 'attribute((progmem))' char dayStr6[] PROGMEM = "Friday";

            ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:46:16: error: variable 'dayStr7' must be const in order to be put into read-only section by means of 'attribute((progmem))' char dayStr7[] PROGMEM = "Saturday";

            ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:48:20: error: variable 'dayNames_P' must be const in order to be put into read-only section by means of 'attribute((progmem))' PGM_P dayNames_P[] PROGMEM = { dayStr0,dayStr1,dayStr2,dayStr3,dayStr4,dayStr5,dayStr6,dayStr7};

                ^

C:\Users\PawUser\Documents\Arduino\libraries\Time\DateStrings.cpp:49:24: error: variable 'dayShortNames_P' must be const in order to be put into read-only section by means of 'attribute((progmem))' char dayShortNames_P[] PROGMEM = "ErrSunMonTueWedThrFriSat";

                    ^

Error compiling.

This report would have more information with "Show verbose output during compilation" enabled in File > Preferences.

Same issue. Have you managed to solve this?

have you tried compiling with arduino 1.0.6? If you have to use version 1.5.8 you may have to try different time.h libraries since some won't work, sorry I can't help any further since i hadn't had these problems. It may help to compile and run the time examples form the arduino IDE, to see if they run at all.

we try to make product like you at http://www.3dmaker.vn

Hi all, I'm having rather a lot of trouble getting the marker to "land" in the eraser holder. It appears that my servos aren't quite linear or the same, so I split SERVOFAKTOR into a "left" and "right" in order to get both servos to get turn 90 degrees in cal. Still no luck, though; there is some clear distortion in my coordinate system (very obvious during "erase"). Does anyone have any ideas for me to get this working? Thanks to joo for such a cool design, and to the community for support.

Here's image of the distortion. Any thoughts as to what constants to work on would be appreciated. http://imgur.com/Yh7IiNf

Figured it out. I had the arm with the pen gripper attached to the right servo, instead of the left one. Oops. All's well, now...

Sep 20, 2014 - Modified Sep 20, 2014

Hi, In the version 1 of the code, there is part which is commented //length of arms L1= a value, L2= a value, L3= a value Two of my arms are 35mm from centre to centre; the others are 55mm and 45mm. My thinking is that the length of the arms affects the position of the pen; From memory as I don't have the code to hand, 35mm is mentioned in the code but values for the others are diffident as noted above. I also done the calibration so that the servo moves 90 degrees. Could you explain the last diagram in relation to the box or the white board? As I currently have the machine thinking that the pen is on the opposite side and the pen holder is too far down from the top. Maybe update the instructions with the correct lengths of the arms needed? I'm also going to download another set of arms from this version as the arms I have, must be too long for this to work correctly.

I believe the way the code works is that L1 is the length of the arms closer to the servo (center to center), L2 is the length between the center of the far side of the L1 linkage and the pen center, and L3 is half the distance between the servo axes. Your "L2 arms" have different lengths because the pen is 10mm from the end of the pivot point, but the geometry is what's important, and the pen is 55mm away.

what's the distance between the 2 gears of the servos?

="thingiverse-ea9b6cd30546ce1e20bd2f6df7e82e64:disqus" href="http://disqus.com/thingiverse-ea9b6cd30546ce1e20bd2f6df7e82e64/joo please check http://www.thingiverse.com/thing:371248http://www.thingiverse.com/thi.... I added some functionality to your plotclock_v1.02.ino but have no glue about github. It should be still backward compatible, so if your want to integrate them as v1.03 please feel free to do so or let me know what I have to do on github

plot thermometer / clock for 3D printers
by smily77
joo - in reply to smily77

thanks a lot! eeprom/serial calibration integration was on my todo list :) don't know when i find the time to update the code the next time but will definitely integrate your code

Hi Joo, This is great project, my model is working well. Thank you for sharing. I have some questions for you. Can you share information how to make a equation to draw number? I tried to figure out the equation using your code, it is not easy to figure out equation for writing number. And I would like to make it writes an alphabets (A,a,B,b,....) Please help me to figure out how to program to do. If I want to make a bigger version to using same code parameters, can I just scale all parameters up, parts and code parameters ? Please give some advises for me.

joo - in reply to pwoong

void number(...) draws the numbers with drawTo (for lines) and bogen (for arcs) functions: Example for number 1: drawTo(bx + 3 scale, by + 15 scale); // Move pen to point x:3 y:15 (left in the middle) lift(0); // Move pen down to surface

drawTo(bx + 10 * scale, by + 20 * scale); // draw diagonally to x:10 y:20 (on the top right)
drawTo(bx + 10 * scale, by + 0 * scale); // draw straight down to y:0

// bx/by are the originpoints for this particular number on the printing surface, with scale you can make it bigger/smaller Number 3 is just 2 bogen functions for the upper and lower arc.

I have written the code using .netmf and remixed some of the parts, will upload soon

Can anyone tell me what screws they used? Where they completely threaded or partially ?

joo - in reply to asedhai

just normal M3 screws, fully threaded

Hai , Can you draw a smiley with the plotclock , is it possible Who wants to write a source code to do this Kind Regards

Hi, I'm newbie to the 3D and 2D printing, and I would like to start with your design. I'm finding quite a lot of problems in trying to upload the PDF design to services like PONOKO or SHAPEWAYS. They ask for SVG files, not PDF. If I convert it to SVG with INKSCAPE, then the updloading fails because it ask for blue lines for cutting and red for engraving... I'm sure that I can end up finding a way to do it, but I suspect that this is too much workaround for a simple task as uploading a design. Could you please give some direction for doing this in Laser-cutting style? THanks

the PDF is meant to directly work on epilog laser-cutters (most common type in fablabs/hackerspaces), so lines to cut are 0.01mm and areas to engrave are in black without an outline. Using inkscape you sould be able to adapt it for commercial services, but i have no experience in doing so.

bubbo: being inverted means the servos work inverted, so the "3000-" trick should work. You may have to change the SERVOLEFT/RIGHTNULL values quite a bit. Sadly all servos I used havn't had that problem, so I couldn't replicate the problem

bubbo - in reply to joo

Hi Joo,

thanks for your answer. In calibration-mode i adjusted the SERVOLEFT/RIGHTNULL values

so that they are in 90 degrees, like in the picture. Then this happens without the "3000-" trick (sorry, this terminology you get when a complete noob like me tries to build this thing) wiping from bottom to top. Writing is from left to right, but it looks upside down (he puts the dots bottom one first) and the parking position is bottom right. Then with the '3000-' trick: wiping from top left to bottom, writing from right to left, but not upside down. parking position is top left. so now i'm a bit confused

joo - in reply to bubbo

nice :) It are always the little things that make big problems ;)

Looking at the code to try and reverse out the kinematics: is L1 = arm attached to servo, L2 = arm from "elbow" to pen, L3 = ? (distance between servo pins?)

i think L3=from the joint where the arms come together to the center of the pen

awesome can't wait till i make 1

After waiting for 25 days for my servos to arrive from China, finally made one for myself! Thanks a lot joo!

I converted the code to C# for use with the Netduino...It prints, but everything is skewed pretty badly. Trying to figure out how things are supposed to be layed out so I can debug a bit better. Is the below correct?

Drawto(0,0) = top left Drawto(50,0) = top right (by the eraser) Drawto(50,50) = bottom right Drawto(0,50) = bottom left

Also, during calibration, is it supposed to be drawing a diagonal line from top left to bottom right?

I'm stuck with ardinuo and getting it working. I have downloaded everything from github but has anyone done a turorial on it or can help please? The plotclock is made, i'm just stuck on the ardinuo software.

Hi Sam, same problem. Did you find a resolution? The only youtube tutorial is in Russian!!

have you read the instructions tab or the comments in the arduino sketch? where are you stuck?

Hi yes i have downloaded the files from github. I have opened plotclock.ino in ardinuo, then downloaded time, timealarm and DS1307RTC from the links. Put these in a folder together so ardinuo see's them when I open plotclock.ino. Plotclock.h then is looking for wire.h and servo.h. Where or how do I get these from? Am I going in the right direction so far?

wire and servo headerfiles come as standard with the arduino softwrare, you may try the arduino-software examples -> servo sketches to verify your arduino and arduino software is working correctly

Hi, I have tried but i don't understand how to get the arduino working. Is there a tutorial online I can follow which anyone knows about please?

I have added the libraries and when I verify it says 'time_t' does not name a type.

Hi,

No one made lasercut & 3D pieces on a selling kit ?

No laser cut machine and 3D printer here :-(

Peter (EuroZone)

Is there anyway to set it up to be a 12hr clock instead of a 24hr one 'cause I don't like 24hr clocks I know it's in the programing but I don't know how

HI Joo,

I just remix it to hold stylus pen on Note 2 to plots time(http://www.thingiverse.com/thing:268065)http://www.thingiverse.com/thi..., But seems I did not do correctly Initial calibration,

According to your code comments, To CALIBRATION :

1) adjust the "SERVOFAKTOR" until the servos move exactly 90 degrees,

      need move like you last upload image?
      I'm trying to adjust but it move more or less around 5 degrees (I will upload video tonight)
      This will affect the text crooked yet?

2) Zero-position of left and right servo

      What does it mean "Zero-position"?

3) origin points of left and right servo

      I do need to adjust in order to calibrate

Thanks for your help and sorry for my English (thanks google translate)

Plotclock on Note 2
by dTom
joo - in reply to dTom

Nice work with the capacitive touch pen :) yes, it should move to the positions as seen in the last image. The zero-variable sets the initial angle, the servofaktor then defines how much "steps" the servo needs in order to turn 90°, you shouldn't need to change the origin points. In your video it looks like the servoholder is a bit loose, since there is much movement by the servomount, but nut by the pen.

Hello again, I managed to solve the problem! Was bad and also the USB cable adapter 9v, very weird because he used the USB cable to print: S and adapter worked well also! the point is to change cables and everything ok.

Thanks for your help and sorry for my English (thanks google translate)

this would be great with a push button to write the time.. that way the pen should last much longer

I have also thought of this idea however the time will be displayed wrong after the minute is up. Perhaps it could write the time when the button is pushed and then after 60sec it erases the time and waits for the next button push? It would be great if there was a feature that could be commented out in the arduino code that would enable this.

that sounds like a good idea.. or it updates for five minutes? then finishes on an erase and waits for a button push (or wire it up to a motion sensor and it will update the time when someone enters the room??)

Joo,

Once again, thank you for the help. I did do the intial calibration and it did draw the time, however it was upside down. Will this give me the figure eight on the x-axis? Why are the start and finish points slightly different? So your going 269 degrees and finishing at -91 degrees?

number(30, 35, 8, 1);

case 8:

drawTo(bx + 5 * scale, by + 10 * scale);
lift(0);
bogenUZS(bx  * scale, by  * scale, 10 * scale,4.7,-1.6, 1);
bogenGZS(bx + 20 * scale, by  * scale, 10 * scale, -4.7, 2, 1);
lift(0);
break;
joo - in reply to xenonion

i actually don't know the exact reason, but i think it had to do with the circles not closing because of the play in the hinges... it also could be that the functions are a bit off and faulty

Thank You for the help! What are the XY maximums? Are the angles in radians? Firstly, I should mention that the plot clock is actually working backwards, it does not draw as in your videos, but upside down. Secondly, I have been playing with the settings and the servos will travel full deflection off of the board if the values are too extreme.

This is very helpful.

joo - in reply to xenonion

angle is in radians, have you used the v1.01 with calibration routine? also if your servos are inverted there is a discussion down the comments about it, a quick fix seems to be the following:

change all .writeMicroseconds(servoLift) to .writeMicroseconds(3000-servoLift)

and change writeMicroseconds(floor(((a2 + a1 - M_PI) SERVOFAKTOR) + SERVOLEFTNULL)); writeMicroseconds(floor(((a1 - a2) SERVOFAKTOR) + SERVORIGHTNULL)); to writeMicroseconds(3000-floor(((a2 + a1 - M_PI) SERVOFAKTOR) + SERVOLEFTNULL)); writeMicroseconds(3000-floor(((a1 - a2) SERVOFAKTOR) + SERVORIGHTNULL)); to reverse the servos

Hello, How would I modify the code to draw a single figure 8 horizontally? Is this possible?

Thank You!

joo - in reply to xenonion

use bogenUZS(float bx, float by, float radius, int start, int ende, float sqee) to draw clockwise arcs (or circles) bx/by = center, radius = radius, start = starting angle, ende = ending angle, squee = sqish or flatten circle bogenGZS is the counter clockwise version

Amazing robot Joo great work! Had an idea from that robot. If i had time and the resources I would replace the marker with a stylus and and for the surface I would put an galaxy note where it could draw the time. Well it could even be used to automate other apps from the device for example Calculator, Angry Birds etc.

Hi Joo - I've added a pull request on github to merge in a couple of small changes into the code:

  • support for DS1307, DS1337 and DS3231 real time clock chips so plotclock tells the right time
  • ability to calibrate servofaktor separately for left and right servos

For anyone interested:

already have a DS1304 module lying around, gonna test it later that week and then merge it, also will update the lasercut parts for a first revison

cain666 - in reply to joo

arre you able to include instructions on how to wire up the RTC to the plot clock??

Would someone be kind enough to comment this code? I think I understand how it works but I dont get how it knows how to plot each number. Thx

can someone video the start and then the cycle it goes through without editing to show home locations and the sequence it goes through, servo with arms is in the home position, I cannot seen to get the arm orientated correctly. It looks like to me that everything is reversed, writing in air (up) and working from right to left.

Thank you HarlanDMii that is exactly what I needed.

Thank you to HalanDMii, everything works fine See previous comments

Kind Regards

I also tried to copy and paste the code from the git hub, but when it is compiling, it says

"

setTime(19,38,0,0,0,0);

'setTime' wasnot declared in this scope.

sketch_feb24a.ino: In function 'void setup()':

sketch_feb24a:66: error: 'setTime' was not declared in this scope

"

Any ideas? Thanks in advance

Hi, I am having the same problem, I have the time library imported (downloaded - imported the zip file) then I (i dowloaded the files from GIT and opened the sketch) yet when I go to verify it still gives the same error. Any Suggestions? Have I missed a step somewhere? Cheers

Figured it out after some more googling...Problem was when you install the time library automatically it puts time.h file within a folder called time...within the time library: Libraries-Time--Time---Time.h. It needs to be Libraries-Time--time.h instead (aka it has an extra time folder)...if that makes sense.

Ok i figured this one out, i just needed to download the time library :)

I copied and pasted the code from github, and it works, but the left and right motors just sweep back and forth with the lift motor up??

Just ended up with some new servos.. Having the same problem with sweeping back and forth.. Apparently, they are over powering the arduino causing it to reset each time it tries to lift. The mini servos I purchased from radio shack didn't have that problem.

delete the line that says

define CALIBRATION

Then upload the sketch to the arduino again

Hello,

I have a question, i cannot seem to be able to open the .ino or arduino sketches?? does anyone have an answer? i just want to load it into the arduino.

Hello again, I have tested with a 9V charger router - 1A and servos only turn left continuously.

I have tried since revision 3 firmware with the same results, the servos turn right and do not stop, I have to stop it to prevent burning.

The connections seem fine :S

Anyway I recorded a video that you may see.

(it's in HD)

http://www.youtube.com/watch?v=HHfq7AAUwBYhttp://www.youtube.com/watch?v...

I'm sad :( I work them all and my no!

I noticed that the LED's on the arduino are red... Are they red like that without the servos connected?

Also in the vid, your wires are connected to pins 1,2 and 3.. The code default is pins 2,3 and 4

Thanks for responding, and I replied to that before it, that the pins are 2, 3 and 4 ... I set myself to try others.

Finally I tried the examples arduino servo and still have the same problem, but do not connect the yellow wire servo data always move and not stop.

The lights are always red when recording unless the firmware.

I do not understand that can happen, the arduino is new and seems to work well, but only Aque sevor connect the arduino to the current, this does not stop moving ...

I was curious if you ever solved the problem. I wonder if it might still be a power problem. I fixed a slightly different issue on mine by using a 5 volt regulator and an external power supply. http://youtu.be/PLDOygEsHCkhttp://youtu.be/PLDOygEsHCk

No friend, I still have the same problem :(

joo - in reply to Aivan

hm, have you changed the servo pins in your arduino sketch because you use 1 2 and 3 instead of 2 3 and 4? also i would recommend you to use the current version 1.01 of the program

Aivan - in reply to joo

Hello! I've tried all versions and with the pins 2,3 and 4, also tried aconfigurar other pins with the same results.

For safety I returned to comporobar the latest version and pins 2, 3 and 4 but still the same: (

joo - in reply to Aivan

well, everything else looks right, the servos are connected correctly and everything. have you tried the arduino example sketches for servos? they are fairly simple and should definitly work

Aivan - in reply to joo

I did some more tests, the servos do not stop riding because they always have current probe to put the servos without data cable and did not stop.

I do not understand why this can happen, the Arduino is new :S

Aivan - in reply to joo

nope, I'll try ... Thanks!

What were the dimensions of the piece which you laser cut (height and length)?

150 x 180mm

don't know exactly, but its a bit smaller than A5-paper, so on the typical A3 laser cutter you can cut four on the same sheet

Hai

I've read that you have quite a few elko in the supply line puts zodicht possible to the servo connections I use 2x 470?F dietary offs (peak flows)

An excellent work!

I have a small problem, first excuse my English (thanks google translator).

I'm using:

Arduino UNO R3 Servos Hextronik hxt900 9g (http://articulo.mercadolibre.cl/MLC-416197377-micro-servo-motor-sg90-_JM)http://articulo.mercadolibre.c... USB Connection

The problem is that Arduino connects and disconnects the USB.

Arduino working properly, load firmware and running, but when I connect the servos are disconnected and reconnected the USB.

I've checked all connections and everything seems fine, I also tried to configure other data pins getting the same results even desperate've tried 3 different computers.

Any idea? Anyone has this happened? Can the problem be the servos?

I want to see the time on my plotclock: (

I had the same problem.. Use a 6-12 volt adaptor to power the arduino.

joo - in reply to Aivan

i had this problem only when the servos needed too much force to move at all, say having a joint too tight or having a mechanical error where the pen is stuck. So first I would check if every joint and connection runs freely, if there still are problems try adding a big capacitor, or using a smartphone/tablet charger for the 5V supply (PC-USB only handles 500mA). Also try connecting the servohorns one at a time to see when the arduino starts resetting.

Aivan - in reply to joo

Thanks for the replies!

I try to use external power.

I have checked all the servos one to one presenting the same problem, if it is true that every time you connect the servos and arduino increasingly less power move.

Not if I explain or understand me well.

So inspiring I actually built one... but I had the same problems as Sembot. I wanted to ask for some info on the code. What are the max/min values? What do you mean by parallel (I don't think it's possible) with reguard to the arms? What do bigger/smaller numbers do? etc. I've been added comments to the code as I figure things out, but I'm still a ways off before it come close to working. I spent a fair bit of time tweaking the files to work with 5mm acrylic so I can use uv/black lights and wet erase markers. I'll follow up if I get it fix. And I'll follow up sooner if I don't ;)

Hai Acklenx,

May I ask if you've already found a solution to the problem of mirror movement I still have not found what reason can be The type of my servos = Micro Servo 9G ?????

Can anyone help with the calibrate

with kind regards

hai,

The movements of my plot clock are mirrored what can I do Erasing from top left to bottom right Writing from top right to bottom left The elevator servo is up (writing in the air) If he stops the pen stand top left, right servo arm outstretched So everything is reversed (mirrored) What can I do, can someone help me I use pin 8,9 and 10 of the Arduino (got the pins 2,3,4 in the program changed) Pin 8 is the lifting servo Pin 9 is the right servo ( highest ) Pin 10 is the left servo with the double support

Kind regards

Can't believe I made such a simple mistake.. I originally said 2000- That should have been 3000- Sorry

change all .writeMicroseconds(servoLift) to .writeMicroseconds(2000-servoLift)

and change writeMicroseconds(floor(((a2 + a1 - M_PI) SERVOFAKTOR) + SERVOLEFTNULL)); writeMicroseconds(floor(((a1 - a2) SERVOFAKTOR) + SERVORIGHTNULL)); to writeMicroseconds(2000-floor(((a2 + a1 - M_PI) SERVOFAKTOR) + SERVOLEFTNULL)); writeMicroseconds(2000-floor(((a1 - a2) SERVOFAKTOR) + SERVORIGHTNULL)); to reverse the servos

joo - in reply to Sembot

it seems your servos are inverted, you may try setting the servofaktor negative, say -620 instead of 620 and also play with the values of LIFT0 / 1 / 2

Where can I buy one?

This thing is so cool and funny i can´t stop to laugh :-D I love it!

How do I download the .stl files for the plotclock?

I am so exciting to make one today and it works good but still need to calibration.Lots of my friends in shenzhen want me to host a workshop.I would like to talk with you about my ideas.Would you share with me ur contacts?Thanks!

Excellent level of effort in creativity and execution. :)

But the important question is: Does it keep printing and erasing 00:00 when you haven't set the time after a power failure? :-).

Man - this is the coolest thing I have seen on here is a while - what a delightful little thing, :)

Incredible project! Admittedly, I am a complete noob when it comes to arduino, but this inspires me to give it a try. Can you give me further detail on what you listed in your instructions: "A small custom servo adapter, there are shields or servo-arduinos that also can be used". I think I'm pretty clear on all the other parts, but not sure what exactly this is. Thanks!

Something similar to this: http://www.adafruit.com/products/1411http://www.adafruit.com/produc... although you don't need as many channels only one per servo I think.

laird - in reply to nkizz

To elaborate slightly, you can control the servo directly from the Arduino, up to the number of pins on the Arduino (12+, depending on the model), but the Arduino doesn't have enough power to drive very many servos, so you have to wire the control to the Arduino, and the power and ground lines to a power supply. For a few servos you can do this on a small breadboard, or solder everything directly. The board that is linked above does this, and adds a multiplexer, so you can control many more servo's.

For this build, you might be able to power three servos from the Arduino directly, depending on how much current the servos draw. But it'd be safer/cleaner to power the servos separately from the Arduino, so that (for example) you can't have interactions like (for an example I've run into) you move all three servos at once, drawing too much current and resetting the Arduino. :-)

That's super-helpful info. Thanks!

what a great example for object-oriented ontology! it's so darn cute.

Das hätte Karl Valentin noch erleben sollen!

One might be able to "write" on glow in the dark painted surfaces with a blue laser too. No need to clean that. It would take some very good paint with a nice slow half life. The light would have to be blue or possibly green. Red is too low energy to excite glow in the dark paint. UV lasers or focused LED's would be best. :-) The machine could repeat the pattern over and over within each minute to keep the image refreshed. Enough of my rambling. Very cool creation as it is right now. :-)

Which time.h library did you use?

This could easily become a milling machine.

This is a great project, I have all the parts printed in PLA with my Prusa Mentel 3D robot and everything was perfect I am confused how to place before the start of the arms from the servos Is the starting position right above?? Anyway, I am happy with this project

Hey my friend, you are really mad :D THIS THING IS AWSOME! ! ! I have great respect for you! Greets from Bremen

Great fun project. This will be my son's first arduino project on the board I geve him. I will start printing the parts for him :-)

He already proposed to build one additional one... next to it..... writing the date :-) And a third writing names of people having birthday that day :-)

Thomas

Dude! This is so cool!

I converted the whole thing to .stl files and i am printing it now. Now i just need to order the servos and the Arduino. This is a GREAT little project! Thanks for sharing it!

Someone needs to add a head above the servos so it looks like its a little guy drawing the time holding onto the market with two hands

I was thinking the same thing and i am already working on it :)

Nicely done. The world is filled with people who are inclined to tell you what to do, but I just can't help myself in this case. With this setup I'd want to see it running on and on and on... , but the pen will get used up and I presume the eraser part will get saturated. If anyone out there has the time, it would be great to modify this design to draw around in tiny sandbox. You'd never use up the sand and it would still be just as cool. It would then be practical to leave running 24/7 for everyone's enjoyment. That just my 2 cents worth. (or should i have said microBTC ?)

Further ideas: If the sandbox had a vibrator attached, the writings could just fade away. If there were 2 different densities of "sand" they would automatically form layers and if they are different colors, the drawing would be more pronounced. (airsoft bb's?) I do it myself If I wasn't so busy. :-) I may do it anyway, but I challenge anyone to beat me to it. :-)

ohhh, that's a good idea. I'd try it if I didn't already have plans for projects. :) go for it

or you could us a litle brush i replace of the gum for the sand :)

Was just thinking about sand also! Though the original idea is still marvelous :)

Or perhaps draw using water on Zen Board (http://blog.freepeople.com/2013/03/living-zen-board/http://blog.freepeople.com/201... or http://www.buddhaboard.com/)?http://www.buddhaboard.com/)? If you could make a marker from some felt and tubing, you could draw with water "forever". I guess you'd have to refill it over time. So then your Aduino could be relaxed and meditate on the nature of time for you!

I don't think you can do zen meditation vicariously through robotics. :-) (but one could try) When I suggested sand, the thoughts zen sand/gravel raking came to mind for me too.

could i use the raspberry pi?

Thats was a really cool project! I just love it!

I had some extra time so I broke down the SketchUp file and created the STL files. They are located here http://www.thingiverse.com/thing:250204http://www.thingiverse.com/thi... as a remix.

Plot Clock STL Files

Holy COW!!! I've seen amazing 3D printed stuff.. and this has gone to the top of my list! AMAZING.. gonna try an make one

Is there any way you could post all of the parts as STL files? I would really like to make this for my High School programming class. Great work by the way, super cool!

you can export this as an .obj from sketchup http://www.sketchup.com/http://www.sketchup.com/ and most 3D printers like the Replicator can use that file type

I really like this and want to build one. It will go nice beside my useless machine. But I dont have sketchup and cannot afford it- Im a retired guy so I cant get the student version. Can you post the parts files as dfx? I could them cut the parts on my CNC router.

I believe that sketchup make is available for non-commercial use. You can go to this link and download it for "Personal Projects".

http://www.sketchup.com/downloadhttp://www.sketchup.com/downlo...

More shaky but I like it even better, esp the way it wipes the number and counts the seconds (a human-like wrist movement). Would you re-make it specifically for 3D printing? thumbs up!

currently developing one which is elegant 3d printed and works without a pen so that it lasts forever and uses micro steppers to get more accuracy... will show it in a month or so......

Will definitely try to get back to it :)

Good for you. Now someone has done it again.

Klasse. tolles Projekt !!! Alle Daumen hoch vom Hackerspace Bremen. ;-)

I gave a talk today at the NY 3D Print Show and as part of it showed some of the cool things that have been uploaded to Thingiverse recently. The plotclock was the hit of the show. Congrats on a fantastic project.

You bet! But please tell me you gave the author proper credit! http://creativecommons.org/licenses/by/3.0/http://creativecommons.org/lic... ;-)

I screensnapped the thing page, so credit was front and center!

This comment has been deleted.
joo - in reply to bre

Thanks a lot!

That's a clever design! I would like to make a derivative for an analog wall clock.

Very Very Cool ... Thanks for sharing! Went to the top of my list of things to make.

it's the same AVR, so it shouldn't be a problem

THIS IS SO BEAUTIFUL I COULD CRY!!!! I must make one immediately!

first of all: great design! So now i made one myself, but also with mine it's writing backwards and the parking is top left instead of topright. Now in tried the '3000-' trick, but that doesn't seem to solve the problem. Is there maybe something else i can try? Perhaps switch pin 3 and 4? hope you can help me out, because i would love this thing to work.

thanks,

Bubbo

Top