{"id":8941,"date":"2021-07-29T17:09:36","date_gmt":"2021-07-29T21:09:36","guid":{"rendered":"https:\/\/itp.nyu.edu\/physcomp\/?page_id=8941"},"modified":"2022-11-06T18:20:33","modified_gmt":"2022-11-06T23:20:33","slug":"i2c-communication-with-a-time-of-flight-distance-sensor","status":"publish","type":"page","link":"https:\/\/itp.nyu.edu\/physcomp\/i2c-communication-with-a-time-of-flight-distance-sensor\/","title":{"rendered":"Lab: I2C Communication with a Time-of-Flight Distance Sensor"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Introduction\"><\/span>Introduction<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>In this lab, you&#8217;ll see synchronous serial communication in action using the Inter-integrated Circuit (I2C)&nbsp;protocol with a time-of-flight distance sensor and a microcontroller.<\/p>\n\n\n\n<p>Many different sensors on the market use the I2C protocol to communicate with microcontrollers. It is the most common way to connect to advanced sensors these days. The VL53L0X used in this lab is typical of an I2C sensor, so the principles covered here will help you when working with other I2C sensors as well. Much of this lab is adapted from the <a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-serial-communication\/i2c-communication-with-a-color-gesture-and-proximity-sensor\/\" data-type=\"page\" data-id=\"7517\">I2C lab on the APDS-9960 Color, Light, and Gesture Sensor<\/a>.<\/p>\n\n\n\n<p>Related videos: <a rel=\"noopener noreferrer\" href=\"https:\/\/vimeo.com\/380370070\" target=\"_blank\">Intro to Synchronous Serial<\/a>, <a rel=\"noopener noreferrer\" href=\"https:\/\/vimeo.com\/380369693\" target=\"_blank\">I2C<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_Youll_Need_to_Know\"><\/span>What You\u2019ll Need to Know<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>To get the most out of this Lab, you should be familiar with the basics of programming an Arduino microcontroller. If you\u2019re not, review the <a rel=\"noopener noreferrer\" href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/digital-input-and-output-with-an-arduino\/\" target=\"_blank\">Digital Input and Output Lab<\/a>, and perhaps the <a rel=\"noopener noreferrer\" href=\"http:\/\/arduino.cc\/en\/Guide\/HomePage\" target=\"_blank\">Getting Started with Arduino guide<\/a>. You should also understand <a rel=\"noreferrer noopener\" href=\"https:\/\/itp.nyu.edu\/physcomp\/lessons\/serial-communication-the-basics\/\" target=\"_blank\">asynchronous serial communication<\/a> and how it differs from <a href=\"https:\/\/itp.nyu.edu\/physcomp\/lessons\/synchronous-serial-communication-the-basics\/\" target=\"_blank\" rel=\"noreferrer noopener\">synchronous serial communication<\/a>. You should also read the <a href=\"https:\/\/itp.nyu.edu\/physcomp\/distance-sensors-the-basics\/\" data-type=\"page\" data-id=\"8445\">notes on distance sensors <\/a>to learn more about time-of-flight, or VCSEL sensors.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Things_Youll_Need\"><\/span>Things You\u2019ll Need<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Figure 1-3 are the parts that&nbsp; you need for this lab.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/hookup_wire2.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/hookup_wire2-150x150.jpg\" alt=\"Three 22AWG solid core hookup wires. Each is about 6cm long. The top one is black; the middle one is red; the bottom one is blue. All three have stripped ends, approximately 4 to 5mm on each end.\" class=\"wp-image-1203\"\/><\/a><figcaption>Figure 1. 22AWG solid core hookup wires.<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image size-thumbnail wp-image-5921\"><figure class=\"alignleft\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/pcomp-kit-f2019-arduino-nano-33-iot-150x150.jpg\" alt=\"Photo of an Arduino Nano 33 IoT module. The USB connector is at the top of the image, and the physical pins are numbered in a U-shape from top left to bottom left, then from bottom right to top right.\" class=\"wp-image-5921\"\/><figcaption>Figure 2. Arduino Nano 33 IoT or other Arduino board<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/VL35L0X_sensor.jpg\" alt=\"\" class=\"wp-image-8942\" width=\"116\" height=\"160\"\/><figcaption>Figure 3. A VL53L0X distance sensor breakout board. <\/figcaption><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Sensor_Characteristics\"><\/span>Sensor Characteristics<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The sensor&nbsp;used in this lab,&nbsp;an ST Micro <a href=\"https:\/\/www.st.com\/en\/imaging-and-photonics-solutions\/vl53l0x.html\">VL53L0X sensor<\/a>, is an integrated circuit (IC) that can read the distance out to about 2000mm. It uses a 940 nm VCSEL emitter (Vertical Cavity Surface-Emitting Laser) that reflects off the target to determine the distance.  There are breakout boards available for this sensor from multiple vendors, including   <a href=\"https:\/\/www.adafruit.com\/product\/3317\">Adafruit<\/a> and <a href=\"https:\/\/www.pololu.com\/product\/2490\">Pololu<\/a> (all available through <a href=\"https:\/\/www.digikey.com\/products\/en\/development-boards-kits-programmers\/evaluation-boards-sensors\/795?k=vl53l0x\">Digikey<\/a>, among others) .<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"I2C_Connections\"><\/span>I2C Connections<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Connect the sensor&#8217;s voltage and ground pins to your voltage and ground buses, and the I2C clock (SCL) and I2C serial data (SDA) pins to your microcontroller&#8217;s corresponding I2C pins as shown in Figure 4-6. The schematic, Figure 4, is the same for both the Uno and the Nano. For the Arduino Uno or the Arduino Nano boards, the I2C pins are pins A4 (SDA) and A5(SCL). This is the same connection for almost any I2C sensor. <\/p>\n\n\n\n<p>Some I2C sensors also have a few other pins: <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>an interrupt pin, used to signal the microprocessor when a reading is ready. <\/li><li>a shutdown or reset pin, used for powering down or resetting the sensor.<\/li><\/ul>\n\n\n\n<p>For this exercise, you won&#8217;t be using interrupt or shutdown pins. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_are_QwiicStemmaGroveGravity\"><\/span>What are Qwiic\/Stemma\/Grove\/Gravity?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>In addition to the standard I2C connections, Sparkfun and Adafruit use a connector called <a href=\"https:\/\/www.sparkfun.com\/qwiic\">Qwiic<\/a> which connects the I2C, power, and interrupt connectors all in one cable, eliminating the need for soldering. It&#8217;s a Sparkfun brand name. However, you&#8217;ll need a Qwiic adapter shield to use it. Adafruit have a similar brand called <a href=\"https:\/\/learn.adafruit.com\/introducing-adafruit-stemma-qt?view=all\">Stemma<\/a>, Seedstudio uses <a href=\"https:\/\/www.seeedstudio.com\/category\/Grove-c-1003.html\">Grove<\/a>, and DFRobot uses <a href=\"https:\/\/www.dfrobot.com\/gravity.html\">Gravity<\/a>. They all support I2C and have custom solderless connectors, though their connectors are not compatible with each other. To maintain compatibility, stick with the I2C header pins. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"400\" height=\"444\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/Vl53L0X-Nano_schem.png\" alt=\"Schematic view of an Arduino attached to an VL53L0X sensor.\" class=\"wp-image-8943\"\/><figcaption><em>Figure 4. Schematic view of an Arduino attached to an VL53L0X sensor. This is the typical schematic for most I2C sensors.<\/em><\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"400\" height=\"300\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/APDS-9960-Uno_bb-2.png\" alt=\"Breadboard view of an Arduino attached to a VL53L0X sensor.\" class=\"wp-image-8944\"\/><figcaption><em>Figure 5. Breadboard view of an Arduino attached to a VL53L0X sensor. This shows an Adafruit breakout board, but other companies&#8217; boards use the same pins: voltage, ground, SDA, and SCL.<\/em><\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image wp-image-6197\"><figure class=\"aligncenter size-full is-resized\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/Vl53L0X-Nano_bb.png\"><img decoding=\"async\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/Vl53L0X-Nano_bb.png\" alt=\"Breadboard view of a VL53L0X distance sensor breakout board connected to an Arduino Nano 33 IoT\" class=\"wp-image-8945\" width=\"-71\" height=\"-44\"\/><\/a><figcaption><em>Figure 6. A VL53L0X distance sensor breakout board connected to an Arduino Nano 33 IoT. This shows an Adafruit breakout board, but other companies&#8217; boards use the same pins: voltage, ground, SDA, and SCL.<\/em><\/figcaption><\/figure><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>The circuit is now complete, and you&#8217;re ready to write a program to control it. One of the advantages of the I2C synchronous serial protocol (as opposed to the SPI protocol) is that you only ever need two wires for communication to one or multiple devices.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"How_I2C_Sensors_Work\"><\/span>How I2C Sensors Work<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>I2C devices exchange&nbsp;bits of data whenever the shared clock signal changes.&nbsp;&nbsp;Controller and peripheral devices both send bits of data when the clock changes from low to high (called the <em>rising edge<\/em> of the clock). Unlike with SPI, they cannot send data at the same time.<\/p>\n\n\n\n<p>The Vl53L0X has a series of memory registers that control its function. You can write to or read from these registers using I2C communication from your microcontroller. Some of these registers are writable by the controller so that you can configure the sensor. Some registers are configuration&nbsp;registers. Writing to them sets the sensor&#8217;s characteristics. For example, you can configure whether the sensor is in high speed mode, high sensitivity mode, or long distance mode. Other memory registers are read-only. For example, when the sensor has read the proximity of an object, it will store the result in a register that you can read from the controller. The details of the chip&#8217;s registers can be found in the<a rel=\"noopener noreferrer\" href=\"http:\/\/www.ti.com\/lit\/ds\/symlink\/tmp007.pdf\" target=\"_blank\"> <\/a><a rel=\"noreferrer noopener\" href=\"https:\/\/www.st.com\/resource\/en\/datasheet\/vl53l0x.pdf\" target=\"_blank\">sensor&#8217;s datasheet<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"How_I2C_Bits_are_Exchanged\"><\/span>How I2C Bits are Exchanged<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Most of the time, you never have to think about how the bits of an I2C message are exchanged. If so, then you might want to skip to the the next section on I2C Libraries. For the low-level details, read on:<\/p>\n\n\n\n<p>I2C devices exchange data in 7-bit chunks, using an eighth bit to signal if you&#8217;re reading or writing by the controller or for acknowledgement of data received. The top seven bits of a byte are the data bits, and the bottom bit is the read\/write bit. To get the distance from the VL53L0X, your controller device sends the sensor&#8217;s address (a 7-bit number, for this sensor it&#8217;s 0\u00d729) followed by a single bit indicating whether you want to read data or write data (1 for read, 0 for write). That means the address byte is 0x53 for read, 0x52 for write access. Then you send the memory register in which the sensor&#8217;s ranging data is stored. The sensor then sends the value of that register back to you.  For this particular sensor, STMicro wraps the control register documentation in an abstracted API, described in <a href=\"https:\/\/documentation.help\/VL53L0X-API\/documentation.pdf\">this document<\/a>. The section labeled &#8220;Define Registers&#8221; lists all the registers and their addresses. The RESULT_RANGE_STATUS register is the register that holds the latest distance reading. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"I2C_and_the_Wire_Library\"><\/span>I2C and the Wire Library<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The Wire library, which is built into the Arduino IDE, is the main library for accessing I2C communication. However, most Arduino-compatible I2C device libraries incorporate this library, but don&#8217;t expose it directly in their APIs. This makes things simpler for the user. Instead of having to work out the details described above, for example, you can just call  a function like <code>readRangeResult()<\/code> which does the I2C work for you.<\/p>\n\n\n\n<p>The libraries for this sensor are typical of this style of library.  For example, the <a href=\"https:\/\/github.com\/adafruit\/Adafruit_VL53L0X\/\">Adafruit_VL53L0X<\/a> library&#8217;s <code>startRange()<\/code>&nbsp;command sends a&nbsp;write command to start a reading of the sensor. The  <code>isRangeComplete()<\/code> sends a&nbsp;read command to read the  register that indicates whether or not the reading is done.&nbsp;<\/p>\n\n\n\n<p>All sensors take a certain amount of time to read the physical phenomena which they sense. With light-based sensors like the VL53L0X, the time they take to get a reading is usually called <strong>ranging time<\/strong>, or ranging measurement time, and it&#8217;s noted in the data sheet how long it is (about 23ms).  In operation, you query the sensor as to whether it&#8217;s got a reading available, and then read it when that&#8217;s true.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"How_To_Pick_a_Library\"><\/span>How To Pick a Library<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Most companies that make breakout boards for a given I2C sensor will also write a library for it. A search on the term &#8220;VL53L0X&#8221; in the Arduino library manager will return several libraries.  All of them will work with any of the breakout boards. What&#8217;s the difference? Ideally, you want a library that works well, has readable examples, and good documentation. Often you have to settle for two of the three.<\/p>\n\n\n\n<p>Different companies and programmers have different styles for writing a library&#8217;s application programming interface, or API. Arduino has a <a href=\"https:\/\/www.arduino.cc\/en\/Reference\/APIStyleGuide\">style guide for writing APIs,<\/a> but it&#8217;s not always followed by others. The Arduino-developed libraries generally follow this guide. Other companies&#8217; libraries may have a few more configuration functions, and their examples are a bit more complicated as a result. You should look at the examples with any library to see if they make sense to you. A good guideline is to use the library with the instructions and examples that you find to be the clearest. Here is the <a href=\"https:\/\/learn.adafruit.com\/adafruit-vl53l0x-micro-lidar-distance-sensor-breakout\">Adafruit guide for this sensor.<\/a> As you can see, it doesn&#8217;t tell you much about the functions themselves. However, you can also get information from the library&#8217;s header file. The header file is generally the file with the name <code>libraryname.h<\/code>. Sometimes it&#8217;s in a directory called <code>src<\/code>. For example, here&#8217;s the <a href=\"https:\/\/github.com\/adafruit\/Adafruit_VL53L0X\/blob\/master\/src\/Adafruit_VL53L0X.h\">header file for the Adafruit_VL53L0X library<\/a>.  Within the header file, there are class names for the library and a section called <code>public<\/code> where you&#8217;ll find all the possible function definitions.<\/p>\n\n\n\n<p>Even if the examples don&#8217;t include all the functions, the <code>public<\/code> section of the header file will. From there, you can build your own examples if the library&#8217;s examples don&#8217;t show how to use a function you want to use. <\/p>\n\n\n\n<p>Adafruit&#8217;s library for this sensor is quite complex, and includes two different ways of reading the sensor. In their examples, they use a function called <a href=\"https:\/\/github.com\/adafruit\/Adafruit_VL53L0X\/blob\/master\/src\/Adafruit_VL53L0X.h#L68\">rangingTest()<\/a>, which puts data into an object in memory called <code>measure<\/code> in the examples, and then you pull the readings from that object. However, you can also read the results directly using a set of <a href=\"https:\/\/github.com\/adafruit\/Adafruit_VL53L0X\/blob\/master\/src\/Adafruit_VL53L0X.h#L83\">simpler functions<\/a>: <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>startRange() &#8211; starts the sensor taking a single reading<\/li><li>readRange() &#8211; returns a single range reading<\/li><li>readRangeResult() &#8211; returns a single range reading, and an error value (oxFFFF) if there&#8217;s an error<\/li><li>startRangeContinuous() &#8211; starts the sensor reading continuously<\/li><li>isRangeComplete() &#8211; returns true when a reading is complete and ready to be read<\/li><li>waitRangeComplete() &#8211; does nothing until the reading is complete<\/li><\/ul>\n\n\n\n<p> <a href=\"https:\/\/github.com\/pololu\/vl53l0x-arduino\/\">Pololu&#8217;s library<\/a> is similar, but the API is a bit simpler, and their <a href=\"https:\/\/github.com\/pololu\/vl53l0x-arduino\/blob\/master\/VL53L0X.h\">header file<\/a> lists all the register addresses, for those interested in the lower-level details. They document all the functions on their <a href=\"https:\/\/github.com\/pololu\/vl53l0x-arduino#library-reference\">repository&#8217;s main page<\/a> as well. Their <a href=\"https:\/\/www.pololu.com\/product\/2490\">product documentation<\/a> is clear, if shorter than Adafruit&#8217;s. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Install_the_External_Libraries\"><\/span>Install the External Libraries<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>You can use the library manager to find these libraries. Make sure you&#8217;re using Arduino version 1.8.14 or later. From the Sketch menu, choose Include Library, then Manage Libraries, and search for VL53L0X. All of the related libraries mentioned here will show up. The examples below use the Adafruit_Vl53L0X library.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Program_the_Microcontroller\"><\/span>Program the Microcontroller<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>At the beginning of your code, include the appropriate&nbsp;libraries. In the <code>setup()<\/code>, initialize the sensor with a function called <code>begin()<\/code> (Sparkfun sometimes uses <code>init()<\/code> instead of <code>begin()<\/code>). If the sensor responds, then <code>begin()<\/code> will return true; if not, it will return false. This is how to check that the sensor is properly wired to your microcontroller, and to configure it:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\n\/\/ include library\n#include &quot;Adafruit_VL53L0X.h&quot;\n\n\/\/ make an instance of the library:\nAdafruit_VL53L0X sensor = Adafruit_VL53L0X();\n\nconst int maxDistance  = 2000;\n\nvoid setup() {\n  \/\/ initialize serial, wait 3 seconds for\n  \/\/ Serial Monitor to open:\n  Serial.begin(9600);\n  if (!Serial) delay(3000);\n\n  \/\/ initialize sensor, stop if it fails:\n  if (!sensor.begin()) {\n    Serial.println(&quot;Sensor not responding. Check wiring.&quot;);\n    while (true);\n  }\n  \/* config can be:\n    VL53L0X_SENSE_DEFAULT: about 500mm range\n    VL53L0X_SENSE_LONG_RANGE: about 2000mm range\n    VL53L0X_SENSE_HIGH_SPEED: about 500mm range\n    VL53L0X_SENSE_HIGH_ACCURACY: about 400mm range, 1mm accuracy\n  *\/\n  sensor.configSensor(Adafruit_VL53L0X::VL53L0X_SENSE_LONG_RANGE);\n  \/\/ set sensor to range continuously:\n  sensor.startRangeContinuous();\n}\n\n<\/pre><\/div>\n\n\n<p>In the main <code>loop()<\/code> function, you&#8217;ll read the sensors.  You&#8217;re going to query the sensor to see if it&#8217;s got a reading available  with the <code>isRangeComplete()<\/code> function, then you&#8217;ll use the <code>readRangeResult()<\/code> function to get the result. This function returns a result in millimeters:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nvoid loop() {\n  \/\/ if the reading is done:\n  if (sensor.isRangeComplete()) {\n    \/\/ read the result:\n    int result = sensor.readRangeResult();\n    \/\/ if it&#039;s with the max distance:\n    if (result &lt; maxDistance) {\n      \/\/ print the result (distance in mm):\n      Serial.println(result);\n\n    }\n  }\n}\n<\/pre><\/div>\n\n\n<p>Run this sketch now, and it will print out the distance from the sensor in millimeters (<a href=\"https:\/\/github.com\/ITPNYU\/physcomp\/blob\/main\/Labs\/LabSynchronousSerial%20\/VL53L0X_Sensor\/VL53L0x_intro\/VL53L0x_intro.ino\">link to the full sketch<\/a>).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>I2C is a common protocol among many ICs, and it&#8217;s handy because you can combine many devices on the same bus. When doing so, however, make sure the device addresses are unique. This can complicate things if you want to use multiple sensors of the same type on the same I2C bus. Fortunately, this is not often the case.<\/p>\n\n\n\n<p>I2C can also be used to combine several Arduinos on a bus, with one as the controller and the others as peripherals. If you <a rel=\"noreferrer noopener\" href=\"http:\/\/arduino.cc\/en\/Main\/Standalone\" target=\"_blank\">build your own Arduino-compatible circuit on a breadboard<\/a>, this can be an inexpensive way to combine several controllers in a more complex project. There are <a href=\"https:\/\/www.arduino.cc\/en\/Reference\/Wire\">examples of this in the Wire library documentation<\/a> on the Arduino site.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction In this lab, you&#8217;ll see synchronous serial communication in action using the Inter-integrated Circuit (I2C)&nbsp;protocol with a time-of-flight distance sensor and a microcontroller. Many different sensors on the market use the I2C protocol to communicate with microcontrollers. It is the most common way to connect to advanced sensors these days. The VL53L0X used in &hellip; <a href=\"https:\/\/itp.nyu.edu\/physcomp\/i2c-communication-with-a-time-of-flight-distance-sensor\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Lab: I2C Communication with a Time-of-Flight Distance Sensor&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":312,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"categories":[41,15,7],"tags":[],"class_list":["post-8941","page","type-page","status-publish","hentry","category-i2c","category-lab","category-sensors"],"_links":{"self":[{"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/pages\/8941"}],"collection":[{"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/comments?post=8941"}],"version-history":[{"count":14,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/pages\/8941\/revisions"}],"predecessor-version":[{"id":10747,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/pages\/8941\/revisions\/10747"}],"wp:attachment":[{"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/media?parent=8941"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/categories?post=8941"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/tags?post=8941"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}