by on Drawing Machines

This machine consists of 2 servos controlling an aluminum arm with a pen attached. It is an attempted improvement on DM#1 by moving the weight back to the shoulder The belt used on this machine was completely unusable because it slipped and then all coordinates were useless. This caused the machine to leave the boundries and destroy itself. DM3 is a rebuild of this arm with a plastic chain and sprocket arrangement.

by on Drawing Machines

This machine consists of 2 servos controlling an aluminum arm with a pen attached.
I origionally developed this hardware using a DS5000 on a simsick.

Code

 /*--------------------------------------------------------------------servo.c
 *  Test program for drawing machines.
 *
 *  This code is targeted at an 89S4051 and compiles with sdcc.
 *
 *  Author: Donald Delmar Davis,
 *  w/ Suggestions from to Bernard Winter and Dan Micheals
 *
 *  Date: 28apr02
 *
 *  Status: alfa VERY alfa.
 *
 *  Notes: This seems to work farely well.
 */

 #include 
 #define NSERVOS 3
 #define SERVO0	P1.7
 #define SERVO1	P1.6
 #define SERVO2	P1.5
 #define KFREQ   11059
 #define STRIM	- 693
 #define ETRIM	+ 81

 unsigned int DegreesX92delay(unsigned int DegreesX9);
 unsigned char CurrentServo;
 unsigned int SpaceDelay;
 unsigned int Servo0Delay;
 unsigned int Servo1Delay;
 unsigned int Servo2Delay;

 /* grid.h is calculated by joe2.c */
 #include "grid.h"

 /*--------------------------------------------------------------------initservos
 *  Initialize servo values and set up timers.
 *
 */

 void initservos(unsigned char s0, unsigned char s1, unsigned char s2 ){

	CurrentServo=0;
	SpaceDelay=65535-((20-(NSERVOS*2))*KFREQ)/12;
	Servo0Delay=DegreesX92delay(s0);
	Servo1Delay=DegreesX92delay(s1);
	Servo2Delay=DegreesX92delay(s2);
        // assembly here is
	// mostly to avoid having to define SERVO pins in both c and asxxx
	// eventually may rewrite routine in assembly.

    _asm
	clr	SERVO0
	clr	SERVO1
	clr	SERVO2
    _endasm;
	// should set flags individually to allow for other timer settings
	TMOD=0x01; //#%00000001
	TCON=0x10; //#%00010000

	TH0=0xFE;
	TL0=0;

	IE=0x82; //#%10000010
 }
 /*--------------------------------------------------------------------servopulse
  * pulse servos sequentially.
  *
  */
 void servopulse(void) interrupt 1 _naked
 {
    _asm
    	clr	TR0
	push	ACC
	push	PSW
	push	B
	clr	SERVO0
	clr	SERVO1
	clr	SERVO2
	mov	A,_CurrentServo
	cjne	A, #NSERVOS, $0001
	mov	A, #255
	mov 	TL0,_SpaceDelay
	mov 	TH0,_SpaceDelay+1
	sjmp	$0007
 $0001:  jnz	$0002
	mov 	TL0,_Servo0Delay
	mov 	TH0,_Servo0Delay+1
	setb	SERVO0
	sjmp	$0007
 $0002:  cjne	A, #1,	$0003
	mov 	TL0,_Servo1Delay
	mov 	TH0,_Servo1Delay+1
	setb	SERVO1
	sjmp	$0007
 $0003:	mov 	TL0,_Servo2Delay
	mov 	TH0,_Servo2Delay+1
	setb    SERVO2
 $0007:	inc	A
	mov	_CurrentServo,A
	pop	B
	pop	PSW
	pop	ACC
	setb	TR0
	reti

     _endasm;
 }

 time1ms()    /* not really a 1 ms delay with XTAL 11.0592MHz */
 {
    int i;
    for (i = 0; i < 8 ; i++)
    ;
 }

 void delay(unsigned int n)      /* do nothing n*1ms */
 {
    int i;
    for (i=0; i< n ; i++)
    time1ms();

 }

 unsigned int DegreesX92delay(unsigned int DegreesX9){
 //delay(10);
 return 0-(690+(DegreesX9));
 }

 void shoulder(unsigned int DegreesX9){
 Servo0Delay=DegreesX92delay(DegreesX9 STRIM);
 }
 void elbow(unsigned int DegreesX9){
 Servo1Delay=DegreesX92delay(DegreesX9 ETRIM);
 }
 void xit (unsigned char x,unsigned char y,unsigned int dly){
 unsigned int s,e;
 unsigned char ds,de;
 s=angles[x][y][0];
 e=angles[x][y][1];

 shoulder(s);elbow(e);delay(dly);

 ds=(char) s - angles[x+1][y][0];
 de=(char) e - angles[x+1][y][1]; 

 ds=ds/3;
 de=de/3;

 shoulder(s+ds);elbow(e+de);delay(dly);
 shoulder(s);elbow(e);delay(dly);
 shoulder(s+ds);elbow(e+de);delay(dly);
 shoulder(s);elbow(e);delay(dly);
 shoulder(s+ds);elbow(e+de);delay(dly);
 shoulder(s);elbow(e);delay(dly);
 shoulder(s+ds);elbow(e+de);delay(dly);
 shoulder(s);elbow(e);delay(dly);
 shoulder(s+ds);elbow(e+de);delay(dly);
 }

 #if 0
 #define GOTO(X,Y)  shoulder(angles[X][Y][0]); elbow(angles[X][Y][1]); delay(dly);
 void xit (unsigned char x,unsigned char y,unsigned int dly){
 unsigned char s,e,n;
 for (e=0;e<5;e++){
 GOTO(x-1,y);
 GOTO(x-1,y+1);
 GOTO(x,y+2);
 GOTO(x+1,y+2);
 GOTO(x+2,y+1);
 GOTO(x+2,y);
 GOTO(x+1,y-1);
 GOTO(x,y-1);
 GOTO(x-1,y);
 }
 }
 #endif

 /*----------------------------------------------------------------------------main()
  *
  */

 main(){

  unsigned char d,e,x,y,n;

  initservos(angles[1][1][0],angles[1][1][1],90);
  d=0;e=0;
  for (n=0; n<50; n++){
     for(x=0;x<15;x++){
	 if (d==0){
	     for(y=1;y<12;y++){
	     xit(x,y,500);
	     }
	     d=1;
         } else {
	     for(y=11;y>0;y--){
	     xit(x,y,500);
	     }
	     d=0;
         }
     }
   e=0;
   }
 }

