Week 9: Input Devices

This week we explored input devices and communication protocols, focusing on sensors and how they transmit data in embedded systems.

Before starting

Input devices are components responsible for capturing information from the physical environment (such as temperature, pressure, motion, or light) and converting it into electrical signals that can be interpreted by electronic systems like microcontrollers (ESP32, Arduino) or industrial controllers (PLC).
In automation and prototyping environments, these devices especially sensors play a key role by enabling systems to monitor real world conditions and transform physical variables into usable data, allowing machines and projects to respond intelligently, optimize processes, and operate safely and efficiently.

Common Sensor Types

Temperature sensors such as DHT22, LM35, or PT100 are used to measure thermal conditions in applications like climate control, fabrication processes, or material testing. Humidity sensors, including capacitive and digital types, are widely used in environmental monitoring and storage control. Pressure sensors, often implemented as transducers, are essential in pneumatic and hydraulic systems, while current and voltage sensors are used for energy monitoring and electrical protection.
Capacitive sensors are commonly used for level detection or proximity sensing without direct contact. Simple input devices like buttons allow manual interaction with systems. Proximity sensors, including ultrasonic and infrared types, are widely used in robotics and automation to measure distance. Other important sensors include flow sensors for liquid measurement, light sensors for automated lighting systems, gas sensors for safety applications, and accelerometers for motion detection in dynamic systems. In general, analog signals represent continuous values, while digital signals represent binary states, and both are fundamental in data acquisition systems.

Common Communication Types

Analog Communication

Analog communication is based on continuous signals such as voltage (0–5V, 0–10V) or current (4–20 mA), where the signal level directly represents the measured variable. It is widely used in industrial environments due to its robustness and resistance to electrical noise, especially over long distances.

Digital Communication

Digital communication uses discrete signals (0 and 1) to transmit information, allowing for higher precision and reduced susceptibility to interpretation errors. It is the foundation of most modern electronic and embedded systems.

I²C (Inter-Integrated Circuit)

I²C uses only two communication lines: data (SDA) and clock (SCL), enabling multiple devices to share the same bus using unique addresses. It is efficient in pin usage and commonly used with sensors, displays, and peripheral modules.

SPI (Serial Peripheral Interface)

SPI is a high-speed communication protocol that uses four main lines (MOSI, MISO, SCK, and CS). It provides faster and more reliable data transfer compared to I²C, making it ideal for high-performance sensors, memory devices, and displays.

UART (Serial Communication)

UART is a simple point to point communication method that uses two lines (TX and RX) for transmitting and receiving data. It is widely used for communication with computers, Bluetooth modules, GPS devices, and other peripherals.

Modbus (Industrial Protocol)

Modbus is a widely used industrial communication protocol, often implemented over RS-485, that allows multiple devices to communicate over long distances. It is known for its reliability and is commonly used in PLC systems and SCADA networks.

CAN Bus

CAN Bus is a robust communication protocol designed for distributed systems, especially in automotive and industrial applications. It allows multiple nodes to communicate efficiently with strong error detection capabilities, making it ideal for critical systems.

When selecting a communication method, it is important to understand how different factors are interconnected: the transmission speed determines how quickly data can be sent, but higher speeds can increase vulnerability to noise; therefore, the communication distance becomes critical, as longer distances often require more robust protocols. At the same time, the presence of electrical noise in the environment can affect signal integrity, making it necessary to choose appropriate communication methods or shielding techniques. The number of connected devices also plays a key role, since some protocols support multiple nodes while others are limited to point-to-point communication, directly influencing system architecture.
Finally, power consumption must be considered, especially in embedded or portable systems, where efficiency must be balanced with performance.
For further information about this topic and the machines at IBERO Puebla, please consult this week’s group page.

Design

At our Fab Lab in Ibero Puebla, we are developing a mini wind turbine system whose main goal is to generate enough energy to become self-sustaining. A key objective of this project is to measure the wattage generated in order to monitor the energy production of the stepper motors being used as generators.

System Architecture

