/* * File: Impedance Analyzer * Author: Rachel Helguero, Jessica Lee, Heather Lukas for ECE 4760 * For use with Sean Carroll's Small Board * Target PIC: PIC32MX250F128B */ //////////////////////////////////// // clock AND protoThreads configure #include "config.h" // threading library #include "pt_cornell_1_2_1.h" #include "i2c_helper.h" #include "math.h" //////////////////////////////////// #define timer_limit 40000 //1ms //===== Pull-up resistors ======== #define EnablePullUpB(bits) CNPDBCLR = bits; CNPUBSET = bits; #define EnablePullUpA(bits) CNPDACLR = bits; CNPUASET = bits; //==== AD5933 Register Addresses ====== #define Control_high 0x80 //Control register high bits #define Control_low 0x81 //Control register low bits #define Start_Freq_high 0x82 //initial starting frequency high bits #define Start_Freq_mid 0x83 //initial starting frequency mid bits #define Start_Freq_low 0x84 //initial starting frequency low bits #define Frq_Incr_high 0x85 //frequency increment #define Frq_Incr_mid 0x86 #define Frq_Incr_low 0x87 #define NumInc_high 0x88 //number of increments #define NumInc_low 0x89 #define Num_Stime_high 0x8A //settling time #define Num_Stime_low 0x8B #define Status 0x8F //Status register #define Temp_high 0x92 //temperature check #define Temp_low 0x93 #define Real_high 0x94 //Impedance Real value high bits #define Real_low 0x95 //Impedance Real value low bits #define Imag_high 0x96 //Imaginary value high bits #define Imag_low 0x97 //Imaginary value low bits #define FSCK 400000 #define PBCLK 40000000 #define PGD 0.000000104 #define BRG_VAL 0x02C //values from table on ECE 4760 website #define IMP_LOG_SIZE 5 //Size of Impedance Array #define gain 6340500 //Gain for Magnitude Impedance Calculation // Impedance real and imaginary struct impedance{ volatile int real; volatile int imaginary; }; struct impedance imp_log[IMP_LOG_SIZE]; //Array for 30kHz to 80kHz with 5 step sweep struct impedance imp_log_sweep[IMP_LOG_SIZE*2]; //Array for 10kHz to 100kHz with 17 step sweep volatile int i = 0; char buffer[60]; volatile unsigned char ctrl_hi; volatile unsigned char value1 =0x0; volatile unsigned char value2 =0x0; // flags for impedance sweep volatile int sweep_stat = 0; //Status if sweep has finished volatile int dft_stat = 1; //Status if one impedance dft calculation has finished volatile int stop = 0; // Used to stop and re-run a sweep volatile int start = 0; // Turn on after initial sweep set-up //Hex value 0x0F5C28 = 30kHz start frequency volatile unsigned char start_freq_data1 = 0x0F; volatile unsigned char start_freq_data2 = 0x5C; volatile unsigned char start_freq_data3 = 0x28; //Hex value 0x051EB8 = 10kHz increment frequency volatile unsigned char freq_incr_data1 = 0x5; volatile unsigned char freq_incr_data2 = 0x1E; volatile unsigned char freq_incr_data3 = 0xB8; //numerical increment -- 5 increments volatile unsigned char num_incr_data1 = 0x0; volatile unsigned char num_incr_data2 = 0x5; //Control commands -- found in data sheet volatile unsigned char init_start_freq_control = 0x10; //Command to start freq volatile unsigned char init_start_freq; volatile unsigned char start_sweep_control = 0x20; //Command to start sweep volatile unsigned char start_sweep; volatile unsigned char increment_control = 0x30; //Command to increment to next freq volatile unsigned char increment; volatile unsigned char power_down = 0xA0; //Command to power down volatile unsigned char set_time1 = 0x0; //Settling time mode 1: 0 volatile unsigned char set_time2 = 0x0a; //Settling time mode 2: 10 //=== Variables for Impedance Average === volatile int sum = 0; volatile int avg = 0; int loop_idx = 10; //loop index for averaging volatile float ble_tx_val = 0; //value sent to Bluetooth static int press;//variable boolean in state machine volatile int mode=1; //mode indicated by buttons int change=0; //flags change in mode from button press int decrement=0; //flag for Dotstar decrement int num = 0; volatile float finIMP; volatile float phase; // === thread structures ============================================ // thread control structs static struct pt pt_timer, pt_imp, pt_uart, pt_dotstar; static struct pt pt_input, pt_DMA_output ; //==== DotStar Setup================================================= #define START_FRAME 0x00000000 #define STOP_FRAME 0xffffffff #define PIXEL_FRAME(i,r,g,b)(0xe0000000 | (((0x1f & (i)))<<24) | ((0xff & (b))<<16) | ((0xff & (g))<<8) | (0xff & (r))) #define FULL_ON 0x1e #define HALF_ON 0x0f #define QUAR_ON 0x07 // number of pixels #define PixelNum 144 #define rowLength 33 // pixel r,g,b,intensity struct typedef struct pixel pixel; struct pixel{ char red; char green; char blue; char intensity; }; int position=0, dir=1; volatile int ADC_value; volatile float ADC_scaled; volatile char pos; volatile char blink =0; // and the whole string pixel pixel_array[PixelNum]; // === End Dotstar Declarations =========================================== // === Function: display the LEDs =========================================== // copies the contents of pixel_array to SPI void write_pixels(void){ // start frame WriteSPI2(START_FRAME); // wait for end of transaction while (SPI2STATbits.SPIBUSY); int i; //payload for (i=0; i=PixelNum) return ; // hsv to rgb conversion from // http://www.rapidtables.com/convert/color/hsv-to-rgb.htm C = v * s; //X = C * (1 - abs((int)(h/60)%2 - 1)); X = C * (1.0 - fabsf(fmodf(h/60.0, 2.0) - 1.)); m = v - C; if ((0<=h) && (h<60)) { rp = C; gp = X; bp = 0;} else if ((60<=h) && (h<120)) { rp = X; gp = C; bp = 0;} else if ((120<=h) && (h<180)){ rp = 0; gp = C; bp = X;} else if ((180<=h) && (h<240)){ rp = 0; gp = X; bp = C;} else if ((240<=h) && (h<300)){ rp = X; gp = 0; bp = C;} else if ((300<=h) && (h<360)){ rp = C; gp = 0; bp = X;} else { rp = 0; gp = 0; bp = 0;} r = (unsigned char)((rp+m)*255) ; g = (unsigned char)((gp+m)*255) ; b = (unsigned char)((bp+m)*255) ; pixel_array[i].intensity = intensity ; //enforce max pixel_array[i].red = r ; pixel_array[i].green = g ; pixel_array[i].blue = b ; } char rowNum(int k){ //Reads in pixel index and determines which row of the teardrop the pixel lies in; if not in teardrop display, return 0 char r =0; if(k==23){ r=1;} else if(k>54&&k<58){ r=2;} else if(k>86&&k<92){ r=3;} else if(k>120&&k<124){ r=4;} return r; } //Read buttons and change mode if button pressed void readButton(int button){ if(button==1){ press= mPORTAReadBits(BIT_3); } else if(button==2){ press = mPORTBReadBits(BIT_13); } else if(button==3){ press = mPORTBReadBits(BIT_7); } if(!press){ mode=button; } } // no ISR was used in this project void __ISR(_TIMER_2_VECTOR, ipl2) Timer2Handler(void) { mT2ClearIntFlag(); } //===================Dotstar thread================= static PT_THREAD (protothread_dotstar(struct pt *pt)){ PT_BEGIN(pt); static int i ; static float h, s, v, m[256]; static char r,g,b,intensity,rows; while(1) { if(mode!=2){ if(mode==3){ if(decrement==1){ ADC_scaled=245; decrement = 0; } else if(ADC_scaled<-30){ mode=1; change=1; } else{ //ADC_scaled=245; ADC_scaled--; } } else if(mode==1){ // read the impedance value ADC_scaled = 245 - ((avg -300)*245.0/400); } h=ADC_scaled; if(ADC_scaled>184){//light up all 4 rows if(ADC_scaled>245){//out of range value renders as blue h = 245; } rows=4; } else if(ADC_scaled>123){//light up 3 rows rows=3; } else if(ADC_scaled>61){//light up 2 rows rows=2; } else if(ADC_scaled>0){//light up 1 row rows=1; } else{// and set to flash every second h = 0;//out of range value renders as red rows=0; } for(i=0; i