Evaluation by the Save our Water, Watershed Hydrologic Analysis Team, Marion Waggoner and Dave Yake.
Background
Broad Run drains a 10 km2 watershed straddling southeastern Pennsylvania and northwest Delaware. Commercial groundwater withdrawal from the aquifer underlying the Broad Run watershed has been approved, but questions about the effect of this withdrawal on Broad Run flow and water quality remain. To address these questions, our organization (Save Our Water) started a stream monitoring program on Broad Run in late 2014.
Our primary objective was to establish a baseline of stream discharge throughout the year that could be used to evaluate the effect of commercial pumping when it begins.
We used an acoustic doppler velocimeter (ADV) to measure the velocity of water flow and calculate discharge. We then developed a stream rating curve to relate water stage (depth, an easy-to-continuously-measure parameter) to water discharge (volume per time, a more difficult to measure parameter but more relevant to our objective).
Our rating curve allows us to continuously predict water discharge from water stage. Multiple rating curves were developed at several locations with particular emphasis on the low flow periods because these periods are when the effect of commercial pumping from the aquifer is expected to be most apparent.
Real-time continuous data from New Garden Township’s EnviroDIY monitoring station allows us to convert stream depth measurements to discharge using our rating curve, but this site is upstream from the commercial well. We needed additional stream flow data from further downstream but did not have money for a submerged pressure (depth) sensor.
We decided to evaluate the Maxbotix ultrasonic sensors for possible monitoring of baseflow stream levels.
Equipment List and Setup
- Mayfly Data Logger with 5-minute logging intervals
- Maxbotix HRXL-MaxSonar-WRM (MB7389) sensor
- Maxbotix HR-Maxtemp-795 sensor
- Onset HOBO Water Level Logger U20-001-04
- DHT11 temperature and humidity sensor
- Arduino IDE and a sketch provided by Shannon Hicks at Stroud Water Research Center (code provided below).
We selected the MB7389 sensor for distance resolution and weather resistance. We initially tested just one sensor but added another when unexpected issues surfaced.
The MB7389 sensors were tested by pointing them downward at a stationary dry target. In the stream, sensors were mounted on standpipes and, later, on a boom extending over open water. We limited the standpipe diameter to 4 inches because a larger standpipe would have been too disruptive to flow in a small stream and would catch lots of debris.
Reviewing the Results
The Positives
Delivers stable data: The two sensors delivered very stable distance data on test stands indoors — stationary plates as targets — at a constant ambient temperature. Generally, over many hours and at a distance near 1 meter, the values varied only about +/- 1 to 2 millimeters.
Functionally impeccable: Both sensors continued to function after extensive time outdoors in operation at temperatures from below 0 degrees Celsius to as high as 39 degrees Celsius.
Extremely rugged: One sensor was washed away during a huge flood on August 7, 2020. A couple of days later we found the sensor and the mounting washed up on the bank in a pile of debris. In spite of the prolonged immersion, the sensor was completely functional and still very accurate.
Remarkable performance: After mounting the sensors over open air above the water, one sensor has operated for nine months, taking ten data points (for averaging) at each 5 minute interval, without returning a single “bad” data value. This is remarkable performance compared to the earlier erratic problems with “bad” data when mounted in standpipes.
Low cost: The sensors cost about $125 each.
Very good depth change performance: During a runoff event where the temperature changes are minor, the Maxbotix sensor delivers very good depth change performance as illustrated in the chart below. At peak flow there is about a 21 millimeter average difference between the Maxbotix and Onset Depth sensors out of a 370 millimeter rise in depth (or about 5.7%). The Onset depth sensor was located on the side of a large stake and could have detected some depth depression at higher peak flow compared to the Maxbotix which was located 2 feet downstream where there was less surface turbulence. Therefore, the 5.7% difference at peak flow is likely a real detected difference in stream depth. Overall, when the Maxbotix is used to measure stream surface height changes using a boom configuration performance is excellent. However, using the Maxbotix as an absolute measure of distance is complicated by a strong temperature variance bias.
The Negatives
“Bad” distance data: When mounted in standpipes, the Maxbotix MB7389 sensors sometimes delivered “bad” distance data — generating values of 300 millimeters when the range was much larger than 300. On rare occasions, the distances might be intermediate between 300 and the real value. Note that these MB7389 sensors are not very accurate below 500 millimeters (50 centimeters) but range well out to about 5 meters. The lower cutoff is approximately 300 millimeters.
We noted that the “bad” data seemed to occur at times when the temperature was dropping and believe that the issue was condensation on the walls of the standpipes. Therefore, the situation should have improved when we insulated the exterior of the standpipes with bubble wrap (would not waterlog) which was over-wrapped with foil. Unfortunately, this helped only marginally. The “bad” data might occur for a single interval or might occur for many consecutive intervals for long time periods (up to a few hours).
We tried adding delays between startup and taking data (to allow the sensor to stabilize) and start to average/integrate distances with built-in software. No improvement was seen.
We had to go to a boom mount of the sensor in open air to eliminate bad data.
Whether mounted over a standpipe or boom-mounted in open air in a stable test stand at a fixed distance to the target, the sensors show large changes in reported distances (as much as +/- 1 centimeter or more) with normal ambient temperature cycling. In fact, we observed this in three conditions:
- Using the sensor’s internal temperature monitor/ correction for temperature.
- Using the Maxbotix external temperature sensor for temperature compensation.
- Attempting to correlate the Maxbotix temperature compensated data with either the Mayfly board temperature or a DHT temperature and % RH sensor. Those results will be discussed along with data in the next section.
Test Data versus Temperature
The issue with temperature seen with the MB7389 sensors is well illustrated in the three figures below. The results are from a stable test stand outdoor mounting over a stationary plate target when the weather was warm/sunny days and cooler nights. The MB7389 was equipped with the Maxbotix external temperature sensor (HR-Maxtemp sensor) which was mounted in the shade under the logger box. The logger box was covered with foil to minimize solar heating of the logger box interior.
Note the +/- spread of the distance data above at any given temperature and % RH. (Click on an image to enlarge.)
A “Multiple Regression Analysis” of the distance vs. Mayfly board temperature or DHT temperature, and percent relative humidity delivered a root squared error the same as using only board temperature: 37%. As would be expected from theory, the relative humidity has very low significance.
Conclusions
- If used in a boom mounting to eliminate issues associated with condensation inside standpipes, the MB7389 sensors reliably deliver distance data over a wide temperature range and other weather conditions. Furthermore, the sensor delivered excellent stream depth change performance because the temperature change during the rain event and runoff was minor.
- In spite of using the Maxbotix external temperature sensor for better temperature compensation, the distance data (fixed test stand) vary significantly with changes in ambient temperature — as much as +/- 1 centimeter or more. It is questionable whether the Maxbotix temperature compensation software can be considered worthwhile since the same results were seen for both ultrasonic sensors.
- Work to correlate the distance changes with other measures of temperature (Mayfly board temperature or an independent temperature as from the DHT digital temperature and humidity sensor) could account for at most 40% of the changes.
- We recommend careful consideration of these results before deploying these sensors if the objective is to have an absolute measure of depth/distance. However, the sensor is excellent for measuring changes in depth over a time frame where the temperature is not changing significantly.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 |
#include <SoftwareSerial_PCINT12.h> #include <Sodaq_PcInt_PCINT0.h> //sketch to log sonar data on Mayfly //this one can use digital pin intermittent power or continuous power from board +rail //or a battery pack to power Maxbotix //serialSonar begin and end empty buffer between each read so all data is new each time //this also solves problems with the interrupts not allowing sleep code #include <Wire.h> #include <avr/sleep.h> #include <avr/wdt.h> #include <SPI.h> #include <SdFat.h> SdFat SD; #include <RTCTimer.h> #include <Sodaq_DS3231.h> SoftwareSerial sonarSerial(11, -1); boolean stringComplete = false; #define READ_DELAY 1 //RTC Timer RTCTimer timer; String dataRec = ""; int currentminute; long currentepochtime = 0; float boardtemp = 0.0; int batteryPin = A6; // select the input pin for the potentiometer int batterysenseValue = 0; // variable to store the value coming from the sensor float batteryvoltage; int range_mm1; int range_mm2; int range_mm3; int range_mm4; int range_mm5; int range_mm6; int range_mm7; int range_mm8; int range_mm9; int range_mm10; int range_mm; int attempts; int average_mm; int total; //RTC Interrupt pin #define RTC_PIN A7 #define RTC_INT_PERIOD EveryMinute #define SD_SS_PIN 12 //The data log file #define FILE_NAME "SonicLog.txt" //Data header #define LOGGERNAME "Ultrasonic Maxbotix Sensor Datalogger" #define DATA_HEADER "DateTime,Loggertime,BoardTemp,Battery_V,SonarRange_mm 1 to 10" void setup() { rtc.begin(); delay(100); pinMode(8, OUTPUT); pinMode(9, OUTPUT); pinMode(10, OUTPUT); greenred4flash(); //blink the LEDs to show the board is on setupLogFile(); //Setup timer events setupTimer(); //Setup sleep mode setupSleep(); ///Serial.println("Power On, running: ultrasonic_logger_example_1.ino"); ///Serial.println("Power On, running: ultrasonic_logger_example_1.ino"); digitalWrite(8, HIGH); digitalWrite(10, HIGH); stringComplete = false; delay(5000);//wait for board to stabilize sonarSerial.begin(9600); range_mm = SonarRead();//does not add data to a string, included only for debugging sonarSerial.end(); attempts = 0; if (range_mm <= 300 || range_mm >= 2000 ) { do { sonarSerial.begin(9600); delay (250); range_mm = SonarRead(); stringComplete = false; attempts++; sonarSerial.end(); delay (50); } while (attempts <21 && (range_mm == 300 || range_mm == 0)); } average_mm = range_mm; //sets initial average for trapping on first reading digitalWrite(10, LOW); digitalWrite(8,LOW); delay (1000);//added to show blink of led before loop. } void loop() { //Update the timer timer.update(); if(currentminute % 5 == 0) { digitalWrite(8, HIGH); dataRec = createDataRecord(); stringComplete = false; delay(100); digitalWrite(10, HIGH);//turns on power to sonar delay(10000);//wait 10 sec for sonar to stabilize after startup sonarSerial.begin(9600);//open to allow data from sonar to enter input serial buffer //also clears buffer of old data delay(250); range_mm1 = SonarRead(); stringComplete = false; sonarSerial.end();//closes serial and stops input to buffer delay(50); attempts = 0; if (range_mm1 <= 300 || range_mm1 >= 2000 ) { do { sonarSerial.begin(9600); delay (250); range_mm1 = SonarRead(); stringComplete = false; attempts++; sonarSerial.end(); delay (50); } while (attempts <11 && (range_mm1 <= 300 || range_mm1 >= 2000)); } delay (200); sonarSerial.begin(9600); delay(250); range_mm2 = SonarRead(); stringComplete = false; sonarSerial.end(); attempts = 0; delay(50); if (range_mm2 <= 300 || range_mm2 >= 2000 ) { do { sonarSerial.begin(9600); delay (250); range_mm2 = SonarRead(); stringComplete = false; sonarSerial.end(); attempts++; delay (50); } while (attempts <11 && (range_mm2 <= 300 || range_mm2 >= 2000)); } delay (200); sonarSerial.begin(9600); delay(250); range_mm3 = SonarRead(); stringComplete = false; sonarSerial.end(); delay(50); attempts = 0; if (range_mm3 <= 300 || range_mm3 >= 2000 ) { do { sonarSerial.begin(9600); delay(250); range_mm3 = SonarRead(); stringComplete = false; sonarSerial.end(); attempts++; delay (50); } while (attempts <11 && (range_mm3 <= 300 || range_mm3 >= 2000)); } delay (200); sonarSerial.begin(9600); delay (250); range_mm4 = SonarRead(); stringComplete = false; sonarSerial.end(); attempts = 0; delay (50); if (range_mm4 <= 300 || range_mm4 >= 2000 ) { do { sonarSerial.begin(9600); delay(250); range_mm4 = SonarRead(); stringComplete = false; sonarSerial.end(); attempts++; delay (50); } while (attempts <11 && (range_mm4 <= 300 || range_mm4 >= 2000)); } delay (200); sonarSerial.begin(9600); delay (250); range_mm5 = SonarRead(); stringComplete = false; sonarSerial.end(); delay(50); attempts = 0; if (range_mm5 <= 300 || range_mm5 >= 2000 ) { do { sonarSerial.begin(9600); delay(250); range_mm5 = SonarRead(); stringComplete = false; sonarSerial.end(); attempts++; delay (50); } while (attempts <11 && (range_mm5 <= 300 || range_mm5 >= 2000)); } delay (200); sonarSerial.begin(9600); delay(250); range_mm6 = SonarRead(); stringComplete = false; sonarSerial.end(); delay(50); attempts = 0; if (range_mm6 <= 300 || range_mm6 >= 2000 ) { do { sonarSerial.begin(9600); delay(250); range_mm6 = SonarRead(); stringComplete = false; sonarSerial.end(); attempts++; delay (50); } while (attempts <11 && (range_mm6 <= 300 || range_mm6 >= 2000)); } delay (200); sonarSerial.begin(9600); delay(250); range_mm7 = SonarRead(); stringComplete = false; sonarSerial.end(); delay(50); attempts = 0; if (range_mm7 <= 300 || range_mm7 >= 2000 ) { do { sonarSerial.begin(9600); delay(250); range_mm7 = SonarRead(); stringComplete = false; sonarSerial.end(); attempts++; delay (50); } while (attempts <11 && (range_mm7 <= 300 || range_mm7 >= 2000)); } delay (200); sonarSerial.begin(9600); delay(250); range_mm8 = SonarRead(); stringComplete = false; sonarSerial.end(); delay(50); attempts = 0; if (range_mm8 <= 300 || range_mm8 >= 2000 ) { do { sonarSerial.begin(9600); delay(250); range_mm8 = SonarRead(); stringComplete = false; sonarSerial.end(); attempts++; delay (50); } while (attempts <11 && (range_mm8 <= 300 || range_mm8 >= 2000)); } delay (200); sonarSerial.begin(9600); delay(250); range_mm9 = SonarRead(); stringComplete = false; sonarSerial.end(); delay(50); attempts = 0; if (range_mm9 <= 300 || range_mm9 >= 2000 ) { do { sonarSerial.begin(9600); delay(250); range_mm9 = SonarRead(); stringComplete = false; sonarSerial.end(); attempts++; delay (50); } while (attempts <11 && (range_mm9 <= 300 || range_mm9 >= 2000)); } delay (200); sonarSerial.begin(9600); delay(250); range_mm10 = SonarRead(); stringComplete = false; sonarSerial.end(); delay(50); attempts = 0; if (range_mm10 <= 300 || range_mm10 >= 2000 ) { do { sonarSerial.begin(9600); delay(250); range_mm10 = SonarRead(); stringComplete = false; sonarSerial.end(); attempts++; delay (50); } while (attempts <11 && (range_mm10 <= 300 || range_mm10 >= 2000)); } delay (100); digitalWrite(8, LOW); digitalWrite(10, LOW); //following records ten data reads. dataRec += ","; dataRec += range_mm1; dataRec += ","; dataRec += range_mm2; dataRec += ","; dataRec += range_mm3; dataRec += ","; dataRec += range_mm4; dataRec += ","; dataRec += range_mm5; dataRec += ","; dataRec += range_mm6; dataRec += ","; dataRec += range_mm7; dataRec += ","; dataRec += range_mm8; dataRec += ","; dataRec += range_mm9; dataRec += ","; dataRec += range_mm10; if (range_mm1 <= 300 || range_mm1 >= 2000) { range_mm1 = average_mm; } if (range_mm2 <= 300 || range_mm2 >= 2000) { range_mm2 = average_mm; } if (range_mm3 <= 300 || range_mm3 >= 2000) { range_mm3 = average_mm; } if (range_mm4 <= 300 || range_mm4 >= 2000) { range_mm4 = average_mm; } if (range_mm5 <= 300 || range_mm5 >= 2000) { range_mm5 = average_mm; } if (range_mm6 <= 300 || range_mm6 >= 2000) { range_mm6 = average_mm; } if (range_mm7 <= 300 || range_mm7 >= 2000) { range_mm7 = average_mm; } if (range_mm8 == 300 || range_mm8 >= 2000) { range_mm8 = average_mm; } if (range_mm9 <= 300 || range_mm9 >= 2000) { range_mm9 = average_mm; } if (range_mm10 <= 300 || range_mm10 >= 2000) { range_mm10 = average_mm; } total = (range_mm1 + range_mm2 + range_mm3 + range_mm4 + range_mm5 + range_mm6 + range_mm7 + range_mm8 + range_mm9 + range_mm10); average_mm = (total/10); dataRec += ",avg= "; dataRec+= average_mm; //Save the data record to the log file logData(dataRec); //Echo the data to the serial connection //Serial.println(); //Serial.print("Data Record: "); //Serial.println(dataRec); String dataRec = ""; } systemSleep(); } void showTime(uint32_t ts) { //Retrieve and display the current date/time String dateTime = getDateTime(); //Serial.println(dateTime); } void setupTimer() { //Schedule the wakeup every minute timer.every(READ_DELAY, showTime); //Instruct the RTCTimer how to get the current time reading timer.setNowCallback(getNow); } void wakeISR() { //Leave this blank } void setupSleep() { pinMode(RTC_PIN, INPUT_PULLUP); PcInt::attachInterrupt(RTC_PIN, wakeISR); //Setup the RTC in interrupt mode rtc.enableInterrupts(RTC_INT_PERIOD); //Set the sleep mode set_sleep_mode(SLEEP_MODE_PWR_DOWN); } void systemSleep() { //Wait until the serial ports have finished transmitting Serial.flush(); Serial1.flush(); //The next timed interrupt will not be sent until this is cleared rtc.clearINTStatus(); //Disable ADC ADCSRA &= ~_BV(ADEN); //Sleep time noInterrupts(); sleep_enable(); interrupts(); sleep_cpu(); sleep_disable(); //Enbale ADC ADCSRA |= _BV(ADEN); } String getDateTime() { String dateTimeStr; //Create a DateTime object from the current time DateTime dt(rtc.makeDateTime(rtc.now().getEpoch())); currentepochtime = (dt.get()); //Unix time in seconds currentminute = (dt.minute()); //Convert it to a String dt.addToString(dateTimeStr); return dateTimeStr; } uint32_t getNow() { currentepochtime = rtc.now().getEpoch(); return currentepochtime; } void greenred4flash() { for (int i=1; i <= 4; i++){ digitalWrite(8, HIGH); digitalWrite(9, LOW); delay(50); digitalWrite(8, LOW); digitalWrite(9, HIGH); delay(50); } digitalWrite(9, LOW); } void setupLogFile() { // initialize the SD card at SPI_FULL_SPEED for best performance. // try SPI_HALF_SPEED if bus errors occur. if (!SD.begin(SD_SS_PIN, SPI_HALF_SPEED)) { SD.initErrorHalt(); } //Check if the file already exists bool oldFile = SD.exists(FILE_NAME); //Open the file in write mode File logFile = SD.open(FILE_NAME, FILE_WRITE); //Add header information if the file did not already exist if (!oldFile) { logFile.println(LOGGERNAME); logFile.println(DATA_HEADER); } //Close the file to save it logFile.close(); } void logData(String rec) { //Re-open the file File logFile = SD.open(FILE_NAME, FILE_WRITE); //Write the CSV data logFile.println(rec); //Close the file to save it logFile.close(); } String createDataRecord() { //Create a String type data record in csv format //TimeDate, Loggertime,Temp_DS, Diff1, Diff2, boardtemp String data = getDateTime(); data += ","; rtc.convertTemperature(); //convert current temperature into registers boardtemp = rtc.getTemperature(); //Read temperature sensor value batterysenseValue = analogRead(batteryPin); batteryvoltage = (3.3/1023.) * (12.7/2.7) * batterysenseValue; data += currentepochtime; data += ","; addFloatToString(data, boardtemp, 3, 1); //float data += ","; addFloatToString(data, batteryvoltage, 4, 2); return data; } static void addFloatToString(String & str, float val, char width, unsigned char precision) { char buffer[10]; dtostrf(val, width, precision, buffer); str += buffer; } int SonarRead() { int result; char inData[5]; //char array to read data into int index = 0; while (sonarSerial.read() != -1) {} while (stringComplete == false) { if (sonarSerial.available()) { char rByte = sonarSerial.read(); //read serial input for "R" to mark start of data if(rByte == 'R') { //Serial.println("rByte set"); while (index < 4) //read next three character for range from sensor { if (sonarSerial.available()) { delay(50); inData[index] = sonarSerial.read(); //Serial.println(inData[index]); //Debug line index++; // Increment where to write next } } inData[index] = 0x00; //add a padding byte at end for atoi() function } rByte = 0; //reset the rByte ready for next reading index = 0; // Reset index ready for next reading stringComplete = true; // Set completion of read to true result = atoi(inData); // Changes string data into an integer for use } } return result; } |
Thankyou so much for doing such detailed work. I’d been thinking of a boom situation for some measurements. However the atmospheric temperature will vary.
Great work guys. We are also interested in these sensors and have also been considering a boom-type setup.
I think it might be worth getting one of these to see if it’s fit for our purpose.
Hey Dave,
As part of my technical institute’s graduation requirements, I’m currently designing a project to test the accuracy of MaxBotix’s sensors (as well as a $75 vented pressure transducer) to determine their applicability for streamflow monitoring. I’m also a hydrometric tech so do put a lot of thought into collecting accurate data.
With that said, I do have a couple of thoughts to consider in regards to how your test was designed.
Here they are in point form for brevity’s sake:
Anyhow, I don’t mean to be a downer. I basically just listed these points as I’ll be critiquing your work in a literature review as part of my project.
Really though I think it’s great that you’ve gone to all this work to test the sensor. I learned a few ideas from reading this that I’ll be incorporating into my tests.
Give me a shout at gallaugher.consulting@gmail.com if you are up to chatting about your tests and helping me to design mine.
Rory,
I have copied the comments from our email so that others can view them… thanks again.
dave
With respect to the barometric pressure: a. Pressure sensor for depth: Remember that we are compensating for barometric pressure changes in the Onset logger by having a parallel sensor following barometric pressure. Not sure he understood that. b. Also, with respect to the ultrasonic sensor, the barometric pressure has a very minimal effect on the speed of sound in air. Marion remembers that it is 2 orders of magnitude below the effect of both temperature and relative humidity (which is much lower than the temp effect.) So, really the only important effect is the temperature effect on speed of sound.
We discarded using the ultrasonic sensor on a stilling well due to the signal dropouts which were somewhat erratic as to when they occurred, but clearly were connected to temp changes from high to low which induced some kind of condensation on the walls (that caused deflection of the wave). Similarly, we actually dispensed with the stilling well on the Onset depth logger just for convenience. So, stilling well experience is not something where got comparison data. The Final result comparisons were not data from stilling wells..
We don’t believe your comments about the metal boom having a significant impact on correct. If you calculate the change in dimension for a uniform metal (ie..
no bimetallic effect) that is heated on only one side (eg. sun) while the other side is cool (shady side) then you can see that the metal is much less than wood. For example, CTE’s for metal will run around 1 * 10**-5 while wood will be at least 10X higher. Still, neither will show much bending with temperature differentials that we see in outside testing. That said, however, it is a concern for planned experiments, and easy to manually measure the separate distance from the boom to the target over the temp range..
We would be interested in your results if/when available…. In particular, it would be helpful to see what the temperature effect (water temp) has on a pressure sensor logger (such as the Onset or the CTD sensor used in the Stroud logger stations..
Hi David,
Just to follow up on your comments, and then provide the report that I wrapped up last month where I tested the Maxbotix sensor.
Just a quick reply to each comment here:
1) yep, definitely understand that barometric pressure is only relevant to the pressure transducer and that the ultrasonic sensor is mostly affected by air temp.
2) stilling well placement is finicky, and so thought I would just comment on that. It’s not where I would have placed the well but to each their own.
3) Interesting to learn that wood would bend more than metal. I had not done the calculations but was told by Water Survey Canada that they accidentally collected errored water level data because they had an ultrasonic sensor on a metal boom that fluctuated with temp.
I should mention too that my comments were in preparation for a literature review that I was preparing for my report. There isn’t much material available on the accuracy of Maxbotix sensors, and so was overly critical of what I did find to show my professors that I have my own thoughts on the current research. In reality, though I really enjoyed your work and found it quite helpful.
I’ll post my research on this blog shortly, but in the meantime, it can be downloaded at the following link:
https://drive.google.com/file/d/1TwziM5uK7JQWOxKAlAWntKWqhyg-bLit/view?usp=sharing
@Rory G I need some assistance testing my maxbotix MB-7386 and I posted my issues in the forum…can you please assist?