# Part 1: Sensor Connection & Data Reading
###### tags: `TA Stuff RP2` `Raspberry Pi Pico`
In this tutorial, you will read about the pinout in your development board, how to connect a sensor to your board, and finally, use the sensor(s) in your code.
We will:
+ read about your development board pinout.
+ read about how to connect a sensor physically to your board.
+ read data from basic **Analog** and **Digital** sensors.
+ read about how to get a library and use it in your code.
+ read about how to connect several sensors with the help of a breadboard.
As always, we'll continuously update this walkthrough. **Is there anything that needs to be clarified, or have you experienced some issues? Please add a comment.** You do this by highlighting the text and then you can write a comment on the highlighted part. You need to log in/create an account on HackMD first.
## 0. Prerequisites
To start this tutorial you must already finished with the following tutorials:
* IDE installation [**here**](https://hackmd.io/@lnu-iot/rkiTJj8O9)
* Raspberry Pi Pico W firmware upgrade [**here**](https://hackmd.io/@lnu-iot/rkFw7gao_)
* Getting familiar with terminology and project structure [**here**](https://hackmd.io/@lnu-iot/B1T1_KM83)
## Raspberry Pi Pico W & Raspberry Pi Pico 2 W Pinout
Both the Raspberry Pi Pico W and its successor, the Raspberry Pi Pico 2 W, share the same pinout, as shown in the following diagram.

This schematic shows information about pins on your Raspberry Pi Pico W and their usage is available [**here**](https://datasheets.raspberrypi.com/picow/PicoW-A4-Pinout.pdf) as pdf file. This schematic shows information about pins on your Raspberry Pi Pico 2 W and their usage is available [**here**](https://datasheets.raspberrypi.com/picow/pico-2-w-pinout.pdf) as pdf file. You will regularly come back to this and eventually familiarize yourself with it.
:::info
Information about different pin types and communication protocols presented in the course recorded lectures and partially in [**this tutorial**](https://hackmd.io/@lnu-iot/B1T1_KM83)
:::
### Analog to Digital
In the schematic, you might first look at the **Analog Pins** called `ADC#`. ADC stands for Analog to Digital Converter - and it takes an input signal from your sensor and converts it to a digital representation - something the computer can work with.
The difference between analog and digital is that **analog** signals *vary*, they go anywhere between 0 and some other voltage, for example, 3.3V (or 5V); while **digital** signals are either 0 or that voltage - which means they are binary, _low_ or _high_ voltage - or in computer language, `0` or `1` (_false_ or _true_).
Your computer works in binary, that's why we need an analog-to-digital converter to work with the signals. We will show how to use them in this tutorial.
### General Purpose Pins
As you might note all PINs that start with `GP#` are General Purpose Input/Output (`GPIO`) Pins and they can be connected to the sensors and be used by the `Pin()` method in MicroPython code.
## How to connect a sensor physically
:::danger
**⚠️IMPORTANT⚠️**
+ Disconnect the power/USB cable from the Development/Expansion board before connecting sensors or changing a sensor pin. This allows us to check that everything is correct before powering the board.
+ Always check if the sensor works on 5V or 3.3V before connecting your sensor to the board. If you are unsure check the sensor datasheet or consult it with a TA.
+ We recommend using colored wires to make it easier to distinguish which wires are which.
+ We recommend using a breadboard if you have several sensors it makes the connection more visible.
:::
The basic sensors are generally quite easy to connect to the development board. They usually have 3 pins, one connects to 5V or 3.3V, another connects to the ground (GND, 0V), and one to a measuring pin, like `GP27`.
For example, to connect a MCP9700 analog temperature sensor you could do as follows:

Connect the positive voltage leg to `3V3`, the ground leg to `GND`, and the output leg to any pin GPIO pin (in this case, `GP27`).

:::danger
:warning: If you accidentally switch 3V3 and GND (connect 3V3 to sensor GND and GND to sensor 3V3) it might burn out your sensor.
:::
To connect your sensors to the development board, a **breadboard** is very useful. They usually contain 2 longer rails on each side, to easily connect to $V_{dd}$ (Positive voltage, operating voltage) and __GND__ (ground, 0V) to all your components. Each row of a breadboard is numbered and contains a rail as shown in the figure below, to easily allow you to connect pins and wires.

### Sensor connection examples
Here's an [**album of some connections that we've made for common sensors and output devices**](https://imgur.com/a/vGyjsWi).
:::info
You can make your diagrams like the ones above using the program [**fritzing**](https://fritzing.org/). Alternatively, you can visit our [**GitHub page**](https://github.com/iot-lnu/pico-w/tree/main) and see if your sensor is listed under `sensor-examples`.
:::
If your sensor isn't in the album, or our GitHub repository, then it's recommended that you read the datasheet of the sensor to figure out how to connect it. This can often be found on the same page you bought it, Sellers often provide datasheets or tutorials. [**Like this one, check it out!**](https://www.electrokit.com/upload/product/41015/41015810/User_guide.pdf) If there's no available, try searching the sensor name + datasheet or tutorial.
**If your sensor needs 5V** (often 3.3V works even when it's not specified) you can use the `VBUS` port on Raspberry Pi Pico if your device is connected via USB to your computer (`VBUS` is just the voltage that goes into your device, USB is 5V).
:::danger
:warning: Never use the `VBUS` pin as input power, it must always be used as output power. If your device is powered on by USB, then `VBUS` should only be used as output, e.g. to power sensors, etc.
:::
## Basic Analog sensors
Analog sensors are devices that produce analog output. These sensors observe the change in external factors such as light intensity, speed of the wind, solar radiation, and others. The output of an analog sensor generally ranges between 0V to 5V (or 3.3V).
In this section, we want to show you a typical example of how to do this in MicroPython. For this example, we'll use the [TO-92 (MCP9700)](https://www.electrokit.com/produkt/mcp9700-e-to-to-92-temperaturgivare/), an analog temperature sensor.

The first thing we want to do is to create an [ADC](https://docs.micropython.org/en/latest/esp8266/tutorial/adc.html) object for analog to digital conversion. This is the "thing" in the code we'll use to read from our sensor. We want to define where we want our `ADC` to collect its input from, that is, which pin our temperature sensor is connected to on the Raspberry Pi Pico.
```python
import machine
adc = machine.ADC(27)
```
In this case, we've connected it to pin `27`, we can now read our sensor.
```python
millivolts = adc.read_u16()
```
This reading comes as millivolts. To gather some useful data out of this, we have to convert it. This is common in the world of analog sensors, and to know how to convert the output of the sensor into something useful, we have to read its [datasheet](http://ww1.microchip.com/downloads/en/devicedoc/20001942g.pdf) (or use Google).
Now we can make this into actually runnable code on our development board!
Check this out!
```python=
import machine
import time
adc = machine.ADC(27)
sf = 4095/65535 # Scale factor
volt_per_adc = (3.3 / 4095)
while True:
time.sleep(2)
millivolts = adc.read_u16()
adc_12b = millivolts * sf
volt = adc_12b * volt_per_adc
# MCP9700 characteristics
dx = abs(50 - 0)
dy = abs(0 - 0.5)
shift = volt - 0.5
temp = shift / (dy / dx)
print(temp)
time.sleep(1)
```
This is just an example of an analog temperature sensor. However, reading from another kind of simple analog sensor would only differentiate in the last step where we convert from millivolts.
## Basic digital sensors
Contrary to analog sensors, digital sensors only output high or low - also known as the binary values `1` or `0`; in layman's terms, the sensor is either "on" or "off" (more advanced digital sensors, such as the DHT11/22, outputs a series of 1's and 0's which your development board interprets - often requiring a [library](#Sensors-that-require-a-library).
They could be anything from a basic tilt switch to a movement sensor. A prime example of a digital sensor is a [knock sensor](https://www.electrokit.com/en/product/knock-sensor/) (See figure below).

The knock sensor detects, as you can imagine, knocks and vibrations. The middle pin needs to be connected to **3.3V** and the pin denoted with a "**$-$**" should be connected to **Ground** (**GND**). If the sensor detects any vibrations, the pin denoted with an "**S**" is set to `0`. If *no* vibrations are detected, it is set to `1`. It is therefore pretty straightforward to extract the information from the sensor. The following image shows the schematic of how we can connect it to Raspberry Pi Pico W.

We can use the following code in `main.py` and start reading from this sensor.
:::warning
If the code below doesn't work as intended, your knock sensor is reverse wired, meaning that it doesn't trigger on 0, but on 1. If that is the case, change the **if-statement** to value == 0.
:::
```python=
from machine import Pin
import time
pin_input = Pin(27, Pin.IN)
while True:
value = pin_input.value()
if value == 1:
print("No vibration detected...")
else:
print("Vibration detected...")
time.sleep_ms(100)
```
The code above continuously checks if the sensor has been disturbed. If it has been disturbed, the string `Vibration detected...` is printed. Let's dissect the code into smaller pieces to understand what is happening:
We must import MicroPython libraries for `Pin` and `time` on top of the code.
```python
from machine import Pin
import time
```
Then, we need to import the necessary MicroPython modules. The [`Pin` module](https://docs.micropython.org/en/latest/rp2/quickref.html#pins-and-gpio) lets us access your board data pins.
```python
pin_input = Pin(27, Pin.IN)
```
The code above has created a `Pin` object. The chosen pin (`27`) needs to be set as an input from the sensor. Therefore, set the mode of the pin to `Pin.IN`.
```python
while True:
value = pin_input.value() # Get the value, either 0 or 1
```
By entering an infinite loop, we can check continuously for updates from the sensor. We extract the value by typing `value = pin_input.value()`, where `pin_input` is the variable name for our pin and `value()` is the function that returns the value of the pin (`1` or `0`).
```python
if value == 1:
print('No vibration detected')
else:
print('Vibration detected')
```
We then check the value from the sensor to determine what message to print.
```python
time.sleep_ms(100)
```
Lastly, we let $100$ milliseconds pass before a new read from the sensor.
## Sensors that require a library
To use more advanced sensors the microcontroller must know how to interact with them, this is done by "drivers" that are called `library`. These libraries include instructions (code) that will bring a certain function to work with, analog to digital conversion, or the ability to calculate mathematical equations, etc., internally in the sensor controller. In this section, we demonstrate how to use sensors that require a library.
### How to download libraries
In our GitHub, there exist some libraries for some sensors which you can use. To download them you go to this [**repository**](https://github.com/iot-lnu/pico-w) and follow the steps in the below picture, libraries are in the `sensor-examples` folder with a sample code on how to use them. If your sensor does not have a library in our repo, you can try looking for one online or ask one of the teaching assistants for help.

:bulb: After downloading the zip folder you need to extract the downloaded files.
### How to import library
To use the downloaded library, you simply copy the content of lib in the extracted folder and paste it under your lib folder, as demonstrated in the previous tutorial [here](https://hackmd.io/@lnu-iot/B1T1_KM83). Once done, your project should look similar to the one shown below.

:bulb: **In each sensor folder of the repository, you will find a library (the lib folder) and example code that run or use it, if they require a library to run.**
### Use the library
You can create your main file that uses the lib. All you need to do is to import the library in `main.py`. You may import the library from lib in 3 different ways:
```python=
import library #imports the whole library file,
#everything is accessible through dot-notation
from library import className #only import a specific part from the
#library
import library as newName #imports the whole library file, however,
#the library is renamed in this file
```
For example, the code below uses the BME680 library (Temperature-Humidity-Pressure-Gas sensor). Read the comments in the code to learn how it uses the library. The datasheet can be found [here](https://cdn-shop.adafruit.com/product-files/3660/BME680.pdf)
```python=
# These libraries are MicroPython libraries
from machine import Pin, SoftI2C
from time import sleep
# This library is BME680 tha copied to lib folder
from bme680 import *
# Initialization of I2C pins
i2c = SoftI2C(scl=Pin(27), sda=Pin(26))
# Passing initilized i2c to the library
bme = BME680_I2C(i2c=i2c)
while True:
try:
temp = str(round(bme.temperature, 2)) + ' C' # Read temperature from library
#temp = (bme.temperature) * (9/5) + 32
#temp = str(round(temp, 2)) + 'F'
hum = str(round(bme.humidity, 2)) + ' %' # Read humidity from library
pres = str(round(bme.pressure, 2)) + ' hPa' # Read Pressure from library
gas = str(round(bme.gas/1000, 2)) + ' KOhms' # Read Gas from sensor
# Print values to the serial terminal
print('Temperature:', temp)
print('Humidity:', hum)
print('Pressure:', pres)
print('Gas:', gas)
print('-------\n')
except OSError as e:
print('Failed to read sensor.')
sleep(5)
```
Your code will look something like this in VS code:

<br><br>
## Connect multiple sensors
Connecting multiple sensors works just like connecting one sensor. You could use the **+** rail on the breadboard where you connected your voltage output from your device and the **-** for GND. The rail goes along the whole breadboard so you can connect several sensors from these rails.


In the example, we are connecting 3 different kinds of sensors/actuators. The first one from the right is the simplest. It's a hall effect sensor (analog). Next is the DHT sensor which measures temperature and humidity. It requires a library to communicate with it. Last but not least we have an OLED display (SSD1306), although it's not a sensor it connects like any other I2C sensor using the SCL and SDA pins.
We can now start connecting sensors. We start by connecting the analog hall effect sensor. We can pick any pin that has An analog to digital converter like we chose `ADC2` in the following connection schematic.

Now we can move on to connect the signal pin of the DHT sensor. We can use any input digital pin but make sure to pick one that doesn't have any other usages that might conflict with the sensor, We pick pin GP22.

Now we can connect the display, for I2C we have to use 2 specific pins. They are marked as SCL and SDA in the pinout diagram of the Raspberry Pi Pico W. We can actually use the same 2 pins for multiple I2C sensors without a problem, but that only applies to I2C (and SPI) sensors.
One of the SDA pin on the RPi Pico is GP26 and the SCL pin is GP27 so we connect to those pins.

:::danger
**⚠️Double and triple check The connections before connecting power.**
:::
If all the connections are correctly in place then all that is left to do is to write/modify the code with the pins we have just connected.
:::success
Congratulation! Now you finished the first part of the three-part IoT tutorial. You can check the second part and choose what wireless communication you want to use for sending your data.
:::