/********************************************************************** ULTRASONIC RANGE FINDER Code by lingib Last update 5 April 2018 This code uses the task scheduler described in https://www.instructables.com/id/Multi-task-Your-Arduino/ to control the transmitter pulse rate. ---------- COPYRIGHT ---------- This code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License. If not, see . ***************************************************************************/ // ------------------------------ // definitions // ------------------------------ // ----- arduino pinouts #define Trig 12 #define Echo 11 // ----- task scheduler int TaskTimer1 = 0; //task 1 (see ISR(TIMER2_COMPA_vect) bool TaskFlag1 = false; //flag 1 // ----- results float Distance; // ------------------------------ // setup // ------------------------------ void setup() { // ----- configure serial port Serial.begin(115200); // ----- configure arduino pinouts pinMode(Echo, INPUT); //make Echo pin an input pinMode(Trig, OUTPUT); //set Trig pin LOW digitalWrite(Trig, LOW); // ----- configure Timer 2 to generate a compare-match interrupt every 1mS noInterrupts(); //disable interrupts TCCR2A = 0; //clear control registers TCCR2B = 0; TCCR2B |= (1 << CS22) | //16MHz/128=8uS (1 << CS20) ; TCNT2 = 0; //clear counter OCR2A = 125 - 1; //8uS*125=1mS (allow for clock propagation) TIMSK2 |= (1 << OCIE2A); //enable output compare interrupt interrupts(); //enable interrupts } // ------------------------------ // loop() // ------------------------------ void loop() { // ----- measure distance once per second if (TaskFlag1) { TaskFlag1 = false; measure(); Serial.print("Distance: "); Serial.print(Distance); Serial.println(" cm"); } } // ------------------------------- // task scheduler (1mS interrupt) // ------------------------------- ISR(TIMER2_COMPA_vect) { // ----- timers TaskTimer1++; //task 1 timer // ----- task1 if (TaskTimer1 > 49) //50mS interval between pings { TaskTimer1 = 0; //reset timer TaskFlag1 = true; //signal loop() to perform task } } // ------------------------------- // measure distance // ------------------------------- void measure() { // ----- locals long start_time; //microseconds long finish_time; //microseconds long time_taken; //microseconds // ----- generate 10uS start pulse digitalWrite(Trig,HIGH); delayMicroseconds(10); digitalWrite(Trig,LOW); /* * At this point the transducer will emit 8 x 25uS pulses approx 400uS * after the Trig pulse has finished and raise the Echo pin HIGH. * * The Echo line goes LOW: * - on receipt of an ech0 * - after approx 40mS if no echo * * Distance = (high level timeƗvelocity of sound (340m/s) / 2. * An approximate formula is: pulse-width(uS)/58= distance (cm). */ while (!digitalRead(Echo)); //wait for Echo pin to go high start_time = micros(); while (digitalRead(Echo)); //wait for Echo pin to go low finish_time = micros(); time_taken = finish_time - start_time; Distance = ((float)time_taken)/57.5; }