Skip to content

5. Input & Output device

This week we continued working on electronics, focusing more on the hardware and sensors and trying to figure out which ones are most suitable for our project. We then split up with each person being given a component to try out and then document how its used and how to tackle any difficulties.

Using ESP32

At first we tried out the ESP32 based microcontroller, this time focusing on the different types of signals as indicated in the following figure.


This image even explains the reasoning behind the colors of each component we used with the microcontroller, for example, red components are digital and must be programmed with the red colored pin number of the port they are inserted in.

I tested out the following devices. All inserted into port number 4:

Buzzer

Used the following code to play a simple tune. I could have tried to make a more complex tune to resemble a song for example, but I thought the class had enough buzzer going off at the same time.

from machine import Pin
import time

Buzzer = Pin(2,Pin.OUT)

while True:
    Buzzer.value(1)
    time.sleep(1)
    Buzzer.value(0)
    time.sleep(0.5)
    Buzzer.value(1)
    time.sleep(1)
    Buzzer.value(0)
    time.sleep(0.5)
    Buzzer.value(1)
    time.sleep(1)
    Buzzer.value(0)
    time.sleep(0.5)

NeoPixel RGB LED

Used this code to test out how to use NeoPixel RGB Devices which only use 1 pin number.

import machine, neopixel
np = neopixel.NeoPixel(machine.Pin(27), 8)

np[0] = (255, 0, 0) # set to red, full brightness
np[1] = (0, 128, 0) # set to green, half brightness
np[2] = (0, 0, 64)  # set to blue, quarter brightness
np[3] = (0, 0, 0)  # alone

import time

def demo(np):
    n = np.n

    # cycle
    for i in range(4 * n):
        for j in range(n):
            np[j] = (0, 0, 0)
        np[i % n] = (255, 255, 255)
        np.write()
        time.sleep_ms(25)

    # bounce
    for i in range(4 * n):
        for j in range(n):
            np[j] = (0, 0, 128)
        if (i // n) % 2 == 0:
            np[i % n] = (0, 0, 0)
        else:
            np[n - 1 - (i % n)] = (0, 0, 0)
        np.write()
        time.sleep_ms(60)

    # fade in/out
    for i in range(0, 4 * 256, 8):
        for j in range(n):
            if (i // 256) % 2 == 0:
                val = i & 0xff
            else:
                val = 255 - (i & 0xff)
            np[j] = (val, 0, 0)
        np.write()

    # clear
    for i in range(n):
        np[i] = (0, 0, 0)
    np.write()

demo(np)


This is possible because of the NeoPixel Library.

Humidity Sensor

Used this code to operate the sensor and print out the readings. Note that if you use DHT22 instead of DHT 11 you will get very high and incorrect readings.

# Complete project details at https://RandomNerdTutorials.com

from machine import Pin
from time import sleep
import dht 

sensor = dht.DHT11(Pin(27)) 
#sensor = dht.DHT22(Pin(14))
# The one we have for the esp32 is DHT11, if you choose DHT22 you will get wrong values.

while True:
  try:
    sleep(0.5)
    sensor.measure()
    temp = sensor.temperature()
    hum = sensor.humidity()
    temp_f = temp * (9/5) + 32.0
    print('Temperature: %3.1f C' %temp)
    print('Temperature: %3.1f F' %temp_f)
    print('Humidity: %3.1f %%' %hum)
  except OSError as e:
    print('Failed to read sensor.')

Potentiometer

Used this code to print out the current values of the potentiometer.

# Complete project details at https://RandomNerdTutorials.com/micropython-programming-with-esp32-and-esp8266/

from machine import Pin, ADC
from time import sleep

pot = ADC(Pin(39))
pot.atten(ADC.ATTN_11DB)       #Full range: 3.3v

while True:
  pot_value = pot.read()
  print(pot_value)
  sleep(0.1)


Note that the readings range from 0 to 4095 which is 2^12 or 12-bit.

Photoresistance

Used the this site to test Light dependant resistor (LDR).

from machine import ADC, Pin
import time


class LDR:
    """This class read a value from a light dependent resistor (LDR)"""

    def __init__(self, pin, min_value=0, max_value=100):
        """
        Initializes a new instance.
        :parameter pin A pin that's connected to an LDR.
        :parameter min_value A min value that can be returned by value() method.
        :parameter max_value A max value that can be returned by value() method.
        """

        if min_value >= max_value:
            raise Exception('Min value is greater or equal to max value')

        # initialize ADC (analog to digital conversion)
        self.adc = ADC(Pin(39))

        # set 11dB input attenuation (voltage range roughly 0.0v - 3.6v)
        self.adc.atten(ADC.ATTN_11DB)

        self.min_value = min_value
        self.max_value = max_value

    def read(self):
        """
        Read a raw value from the LDR.
        :return A value from 0 to 4095.
        """
        return self.adc.read()

    def value(self):
        """
        Read a value from the LDR in the specified range.
        :return A value from the specified [min, max] range.
        """
        return (self.max_value - self.min_value) * self.read() / 4095


# initialize an LDR
ldr = LDR(34)

while True:
    # read a value from the LDR
    value = ldr.value()
    print('value = {}'.format(value))

    # a little delay
    time.sleep(0.5)


Investigating Electronics For Our Project

After the ESP appetizer, we focused on Arduino electronics that we believed could be used in our project.

Using BLE For Detecting Devices In Proximity

We used the Adafruit Feather Sense which has a lot of built in features including bluetooth, in order to come up with a method of detecting if a device is in proximity of another using BLE.

Bluetooth Low Energy (BLE) is a wireless personal area network technology that uses considerably less power and costs less than normal Bluetooth, yet offers similar range. It is typically used to transfer small amounts of data between nearby devices, including the use of proximity sensors.

To use BLE there must be a central device which scans the vicinity for advertisements, and a peripheral devices which emits these advertisements.

To do this, we used example codes that are available in Arduino IDE when an Adafruit Feather is connected and properly installed to it (Refer to Week 1).

Because this code is long I will not paste it here, instead you can download it here.
I honestly don’t understand most of the code, but I do understand how to use it. For the devices to identify each other they must be set to the same UUID, for testing I did not change this from the default value in the example, however, for actual use you can use an online UUID generator and then change the default value in both the central and peripheral code to this new value.

Universally Unique Identifier (UUID) is a 128-bit value used to uniquely identify an object or entity on the internet. The chances that a UUID is not unique are not zero but are negligible.

After setting the UUID, upload the code to the peripheral device (for the Adafruit Feather you must press the reset button and wait for the LED to turn green before uploading code). The device should then advertise the UUID.
You can then upload the code to the cental device, which will scan for UUID in its proximity. If it detects the peripheral device, it should connect to it.

After the central device finds a peripheral device it displays in the serial monitor the address of the device (idk what type of address), its RSSI value, and the length of time the peripheral device has been on in milliseconds.

Received Signal Strength Indicator (RSSI) is a measure that represents the relative quality level of a Bluetooth signal received on a device. As the RSSI value decreases (becomes more negative), the proximity (distance) between the devices tends to increase. RSSI is measured in negative dBm and the closer it is to 0 the better the signal is.



Last update: August 11, 2024