/////////////////////////////////////////////////////////////////////////
//// TEST2.C ////
//// ////
//// This program scans eight sensors connected to (8) a/d inputs ////
//// and generates MIDI note on/off commands. Two pushbuttons are ////
//// used for ?????? ////
//// A value is displayed as hex on a 2-digit 7-segment readout. ////
//// Written for the PIC-16C74 chip, using Custom Computer Systems' ////
//// C-Compiler. ////
//// 23 FEB 97 ////
/////////////////////////////////////////////////////////////////////////

#include <16C74.H>

#fuses HS,NOPROTECT,NOWDT

#define HOLD_OFF 500
#define PEAK20 25
#define PEAK40 38
#define PEAK50 50
#define PEAK60 55

#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use fast_io(e)
#use delay(clock=20000000)
#use rs232(baud=31250,xmit=PIN_C6,rcv=PIN_C7)

/* DEFINE EQUATES FOR PORTS */

#byte PORTA = 5
#byte PORTB = 6
#byte PORTC = 7
#byte PORTD = 8
#byte PORTE = 9


/* Bit pattern for PortB to display hex characters: */

char const HEX_TABLE_B[16]={0xE0, 0xFC, 0xD2, 0xD8, 0xCC, 0xC9, 0xC1, 0xFC
0xC0, 0xC8, 0xC4, 0xC1, 0xE3, 0xD0, 0xC3, 0xC7};

/* Bit pattern for PortD to display hex characters: */

char const HEX_TABLE_D[16]={0x40, 0xC0, 0x40, 0x40, 0xc0, 0x40, 0x40, 0x40
0x40, 0x40, 0x40, 0xC0, 0x40, 0xC0, 0x40, 0x40};


main() {

unsigned action, i, value, softtime, dispval;
unsigned peak0, peak1, peak2, peak3;
unsigned peak4, peak5, peak6, peak7;
long swbonk1, swbonk2;
long wait0, wait1, wait2, wait3;
long wait4, wait5, wait6, wait7;
long avg0, avg1, avg2, avg3;
long avg4, avg5, avg6, avg7;

disable_interrupts(GLOBAL);

setup_port_a( ALL_ANALOG );
setup_adc( ADC_CLOCK_DIV_32 );
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_1);
set_tris_a( 0XFF ); /* ALL INPUTS FOR a/d CONVERTER */
set_tris_b( 0X00 ); /* ALL OUTPUTS */
set_tris_c( 0X9F ); /* c0-4, 7 = INPUT, c5, 6 = OUTPUT */
set_tris_d( 0X3F ); /* d0-5 = INPUT, d6, 7 = OUTPUT */
set_tris_e( 0X07 ); /* e0-2 = INPUT (ONLY 3 PINS AVAILABLE */

output_high(PIN_C5);
delay_ms(10);
output_low(PIN_C5);
action=0;
peak0=0;
peak1=0;
wait0=0;
wait1=0;

