//=========================================================================== // XP EZIO STEPPER RGB SCANNER // USING TWO VEXTA c4010 STEPPER MOTORS // Analog-To-Digital Connections: // Terminal #1: White wire (Red sensor). // Terminal #2: Yellow wire (Green sensor). // Terminal #3: Blue wire (Blue sensor). //=========================================================================== // You can adjust the sensistivity of the RGB sensors by setting // the trackbars after pressing "Sense." This changes the values // of the Red, Green and Blue raw data multipliers. //=========================================================================== // BORLAND CODE //=========================================================================== #include #pragma hdrstop #include "Unit1.h" #include // You must add this yourself. //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- //=========================================================================== // COM1: VARIABLES //=========================================================================== HANDLE hComm = NULL; COMMTIMEOUTS ctmoNew = {0}, ctmoOld; //=========================================================================== // COM1: EVENT HANDLER - ON FORM CREATE // This opens COM1, the RS-232 Serial Port // It remembers the values that existed before this program opened //=========================================================================== void __fastcall TForm1::FormCreate(TObject *Sender) { DCB dcbCommPort; // OPEN THE COMM PORT. hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); // IF THE PORT CANNOT BE OPENED, BAIL OUT. if(hComm == INVALID_HANDLE_VALUE) Application->Terminate(); // SET THE COMM TIMEOUTS IN OUR EXAMPLE. GetCommTimeouts(hComm,&ctmoOld); ctmoNew.ReadTotalTimeoutConstant = 10; ctmoNew.ReadTotalTimeoutMultiplier = 0; ctmoNew.WriteTotalTimeoutMultiplier = 0; ctmoNew.WriteTotalTimeoutConstant = 0; SetCommTimeouts(hComm, &ctmoNew); // SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS. // THERE ARE OTHER WAYS OF DOING SETTING THESE BUT THIS IS THE EASIEST. dcbCommPort.DCBlength = sizeof(DCB); GetCommState(hComm, &dcbCommPort); BuildCommDCB("57600,N,8,1", &dcbCommPort); SetCommState(hComm, &dcbCommPort); } //=========================================================================== // COM1: EVENT HANDLER - ON FORM CLOSE // This closes COMM1 // It restores the values that existed before this program opened //=========================================================================== void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) { // WAIT FOR THREAD TO TERMINATE, // PURGE THE INTERNAL COMM BUFFER, // RESTORE THE PREVIOUS TIMEOUT SETTINGS, // AND CLOSE THE COMM PORT. Sleep(250); PurgeComm(hComm, PURGE_RXABORT); SetCommTimeouts(hComm, &ctmoOld); CloseHandle(hComm); } //=========================================================================== // VARIABLES //=========================================================================== int phase[2] = {0, 0}; int motor = 0; int direction = 0; int pause = 10; int x, y; int red, green, blue; bool stop = true; bool sense = false; int redX = 10, greenX = 15, blueX = 10; // Color Sensor Multipliers DWORD dwWritten = 0; // Required for WriteFile() char coil; // Data for WriteFile() char sensor; // Data for WriteFile() DWORD dwBytesRead; // Required for ReadFile() int InBuff[100]; // Required for ReadFile() int delay = 300000; // Used for Delay long double square, root; // Used for Delay int lut[140] = { // Look Up Table (Not Used) 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,3,6,9,12,15,19,25,28,31,34,37,40,44,47,50,53,56,63, 66,69,72,75,78,81,84,87,91,94,97,100,104,107,110,114,117,120,123,126, 129,131,134,138,141,144,147,151,154,157,160,164,167,170,174,177,181, 184,187,190, 193,198,203,208,213,218,223,228,233,238,243,248,253,255,255,255,255, 255,255,255 }; //=========================================================================== // FUNCTIONS //=========================================================================== //--------------------------------------------------------------------------- // ........ Coil Excitation Sequence....... // Coil: 0 1 2 3 // Phase 1: RED YELLOW // Phase 2: RED GREEN // Phase 3: GREEN BLACK // Phase 4: BLACK YELLOW // // Horizontal Motor in Digital Out 0-3 // Vertical Motor in Digital Out 4-7 // // Red Photoresistor (White Wire) Analog In 0 // Green Photoresistor (Yellow Wire) Analog In 1 // Blue Photoresistor (Blue Wire) Analog In 2 // (Red Wire) +5 Volts for Sensors // (Black Wire) GND for Sensors //--------------------------------------------------------------------------- // Clockwise = Forward = 1 // Counterclockwise = Reverse = 0 //--------------------------------------------------------------------------- //---------------------------------------------------------------------- MOVE void move (int motor, int direction, int steps) { for (int i = 1; i <= steps; i++) { if (direction == 1) { // forward phase[motor] = ((phase[motor] + 1) % 4); } if (direction == 0) { // reverse phase[motor] = ((phase[motor] + 3) % 4); } // Coil On WriteFile(hComm, "w", 1, &dwWritten, NULL); coil = phase[motor] + (motor * 4); WriteFile(hComm, &coil, 1, &dwWritten, NULL); WriteFile(hComm, "\x1", 1, &dwWritten, NULL); // Coil On (Redundant if direction is not changed) WriteFile(hComm, "w", 1, &dwWritten, NULL); coil = ((phase[motor] + 3) % 4) + (motor * 4); WriteFile(hComm, &coil, 1, &dwWritten, NULL); WriteFile(hComm, "\x1", 1, &dwWritten, NULL); // Coil Off WriteFile(hComm, "w", 1, &dwWritten, NULL); coil = ((phase[motor] + 2) % 4) + (motor * 4); WriteFile(hComm, &coil, 1, &dwWritten, NULL); WriteFile(hComm, "\x0", 1, &dwWritten, NULL); // Coil Off (Redundant if direction is not changed) WriteFile(hComm, "w", 1, &dwWritten, NULL); coil = ((phase[motor] + 1) % 4) + (motor * 4); WriteFile(hComm, &coil, 1, &dwWritten, NULL); WriteFile(hComm, "\x0", 1, &dwWritten, NULL); // Delay According to Track Bar Setting for (int i = 0; i < delay; i++) { root = sqrt (29384756 + i); } } Form1->EditMotor0->Text = phase[0]; Form1->EditMotor1->Text = phase[1]; } //--------------------------------------------------------------------- RESET void reset (void) { for (int motor = 0; motor < 2; motor++) { for (int direction = 0; direction < 2; direction ++) { move(motor, direction, 5); } } } //------------------------------------------------------------------- RELEASE void release (void) { for (int i = 0; i < 10; i++) { // for all outputs WriteFile(hComm, "w", 1, &dwWritten, NULL); coil = i; WriteFile(hComm, &coil, 1, &dwWritten, NULL); WriteFile(hComm, "\x0", 1, &dwWritten, NULL); } } //---------------------------------------------------------------------- SCAN void scan (void) { reset(); // move from center position of a 26 x 26 pixel field to its center for (motor = 0; motor < 2; motor++) { move (motor, 0, 13); } Form1->Canvas->Pen->Width = 0; // for vertical angle (motor 1) for (y = 0; y < 26; y++) { if (stop) goto end; move(1, 1, 1); // for horizontal angle (motor 0) for (int x = 0; x < 26; x++) { move(0, 1, 1); // Read Roscoe #26 Light Red WriteFile(hComm, "A", 1, &dwWritten, NULL); sensor = 0; WriteFile(hComm, &sensor, 1, &dwWritten, NULL); ReadFile(hComm, InBuff, 50, &dwBytesRead, NULL); red = *InBuff * redX; if (red > 255) red = 255; // Read Roscoe #91 Primary Green WriteFile(hComm, "A", 1, &dwWritten, NULL); sensor = 1; WriteFile(hComm, &sensor, 1, &dwWritten, NULL); ReadFile(hComm, InBuff, 50, &dwBytesRead, NULL); green = *InBuff * greenX * 1.5; if (green > 255) green = 255; // Read Roscoe #80 Primary Blue WriteFile(hComm, "A", 1, &dwWritten, NULL); sensor = 2; WriteFile(hComm, &sensor, 1, &dwWritten, NULL); ReadFile(hComm, InBuff, 50, &dwBytesRead, NULL); blue = *InBuff * blueX; if (blue > 255) blue = 255; //data = lut[data]; // Look Up Table // Render Form1->Canvas->Brush->Color = static_cast(RGB(red, green, blue)); Form1->Canvas->Pen->Color = Form1->Canvas->Brush->Color; Form1->Canvas->Rectangle(x*20, 500-y*20, x*20+20, 500-y*20+20); Application->ProcessMessages(); } move(0, 0, 26); } move(1, 0, 26); // move back to lower left corner for (motor = 0; motor < 2; motor++) { // move to center position move (motor, 1, 13); } end: release(); } //------------------------------------------------------------ MONITOR SENSOR void monitorSensor (void) { while (sense) { // Input Red WriteFile(hComm, "A", 1, &dwWritten, NULL); sensor = 0; WriteFile(hComm, &sensor, 1, &dwWritten, NULL); ReadFile(hComm, InBuff, 50, &dwBytesRead, NULL); red = *InBuff * redX; // Input Green WriteFile(hComm, "A", 1, &dwWritten, NULL); sensor = 1; WriteFile(hComm, &sensor, 1, &dwWritten, NULL); ReadFile(hComm, InBuff, 50, &dwBytesRead, NULL); green = *InBuff * greenX * 1.5; // Input Blue WriteFile(hComm, "A", 1, &dwWritten, NULL); sensor = 2; WriteFile(hComm, &sensor, 1, &dwWritten, NULL); ReadFile(hComm, InBuff, 50, &dwBytesRead, NULL); blue = *InBuff * blueX; Form1->EditRed->Text = red; Form1->EditGreen->Text = green; Form1->EditBlue->Text = blue; Form1->ShapeRed->Brush->Color = static_cast(RGB(red, 0, 0)); Form1->ShapeGreen->Brush->Color = static_cast(RGB(0, green, 0)); Form1->ShapeBlue->Brush->Color = static_cast(RGB(0, 0, blue)); Form1->ShapeRGB->Brush->Color = static_cast(RGB(red, green, blue)); Application->ProcessMessages(); } } //=========================================================================== // EVENT HANDLERS //=========================================================================== //----------------------------------------------------------------- UP BUTTON void __fastcall TForm1::ButtonUpClick(TObject *Sender) { move(1, 1, 1); } //--------------------------------------------------------------- LEFT BUTTON void __fastcall TForm1::ButtonLeftClick(TObject *Sender) { move(0, 0, 1); } //--------------------------------------------------------------- RIGHT BUTTON void __fastcall TForm1::ButtonRightClick(TObject *Sender) { move(0, 1, 1); } //--------------------------------------------------------------- DOWN BUTTON void __fastcall TForm1::ButtonDownClick(TObject *Sender) { move (1, 0, 1); } //-------------------------------------------------------------- RESET BUTTON void __fastcall TForm1::ButtonResetClick(TObject *Sender) { reset(); } //------------------------------------------------------------ RELEASE BUTTON void __fastcall TForm1::ButtonReleaseClick(TObject *Sender) { release(); } //-------------------------------------------------------------- SENSE BUTTON void __fastcall TForm1::ButtonSenseClick(TObject *Sender) { sense = !sense; if (sense) { Form1->ShapeRGB->Visible = true; Form1->ShapeRed->Visible = true; Form1->ShapeGreen->Visible = true; Form1->ShapeBlue->Visible = true; Form1->EditRed->Visible = true; Form1->EditGreen->Visible = true; Form1->EditBlue->Visible = true; Form1->TrackBarRedX->Visible = true; Form1->TrackBarGreenX->Visible = true; Form1->TrackBarBlueX->Visible = true; Form1->EditRedX->Visible = true; Form1->EditGreenX->Visible = true; Form1->EditBlueX->Visible = true; monitorSensor(); } else { Form1->ShapeRGB->Visible = false; Form1->ShapeRed->Visible = false; Form1->ShapeGreen->Visible = false; Form1->ShapeBlue->Visible = false; Form1->EditRed->Visible = false; Form1->EditGreen->Visible = false; Form1->EditBlue->Visible = false; Form1->EditRed->Text = ""; Form1->EditGreen->Text = ""; Form1->EditBlue->Text = ""; Form1->TrackBarRedX->Visible = false; Form1->TrackBarGreenX->Visible = false; Form1->TrackBarBlueX->Visible = false; Form1->EditRedX->Visible = false; Form1->EditGreenX->Visible = false; Form1->EditBlueX->Visible = false; } } //------------------------------------------------------------- Red Track Bar void __fastcall TForm1::TrackBarRedXChange(TObject *Sender) { redX = TrackBarRedX->Position; Form1->EditRedX->Text = redX; } //----------------------------------------------------------- Green Track Bar void __fastcall TForm1::TrackBarGreenXChange(TObject *Sender) { greenX = TrackBarGreenX->Position; Form1->EditGreenX->Text = greenX; } //------------------------------------------------------------ Blue Track Bar void __fastcall TForm1::TrackBarBlueXChange(TObject *Sender) { blueX = TrackBarBlueX->Position; Form1->EditBlueX->Text = blueX; } //--------------------------------------------------------------- SCAN BUTTON void __fastcall TForm1::ButtonScanClick(TObject *Sender) { stop = false; scan(); } //--------------------------------------------------------------- STOP BUTTON void __fastcall TForm1::ButtonStopClick(TObject *Sender) { stop = true; } //-------------------------------------------------------------- CLEAR BUTTON void __fastcall TForm1::ButtonClearClick(TObject *Sender) { Refresh(); } //------------------------------------------------------------ DELAY TRACKBAR void __fastcall TForm1::TrackBarDelayChange(TObject *Sender) { delay = TrackBarDelay->Position; } //---------------------------------------------------------- THAT'S ALL FOLKS