PX4 Firmware
PX4 Autopilot Software http://px4.io
srf02.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2013-2018 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 /**
35  * @file srf02.cpp
36  *
37  * Driver for the SRF02 sonar range finder adapted from the Maxbotix sonar range finder driver (srf02).
38  */
39 
40 #include <px4_platform_common/px4_config.h>
41 #include <px4_platform_common/defines.h>
42 #include <px4_platform_common/getopt.h>
43 #include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp>
44 #include <containers/Array.hpp>
45 
46 #include <drivers/device/i2c.h>
47 
48 #include <sys/types.h>
49 #include <stdint.h>
50 #include <stdlib.h>
51 #include <stdbool.h>
52 #include <semaphore.h>
53 #include <string.h>
54 #include <fcntl.h>
55 #include <poll.h>
56 #include <stdio.h>
57 #include <math.h>
58 #include <unistd.h>
59 
60 #include <perf/perf_counter.h>
61 
62 #include <drivers/drv_hrt.h>
65 
66 #include <uORB/uORB.h>
68 
69 #include <board_config.h>
70 
71 /* Configuration Constants */
72 #define SRF02_BASEADDR 0x70 // 7-bit address. 8-bit address is 0xE0.
73 #define SRF02_BUS_DEFAULT PX4_I2C_BUS_EXPANSION
74 #define SRF02_DEVICE_PATH "/dev/srf02"
75 
76 /* SRF02 Registers addresses */
77 #define SRF02_TAKE_RANGE_REG 0x51 // Measure range Register.
78 #define SRF02_SET_ADDRESS_0 0xA0 // Change address 0 Register.
79 #define SRF02_SET_ADDRESS_1 0xAA // Change address 1 Register.
80 #define SRF02_SET_ADDRESS_2 0xA5 // Change address 2 Register.
81 
82 /* Device limits */
83 #define SRF02_MIN_DISTANCE (0.20f)
84 #define SRF02_MAX_DISTANCE (7.65f)
85 
86 #define SRF02_CONVERSION_INTERVAL 100000 // 60ms for one sonar.
87 #define SRF02_INTERVAL_BETWEEN_SUCCESIVE_FIRES 100000 // 30ms between each sonar measurement (watch out for interference!).
88 
89 class SRF02 : public device::I2C, public px4::ScheduledWorkItem
90 {
91 public:
92  SRF02(uint8_t rotation = distance_sensor_s::ROTATION_DOWNWARD_FACING, int bus = SRF02_BUS_DEFAULT,
93  int address = SRF02_BASEADDR);
94  virtual ~SRF02();
95 
96  int init() override;
97 
98  int ioctl(device::file_t *filp, int cmd, unsigned long arg) override;
99 
100  /**
101  * Diagnostics - print some basic information about the driver.
102  */
103  void print_info();
104 
105  ssize_t read(device::file_t *filp, char *buffer, size_t buflen) override;
106 
107 protected:
108  int probe() override;
109 
110 private:
111 
112  int collect();
113 
114  int measure();
115 
116  /**
117  * Test whether the device supported by the driver is present at a
118  * specific address.
119  * @param address The I2C bus address to probe.
120  * @return True if the device is present.
121  */
122  int probe_address(uint8_t address);
123 
124  /**
125  * Perform a poll cycle; collect from the previous measurement
126  * and start a new one.
127  */
128  void Run() override;
129 
130  /**
131  * Initialise the automatic measurement state machine and start it.
132  *
133  * @note This function is called at open and error time. It might make sense
134  * to make it more aggressive about resetting the bus in case of errors.
135  */
136  void start();
137 
138  /**
139  * Stop the automatic measurement state machine.
140  */
141  void stop();
142 
143  px4::Array<uint8_t, RANGE_FINDER_MAX_SENSORS> addr_ind; // Temp sonar i2c address vector.
144 
145  bool _sensor_ok{false};
146  bool _collect_phase{false};
147 
149  int _cycling_rate{0}; // Initialize cycling rate to zero, (can differ depending on one sonar or multiple).
152 
153  uint8_t _cycle_counter{0}; // Initialize counter to zero - used to change i2c adresses for multiple devices.
154  uint8_t _index_counter{0}; // Initialize temp sonar i2c address to zero.
155  uint8_t _rotation;
156 
159 
162 
164 
165  ringbuffer::RingBuffer *_reports{nullptr};
166 };
167 
168 /*
169  * Driver 'main' command.
170  */
171 extern "C" __EXPORT int srf02_main(int argc, char *argv[]);
172 
173 SRF02::SRF02(uint8_t rotation, int bus, int address) :
174  I2C("SRF02", SRF02_DEVICE_PATH, bus, address, 100000),
175  ScheduledWorkItem(MODULE_NAME, px4::device_bus_to_wq(get_device_id())),
176  _rotation(rotation)
177 {
178 }
179 
181 {
182  // Ensure we are truly inactive.
183  stop();
184 
185  // Free any existing reports.
186  if (_reports != nullptr) {
187  delete _reports;
188  }
189 
190  if (_class_instance != -1) {
191  unregister_class_devname(RANGE_FINDER_BASE_DEVICE_PATH, _class_instance);
192  }
193 
194  // Free perf counters.
197 }
198 
199 int
201 {
202  // Read from the sensor.
203  uint8_t val[2] = {0, 0};
204  uint8_t cmd = 0x02;
206 
207  int ret = transfer(&cmd, 1, nullptr, 0);
208  ret = transfer(nullptr, 0, &val[0], 2);
209 
210  if (ret < 0) {
211  PX4_DEBUG("error reading from sensor: %d", ret);
214  return ret;
215  }
216 
217  uint16_t distance_cm = val[0] << 8 | val[1];
218  float distance_m = float(distance_cm) * 1e-2f;
219 
220  struct distance_sensor_s report;
221  report.current_distance = distance_m;
222  report.id = 0; // TODO: set proper ID.
223  report.max_distance = _max_distance;
224  report.min_distance = _min_distance;
225  report.orientation = _rotation;
226  report.signal_quality = -1;
227  report.variance = 0.0f;
228  report.timestamp = hrt_absolute_time();
229  report.type = distance_sensor_s::MAV_DISTANCE_SENSOR_ULTRASOUND;
230 
231  // Publish it, if we are the primary.
232  if (_distance_sensor_topic != nullptr) {
233  orb_publish(ORB_ID(distance_sensor), _distance_sensor_topic, &report);
234  }
235 
236  _reports->force(&report);
237 
238  // Notify anyone waiting for data.
239  poll_notify(POLLIN);
241  return PX4_OK;
242 }
243 
244 int
246 {
247  // I2C init (and probe) first.
248  if (I2C::init() != OK) {
249  return PX4_ERROR;
250  }
251 
252  // Allocate basic report buffers.
253  _reports = new ringbuffer::RingBuffer(2, sizeof(distance_sensor_s));
254 
255  _index_counter = SRF02_BASEADDR; // Set temp sonar i2c address to base adress.
256  set_device_address(_index_counter); // Set I2c port to temp sonar i2c adress.
257 
258  if (_reports == nullptr) {
259  return PX4_ERROR;
260  }
261 
262  _class_instance = register_class_devname(RANGE_FINDER_BASE_DEVICE_PATH);
263 
264  // Get a publish handle on the range finder topic.
265  struct distance_sensor_s ds_report = {};
266 
267  _distance_sensor_topic = orb_advertise_multi(ORB_ID(distance_sensor), &ds_report,
269 
270  if (_distance_sensor_topic == nullptr) {
271  PX4_ERR("failed to create distance_sensor object");
272  }
273 
274  // XXX we should find out why we need to wait 200 ms here
275  px4_usleep(200000);
276 
277  /* Check for connected rangefinders on each i2c port:
278  * We start from i2c base address (0x70 = 112) and count downwards,
279  * so the second iteration it uses i2c address 111, third iteration 110, and so on. */
280  for (unsigned counter = 0; counter <= RANGE_FINDER_MAX_SENSORS; counter++) {
281  _index_counter = SRF02_BASEADDR - counter; // Set temp sonar i2c address to base adress - counter.
282  set_device_address(_index_counter); // Set I2c port to temp sonar i2c adress.
283 
284  int ret = measure();
285 
286  if (ret == 0) {
287  // Sonar is present -> store address_index in array.
289  PX4_DEBUG("sonar added");
290  }
291  }
292 
294  set_device_address(_index_counter); // Set i2c port back to base adress for rest of driver.
295 
296  // If only one sonar detected, no special timing is required between firing, so use default.
297  if (addr_ind.size() == 1) {
299 
300  } else {
302  }
303 
304  // Show the connected sonars in terminal.
305  for (unsigned i = 0; i < addr_ind.size(); i++) {
306  PX4_DEBUG("sonar %d with address %d added", (i + 1), addr_ind[i]);
307  }
308 
309  PX4_DEBUG("Number of sonars connected: %zu", addr_ind.size());
310 
311  // Sensor is ok, but we don't really know if it is within range.
312  _sensor_ok = true;
313 
314  return PX4_OK;
315 }
316 
317 int
318 SRF02::ioctl(device::file_t *filp, int cmd, unsigned long arg)
319 {
320  switch (cmd) {
321 
322  case SENSORIOCSPOLLRATE: {
323  switch (arg) {
324 
325  // Zero would be bad.
326  case 0:
327  return -EINVAL;
328 
329  // Set default polling rate.
331  // Do we need to start internal polling?.
332  bool want_start = (_measure_interval == 0);
333 
334  // Set interval for next measurement to minimum legal value.
336 
337  // If we need to start the poll state machine, do it.
338  if (want_start) {
339  start();
340 
341  }
342 
343  return OK;
344  }
345 
346  // Adjust to a legal polling interval in Hz.
347  default: {
348  // Do we need to start internal polling?.
349  bool want_start = (_measure_interval == 0);
350 
351  // Convert hz to tick interval via microseconds.
352  int interval = (1000000 / arg);
353 
354  // check against maximum rate.
355  if (interval < _cycling_rate) {
356  return -EINVAL;
357  }
358 
359  // Update interval for next measurement.
360  _measure_interval = interval;
361 
362  // If we need to start the poll state machine, do it.
363  if (want_start) {
364  start();
365  }
366 
367  return OK;
368  }
369  }
370  }
371 
372  default:
373  // Give it to the superclass.
374  return I2C::ioctl(filp, cmd, arg);
375  }
376 }
377 
378 int
380 {
381  uint8_t cmd[2];
382  cmd[0] = 0x00;
383  cmd[1] = SRF02_TAKE_RANGE_REG;
384 
385  // Send the command to begin a measurement.
386  int ret = transfer(cmd, 2, nullptr, 0);
387 
388  if (ret != PX4_OK) {
390  PX4_DEBUG("i2c::transfer returned %d", ret);
391  return ret;
392  }
393 
394  return PX4_OK;
395 }
396 
397 void
399 {
402  printf("poll interval: %u\n", _measure_interval);
403  _reports->print_info("report queue");
404 }
405 
406 int
408 {
409  return measure();
410 }
411 
412 ssize_t
413 SRF02::read(device::file_t *filp, char *buffer, size_t buflen)
414 {
415 
416  unsigned count = buflen / sizeof(struct distance_sensor_s);
417  struct distance_sensor_s *rbuf = reinterpret_cast<struct distance_sensor_s *>(buffer);
418  int ret = 0;
419 
420  // Buffer must be large enough.
421  if (count < 1) {
422  return -ENOSPC;
423  }
424 
425  // If automatic measurement is enabled.
426  if (_measure_interval > 0) {
427 
428  /*
429  * While there is space in the caller's buffer, and reports, copy them.
430  * Note that we may be pre-empted by the workq thread while we are doing this;
431  * we are careful to avoid racing with them.
432  */
433  while (count--) {
434  if (_reports->get(rbuf)) {
435  ret += sizeof(*rbuf);
436  rbuf++;
437  }
438  }
439 
440  // If there was no data, warn the caller.
441  return ret ? ret : -EAGAIN;
442  }
443 
444  // Manual measurement - run one conversion.
445  do {
446  _reports->flush();
447 
448  // Trigger a measurement.
449  if (OK != measure()) {
450  ret = -EIO;
451  break;
452  }
453 
454  // Wait for it to complete.
455  px4_usleep(_cycling_rate * 2);
456 
457  // Run the collection phase.
458  if (OK != collect()) {
459  ret = -EIO;
460  break;
461  }
462 
463  // State machine will have generated a report, copy it out.
464  if (_reports->get(rbuf)) {
465  ret = sizeof(*rbuf);
466  }
467 
468  } while (0);
469 
470  return ret;
471 }
472 
473 void
475 {
476  if (_collect_phase) {
477  _index_counter = addr_ind[_cycle_counter]; // Sonar from previous iteration collect is now read out.
478  set_device_address(_index_counter);
479 
480  // Perform collection.
481  if (OK != collect()) {
482  PX4_DEBUG("collection error");
483  // If error restart the measurement state machine.
484  start();
485  return;
486  }
487 
488  // Next phase is measurement.
489  _collect_phase = false;
490 
491  // Change i2c adress to next sonar.
493 
494  if (_cycle_counter >= addr_ind.size()) {
495  _cycle_counter = 0;
496  }
497 
498  // Is there a collect->measure gap? Yes, and the timing is set equal to the cycling_rate
499  // Otherwise the next sonar would fire without the first one having received its reflected sonar pulse.
501 
502  // schedule a fresh cycle call when we are ready to measure again.
503  ScheduleDelayed(_measure_interval - _cycling_rate);
504  return;
505  }
506  }
507 
508  // Measurement (firing) phase - Ensure sonar i2c adress is still correct.
510  set_device_address(_index_counter);
511 
512  // Perform measurement.
513  if (OK != measure()) {
514  PX4_DEBUG("measure error sonar adress %d", _index_counter);
515  }
516 
517  // Next phase is collection.
518  _collect_phase = true;
519 
520  // Schedule a fresh cycle call when the measurement is done.
521  ScheduleDelayed(_cycling_rate);
522 }
523 
524 void
526 {
527  // Reset the report ring and state machine.
528  _collect_phase = false;
529  _reports->flush();
530 
531  // Schedule a cycle to start things.
532  ScheduleDelayed(5);
533 }
534 
535 void
537 {
538  ScheduleClear();
539 }
540 
541 
542 /**
543  * Local functions in support of the shell command.
544  */
545 namespace srf02
546 {
547 
549 
550 int reset();
551 int start(uint8_t rotation);
552 int start_bus(uint8_t rotation, int i2c_bus);
553 int status();
554 int stop();
555 int test();
556 int usage();
557 
558 /**
559  * Reset the driver.
560  */
561 int
563 {
564  int fd = px4_open(SRF02_DEVICE_PATH, O_RDONLY);
565 
566  if (fd < 0) {
567  PX4_ERR("failed");
568  return PX4_ERROR;
569  }
570 
571  if (ioctl(fd, SENSORIOCRESET, 0) < 0) {
572  PX4_ERR("driver reset failed");
573  return PX4_ERROR;
574  }
575 
577  PX4_ERR("driver poll restart failed");
578  return PX4_ERROR;
579  }
580 
581  px4_close(fd);
582  return PX4_OK;
583 }
584 
585 /**
586  * Attempt to start driver on all available I2C busses.
587  *
588  * This function will return as soon as the first sensor
589  * is detected on one of the available busses or if no
590  * sensors are detected.
591  */
592 int
593 start(uint8_t rotation)
594 {
595  if (g_dev != nullptr) {
596  PX4_ERR("already started");
597  return PX4_ERROR;
598  }
599 
600  for (unsigned i = 0; i < NUM_I2C_BUS_OPTIONS; i++) {
601  if (start_bus(rotation, i2c_bus_options[i]) == PX4_OK) {
602  return PX4_OK;
603  }
604  }
605 
606  return PX4_ERROR;
607 }
608 
609 /**
610  * Start the driver on a specific bus.
611  *
612  * This function only returns if the sensor is up and running
613  * or could not be detected successfully.
614  */
615 int
616 start_bus(uint8_t rotation, int i2c_bus)
617 {
618  if (g_dev != nullptr) {
619  PX4_ERR("already started");
620  return PX4_ERROR;
621  }
622 
623  // Create the driver.
624  g_dev = new SRF02(rotation, i2c_bus);
625 
626  if (g_dev == nullptr) {
627  PX4_ERR("failed to instantiate the device");
628  return PX4_ERROR;
629  }
630 
631  if (OK != g_dev->init()) {
632  PX4_ERR("failed to initialize the device");
633  delete g_dev;
634  g_dev = nullptr;
635  return PX4_ERROR;
636  }
637 
638  // Set the poll rate to default, starts automatic data collection.
639  int fd = px4_open(SRF02_DEVICE_PATH, O_RDONLY);
640 
641  if (fd < 0) {
642  delete g_dev;
643  g_dev = nullptr;
644  return PX4_ERROR;
645  }
646 
648  delete g_dev;
649  g_dev = nullptr;
650  px4_close(fd);
651  return PX4_ERROR;
652  }
653 
654  px4_close(fd);
655  return PX4_OK;
656 }
657 
658 /**
659  * Print the driver status.
660  */
661 int
663 {
664  if (g_dev == nullptr) {
665  PX4_ERR("driver not running");
666  return PX4_ERROR;
667  }
668 
669  printf("state @ %p\n", g_dev);
670  g_dev->print_info();
671 
672  return PX4_OK;
673 }
674 
675 /**
676  * Stop the driver
677  */
678 int
680 {
681  if (g_dev != nullptr) {
682  delete g_dev;
683  g_dev = nullptr;
684 
685  } else {
686  PX4_ERR("driver not running");
687  return PX4_ERROR;
688  }
689 
690  return PX4_OK;
691 }
692 
693 /**
694  * Perform some basic functional tests on the driver;
695  * make sure we can collect data from the sensor in polled
696  * and automatic modes.
697  */
698 int
700 {
701  int fd = px4_open(SRF02_DEVICE_PATH, O_RDONLY);
702 
703  if (fd < 0) {
704  PX4_ERR("%s open failed (try 'srf02 start' if the driver is not running)", SRF02_DEVICE_PATH);
705  return PX4_ERROR;
706  }
707 
708  struct distance_sensor_s report;
709 
710  // Perform a simple demand read.
711  ssize_t sz = read(fd, &report, sizeof(report));
712 
713  if (sz != sizeof(report)) {
714  PX4_ERR("immediate read failed");
715  return PX4_ERROR;
716  }
717 
718  print_message(report);
719 
720  // Start the sensor polling at 2Hz.
721  if (OK != ioctl(fd, SENSORIOCSPOLLRATE, 2)) {
722  PX4_ERR("failed to set 2Hz poll rate");
723  return PX4_ERROR;
724  }
725 
726  // Read the sensor 5x and report each value.
727  for (unsigned i = 0; i < 5; i++) {
728  struct pollfd fds;
729 
730  // Wait for data to be ready.
731  fds.fd = fd;
732  fds.events = POLLIN;
733  int ret = poll(&fds, 1, 2000);
734 
735  if (ret != 1) {
736  PX4_ERR("timed out waiting for sensor data");
737  return PX4_ERROR;
738  }
739 
740  // Now go get it.
741  sz = read(fd, &report, sizeof(report));
742 
743  if (sz != sizeof(report)) {
744  PX4_ERR("periodic read failed");
745  return PX4_ERROR;
746  }
747 
748  print_message(report);
749  }
750 
751  // Reset the sensor polling to default rate.
753  PX4_ERR("failed to set default poll rate");
754  return PX4_ERROR;
755  }
756 
757  PX4_INFO("PASS");
758  return PX4_OK;
759 }
760 
761 int
763 {
764  PX4_INFO("usage: srf02 command [options]");
765  PX4_INFO("options:");
766  PX4_INFO("\t-b --bus i2cbus (%d)", SRF02_BUS_DEFAULT);
767  PX4_INFO("\t-a --all");
768  PX4_INFO("\t-R --rotation (%d)", distance_sensor_s::ROTATION_DOWNWARD_FACING);
769  PX4_INFO("command:");
770  PX4_INFO("\tstart|stop|test|reset|info");
771  return PX4_OK;
772 }
773 
774 } // namespace srf02
775 
776 
777 /**
778  * Driver 'main' command.
779  */
780 extern "C" __EXPORT int srf02_main(int argc, char *argv[])
781 {
782  const char *myoptarg = nullptr;
783 
784  int ch;
785  int myoptind = 1;
786  int i2c_bus = SRF02_BUS_DEFAULT;
787 
788  uint8_t rotation = distance_sensor_s::ROTATION_DOWNWARD_FACING;
789 
790  bool start_all = false;
791 
792  while ((ch = px4_getopt(argc, argv, "ab:R:", &myoptind, &myoptarg)) != EOF) {
793  switch (ch) {
794  case 'R':
795  rotation = (uint8_t)atoi(myoptarg);
796  break;
797 
798  case 'b':
799  i2c_bus = atoi(myoptarg);
800  break;
801 
802  case 'a':
803  start_all = true;
804  break;
805 
806  default:
807  PX4_WARN("Unknown option!");
808  return srf02::usage();
809  }
810  }
811 
812  if (myoptind >= argc) {
813  return srf02::usage();
814  }
815 
816  // Start/load the driver.
817  if (!strcmp(argv[myoptind], "start")) {
818  if (start_all) {
819  return srf02::start(rotation);
820 
821  } else {
822  return srf02::start_bus(rotation, i2c_bus);
823  }
824  }
825 
826  // Stop the driver.
827  if (!strcmp(argv[myoptind], "stop")) {
828  return srf02::stop();
829  }
830 
831  // Test the driver/device.
832  if (!strcmp(argv[myoptind], "test")) {
833  return srf02::test();
834  }
835 
836  // Reset the driver.
837  if (!strcmp(argv[myoptind], "reset")) {
838  return srf02::reset();
839  }
840 
841  // Print driver information.
842  if (!strcmp(argv[myoptind], "info") ||
843  !strcmp(argv[myoptind], "status")) {
844  return srf02::status();
845  }
846 
847  return srf02::usage();
848 }
perf_counter_t _sample_perf
Definition: srf02.cpp:161
int start(uint8_t rotation)
Attempt to start driver on all available I2C busses.
Definition: srf02.cpp:593
int probe_address(uint8_t address)
Test whether the device supported by the driver is present at a specific address. ...
void Run() override
Perform a poll cycle; collect from the previous measurement and start a new one.
Definition: srf02.cpp:474
SRF02 * g_dev
Definition: srf02.cpp:548
#define SRF02_BUS_DEFAULT
Definition: srf02.cpp:73
#define RANGE_FINDER_BASE_DEVICE_PATH
bool _collect_phase
Definition: srf02.cpp:146
int stop()
Stop the driver.
Definition: srf02.cpp:679
int test()
Perform some basic functional tests on the driver; make sure we can collect data from the sensor in p...
Definition: srf02.cpp:699
uint8_t _cycle_counter
Definition: srf02.cpp:153
#define SRF02_BASEADDR
Definition: srf02.cpp:72
measure the time elapsed performing an event
Definition: perf_counter.h:56
API for the uORB lightweight object broker.
uint8_t _index_counter
Definition: srf02.cpp:154
float _max_distance
Definition: srf02.cpp:157
#define SENSOR_POLLRATE_DEFAULT
poll at driver normal rate
Definition: drv_sensor.h:136
#define SRF02_DEVICE_PATH
Definition: srf02.cpp:74
void usage(const char *reason)
Print the correct usage.
Definition: Commander.cpp:4238
size_t size() const
Definition: Array.hpp:88
Definition: I2C.hpp:51
int ioctl(device::file_t *filp, int cmd, unsigned long arg) override
Definition: srf02.cpp:318
int start_bus(uint8_t rotation, int i2c_bus)
Start the driver on a specific bus.
Definition: srf02.cpp:616
SRF02(uint8_t rotation=distance_sensor_s::ROTATION_DOWNWARD_FACING, int bus=SRF02_BUS_DEFAULT, int address=SRF02_BASEADDR)
Definition: srf02.cpp:173
int _class_instance
Definition: srf02.cpp:148
bool push_back(const T &x)
Definition: Array.hpp:47
count the number of times an event occurs
Definition: perf_counter.h:55
High-resolution timer with callouts and timekeeping.
int collect()
Definition: srf02.cpp:200
px4::Array< uint8_t, RANGE_FINDER_MAX_SENSORS > addr_ind
Definition: srf02.cpp:143
#define SENSORIOCSPOLLRATE
Set the driver polling rate to (arg) Hz, or one of the SENSOR_POLLRATE constants. ...
Definition: drv_sensor.h:134
orb_advert_t _distance_sensor_topic
Definition: srf02.cpp:163
int reset()
Reset the driver.
Definition: srf02.cpp:562
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
Definition: uORB.h:87
void perf_count(perf_counter_t handle)
Count a performance event.
#define SRF02_MIN_DISTANCE
Definition: srf02.cpp:83
Header common to all counters.
perf_counter_t _comms_errors
Definition: srf02.cpp:160
void perf_free(perf_counter_t handle)
Free a counter.
void init()
Activates/configures the hardware registers.
int _orb_class_instance
Definition: srf02.cpp:151
#define perf_alloc(a, b)
Definition: px4io.h:59
__EXPORT int srf02_main(int argc, char *argv[])
Driver &#39;main&#39; command.
Definition: srf02.cpp:780
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Definition: integration.cpp:8
static unsigned counter
Definition: safety.c:56
int status()
Print the driver status.
Definition: srf02.cpp:662
void perf_end(perf_counter_t handle)
End a performance event.
virtual ~SRF02()
Definition: srf02.cpp:180
__BEGIN_DECLS typedef void * orb_advert_t
ORB topic advertiser handle.
Definition: uORB.h:134
int fd
Definition: dataman.cpp:146
int orb_publish(const struct orb_metadata *meta, orb_advert_t handle, const void *data)
Definition: uORB.cpp:70
static const int i2c_bus_options[]
Definition: i2c.h:46
int probe() override
Definition: srf02.cpp:407
int _cycling_rate
Definition: srf02.cpp:149
void stop()
Stop the automatic measurement state machine.
Definition: srf02.cpp:536
int _measure_interval
Definition: srf02.cpp:150
int init() override
Definition: srf02.cpp:245
int usage()
Prints info about the driver argument usage.
Definition: srf02.cpp:762
int px4_open(const char *path, int flags,...)
#define SRF02_MAX_DISTANCE
Definition: srf02.cpp:84
int measure()
Definition: srf02.cpp:379
void perf_print_counter(perf_counter_t handle)
Print one performance counter to stdout.
#define SENSORIOCRESET
Reset the sensor to its default configuration.
Definition: drv_sensor.h:141
ringbuffer::RingBuffer * _reports
Definition: srf02.cpp:165
Definition: bst.cpp:62
void print_info()
Diagnostics - print some basic information about the driver.
Definition: srf02.cpp:398
uint8_t _rotation
Definition: srf02.cpp:155
#define OK
Definition: uavcan_main.cpp:71
Definition: srf02.cpp:89
ssize_t read(device::file_t *filp, char *buffer, size_t buflen) override
Definition: srf02.cpp:413
void start()
Initialise the automatic measurement state machine and start it.
Definition: srf02.cpp:525
bool _sensor_ok
Definition: srf02.cpp:145
float _min_distance
Definition: srf02.cpp:158
#define NUM_I2C_BUS_OPTIONS
Definition: i2c.h:61
Local functions in support of the shell command.
Definition: srf02.cpp:545
#define SRF02_TAKE_RANGE_REG
Definition: srf02.cpp:77
orb_advert_t orb_advertise_multi(const struct orb_metadata *meta, const void *data, int *instance, int priority)
Definition: uORB.cpp:53
#define SRF02_CONVERSION_INTERVAL
Definition: srf02.cpp:86
void perf_begin(perf_counter_t handle)
Begin a performance event.
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
#define RANGE_FINDER_MAX_SENSORS
int px4_close(int fd)
Performance measuring tools.
#define SRF02_INTERVAL_BETWEEN_SUCCESIVE_FIRES
Definition: srf02.cpp:87
Base class for devices connected via I2C.