do {
if (action !=0) goto act1;
avg0=0;
avg1=0;
for (i=0; i<8; i++)
{
set_adc_channel( 0 );
delay_us(20);
value = Read_ADC();
if (value < 0x7F) value = 0x7F - value;
if (value >= 0x7F) value-=0x7F;
avg0+=value;

set_adc_channel( 1 );
delay_us(20);
value = Read_ADC();
if (value < 0x7F) value = 0x7F - value;
if (value >= 0x7F) value-=0x7F;
avg1+=value;

set_adc_channel( 2 );
delay_us(20);
value = Read_ADC();
if (value < 0x7F) value = 0x7F - value;
if (value >= 0x7F) value-=0x7F;
avg2+=value;

set_adc_channel( 3 );
delay_us(20);
value = Read_ADC();
if (value < 0x7F) value = 0x7F - value;
if (value >= 0x7F) value-=0x7F;
avg3+=value;

set_adc_channel( 4 );
delay_us(20);
value = Read_ADC();
if (value < 0x7F) value = 0x7F - value;
if (value >= 0x7F) value-=0x7F;
avg4+=value;

set_adc_channel( 5 );
delay_us(20);
value = Read_ADC();
if (value < 0x7F) value = 0x7F - value;
if (value >= 0x7F) value-=0x7F;
avg5+=value;

set_adc_channel( 6 );
delay_us(20);
value = Read_ADC();
if (value < 0x7F) value = 0x7F - value;
if (value >= 0x7F) value-=0x7F;
avg6+=value;

set_adc_channel( 7 );
delay_us(20);
value = Read_ADC();
if (value < 0x7F) value = 0x7F - value;
if (value >= 0x7F) value-=0x7F;
avg7+=value;

}

avg0 /=8;
avg1 /=8;
avg2 /=8;
avg3 /=8;
avg4 /=8;
avg5 /=8;
avg6 /=8;
avg7 /=8;

if ((avg0 > peak0) && (avg0>10)) /* REACHED A LOCAL MAXIMA? */
{
putc(0x99);
putc(0x2E);
peak0=avg0;
putc(peak0);
wait0=50;
if (peak0 > 20) wait0=PEAK20;
if (peak0 > 40) wait0=PEAK40;
if (peak0 > 50) wait0=PEAK50;
if (peak0 > 60) wait0=PEAK60;
}
if (wait0==1)peak0=0;
if (wait0 !=0) wait0--;

if ((avg1 > peak1) && (avg1>10)) /* REACHED A LOCAL MAXIMA? */
{
putc(0x99);
putc(0x2F);
peak1=avg1;
putc(peak1);
wait1=50;
if (peak1 > 20) wait1=PEAK20;
if (peak1 > 40) wait1=PEAK40;
if (peak1 > 50) wait1=PEAK50;
if (peak1 > 60) wait1=PEAK60;
}
if (wait1==1) peak1=0;
if (wait1 !=0) wait1--;

if ((avg2 > peak2) && (avg2>10)) /* REACHED A LOCAL MAXIMA? */
{
putc(0x99);
putc(0x30);
peak2=avg2;
putc(peak2);
wait2=50;
if (peak2 > 20) wait2=PEAK20;
if (peak2 > 40) wait2=PEAK40;
if (peak2 > 50) wait2=PEAK50;
if (peak2 > 60) wait2=PEAK60;
}
if (wait2==1) peak2=0;
if (wait2 !=0) wait2--;

if ((avg3 > peak3) && (avg3>10)) /* REACHED A LOCAL MAXIMA? */
{
putc(0x99);
putc(0x31);
peak3=avg3;
putc(peak3);
wait3=50;
if (peak3 > 20) wait3=PEAK20;
if (peak3 > 40) wait3=PEAK40;
if (peak3 > 50) wait3=PEAK50;
if (peak3 > 60) wait3=PEAK60;
}
if (wait3==1) peak3=0;
if (wait3 !=0) wait3--;

if ((avg4 > peak4) && (avg4>10)) /* REACHED A LOCAL MAXIMA? */
{
putc(0x99);
putc(0x23);
peak4=avg4;
putc(peak4);
wait4=50;
if (peak4 > 20) wait4=PEAK20;
if (peak4 > 40) wait4=PEAK40;
if (peak4 > 50) wait4=PEAK50;
if (peak4 > 60) wait4=PEAK60;
}
if (wait4==1) peak4=0;
if (wait4 !=0) wait4--;

if ((avg5 > peak5) && (avg5>10)) /* REACHED A LOCAL MAXIMA? */
{
putc(0x99);
putc(0x25);
peak5=avg5;
putc(peak5);
wait5=50;
if (peak5 > 20) wait5=PEAK20;
if (peak5 > 40) wait5=PEAK40;
if (peak5 > 50) wait5=PEAK50;
if (peak5 > 60) wait5=PEAK60;
}
if (wait5==1) peak5=0;
if (wait5 !=0) wait5--;

if ((avg6 > peak6) && (avg6>10)) /* REACHED A LOCAL MAXIMA? */
{
putc(0x99);
putc(0x27);
peak6=avg6;
putc(peak6);
wait6=50;
if (peak6 > 20) wait6=PEAK20;
if (peak6 > 40) wait6=PEAK40;
if (peak6 > 50) wait6=PEAK50;
if (peak6 > 60) wait6=PEAK60;
}
if (wait6==1) peak6=0;
if (wait6 !=0) wait6--;

if ((avg7 > peak7) && (avg7>10)) /* REACHED A LOCAL MAXIMA? */
{
putc(0x99);
putc(0x36);
peak7=avg7;
putc(peak7);
wait7=50;
if (peak7 > 20) wait7=PEAK20;
if (peak7 > 40) wait7=PEAK40;
if (peak7 > 50) wait7=PEAK50;
if (peak7 > 60) wait7=PEAK60;
}
if (wait7==1) peak7=0;
if (wait7 !=0) wait7--;


dispval=peak0;
if (!(PORTD & 0x10)) action=1; /* READ PUSHBUTTON #1 */
if (!(PORTD & 0x20)) peak0=0; /* READ PUSHBUTTON #2 */
goto display;

act1: set_adc_channel( 0 );
delay_us(20);
value = Read_ADC();
if (value < 0x7F) value = 0x7F - value;
if (value >= 0x7F) value-=0x7F;
if (( value > dispval )&&( wait0==0 ))
{
putc(0x99);
putc(0x2E);
if (value < (dispval + 5)) putc(0x1F);
if (value >= (dispval + 5)) putc(0x7F);
wait0=HOLD_OFF;
}
if( wait0 !=0 ) wait0--;

/* READ PUSHBUTTON #1: */

if (PORTD & 0x10) swbonk1=30;
if ((!(PORTD & 0x10)) && (swbonk1 == 1))
{
putc(0x99);
putc(dispval);
putc(0x7F);
dispval++;
swbonk1=5000;
}
if ((!(PORTD & 0x10)) && (swbonk1 != 0)) swbonk1--;

/* READ PUSHBUTTON #2: */

if (PORTD & 0x20) swbonk2=30;
if ((!(PORTD & 0x20)) && (swbonk2 == 1))
{
dispval--;
swbonk2=1000;
}
if ((!(PORTD & 0x20)) && (swbonk2 != 0)) swbonk2--;


/* SEND dispval TO THE DIGITAL DISPLAY... */

display: softtime++;
output_high(PIN_B6); /* PREVENT GHOSTING */
output_high(PIN_B7); /* PREVENT GHOSTING */
switch (softtime & 0x01) /* MUX ALT DIGIT EACH TIME */
{
case 0 : i=HEX_TABLE_D[dispval & 0x0F];
PORTD = i;
i=HEX_TABLE_B[dispval & 0x0F];
PORTB = i & 0x7F; /* PB7=0 TO ENABLE LO DIG */
break;
case 1 : i=HEX_TABLE_D[dispval >> 4];
PORTD = i;
i=HEX_TABLE_B[dispval >> 4];
PORTB = i & 0xBF; /* PB6=0 TO ENABLE HI DIG */
break;
}
} while (TRUE);
}