Input devices

Potentiometer

This week I channeled the mantra: "You make mistakes, but that's how you learn" (or something like htat).

Erwin's lesson

Below are a few concepts about input devices, from Erwin's lecture, that are worth understanding.

Signals (basic)

There are two types of signals:

Analog, which is continuous and we measure points along the wave.

Digital, which is either on or off.

  • Converting analog signals to digital signals turns voltage into a value.
  • Converters come in different resolutions, for instance: 8bit (0-255) can measure in 255 steps.

GPIO pins

General Purpose Input-Output

  • GPIO pins read either low or high.
  • LOW: 0 - 1/3rds VCC
  • HIGH: 2/3rds VCC - 1 VCC.
  • A GPIO reading is undefined between 1/3rds VCC and 2/3rds.

Pull-up / pull-down resistors

The purpose of pull-up/pull-down resistors is to prevent the pin from "floating" in an undefined state, which could lead to unpredictable behavior.

  • A pull-up resistor connects the pin to VCC, ensuring it reads HIGH when not driven.
  • A pull-down resistor connects the pin to ground, ensuring it reads LOW when not driven.

NB. Many microcontrollers have internal pull-up/pull-down resistors that can be enabled in software.

This is a diagram that Erwin drew to help explain PU/PD resistors.

Resistors

Interfaces - protocol

ie. how components communicate.

  • 1wire/two wire (twi): communicates over gnd and vcc -- data transmitted over the one cable.
  • I2C: uses 7 bit addresses clock and data signals (different to Serial, which uses baudrate).
  • SPI: exchanges bits between microcontrollers or sensor + MCU -- uses pins instead of addresses.
  • PWM: for noisy environments.
  • Serial: Rx / Tx receive transmit with a baudrate. Serial runs on 1 to 1 communication, meaning you need a new serial port for other devices.

Button noise

There's a small amount of noise when you push in a button, just before the button has totally bridged the connection.

This input noise can mess up readings. There are two main ways to deal with the noise:

  • In software (ie. code that says to ignore the first 10 ms)
  • Using a capacitor

When taking the software approach, MCU's with an Aref (analog reference) signal can be used to show what the clean voltage is as a reference.

The other approach is using a capacitor, as Erwin explains, visualized below:

Capacitance

The SI system

The 7 core values that we use (aka The SI system) to define (pretty much) everything. They are:

  • seconds
  • meters
  • grams
  • amperes
  • kelvins
  • moles
  • candelas

Everything else is defined by these values, for example, how to calculate Volts.

1 Volt = 1kg⋅m²⋅s⁻³⋅A⁻¹

Group project

During the group assignment we set connected various input devices to an Arduino and interpreted the results.

Microwave radar (RCWL-0516)

Microwave 2

Microwave 1

Our tests didn't seem to work. The output pin of the sensor was connected to an LED on a breadboard. The LED flashes didn't correlate with the movements we made.

The multimeter indicated that there were no broken circuits.

Microwave test

After extensive debugging and still no improvement, we opted to move on and check a sensor that we knew was in good working condition.

Ultrasonic (HCSR04)

This is Henk's favorite sensor. In 2018, he documented about using it to measure the thickness of ice.

The sensor has four pins, two of which are for emitting and receiving ultrasonic pulses. To get a better idea of how the sensor worked, we hooked up a logic analyzer to some of the pins.

Sonar DS

Sonar

To better understand the readings, we decided to hook the sensor up to a logic analyzer (Irja took really good notes on this).