Fab termi
The implemented process begins by taking the four phases of each of the five stepper motors. Each pair of phases is connected to a bridge rectifier (diode bridge), which converts the generated AC signal into DC. All rectified outputs are then connected in parallel, combining the generated current.
Fab termi
The implemented process begins by taking the four phases of each of the five stepper motors. Each pair of phases is connected to a bridge rectifier (diode bridge), which converts the generated AC signal into DC. All rectified outputs are then connected in parallel, combining the generated current.
From there, the output is routed through pin headers designed to connect to a boost converter, whose function is to increase the voltage from approximately 1–3V up to at least 14V. This step is necessary because the raw voltage generated by the motors is too low for practical use.
The boosted voltage is then sent directly to a solar charge controller. Although typically used for solar panels, this type of controller can also be used in wind systems because it is designed to:
  • Regulate incoming DC voltage
  • Protect batteries from overcharging
  • Stabilize energy input regardless of fluctuations
This makes it suitable for wind applications, where energy generation is also variable and inconsistent.
Fab termi
After the charge controller, the output passes through a voltage regulator, stepping down the voltage from ~14V to 5V, which is used to power a Seeed XIAO microcontroller through its 5V input pin.
The XIAO board then powers the INA sensor using its 3V output, and the sensor sends measurement data from its OUT pin to one of the XIAO’s digital pins (in this case, D0). This completes the circuit, ensuring that as long as energy is being generated (originally intended for a solar panel), the system remains powered and the microcontroller continues operating as the “brain” of the system.

Current Peaks and PCB Design Considerations

Stepper motors used as generators can produce unexpected current spikes, especially under strong wind conditions. These spikes can reach significant transient currents (often in the range of several hundred milliamps up to a few amps depending on the motor and load), which may damage PCB traces if they are not properly dimensioned.
To prevent this, PCB trace width must be calculated based on current handling capacity.
I = k · (ΔT)^0.44 · (A)^0.725

This empirical formula (based on IPC-2221 standards) relates the allowable current (I), temperature rise (ΔT), and cross-sectional area of the trace (A). It is used to estimate how much current a PCB trace can safely carry.

A = W · T

The cross-sectional area (A) of the trace depends on its width (W) and copper thickness (T). Standard PCB copper thickness is typically 1 oz/ft² (~35 µm).

W = \frac{A}{T}

This allows calculating the required trace width once the desired current capacity and copper thickness are known.

P = V · I

This equation relates power (P), voltage (V), and current (I), helping estimate the electrical load and expected current flow in the system.

Based on these calculations and considering safety margins for current spikes, a minimum trace width of 0.8 mm was selected. This ensures that the PCB can handle the expected current without overheating or damaging the conductive paths.

Schematic design

Following the connection architecture, we move into KiCad, starting by importing the components using the “A” key, ensuring that all the required libraries are preloaded. These include:
Fab termi

  • Pin headers (4 pins) for the motor phases and Components for the boost converter, voltage regulator, and solar panel charger.
  • Fab termi
    Fab termi
  • A 6-pin header for the INA sensor
  • Fab termi
  • The XIAO module, whose footprint already includes properly spaced pads
  • Fab termi
  • Diodes (×42), mainly defined by their footprint
  • Fab termi
    A key detail in the circuit architecture is the 5V input of the XIAO, where two power sources are connected:
    • One from the solar panel charging system
    • One emergency input
    Both lines are controlled using diodes, allowing automatic power selection without backfeeding between sources. This ensures safe and seamless switching depending on availability.
Following the architecture logic, the electrical schematic is assembled and the ERC (Electrical Rules Check) is executed to verify correctness.
Fab termi
Fab termi
In this case, some warnings appeared but they were non critical and did not affect functionality.

PCB Layout

Moving to the PCB editor:
  • For updating the board, we need to using the button located in the top menu
  • Fab termi
  • Routing is performed following the connection guides automatically generated by KiCad from the schematic
Once organized, the board layout is completed.

Copper fill (F.Cu layer)

