firmware code added

This commit is contained in:
moonanjum26
2018-08-09 18:32:11 +05:30
parent 9b9b88968d
commit fbbd8647a1

View File

@@ -0,0 +1,479 @@
#include <EEPROM.h>
#define Xdir 13
#define Ydir 12
#define Zdir 11
#define Ybump 32
#define Xbump 36
#define AFbump 28
#define bumpGnd 42
/***************************************************************************************
This is what matters when you change the Step size : change the FoV accordingly
Rest of everything is calculated in terms of steps only
So the GUI needs to take care of step size to um conversion
***************************************************************************************/
// FoV size. This is in steps. Calcuated as FoV (steps) = FoV (um) / stepSize
// The step size as on 27 June is 198 nm / step
long xFoV = 1843, yFoV = 2323;
long XMaxStep=260000L, YMaxStep=130000L, ZMaxStep=30000L;
long limitTOZfocus = 31000L,limitToXZero=-250000,limitToYZero=4000;
// steps to go before stopping
int trayOutNoiseMargin = 50;
long XcurrStep=0L, YcurrStep=0L, ZcurrStep=0L;
long Ax=0L,Ay=0L,Az=0L,Bx=0L,By=0L,Bz=0L,Cx=0L,Cy=0L,Cz=0L;
long nextZstep = 0, XdeltaZperFoV=0, YdeltaZperFoV=0;
int needtocheckXmovement=0,needtocheckYmovement=0,needtocheckZmovement=0;
void setup() {
Serial.begin(57600);
// pulse : X,Y,Z :: TX 1,2,3
Serial1.begin(38400); Serial2.begin(38400); Serial3.begin(38400);
pinMode(Zdir,OUTPUT); pinMode(Ydir,OUTPUT); pinMode(Xdir,OUTPUT);
pinMode(Xbump,INPUT); pinMode(Ybump,INPUT); pinMode(AFbump,INPUT); // The bump switchs
pinMode(bumpGnd,OUTPUT); digitalWrite(bumpGnd,LOW); // this sets the gnd for the bump switches
}
void loop() {
int choice = Serial.read();
switch(choice){
case('T') : digitalWrite(Zdir,LOW); delayMicroseconds(10); doZSteps(1); ZcurrStep=ZcurrStep-1; // T == Z up by 5 counts
break;
case('G') : digitalWrite(Zdir,HIGH); delayMicroseconds(10); doZSteps(1); ZcurrStep=ZcurrStep+1; // G == Z down
break;
case('A') : needtocheckXmovement=1; digitalWrite(Xdir,LOW); delayMicroseconds(10); doXSteps(xFoV/5); XcurrStep=XcurrStep+xFoV; // A == X up by 1 FoV
break;
case('D') : needtocheckXmovement=0; digitalWrite(Xdir,HIGH); delayMicroseconds(10); doXSteps(xFoV/5); XcurrStep=XcurrStep-xFoV; // D == X down by 1 FoV
break;
case('W') : needtocheckYmovement=0; digitalWrite(Ydir,LOW); delayMicroseconds(10); doYSteps(yFoV/5); YcurrStep=YcurrStep+yFoV; // W == Y up
break;
case('S') : needtocheckYmovement=1; digitalWrite(Ydir,HIGH); delayMicroseconds(10); doYSteps(yFoV/5); YcurrStep=YcurrStep-yFoV; // S == Y down
break;
case('J') : XcurrStep = 0; // J == X reset
break;
case('K') : YcurrStep = 0; // K == Y reset
break;
case('L') : ZcurrStep = 0; // L == Z reset
break;
case('B') : gotoXSetStep(getStep());
break;
case('N') : gotoYSetStep(getStep());
break;
case('M') : gotoZSetStep(getStep());
break;
case('I') : Serial1.flush(); Serial.print('X'); Serial.print("#"); Serial.print(XcurrStep); Serial.print("#");
break;
case('O') : Serial2.flush(); Serial.print('Y'); Serial.print("#"); Serial.print(YcurrStep); Serial.print("#");
break;
case('P') : Serial3.flush(); Serial.print('Z');Serial.print("#"); Serial.print(ZcurrStep); Serial.print("#");
break;
// Set A,B,C - Codes are E,R,Y respectively
case('E') : Ax=XcurrStep; Ay=YcurrStep; Az=ZcurrStep;
break;
case('R') : Bx=XcurrStep; By=YcurrStep; Bz=ZcurrStep;
break;
case('Y') : Cx=XcurrStep; Cy=YcurrStep; Cz=ZcurrStep;
break;
case('U') :
break;
case('Z') : do4ptArea();
break;
case('X') :
break;
case('C') : // linear scan
doAtoB();
break;
case('V') : debug();
break;
case('Q') : gohome();
break;
case('F') : doFullArea();
break;
case('H') : gotoZSetStep(0);
// Signal that ready to AF now
Serial.print("H#");
break;
case('1') : tray_out();
break;
case('2') : tray_in();
break;
case('0') : EEPROM.write(0,0);
break;
case('7') : Serial.print('7'); Serial.print("#");
break;
case('3') : digitalWrite(Zdir,HIGH); delayMicroseconds(10); Serial3.print("X"); ZcurrStep=ZcurrStep+1;
break;
case('5') : digitalWrite(Zdir,LOW); delayMicroseconds(10); Serial3.print("X"); ZcurrStep=ZcurrStep-1;
break;
case('.'): // this is the travel sync option. First go 20 k steps and note time
Serial.print('0'); Serial.print("#"); gotoXSetStep(XcurrStep+20000); Serial.print('1'); Serial.print("#");
Serial.print('2'); Serial.print("#"); gotoXSetStep(XcurrStep-20000); Serial.print('3'); Serial.print("#");
Serial.print('4'); Serial.print("#"); gotoYSetStep(YcurrStep+20000); Serial.print('5'); Serial.print("#");
Serial.print('6'); Serial.print("#"); gotoYSetStep(YcurrStep-20000); Serial.print('7'); Serial.print("#");
default : break;
}
}
void doXSteps(long num) { while (num > 0 ) {
if( (needtocheckXmovement==1) && (digitalRead(Xbump) == LOW)) { XcurrStep=0; return;} // DO NOT MOVE IF ALREADY AT LIMIT
Serial1.print("U"); num--; } }
void doYSteps(long num) { while (num > 0 ) {
if( (needtocheckYmovement==1) && (digitalRead(Ybump) == LOW)) { YcurrStep=0; return;} // DO NOT MOVE IF ALREADY AT LIMIT
Serial2.print("U"); num--; } }
void doZSteps(long num) { while (num > 0 ) {
if( (needtocheckZmovement==1) && (digitalRead(AFbump) == LOW)) { ZcurrStep=0; return;} // DO NOT MOVE IF ALREADY AT LIMIT
Serial3.print("@"); num--; } }
long getStep()
{
long index = 0, inpStep[7]={0,0,0,0,0,0,0}, invalidInput = 0;
long setStep = 0L;
for(index=0; index<8; index++ )
{
while ( Serial.available() < 1 );
inpStep[index] = Serial.read() - 48;
}
// DISCARD first byte : MATLAB sends the terminator character there. We need it since if we turn it off, MATALB won't read the Tx from this arduino
// ALSO igmore the second byte : that's the sign symbol
setStep = (inpStep[2]*100000) + (inpStep[3]*10000) + (inpStep[4]*1000) + (inpStep[5]*100) + (inpStep[6]*10) + (inpStep[7]*1) + 0L ;
// check what sign was sent. If it was anything other than a '-' then dont worry
if (inpStep[1] + 48 == '-' ) { setStep = setStep*(-1); }
return setStep;
}
void gotoXSetStep(long XsetStep)
{
if(XsetStep > XMaxStep) {XsetStep=XMaxStep;}
long stepstodo = abs(XsetStep - XcurrStep) / 5;
if (XsetStep > XcurrStep)
{ needtocheckXmovement=1 ;
digitalWrite(Xdir,LOW); delayMicroseconds(10); XcurrStep=XsetStep; doXSteps( stepstodo ); }
if (XsetStep < XcurrStep)
{ needtocheckXmovement=0 ;
digitalWrite(Xdir,HIGH); delayMicroseconds(10); XcurrStep=XsetStep; doXSteps( stepstodo ); }
}
void gotoYSetStep(long YsetStep)
{
if(YsetStep > YMaxStep) {YsetStep = YMaxStep;}
long stepstodo = abs(YsetStep - YcurrStep) / 5;
if (YsetStep > YcurrStep)
{ needtocheckYmovement=0 ;
digitalWrite(Ydir,LOW); delayMicroseconds(10); YcurrStep=YsetStep; doYSteps( stepstodo ); }
if (YsetStep < YcurrStep)
{
needtocheckYmovement=1 ;
digitalWrite(Ydir,HIGH); delayMicroseconds(10); YcurrStep=YsetStep; doYSteps( stepstodo ); }
}
void gotoZSetStep(long ZsetStep)
{
//if(ZsetStep > ZMaxStep) {ZsetStep = ZMaxStep;}
long stepstodo = abs(ZsetStep - ZcurrStep) / 5;
if (ZsetStep > ZcurrStep)
{ needtocheckZmovement=0 ;
digitalWrite(Zdir,HIGH); delayMicroseconds(10); ZcurrStep=ZsetStep; doZSteps( stepstodo ); }
if (ZsetStep < ZcurrStep)
{
needtocheckZmovement=1 ;
digitalWrite(Zdir,LOW); delayMicroseconds(10); ZcurrStep=ZsetStep; doZSteps( stepstodo ); }
}
void tray_out ()
{/*
// if already tray out then skip this
//if (EEPROM.read(0) == 1) { return; }
// var to even out electric noise
int Xnoise=0, Ynoise=0, Znoise=0;
// x & y out
digitalWrite(Xdir,HIGH); digitalWrite(Ydir,HIGH); digitalWrite(Zdir,HIGH); delayMicroseconds(20);
while ( Znoise < trayOutNoiseMargin )
{
Serial1.print("U");
if (digitalRead(AFbump) == HIGH) { Znoise++; }
}
digitalWrite(Zdir,LOW);
for (int i=0; i<2000;i++)
{ Serial1.print("U"); }
while ( Xnoise < trayOutNoiseMargin )
{
Serial2.print("U");
if (digitalRead(Xbump) == HIGH) { Xnoise++; }
}
for (int i=0; i<5000;i++)
{ Serial2.print("U"); }
while ( Ynoise < trayOutNoiseMargin )
{
Serial3.print("U");
if (digitalRead(Ybump) == LOW) { Ynoise++; }
}
// if all done, store this in EEPROM
//EEPROM.write(0,1);
*/
Serial.println("Tray out");
}
void tray_in()
{
// assuming that it is called only after tray_out
// gotoXSetStep(125000);
//gotoYSetStep(-40000);
// gotoZSetStep(-3000);
// now that we're at position, reset counts
//XcurrStep=0L; YcurrStep=0L; ZcurrStep=0L;
// and the tray in var
// EEPROM.write(0,0);
}
void doFullArea()
{
// calculate num of x & y FoV. And the tilts
long XstepCount = 252525 ; long numXsteps = (XstepCount / xFoV) ; long YstepCount = 126260 ; long numYsteps = (YstepCount / yFoV) ;
/* The equations are
* Az = {Tx(Ax-Bx)} + {Ty(Ay-By)} + {Bz}
* and
* Az = {Tx(Ax-Cx)} + {Ty(Ay-Cy)} + {Cz}
*
* we can find Tx and Ty after some algebra
* After Tx and Ty, we can find Oz too
*/
long a = (round)( (Ax-Bx) / (float)xFoV); long b = (round)((Ay-By)/(float)yFoV); long c = (Az-Bz);
long d = (round)((Ax-Cx)/(float)xFoV); long e = (round)((Ay-Cy)/(float)yFoV); long f =(Az-Cz);
long Oz = 0L;
XdeltaZperFoV = (round) ((c*e)-(b*f)) / (float) ((a*e)-(b*d)) ;
YdeltaZperFoV = (round) (c-(a*XdeltaZperFoV)) / (float) b ;
Oz = Az - (XdeltaZperFoV *(Ax/xFoV)) - (YdeltaZperFoV * (Ay/yFoV));
// Tilts calculated. Now go ahead with WSI **************************************************************
// set the initial delta z to the x one. Later, in the loop, it will be changed continously
long deltaZperFoV = XdeltaZperFoV;
//this var keeps track of xdir while scanning . +1 is inc., -1 is dec
long XtravelDir = 1;
// go to the origin
gotoXSetStep(0); gotoYSetStep(0); gotoZSetStep(Oz);
delay(300);
// Send sync signal to the imager. By now we're starting FoV and this will be immediately imaged.
Serial.print("S#");
// go go go
for (long trackY = 0; trackY <= numYsteps; trackY++)
{
for (long trackX = 0; trackX < numXsteps; trackX++)
{
gotoXSetStep(XcurrStep + (XtravelDir * xFoV));
/* Four cases now --- (a) we're at 1st fov : dont move Z !
* --- (b)we're on first strip but more than 1st fov : keep adding X tilt
* --- (c) we're at end of strip and just moved to next strip : only add the Y tilt
* --- (d) we're in 2nd or higher strip : keep adding only X tilt (Y tilt already added at (c))
*/
if((trackX==0)&&(trackY==0)) { nextZstep = ZcurrStep; }
if((trackX>0)&&(trackY==0)) { nextZstep = ZcurrStep +(XtravelDir * deltaZperFoV); }
if((trackX==0)&&(trackY>0)) { nextZstep = ZcurrStep + YdeltaZperFoV;}
if((trackX>0)&&(trackY>0)) { nextZstep = ZcurrStep +(XtravelDir * deltaZperFoV); }
gotoZSetStep(nextZstep);
}
// shift in the Y dir
gotoYSetStep(YcurrStep + yFoV);
// now go in the opposite direction
XtravelDir = XtravelDir * -1;
}
// All done. Now go back to ORIGIN
gotoXSetStep(0); gotoYSetStep(0); gotoZSetStep(0);
delay(300);
}
//88888888888888888888888888888888888888888888888888888888888888888
// THIS IS THE GOHOME() FUNCTION
//88888888888888888888888888888888888888888888888888888888888888888
void gohome()
{
// turn on all lights
gotoYSetStep(-300000); gotoXSetStep(400000);
Serial1.flush(); Serial.print('X'); Serial.print("#"); Serial.print(XcurrStep); Serial.print("#");
// Y already at origin. Need to bring X and Z there
gotoXSetStep(limitToXZero); gotoYSetStep(limitToYZero);
gotoZSetStep(-100000); gotoZSetStep(limitTOZfocus);
// SET THIS AS ORIGIN
XcurrStep=0L; YcurrStep=0L; ZcurrStep=0L;
// all done now. Send sync signal
Serial.print("S#");
}
void debug()
{
// calc steps in X
long XstepCount = abs(Bx - Ax) ; long numXsteps = (XstepCount / xFoV) ;
// calc steps in Y
long YstepCount = abs(Cy - By) ; long numYsteps = (YstepCount / yFoV) ;
// calc the z changes
long XZdeltaCount = Bz - Az ; long XdeltaZperFoV = XZdeltaCount / (numXsteps-1);
long YZdeltaCount = Cz - Bz ; long YdeltaZperFoV = YZdeltaCount / (numYsteps-1);
// set the initial delta z to the x one. Later, in the loop, it will be changed continously
long deltaZperFoV = XdeltaZperFoV;
Serial.print(" Ax: ");Serial.print(Ax);Serial.print(" Ay: ");Serial.print(Ay);Serial.print(" Az: ");Serial.print(Az);
Serial.print(" Bx: ");Serial.print(Bx);Serial.print(" By: ");Serial.print(By);Serial.print(" Bz: ");Serial.print(Bz);
Serial.print(" Cx: ");Serial.print(Cx);Serial.print(" Cy: ");Serial.print(Cy);Serial.print(" Cz: ");Serial.print(Cz);
Serial.print(" XdeltaZperFoV: ");Serial.print(XdeltaZperFoV);
Serial.print(" YdeltaZperFoV: ");Serial.print(YdeltaZperFoV);
Serial.print("#");
}
void do4ptArea()
{
// calc steps in X
long XstepCount = abs(Bx - Ax) ; long numXsteps = (XstepCount / xFoV) ;
// calc steps in Y
long YstepCount = abs(Cy - By) ; long numYsteps = (YstepCount / yFoV) ;
// calc the z changes
long XZdeltaCount = Bz - Az ; long XdeltaZperFoV = XZdeltaCount / (numXsteps-1);
long YZdeltaCount = Cz - Bz ; long YdeltaZperFoV = YZdeltaCount / (numYsteps-1);
// set the initial delta z to the x one. Later, in the loop, it will be changed continously
long deltaZperFoV = XdeltaZperFoV;
//this var keeps track of xdir while scanning . +1 is inc., -1 is dec
long XtravelDir = 1;
// go to the origin
gotoXSetStep(Ax); gotoYSetStep(Ay); gotoZSetStep(Az);
delay(300);
// Send sync signal to the imager
Serial.print("S#");
// go go go
for (long trackY = 0; trackY <= numYsteps; trackY++)
{
for (long trackX = 0; trackX < numXsteps; trackX++)
{
gotoXSetStep(XcurrStep + (XtravelDir * xFoV));
/* Four cases now --- (a) we're at 1st fov : dont move Z !
* --- (b)we're on first strip but more than 1st fov : keep adding X tilt
* --- (c) we're at end of strip and just moved to next strip : only add the Y tilt
* --- (d) we're in 2nd or higher strip : keep adding only X tilt (Y tilt already added at (c))
*/
if((trackX==0)&&(trackY==0)) { nextZstep = ZcurrStep; }
if((trackX>0)&&(trackY==0)) { nextZstep = ZcurrStep +(XtravelDir * deltaZperFoV); }
if((trackX==0)&&(trackY>0)) { nextZstep = ZcurrStep + YdeltaZperFoV;}
if((trackX>0)&&(trackY>0)) { nextZstep = ZcurrStep +(XtravelDir * deltaZperFoV); }
gotoZSetStep(nextZstep);
}
// shift in the Y dir
gotoYSetStep(YcurrStep + yFoV);
// now go in the opposite direction
XtravelDir = XtravelDir * -1;
}
// All done. Now go back to ORIGIN
gotoXSetStep(0); gotoYSetStep(0); gotoZSetStep(0);
delay(300);
}
void doAtoB()
{
long XMovDir = 1;
// find num of Fov to be traversed and their direction
long XstepCount = abs(Bx - Ax) ; long numXFoV = (XstepCount / xFoV) ;
if (Bx > Ax) { XMovDir = 1; }
if (Bx < Ax) { XMovDir = -1; }
// setup Z data
long ZdeltaCount = Bz - Az ;
long deltaZperFoV = ZdeltaCount / numXFoV; // This gives the Z change per FoV
Serial.println("deltaperZfov is ");
Serial.println(deltaZperFoV);
// go to the origin
gotoXSetStep(Ax); gotoYSetStep(Ay); gotoZSetStep(Az);
// Send sync signal to the imager
Serial.print("S#");
delay(300);
// go go go
if( XMovDir == 1) // means we're going in inc X dir
{
for(long i=0; i<numXFoV; i++)
{
gotoXSetStep(XcurrStep + xFoV);
gotoZSetStep(ZcurrStep + deltaZperFoV);
}
}
if( XMovDir == -1) // means we're going in dec X dir
{
for(long i=0; i<numXFoV; i++)
{
gotoXSetStep(XcurrStep - xFoV);
gotoZSetStep(ZcurrStep + deltaZperFoV);
}
}
}