Sensors Equipment

ITLL Sensors and Equipment Checkout.xlsx

Measuring force: load cells

Author: Claire Porter (claire.porter@colorado.edu, please stop by the Electronics Center or email me if you have questions/would like to check out a load cell)

ITLL load cell inventory  (note- this isn't updated with what is currently checked out)

Quick start guide:

If you have questions, or you want to use an Arduino - read on :)

How do we measure force?

Mechanical forces are typically measured using a load cell. Your bathroom scale has load cells. Truck weighing stations use load cells. High quality fishing scales use load cells (cheap ones just measure a spring). The MST downstairs at the ITLL (materials tester) uses load cells to measure force.

Load cells come in various shapes and sizes based on the magnitude, direction, and frequency response of the force you are interested in measuring. 

Various types of load cells:

image.png image.png image.png  image.png

Pre-quiz (test your knowledge!):

  1. What are each of the type of load cells depicted above called?
  2. Which are used to measure compressive forces, and which are used to measure tensile forces? 
  3. Which type do you think the MST downstairs uses? (materials tester)
Answers to quiz
  1. From left to right: button or pancake, S-type, single point, and uniaxial in-line
  2. Compressive forces: all of them
    1. Tensile forces: technically all of them except for the button cell. In practice, the uniaxial in-line cell would be the easiest to use due to its threaded mounting points. 
  3. I would guess it uses in-line uniaxial load cells that can measure tension and compression

Consider the following questions regarding your particular application:

What is the maximum force I expect to measure?

Am I measuring a compression or tension force?

Am I measuring a static or dynamic force?

Is one axis of measurement sufficient, or do I need a multi-axis load cell?

Need help answering the questions above?

Compression vs tension

Compression load cells are perhaps more common; they measure a force that is pushed down into the load cell. Think of a bathroom scale.

Tension load cells measure a force that is pulled away from the body of a load cell. Think of a hanging scale for measuring the weight of luggage or a fish.

Static vs dynamic

An unchanging or very slowly changing force is a static force. Once again, the bathroom scale is a good example. A dynamic force is a transient or quickly changing load, such as a force from an impact or a vibration. Typically we use different load cells for static vs dynamic force measurements, and this is because the operational principle underlying each type of load cell differs. Static load cells comprise of strain gauges, which do not have a particularly fast response time, but they give a stable linear signal over time, whereas dynamic load cells often comprise of piezo-resistive elements which are capable of fast responses but offer a tradeoff with linearity over time.

Uniaxial vs multi-axial

If you only need to measure compression or tension along one axis (once again, think of standing on a bathroom scale, the only acceleration we are concerned with here is due to gravity, so F=ma is only along one vector), a standard uniaxial load cell will do just fine. However, if you are interested in measuring forces along multiple axes in a structure or a robot, a multi-axial load cell might eliminate a complicated set-up involving mounting multiple load cells along different axes.

Range

Load cells come in a wide span of ranges, from less than 1lbf (pound force) to over 2,000 lbf! If you use too high of a load cell, all of your data will be compressed down to the lower end of the range of your sensor, and you aren't maximizing the resolution of your DAQ. A good rule of thumb is to choose a sensor whose range is around 10% higher than your maximum expected force.

How a load cell works: Wheatstone Bridge circuit

A load cell is a sensor containing resistors, and as you apply a force on the load cell, the resistance changes. "Cool, so we are measuring resistance", you might be thinking. Not exactly. The resistors that are in load cells are called strain gauges, and their change in resistance to an applied force is on the order of tenths, or even hundredths of ohms for small forces. If we tried to just measure the change in resistance of a single strain gauge, we would need a very good multimeter that can measure very small electrical changes. "What if we just drove up the supply voltage to generate a larger measurable change in resistance?" you might be thinking. Good idea- but the heat generated from supplying more power would cause the sensitive resistor to heat up, which would change its resistance. You would have no way of knowing if the subtle change in resistance you measure is due to an applied force, or a change in temperature. Ahh!

To get around the problem of measuring a tiny resistance that is susceptible to temperature-induced changes, we use a very old but useful circuit called a Wheatstone Bridge. This circuit has stood the test of time and is used in other sensing applications besides load cells, including pressure sensors.

Wheatstone Bridge circuit (image source: link):

image.png

Each of the resistors depicted above (R1, R2, R3, R4) in the Wheatstone Bridge circuit are strain gauges. They are all contained in your load cell, and might even be visible if you have an S-type load cell. Often you can't see the strain gauges, as in the case of a button load cell or in-line cell, but they are there! The working principle is that the resistance values of the strain gauges change in response to an applied force. A change in resistance value is something we can measure electrically, and this electrical response is directly proportional to the applied mechanical force. 

Basics:
  1. You must supply an excitation voltage to the load cell (labeled VEX  above)
  2. You measure the voltage at the nodes labeled "-" and "+" in the diagram above
    • The voltage will change in response to applying a load to the load cell, since the relative resistances of R1, R2, R3, and R4 change (when they are compressed, their resistance decreases since their cross sectional area has increased. Vice versa for tension.)
  3. This circuit is simply two voltage dividers connected in parallel 
  4. The output voltage is typically very small (on the order of micro or millivolts), so we have to amplify it or choose a DAQ with a high resolution ADC