Input values from the sensor (on Arduino's serial monitor):

working values

Here we can see the relationship between echo and trigger signals.

echo trigger

The sensor takes 180.92 ms to process an Out of range value. While it processes that, no other signals are sent out, which results in a delay.

out of range

We also connected the logic analyzer to the serial communication. The 3rd row gives back a reading when values are printed in the serial monitor. Below, Sam wrote something in the serial monitor. The bottom row shows that.

rx tx 1

Individual project

My initial focus was to get each component on the Henkduino board to do it's most basic functions.

  1. Turn the LED on.
  2. Get the button to turn the LED on and off.
  3. Get readings from the phototransistor in the Serial Monitor.

henk-test

Henk pcb

It took me ages to figure out why the LED wasn't blinking. I had tested it with the multimeter at Waag, so I knew that the connection was ok. In the end, it turned out the issue was that I had the ledPin defined as D3 rather than D2.

Once I got all of the pins correctly defined, everything worked. YEEHAW!

Here are the readings of the light that I got in my serial monitor:

readings

This was my first spiral / most basic code, to check that everything worked:

const int ledPin = D2; // define LED
const int buttonPin = D10; // define button
const int photoPin = D0; // define phototransistor

int buttonState = 0; // define the button's initial state with a value

void setup() {
  Serial.begin(9600); // set up communication frequency with the computer
  pinMode(ledPin, OUTPUT); // define pin type
  pinMode(buttonPin, INPUT);
  pinMode(photoPin, INPUT);

}
void loop() {
  int lightLevel = analogRead(photoPin); // read the photoPin's value and define it as an integer
  Serial.println(lightLevel); // print that value
  delay(100);

  buttonState = digitalRead(buttonPin); // Read button state

  if (buttonState == HIGH) {           // If button is pressed
    digitalWrite(ledPin, HIGH);        // Turn LED on
  } else {
    digitalWrite(ledPin, LOW);         // Turn LED off
  }
}

VL53L1X project (with programmer)

Some important definitions

I2C - I2C is a two-wire serial communication protocol using a serial data line (SDA) and a serial clock line (SCL).

Multiplexer - an electronic device that allows multiple input signals to be selected and transmitted over a single output line.

Programmer - a device used to upload code or firmware to a microcontroller.

Breakout board - an electronic device that allows multiple input signals to be selected and transmitted over a single output line

My goal was to make a circuit using the TOF sensor. I felt that this was a good option for my final project. The stepper motor controlling the toilet seat lifter could be activated by someone's foot coming close enough to the TOF sensor.

Most of the Fab academy documentation that I found for TOF sensors used Adafruit breakout boards.

As we didn't have any available at Waag, I decided to try and make my own.

After some searching, I stumbled on Sparkfun's breakout board, which came with a nice schematic!

schematic

Sparkfun schematic PDF

Click here to learn more about Jumpers.

There was a bit of confusion in the SparkFun schematic around what Jumpers were. My understanding is that they are connections to pull-up resistors that can be soldered or unsoldered depending on if there are already pull up resistors in the circuit or not.

I asked AI to help me understand more about Jumpers.

GPT explanation

jumpers

I began recreating the Sparkfun breakout board in KiCad, but eventually decided to rather follow the Pololu breakout board schematic.

pololu schematic

Pololu schematic PDF

In the end, I was running out of time and decided to simplify my project. However, I learned a lot about the VL53L1X.

Resources specific to the VL53L1X:

VL53L1X project (with XIAO board)

voltage

pinout

XSHUT and INT/GPIO

XSHUT and GPIO1 purposes (AI report)

XSHUT: Power Saving -- The primary reason to use the SHUT pin is to conserve power. When you don't need the sensor to be actively measuring distances, you can pull the SHUT pin LOW to put the sensor into a low-power state. This is important for battery-powered applications.

GPIO1/INT on the VL53L1X is to a digital pin on the microcontroller (optional, for interrupt).

schematic from data sheet

NB. The capacitors are used for decoupling and noise filtering, which are essential for stable operation.

Pull up decided

The datasheet indicates that we need to use a pull-up resistor for the XSHUT pin.

The VL53L1X's XSHUT pin requires a pull-up to a valid logic high voltage (e.g., 2.8V or 3.3V) to keep the sensor enabled. Without a pull-up resistor, the XSHUT pin would remain low due to the RP2040's default pull-down state, which would disable the sensor.

Adding a 10k pull-up resistor to 3.3V is generally a safe choice. It ensures the XSHUT pin remains in a defined state and protects against floating inputs.

Schematic design

NB. Make sure to check what resistors and capacitors are available in the lab before completing the PCB layout.

I designed and milled my PCB, only to realize that we didn't have the specific resistors that I had planned my circuit around.

my schematic

PCB

3D

Digital files

Clearance and simulated path view check

The TOF sensor has 12 tiny pads, that have 0.3mm between them, but the diameter settings of the milling bit I used was 0.4mm. This resulted in a bad mill.

bad mill

3d of bad mill

NB. In the future, make sure to look at the simulated path view to check if the mill looks right.

The updated tool diameter of 0.3mm worked.

There was actually evidence in KiCad that this might be an issue. I wasn't able to draw traces as my settings weren't small enough (0.3mm).

clearance error

Mill: offset settings

I realized that I was slightly confused about the offset number setting.

For the F.Cu milling I had chosen an offset of 0, because I wanted to clear out all of the empty areas on my board. That's a HUGE waste of time.

The Offset number should have been = 4 for this project. Offset number = 1 on Edge.cuts, as we don't need to offset the cutting of the border!

Also worth remembering: the Mill depth on Edge.cuts should start at 0.3 mm not 0.003 in.

Make sure to have the Fill edge cuts box selected on the Gerber to PNG tool for the F.Cu layer.

Soldering the TOF sensor

NB. Don't use too much solder.

  • Add reflow
  • Dab with tip onto the copper areas being soldered
  • Put a tiny bit down and spread it around
  • Place component
  • Use hot airgun to activate the solder (first take off protective film over sensor)

Reflow makes the solder spread out and lie flat on the copper.

reflow

reflow 2

Careful of the part melting and check with a microscope if the solder has worked.

Useful resource: Here are some extra Soldering tips from Kris

Test board

Henk gave me an I2C code to check on the controller, but I was having issues with sending code from Arduino.

The loading of the code kept getting stuck on "Resetting /dev/cu.usbmodem101".

After much debugging and learning about boot mode, Sam noticed that, actually, I had my pins set up incorrectly.

WRONG:

pin error 2

HOW IT SHOULD BE:

pin error 3

THE ISSUE (mixing up the schematic numbers from the actual pin numbers):

issue

FIXED:

pin error

TRY AGAIN:

I milled a new board, flowed/soldered the parts on, and tested again.

However, the LEDs on the XIAO weren't turning on when plugged onto my PCB.

The beep test 'beeped' when I had the multimeter on ground and power. There was a short circuit somewhere.

I took off the capacitors.

Still beeping.

Took off the TOF.

No longer beeping.

Sam reflowed the sensor on and it didn't beep, but I still wasn't able to get an I2C reading in Arduino's Serial monitor.

The week ended without me being able to get the TOF circuit to work.

PCB fail

Useful resources:

VL53L0/1XV2 breakout board

Hello, this is Dylan from the future (networking week)

I came back to the TOF sensor, so that I would have something to communicate with for networking week. I hooked a TOF breakout board to a XIAO RP2040 and used an example code.

tof board

labels

Here are the .png files of my PCB

FCU

Edge

Voila!

It worked.

/*
This example shows how to take simple range measurements with the VL53L1X. The
range readings are in units of mm.
*/

#include <Wire.h> // Enables I2C communication between the Arduino and the VL53L1X sensor
#include <VL53L1X.h>

VL53L1X sensor;

void setup()
{
  while (!Serial) {}
  Serial.begin(115200);
  Wire.begin();
  Wire.setClock(400000); // use 400 kHz I2C

  // Sets a timeout of 500 ms for sensor operations

  sensor.setTimeout(500);
  if (!sensor.init())
  {
    Serial.println("Failed to detect and initialize sensor!");
    while (1);
  }

  // Use long distance mode and allow up to 50000 us (50 ms) for a measurement.
  // You can change these settings to adjust the performance of the sensor, but
  // the minimum timing budget is 20 ms for short distance mode and 33 ms for
  // medium and long distance modes. See the VL53L1X datasheet for more
  // information on range and timing limits.

  sensor.setDistanceMode(VL53L1X::Long); // "Long" mode allows for measurements up to 4 meters
  sensor.setMeasurementTimingBudget(50000); // How long the sensor spends on each measurement - A longer timing budget improves accuracy but reduces speed

  // Start continuous readings at a rate of one measurement every 50 ms (the
  // inter-measurement period). This period should be at least as long as the
  // timing budget.

  sensor.startContinuous(50);
}

void loop()
{
  Serial.print(sensor.read());
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }

  Serial.println();
}