by on 8051

This is a timer I built using a gutted alarm clock and a 2051. I developed the hardware using a DS5000 based emulater and the 89s8252 based programmer that I built last fall.

Schematic


The emulator

The programmer

Testing with actual chip

The carcas

The finished product buried on the messy bench

code

/*---------------------------------------------------------------------timer.c** This is the code for a soldering iron timer. 
* 
* C 2002 Donald Delmar Davis (delmar@digithink.com).** The hardware is built around the 20 pin atmel 89C2051. 
* (http://www.atmel.com/atmel/products/prod71.htm)* This program was compiled using sdcc (sdcc.sourceforge.com)** P1 is connected to the lower half of a 3.5 digit multiplexed clock display.* P3.0 is connected to the transister driving a relay.* P3.4-3.7 are connected to a BCD switch.* 
* P3.3 is connected to an off switch. (currently unimplimented).** The reset switch causes the machine to read the BCD switch. The timer 
* then counts down from 10 times the switch value plus 5 minutes. 
* 
** Most of the work is done by the timer interupt which not only counts* time but also multiplexes the display. 
*----------------------------------------------------------------------------*/#include #define RELAY P3_0static unsigned int pulses;static unsigned char seconds,ones,tens;code unsigned char tens_b[] = {0x58,0x00,0x38,0x30,0x60,0x70,0x78,0x00,0x78,0x70};code unsigned char tens_a[] = {0xf0,0xb0,0xe0,0xf0,0xb0,0xd0,0xd0,0xf0,0xf0,0xf0};code unsigned char ones_b[] = {0x07,0x06,0x05,0x07,0x06,0x03,0x03,0x07,0x07,0x07};code unsigned char ones_a[] = {0x8b,0x80,0x8e,0x86,0x85,0x87,0x8f,0x80,0x8f,0x87};/*---------------------------------------------------pulse_count * Count "pulses" from timer1 also multiple the display. * timer1 is set up to count 9600 ticks per second. * * * This could probably be optimized to create cleaner assembly. * does the job just fine. 
 */void pulse_count (void) interrupt 3 {pulses++;if (pulses==9600) {  if (++seconds == 60) {        if (ones==0){          ones=9;          if (tens==0) {            RELAY=0;	    P1=0;           /* could power down here */ 
	    while (1) ;          } else {          tens--;          }        } else {        ones--;        }   seconds=0;   }   pulses=0;}if (pulses&0x0001) {  P1=tens_a[tens]|ones_a[ones];} else {  P1=tens_b[tens]|ones_b[ones];}}main(){TMOD &= 0x0f;        /* clear timer 1 control bits     */TMOD |= 0x20;        /* set timer 1 to mode 2          */ 
TL1 = -3; TH1 = -3;  /* 9600bps with 11.059MHz crystal */TR1 = 1;P1=0x11;ones=0;tens=0;seconds=0;pulses=0 ;P3 = 0xff;RELAY=1;tens=(((~P3&0x80)>>1)|(~P3&0x38))>>3;ones=5;ET1=1;     /* enable timer 1 interupt */EA=1;      /* enable interupts        */ 
while (1){; }}

