PX4 Firmware
PX4 Autopilot Software http://px4.io
mb12xx.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2013-2015 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 mb12xx.cpp
36  * @author Greg Hulands
37  * @author Jon Verbeke <jon.verbeke@kuleuven.be>
38  *
39  * Driver for the Maxbotix sonar range finders connected via I2C.
40  */
41 
42 #include <fcntl.h>
43 #include <math.h>
44 #include <poll.h>
45 #include <semaphore.h>
46 #include <stdbool.h>
47 #include <stdint.h>
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <sys/types.h>
52 #include <termios.h>
53 #include <unistd.h>
54 
55 #include <board_config.h>
56 #include <containers/Array.hpp>
57 #include <drivers/device/device.h>
58 #include <drivers/device/i2c.h>
60 #include <drivers/drv_hrt.h>
62 #include <perf/perf_counter.h>
63 #include <px4_platform_common/px4_config.h>
64 #include <px4_platform_common/getopt.h>
65 #include <px4_platform_common/module_params.h>
66 #include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp>
67 #include <uORB/uORB.h>
69 
70 using namespace time_literals;
71 
72 /* Configuration Constants */
73 #define MB12XX_BASE_ADDR 0x70 // 7-bit address is 0x70 = 112. 8-bit address is 0xE0 = 224.
74 #define MB12XX_MIN_ADDR 0x5A // 7-bit address is 0x5A = 90. 8-bit address is 0xB4 = 180.
75 #define MB12XX_BUS_DEFAULT PX4_I2C_BUS_EXPANSION
76 #define MB12XX_BUS_SPEED 100000 // 100kHz bus speed.
77 #define MB12XX_DEVICE_PATH "/dev/mb12xx"
78 
79 /* MB12xx Registers addresses */
80 #define MB12XX_TAKE_RANGE_REG 0x51 // Measure range Register.
81 #define MB12XX_SET_ADDRESS_1 0xAA // Change address 1 Register.
82 #define MB12XX_SET_ADDRESS_2 0xA5 // Change address 2 Register.
83 
84 /* Device limits */
85 #define MB12XX_MIN_DISTANCE (0.20f)
86 #define MB12XX_MAX_DISTANCE (7.65f)
87 
88 #define MB12XX_MEASURE_INTERVAL 100_ms // 60ms minimum for one sonar.
89 #define MB12XX_INTERVAL_BETWEEN_SUCCESIVE_FIRES 100_ms // 30ms minimum between each sonar measurement (watch out for interference!).
90 
91 class MB12XX : public device::I2C, public ModuleParams, public px4::ScheduledWorkItem
92 {
93 public:
94  MB12XX(const int bus = MB12XX_BUS_DEFAULT);
95  virtual ~MB12XX();
96 
97  virtual int init() override;
98 
99  /**
100  * Diagnostics - print some basic information about the driver.
101  */
102  void print_info();
103 
104  /**
105  * Sets a new device address.
106  * @param address The new sensor address to be set: 200-224 even addresses only.
107  * @return Returns PX4_OK iff successful, PX4_ERROR otherwise.
108  */
109  int set_address(const uint8_t address = MB12XX_BASE_ADDR);
110 
111  /**
112  * Initialise the automatic measurement state machine and start it.
113  *
114  * @note This function is called at open and error time. It might make sense
115  * to make it more aggressive about resetting the bus in case of errors.
116  */
117  void start();
118 
119  /**
120  * Stop the automatic measurement state machine.
121  */
122  void stop();
123 
124 protected:
125 
126 private:
127 
128  /**
129  * Collects the most recent sensor measurement data from the i2c bus.
130  */
131  int collect();
132 
133  /**
134  * Gets the current sensor rotation value.
135  */
136  int get_sensor_rotation(const size_t index);
137 
138  /**
139  * Sends an i2c measure command to start the next sonar ping.
140  */
141  int measure();
142 
143  /**
144  * Perform a poll cycle; collect from the previous measurement
145  * and start a new one.
146  */
147  void Run() override;
148 
151 
152  int _measure_interval{MB12XX_MEASURE_INTERVAL}; // Initialize the measure interval for a single sensor.
153  int _orb_class_instance{-1};
154 
155  size_t _sensor_index{0}; // Initialize counter for cycling i2c adresses to zero.
156 
157  size_t _sensor_count{0};
158 
159  orb_advert_t _distance_sensor_topic{nullptr};
160 
161  perf_counter_t _comms_error{perf_alloc(PC_ELAPSED, "mb12xx_comms_error")};
162  perf_counter_t _sample_perf{perf_alloc(PC_COUNT, "mb12xx_sample_perf")};
163 
164  DEFINE_PARAMETERS(
165  (ParamInt<px4::params::SENS_EN_MB12XX>) _p_sensor_enabled,
166  (ParamInt<px4::params::SENS_MB12_0_ROT>) _p_sensor0_rot,
167  (ParamInt<px4::params::SENS_MB12_1_ROT>) _p_sensor1_rot,
168  (ParamInt<px4::params::SENS_MB12_2_ROT>) _p_sensor2_rot,
169  (ParamInt<px4::params::SENS_MB12_3_ROT>) _p_sensor3_rot,
170  (ParamInt<px4::params::SENS_MB12_4_ROT>) _p_sensor4_rot,
171  (ParamInt<px4::params::SENS_MB12_5_ROT>) _p_sensor5_rot,
172  (ParamInt<px4::params::SENS_MB12_6_ROT>) _p_sensor6_rot,
173  (ParamInt<px4::params::SENS_MB12_7_ROT>) _p_sensor7_rot,
174  (ParamInt<px4::params::SENS_MB12_8_ROT>) _p_sensor8_rot,
175  (ParamInt<px4::params::SENS_MB12_9_ROT>) _p_sensor9_rot,
176  (ParamInt<px4::params::SENS_MB12_10_ROT>) _p_sensor10_rot,
177  (ParamInt<px4::params::SENS_MB12_11_ROT>) _p_sensor11_rot
178  );
179 };
180 
181 MB12XX::MB12XX(const int bus) :
183  ModuleParams(nullptr),
184  ScheduledWorkItem(MODULE_NAME, px4::device_bus_to_wq(get_device_id()))
185 {
186 }
187 
189 {
190  // Ensure we are truly inactive.
191  stop();
192 
193  // Unadvertise the distance sensor topic.
194  if (_distance_sensor_topic != nullptr) {
196  }
197 
198  // Free perf counters.
201 }
202 
203 int
205 {
207  uint8_t val[2] = {};
208 
209  // Increment i2c adress to next sensor.
210  _sensor_index++;
212 
213  // Set the sensor i2c adress for the active cycle.
214  set_device_address(_sensor_addresses[_sensor_index]);
215 
216  // Transfer data from the bus.
217  int ret_val = transfer(nullptr, 0, &val[0], 2);
218 
219  if (ret_val < 0) {
220  PX4_ERR("sensor %i read failed, address: 0x%02X", _sensor_index, get_device_address());
223  return ret_val;
224  }
225 
226  uint16_t distance_cm = val[0] << 8 | val[1];
227  float distance_m = static_cast<float>(distance_cm) * 1e-2f;
228 
229  distance_sensor_s report;
230  report.current_distance = distance_m;
235  report.signal_quality = -1;
236  report.timestamp = hrt_absolute_time();
237  report.type = distance_sensor_s::MAV_DISTANCE_SENSOR_ULTRASOUND;
238  report.variance = 0.0f;
239 
240  int instance_id;
241  orb_publish_auto(ORB_ID(distance_sensor), &_distance_sensor_topic, &report, &instance_id, ORB_PRIO_DEFAULT);
242 
243  // Begin the next measurement.
244  if (measure() != PX4_OK) {
245  PX4_INFO("sensor %i measurement error, address 0x%02X", _sensor_index, get_device_address());
248  return ret_val;
249  }
250 
252  return PX4_OK;
253 }
254 
255 int
256 MB12XX::get_sensor_rotation(const size_t index)
257 {
258  switch (index) {
259  case 0: return _p_sensor0_rot.get();
260 
261  case 1: return _p_sensor1_rot.get();
262 
263  case 2: return _p_sensor2_rot.get();
264 
265  case 3: return _p_sensor3_rot.get();
266 
267  case 4: return _p_sensor4_rot.get();
268 
269  case 5: return _p_sensor5_rot.get();
270 
271  case 6: return _p_sensor6_rot.get();
272 
273  case 7: return _p_sensor7_rot.get();
274 
275  case 8: return _p_sensor8_rot.get();
276 
277  case 9: return _p_sensor9_rot.get();
278 
279  case 10: return _p_sensor10_rot.get();
280 
281  case 11: return _p_sensor11_rot.get();
282 
283  default: return PX4_ERROR;
284  }
285 }
286 
287 int
289 {
290  if (_p_sensor_enabled.get() == 0) {
291  PX4_WARN("disabled");
292  return PX4_ERROR;
293  }
294 
295  // Initialize the I2C device
296  if (I2C::init() != OK) {
297  return PX4_ERROR;
298  }
299 
300  // Check for connected rangefinders on each i2c port by decrementing from the base address,
301  // (MB12XX_BASE_ADDR = 112, MB12XX_MIN_ADDR = 90).
302  for (uint8_t address = MB12XX_BASE_ADDR; address > MB12XX_MIN_ADDR ; address--) {
303  set_device_address(address);
304 
305  if (measure() == PX4_OK) {
306  // Store I2C address
307  _sensor_addresses[_sensor_count] = address;
309  _sensor_count++;
310 
311  PX4_INFO("sensor %i at address 0x%02X added", _sensor_count, get_device_address());
312 
314  break;
315  }
316 
317  px4_usleep(_measure_interval);
318  }
319  }
320 
321  // Return an error if no sensors were detected.
322  if (_sensor_count == 0) {
323  PX4_ERR("no sensors discovered");
324  return PX4_ERROR;
325  }
326 
327  // If more than one sonar is detected, adjust the meaure interval to avoid sensor interference.
328  if (_sensor_count > 1) {
330  }
331 
332  PX4_INFO("Total sensors connected: %i", _sensor_count);
333  return PX4_OK;
334 }
335 
336 int
338 {
339  // Send the command to take a measurement.
340  uint8_t cmd = MB12XX_TAKE_RANGE_REG;
341  int ret_val = transfer(&cmd, 1, nullptr, 0);
342 
343  return ret_val;
344 }
345 
346 void
348 {
351  PX4_INFO("poll interval: %ums", _measure_interval / 1000);
352 
353  for (size_t i = 0; i < _sensor_count; i++) {
354  PX4_INFO("sensor: %u, address %u", i, _sensor_addresses[i]);
355  }
356 }
357 
358 void
360 {
361  // Collect the sensor data.
362  if (collect() != PX4_OK) {
363  PX4_INFO("collection error");
364  }
365 }
366 
367 int
368 MB12XX::set_address(const uint8_t address)
369 {
370  if (_sensor_count > 1) {
371  PX4_INFO("multiple sensors are connected");
372  return PX4_ERROR;
373  }
374 
375  if (address < 2 ||
376  address == 80 ||
377  address == 164 ||
378  address == 170 ||
379  address > 224) {
380  PX4_ERR("incompatible address requested");
381  return PX4_ERROR;
382  }
383 
384  PX4_INFO("requested address: %u", address);
385 
386  uint8_t shifted_address = (address << 1);
387  uint8_t cmd[3] = {MB12XX_SET_ADDRESS_1, MB12XX_SET_ADDRESS_2, shifted_address};
388 
389  if (transfer(cmd, sizeof(cmd), nullptr, 0) != PX4_OK) {
390  PX4_INFO("could not set the address");
391  }
392 
393  set_device_address(address);
394  PX4_INFO("device address: %u", get_device_address());
395  return PX4_OK;
396 }
397 
398 void
400 {
401  // Fetch parameter values.
402  ModuleParams::updateParams();
403 
404  // Schedule the driver cycle at regular intervals.
405  ScheduleOnInterval(_measure_interval);
406 }
407 
408 void
410 {
411  ScheduleClear();
412 }
413 
414 /**
415  * Local functions in support of the shell command.
416  */
417 namespace mb12xx
418 {
419 
421 
422 int reset();
423 int set_address(const uint8_t address = MB12XX_BASE_ADDR);
424 int start();
425 int start_bus(const int i2c_bus = MB12XX_BUS_DEFAULT);
426 int status();
427 int stop();
428 int test();
429 int usage();
430 
431 /**
432  * Reset the driver.
433  */
434 int
436 {
437  PX4_INFO("driver resetting");
438  stop();
439  start();
440  return PX4_OK;
441 }
442 
443 int
444 set_address(const uint8_t address)
445 {
446  if (g_dev != nullptr) {
447  if (g_dev->set_address(address) != PX4_OK) {
448  PX4_ERR("address not set");
449  return PX4_ERROR;
450  }
451  }
452 
453  reset();
454  return PX4_OK;
455 }
456 
457 /**
458  * Attempt to start driver on all available I2C busses.
459  *
460  * This function will return as soon as the first sensor
461  * is detected on one of the available busses or if no
462  * sensors are detected.
463  */
464 int
466 {
467  if (g_dev != nullptr) {
468  PX4_ERR("already started");
469  return PX4_ERROR;
470  }
471 
472  for (unsigned i = 0; i < NUM_I2C_BUS_OPTIONS; i++) {
473  if (start_bus(i2c_bus_options[i]) == PX4_OK) {
474  return PX4_OK;
475  }
476  }
477 
478  return PX4_ERROR;
479 }
480 
481 /**
482  * Start the driver on a specific bus.
483  *
484  * This function only returns if the sensor is up and running
485  * or could not be detected successfully.
486  */
487 int
488 start_bus(const int i2c_bus)
489 {
490  if (g_dev != nullptr) {
491  PX4_ERR("already started");
492  return PX4_OK;
493  }
494 
495  // Instantiate the driver.
496  g_dev = new MB12XX(i2c_bus);
497 
498  if (g_dev == nullptr) {
499  delete g_dev;
500  return PX4_ERROR;
501  }
502 
503  // Initialize the sensor.
504  if (g_dev->init() != PX4_OK) {
505  delete g_dev;
506  g_dev = nullptr;
507  return PX4_ERROR;
508  }
509 
510  // Start the driver.
511  g_dev->start();
512 
513  PX4_INFO("driver started");
514  return PX4_OK;
515 }
516 
517 /**
518  * Print the driver status.
519  */
520 int
522 {
523  if (g_dev == nullptr) {
524  PX4_ERR("driver not running");
525  return PX4_ERROR;
526  }
527 
528  g_dev->print_info();
529 
530  return PX4_OK;
531 }
532 
533 /**
534  * Stop the driver.
535  */
536 int
538 {
539  if (g_dev != nullptr) {
540  delete g_dev;
541  g_dev = nullptr;
542  }
543 
544  PX4_INFO("driver stopped");
545  return PX4_OK;
546 }
547 
548 /**
549  * Perform some basic functional tests on the driver;
550  * make sure we can collect data from the sensor in polled
551  * and automatic modes.
552  */
553 int
555 {
556  int fd = px4_open(MB12XX_DEVICE_PATH, O_RDONLY);
557 
558  if (fd < 0) {
559  PX4_ERR("%s open failed (try 'mb12xx start' if the driver is not running)", MB12XX_DEVICE_PATH);
560  return PX4_ERROR;
561  }
562 
563  // Perform a simple demand read.
564  distance_sensor_s report {};
565  ssize_t sz = read(fd, &report, sizeof(report));
566 
567  if (sz != sizeof(report)) {
568  PX4_ERR("immediate read failed");
569  return PX4_ERROR;
570  }
571 
572  print_message(report);
573 
574  PX4_INFO("PASS");
575  return PX4_OK;
576 }
577 
578 /**
579  * Print information about the driver usage.
580  */
581 int
583 {
584  PX4_INFO("usage: mb12xx <command> [options]");
585  PX4_INFO("options:");
586  PX4_INFO("\t-a --all available busses");
587  PX4_INFO("\t-b --bus i2cbus (%d)", MB12XX_BUS_DEFAULT);
588  PX4_INFO("\t-A --set device address (0-112, 0x00-0x70)");
589  PX4_INFO("command:");
590  PX4_INFO("\treset|set_address|start|status|stop|test|usage");
591  return PX4_OK;
592 }
593 
594 } // namespace mb12xx
595 
596 /**
597  * Driver 'main' command.
598  */
599 extern "C" __EXPORT int mb12xx_main(int argc, char *argv[])
600 {
601  const char *myoptarg = nullptr;
602 
603  int ch = 0;
604  int i2c_bus = MB12XX_BUS_DEFAULT;
605  int myoptind = 1;
606 
607  uint8_t address = MB12XX_BASE_ADDR;
608 
609  bool start_all = false;
610 
611  while ((ch = px4_getopt(argc, argv, "abs:", &myoptind, &myoptarg)) != EOF) {
612  switch (ch) {
613  case 'a':
614  start_all = true;
615  break;
616 
617  case 'b':
618  i2c_bus = atoi(myoptarg);
619  break;
620 
621  case 's':
622  address = (uint8_t)atoi(myoptarg);
623  break;
624 
625  default:
626  PX4_WARN("Unknown option!");
627  return mb12xx::usage();
628  }
629  }
630 
631  if (myoptind >= argc) {
632  return mb12xx::usage();
633  }
634 
635  // Reset the driver.
636  if (!strcmp(argv[myoptind], "reset")) {
637  return mb12xx::reset();
638  }
639 
640  // Set the device I2C address.
641  if (!strcmp(argv[myoptind], "set_address")) {
642  return mb12xx::set_address(address);
643  }
644 
645  // Start/load the driver.
646  if (!strcmp(argv[myoptind], "start")) {
647  if (start_all) {
648  return mb12xx::start();
649 
650  } else {
651  return mb12xx::start_bus(i2c_bus);
652  }
653  }
654 
655  // Print the driver status.
656  if (!strcmp(argv[myoptind], "status")) {
657  return mb12xx::status();
658  }
659 
660  // Stop the driver.
661  if (!strcmp(argv[myoptind], "stop")) {
662  return mb12xx::stop();
663  }
664 
665  // Test the driver/device.
666  if (!strcmp(argv[myoptind], "test")) {
667  return mb12xx::test();
668  }
669 
670  // Print driver usage information.
671  return mb12xx::usage();
672 }
void Run() override
Perform a poll cycle; collect from the previous measurement and start a new one.
Definition: mb12xx.cpp:359
measure the time elapsed performing an event
Definition: perf_counter.h:56
API for the uORB lightweight object broker.
#define MB12XX_SET_ADDRESS_2
Definition: mb12xx.cpp:82
__EXPORT int mb12xx_main(int argc, char *argv[])
Driver &#39;main&#39; command.
Definition: mb12xx.cpp:599
void usage(const char *reason)
Print the correct usage.
Definition: Commander.cpp:4238
int set_address(const uint8_t address=MB12XX_BASE_ADDR)
Sets a new device address.
Definition: mb12xx.cpp:368
Definition: I2C.hpp:51
px4::Array< uint8_t, RANGE_FINDER_MAX_SENSORS > _sensor_rotations
Definition: mb12xx.cpp:150
static void stop()
Definition: dataman.cpp:1491
void print_info()
Diagnostics - print some basic information about the driver.
Definition: mb12xx.cpp:347
count the number of times an event occurs
Definition: perf_counter.h:55
int set_address(const uint8_t address=MB12XX_BASE_ADDR)
Definition: mb12xx.cpp:444
void stop()
Stop the automatic measurement state machine.
Definition: mb12xx.cpp:409
int measure()
Sends an i2c measure command to start the next sonar ping.
Definition: mb12xx.cpp:337
#define MB12XX_MAX_DISTANCE
Definition: mb12xx.cpp:86
High-resolution timer with callouts and timekeeping.
size_t _sensor_count
Definition: mb12xx.cpp:157
int get_sensor_rotation(const size_t index)
Gets the current sensor rotation value.
Definition: mb12xx.cpp:256
static void read(bootloader_app_shared_t *pshared)
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
Definition: uORB.h:87
int collect()
Collects the most recent sensor measurement data from the i2c bus.
Definition: mb12xx.cpp:204
MB12XX * g_dev
Definition: mb12xx.cpp:420
orb_advert_t _distance_sensor_topic
Definition: mb12xx.cpp:159
void perf_count(perf_counter_t handle)
Count a performance event.
int start()
Attempt to start driver on all available I2C busses.
Definition: mb12xx.cpp:465
Header common to all counters.
void perf_free(perf_counter_t handle)
Free a counter.
void init()
Activates/configures the hardware registers.
#define MB12XX_BASE_ADDR
Definition: mb12xx.cpp:73
#define perf_alloc(a, b)
Definition: px4io.h:59
#define MB12XX_MEASURE_INTERVAL
Definition: mb12xx.cpp:88
#define MB12XX_MIN_DISTANCE
Definition: mb12xx.cpp:85
Local functions in support of the shell command.
Definition: mb12xx.cpp:417
void start()
Initialise the automatic measurement state machine and start it.
Definition: mb12xx.cpp:399
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Definition: integration.cpp:8
#define MB12XX_INTERVAL_BETWEEN_SUCCESIVE_FIRES
Definition: mb12xx.cpp:89
#define MB12XX_TAKE_RANGE_REG
Definition: mb12xx.cpp:80
int status()
Print the driver status.
Definition: mb12xx.cpp:521
void perf_end(perf_counter_t handle)
End a performance event.
virtual ~MB12XX()
Definition: mb12xx.cpp:188
int start_bus(const int i2c_bus=MB12XX_BUS_DEFAULT)
Start the driver on a specific bus.
Definition: mb12xx.cpp:488
__BEGIN_DECLS typedef void * orb_advert_t
ORB topic advertiser handle.
Definition: uORB.h:134
int fd
Definition: dataman.cpp:146
static const int i2c_bus_options[]
Definition: i2c.h:46
#define MB12XX_BUS_DEFAULT
Definition: mb12xx.cpp:75
static int start()
Definition: dataman.cpp:1452
virtual int init() override
Definition: mb12xx.cpp:288
#define MB12XX_SET_ADDRESS_1
Definition: mb12xx.cpp:81
int px4_open(const char *path, int flags,...)
#define MB12XX_MIN_ADDR
Definition: mb12xx.cpp:74
#define MB12XX_BUS_SPEED
Definition: mb12xx.cpp:76
int test()
Perform some basic functional tests on the driver; make sure we can collect data from the sensor in p...
Definition: mb12xx.cpp:554
void perf_print_counter(perf_counter_t handle)
Print one performance counter to stdout.
int orb_unadvertise(orb_advert_t handle)
Definition: uORB.cpp:65
int _measure_interval
Definition: mb12xx.cpp:152
Definition: bst.cpp:62
int stop()
Stop the driver.
Definition: mb12xx.cpp:537
#define MB12XX_DEVICE_PATH
Definition: mb12xx.cpp:77
#define OK
Definition: uavcan_main.cpp:71
int usage()
Print information about the driver usage.
Definition: mb12xx.cpp:582
#define NUM_I2C_BUS_OPTIONS
Definition: i2c.h:61
perf_counter_t _sample_perf
Definition: mb12xx.cpp:162
int reset()
Reset the driver.
Definition: mb12xx.cpp:435
MB12XX(const int bus=MB12XX_BUS_DEFAULT)
Definition: mb12xx.cpp:181
void perf_begin(perf_counter_t handle)
Begin a performance event.
perf_counter_t _comms_error
Definition: mb12xx.cpp:161
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
size_t _sensor_index
Definition: mb12xx.cpp:155
static int orb_publish_auto(const struct orb_metadata *meta, orb_advert_t *handle, const void *data, int *instance, int priority)
Advertise as the publisher of a topic.
Definition: uORB.h:177
px4::Array< uint8_t, RANGE_FINDER_MAX_SENSORS > _sensor_addresses
Definition: mb12xx.cpp:149
#define RANGE_FINDER_MAX_SENSORS
Performance measuring tools.
Base class for devices connected via I2C.