Useful points:
  1.  When the circuit is balanced (all four resistors have the same resistance value), the output voltage measured between the measurement nodes ("-" and "+" in above image) is zero (look at diagram - do you see why that's true?). This is useful - if there is no force applied to your load cell, you will read zero volts. Very logical!
  2. The arrangement of the strain gauges (alternating in compression/tension) means that for a given force, the measured output voltage will increase for a compressive force, and decrease for a tensile force. If this isn't true for your load cell, try swapping the + and - signal wires
Another definition of the Wheatstone Bridge circuit, from NI

 (Source: Pulled straight from NI-MAX by Claire)

Bridge-based sensors operate by correlating a physical phenomena, such as strain, temperature, or force, to a change in resistance in one or more legs of a Wheatstone bridge. The general Wheatstone bridge, shown in the following figure, is a network of four resistive legs with an excitation voltage, VEX, that is applied across the bridge. One or more of these legs can be active sensing elements.

{BFE275E3-5B86-4CCA-B40E-62712A8BC64B}.png

The Wheatstone bridge is the electrical equivalent of two parallel voltage divider circuits. R1 and R2 compose one voltage divider circuit, and R4 and R3 compose the second voltage divider circuit. You measure the output of a Wheatstone bridge between the middle nodes of the two voltage dividers. 

A physical phenomena, such as a temperature shift or a change in strain applied to a specimen, changes the resistance of the sensing elements in the Wheatstone bridge. You can use the Wheatstone bridge configuration to help measure the small variations in resistance that the sensing elements produce corresponding to a physical change in the specimen. [Claire note - when the bridge is "balanced". it reads zero voltage when no load is applied]

[Claire note: the circuit depicted above is a full bridge circuit, where all four resistors (R1-R4) are strain gauges. If only two resistors are strain gauges, that would be a half bridge, and in a quarter bridge configuration only one of the resistors is a strain gauge. In a half or quarter bridge configuration, the remaining resistors are static resistors. Why would we ever do this? Sometimes a load cell isn't practical for our measurement because it is too bulky, for example if we are interested in analyzing strain along the skin of an aircraft]


How to wire up a load cell for data acquisition

Most load cells have four wires. You will need to connect the four wires correctly to a data acquisition (DAQ) module to generate data measured by the load cell. 

But wait! You haven't told me where to connect the wires, just what they do 

You're absolutely right. I want you understand how a load cell works, to make you a better engineer. If you can explain how the four wires of a load cell relate to the Wheatstone Bridge circuit, you understand the basic fundamentals of force sensing using a load cell. Congratulations!

At this point you understand that we need to apply an excitation voltage (red and black wires), and measure the voltage difference between the other two wires produced when the load cell experiences strain. 

Choosing the right DAQ: Arduino vs other DAQs to read your force data

You have several options for measuring the voltage response from your load cell, but note that the voltage produced by a load cell is small enough (sometimes as low as a single mV for small loads) that we either need to amplify the voltage or use a high enough resolution DAQ to provide meaningful results.

1. NI USB DAQ (NI 6001, 6002, 6008, 6009) Pros: Very easy to wire up. No need to amplify
Cons: You must know LabVIEW or Python (use nidaqmx library)
2. Arduino Pros: You might already familiar with Arduino Cons: You need to amplify the voltage to read it
3. NI 9237 or NI 9219 Pros: Fairly easy to wire up. No need to amplify Cons: You must know LabVIEW or Python (use nidaqmx library)
4. TMO-2A signal conditioner Pros: Dedicated load cell signal conditioner. This will reject low Hz noise and amplify your output to a nice 4-20mA signal. Built in gain/balance pots for calibration.
Cons: You will need to connect this to something that can read current (I'd recommend an NI-9203, and am happy to show you how to do this)
Other GPIO hardware not currently available for checkout from the ITLL Pros: Presumably there is some good reason why you are using it
Cons: ITLL staff may or may not be able to help you, certainly worth an ask

1. NI USB DAQ (NI 6002, 6003, 6008, 6009)

This is the easiest way to go, assuming you know LabVIEW or Python (Python: use nidaqmx library). 

Note on sample rate: these USB DAQs sample incredibly fast, making them useful for either static or dynamic force measurements. The USB 6002 measures 50 kS/sec!

Step by step instructions

Step 1: Find the datasheet for your load cell

Step 2: Identify the range of excitation voltages that your load cell accommodates. 

Step 3: Verify that 5VDC is within that acceptable range you found in Step 2.

Step 4: Wire the two EX+/EX- (might be labeled as something else on the load cell data sheet, but the leads that correspond to the excitation voltage) leads to the 5V and GND on your USB DAQ. On the datasheet screenshot below, these leads are labeled V+/V-.

If you're using a FX1901-0001-0010-L , you can follow the color schematic below (V is excitation voltage and O is output voltage): 

image.png

Step 5: Wire the output signal leads (typically white/green or white/yellow) to analog inputs (AI+/-) on your DAQ.  The voltage across these wires will change in response to the applied force on your load cell. 

Step 6: Launch LabVIEW or NI MAX and click through to "Acquire Signals-->Voltage"; you are measuring a differential voltage across the two inputs on A0 (or whichever channel you chose). This is a differential, not an RSE (reference single ended) measurement. Pick continuous or N samples based on your data acquisition needs.

Step 7: You should be seeing an output voltage that changes when you press on your load cell! To convert voltage to force, you will need to perform the following calculation:

 y = mx + b , where y is the force you are measuring 

I like seeing equations with units clearly specified. I will use lbs as an example, you could use kg or N:                      

 y [lbs] = m [lbs/mV] * x [mV] + b [lbs]

The slope m is the range of your load cell divided by the span in mV. 

Example calculation for slope, m:

 m = Range of your load cell [lbs] / (V_EX  [volts]  * Span [mV/V] ) 

Span = max voltage (voltage corresponding to max rated load of your load cell)  

So for our 10lbf (btw, "lbf" just means "pound force") load cells, the span is 20 mV/V and I applied a 5VDC excitation voltage (V_EX). Therefore, my max voltage is 5V * 20mV/V = 100 mV. My slope is 10 lbf/100mV or 0.1 lbf/mV.

The y-intercept b needs to be solved for - simply record the voltage when nothing is placed on your load cell, and solve y = mx + b, plugging in 0 for y and the value for m that you found in the step above. 

Pro tip: If you want to use a 3D printed jig attached to your load cell, this is a good time to attach it and include it in your offset b. Now the mass of that jig is accounted for in the offset, making downstream calculations simplified.

FX1901-0001-0010-L datasheet

general documentation on this load cell

datasheet

image.png


2. Arduino (e.g., Uno, Nano)

You will need to get a load cell amplifier (we have one or two available for checkout at the Electronics Center, or else they are fairly cheap to buy from Sparkfun) or construct your own amplifier circuit so that the voltage is large enough to read on the Arduino.

I bought an amplifier

Step 1: Find the datasheet for your load cell by googling the part number

Step 2: Verify that 5 VDC or 3.3V is an acceptable excitation voltage for your particular load cell

Step 3: Wire the corresponding colors of your load cell wires to the load cell amplifier. You might want to solder in header pins or sockets if the load cell amplifier comes bare like the image below. If you are using a load cell checked out from the Electronics Center, please ask an engineer how to make connections from your load cell to the amplifier (some of our load cells have header pins already soldered on, and some have bare wires for connection to a screw-terminal. Please don't start soldering to our load cells without discussing with us first). 

{CDC246EC-396C-4485-88A2-B22A66A32115}.png

The "YLW" hole is for a shield wire to protect against stray electromagnetic radiation that might influence your measurement; your load cell might have bare foil instead of a yellow wire, or it might have no shield wire at all. If so, that's fine, leave it bare!


Step 4: Wire up the other side of the load cell as follows:

VDD and VCC: 5V (unless your microcontroller operates on 3.3V logic, then use 3.3V for digital data (VDD) and 5V to power your load cell

DAT: Pin 3

CLK: Pin 2

GND: Arduino GND

{CD29B917-6CAF-45C8-9D49-BAE016D4FB7E}.png

Step 5: Download Arduino code from here: HX711 arduino library

Have fun - and reach out to an engineer in the Electronics Center with any questions you may have!

I want to build the amplifier circuit

IN PROGRESS! Talk to an engineer in the Electronics Center if you choose to go this route

Step 1: Build the amplifier circuit activate this link when tutorial is complete (https://itll-wiki.colorado.edu/bookstack/books/electronics-engineering-tutorials/page/using-an-op-amp-to-amplify-a-signal-eg-from-a-load-cell)

Step 2: Wire up


3. NI 9219 or NI-9237 DAQ

The NI-9219 sample rate is pretty slow (2 Samples/second per channel) so this is ok for static load measurements, but not for dynamic measurements. You can change from High Resolution to High Speed mode for a slight improvement in acquisition speed. This particular DAQ isn't designed for speed; it's a well-rounded workhorse of a DAQ that can measure input from load cells, thermocouples, RTD's, and more on a single DAQ. 

The NI-9237 is much faster (50 kS/s per channel) than the NI-9219, but it is dedicated strain/bridge module. Maybe you want to measure other things, like temperature?

NI-9219 instructions (general purpose NI DAQ)

You will need:

Step 1: Determine the excitation voltage and bridge resistance for your load cell 

Step 2: Pick a channel. Wire the red and black wires of your load cell into 3 and 5 (respectively) on your selected channel, and V_high and V_low into 4 and 6, respectively. The numbers are on the DAQ, but kind of hard to see.

If you've never used this DAQ before, the way to get the wires into the holes is to insert a small flathead screwdriver into the adjacent square, along the midline of the DAQ. Align the screwdriver so the blade of the screwdriver is parallel with the long (up and down if you're holding it like in the image below) axis of the DAQ. Now, stick the screwdriver directly into the square to release the spring on the adjacent hole, allowing you to slide the wire into the hole. Release the screwdriver, and the spring terminal will clamp down on the wire. Verify that you made a good connection by performing a gentle tug test on the wire. Does it fall out? No? Great! If the wire comes out when you tug on it gently, try the steps again. If you need help, ask an engineer in the Electronics Center. Claire- add a video 

image.png

Step 3: If you haven't already, install the DAQ into a chassis. 

Step 4: Plug the chassis into your computer using a USB cable.

Step 5: Start up a VI and insert a DAQ Assistant block. Double click on the DAQ Assistant and choose Acquire Signals-->Analog--> Force(Bridge)

Step 6: The max excitation voltage you can provide with this DAQ is 2.5 V (Claire- verify) . You will need to check the bridge resistance of your load cell and update the boxed field below. Finally, you will need to click "Configure Scale" and input values relevant for your load cell so that the DAQ outputs force, not just voltage.

{F50FBF18-AFB9-4E3A-9A06-83CCEB736176}.png

Step 7: You should be correctly reading force at this point. This guide assumes that you are already comfortably building VI's in LabVIEW. If you have any issues, please reach out to the DAQ engineer. 

Have fun, and happy measuring!

NI-9237 instructions (strain/bridge NI DAQ)

Overview of test setup:

20250930_170616.jpg

You will need:

Step 1: Determine the excitation voltage and bridge resistance for your load cell 

Step 2: Wire the red and black wires of your load cell into 6 and 7 (respectively) of the screw terminal block, and the remaining two wires into 2 and 3. See images below:

20250930_170551.jpg          {9EF592B4-DEB0-4A91-B1F3-B9E06197E7FC}.png

Step 4: Connect DAQ to chassis, and RJ-50 cable between DAQ and screw terminal block. Finally, connect chassis to computer with USB cable

Step 5: Start up a VI and insert a DAQ Assistant block. Double click on the DAQ Assistant and choose Acquire Signals-->Analog--> Force(Bridge)

Step 6: The maximum excitation voltage you can provide with this DAQ is only 2.5 V. You will need to check the bridge resistance of your load cell and update the boxed field below. On the Transducer Technique load cells, I think this corresponds to "Output Resistance". Finally, you will need to click "Configure Scale" and input values relevant for your load cell so that the DAQ outputs force, not just voltage. I leave First Value as 0 for both Electrical and Physical fields, and for the Second Value I put down the span (sometimes labeled "Rated Output") in units of mV/V, and I put the range or capacity of the load cell in the Second Value field under Physical (pay attention to units in the dropdown menu!). Then hit Ok.

{F50FBF18-AFB9-4E3A-9A06-83CCEB736176}.png

Step 7: You should be correctly reading force at this point. This guide assumes that you are already comfortably building VI's in LabVIEW. If you have any issues, please reach out to the DAQ engineer. 

Have fun, and happy measuring!

4. TMO-2A signal conditioner (from Transducer Techniques)

This dedicated load cell signal conditioner has a built in calibration function which makes it an excellent choice for applications requiring the utmost accuracy. If you are using a Transducer Techniques load cell, this is a very good choice (since the load cell's data sheet will have a PCT value you can grab and use during calibration).

TMO-2A instructions

Unfortunately, the manual for this signal conditioner contains errors (I have let Tom at Transducer Techniques know) at least as of 7/22/2026 so good thing you are here! 

Note: you will need an ammeter. You will also need the TMO-2A (I have 2 available for checkout from the Electronics Center, come talk to me in ECCE 167A). You can use a general purpose DMM set to measure amperage, but even better to use a high resolution DAQ like an NI 9203. Or a benchtop DMM is fine, too. Just something that can measure 4-20 mA.

  1. Follow the wiring guide as specified in the manual linked above.
  2. Follow the balance adjustment as instructed in manual linked above.
  3. For the gain adjustment, the manual is incorrect. Don't measure voltage (this is a 4-20mA conditioner, you are working with current, not voltage), keep your ammeter connected the output leads you had it on for step 2, and perform the following steps:
    1. Install banana shunt resistor into signal conditioner
    2. Press down calibration button as you read output current
    3. Refer to your load cell (if it's a Transducer Techniques load cell) data sheet and multiply the percentage under "PCT load" (make it a percent!) by 20mA. 
    4. While pressing the calibration button, turn the gain knob with a flathead screwdriver until the ammeter reads the current you calculated above
  4. You are set to measure! The force is a linear function of the mA generated. You'll need to calculate y [lbs]=m [lbs/mA] x [mA] + b [lbs, should be negative] for your load cell. 

Photo of my test setup:



Even more load cell resources:

Very approachable intro guide

nice resource on load cells from Futek

highly technical resource from Texas Instruments on 4-20mA output

Measuring Temperature

Covers various ways to measure temperature (e.g., thermocouples, RTD's, thermistors, etc)

Measuring Temperature

Which temperature sensor do I use?

So you want to sense temperature. There are several things to consider as you decide between the various options. For most (room temperature +/- 50 degrees) applications, you could use any of the options below. So how do you decide?! Read on. 

________________________________________________________

Claire's quick start guide:

For temperatures above 1000°C : use a thermocouple (Type K, or check other types for their temp range)

Easiest to put on a breadboard (least wiring, doesn't require considering fancy concepts like "cold junction compensation"): TMP36GZ

Fast response time and cheap (maybe you need 100 of them): Thermistor

__________________________________________________________

Claire's more complete table:

Method How it works Electrical requirements DAQ requirements Temp range Accuracy

TMP36GZ

 


As temp increases, voltage across diode's base and emitter (V_be) decreases at a known rate. This voltage is amplified, and voila.

 

To convert the voltage to temperature, simply use the basic formula:

Temp in °C = [(Vout in mV) - 500] / 10

Requires a current

 

1- 2.7 - 5.5 VCC  (0.05 mA current draw)

2 - analog V_out

3- GND

 

(1-2-3 left to right, part number facing you)

Analog voltage input up to 2 V 

-40 - 150 °C

 

(-40 - 302 °F)

+/- 0.2°C;

 

Thermocouple Two different metals form a junction (where we sense temperature), and when a change in temperature occurs, a voltage is generated via the Seebeck effect. This voltage is measured by the DAQ and interpreted to give a temperature. Self powered Analog voltage input

(typical, depends on type [K, J, T etc]);

200 - 1750°C 

(typical)

0.5 - 5 °C;

 

0.10 - 10 sec

Thermistor Semiconductor typically combined with binders and stabilizers with a negative or positive temperature coefficient. Basically, temperature increases, and resistance of sensing element increases (PTC) or decreases (NTC) Requires a current Analog voltage input

(typical)

-100 - 325°C

as low as +/- 0.05 °C;

 

0.12 - 10 seconds

RTD (resistance temperature detector) Resistance of a sensing element (usually a pure metal like platinum protected in a sheath/embedded in ceramic) increases as temperature increases Requires a current Analog voltage input

(typical)

-200 - 650 °C

+/- 0.1 to 1 °C;

 

1 - 50 sec

____________________________________________________________________________________________

TMP36GZ (image from Adafruit)

image.png

_______________________________________________________________________________________________

RTD vs thermistor (nice guide from Omega)

{E9154127-C1A8-4A44-8D31-2F99CED76C52}.png

_______________________________________________________________________________________________

RTD vs Thermocouple (nice guide from McMaster)

{1E70E4FE-7907-4B60-889C-AD3A588F1C1B}.png

_______________________________________________________________________________________________

RTD vs thermistor

{FB3914A1-59D6-465B-AE6F-050FCC98515E}.png

Measuring Temperature

Comparing thermocouple types

This is a nice link: link

Type T thermocouples (Cu/constantan or blue/red) have an accuracy of $/pm$ 1 degree C, whereas Type K thermocouples have an accuracy of $/pm$ 2.2C. 

Remote Sensing

We will cover ways to remotely sense data including WiFi, LoRa, and Bluetooth.

New sensors for Fall 2026

Thanks to the Engineering Excellence Fund, we acquired over 50 new sensors the summer of 2026 that are inventoried, tested, and ready for student checkout Fall 2026.

Here's what's new for Fall 2026!

Everything below is available for checkout from the ITLL Electronics Center (ECCE 167)!

Incremental Rotary Encoders (QTY 2)

Autonics_E40S_Series1.jpg

encoder_gif.gif{40A3F865-DCED-49D8-9D0F-FC458B6602CB}.png

Description above from: https://www.pjrc.com/teensy/td_libs_Encoder.html?#

GIF made by yours truly (Claire Porter). I'm turning the encoder shaft CW, then CCW, and you can see the output increment, then decrease.

CODE (Arduino)

I used this library on an Arduino Uno: 

{5E827665-82F5-4414-8DFF-F59361C5BC0E}.png

I gave the encoder 5V via brown (5V) and blue (GND) wires, and plugged black (OUT A) and white (OUT B) into digital pins 5 and 6. I also tested other pins (2 and 3). I plugged the orange wire (OUT Z) into a random digital pin (8), but did not call it in my code.

TROUBLESHOOTING

1. Initially I couldn't get Basic.ino to run. I got the following errors:

direct_pin_read.h:8:56: note: in definition of macro 'DIRECT_PIN_READ'
 #define DIRECT_PIN_READ(base, mask)     (((*(base)) & (mask)) ? 1 : 0)

FIX: I uninstalled and installed the library. 

2. I thought 2000 pulses = 1 revolution, but I'm finding that 1 revolution ~ 8000 pulses. I'm using pins 2 and 3 for black and white wires. Even weirder - when I switch to different pins, I find that 1 revolution ~ 70 pulses. I thought that the resolution of this encoder was 2000 pulses per revolution. HALP!

FIX: It turns out that on an Arduino Uno, pins 2 and 3 are dedicated interrupt pins, which is a good thing for counting pulses as quickly as possible. You want to use these pins (and if you aren't using an Arduino Uno, check and see which are the hardware interrupt pins for your board). The code is just incrementing when the signals read on either pin 2 or 3 change, and since A and B (output from this quadrature encoder) change 4 times per change in position (the laser shines through a new window on the internal wheel). This is because the waveform generated by A is 90 degrees offset from B, or equivocally, the the phase offset of B relative to A is 1/4 the period of A. Talk to Claire or Nora if you are confused and would like a whiteboard demonstration of how a quadrature encoder works.

When I tested other pins:, such as 5 and 6, and 11 and 10, I found ~70 PPR. Note that if you switch the white and black wire, this just switches whether CW or CCW rotation corresponds to the encoder count increasing. Don't use pin 13 (built in LED); the counter misses pulses likely due to hardware conflicts.

Linear Actuators (QTY 4)

332c1edd-2f77-4b04-af92-56cd22efc3d3.jpg

These little 50mm linear actuators are from DF Robot will be a great asset to a project requiring controlled linear movement. Although they nominally take 6V, I was able to run them using 5V on an Arduino Uno. I interfaced with a Sparkfun DC Motor driver, and was impressed at the force they delivered. Even when pushing fairly hard with my finger, the actuator was able to extend fully. These are awesome. Note that you will need to use a driver, or else construct your own H-bridge circuit to retract them after they've extended.

SENSOR 

(ADD PHOTO)

PM2.5 Air Quality Sensor and Breadboard Adapter Kit

PM2.5 Air Quality Sensor and Breadboard Adapter Kit [PMS5003] : Adafruit Industries, Unique & fun DIY electronics and kits

Arduino Code | PM2.5 Air Quality Sensor | Adafruit Learning System

Use case, any helpful tips?

The PM2.5 Air Quality Sensor provides real-time, reliable measurement of PM2.5 dust concentrations! (PM2.5 refers to particles that are 2.5 microns or smaller in diameter.) This sensor uses laser scattering to radiate suspending particles in the air, then collects scattering light to obtain the curve of scattering light change with time. The microprocessor calculates equivalent particle diameter and the number of particles with different diameter per unit volume.

Troubleshooting (document any issues you ran into and their resolution):

Issue: The code provided in the link is set up to be able to handle both hardware and software serial communication.

Fix: Due to this when using that code, the user needs to uncomment out a few commented-out lines. These lines are the pin set ups and the serial communication lines. User needs to make sure to comment / uncomment a few lines according to what type of serial communication they are using. 

SENSOR 

(ADD PHOTO)

Adafruit 9-DOF Orientation IMU Fusion Breakout - BNO085

Adafruit 9-DOF Orientation IMU Fusion Breakout - BNO085 (BNO080) [STEMMA QT / Qwiic] : Adafruit Industries, Unique & fun DIY electronics and kits

Code link:

Overview | Adafruit 9-DOF Orientation IMU Fusion Breakout - BNO085 | Adafruit Learning System

Use case, any helpful tips?

I2C Wiring:

Troubleshooting (document any issues you ran into and their resolution):

Issue: When using I2C communication, the library needed to use the IMU is too large and complex to fit onto the Arduino Uno. 

Fix: To use this sensor with an Arduino Uno you are to use UART communication. This means you cannot use the nice I2C chord provided with the sensor. Instead, you have to plug the header pins into a breadboard and manually set up each pin. 

PINOUTS FOR UART

VIN ---> 5V

GND ---> GND

SDA ---> Digital Pin 2

P0 ---> 5V

No other pins need to be connected

CODE FOR UART

#include <SoftwareSerial.h>
#include <Adafruit_BNO08x_RVC.h>

// Connect Arduino Pin 2 to BNO085 SDA (TX Out)
SoftwareSerial softwareSerial(2, 3);

Adafruit_BNO08x_RVC rvc;

void setup() {
  Serial.begin(115200);
  while (!Serial) delay(10);

  Serial.println("Adafruit BNO08x RVC Test!");
  softwareSerial.begin(115200);

  // Pass our software serial port to the RVC library
  if (!rvc.begin(&softwareSerial)) {
    Serial.println("Could not find sensor. Check wiring and P0 pin!");
    while (1) delay(10);
  }
  
  Serial.println("Sensor Found! Starting stream...");
}

void loop() {
  BNO08x_RVC_Data heading;
  
  // Read the incoming continuous data stream
  if (rvc.read(&heading)) {
    Serial.print("Yaw: ");
    Serial.print(heading.yaw);
    Serial.print(" Pitch: ");
    Serial.print(heading.pitch);
    Serial.print(" Roll: ");
    Serial.println(heading.roll);
  }
}

Note: When using UART with an Arduino Uno you can only utilize the gyroscopic features of the unit, you cannot access any of those advanced features (like step counting, shake detection, activity tracking, or alternative heading vectors) as long as you are using the UART-RVC with an Arduino Uno. 

Adafruit Ultimate GPS PA1616S

*add photo 

Use case, any helpful tips?: 

The Adafruit Ultimate GPS module gives any microcontroller project access to location, time, date, speed and heading data---pulled directly from GPS satellites.

Common Uses:

Very Helpful Documentation I referenced

I particularly found the direct computer wiring, computer Arduino wiring and, computer Arduino parsing helpful. Each section tests three stages of working with the GPS module and each have a distinct purpose: 

Direct Computer Wiring 

This bypasses the Arduino's microcontroller entirely and routes the GPS straight to the USB-to-serial chip (using a blank sketch) --> RAW VERIFICATION 

* add wiring photo 

* add blank sketch 

Troubleshooting 

  1. Issue: Serial monitor shows garbled serial output instead of readable NMEA sentences

Becuase the data looks crazy here but nothing is actually introduced to the wiring we know the problem is the GPS hardwire or our wiring and NOT the code. 

ex) :

AI5 ⸮235953.800,V,,,,,0.00,0.00,050180,,,N*42
⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮$GPGGA,000518.800,,,,,0,0,,,M,,M,,*4C

instead of 

$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPRMC,000518.800,V,,,,,0.00,0.00,050180,,,N*45
$GPGGA,000519.800,,,,,0,0,,,M,,M,,*4D
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPRMC,000519.800,V,,,,,0.00,0.00,050180,,,N*44

  1. Fix: 

Breakout Arduino Wiring

Now that we have completed a sanity check that the sensor works as expected without other software variables, breakout Arduino wiring will test the Arduino's own microcontroller reads the incoming serial stream. This will prove that the full data path works. 

GPS --> Arduino --> USB --> Computer 

I used this library on an Arduino Uno and the example sketch GPS_SoftwareSerial_ECHO:

* add photo of library name and example sketch 

* add photo of wiring 

Troubleshooting 

  1. Issue: Serial monitor doesn't output readable NMEA sentences

ex) : ?????????????????????????????????

instead of 

Software3*30
$PMTK705,AXN_2.51_3339_17112000,0004,1616S,1.0*56
⸮Software Serial GPS Test Echo Test
Get version!
$GPGGA,000016.799,,,,,0,0,,,M,,M,,*48
$GPGLL,,,,,000016.799,V,$PMTK705,AXN_2.51_3339_17112000,0004,1616S,1.0*56
$GPGGA,000018.799,,,,,0,0,,,M,,M,,*46
$GPGLL,,,,,000018.799,V,N*74
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,1,1,00*79
$GPRMC,000018.799,V,,,,,0.00,0.00,050180,,,N*4F

1. Fix: 

Breakout Arduino Parsing 

Up until now, we have just been displaying raw text. This is where we will use a library to interpret the NMEA sentences into usable variables like latitude, longitude, speed, time, fix status etc. 

I used the same library and wiring as the previous wiring section on an Arduino Uno but now we will use the example sketch GPS_SoftwareSerial_Parsing:

* add photo of library name and example sketch 

Thermocouple amplifier (MAX31856)

image.png

Code:

Use the Adafruit Max31856 library for Arduino. 

{36E956B3-3DFB-42BA-A77F-30E707C36CFB}.png

Make sure you either use the hardware SPI pins for your microcontroller, or use software SPI and then you can use whatever pins you want but you must specify which pins you are using in the line: Adafruit_MAX31856 maxthermo = Adafruit_MAX31856(9, 10, 11, 12);. Also make sure to wire the positive thermocouple lead to the + terminal, which for a type K thermocouple is yellow (negative is red). For a Type T thermocouple, blue is + and red is negative. Red is always negative for these two, and you can remember that because red is an angry, negative emotion. Forget your intuition about red being positive from DC circuits. Type T and K thermocouples comprise 99% of the thermocouples available for checkout from the ITLL.

You should see this output (data are in Celsius):

{78C3B39A-6966-4403-BE8E-ECCE4EEF824A}.png

You can also open Serial Plotter (ARD IDE 2.x: upper right corner, plot icon, ARD IDE 1.x: Tools-->Serial Plotter), which is nice (If you don't see data, comment out the "Serial.print(".") function so that you are only printing out numbers):

{BDC32E1B-D640-44A6-AB72-E94BDB4A2682}.png

Troubleshooting

Problem 1: The output looked like this:

{BB3B857E-B5BD-460C-B24D-AC9A9928683C}.png

Solution 1: Change from hardware SPI to software SPI and specify the correct pins for CS, DI, DO, and CLK. And DRDY ("data ready" - this is the pin that is pulled low when the amplifier completes its operation and the chip is ready with temperature data for you).

Comment out line 11 and comment in line 9 (remember ctrl + ? is the hot key for commenting in/out one or multiple lines of code):

{3C7D4362-AA4B-46B8-A3FE-EF8379138F1D}.png

Change to:

{A2B6FE7B-037C-4CE6-8D5A-5718C15C27AC}.png


Problem 2: When trying to upload edits, I got this annoying error (at least with an Arduino Nano)

{3C02DD5C-73B8-40AA-B890-CC8D93DE16EE}.png

Solution 2: Close Serial Monitor and try again. If that doesn't fix the problem, close and restart Arduino IDE. 

Problem 3: Everything worked one day, then the next day, on the same computer, etc - the code wouldn't upload and I got this nasty long error message (open dropdown):

yikes

C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_SPIDevice*, unsigned int, _Adafruit_BusIO_SPIRegType, unsigned char, unsigned char, unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_SPIDevice*, unsigned int, _Adafruit_BusIO_SPIRegType, unsigned char, unsigned char, unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, Adafruit_SPIDevice*, _Adafruit_BusIO_SPIRegType, unsigned int, unsigned char, unsigned char, unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, Adafruit_SPIDevice*, _Adafruit_BusIO_SPIRegType, unsigned int, unsigned char, unsigned char, unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_GenericDevice*, unsigned int, unsigned char, unsigned char, unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_GenericDevice*, unsigned int, unsigned char, unsigned char, unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::write(unsigned char*, unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::write(unsigned long, unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::readCached()'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::read(unsigned char*, unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::read()'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::read(unsigned int*)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::read(unsigned char*)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::print(Stream*)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::println(Stream*)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_RegisterBits::Adafruit_BusIO_RegisterBits(Adafruit_BusIO_Register*, unsigned char, unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_RegisterBits::Adafruit_BusIO_RegisterBits(Adafruit_BusIO_Register*, unsigned char, unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_RegisterBits::read()'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_RegisterBits::write(unsigned long)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::width()'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::setWidth(unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::setAddress(unsigned int)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register.cpp.o (symbol from plugin): In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::setAddressWidth(unsigned int)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_BusIO_Register - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_GenericDevice.cpp.o (symbol from plugin): In function `Adafruit_GenericDevice::Adafruit_GenericDevice(void*, bool (*)(void*, unsigned char*, unsigned int), bool (*)(void*, unsigned char const*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char const*, unsigned int))':
(.text+0x0): multiple definition of `Adafruit_GenericDevice::Adafruit_GenericDevice(void*, bool (*)(void*, unsigned char*, unsigned int), bool (*)(void*, unsigned char const*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char const*, unsigned int))'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_GenericDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_GenericDevice.cpp.o (symbol from plugin): In function `Adafruit_GenericDevice::Adafruit_GenericDevice(void*, bool (*)(void*, unsigned char*, unsigned int), bool (*)(void*, unsigned char const*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char const*, unsigned int))':
(.text+0x0): multiple definition of `Adafruit_GenericDevice::Adafruit_GenericDevice(void*, bool (*)(void*, unsigned char*, unsigned int), bool (*)(void*, unsigned char const*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char const*, unsigned int))'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_GenericDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_GenericDevice.cpp.o (symbol from plugin): In function `Adafruit_GenericDevice::Adafruit_GenericDevice(void*, bool (*)(void*, unsigned char*, unsigned int), bool (*)(void*, unsigned char const*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char const*, unsigned int))':
(.text+0x0): multiple definition of `Adafruit_GenericDevice::begin()'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_GenericDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_GenericDevice.cpp.o (symbol from plugin): In function `Adafruit_GenericDevice::Adafruit_GenericDevice(void*, bool (*)(void*, unsigned char*, unsigned int), bool (*)(void*, unsigned char const*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char const*, unsigned int))':
(.text+0x0): multiple definition of `Adafruit_GenericDevice::end()'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_GenericDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_GenericDevice.cpp.o (symbol from plugin): In function `Adafruit_GenericDevice::Adafruit_GenericDevice(void*, bool (*)(void*, unsigned char*, unsigned int), bool (*)(void*, unsigned char const*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char const*, unsigned int))':
(.text+0x0): multiple definition of `Adafruit_GenericDevice::write(unsigned char const*, unsigned int)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_GenericDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_GenericDevice.cpp.o (symbol from plugin): In function `Adafruit_GenericDevice::Adafruit_GenericDevice(void*, bool (*)(void*, unsigned char*, unsigned int), bool (*)(void*, unsigned char const*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char const*, unsigned int))':
(.text+0x0): multiple definition of `Adafruit_GenericDevice::read(unsigned char*, unsigned int)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_GenericDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_GenericDevice.cpp.o (symbol from plugin): In function `Adafruit_GenericDevice::Adafruit_GenericDevice(void*, bool (*)(void*, unsigned char*, unsigned int), bool (*)(void*, unsigned char const*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char const*, unsigned int))':
(.text+0x0): multiple definition of `Adafruit_GenericDevice::readRegister(unsigned char*, unsigned char, unsigned char*, unsigned int)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_GenericDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_GenericDevice.cpp.o (symbol from plugin): In function `Adafruit_GenericDevice::Adafruit_GenericDevice(void*, bool (*)(void*, unsigned char*, unsigned int), bool (*)(void*, unsigned char const*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char*, unsigned int), bool (*)(void*, unsigned char*, unsigned char, unsigned char const*, unsigned int))':
(.text+0x0): multiple definition of `Adafruit_GenericDevice::writeRegister(unsigned char*, unsigned char, unsigned char const*, unsigned int)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_GenericDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice.cpp.o (symbol from plugin): In function `Adafruit_I2CDevice::Adafruit_I2CDevice(unsigned char, TwoWire*)':
(.text+0x0): multiple definition of `Adafruit_I2CDevice::Adafruit_I2CDevice(unsigned char, TwoWire*)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice.cpp.o (symbol from plugin): In function `Adafruit_I2CDevice::Adafruit_I2CDevice(unsigned char, TwoWire*)':
(.text+0x0): multiple definition of `Adafruit_I2CDevice::Adafruit_I2CDevice(unsigned char, TwoWire*)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice.cpp.o (symbol from plugin): In function `Adafruit_I2CDevice::Adafruit_I2CDevice(unsigned char, TwoWire*)':
(.text+0x0): multiple definition of `Adafruit_I2CDevice::end()'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice.cpp.o (symbol from plugin): In function `Adafruit_I2CDevice::Adafruit_I2CDevice(unsigned char, TwoWire*)':
(.text+0x0): multiple definition of `Adafruit_I2CDevice::detected()'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice.cpp.o (symbol from plugin): In function `Adafruit_I2CDevice::Adafruit_I2CDevice(unsigned char, TwoWire*)':
(.text+0x0): multiple definition of `Adafruit_I2CDevice::begin(bool)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice.cpp.o (symbol from plugin): In function `Adafruit_I2CDevice::Adafruit_I2CDevice(unsigned char, TwoWire*)':
(.text+0x0): multiple definition of `Adafruit_I2CDevice::write(unsigned char const*, unsigned int, bool, unsigned char const*, unsigned int)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice.cpp.o (symbol from plugin): In function `Adafruit_I2CDevice::Adafruit_I2CDevice(unsigned char, TwoWire*)':
(.text+0x0): multiple definition of `Adafruit_I2CDevice::_read(unsigned char*, unsigned int, bool)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice.cpp.o (symbol from plugin): In function `Adafruit_I2CDevice::Adafruit_I2CDevice(unsigned char, TwoWire*)':
(.text+0x0): multiple definition of `Adafruit_I2CDevice::read(unsigned char*, unsigned int, bool)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice.cpp.o (symbol from plugin): In function `Adafruit_I2CDevice::Adafruit_I2CDevice(unsigned char, TwoWire*)':
(.text+0x0): multiple definition of `Adafruit_I2CDevice::write_then_read(unsigned char const*, unsigned int, unsigned char*, unsigned int, bool)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice.cpp.o (symbol from plugin): In function `Adafruit_I2CDevice::Adafruit_I2CDevice(unsigned char, TwoWire*)':
(.text+0x0): multiple definition of `Adafruit_I2CDevice::address()'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice.cpp.o (symbol from plugin): In function `Adafruit_I2CDevice::Adafruit_I2CDevice(unsigned char, TwoWire*)':
(.text+0x0): multiple definition of `Adafruit_I2CDevice::setSpeed(unsigned long)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_I2CDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp.o (symbol from plugin): In function `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)':
(.text+0x0): multiple definition of `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp.o (symbol from plugin): In function `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)':
(.text+0x0): multiple definition of `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp.o (symbol from plugin): In function `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)':
(.text+0x0): multiple definition of `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, signed char, signed char, signed char, unsigned long, _BitOrder, unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp.o (symbol from plugin): In function `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)':
(.text+0x0): multiple definition of `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, signed char, signed char, signed char, unsigned long, _BitOrder, unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp.o (symbol from plugin): In function `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)':
(.text+0x0): multiple definition of `Adafruit_SPIDevice::~Adafruit_SPIDevice()'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp.o (symbol from plugin): In function `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)':
(.text+0x0): multiple definition of `Adafruit_SPIDevice::~Adafruit_SPIDevice()'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp.o (symbol from plugin): In function `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)':
(.text+0x0): multiple definition of `Adafruit_SPIDevice::begin()'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp.o (symbol from plugin): In function `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)':
(.text+0x0): multiple definition of `Adafruit_SPIDevice::transfer(unsigned char*, unsigned int)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp.o (symbol from plugin): In function `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)':
(.text+0x0): multiple definition of `Adafruit_SPIDevice::transfer(unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp.o (symbol from plugin): In function `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)':
(.text+0x0): multiple definition of `Adafruit_SPIDevice::beginTransaction()'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp.o (symbol from plugin): In function `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)':
(.text+0x0): multiple definition of `Adafruit_SPIDevice::endTransaction()'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp.o (symbol from plugin): In function `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)':
(.text+0x0): multiple definition of `Adafruit_SPIDevice::setChipSelect(int)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp.o (symbol from plugin): In function `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)':
(.text+0x0): multiple definition of `Adafruit_SPIDevice::beginTransactionWithAssertingCS()'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp.o (symbol from plugin): In function `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)':
(.text+0x0): multiple definition of `Adafruit_SPIDevice::endTransactionWithDeassertingCS()'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp.o (symbol from plugin): In function `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)':
(.text+0x0): multiple definition of `Adafruit_SPIDevice::write(unsigned char const*, unsigned int, unsigned char const*, unsigned int)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp.o (symbol from plugin): In function `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)':
(.text+0x0): multiple definition of `Adafruit_SPIDevice::read(unsigned char*, unsigned int, unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp.o (symbol from plugin): In function `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)':
(.text+0x0): multiple definition of `Adafruit_SPIDevice::write_then_read(unsigned char const*, unsigned int, unsigned char*, unsigned int, unsigned char)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp.o (symbol from plugin): In function `Adafruit_SPIDevice::Adafruit_SPIDevice(signed char, unsigned long, _BitOrder, unsigned char, SPIClass*)':
(.text+0x0): multiple definition of `Adafruit_SPIDevice::write_and_read(unsigned char*, unsigned int)'
C:\Users\clpo1571\AppData\Local\arduino\sketches\20A885DA607E1CD1BE80325411DFD77C\libraries\Adafruit_BusIO\Adafruit_SPIDevice - Copy.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
exit status 1

Compilation error: exit status 1

Often with long error messages like this, I look at what the very first or last error was. In this case, the first error was: " In function `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)':
(.text+0x0): multiple definition of `Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice*, unsigned int, unsigned char, unsigned char, unsigned char)'"

I decided to run an example SPI code from the Adafruit_BusIO library and lo and behold it looks like the confusion was with multiple BUSIO libraries. 

{7762E4CD-6BE2-488D-B439-D4152D05DEC2}.png

Solution 3: Simply uninstalling and reinstalling the Adafruit Bus IO library fixed the issue completely.

{758D150F-49A8-46E6-92D9-BDB707F59B26}.png

Measuring distance/proximity

The Electronics Center has a wide variety of object/distance detection sensors available for your project needs. 

Everything listed below is available for checkout from the Electronics Center (ECCE 167).

If you just need to sense if an object has moved (e.g., counting fan blade rotations or detecting a waving hand):

If you need to quanitfy or measure a distance to an object, we recommend:

Measuring distance/proximity

Passive Infrared (PIR) Sensors

Overview

PIR or Passive Infrared Sensors are commonly used in projects where students want a device capable of motion detection. These sensors detect movement by measuring changes in infrared radiation emitted by warm objects, such as people or animals, within their field of view. These sensors are known as "passive" sensors, as they merely listen to changes in energy, and do not emit any signals themselves. This passive characteristic makes them ideal for low power applications.

Staff at the ITLL tested the detection range of these sensors along with doing some research and found it could sense motion up to approximately 23 feet or 7 meters (depending on model and conditions). You may have seen these sensors before as they are commonly used for automatic lights, interactive exhibits, or security alarms. At the ITLL, you can find them controlling the lights within our lab spaces to save energy. 

Students are welcome to come by and check out sensors from the Electronics Center. These are the sensors you can check out from the ITLL:  link to inventory . If you do not see a sensor listed feel free to come in and chat with an Engineer about you project. 

What is a PIR Sensor?

image.png

A PIR sensor comes with a small white dome shaped lens on top of the PCB. This lens, the Fresnel lens, helps focus light from any direction to the small pyroelectric sensor underneath. When motion occurs, half of this sensor detects a change in IR before the other, and the difference causes a signal change (from LOW to HIGH). These sensors also include a sensitivity and time delay adjustment potentiometer. Which allow you to change the range or distance the sensor can detect, and how long the sensor remains active (before switching back from HIGH to LOW). Below you can find an image labeling the potentiometers.

Wiring the Sensor

Important:  Look up your specific sensors pinout and input voltage as they can differ. The pinout for the sensor we used in this demo was...

image.png

Example circuit setup: 

image.png

Troubleshooting

  1.  If sensor reading always HIGH or ON
    - Sensor may be warming up (10-60 seconds after being turned on)
    - Reduce sensitivity with potentiometer
    - Ensure stable power supply
  2.  If no output changes
    - Verify correct wiring 
    - Use Serial Monitor to debug readings
  3. If false triggering
    - Avoid pointing sensor at heat source (like a vent)
    - Ensure no vibration of sensor mount

Simple Code

image.png

  1. int LED = 6;        // LED connected to digital pin 6
  2. int PIR = 2;        // PIR motion sensor connected to digital pin 2
  3.  
  4. int state = LOW;    // Tracks previous motion state:
  5.                     // LOW  = no motion previously detected
  6.                     // HIGH = motion previously detected
  7.  
  8. int value = 0;      // Stores current reading from PIR sensor (HIGH or LOW)
  9.  
  10. void setup() {
  11.   pinMode(LED, OUTPUT);   // Set LED pin as output (Arduino controls LED)
  12.   pinMode(PIR, INPUT);    // Set PIR pin as input (Arduino reads sensor signal)
  13.    
  14.   Serial.begin(9600);     // Start serial communication for debugging/output
  15. }
  16.  
  17. void loop() {
  18.   // Read the current value from the PIR sensor
  19.   value = digitalRead(PIR);  // Will be HIGH (motion) or LOW (no motion)
  20.  
  21.   // If motion is detected
  22.   if (value == HIGH) {
  23.     digitalWrite(LED, HIGH);  // Turn LED ON
  24.     delay(100);               // Keep LED on briefly (100 ms)
  25.  
  26.     // Only print when motion FIRST starts (prevents spamming Serial Monitor)
  27.     if (state == LOW) {
  28.       Serial.println("Motion Detected");
  29.       state = HIGH;           // Update state to indicate motion is active
  30.     }
  31.   }
  32.   else {  // If NO motion is detected
  33.     digitalWrite(LED, LOW);   // Turn LED OFF
  34.     delay(100);               // Small delay
  35.  
  36.     // Only print when motion JUST stopped
  37.     if (state == HIGH) {
  38.       Serial.println("Motion has stopped");
  39.       state = LOW;            // Update state to indicate no motion
  40.     } 
  41.   }
  42. }
Measuring distance/proximity

Ultrasonic Sensor

Overview

Ultrasonic Sensors are a common form of proximity and distance sensors used in a wide variety of different projects. These sensors feature both an emitter (trigger) which releases an ultrasonic sound wave, and a receiver (echo) which reads the ultrasonic sound wave as it returns. 

 

Claire suggested edits: 

In the Overview, provide the range and accuracy of these sensors. I'd get rid of the first sentence. Second sentence is great because it explains the working principle.

I actually had something written up about these sensors elsewhere, and I will paste my sentences here. Feel free to take 'em or leave 'em:

These sensors can detect objects within a range of 2 cm - 4 m with a ranging accuracy of up to 3mm. One thing to note is that they have a measure angle of 15 degrees, so they do well at measuring objects directly in front of the sensor. For most applications, this is favorable. 

image.png

Helpful resource from Sparkfun with example code, and wiring diagram: https://www.sparkfun.com/ultrasonic-distance-sensor-hc-sr04.html

 Students are welcome to come by and check out sensors from the Electronics Center. These are the sensors you can check out from the ITLL:  link to inventory . If you do not see a sensor listed feel free to come in and chat with an Engineer about you project. 

What is an Ultrasonic Sensor?

image.png

A PIR sensor comes with a small white dome shaped lens on top of the PCB. This lens, the Fresnel lens, helps focus light from any direction to the small pyroelectric sensor underneath. When motion occurs, half of this sensor detects a change in IR before the other, and the difference causes a signal change (from LOW to HIGH). These sensors also include a sensitivity and time delay adjustment potentiometer. Which allow you to change the range or distance the sensor can detect, and how long the sensor remains active (before switching back from HIGH to LOW). Below you can find an image labeling the potentiometers.

Wiring the Sensor

Important:  Look up your specific sensors pinout and input voltage as they can differ. The pinout for the sensor we used in this demo was...

image.png

Example circuit setup: 

image.png

Troubleshooting

Claire edits: 

  1.  If sensor reading 0 only
    - Run test code below
    - Ensure pin definitions are correct and wires are plugged in to correct spots 
  2. If nothing shows up in serial monitor
    - Make sure you include Serial.begin(9600);
    - Ensure serial monitor has 9600 baud rate selected

Simple Code

image.png

// Define pin numbers
const int trigPin = 3;                   // pin sending the ultrasonic wave
const int echoPin = 2;                   // pin reading the ultrasonic wave
long duration;                           // time it takes for wave to travel
int distance;                            // distance wave has traveled

void setup() {
 
  pinMode(trigPin, OUTPUT);             // Sets the trigPin as an Output
  pinMode(echoPin, INPUT);              // Sets the echoPin as an Input
 
  Serial.begin(9600);                   //initializing serial communication at 9600 baud rate  
}

void loop() {

  // Trigger the sensor by sending a HIGH pulse for 10 microseconds
  digitalWrite(trigPin, HIGH);
  delay(10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);    // pulseIn() returns the sound wave travel time in microseconds

  distance = duration * 0.034 / 2;      // Calc. distance 9speed of sound is 0.034 cm per microsec. and wave goes there and back0

  // Print the distance to the Serial Monitor
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");
  
  delay(200);                          // Delay before the next reading
}
Measuring distance/proximity

Measuring distance/proximity

If you need to quantify distance:

SHARP 2Y0A02, IR sensor (λ = 850 ± 70nm)
At-a-glance useful details:

{54C81708-A400-4B9E-AF00-ADA567605335}.png

{71064E72-9B44-41D5-8E68-45F4EB5E22A0}.png

Ultrasonic Sensor (HC-SR04)

image.png

These sensors can detect objects within a range of 2 cm - 4 m with a ranging accuracy of up to 3mm. One thing to note is that they have a measure angle of 15 degrees, so they do well at measuring objects directly in front of the sensor. For most applications, this is favorable.

 

Helpful resource from Sparkfun with example code, and wiring diagram: https://www.sparkfun.com/ultrasonic-distance-sensor-hc-sr04.html

 

If you just need to know if an object is present or not:

 (e.g., detecting fan speed, motion detector, etc.)
Hall Sensor (AH1815, from Treston)

 


Measuring distance/proximity

IR LED & transceiver

Two options:

  1. Single PCB with LED and transceiver
  2. LED and transceiver from Treston (BYOC or build your own circuit)

Good for:

Detecting a moving object less than few inches away from the sensor

Measuring distance/proximity

Hall Sensor (AH1815, from Treston)

Author: Claire Porter

Overview

Hall sensors are available from the Treston. The presence of a magnetic field switches their output pin (pin 3) from HIGH to LOW. 

Detection distance: ~1cm 

Pictures illustrating short range of sensor

To test the range of the Hall sensor. I used my nametag magnet and held it far away from the sensor. I slowly brought the magnet close until I read a low signal on the digital pin to which I wired the output of this sensor (yellow jumper wire going to Arduino digital pin 8). The images below demonstrate the threshold distance close enough to trigger the sensor, as well as the fact that the sensor detects a field behind or in front of it. 

Media (1).jpg

 

 

Media.jpg

Magnetic field operating point: ~350 Gauss (a cheap kitchen magnet is around 100 Gauss, a strong magnet is 200-2,000 Gauss)

Pinout for the AH1815, note the orientation/non-flat face is up

{F75335B5-CB78-4AE7-ADCD-45B9B438A954}.png

How to use

You will need to add a pull-up resistor to the output pin. I'd recommend a 10k resistor. 

{0465A7D3-0478-4D10-95AE-48BE238D1C61}.png

Image above is from this component's  data sheet

See if you can wire this circuit just based off of the image above!

Need help?

I will show you an image below of how I wired it onto a breadboard. Importantly, you could wire this differently, or solder on longer wires onto each pin of the Hall sensor, or solder this onto a protoboard. 

Regardless of whether you are using a breadboard or soldering, you need to make sure that:

  1. Leftmost pin goes to power (2.5-5.5V input range, so you can use this with a 3.3V microcontroller)
  2. Middle pin goes to ground
  3. Rightmost pin goes to a digital pin on your microcontroller
  4. Add a 10kOhm resistor between power and rightmost (output) pin
  5. Add a 100 nF capacitor across power and ground to decrease noise

shared image.jpg

Sample Arduino code

int hallpin = 8;

void setup() {
  pinMode(8, INPUT);
  Serial.begin(9600);
}

void loop() {
  if (digitalRead(hallpin) == true) {   //this is the same as asking if digitalRead(hallpin) == HIGH
    Serial.println("Waiting...");
    delay(100);
  }
  else{
    Serial.println("OOh a magnet!");
    delay(100);
  }
}

Troubleshooting

1) There's no output when I run the code above

2) The output bounces all over the place

3) The output thinks there is a magnet there when there isn't

4) It's too slow

 

Strain gauges

In this guide, I will walk you through setting up a strain gauge measurement with a NI-9237 DAQ (both strain gauges and NI-9237 DAQ are available for checkout) in the quarter bridge (1 active strain gauge) configuration. Other configurations are possible. 

Data from the test setup below (bending the aluminum bar below with hand strength of an ESS test subject):

image.png

You will need:

shared image (19).jpg

*note : if you are not using a 120 Ohm strain gauge, use the appropriate terminal block that matches the nominal resistance value of your strain gauge

Hardware

Pin 0 on NI-9944 attaches to red lead of strain gauge attached to one side of strain gauge

Pin 1 and 2 attach to white and black leads, which are connected to the same point on the other side of the strain gauge 

shared image (18).jpg

Software

Effectively we are just following this guide from NI. I would recommend using LabVIEW.

image.png

I will point out a couple of things below that might not be obvious from the guide:

{C2196EFE-BE7D-4AAC-9DDC-013FE8866FA2}.png

Select "strain" (analog input) when you configure the DAQ assistant in LabVIEW. This will bring up the menu above.

  1. The scaled units generated are already in strain. How convenient! LabVIEW is solving the following equation for you (equation source):

{953467F7-966A-486E-A71D-F3E056550413}.png

Recall that the definition of strain is change in length divided by original length. So 1 microstrain = a change in length of 1 mm for a 1 km long bar. Wow - that's not a lot of strain! What is the strain if a 5.00 cm bar is compressed and now measures 4.95 cm?