by on Drawing Machines

I finally said to heck with it and abandoned my previous stepper based system. This is an avr based design with one avr providing the step function as an 12c device.

by on Drawing Machines

This is a sort of meditation inspired by the etchasketch.

Date: Fri, 21 Feb 2003 16:17:06 -0800 (PST)
From: D. Delmar Davis <feurig@fromhell.com>
To: D*** S********* <girlfriend@fromhell.com>
Subject: Re: click click

On Fri, 21 Feb 2003, D*** S******** wrote:

> so what's inside an etchasketch?
> i've always wanted to know!
>

Aluminum powder and plastic pellets the size off a pin in diameter (~1mm). which ohio art swears is non toxic (I trilled holes and vacumed as much as possible out before making a big hole in the back.

There is also a pully system (which I think I reassembled correctly). I have a diagram of it at.

by on Drawing Machines

This is the second attempt to write the AVR code based on a technique based on the autonomous vehicle project described at http://instruct1.cit.cornell.edu/courses/ee476/FinalProjects/s1999/gurnee/index.htm

Code

/*---------------------------------------------------------------------------------13.c

    $Revision: 1.2 $
    Author:     Donald Delmar Davis
    Date:      08feb03
    Purpose:   port of sketchy to avrgcc.
    Credits:    AVR-GCC test program #4 (Author: Volker Oth) / Autonomous car program.

*/
//#if defined (__ATmega163__)
//#define __AVR_ATmega163__ 1
#define __AVR_ATmega8__ 1
//#endif

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

#define ETRIM -200
#define STRIM -100

#define F_CPU            8000000      /* 8Mhz */
#define PULSESPACE	 0xFFFF - 20000

#define PULSECENTER	 (1900 + PULSESPACE)

#define SDLY(DEG)	(1000+(11*(DEG))+PULSESPACE)
#define EDLY(DEG)	(1000+(10*(DEG))+PULSESPACE)

#ifdef __AVR_AT_Mega8__
/* switch defines for dt107 */
#define	SERVOPORTPINS	 PORTB
#define	SERVOPORTDDR	 DDRB
#define E_SERVO		 PINB1
#define S_SERVO		 PINB2
#else
/* switch defines for sim100 */
#define	SERVOPORTPINS	 PORTB
#define	SERVOPORTDDR	 DDRB
#define E_SERVO		 PINB1
#define S_SERVO		 PINB0
#endif

//#define UART_BAUD_RATE      9600      /* 9600 baud */
//#define UART_BAUD_SELECT (F_CPU/(UART_BAUD_RATE*16l)-1)

typedef unsigned char  u08;
typedef          char  s08;
typedef unsigned short u16;
typedef          short s16;

typedef struct _todolist {
	u16 shoulder;
	u16 elbow;
	u16  duration;
	struct _todolist *next;
} todolist;

/* uart globals */
static volatile u08 *uart_data_ptr;
static volatile u08 uart_counter;

unsigned char led;
static volatile u16 sservo,eservo;
static volatile u16 duration;

static volatile todolist stufftodo[]={

  { SDLY(-50), EDLY(0), 2500, (todolist *) &(stufftodo[4]) }, /* when right front hits back right tire */
  { SDLY(0), EDLY(-50), 2500, (todolist *) &(stufftodo[4]) }, /* when left front hits back left tire   */
  { SDLY(50), EDLY(0), 2500, (todolist *) &(stufftodo[4]) },  /* when right rear hits fwd right tire   */
  { SDLY(0), EDLY(50), 2500, (todolist *) &(stufftodo[4]) },  /* when left rear hits fwd left tire     */

  { SDLY(00),EDLY(45),800, (todolist *) &(stufftodo[5]) },
  { SDLY(10),EDLY(45),100, (todolist *) &(stufftodo[6]) },
  { SDLY(20),EDLY(45),100, (todolist *) &(stufftodo[7]) },
  { SDLY(30),EDLY(45),100, (todolist *) &(stufftodo[8]) },
  { SDLY(40),EDLY(45),100, (todolist *) &(stufftodo[9]) },
  { SDLY(50),EDLY(45),100, (todolist *) &(stufftodo[10]) },
  { SDLY(60),EDLY(45),100, (todolist *) &(stufftodo[11]) },
  { SDLY(70),EDLY(45),100, (todolist *) &(stufftodo[12]) },
  { SDLY(80),EDLY(45),100, (todolist *) &(stufftodo[13]) },
  { SDLY(90),EDLY(45),800, (todolist *) &(stufftodo[14]) },
  { SDLY(90),EDLY(50),100, (todolist *) &(stufftodo[15]) },
  { SDLY(90),EDLY(40),100, (todolist *) &(stufftodo[16]) },
  { SDLY(90),EDLY(45),800, (todolist *) &(stufftodo[17]) },
  { SDLY(80),EDLY(45),100, (todolist *) &(stufftodo[18]) },
  { SDLY(70),EDLY(45),100, (todolist *) &(stufftodo[19]) },
  { SDLY(60),EDLY(45),100, (todolist *) &(stufftodo[20]) },
  { SDLY(50),EDLY(45),100, (todolist *) &(stufftodo[21]) },
  { SDLY(40),EDLY(45),100, (todolist *) &(stufftodo[22]) },
  { SDLY(30),EDLY(45),100, (todolist *) &(stufftodo[23]) },
  { SDLY(20),EDLY(45),100, (todolist *) &(stufftodo[24]) },
  { SDLY(10),EDLY(45),100, (todolist *) &(stufftodo[25]) },
  { SDLY(00),EDLY(45),800, (todolist *) &(stufftodo[26]) },
  { SDLY(00),EDLY(50),100, (todolist *) &(stufftodo[27]) },
  { SDLY(00),EDLY(40),100, (todolist *) &(stufftodo[4]) }

};

#define RFSWITCHTODO  ( (todolist *) &(stufftodo[0]) )
#define LFSWITCHTODO  ( (todolist *) &(stufftodo[1]) )
#define RRSWITCHTODO  ( (todolist *) &(stufftodo[2]) )
#define LRSWITCHTODO  ( (todolist *) &(stufftodo[3]) )

static volatile todolist *thingtodo=&(stufftodo[4]);

/*;**********************Timer 1 overflow**************
 *;brings two servo lines hi, reloads servo position values
 *;
 *;_______|-|____
 *;      /
 *;       |
 *;	overflow here
*/

SIGNAL(SIG_OVERFLOW1)
{
	sbi(SERVOPORTPINS,E_SERVO);
	sbi(SERVOPORTPINS,S_SERVO);
	outw(TCNT1,PULSESPACE);
	outw(OCR1A,eservo);
	outw(OCR1B,sservo);
}

SIGNAL(SIG_OUTPUT_COMPARE1A)
{
	cbi(SERVOPORTPINS,E_SERVO);
}

SIGNAL(SIG_OUTPUT_COMPARE1B)
{
	cbi(SERVOPORTPINS,S_SERVO);
}

SIGNAL(SIG_OVERFLOW2)
{
	outb(TCNT2,0); /*(i dunno if this is necissary )*/

        if ((--duration)<=0) {
   	  thingtodo=thingtodo->next;
        } else {
          return;
        }
	  sservo=thingtodo->shoulder+STRIM;
	  eservo=thingtodo->elbow+ETRIM;
	  duration=thingtodo->duration;

}
void main(void)
{

        outb(TIMSK,(_BV(TOIE2)|_BV(TOIE1)|_BV(OCIE1A)|_BV(OCIE1B))); /* enable TCNT overflow */
        outw(TCNT1,0xFF00); // idea is to start with an interupt (not sure if this wil work).
	outb(TCCR1A,0);
	outb(TCCR1B,2); //  ck/8

        duration=10;
	cbi(ASSR,AS2);
	outb(TCNT2,0x00);
	outb(TCCR2,3); //   ck/1024

	eservo=PULSECENTER+ETRIM;
	sservo=PULSECENTER+STRIM;

    	outb(SERVOPORTDDR,0xff);      /* servoport = output */
    	outb(SERVOPORTPINS,0x00);     /* switch outputs off */

    	sei();                 /* enable interrupts */

}

by on Drawing Machines

This really isnt a new drawing machine. It is a replacement of the simstick in dm1 with a dt107 and an atmel Mega8. This is my first crack at the avr servo driving.

 
/*$Revision: 1.3 $

 timings

 The idea here is that the maximum pulse is about 2ms.
 if we map the timings so that 255=2ms then the usable
 servo pulse is between 

 */

#include <io.h>
#include <interrupt.h>
#include <signal.h>

#define NSERVOS 3

uint_8 servodelay[NSERVOS+1]; /* max of 8 */
uint_8 currentservo=0;
uint_8 servoport=0;
uint_8 servoportmask=0x07;
uint_8 skipbeat=10-(NSERVOS/2);

SIGNAL(SIG_OVERFLOW0)        /* signal handler for tcnt0 overflow interrupt */
{
    if (currentservo==NSERVOS) {
        if (!(--skipbeat)) {
            skipbeat=10-(NSERVOS/2);
            servoport=1;
            currentservo=0;
            outp(servodelay[currentservo],TCNT0);
            outp(servoport,PORTB);
        }
    } else {
	servoport<<1;
	currentservo++;
        outp(servodelay[currentservo],TCNT0);
    }
}

int main(void)
{
    outp(0xff,DDRB);         /* use all pins on PortB for output */
    outp((1<<TOIE0), TIMSK); /* enable TCNT0 overflow */
    outp(0,   TCNT0);        /* reset TCNT0 */
    outp(5,   TCCR0);        /* count with cpu clock/1024 */

    led = 1;                 /* init variable representing the LED state */
    sei();                   /* enable interrupts */
    for (;;) {}              /* loop forever */
}

by on Drawing Machines

Drawing Machines

I have been working as a unix system admin for close to 10 years now

much of it on the net where everything is transient, rushed,
insecure, and obsolete before it is finished.

Since I couldnt make welding pay my bills I came to a few conclusions.

  1. Computers should be fun and intertesting.
  2. When I move a brick sized object somthing should happen.
  3. I have a hardware / software degree. I am supposed to know how to do this stuff.

It was either this or a snipercam.


Drawing Machine number 1
A servo based drawing arm

Drawing Machine number 2
An attempt to improve on #1
Drawing Machine #3 Attempt #3 at improvment
Drawing Machine #4 Attempt #4 at improvment

Drawing Machine number 5
Recreating Marvin Green’s entry into Robothon95 “Art ‘Bot” Competition

Drawing Machine number #6
Experimenting with servo control of vibration based movement
Drawing Machine number #7(a-e) Further experiments in this direction.

Drawing Machine #8(a-c)
Initial forey into pen rovers based on Mindstorms “art-bot”

Drawing Machine number #9
A hacked servo based “pen” computer.
Drawing Machine number #10? First crack at weighted drawing arm
Drawing Machine number #11 Replacing processor in Dm1 with AVR

Drawing Machine number #12
A better stepper motor based rover.

Drawing Machine number #13
Weighted drawing arm
Drawing Machine #14 Etchy Sketchy

See Also:

by on Drawing Machines

Drawing machine #9 is another rover based machine.This machine will eventually be driven by the palm pilot.

 For now It is autonomous and the palm pilot just gets a free ride.

It uses a very popular technique of hacking a servo.

This is my first attempt at modifying servos I have photographed the stepps in this conversion. If I were to modify any part of this project it would be to use a multi turn trim pot in place of the matched resisters.

I had to adjust for this in code.

There are a few interesting points about this type of drawing machine.

Not the least of which is that there is no way to draw a horizontal

 line directly. (insert figure here). Before I installed the switches

on this machine it continuously pushed its way out of the barracades that I supported with rather large rocks. This wheel set might make a good sumo candidate. It also dug a hole through several sheets of paper and proceeded to blead over several more sheets. Up to this point I had been using a sketch books to store the various trees of development. This machine damaged the work of 5 of its contemporaries.

From then on I took the finished work out of the books.

Currently the base is autonomous. Eventually the palm pilot will be the brains of the operation.

ahem *New 10 feb 03*

This is my first shift from sdcc and the 8051 to gcc and the AVR. Thanks to Dontronics and the simstick I just spent a manmonth or so learning the new software environment on my handy SDK500 and then swapped the dt107 with the 89S53 on it for one with the ATmega8.

See Also:

http://home1.gte.net/tdickens/68hc11/trp2/trp2.html

code

/*---------------------------------------------------------------------------------avrwander.c

    $Revision: 1.6 $
    Author:     Donald Delmar Davis
    Date:      08feb03
    Purpose:   Port of Penwander code from sdcc to avrgcc.
    Credits:    AVR-GCC test program #4 (Author: Volker Oth) / Autonomous car program.

*/
//#if defined (__ATmega163__)
//#define __AVR_ATmega163__ 1
#define __AVR_ATmega8__ 1
//#endif

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

//#define LTRIM -340

//#define RTRIM -120

#define LTRIM 750
#define RTRIM 750

#define F_CPU            8000000      /* 8Mhz */
#define PULSESPACE	 0xFFFF - 20000
#define PULSECENTER	 (1900 + PULSESPACE)
#define	SERVOPORTPINS	 PORTC
#define	SERVOPORTDDR	 DDRC
#define L_SERVO		 PINC4
#define R_SERVO		 PINC5
#define RDT(DEG)	(1000+(10*(DEG))+PULSESPACE)
//#define LDT(DEG)	(1000+(10*(180-DEG))+PULSESPACE)
#define LDT(DEG)	(1000+(10*(DEG))+PULSESPACE)

#define	SWITCHPORTPULL   PORTB
#define	SWITCHPORTPINS	 PINB
#define	SWITCHPORTDDR	 DDRB

#ifdef __AVR_AT_Mega8__
/* switch defines for dt107 */

#define RIGHT_FRONT	 PINB5
#define LEFT_FRONT	 PINB4
#define RIGHT_REAR	 PINB3
#define	LEFT_REAR	 PINB2
#else
/* switch defines for sim100 */
#define RIGHT_FRONT	 PINB7
#define LEFT_FRONT	 PINB6
#define RIGHT_REAR	 PINB5
#define	LEFT_REAR	 PINB4
#endif

//#define UART_BAUD_RATE      9600      /* 9600 baud */
//#define UART_BAUD_SELECT (F_CPU/(UART_BAUD_RATE*16l)-1)

typedef unsigned char  u08;
typedef          char  s08;
typedef unsigned short u16;
typedef          short s16;

typedef struct _todolist {
	u16 rwheel;
	u16 lwheel;
	u16  duration;
	struct _todolist *next;
} todolist;

/* uart globals */
static volatile u08 *uart_data_ptr;
static volatile u08 uart_counter;

unsigned char led;
static volatile u16 rservo,lservo;
static volatile u16 duration;

static volatile todolist stufftodo[]={

  { RDT(-50), LDT(0), 2500, (todolist *) &(stufftodo[4]) }, /* when right front hits back right tire */
  { RDT(0), LDT(-50), 2500, (todolist *) &(stufftodo[4]) }, /* when left front hits back left tire   */
  { RDT(50), LDT(0), 2500, (todolist *) &(stufftodo[4]) },  /* when right rear hits fwd right tire   */
  { RDT(0), LDT(50), 2500, (todolist *) &(stufftodo[4]) },  /* when left rear hits fwd left tire     */

  { RDT(50),LDT(0),200, (todolist *) &(stufftodo[5]) },
  { RDT(0),LDT(-50),200, (todolist *) &(stufftodo[6]) },
  { RDT(-50),LDT(0),200, (todolist *) &(stufftodo[7]) },
  { RDT(0),LDT(50),400, (todolist *) &(stufftodo[4]) }

};

#define RFSWITCHTODO  ( (todolist *) &(stufftodo[0]) )
#define LFSWITCHTODO  ( (todolist *) &(stufftodo[1]) )
#define RRSWITCHTODO  ( (todolist *) &(stufftodo[2]) )
#define LRSWITCHTODO  ( (todolist *) &(stufftodo[3]) )

static volatile todolist *thingtodo=&(stufftodo[4]);

/*;**********************Timer 1 overflow**************
 *;brings two servo lines hi, reloads servo position values
 *;
 *;_______|-|____
 *;      /
 *;       |
 *;	overflow here
*/

SIGNAL(SIG_OVERFLOW1)
{
	sbi(SERVOPORTPINS,L_SERVO);
	sbi(SERVOPORTPINS,R_SERVO);
	outw(TCNT1,PULSESPACE);
	outw(OCR1A,rservo);
	outw(OCR1B,lservo);
}

SIGNAL(SIG_OUTPUT_COMPARE1A)
{
	cbi(SERVOPORTPINS,L_SERVO);
}

SIGNAL(SIG_OUTPUT_COMPARE1B)
{
	cbi(SERVOPORTPINS,R_SERVO);
}

SIGNAL(SIG_OVERFLOW2)
{
	outb(TCNT2,0); /*(i dunno if this is necissary )*/

 /*       if (bit_is_clear(SWITCHPORTPINS,RIGHT_FRONT)){
           thingtodo=RFSWITCHTODO;
        } else if (bit_is_clear(SWITCHPORTPINS,LEFT_FRONT)){
           thingtodo=LFSWITCHTODO;
        } else if (bit_is_clear(SWITCHPORTPINS,RIGHT_REAR)){
           thingtodo=RRSWITCHTODO;
        } else if (bit_is_clear(SWITCHPORTPINS,LEFT_REAR)){
           thingtodo=LRSWITCHTODO;
        } else*/  if ((--duration)<=0) {
   	  thingtodo=thingtodo->next;
        } else {
          return;
        }
	  rservo=thingtodo->rwheel+RTRIM;
	  lservo=thingtodo->lwheel+LTRIM;
	  duration=thingtodo->duration;

}
void main(void)
{

        outb(TIMSK,(_BV(TOIE2)|_BV(TOIE1)|_BV(OCIE1A)|_BV(OCIE1B))); /* enable TCNT overflow */
        outw(TCNT1,0xFF00); // idea is to start with an interupt (not sure if this wil work).
	outb(TCCR1A,0);
	outb(TCCR1B,2); //  ck/8

        duration=10;
	cbi(ASSR,AS2);
	outb(TCNT2,0x00);
	outb(TCCR2,3); //   ck/1024

	rservo=PULSECENTER+LTRIM;
	lservo=PULSECENTER+RTRIM;

    	outb(SERVOPORTDDR,0xff);      /* servoport = output */
    	outb(SERVOPORTPINS,0x00);     /* switch outputs off */

    	outb(SWITCHPORTDDR,0x00);      /* switchport = input */
//    	outb(SWITCHPORTPULL,0xff);     /* Turn Pullups ON */

    	sei();                 /* enable interrupts */

}

by on Drawing Machines

These are my initial attempts at working through a rover based drawing machine. They were inspired largly by the Lego Mindstorms (TM) Art-Bot project that my then 6.5 year old son built and programmed with very little assistance from me. After playing with a Robotix based pen rover I decided to try to build a stepper based one from the parts of a printer.

I abandoned this project when SDCC kept modifying the code I was attempting to use. It kept optimizing out loops which would wait for a timer interupt based variable changes. (curse evilyn the code modifying dog). By the time I had a prototype of done and hammered it with code resulting in mostly jitters the piece has mostly fallen appart. Iwill more than likely build a fresh one once I identify the appropriate matched stepper moters and start over using avr-gcc.

(And find a better picture of this thing)

by on Drawing Machines

This is an attemt to recreate an art-bot submitted by Marvin Green to Robothon 95.

The description is of a vibrator motor and a plastic cup.

It actually works qutie well.

by on Sort Me

This is an attemt to control vibration based movement by mounting motor on a servo.

This experiment was not very successfull in realizing controll and destroyed itself in the process.