Advertisement
Guest User

Untitled

a guest
Aug 13th, 2013
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.69 KB | None | 0 0
  1. /* Arduino active sonar with metal detector style buzzer response */
  2.  
  3. // Libraries, external functions
  4. #include <NewPing_mod.h>
  5. #include <EEPROM_Int_ReadWrite>
  6.  
  7. // Configuration constants
  8. const unsigned int BAUD_RATE = 9600; // Serial communication rate (Bd)
  9. const unsigned int STATUS_PIN = 13; // Pin identifier of internal LED
  10. const unsigned int BUZZ_PIN = 12; // Pin identifier of buzzer output
  11. const unsigned int SONAR_TRIG_PIN = 7; // Pin identifier of sonar output (can be the same as echo pin)
  12. const unsigned int SONAR_ECHO_PIN = 8; // Pin identifier of sonar input (can be the same as trigger pin)
  13. const unsigned int BUZZ_LENGTH = 80; // Duration of a buzz (ms)
  14. const unsigned int PULSE_LENGTH = 10; // Duration of outgoing trigger signal (us)
  15. const unsigned int PULSE_SAMPLES = 1; // Number of sonar pulses to take a statistical mean from (potentially interferes with buzz timing at high frequencies)
  16. const unsigned int PULSE_SKIP = 3; // Number of measurements to discard from start of execution, because the initial responses are off sometimes
  17. const unsigned int PULSE_DELAY = 500; // Amount of time between sonar queries (ms)
  18. const unsigned int MAX_DISTANCE = 900; // Maxium distance to probe for (cm)
  19. const unsigned int LOW_DISTANCE = 5 * US_ROUNDTRIP_CM; // Response time corresponding to a solid tone (us)
  20. const unsigned int HIGH_DISTANCE = 350 * US_ROUNDTRIP_CM; // Response time corresponding to highest buzz delay (us)
  21. const unsigned int MAX_BUZZ_DELAY = 5000; // Buzz delay to use with highest distance (ms)
  22. const unsigned int MIN_BUZZ_DELAY = 150; // Buzz delay to use with lowest distance (ms)
  23. const signed int RECORD_ADDR = 0; // Use this EEPROM address (occupies 2 bytes) to save maximum measured distance (negative value to disable)
  24. const bool BUZZ_ENABLED = true; // Use the buzzer to report distance metal detector style
  25. const bool STATUS_ENABLED = true; // Use the status led in addition to / instead of buzzer beeps
  26.  
  27. // Internal constants and variables
  28. const float DISTANCE_RANGE = HIGH_DISTANCE - LOW_DISTANCE; // Range in which to vary buzz delay (us)
  29. const unsigned int BUZZ_DELAY_RANGE = MAX_BUZZ_DELAY - MIN_BUZZ_DELAY; // Range of values for buzz delay (ms)
  30. unsigned long buzzDelay = 0; // Delay between buzzes (ms)
  31. unsigned long lastBuzz = 1; // Historical timestamp of most recent buzz (ms)
  32. unsigned long nextPulse = 1; // Timestamp for next sonar pulse (ms)
  33. unsigned long pulseCount = 0; // Number of queries performed from start of execution
  34. unsigned int recordDistance = 0; // Highest distance measured (us)
  35. NewPing sonar(SONAR_TRIG_PIN, SONAR_ECHO_PIN, MAX_DISTANCE); // NewPing sonar interface
  36.  
  37. void setup() {
  38.  
  39.  // Set up output pins
  40.  pinMode(STATUS_PIN, OUTPUT);
  41.  pinMode(BUZZ_PIN, OUTPUT);
  42.  
  43.  // Make sure outputs are low
  44.  digitalWrite(STATUS_PIN, LOW);
  45.  digitalWrite(BUZZ_PIN, LOW);
  46.  
  47.  // Start serial connection
  48.  Serial.begin(BAUD_RATE);
  49.  
  50.  // Read and report current record
  51.  if (RECORD_ADDR > -1) {
  52.   recordDistance = EEPROMReadInt(RECORD_ADDR);
  53.   if (recordDistance > 0xFF00) recordDistance = 0; // Reset uninitialized or faulty value
  54.    Serial.print("Current record is ");
  55.    outputDistance(recordDistance);
  56.    Serial.println();
  57.  }
  58.  
  59. }
  60.  
  61. void loop() {
  62.  
  63.  // Read current Arduino timestamp
  64.  unsigned long arduinoTime = millis();
  65.  
  66.  // Start a new buzz (solid tone)
  67.  if (buzzDelay == 1 && digitalRead(BUZZ_PIN) == LOW) {
  68.    startBuzz();
  69.    
  70.  // Start a new buzz (single beep)
  71.  } else if (buzzDelay != 0 && arduinoTime > lastBuzz + buzzDelay) {
  72.    
  73.     startBuzz();
  74.    
  75.     // Schedule the buzz end and next buzz
  76.     NewPing::timer_ms(BUZZ_LENGTH, stopBuzz);
  77.     lastBuzz = arduinoTime;
  78.      
  79.   }
  80.  
  81.  // Query the ultrasonic sensor
  82.  if (nextPulse != 0 && arduinoTime > nextPulse) {
  83.  
  84.   // Read and filter the sensor data
  85.   unsigned int responseTime = sonar.ping_median(PULSE_SAMPLES);
  86.  
  87.   // Update pulse count and proceed only if high enough
  88.   if (++pulseCount > PULSE_SKIP) {
  89.  
  90.     // Report values to the serial port
  91.     Serial.print("Measured ");
  92.     outputDistance(responseTime);
  93.     Serial.print(" (");
  94.     Serial.print(pulseCount);
  95.     Serial.println(")");
  96.    
  97.     // Update and report record
  98.    if (RECORD_ADDR > -1 && responseTime > recordDistance) {
  99.      recordDistance = responseTime;
  100.      EEPROMWriteInt(RECORD_ADDR, responseTime);
  101.      Serial.print("Wrote new record to ROM: ");
  102.      outputDistance(recordDistance);
  103.      Serial.println();
  104.    }
  105.    
  106.     // Adjust buzz timing
  107.     boolean solidTone = (buzzDelay == 1);
  108.     if (responseTime == 0) {
  109.      buzzDelay = 0;
  110.     } else {
  111.      if (responseTime <= LOW_DISTANCE) {
  112.        buzzDelay = 1;
  113.      }
  114.      if (responseTime > LOW_DISTANCE && responseTime <= HIGH_DISTANCE) {
  115.       buzzDelay = (responseTime - LOW_DISTANCE) / DISTANCE_RANGE * BUZZ_DELAY_RANGE + MIN_BUZZ_DELAY;
  116.      }
  117.      if (responseTime > HIGH_DISTANCE) {
  118.       buzzDelay = MAX_BUZZ_DELAY;
  119.      }
  120.     }
  121.     if (solidTone && buzzDelay != 1) stopBuzz();
  122.  
  123.   } else {
  124.      Serial.print("Skipped measurement ");
  125.      Serial.println(pulseCount);
  126.   }
  127.  
  128.   // Schedule the next pulse
  129.   nextPulse = arduinoTime + PULSE_DELAY;
  130.  
  131.  }
  132.  
  133. }
  134.  
  135. // Activate buzzer
  136. void startBuzz() {
  137.   if (BUZZ_ENABLED) digitalWrite(BUZZ_PIN, HIGH);
  138.   if (STATUS_ENABLED) digitalWrite(STATUS_PIN, HIGH);
  139. }
  140.  
  141. // Stop an ongoing buzz
  142. void stopBuzz() {
  143.   digitalWrite(BUZZ_PIN, LOW);
  144.   digitalWrite(STATUS_PIN, LOW);
  145.   NewPing::timer_stop();
  146. }
  147.  
  148. // Output response time in human-readable format
  149. void outputDistance(int responseTime) {
  150.   Serial.print(responseTime);
  151.   Serial.print(' ');
  152.   Serial.write(181); // Micro sign in ISO-8859-1
  153.   Serial.print("s / ");
  154.   Serial.print(sonar.convert_cm(responseTime));
  155.   Serial.print(" cm");
  156. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement