void ArduEyeSMHClass::setBiasesVdd(char vddType) { // determine biases. Only one option for now. switch (vddType) { case SMH1_VDD_5V0: //chip receives 5V default: setPointerValue(SMH_SYS_NBIAS,SMH_NBIAS_5V0); setPointerValue(SMH_SYS_AOBIAS,SMH_AOBIAS_5V0); setPointerValue(SMH_SYS_VREF,SMH_VREF_5V0); break; } }
// setBiasesVdd // Sets biases based on chip voltage void Stonyman::setBiasesVdd(char flagVddType5v5) { // determine biases. Only one option for now. switch (flagVddType5v5) { case 1: //chip receives 5V default: setPointerValue(Stonyman::REG_NBIAS,Stonyman::DEFAULT_NBIAS_5V0); setPointerValue(Stonyman::REG_AOBIAS,Stonyman::DEFAULT_AOBIAS_5V0); setPointerValue(Stonyman::REG_VREF,Stonyman::DEFAULT_VREF_5V0); break; } }
void Stonyman::getPixelList( short *img, unsigned char rowlist[], unsigned char collist[], unsigned char numPixels ) { short *pimg = img; // pointer to output image array int val; //russ: unused //unsigned char chigh,clow; unsigned char i; unsigned char row,col,lastRow,lastCol; setPointerValue(Stonyman::REG_ROWSEL,rowlist[0]); setPointerValue(Stonyman::REG_COLSEL,0); lastRow = rowlist[0]; lastCol = 0; // Loop through all rows for (i=0; i<numPixels; ++i) { // If row has changed, update row and col registers if (rowlist[i] != lastRow) { setPointer(Stonyman::REG_ROWSEL); incValue(rowlist[i] - lastRow); lastRow = rowlist[i]; setPointerValue(Stonyman::REG_COLSEL,collist[i]); } else { // If not, just update col register setPointer(Stonyman::REG_COLSEL); incValue(collist[i] - lastCol); lastCol = collist[i]; } // settling delay delayMicroseconds(1); // pulse amplifier if needed if (flagUseAmplifier) { pulseInphi(2); // TODO russ: necessary value unclear/unknown } // get data value delayMicroseconds(1); val = analogRead(pinANALOG1); // AHHH: shorten casts! *pimg = (short)val; // store pixel pimg++; // advance pointer } }
// russ: dual read! void Stonyman::getDualImages( short *img1, short *img2, unsigned char rowstart, unsigned char numrows, unsigned char rowskip, unsigned char colstart, unsigned char numcols, unsigned char colskip ) //, char ADCType, char anain ) { short *pimg1 = img1; // pointer to output image array short *pimg2 = img2; // pointer to output image array int val1, val2; //russ: unused //unsigned char chigh,clow; unsigned char row,col; // Go to first row setPointerValue(Stonyman::REG_ROWSEL,rowstart); // Loop through all rows for (row=0; row<numrows; ++row) { // Go to first column setPointerValue(Stonyman::REG_COLSEL,colstart); // Loop through all columns for (col=0; col<numcols; ++col) { // settling delay delayMicroseconds(1); // pulse amplifier if needed if (flagUseAmplifier) { pulseInphi(2); // TODO russ: necessary value unclear/unknown } // get data value delayMicroseconds(1); val1 = analogRead(pinANALOG1); val2 = analogRead(pinANALOG2); // AHHH: shorten casts! *pimg1 = (short)val1; // store pixel *pimg2 = (short)val2; // store pixel pimg1++; // advance pointer pimg2++; // advance pointer incValue(colskip); // go to next column } setPointer(Stonyman::REG_ROWSEL); incValue(rowskip); // go to next row } }
void ArduEyeSMHClass::begin(short vref,short nbias,short aobias,char gain,char selamp) { //set all digital pins to output RESP_DDR|=RESP; INCP_DDR|=INCP; RESV_DDR|=RESV; INCV_DDR|=INCV; INPHI_DDR|=INPHI; //set external ADC SS to high ADC_SS_DDR|=ADC_SS; ADC_SS_PORT|=ADC_SS; //set all pins low SMH1_SetAllLow; //clear all chip register values clearValues(); //set up biases setBiases(vref,nbias,aobias); short config=gain+(selamp*8)+(16); //turn chip on with config value setPointerValue(SMH_SYS_CONFIG,config); //if amp is used, set useAmp variable if(selamp==1) useAmp=1; else useAmp=0; }
// clearValues // Resets the value of all registers to zero void Stonyman::clearValues(void) { short ii; for (ii = 0; ii < Stonyman::REG_CNT; ++ii) { setPointerValue(ii,0); //set each register to zero } }
// init // Initializes the vision chips for normal operation. Sets vision chip pins to low outputs, clears // chip registers, sets biases and config register. Arduino pin numbers must be specified. For // the remaining parameters if no parameters are passed in, default values are used. void Stonyman::init( char inPinRESP, char inPinINCP, char inPinRESV, char inPinINCV, char inPinINPHI, char inPinANALOG1, char inPinANALOG2, short vref, short nbias, short aobias, char gain, char selamp ) { short config; /* TODO russ: use later if(Stonyman::MAX_GAIN < inGain) { return Stonyman::RC_ERROR_BADPARAM; } // TODO russ: there are likely other checks to perform (vref, nbias, aobias) */ pinRESP = inPinRESP; pinINCP = inPinINCP; pinRESV = inPinRESV; pinINCV = inPinINCV; pinINPHI = inPinINPHI; pinANALOG1 = inPinANALOG1; pinANALOG2 = inPinANALOG2; // set all digital pins to output pinMode(pinRESP, OUTPUT); pinMode(pinINCP, OUTPUT); pinMode(pinRESV, OUTPUT); pinMode(pinINCV, OUTPUT); pinMode(pinINPHI, OUTPUT); // FIXME russ: is this necessary? pinMode(pinANALOG1, INPUT); pinMode(pinANALOG2, INPUT); // set all pins low digitalWriteFast(pinRESP, 0); digitalWriteFast(pinINCP, 0); digitalWriteFast(pinRESV, 0); digitalWriteFast(pinINCV, 0); digitalWriteFast(pinINPHI, 0); //clear all chip register values clearValues(); //set up biases // TODO russ: haven't looked at what this function does setBiases(vref,nbias,aobias); // sanitize this input before use flagUseAmplifier=selamp ? 1:0; config=gain+(flagUseAmplifier*8)+(16); //turn chip on with config value setPointerValue(Stonyman::REG_CONFIG,config); // TODO russ: use later // return Stonyman::RC_OK; }
// chipToMatlab // This function dumps the entire contents of a Stonyman or // Hawksbill chip to the Serial monitor in a form that may be copied // into Matlab. The image is written be stored in matrix Img. void Stonyman::chipToMatlab() { unsigned char row,col,rows,cols; unsigned short val; // russ: unused //unsigned char chigh,clow; rows=cols=112; Serial.println("Img = ["); setPointerValue(Stonyman::REG_ROWSEL,0); // set row = 0 for (row=0; row<rows; ++row) { setPointerValue(Stonyman::REG_COLSEL,0); // set column = 0 for (col=0; col<cols; ++col) { // settling delay delayMicroseconds(1); // pulse amplifier if needed if (flagUseAmplifier) { pulseInphi(2); } // get data value delayMicroseconds(1); val = analogRead(pinANALOG1); // increment column incValue(1); Serial.print(val); Serial.print(" "); } setPointer(Stonyman::REG_ROWSEL); // point to row incValue(1); // increment row Serial.println(" "); } Serial.println("];"); }
// setConfig // Sets configuration register // cvdda: (1) connect vdda, always should be connected // selamp: (0) bypasses amplifier, (1) connects it // gain: amplifier gain 1-7 // EXAMPLE 1: To configure the chip to bypass the amplifier: // setConfig(0,0,1); // EXAMPLE 2: To use the amplifier and set the gain to 4: // setConfig(4,1,1); void Stonyman::setConfig(char gain, char selamp, char cvdda) { short config; config=gain+(selamp*8)+(cvdda*16); //form register value flagUseAmplifier = selamp ? 1:0; // Note that config will have the following form binary form: // 000csggg where c=cvdda, s=selamp, ggg=gain (3 bits) // Note that there is no overflow detection in the input values. setPointerValue(Stonyman::REG_CONFIG,config); }
void ArduEyeSMHClass::setBinning(short hbin,short vbin) { short hsw,vsw; switch (hbin) //horizontal binning { case 2: //downsample by 2 hsw = 0xAA; break; case 4: //downsample by 4 hsw = 0xEE; break; case 8: //downsample by 8 hsw = 0xFE; break; default: //no binning hsw = 0x00; } switch (vbin) //vertical binning { case 2: //downsample by 2 vsw = 0xAA; break; case 4: //downsample by 4 vsw = 0xEE; break; case 8: //downsample by 8 vsw = 0xFE; break; default: //no binning vsw = 0x00; } //set switching registers setPointerValue(SMH_SYS_HSW,hsw); setPointerValue(SMH_SYS_VSW,vsw); }
void ArduEyeSMHClass::setConfig(char gain, char selamp, char cvdda) { short config=gain+(selamp*8)+(cvdda*16); //form register value if(selamp==1) //if selamp is 1, set useAmp variable to 1 useAmp=1; else useAmp=0; // Note that config will have the following form binary form: // 000csggg where c=cvdda, s=selamp, ggg=gain (3 bits) // Note that there is no overflow detection in the input values. setPointerValue(SMH_SYS_CONFIG,config); }
// setAmpGain // A friendlier version of setConfig. If amplifier gain is set to zero, amplifier is bypassed. // Otherwise the appropriate amplifier gain (range 1-7) is set. void Stonyman::setAmpGain(char gain) { short config; if((gain>0) && (gain<=Stonyman::MAX_GAIN)) //if gain is a proper value, connect amp { config=gain+8+16; //gain+(selamp=1)+(cvdda=1) flagUseAmplifier=1; //using amplifier } else //if gain is zero or outside range, bypass amp { config=16; //(cvdda=1) flagUseAmplifier=0; //bypassing amplifier } setPointerValue(Stonyman::REG_CONFIG,config); //set config register }
void ArduEyeSMHClass::setAmpGain(char gain) { short config; if((gain>0)&&(gain<8)) //if gain is a proper value, connect amp { config=gain+8+16; //gain+(selamp=1)+(cvdda=1) useAmp=1; //using amplifier } else //if gain is zero or outside range, bypass amp { config=16; //(cvdda=1) useAmp=0; //bypassing amplifier } setPointerValue(SMH_SYS_CONFIG,config); //set config register }
// setBiases // Sets all three biases void Stonyman::setBiases(short vref,short nbias,short aobias) { setPointerValue(Stonyman::REG_NBIAS,nbias); setPointerValue(Stonyman::REG_AOBIAS,aobias); setPointerValue(Stonyman::REG_VREF,vref); }
void ArduEyeSMHClass::setNBIAS(short nbias) { setPointerValue(SMH_SYS_NBIAS,nbias); }
// setAOBIAS // Sets the AOBIAS register value (0-63) void Stonyman::setAOBIAS(short aobias) { setPointerValue(Stonyman::REG_AOBIAS,aobias); }
// setNBIAS // Sets the NBIAS register value (0-63) void Stonyman::setNBIAS(short nbias) { setPointerValue(Stonyman::REG_NBIAS,nbias); }
void ArduEyeSMHClass::setAOBIAS(short aobias) { setPointerValue(SMH_SYS_AOBIAS,aobias); }
ValueLineEdit::ValueLineEdit(QWidget *parent) : QLineEdit(parent) { connect(this, SIGNAL(textEdited(QString)), this, SLOT(setPointerValue(QString))); }
void ArduEyeSMHClass::clearValues(void) { for (char i=0; i!=8; ++i) setPointerValue(i,0); //set each register to zero }
void ArduEyeSMHClass::setBiases(short vref,short nbias,short aobias) { setPointerValue(SMH_SYS_NBIAS,nbias); setPointerValue(SMH_SYS_AOBIAS,aobias); setPointerValue(SMH_SYS_VREF,vref); }
void ArduEyeSMHClass::getImageColSum(short *img, unsigned char rowstart, unsigned char numrows, unsigned char rowskip, unsigned char colstart, unsigned char numcols, unsigned char colskip, char ADCType,char anain) { short *pimg = img; // pointer to output image array short val,total=0; unsigned char chigh,clow; unsigned char row,col; if(ADCType==SMH1_ADCTYPE_ONBOARD) //if using onboard ADC setAnalogInput(anain); //set analog input to Arduino else if(ADCType==SMH1_ADCTYPE_MCP3201_2) { setAnalogInput(anain); ADC_SS_PORT |= ADC_SS; // make sure SS is high } else //if using external ADC { setADCInput(anain,1); // enable chip ADC_SS_PORT |= ADC_SS; // make sure SS is high } // Go to first col setPointerValue(SMH_SYS_COLSEL,colstart); // Loop through all cols for (col=0; col<numcols; ++col) { // Go to first row setPointerValue(SMH_SYS_ROWSEL,rowstart); total=0; // Loop through all rows for (row=0; row<numrows; ++row) { // settling delay delayMicroseconds(1); // pulse amplifier if needed if (useAmp) pulseInphi(2); // get data value delayMicroseconds(1); // get pixel value from ADC switch (ADCType) { case SMH1_ADCTYPE_ONBOARD: //onboard Arduino ADC val = analogRead(anain); // acquire pixel break; case SMH1_ADCTYPE_MCP3001: // Micrchip 10 bit ADC_SS_PORT &= ~ADC_SS; // turn SS low to start conversion chigh=SPI.transfer(0); // get high byte clow=SPI.transfer(0); // get low byte val = ((short)(chigh&0x1F))<<5; val += (clow&0xF8)>>3; ADC_SS_PORT |= ADC_SS; // SS high to stop break; case SMH1_ADCTYPE_MCP3201: // Microchip 12 bit case SMH1_ADCTYPE_MCP3201_2: ADC_SS_PORT &= ~ADC_SS; // turn SS low to start conversion chigh=SPI.transfer(0); // get high byte clow=SPI.transfer(0); // get low byte val = ((short)(chigh&0x1F))<<7; val += (clow&0xFE)>>1; ADC_SS_PORT |= ADC_SS; // SS high to stop break; default: val = 555; break; } total+=val; //sum value along column incValue(rowskip); // go to next row } *pimg = total>>4; // store pixel pimg++; // advance pointer setPointer(SMH_SYS_COLSEL); incValue(colskip); // go to next col } if((ADCType!=SMH1_ADCTYPE_ONBOARD)&&(ADCType!=SMH1_ADCTYPE_MCP3201_2)) setADCInput(anain,0); // disable chip }
void ArduEyeSMHClass::setVREF(short vref) { setPointerValue(SMH_SYS_VREF,vref); }
void ArduEyeSMHClass::findMax(unsigned char rowstart, unsigned char numrows, unsigned char rowskip, unsigned char colstart, unsigned char numcols,unsigned char colskip, char ADCType,char anain,unsigned char *max_row, unsigned char *max_col) { unsigned short maxval=5000,minval=0,val; unsigned char row,col,bestrow,bestcol; unsigned char chigh,clow; if(ADCType==SMH1_ADCTYPE_ONBOARD) //if using onboard ADC setAnalogInput(anain); //set Arduino analog input else { setADCInput(anain,1); // enable chip ADC_SS_PORT |= ADC_SS; // make sure SS is high } // Go to first row setPointerValue(SMH_SYS_ROWSEL,rowstart); // Loop through all rows for (row=0; row<numrows; ++row) { // Go to first column setPointerValue(SMH_SYS_COLSEL,colstart); // Loop through all columns for (col=0; col<numcols; ++col) { // settling delay delayMicroseconds(1); // pulse amplifier if needed if (useAmp) pulseInphi(2); // get data value delayMicroseconds(1); // get pixel from ADC switch (ADCType) { case SMH1_ADCTYPE_ONBOARD: //onboard Arduino ADC val = analogRead(anain); // acquire pixel break; case SMH1_ADCTYPE_MCP3001: // Micrchip 10 bit ADC_SS_PORT &= ~ADC_SS; // turn SS low to start conversion chigh=SPI.transfer(0); // get high byte clow=SPI.transfer(0); // get low byte val = ((short)(chigh&0x1F))<<5; val += (clow&0xF8)>>3; ADC_SS_PORT |= ADC_SS; // SS high to stop break; case SMH1_ADCTYPE_MCP3201: // Microchip 12 bit ADC_SS_PORT &= ~ADC_SS; // turn SS low to start conversion chigh=SPI.transfer(0); // get high byte clow=SPI.transfer(0); // get low byte val = ((short)(chigh&0x1F))<<7; val += (clow&0xFE)>>1; ADC_SS_PORT |= ADC_SS; // SS high to stop break; default: val = 555; break; } if(useAmp) //amplifier is inverted { if (val>minval) //find max val (bright) { bestrow=row; bestcol=col; minval=val; } } else //unamplified { if (val<maxval) //find min val (bright) { bestrow=row; bestcol=col; maxval=val; } } incValue(colskip); // go to next column } setPointer(SMH_SYS_ROWSEL); incValue(rowskip); // go to next row } if(ADCType!=SMH1_ADCTYPE_ONBOARD) setADCInput(anain,0); // disable chip // Optionally we can comment out these next three items //Serial.print("bestrow = "); Serial.println((short)bestrow); //Serial.print("bestcol = "); Serial.println((short)bestcol); //Serial.print("maxval = "); Serial.println((short)maxval); *max_row = bestrow; *max_col = bestcol; }
// setVREF // Sets the VREF register value (0-63) void Stonyman::setVREF(short vref) { setPointerValue(Stonyman::REG_VREF,vref); }
void ArduEyeSMHClass::chipToMatlab(char whichchip,char ADCType, char anain) { unsigned char row,col,rows,cols; unsigned short val; unsigned char chigh,clow; if(ADCType==SMH1_ADCTYPE_ONBOARD) //if onboard ADC setAnalogInput(anain); //set analog input else { setADCInput(anain,1); // enable chip ADC_SS_PORT |= ADC_SS; // make sure SS is high } if (whichchip==1) { rows=cols=136; //hawksbill } else { rows=cols=112; //stonyman } Serial.println("Img = ["); setPointerValue(SMH_SYS_ROWSEL,0); // set row = 0 for (row=0; row<rows; ++row) { setPointerValue(SMH_SYS_COLSEL,0); // set column = 0 for (col=0; col<cols; ++col) { // settling delay delayMicroseconds(1); // pulse amplifier if needed if (useAmp) pulseInphi(2); // get data value delayMicroseconds(1); // get pixel from ADC switch (ADCType) { case SMH1_ADCTYPE_ONBOARD: val = analogRead(anain); // acquire pixel break; case SMH1_ADCTYPE_MCP3001: // Micrchip 10 bit ADC_SS_PORT &= ~ADC_SS; // turn SS low to start conversion chigh=SPI.transfer(0); // get high byte clow=SPI.transfer(0); // get low byte val = ((short)(chigh&0x1F))<<5; val += (clow&0xF8)>>3; ADC_SS_PORT |= ADC_SS; // SS high to stop break; case SMH1_ADCTYPE_MCP3201: // Microchip 12 bit ADC_SS_PORT &= ~ADC_SS; // turn SS low to start conversion chigh=SPI.transfer(0); // get high byte clow=SPI.transfer(0); // get low byte val = ((short)(chigh&0x1F))<<7; val += (clow&0xFE)>>1; ADC_SS_PORT |= ADC_SS; // SS high to stop break; default: val = 555; break; } // increment column incValue(1); Serial.print(val); Serial.print(" "); } setPointer(SMH_SYS_ROWSEL); // point to row incValue(1); // increment row Serial.println(" "); } Serial.println("];"); if(ADCType!=SMH1_ADCTYPE_ONBOARD) setADCInput(anain,0); // disable chip }
void ArduEyeSMHClass::sectionToMatlab(unsigned char rowstart, unsigned char numrows, unsigned char rowskip, unsigned char colstart, unsigned char numcols, unsigned char colskip, char ADCType, unsigned char anain) { short val; unsigned char row,col; unsigned char clow,chigh; if(ADCType==SMH1_ADCTYPE_ONBOARD) //if onboard ADC setAnalogInput(anain); else { setADCInput(anain,1); // enable chip ADC_SS_PORT |= ADC_SS; // make sure SS is high } Serial.println("Img = ["); setPointerValue(SMH_SYS_ROWSEL,rowstart); for (row=0; row<numrows; row++) { setPointerValue(SMH_SYS_COLSEL,colstart); for (col=0; col<numcols; col++) { // settling delay delayMicroseconds(1); // pulse amplifier if needed if (useAmp) pulseInphi(2); delayMicroseconds(1); // get pixel from ADC switch (ADCType) { case SMH1_ADCTYPE_ONBOARD: val = analogRead(anain); // acquire pixel break; case SMH1_ADCTYPE_MCP3001: // Micrchip 10 bit ADC_SS_PORT &= ~ADC_SS; // turn SS low to start conversion chigh=SPI.transfer(0); // get high byte clow=SPI.transfer(0); // get low byte val = ((short)(chigh&0x1F))<<5; val += (clow&0xF8)>>3; ADC_SS_PORT |= ADC_SS; // SS high to stop break; case SMH1_ADCTYPE_MCP3201: // Microchip 12 bit ADC_SS_PORT &= ~ADC_SS; // turn SS low to start conversion chigh=SPI.transfer(0); // get high byte clow=SPI.transfer(0); // get low byte val = ((short)(chigh&0x1F))<<7; val += (clow&0xFE)>>1; ADC_SS_PORT |= ADC_SS; // SS high to stop break; default: val = 555; break; } incValue(colskip); Serial.print(val); Serial.print(" "); } setPointer(SMH_SYS_ROWSEL); incValue(rowskip); // go to next row Serial.println(" "); } Serial.println("];"); if(ADCType!=SMH1_ADCTYPE_ONBOARD) setADCInput(anain,0); // disable chip }