char serialport[128] = "/dev/ttyS1\0"; unsigned char ser_sbufout[38] = "0000000000\0"; unsigned char ser_sbufin[38] = "00000000000000000000000000000000000\0"; int serialfd = 0; time_t serflowmotorstart; double serflowazhspersecsslow; double serflowalthspersecsslow; double serflowazhspersecsfast; double serflowalthspersecsfast; int sercurazleft; int sercuraltdown; int sercurfrleft; double seraztarget; double seralttarget; int sercorrectionazmotor = 0; int sercorrectionaltmotor = 0; double serencoder_azcount = 32768; double serencoder_altcount = 32768; unsigned char ser_calculateramp( unsigned char speed ) { if(speed >= 20 ){ return(speed); } if(speed >= 10 ){ return(20); } return(254); } unsigned char serSLOWBYTE( unsigned char val ) { unsigned char v; v = val & 0x0f; v = v + 0x30; return(v); } unsigned char serSHIBYTE( unsigned char val ) { unsigned char v; v = val >> 4; v = v & 0x0f; v = v + 0x30; return(v); } unsigned char serSFBYTE( unsigned char low, unsigned char high ) { unsigned char v,l,h; l = low - 0x30; l = l & 0x0f; h = high - 0x30; h = h << 4; h = h & 0xf0; v = l | h; return(v); } void setserialoutbuffer( unsigned char cmd, unsigned char v1, unsigned char v2, unsigned char v3, unsigned char v4) { ser_sbufout[0] = serSLOWBYTE(cmd); ser_sbufout[1] = serSHIBYTE(cmd); ser_sbufout[2] = serSLOWBYTE(v1); ser_sbufout[3] = serSHIBYTE(v1); ser_sbufout[4] = serSLOWBYTE(v2); ser_sbufout[5] = serSHIBYTE(v2); ser_sbufout[6] = serSLOWBYTE(v3); ser_sbufout[7] = serSHIBYTE(v3); ser_sbufout[8] = serSLOWBYTE(v4); ser_sbufout[9] = serSHIBYTE(v4); } unsigned char getdoublebyteval( double val ) { double v; unsigned long w; unsigned char *p; v = makeAbsoluteDouble(val); w = (unsigned long) v; p = (unsigned char *)&w; return(p[0]); } unsigned short getdoubleshortval( double val ) { double v; unsigned long w; unsigned short *p; v = makeAbsoluteDouble(val); w = (unsigned long) v; p = (unsigned short *)&w; return(p[0]); } void doubletoserial24( unsigned char cmd, double val ) { double v; unsigned long w; unsigned char *p; v = makeAbsoluteDouble(val); w = (unsigned long) v; p = (unsigned char *)&w; setserialoutbuffer(cmd,p[0],p[1],p[2],0x40); } double serial24todouble( unsigned char *src ) { double d; unsigned long w[2]; unsigned char *p; unsigned char v; d = 0; w[0] = 0; w[1] = 0; p = (unsigned char *)&w[0]; v = serSFBYTE( src[0], src[1]); p[0] = v; v = serSFBYTE( src[2], src[3]); p[1] = v; v = serSFBYTE( src[4], src[5]); p[2] = v; d = ( double )w[0]; return( d ); } int serialsequenceout(void) { int ct; if(serialfd <= 0 ){ return(0); } ser_sbufout[8] = 0x0a; ser_sbufout[9] = 0x0a; ct = 0; while(ct < 9 ){ if( waitWriteFD( (char *)&ser_sbufout[ct], serialfd , 1 ) == 0 ) { return(0); } ct++; } tcdrain(serialfd); return(1); } int serialsequencein( size_t num ) { int ct; if(serialfd <= 0 ){ return(0); } ct = 0; while( ct < num ){ if( waitReadFD( (char *)&ser_sbufin[ct], serialfd , 1 ) == 0 ) { return(0); } ct++; } return(1); } unsigned char serialgetinputval( void ) { unsigned char val; setserialoutbuffer(0x1f,0x40,0x40,0x40,0x40); if(serialsequenceout() == 0){ return(0); } if(serialsequencein( 11 ) == 0){ return(0); } val = serSFBYTE( ser_sbufin[2], ser_sbufin[3]); return(val); } double serialgetencodercount( char *src ) { double d; unsigned long w[2]; unsigned char *p; unsigned char v; d = 0; w[0] = 0; w[1] = 0; p = (unsigned char *)&w[0]; v = serSFBYTE( src[0], src[1]); p[0] = v; v = serSFBYTE( src[8], src[9]); p[1] = v; d = ( double )w[0]; return( d ); } int serialcalcencoder_az( char *src, double hs ) { /* double val,diff; val = serialgetencodercount( src ); if(val == serencoder_azcount){ if(encoder.az_errcount > 0.0){ if(! encoders_compare_az( hs ) ) { doubletoserial24( 0x39, encoder.correctazhs ); if(serialsequenceout() == 0){ fprintf(stderr,"\nComparison of encoder az position again: Error when sending new values to serial device\n"); } ctrif_waitmillisecs( 20 ); return(0); } } encoder.cazhs = hs; return(1); } if(val < serencoder_azcount){ encoder.azleft = 1; } else { encoder.azleft = 0; } diff = serencoder_azcount - val; if(diff < 0.0){ diff = diff * -1.0; } serencoder_azcount = val; _encoder_set_azvalues( hs , diff ); if(! encoders_compare_az( hs ) ) { doubletoserial24( 0x39, encoder.correctazhs ); if(serialsequenceout() == 0){ fprintf(stderr,"\nComparison of encoder az position: Error when sending new values to serial device\n"); } ctrif_waitmillisecs( 20 ); return(0); } */ return( 1 ); } int serialcalcencoder_alt( char *src, double hs ) { /* double val,diff; val = serialgetencodercount( src ); if(val == serencoder_altcount){ if(encoder.alt_errcount > 0.0){ if(! encoders_compare_alt( hs ) ) { doubletoserial24( 0x3a, encoder.correctalths ); if(serialsequenceout() == 0){ fprintf(stderr,"\nComparison of encoder alt position again: Error when sending new values to serial device\n"); } ctrif_waitmillisecs( 20 ); return(0); } } encoder.calths = hs; return(1); } if(val < serencoder_altcount){ encoder.altdown = 1; } else { encoder.altdown = 0; } diff = serencoder_altcount - val; if(diff < 0.0){ diff = diff * -1.0; } serencoder_altcount = val; _encoder_set_altvalues( hs , diff ); if(! encoders_compare_alt( hs ) ) { doubletoserial24( 0x3a, encoder.correctalths ); if(serialsequenceout() == 0){ fprintf(stderr,"\nComparison of encoder alt position: Error when sending new values to serial device\n"); } ctrif_waitmillisecs( 20 ); return(0); } */ return( 1 ); } int serialOperationStopMotorPower( void ) { if(serialfd <= 0){ return(0); } setserialoutbuffer(0x3d,0x40,0x40,0x40,0x40); if(serialsequenceout() == 0){ return(0); } return(1); } /*############################################################*/ /*############################################################*/ /*############################################################*/ //init serial connection to eldob-cpu-board //first test if available int serial_openConnection() { unsigned short us,_us; unsigned char l,h; if(serialfd > 0){ return(1); } serialfd = setBaudRateOpenPort(serialport , "19200"); if(serialfd <= 0){ return(0); } setserialoutbuffer(0x3e,0x40,0x40,0x40,0x40); if(serialsequenceout() == 0){ return(0); } ctrif_waitmillisecs( 20 ); setserialoutbuffer(0x20,0x40,0x40,0x40,0x40); if(serialsequenceout() == 0){ return(0); } ctrif_waitmillisecs( 20 ); setserialoutbuffer(0x3d,0x40,0x40,0x40,0x40); if(serialsequenceout() == 0){ return(0); } ctrif_waitmillisecs( 20 ); doubletoserial24( 0x26, elctr.hs_az360 ); if(serialsequenceout() == 0){ return(0); } ctrif_waitmillisecs( 20 ); doubletoserial24( 0x2b, elctr.hs_altlb ); if(serialsequenceout() == 0){ return(0); } ctrif_waitmillisecs(20); doubletoserial24( 0x2c, elctr.hs_altub ); if(serialsequenceout() == 0){ return(0); } ctrif_waitmillisecs(20); doubletoserial24( 0x31, elctr.hs_fr360 ); if(serialsequenceout() == 0){ return(0); } ctrif_waitmillisecs(20); /* //0 is the default on board for TIMERINTVAL setserialoutbuffer(0x38,0x00,0x00,0x40,0x40); if(serialsequenceout() == 0){ return(0); } ctrif_waitmillisecs(20); */ setserialoutbuffer(0x39,0x00,0x00,0x00,0x40); if(serialsequenceout() == 0){ return(0); } ctrif_waitmillisecs( 20 ); setserialoutbuffer(0x3A,0x00,0x00,0x00,0x40); if(serialsequenceout() == 0){ return(0); } ctrif_waitmillisecs( 20 ); setserialoutbuffer(0x3B,0x00,0x00,0x00,0x40); if(serialsequenceout() == 0){ return(0); } ctrif_waitmillisecs( 20 ); setserialoutbuffer(0x3c,0x40,0x40,0x40,0x40); if(serialsequenceout() == 0){ return(0); } ctrif_waitmillisecs( 20 ); /* if(encoder.type == SERIALENCODER ){ setserialoutbuffer(0x3f,0x40,0x40,0x40,0x40); if(serialsequenceout() == 0){ return(0); } ctrif_waitmillisecs( 20 ); setserialoutbuffer(0x22,0x40,0x40,0x40,0x40); if(serialsequenceout() == 0){ return(0); } if(serialsequencein( 11 ) == 0){ return(0); } serencoder_azcount = serialgetencodercount( &ser_sbufin[0] ); ctrif_waitmillisecs( 20 ); setserialoutbuffer(0x23,0x40,0x40,0x40,0x40); if(serialsequenceout() == 0){ return(0); } if(serialsequencein( 11 ) == 0){ return(0); } serencoder_altcount = serialgetencodercount( &ser_sbufin[0] ); encoders_reset(0,0); ctrif_waitmillisecs( 20 ); } */ return(1); } int serial_stopMotors( void ) { if(serialfd <= 0){ return(0); } setserialoutbuffer(0x20,0x40,0x40,0x40,0x40); if(serialsequenceout() == 0){ return(0); } return(1); } int serial_closeConnection( void ) { if( serialfd <= 0){ return(1); } if(serial_stopMotors() == 0) { return(0); } ctrif_waitmillisecs( 20 ); if(serialOperationStopMotorPower() == 0) { return(0); } close( serialfd ); serialfd = 0; return(1); } double serial_getCurrentAzKoor( void ) { double d; if(serialfd <= 0){ return(-1.0); } if( ! elctr.motorrun ) { setserialoutbuffer(0x22,0x40,0x40,0x40,0x40); if(serialsequenceout() == 0){ return(-1.0); } if(serialsequencein( 11 ) == 0){ return(-2.0); } d = serial24todouble( &ser_sbufin[2] ); elctr.lastazhs = d; /* if(! serialcalcencoder_az( &ser_sbufin[0], d )){ elctr.lastazhs = encoder.correctazhs; d = elctr.lastazhs; } */ return( d ); } d = elctr.lastazhs; return( d ); } double serial_getCurrentAltKoor( void ) { double d; if(serialfd <= 0){ return(-1.0); } if( ! elctr.motorrun ) { setserialoutbuffer(0x23,0x40,0x40,0x40,0x40); if(serialsequenceout() == 0){ return(-1.0); } if(serialsequencein( 11 ) == 0){ return(-2.0); } d = serial24todouble( &ser_sbufin[2] ); elctr.lastalths = d; /* if(! serialcalcencoder_alt( &ser_sbufin[0], d )){ elctr.lastalths = encoder.correctalths; d = elctr.lastalths; } */ return( d ); } d = elctr.lastalths; return(d); } double serial_getCurrentFrKoor( void ) { double d; if(serialfd <= 0){ return(-1.0); } if( ! elctr.motorrun ) { setserialoutbuffer(0x24,0x40,0x40,0x40,0x40); if(serialsequenceout() == 0){ return(-1.0); } if(serialsequencein( 11 ) == 0){ return(-2.0); } d = serial24todouble( &ser_sbufin[2] ); elctr.lastfrhs = d; return( d ); } d = elctr.lastfrhs; return(d); } //set speeds to value < 0, for motors not used. //if all < 0, only timercounter will set to ct, expecting ct is also <0 //a dirvalue of 1 means left, 0 means right int serial_CorrectionMode( int spd, double azsp, int azdir, double altsp, int altdir, double frsp, int frdir ) { unsigned char settings; unsigned char speed,ramp; unsigned char _ct; time_t tt; settings = 0; if(serialfd <= 0){ return(0); } sercorrectionaltmotor = 0; sercorrectionazmotor = 0; if( spd >= 0){ if(spd == SPEED_FAST){ _ct = getdoublebyteval( elctr.timerintct_goto ); } else { _ct = getdoublebyteval( elctr.timerintct_correction ); } setserialoutbuffer(0x25,_ct,0x40,0x40,0x40); if(serialsequenceout() == 0){ return(0); } ctrif_waitmillisecs( 20 ); } if(azsp >= 0){ settings = settings | 1; sercorrectionazmotor = 1; sercurazleft = 0; elctr.azleft = 0; if(azdir){ settings = settings | 16; sercurazleft = 1; elctr.azleft = 1; } speed = getdoublebyteval( azsp ); ramp = ser_calculateramp(speed); setserialoutbuffer(0x2a,speed,ramp,0x40,0x40); if(serialsequenceout() == 0){ return(0); } ctrif_waitmillisecs( 20 ); } if(altsp >= 0){ settings = settings | 2; sercorrectionaltmotor = 1; sercuraltdown = 0; elctr.altdown = 0; if(altdir){ settings = settings | 32; sercuraltdown = 1; elctr.altdown = 1; } speed = getdoublebyteval( altsp ); ramp = ser_calculateramp(speed); setserialoutbuffer(0x30,speed,ramp,0x40,0x40); if(serialsequenceout() == 0){ return(0); } ctrif_waitmillisecs( 20 ); } if(frsp >= 0){ settings = settings | 4; sercurfrleft = 0; if(frdir){ settings = settings | 64; sercurfrleft = 1; } speed = getdoublebyteval( frsp ); ramp = ser_calculateramp(speed); setserialoutbuffer(0x35,speed,ramp,0x40,0x40); if(serialsequenceout() == 0){ return(0); } ctrif_waitmillisecs( 20 ); } if( settings > 0 ){ serflowmotorstart = time( &tt); setserialoutbuffer(0x21,0x21,settings,0x40,0x40); if(serialsequenceout() == 0){ return(0); } } return(1); } //return with 1 it connection error //return with 2 if koordinatoutofrangeerror //return with 0 if all ok int serial_Goto ( double azhs, double alths ) { double curaz,curalt,newaz,newalt,azevt,altevt; unsigned char settings; unsigned char speed,ramp,_ct; time_t tt; if(serialfd <= 0){ return(1); } setserialoutbuffer(0x22,0x40,0x40,0x40,0x40); if(serialsequenceout() == 0){ return(1); } if(serialsequencein( 11 ) == 0){ return(1); } curaz = serial24todouble( &ser_sbufin[2] ); /* if(! serialcalcencoder_az( &ser_sbufin[0], curaz )){ curaz = encoder.correctazhs; } */ ctrif_waitmillisecs( 10 ); setserialoutbuffer(0x23,0x40,0x40,0x40,0x40); if(serialsequenceout() == 0){ return(1); } if(serialsequencein( 11 ) == 0){ return(1); } curalt = serial24todouble( &ser_sbufin[2] ); /* if(! serialcalcencoder_alt( &ser_sbufin[0], curalt )){ curalt = encoder.correctalths; } */ settings = 0; seraztarget = azhs; seralttarget = alths; newaz = azhs; newalt = alths; // now we have the current position with curaz, and curalt as number of halfsteps // and we have the new position with newaz, and newalt also as number of halfsteps // Now we must search the shortes way. if( curaz != newaz ){ if(newaz > elctr.hs_az360){ return(2); } settings = settings | 1; // az motor on if( ( curaz >= 0 ) && ( curaz < elctr.hs_az180 ) ){ //scope is current between 0 and 180 degrees if( ( newaz >= 0 ) && ( newaz < elctr.hs_az180 ) ){ //new azval is in the same sector if(newaz < curaz){ settings = settings | 16; // turn left azevt = curaz - newaz; sercurazleft = 1; elctr.azleft = 1; } else { // turn right azevt = newaz - curaz; sercurazleft = 0; elctr.azleft = 0; } } else { //new azval is in the opposite sector //normally turn right azevt = newaz - curaz; sercurazleft = 0; elctr.azleft = 0; if( ( curaz < elctr.hs_az90) && ( newaz >= elctr.hs_az270 ) ){ //scope is current between 0 and 90 degrees //and new az also north settings = settings | 16; // turn left azevt = ( elctr.hs_az360 - newaz ) + curaz; sercurazleft = 1; elctr.azleft = 1; } } } else { // scope is cuurrent between 180 and 360 degrees if( ( newaz >= elctr.hs_az180 ) && ( newaz <= elctr.hs_az360 ) ){ //new azval is in the same sector if(newaz < curaz){ settings = settings | 16; // turn left azevt = curaz - newaz; sercurazleft = 1; elctr.azleft = 1; } else { //turn right azevt = newaz - curaz; sercurazleft = 0; elctr.azleft = 0; } } else { // new azval is in the opposite sector if( ( curaz >= elctr.hs_az270 ) && ( newaz < elctr.hs_az90 ) ){ //scope is current between 270 and 360 degrees //and new az also north // turn right azevt = ( elctr.hs_az360 - curaz ) + newaz; sercurazleft = 0; elctr.azleft = 0; } else { //normally turn left settings = settings | 16; azevt = curaz - newaz; sercurazleft = 1; elctr.azleft = 1; } } } } if(curalt != newalt ) { if(newalt <= elctr.hs_altlb){ return(2); } if(newalt >= elctr.hs_altub){ return(2); } settings = settings | 2; if( newalt < curalt ){ //turn down settings = settings | 32; altevt = curalt - newalt; sercuraltdown = 1; elctr.altdown = 1; } else { //turn up altevt = newalt - curalt; sercuraltdown = 0; elctr.altdown = 0; } } if(settings > 0 ){ _ct = getdoublebyteval( elctr.timerintct_goto ); setserialoutbuffer(0x25,_ct,0x40,0x40,0x40); if(serialsequenceout() == 0){ return(1); } ctrif_waitmillisecs( 30 ); speed = getdoublebyteval( elctr.az_gotospeed ); ramp = ser_calculateramp(speed); setserialoutbuffer(0x2a,speed,ramp,0x40,0x40); if(serialsequenceout() == 0){ return(1); } ctrif_waitmillisecs( 30 ); speed = getdoublebyteval( elctr.alt_gotospeed ); ramp = ser_calculateramp(speed); setserialoutbuffer(0x30,speed,ramp,0x40,0x40); if(serialsequenceout() == 0){ return(1); } ctrif_waitmillisecs( 30 ); doubletoserial24( 0x27, azevt ); if(serialsequenceout() == 0){ return(1); } ctrif_waitmillisecs( 30 ); doubletoserial24( 0x2D, altevt ); if(serialsequenceout() == 0){ return(1); } ctrif_waitmillisecs( 30 ); serflowmotorstart = time( &tt); setserialoutbuffer(0x21,0x22,settings,0x40,0x40); if(serialsequenceout() == 0){ return(1); } } //all ok return(0); } int serial_ResetKoors ( double azhs, double alths ) { if(serialfd <= 0){ return(0); } doubletoserial24( 0x39, azhs ); if(serialsequenceout() == 0){ return(0); } ctrif_waitmillisecs( 20 ); doubletoserial24( 0x3a, alths ); if(serialsequenceout() == 0){ return(0); } return( 1 ); } /* makes one step per motor ( az, alt, fr - set to 1 what you use, otherwise 0) to direction ( azleft, frleft 0 = right, 1 = left, altdown 0 = up, 1 = down ) function gets new halfstepvalues for az,alt, if answer if set to 1, and sets *azhs,*alths to this. In mostly case when using az,alt this should be use in every case, for knowing if step is ready done. For only using fr, this makes mostly no sense. ms is a little timer in microsecs. Sometimes we need a little wait after doing halfsteps, for beeing sure, steps are ready. Normally for serial interface, this makes no sense. */ int serial_Step( int answer, int az, int azleft, int alt, int altdown, int fr, int frleft, double * azhs, double * alths, long ms ) { unsigned char azsetting,altsetting,frsetting; if(serialfd <= 0){ return( 0 ); } azsetting = 0; altsetting = 0; frsetting = 0; if( az ){ azsetting = azsetting | 1; elctr.azleft = 0; if(azleft){ azsetting = azsetting | 2; elctr.azleft = 1; } } if( alt ){ altsetting = altsetting | 1; elctr.altdown = 0; if(altdown){ altsetting = altsetting | 2; elctr.altdown = 1; } } if( fr ){ frsetting = frsetting | 1; if(frleft){ frsetting = frsetting | 2; } } if( (az == 0) && ( alt == 0 ) && (fr == 0 ) ){ return(1); } if( answer ) { azsetting = azsetting | 4; setserialoutbuffer(0x1e,azsetting,altsetting,frsetting,0x40); if(serialsequenceout() == 0){ return(0); } if(serialsequencein( 11 ) == 0){ return(0); } *azhs = serial24todouble( &ser_sbufin[2] ); setserialoutbuffer(0x23,0x40,0x40,0x40,0x40); if(serialsequenceout() == 0){ return(0); } if(serialsequencein( 11 ) == 0){ return(0); } *alths = serial24todouble( &ser_sbufin[2] ); if(ms > 0 ){ ctrif_waitmicrosecs( ms ); } return(1); } setserialoutbuffer(0x1e,azsetting,altsetting,frsetting,0x40); if(serialsequenceout() == 0){ return(0); } if(ms > 0 ){ ctrif_waitmicrosecs( ms ); } return(1); }