Please update your bookmarks..
Go to my new LEGO website
http://mastincrosbie.com/Marks_LEGO_projects
LEGO Tape Reader
For fun I decided to build a LEGO tape drive. There seems to be a lot
of interest in building LEGO analogies to digital computer
hardware. I've seen LEGO plotters, scanners and even keyboards out
there!
This first version is primitive, with a storage capacity of 15 bits
(yes folks, that's bits). I wanted to start with a very basic setup: a
light sensor scans a piece of paper glued to a wheel. The paper has
alternating marks of black and white on it, which the light sensor
distinguishes as "bits" of data on the tape. The wheel is connected to
a rotation sensor so that the bit location on the wheel can be
deduced.
I measured the circumference of my LEGO wheel, and then measured a
strip of paper to fit. I divided the paper into 16 segments, each of
equal length. Each segment corresponds to one "bit" of data. Thus one
pulse from the rotation sensor indicates that one bit of data has
moved past the light sensor.
Each tape starts with a SYNC bit which is twice as wide as a regular bit.
Version 1 of the tape drive simply reads the bits off the tape and
stops when it reaches the SYNC bit. The total count of bits read is
the displayed. Click here to download
the source code.
/*
* bitcounter.c
*
* Rotate a wheel with a paper barcode and read off the light values
*
* Extending on findsync.c, this version searches for a
* synchronization bit on the paper. A sync bit is a black mark which
* extends for SYNC rotation sensor pulses.
*
* Once we find the sync bit, count how many bits are read until we
* hit the SYNC bit again
*
* Mark Crosbie 9/10/00 mark@mastincrosbie.com
*/
#define DEBUG
#define BEEP
#include
#include
#include
#include
#include
#define ROTSENSOR SENSOR_1
#define LIGHTSENSOR SENSOR_3
#define MOTOR MOTOR_A
/* some motor speed settings */
#define CRAWL 10
#define SLOW 50
#define MID_SPEED ((MAX_SPEED - MIN_SPEED) / 2)
/* a handy abs() function */
#define ABS(x) ((x)>=0)?(x):-(x)
/* difference in light sensor reading */
#define THRESHOLD 20
/* function prototypes */
void initall(void);
void findSync(void);
int bitLength(void);
void tapeForwards(int speed);
void tapeBackwards(int speed);
int main(int argc, char *argv[]) {
int length;
initall();
/* turn on the tape */
tapeForwards(SLOW);
/* find the SYNC bit marker on the tape and stop */
findSync();
/* turn the tape on again */
tapeForwards(SLOW);
/* and print how long it is */
length = bitLength();
lcd_int(length);
return 0;
}
void initall(void) {
/* initialize the sensors */
ds_init();
ds_active(&ROTSENSOR);
ds_active(&LIGHTSENSOR);
/* start sensor processing */
ds_rotation_on(&ROTSENSOR);
ds_rotation_set(&ROTSENSOR, 0);
/* let sensor reading stabilize */
msleep(500);
}
void tapeForwards(int speed) {
/* and turn on the motor */
motor_a_dir(fwd);
motor_a_speed(speed);
}
void tapeBackwards(int speed) {
/* and turn on the motor */
motor_a_dir(rev);
motor_a_speed(speed);
}
/*
* Name:
* findSync
*
* Description:
* Rotate the tape until the sync bit is located
*
* Parameters:
* None
*
* Returns:
* None - returns when sensor is at sync bit
*
* Globals affected:
* None
*
* Algorithm:
* The sync bit on the tape is SYNC rotation counter pulses long.
*
*/
void findSync(void) {
int lastlevel = 0;
int level = 0, diff;
/* take the initial reading */
lastlevel = LIGHT_3;
while(1) {
level = LIGHT_3;
diff = ABS(lastlevel - level);
/* darker gives a smaller reading from the light sensor.
* A darker reading indicates the start of a bit.
*/
if( diff > THRESHOLD) {
motor_a_dir(brake);
msleep(300);
motor_a_dir(off);
#ifdef BEEP
dsound_system(DSOUND_BEEP);
#endif
return;
}
lastlevel = level;
/* for some reason, this msleep is needed to stabilize the reading
* from the light sensor
*/
msleep(1);
}
}
/*
* Name:
* bitLength
*
* Description:
* Returns the length of the current bit in rotation sensor pulses
*
* Parameters:
* None
*
* Returns:
* length
*
* Globals affected:
* None
*
* Algorithm:
* Run the tape until we get a threshold transition and then return
* the rotation sensor count
*
*/
int bitLength(void) {
int lastlevel = 0;
int level = 0, diff;
/* take the initial reading */
lastlevel = LIGHT_3;
/* reset the rotation sensor */
ds_rotation_set(&ROTSENSOR, 0);
while(1) {
level = LIGHT_3;
diff = ABS(lastlevel - level);
/* darker gives a smaller reading from the light sensor.
* A darker reading indicates the start of a bit.
* Count how long this bit is
*/
if( diff > THRESHOLD) {
motor_a_dir(brake);
msleep(300);
motor_a_dir(off);
return ABS(ROTATION_1);
}
lastlevel = level;
/* for some reason, this msleep is needed to stabilize the reading
* from the light sensor
*/
msleep(1);
}
}
|