To finalize the top copper layer:
  • The copper pour (fill) tool is selected
  • The board area is outlined as desired
  • Press “B” to refill zones
This completes the F.Cu layer
Fab termi
Fab termi

Board outline (Edge.Cuts layer)

Next, the Edge.Cuts layer is defined:
  • This step creates the physical outline of the PCB
  • A 2 mm line width is used to match the cutting tool diameter
Fab termi

Drilling layer (User.1)

Finally, in the User.1 layer, all drilling points for pads are defined:
  • Holes are drawn manually as filled circles
  • Minimum radius must be 0.4 mm, since the tool diameter is 0.8 mm
  • In this case, a radius of 0.5 mm is used for safety and tolerance
Fab termi
There are several ways to generate files suitable for Manufacturing Readiness Levels (MRL), which ensure that a design is properly prepared for fabrication. One practical approach is using a web-based tool developed by the Fab Lab community called MODS CE.
Within this platform, a wide variety of machines can be selected from the left-hand menu. In this case, the Roland SRM-20 milling machine was chosen under the “mill 2D PCB” option.
Fab termi
Fab termi
Fab termi
The interface provides a modular workflow, where each step corresponds to a stage in preparing the machining process. The first step is to import an .svg file, which contains the PCB design.
The modules “Read SVG” and “Convert SVG Image” are used to visualize and manipulate the working area of the PCB. These allow the user to define dimensions and identify cutting regions, which are typically shown in black (indicating where the tool will remove material). Another important module is “Set PCB Defaults”, which works in conjunction with “mill raster 2D”, as it defines the tool parameters such as cutting depth, speed, and offsets.
Fab termi

Drilling Process

For drilling operations, a 0.79 mm drill bit is used. Before exporting the toolpath, it is necessary to adjust the feed rate in the Roland SRM-20 milling machine module to 0.2 mm/s, which helps prevent tool breakage due to excessive stress.
Fab termi
Fab termi
Additionally, the origin must be set to (0,0,0) in both the XY plane and Z axis to ensure proper alignment during machining. To export the file, the on/off button must be set to “true”, after which clicking “calculate” generates the toolpath. A preview of the PCB can be displayed by clicking “view”, or it may appear automatically after calculation.
Fab termi
Fab termi
An important detail

is that some holes, such as those for the transistor, may not appear. This occurs because the drill bit diameter is larger than the hole size defined in the design, making it impossible for the tool to reproduce those features accurately.

Traces Milling

The process for milling traces is similar, but with a key difference. When importing the SVG, the traces may appear in black, which indicates that they will be removed this is incorrect for PCB traces.
Fab termi
To fix this, the image must be inverted in the “Convert SVG Image” module, so that the tool removes only the surrounding copper and preserves the traces. Just click on the button invert
For this step, a 0.40 mm flat end mill is used with a feed rate of 4 mm/s, and the origin is again set to (0,0,0).
Fab termi
Fab termi
Fab termi
A limitation

observed in this stage is that small features, such as micro-USB pins, may appear merged in the preview. This happens because the tool diameter is too large to properly isolate such fine details, which is an important consideration when designing for CNC milling.

Board Outline

Finally, for cutting the board outline, a 1.59 mm cutout tool is used with a feed rate of 4 mm/s, maintaining the origin at (0,0,0).
Fab termi
Fab termi
In this case, the outline is correctly represented, and the toolpath accurately follows the intended board shape.
Fab termi
Fab termi

Board

SRM-20 by DGSHAPE

Moving on to the SRM-20 by DGSHAPE, the first step is to properly secure the PCB material onto the sacrificial bed. This is done using double-sided tape, ensuring the board is firmly attached. The sacrificial bed itself must be fixed to the MonoFab base using the provided screws or bolts to prevent any problem during machining.
Fab termi
Fab termi
Fab termi
To power on the machine, press the power button located at the back of the SRM-20.
Fab termi
Once the machine is on, open the control software VPanel, which allows manual and automated control of the milling process. The interface contains several important menus:
Fab termi
Set Origin Point:

This is used to define the reference position of the machine. The X/Y axes are set to establish the horizontal origin, and the Z axis is set separately to define the vertical starting point.

Move:

This option allows manual positioning of the toolhead to locate the origin or move to a specific point on the board.

Cursor Step:

Adjusts the step size or speed of manual movements, enabling fine or coarse positioning depending on the need.

Spindle:

Controls the rotation of the milling spindle. It is especially useful when setting the Z axis, as the tool can be carefully lowered without applying excessive force that could damage it.

Process Controls

These manage the execution of the machining jobs.

To load machining files, click on the “Cut” button. A new window will appear:
  1. Click “Delete All” to remove any previously loaded jobs.
  2. Click “Add” and select the .rml files generated earlier in MODS.
It is critical to follow the correct processing order:
Drilling -> Traces -> Outline
This order is essential because:
  • If drilling is done after milling traces, it may damage or lift the copper tracks.
  • If the outline is cut first, the board may move, ruining the remaining processes.
Fab termi
After loading the files in the correct order, press “Output” to start the machining process.

Tooling and Setup Considerations

The tool dimensions used in MODS correspond to real milling bits:
Process Tool Diameter
Drilling 0.8 mm
Traces rounded to 0.4 mm
Cutout 2 mm
Fab termi
Each tool must be manually installed by inserting the bit into the spindle and tightening it using an Allen key on the set screw.
Since each tool serves a different purpose, they must be changed between operations. This is why the files are executed separately and in a specific order.
Important:

Every time the tool is changed, the Z axis must be recalibrated, since the tool length may vary. Failing to do this can result in improper cutting depth or tool breakage.

The complete workflow consists of:
  1. Securing the PCB material to the bed.
  2. Setting the X, Y, and Z origin points.
  3. Loading the .rml files in the correct order.
  4. Running each process sequentially (drilling, traces, cutout).
  5. Changing tools and recalibrating Z between each step.
Fab termi

Solder

With the PCB already milled and cut, the next step is soldering. Since most of the components are SMD, it is necessary to pretin the pads before placing the components. This process consists of applying a small amount of solder to the pad by heating it with the soldering iron for a few seconds, and then feeding solder from the opposite side until it melts and forms a thin, even layer.
Once the pad is pretinned, the component can be positioned and soldered by reheating the pad and allowing the solder to secure it in place.
Fab termi
Fab termi
The soldering temperature used is 700°F (~370°C), which provides a good balance between efficient heat transfer and control. If the temperature is too low, the solder may not flow properly, resulting in weak or “cold” joints. On the other hand, excessively high temperatures can damage components, lift PCB pads, or degrade the board material.
Fab termi

Soldering Temperatures

Temperature (°F) Application
600–650°F Delicate components, low thermal mass
650–700°F General SMD soldering (recommended range)
700–750°F Through-hole components or larger pads
750°F+ Heavy ground planes (use with caution)
For a more efficient assembly process, it is recommended to solder components in the following order to going from smallest to largest, improves accessibility and reduces the risk of interfering with already soldered components.
Fab termi

For further information about this topic, please consult this video from Mundo Electrónica.

Code

Hardware Definitions



 const int pinCorriente = D0;
const int pinVoltaje = D1;
  • Defines which pins will read the signals.
  • pinCorriente reads current sensor output.
  • pinVoltaje reads voltage signal.
  • Uses analog-capable pins of the XIAO.

ADC Configuration



 // Parámetros ADC 
const float VREF = 3.3;
const int ADC_RES = 4095;
  • VREF is the reference voltage (max readable voltage).
  • ADC_RES is resolution (12-bit → 0–4095).
  • Used to convert raw ADC values into real voltage.

Sensor Calibration



 // AJUSTAR CON CALIBRACIÓN float offset = 1.65; float sensibilidad = 0.1; 
  • offset: baseline voltage when no current flows.
  • sensibilidad: sensor gain (Volts per Ampere).
  • These values MUST be calibrated experimentally.
  • Critical for accurate current measurement.

Noise Filtering


 // Promedio const int samples = 10;

