// // // hello.button.45.c // // button hello-world // 9600 baud FTDI interface // // Neil Gershenfeld // 10/31/10 // // (c) Massachusetts Institute of Technology 2010 // Permission granted for experimental and personal use; // license for commercial sale available from MIT. // #include #include #define output(directions,pin) (directions |= pin) // set port direction for output #define input(directions,pin) (directions &= (~pin)) // set port direction for input #define set(port,pin) (port |= pin) // set port pin #define clear(port,pin) (port &= (~pin)) // clear port pin #define pin_test(pins,pin) (pins & pin) // test for port pin #define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set #define bit_delay_time 100 // bit delay for 9600 with overhead #define bit_delay() _delay_us(bit_delay_time) // RS232 bit delay #define half_bit_delay() _delay_us(bit_delay_time/2) // RS232 half bit delay #define char_delay() _delay_ms(10) // char delay #define serial_port PORTA #define serial_direction DDRA #define serial_pin (1 << PA1) #define sonar_transmit_port PORTA #define sonar_transmit_direction DDRA #define sonar_transmit_pin (1 << PA7) #define sonar_receive_pos_port PORTA #define sonar_receive_pos_direction DDRA #define sonar_receive_pos_pin (1 << PA2) #define sonar_receive_neg_port PORTA #define sonar_receive_neg_direction DDRA #define sonar_receive_neg_pin (1 << PA3) #define test_port PORTA #define test_direction DDRA #define test_pin (1 << PA6) void put_char(volatile unsigned char *port, unsigned char pin, char txchar) { // // send character in txchar on port pin // assumes line driver (inverts bits) // // start bit // clear(*port,pin); bit_delay(); // // unrolled loop to write data bits // if bit_test(txchar,0) set(*port,pin); else clear(*port,pin); bit_delay(); if bit_test(txchar,1) set(*port,pin); else clear(*port,pin); bit_delay(); if bit_test(txchar,2) set(*port,pin); else clear(*port,pin); bit_delay(); if bit_test(txchar,3) set(*port,pin); else clear(*port,pin); bit_delay(); if bit_test(txchar,4) set(*port,pin); else clear(*port,pin); bit_delay(); if bit_test(txchar,5) set(*port,pin); else clear(*port,pin); bit_delay(); if bit_test(txchar,6) set(*port,pin); else clear(*port,pin); bit_delay(); if bit_test(txchar,7) set(*port,pin); else clear(*port,pin); bit_delay(); // // stop bit // set(*port,pin); bit_delay(); // // char delay // bit_delay(); } int main(void) { // // main // char char_low, char_high; //should be unsigned unsigned int value = 0; unsigned short i = 0, sensor_value; // set clock divider to /1 // CLKPR = (1 << CLKPCE); CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0); // // initialize pins // //init Serial set(serial_port, serial_pin); output(serial_direction, serial_pin); //init Sonar transmit clear(sonar_transmit_port, sonar_transmit_pin); output(sonar_transmit_direction, sonar_transmit_pin); //init Sonar receiver_pos set(sonar_receive_pos_port, sonar_receive_pos_pin); input(sonar_receive_pos_direction, sonar_receive_pos_pin); //init Sonar receiver_neg set(sonar_receive_neg_port, sonar_receive_neg_pin); input(sonar_receive_neg_direction, sonar_receive_neg_pin); //init Test port clear(test_port, test_pin); output(test_direction, test_pin); // // init A/D // ADMUX = (1 << REFS1) | (0 << REFS0) // 1.1v ref | (0 << MUX5) | (1 << MUX4) | (0 << MUX3) | (0 << MUX2) | (0 << MUX1) | (1 << MUX0); // POS:PA2 NEG:PA3 with 20x ADCSRA = (1 << ADEN) // enable // | (1 << ADPS2) | (0 << ADPS1) | (1 << ADPS0); // prescaler /32 // | (1 << ADPS2) | (0 << ADPS1) | (0 << ADPS0); // prescaler /18 | (0 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // prescaler /8 BEST // | (0 << ADPS2) | (1 << ADPS1) | (0 << ADPS0); // prescaler /4 dies here.. ADCSRB |= (0 << ADLAR); // right adjust // ADCSRB |= (1 << ADLAR); // right adjust // // main loop // while (1) { clear(test_port, test_pin); //Send out signal for( i = 0; i < 10; i++){ set(sonar_transmit_port, sonar_transmit_pin); _delay_us(12.5); clear(sonar_transmit_port, sonar_transmit_pin); _delay_us(12.5); } //how much delay to pass the first wave of noise resonance //this was finly tuned _delay_us(1750); //1500 sensor_value = 0; //can be seen as your window of looking for( i = 0; i < 1000; i++){ // initiate conversion ADCSRA |= (1 << ADSC); // wait for completion while (ADCSRA & (1 << ADSC)) ; // get result char_low = ADCL; char_high = ADCH; value = ((unsigned int)char_high<<8) + ((unsigned int)char_low); //threshold value which was finely tuned if(value < 500){ //last time 150 set(test_port, test_pin); sensor_value = i; break; }else{ clear(test_port, test_pin); } } // Signal is in the variable i which we broke out of before char_low = (unsigned char)(sensor_value & 0xff); char_high = (unsigned char)(sensor_value>>8 & 0xff); // // Send framing out to serial put_char(&serial_port, serial_pin, 1); put_char(&serial_port, serial_pin, 2); put_char(&serial_port, serial_pin, 3); put_char(&serial_port, serial_pin, 4); // Send result out to serial put_char(&serial_port, serial_pin, char_low); put_char(&serial_port, serial_pin, char_high); //Delay needed to move past the first ringing responses _delay_us(7500); } }