|
|
|
If you exclude the comments, there are less than 100 lines of code. I wonder if General Electric or Allen Bradley or Modicon could do that with their Programmable Logic Controllers! For those unfamiliar with LEGO, the program is written in a reduced instruction set version of 'C' called NQC (Not Quite C). Comments, for clarity, are coloured green and have no effect on the program. The RCX controller and NQC support multi-tasking. All the tasks are being executed simultaneously. /*spooler1.nqc
a program to spool thread */
#define LENGTH SENSOR_1 //rotation
#define START SENSOR_2 //switch
#define TENSION SENSOR_3 //photo-cell
#define WIND OUT_A
#define WORM OUT_B
#define UNWIND OUT_C
//the following constants need a bit of tuning for each individual system
#define THRESHOLD 45 //turns on UNWIND when TENSION below THRESHOLD
#define WORM_JOG1 25 //run time
#define WORM_JOG2 100 //off time
#define TRAVERSE_TIME 800 //time to go from one end of WORM to the other
#define UNWIND_DWELL 4 //time to raise weight above THRESHOLD
int customer_length; //how many revolutions are spooled
int input_count; //how many times you push the button
/*Divide program into tasks as follows:
- task main that ties everything together
- task shuttle to traverse thread back and forth for even wind
- task wormDrive that jogs WORM to make traverse slower
- task readSwitch to increment (count) switch presses for length input
- task spoolToLength watch LENGTH and stop spooling at set length
- task unwind to watch TENSION and switch UNWIND to keep festoon centered
*/
task main()
{
start shuttle;
start readSwitch;
Wait (1000); //allow 10 seconds to 'read' input length
PlaySound (2); //to signal the end of the input period
stop readSwitch;
Wait (100);
start spoolToLength;
start unWind;
until (START == 1);
until (START == 0); //starts winding
SetPower (WIND, 0);
OnRev (WIND);
}
task shuttle()
{
SetPower (WORM, 0);
start wormDrive;
while (true)
{
Wait (TRAVERSE_TIME);
Toggle (WORM);
}
}
task wormDrive()
{
Toggle (WORM);
while (true)
{
On (WORM);
Wait (WORM_JOG1);
Off (WORM);
Wait (WORM_JOG2);
}
}
task readSwitch()
{
SetSensor (START, SENSOR_TOUCH);
input_count = 0;
while (true)
{
until (START == 1);
until (START == 0);
input_count++;
PlayTone (262, 40);
}
}
task spoolToLength()
{
SetSensor (LENGTH, SENSOR_ROTATION);
customer_length = input_count * 1600;// resolution is 1/16 of a revolution
until (LENGTH > customer_length); // so... each press of the switch is 100 revolutions
PlaySound (3); //to signal we have reached customer length
Off (WIND + WORM + UNWIND);
StopAllTasks();
}
task unWind()
{
SetSensor (TENSION, SENSOR_LIGHT);
SetPower (UNWIND, 0);
while (true)
{
if (TENSION < THRESHOLD) {Off (UNWIND);}
else
{
Wait (UNWIND_DWELL);
OnFwd (UNWIND);
}
}
}
|