#include //#include #include //I like these definitions #define begin { #define end } #define t1 200 //Valve cycle time #define t2 100 #define t3 400 //State machine state names - Debouncer #define NoPush 1 #define MaybePush 2 #define Pushed 3 #define MaybeNoPush 4 #define int2fix(a) (((int)(a))<<8) #define fix2int(a) ((signed char)((a)>>8)) #define float2fix(a) ((int)((a)*256.0)) #define fix2float(a) ((float)(a)/256.0) #define N_WAVE 16 /* size of FWT */ #define LOG2_N_WAVE 4 /* log2(N_WAVE) */ int fwt_t1, fwt_t2; //FWT State #define Single 1 //Find max sequency - 1 valve on per cycle #define Multi 2 //Valve on if pass threshold int ain1[N_WAVE], ain0[N_WAVE] ; //double buffer inputs char countISR, Nbuffer; //Nbuffer keeps track of which buffer is in use unsigned char State; unsigned int timer, debtime, time3; unsigned char PushFlag1, PushFlag2, PushFlag3; //message indicating a button push unsigned char PushState1, PushState2, PushState3; //state machine //reordering tables flash char reorder16[16] = {0,15,7,8,3,12,4,11,1,14,6,9,2,13,5,10}; //======================================================== void FWTfix(int x[]) // This routine does foward transform only //output is in dyadic order -- see web links //use FWTreorder() to put the transform in sequency order begin unsigned char ii, k, j, i, bb, st; bb = N_WAVE/2; st = N_WAVE; // for (i=1; i>1 ; //scale to keep fixed pt in range fwt_t2 = x[ii+bb] >>1 ; x[ii] = fwt_t1 + fwt_t2 ; // x[ii+bb] = fwt_t1 - fwt_t2 ; end end bb = bb>>1 ; st = st>>1 ; end end //======================================================== void FWTreorder(int x[], flash char r[]) //converts from dyadic order to sequency order -- see references begin char i,j; int xp[N_WAVE]; for (i=0; i0) timer--; if(debtime>0) debtime--; if(time3>0) time3--; if (countISR < N_WAVE) begin if (Nbuffer) ain1[countISR] = (ADCH *2); else ain0[countISR] = (int)(ADCH *2) ; //start a/d converter ADCSR.6 = 1; //update ISR counter countISR++; //PORTB = ~PORTB; end end //======================================================== void debounce1(void) //button for switching modes begin debtime=t2; //reset the task timer switch (PushState1) begin case NoPush: if (~PINA.1 == 0x01) PushState1=MaybePush; else PushState1=NoPush; break; case MaybePush: if (~PINA.1 == 0x01) begin PushState1=Pushed; PushFlag1=1; end else PushState1=NoPush; break; case Pushed: if (~PINA.1 == 0x01) PushState1=Pushed; else PushState1=MaybeNoPush; break; case MaybeNoPush: if (~PINA.1 == 0x01) PushState1=Pushed; else begin PushState1=NoPush; PushFlag1=0; end break; end end //======================================================== void debounce2(void) //button for increasing threshold begin switch (PushState2) begin case NoPush: if (~PINA.2 == 0x01) PushState2=MaybePush; else PushState2=NoPush; break; case MaybePush: if (~PINA.2 == 0x01) begin PushState2=Pushed; PushFlag2=1; end else PushState2=NoPush; break; case Pushed: if (~PINA.2 == 0x01) PushState2=Pushed; else PushState2=MaybeNoPush; break; case MaybeNoPush: if (~PINA.2 == 0x01) PushState2=Pushed; else begin PushState2=NoPush; PushFlag2=0; end break; end end //======================================================== void debounce3(void) //button for decreasing threshold begin switch (PushState3) begin case NoPush: if (~PINA.3 == 0x01) PushState3=MaybePush; else PushState3=NoPush; break; case MaybePush: if (~PINA.3 == 0x01) begin PushState3=Pushed; PushFlag3=1; end else PushState3=NoPush; break; case Pushed: if (~PINA.3 == 0x01) PushState3=Pushed; else PushState3=MaybeNoPush; break; case MaybeNoPush: if (~PINA.3 == 0x01) PushState3=Pushed; else begin PushState3=NoPush; PushFlag3=0; end break; end end //======================================================== //read A/D converter // transform // PWM LEDs to make 8 channel analyser void main(void) begin unsigned char CurBuf, i, m ; int compare[8], th; //serial setup for debugging using printf, etc. UCSRB = 0x18 ; UBRRL = 103 ; //putsf("\r\nStarting...\r\n"); //set up timer0 to sample a/d at about 7800 Hz //turn on timer with period= 256*8 cycles = 2048 cycles //which implies 7812 samples/sec TCCR0 = 0b00001011; TIMSK = 2 ; OCR0 = 125; timer = t1; debtime = t2; time3 = t3; //set up a/d for external Vref, channel 0 //channel zero/ left adj /EXTERNAL Aref //!!!CONNECT Aref jumper!!!! ADMUX = 0b01100000; //enable ADC and set prescaler to 1/128*16MHz=125,000 //and clear interupt enable //and start a conversion ADCSR = 0b11000111; //initialize state to single valve State = Single; //set up PORTB/D for output DDRB=0xff; DDRD=0xff; PORTD.7=0; //initialize PortB for off (Valve Normally Open) PORTB=0xff; //initialize debounce variables PushFlag1=0; PushFlag2=0; PushFlag3=0; PushState1=NoPush; PushState2=NoPush; PushState3=NoPush; //and start the show #asm("sei") //start with buffer 0 Nbuffer = 0; //led threshold ************************************************** th=40; //initial value while(1) begin if(debtime==0) begin debtime=t2; debounce1(); debounce2(); debounce3(); end if(time3==0) begin time3=t3; if(PushFlag1) begin if(State==Single) State=Multi; else if(State==Multi) State=Single; PushFlag1=0; end //threshold can be set from 10-80 if(PushFlag2 && th<80) begin th = th + 10; PushFlag2=0; end if(PushFlag3 && th>10) begin th = th-10; PushFlag3=0; end end //when there are 16 points in buffer if (countISR == N_WAVE) begin //critical section #asm("cli") CurBuf = Nbuffer; //switch input buffers Nbuffer ^= 0x01; //reset the counter countISR = 0; #asm("sei") //end critical section //update the FWT if (CurBuf) FWTfix(ain1); else FWTfix(ain0); // sequency order if (CurBuf) FWTreorder(ain1,reorder16); else FWTreorder(ain0,reorder16); // combine sal and cal if (CurBuf) begin //omit DC in ain1[0] compare[0] = (abs(ain1[1])+abs(ain1[2])) ;//adds the cal and sal values for each sequency band compare[1] = (abs(ain1[3])+abs(ain1[4])) ; compare[2] = (abs(ain1[5])+abs(ain1[6])) ; compare[3] = (abs(ain1[7])+abs(ain1[8])) ; compare[4] = (abs(ain1[9])+abs(ain1[10])) ; compare[5] = (abs(ain1[11])+abs(ain1[12])) ; compare[6] = (abs(ain1[13])+abs(ain1[14])) ; compare[7] = (abs(ain1[15])); //highest sequency - no sal value //printf("%u\r\n",compare[7]); end else begin //omit DC compare[0] = (abs(ain0[1])+abs(ain0[2])) ;//adds the cal and sal values for each sequency band compare[1] = (abs(ain0[3])+abs(ain0[4])) ; compare[2] = (abs(ain0[5])+abs(ain0[6])) ; compare[3] = (abs(ain0[7])+abs(ain0[8])) ; compare[4] = (abs(ain0[9])+abs(ain0[10])) ; compare[5] = (abs(ain0[11])+abs(ain0[12])) ; compare[6] = (abs(ain0[13])+abs(ain0[14])) ; compare[7] = (abs(ain0[15])); //highest sequency - no sal value end if(timer == 0) begin //printf("********************************\n\r"); /*printf("compare0 %i \n\r", compare[0]); printf("compare1 %i \n\r", compare[1]); printf("compare2 %i \n\r", compare[2]); printf("compare3 %i \n\r", compare[3]); printf("compare4 %i \n\r", compare[4]); printf("compare5 %i \n\r", compare[5]); printf("compare6 %i \n\r", compare[6]); printf("compare7 %i \n\r", compare[7]); */ //printf("state %i\n\r", State); //printf("th %i\n\r", th); //printf("m %i \n\r", m); //combine threshold and max and light leds //find the maximum element m = 0; for (i=1; i<8; i++) begin if (compare[i]>compare[m]) m = i; end if (State == Single) begin if((m == 7) && (compare[7]>th)) PORTB.0 = 0; else PORTB.0 = 1; if((m == 6) && (compare[6]>th)) PORTB.1 = 0; else PORTB.1 = 1; if((m == 5) && (compare[5]>th)) PORTB.2 = 0; else PORTB.2 = 1; if((m == 4) && (compare[4]>th)) PORTB.3 = 0; else PORTB.3 = 1; if((m == 3) && (compare[3]>th)) PORTB.4 = 0; else PORTB.4 = 1; if((m == 2) && (compare[2]>th)) PORTB.5 = 0; else PORTB.5 = 1; if((m == 1) && (compare[1]>th)) PORTB.6 = 0; else PORTB.6 = 1; if((m == 0) && (compare[0]>th)) PORTB.7 = 0; else PORTB.7 = 1; end if (State == Multi) begin if((compare[7]>th)) PORTB.0 = 0; else PORTB.0 = 1; if((compare[6]>th)) PORTB.1 = 0; else PORTB.1 = 1; if((compare[5]>th)) PORTB.2 = 0; else PORTB.2 = 1; if((compare[4]>th)) PORTB.3 = 0; else PORTB.3 = 1; if((compare[3]>th)) PORTB.4 = 0; else PORTB.4 = 1; if((compare[2]>th)) PORTB.5 = 0; else PORTB.5 = 1; if((compare[1]>th)) PORTB.6 = 0; else PORTB.6 = 1; if((compare[0]>th)) PORTB.7 = 0; else PORTB.7 = 1; end timer = t1; end end end end