Hardware 101 - was: ECM Bench Problem
Peter Gargano
peter at ntserver.techedge.com.au
Sun Dec 12 03:18:34 GMT 1999
Dear Dr Plecan (Hardware 101 lecturer at the Uni of GMECM),
Here is my assignment for Hardware 101, where we had to design a
circuit to produce a signal like that from a Hall Effect pickup
using a slotted wheel with 7 unequal slots designed to give a
positive edge at 0, 10, 60, 120, 180, 240, 300, and 360/0 (repeating).
Due to the difficulty of delivering my hardware to you by the
assignment's deadline, I have taken the liberty to ask you to
supply the hardware - in this case a straightened paper-clip plugged
into pin 2 of your PC's parallel port (LPT1) (you may wish to
substitute a DB25P with an insulated wire soldered to pin 2, this
will enhance the life of your LPT port's DB connector).
My "hardware driver" follows - it is "hardwired" to produce an
increasing "RPM" from 600 to 6,000 over approximately a 10 second
period. Simply connect a signal measuring device to the hardware's
"output" - pin 2 mentioned above, and watch the signal!
For the CREDIT part of the question "design a circuit to allow the
RPM to be varied", I was going to supply a 555 timer circuit connected
to pin 10 of your LPT1, but I realised that you wouldn't receive this
in time either. So, I was going to ask you to supply your own games
joystick (a term I believe overstates the functionality of this device)
and use this to control the RPM. Unfortunately, due to the impending
assignment deadline, I will have to leave this as an exercise for you
to set your next semester's class.
Thank you again, Dr Plecan, for the learning experience you have
given me.
Here is my assignment (I compiled it with Borland C v3.1):
/*
Hall Effect Ignition Sensor Emulator using LPT1.
Uses PC's 8253 (or AT's 8254) timer channel 0 as time reference.
Master Clock: 14.318180 MHz
8253 Clock input: 1.193182 MHz = master clock / 12
8353 Clock period: 0.838095 uSec (p = 1/T of clock input)
PC software clock: 54.925416 mSec (65536 * Clock period)
PC Clock frequency 18.206507 Hz (1/software clock)
In one second we get 1,193,182 clock pulses.
Time for one revolution (360 degrees of rotation) is:
t = RPM / 60 (Secs.)
So the conversion from RPM (R) to counts/degree (Cpd) is
Cpd = 1193182 / 360 x (R/60)
= 198863.7 / R
History:
12dec99 Peter Gargano - create
*/
#include <stdio.h>
#include <string.h>
#include <dos.h>
typedef unsigned char BYTE;
typedef unsigned int WORD;
// the count represents degrees of rotation, the table entries should
// total 72 (360 degrees)
BYTE degreesInterval [14] = {
5, 5, // 0 -> 10
25, 25, // 10 -> 60
30, 30, // 300 -> 120
30, 30, // 120 -> 180
30, 30, // 180 -> 240
30, 30, // 240 -> 300
30, 30, // 300 -> 360/0
};
WORD lptAddr; // LPT port to use
WORD startCount; // global timestamp
WORD lastCount; // used for wrap around testing
//=======================================================================
WORD readCounter0 (void) {
WORD count;
outportb (0x43, 0); // Command to read counter 0
count = inportb(0x40); // Read LSB
count += (inportb(0x40) << 8); // read MSB into MSB position
return count;
}
// delayUntil returns when the elapsed count has been reached
void delayUntil (WORD limit) {
WORD count;
///printf (" - limit count = %04x (%d)\n", limit, limit);
for (;;) {
count = readCounter0 ();
if (limit < lastCount) { // downcount to reach is lower (ie. NOT wrapped around)
if (count < limit // and count IS lower
|| count > lastCount) // OR count has wrapped around already
break;
}
else { // downcount to reach is higher (ie. wrap around)
if (count < limit // limit was reached
&& count > lastCount) // AND check that we have wrapped too!
break;
}
}
lastCount = limit; // new timestamp
}
void main (void)
{
int index;
int RPM;
WORD cnt;
int i;
WORD tot;
lptAddr = 0x378; // use LPT1
lastCount = startCount = readCounter0 ();
RPM = 600;
for (i=0; i < 1000; i++) {
RPM = 600 + (6*i); //debug
tot = 0;
for (index=0; index < 14; index++) {
outportb (lptAddr, index); // bit 0 (pin 2) will toggle as index++
tot += degreesInterval [index]; // running total of degrees this rev
cnt = (float) tot * (198863.7 / (float) RPM); // count represented by tot
///printf ("RPM=%d, index=%02d [=%d], cnt=%d. ", RPM, index, degreesInterval [index], cnt);
delayUntil (startCount - cnt);
}
startCount -= cnt;
}
void main (void)
{
int index; //index into degrees table
int RPM;
WORD cnt;
int i;
WORD tot;
lastCount = startCount = readCounter0 ();
lptAddr = 0x378; // use LPT1 for output
RPM = 600;
for (i=0; i < 1000; i++) {
RPM = 600 + (6*i); ///debug
tot = 0;
for (index=0; index < 14; index++) {
outportb (lptAddr, index); // bit 0 (pin 2) will toggle as index++
tot += degreesInterval [index]; // running total of degrees this rev
cnt = (float) tot * (198863.7 / (float) RPM); // count represented by tot
///printf ("RPM=%d, index=%02d [=%d], cnt=%d. ", RPM, index, degreesInterval [index], cnt);
delayUntil (startCount - cnt);
}
startCount -= cnt;
}
}
More information about the Gmecm
mailing list