float leerPromedio(int pin) {
long sum = 0;
for (int i = 0; i < samples; i++) {
sum += analogRead(pin);
delay(2);
}
return sum / (float)samples;
}
  • Reads the same pin multiple times.
  • Reduces noise from analog signals.
  • samples controls smoothing level.
  • Similar to adc_avg() in your reference code.

Initialization


 void setup() { Serial.begin(115200); } 
  • Initializes serial communication.
  • Used to print sensor data.
  • 115200 baud = fast data transmission.

Current Measurement


float rawCorr = leerPromedio(pinCorriente);
float voltCorr = rawCorr * (VREF / ADC_RES);
float corriente = (voltCorr - offset) / sensibilidad;
  • Reads raw ADC value.
  • Converts to voltage.
  • Removes offset.
  • Divides by sensitivity to get current (A).

Voltage Measurement


float rawVolt = leerPromedio(pinVoltaje); 
float voltaje = rawVolt * (VREF / ADC_RES);
  • Reads ADC from voltage line.
  • Converts to real voltage.
  • Assumes voltage is already scaled (important!).

Power Calculation


float potencia = voltaje * corriente; 
  • Uses basic electrical formula:
  • P = V × I
  • Gives power in Watts.

Serial Output


Serial.print("Voltaje: "); 
Serial.print(voltaje);
Serial.print(" V | Corriente: ");
Serial.print(corriente);
Serial.print(" A | Potencia: ");
Serial.print(potencia);
Serial.println(" W"); delay(500);
  • Prints all measurements in one line.
  • Easy to monitor in Serial Plotter.
  • delay(500) updates every 0.5 seconds.
 
                                        const int pinCorriente = D0; 
                                        const int pinVoltaje = D1; 
                                        // ===== ADC ===== 
                                        const float VREF = 3.3; 
                                        const int ADC_RES = 4095; 
                                        // ===== Calibration ===== 
                                        float offset = 1.65; 
                                        float sensibilidad = 0.1; 

                                        const int samples = 10; 
                                        float leerPromedio(int pin) { 
                                            long sum = 0; 
                                        for (int i = 0; i < samples; i++) { 
                                                sum += analogRead(pin); delay(2); 
                                            } 
                                            return sum / (float)samples; 
                                        } 
                                        // ===== Setup ===== 
                                        void setup() { 
                                            Serial.begin(115200); 
                                        } 
                                        // ===== Loop ===== 
                                        void loop() { 

                                            float rawCorr = leerPromedio(pinCorriente); 
                                            float voltCorr = rawCorr * (VREF / ADC_RES); 
                                            float corriente = (voltCorr - offset) / sensibilidad; 
                                            
                                            float rawVolt = leerPromedio(pinVoltaje); 
                                            float voltaje = rawVolt * (VREF / ADC_RES); 
                                            
                                            float potencia = voltaje * corriente; 

                                            // ===== OUTPUT ===== 
                                            Serial.print("Voltaje: "); 
                                            Serial.print(voltaje); Serial.print(" V | Corriente: "); 
                                            Serial.print(corriente); Serial.print(" A | Potencia: "); 
                                            Serial.print(potencia); Serial.println(" W"); 
                                            delay(500); 
                                        } 
With this, the system is now ready to operate.

Problem


When testing the wind turbine outdoors, we noticed that it generates a very low voltage (around 2.4 V). This is insufficient to activate the solar charger module and power the XIAO, and consequently, the INA sensor as well. As a result, the system cannot operate under these conditions.

Solution


For practical demonstration purposes, we decided to use an external power supply to provide 9 V, which is more than sufficient to power the system and validate its functionality.
After connecting the board to the power supply, we verified that the sensor is correctly transmitting data. In this case, a voltage drop from 9 V to approximately 8.2 V was observed.
It confirms that the system is actively drawing power and that all components are functioning as intended, even though ideal voltage values are not maintained throughout the circuit.

Results

Test and simulation

Download files

For download 3D and others files, just click on the dancing shrimp.