by on 8051

Bootstrap 89×051 programmer

This is a result of many searches through the web to put together a 4051 programmer. Most of the programmers required a preprogrammed 4051. Many of them used the reference circuit provided by atmel to supply the 0/5/12 programming voltage. This circuit used a 317 and a series of odd resister values which I had to fabricate using several less odd ones. •• I found a c based programmer which served as an algorythm. Unfortunately the source code was written for a commercial compiler. •••

So what the world needs now is another 89X051 programmer ••••This programmer uses an $7 Atmel AT89S8252 or AT89S53 which is programmed in circuit using Vona’s ’89prog’ and a 50cent Paralell Cable adapter. Asside from the Atmel which you can get from jdr microdevices or from digikey you can pretty much get everything else at radio shack. You could also probably use another in circuit programmer. I just figured this one out first. To make the programming more straight forward most of the pins required for programming are connected straight across (P1.0-7,P3.2-5) I may try to make a board which will work both as an adapter/emulator. The programming voltage circuit which uses common resistors values and general purpose transisters is from the burn project. It is written in the publically avaliable Small Device C Compiler.

  • Code
  • schematic

  • (I hate all of those 4051 programmers that require a preprogrammed 4051. They Suck!)
    •• (So does atmels 0/5/12 Programming Voltage circuit with its weird resistor values. It sucks too)
    ••• (which of course sucks).
    •••• (like I need a hole in my head).

by on 8051

The 8051 has come along way since I was a student. Windowed eproms etc, I would go into it but eventually I would sound like one of those old IMSI 8080 owners talking about loading their bootstraps one bit at a time.
I have been working with the ds5000 and the atmel flash based family. A noticable issue with the 8051 is the lack of a decent public domain c compiler. For this reason I have shifted from the AVR with an eye on the motorolas.

4051 programmer This is my first 89s8252 project
Soldering Iron Timer This is the first thing I did with my development environment