In this two part series we take a look at mechanical relays: different types, terminology, theory of operation, and design considerations. We finish part one with a demo of an armature relay showing its inside, how to actuate it, and capture its flyback voltage waveform with an Oscilloscope. In part 2 we look at a simple circuit that allows us to control armature or reed relays with a simple digital pin from a microcontroller. We also look at a circuit design that allows us to avoid hot switching when using mechanical relays.
The ForceTronics blog provides tutorials on creating fun and unique electronic projects. The goal of each project will be to create a foundation or jumping off point for amateur, hobbyist, and professional engineers to build on and innovate. Please use the comments section for questions and go to forcetronics.com for information on forcetronics consulting services.
Friday, June 23, 2023
Tutorial on Routing Electrical Signal with Mechanical Relays
Wednesday, April 26, 2023
Designing an Adjustable LED Drive Circuit
Thursday, February 23, 2023
Building a Dynamic ESP32 Wireless Network using the ESP-Now Protocol
In this three part series we will design a dynamic wireless network using ESP32 modules and leveraging EXPRESSIF's ESP-NOW communication protocol.
In part 1 we provide an overview of the
ESP-NOW communication protocol and talk about how our dynamic wireless network
will work.
In part 2 we look at a simple
implementation of ESP-Now that will serve as a foundation for the dynamic
network we will design and cover in part 3.
Patreon page link: https://www.patreon.com/forcetronics
ESP-NOW documentation: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_now.html
**************Part 3 coming soon*******************************
Friday, January 6, 2023
Designing a Li-Ion and USB Power Circuit with Built-in Charging
This video series will take you step by step through how to design a circuit that can be powered from a USB input (5V) or from a Lithium Ion battery cell and output a regulated 5V. The design includes a battery charging circuit and a circuit that automatically isolates the battery from the power bus when USB power is applied.
Please support ForceTronics on Patreon: patreon.com/forcetronics
In part one we review the overall plan for the design, go over Li-ion battery cell basics, and give a crash course on boost switching voltage regulators.
Battery university link: https://batteryuniversity.com/
In part two we go into detail on our boost switching regulator design using Texas Instruments TPS61202 5-V fixed output voltage boost converter.
Link to TI’s TPS61202 product page: https://www.ti.com/product/TPS61202?qgpn=tps61202
In part three we look at the battery charging circuit and the power source isolation circuit
Sunday, December 4, 2022
How to Design a Programming Circuit for the ESP32
In the video we look at how to design a circuit for programming an ESP32 module. We also explain the Strapping Pins on the ESP32 and how they work.
Oscilloscope Capture of EN pin and GPIO0 setting ESP32 in Download Boot Mode
Sunday, November 27, 2022
How to Use a USB Type-C Connector in Your Next Microcontroller Based Project
In this video we give an overview of the USB type-C connector standard along with other related USB standards. We then look at an example design that implements a USB type-C connector and converts the USB 2.0 communication to serial or UART communication. You can then use the serial data to communicate, debug, or program your microcontroller for programming environments such as Arduino.
USB Type C Connector example implementation
USB 2.0 communication converted to UART / Serial
Wednesday, September 14, 2022
How to Control Water Flow with Arduino IoT Cloud and a Solenoid Parts 1 and 2
In this two part series we look at how to control a Solenoid using an ESP32 board and the Arduino IoT Cloud. In part one we focus on what a solenoid is and the hardware needed to drive a solenoid open or closed. In part 2 we focus on setting up the Arduino IoT Cloud control.
Saturday, November 13, 2021
How to Build a Switch Debounce Circuit for a Rotary Encoder
Tuesday, December 22, 2020
How to Setup and Change the System Clock on the SAMD21 Microcontroller Family
In this video we look at how to setup and change the system clock on the SAMD21 family of microcontrollers from Microchip / Atmel. This example code is written in C++ and uses direct register access.
Free version can be found on GitHub: https://github.com/ForceTronics/SamD21_Clock_Setup
For pay version includes the following additional features:
Demonstrates how to use the calibration values stored in NVM to tune the 48MHz clock for higher accuracy
Allows you to change the system clock to 48MHz, 8MHz, 1MHz, and 32768Hz
Shows how to output the system clock from pin PA27
Link to code on ForceTronics.com: http://www.forcetronics.com/example-code-for-purchase/samd21-clock-setup-and-control-c-code-example
Sunday, November 29, 2020
How to Design 24VAC to DC Power Supply for HVAC Applications Part 2
In the video we look at how to design a 24VAC power supply for industrial and HVAC applications. The supply will be flexible enough to handle DC voltage inputs. The power supply will employ a DC to DC buck converter, half wave rectifier, input protection against over voltage, and output noise reduction circuit features. In part 2 we look at the PCB design, the finished product, and capture some test data to see how it is working.
Monday, November 16, 2020
How to Design a 24VAC to DC Power Supply for HVAC Applications Part 1
In the video we look at how to design a 24VAC power supply for industrial and HVAC applications. The supply will be flexible enough to handle DC voltage inputs. The power supply will employ a DC to DC buck converter, half wave rectifier, input protection against over voltage, and output noise reduction circuit features
Monday, December 9, 2019
Designing an Automatic Battery Cutoff Circuit to Prevent Over Discharge of Rechargeable Batteries Part 2
BOM of battery cutoff circuit:
- S-1011A70-M6T1U4 Voltage Detector from ABLIC
- DMP4015SSS-13 P Chan MOSFET from Diodes Inc
- BSS138 N Chan MOSFET from multiple manufacturers
- RSX051VYM30FHTR Schottky Diode from ROHM Semi
- 2x 3.3 nF Ceramic Capacitor
- ~100 kOhm Resistor
- 1 to 10 MOhm Resistor (used 4.7M in example circuit)
| PCB Layout of Battery Cutoff Circuit |
Friday, November 29, 2019
Designing an Automatic Battery Cutoff Circuit to Prevent Over Discharge of Rechargeable Batteries Part 1
BOM from video:
- S-1011A70-M6T1U4 Voltage Detector from ABLIC
- DMP4015SSS-13 P Chan MOSFET from Diodes Inc
- BSS138 N Chan MOSFET from multiple manufacturers
- RSX051VYM30FHTR Schottky Diode from ROHM Semi
- 2x 3.3 nF Ceramic Capacitor
- ~100 kOhm Resistor
- 1 to 10 MOhm Resistor
| Battery Cutoff Circuit Schematic |
Friday, May 31, 2019
Ways to Improve ADC Measurement Accuracy and Resolution Part 2
To access the white paper that was referenced to derive the equation related to RC time constants and sampling time: https://www.silabs.com/documents/public/application-notes/AN119.pdf
| Cutout from Silicon Labs App Note on calculating settling time for SAR ADC |
Saturday, March 30, 2019
Ways to Improve ADC Measurement Accuracy and Resolution Part 1
//***************Arduino code used in video*******************************
/*This code demonstrates how to change the ADC voltage reference on an Arduino
* This was shown in an ADC tutorial on the ForceTronics YouTube Channel.
* This code is free and open for anybody to use at their own risk.
*/
void setup() {
Serial.begin(115200); //setup serial connection
while(!Serial);
analogReference(AR_EXTERNAL); //sets the ADC reference voltage to external (input is aRef pin)
//analogReference(AR_DEFAULT); //set the ADC reference to default which is AVCC (uses power supply voltage or VCC as reference)
//analogReference(AR_INTERNAL2V23); //uses 2.23V internal reference in SAMD21 uC
analogReadResolution(12); //Set ADC to 12bit resolution, default is 10
burn8Readings(); //make 8 readings but don't use them to ensure good reading after reference change
delay(100);
for(int i=0;i<500;i++) { //loop through a bunch of ADC readings and print them to serial plotter
Serial.println(analogRead(A0)); //Make ADC measurement at A0
}
}
void loop() {
//don't need the loop
}
//This function makes 8 ADC measurements but does nothing with them
//Since after a reference change the ADC can return bad readings at first. This function is used to get rid of the first
//8 readings to ensure an accurate one is displayed
void burn8Readings() {
for(int i=0; i<8; i++) {
analogRead(A0);
delay(1);
}
}
Wednesday, March 6, 2019
Tutorial on Digital to Analog Converters (DAC) and Example Using the MCP4728 Part 2
Link for PCB board at PCBWay: https://www.pcbway.com/project/shareproject/W08904ASW106_DAC_Example_Gerber.html
//**********Arduino Code with MCP4728 examples from video***************
/*
* This code was written to demonstrate functions on the MCP4728 4 channel DAC for a video on the ForceTronics YouTube channel
* This sketch leverages a library from GitHub made by Hideakitai, link to library: https://github.com/hideakitai/MCP4728
* This code is public domain and free to anyone to use and modify with no restrictions at your own risk
*/
#include <Wire.h>
#include "MCP4728.h"
MCP4728 dac; //create object to library
//variables for wavform
int const sampleCount = 24; //samples to read to have a buffer
int signalSamples[sampleCount]; //create array to hold signal or waveform
float pi2 = 6.283; //value of pi times 2
const long clkFrequency = 400000; //I2C clock frequency
const uint8_t t1 = 3; //pin to setup test 1 fast sinewave
const uint8_t t2 = 4; //pin to setup test 2 sync'd sinewaves
const uint8_t LDAC = 5; //Output pin on MCU to control LDAC(not) pin on DAC
void setup() {
//Create sinewave
float in;
float hBit = 2047.5;
for (int i=0;i<sampleCount;i++)
{
in = pi2*(1/(float)sampleCount)*(float)i;
signalSamples[i] = (int)(sin(in)*hBit + hBit);
}
pinMode(t1,INPUT_PULLUP); //configure test check pins
pinMode(t2,INPUT_PULLUP); //configure test check pins
pinMode(LDAC,OUTPUT); //configure test check pins
digitalWrite(LDAC,HIGH); //turn DAC outputs off
Wire.begin(); //start up I2C library
Wire.setClock(clkFrequency); //set clock frequency for I2C comm
dac.attatch(Wire, 13); //second argument is Arduino pin connected to LDAC(not), we are controlling LDAC manually so just entered pin we are not using
dac.readRegisters(); //Used to read current settings from MCP4728
dac.selectVref(MCP4728::VREF::VDD, MCP4728::VREF::VDD, MCP4728::VREF::VDD, MCP4728::VREF::VDD); //setup voltage ref for each DAC channel
dac.selectPowerDown(MCP4728::PWR_DOWN::NORMAL, MCP4728::PWR_DOWN::NORMAL, MCP4728::PWR_DOWN::NORMAL, MCP4728::PWR_DOWN::NORMAL); //set power down mode, used for saving power
dac.selectGain(MCP4728::GAIN::X1, MCP4728::GAIN::X1, MCP4728::GAIN::X1, MCP4728::GAIN::X1); //set gain on output amp
//dac.enable(true); //enables the DAC outputs by controlling LDAC pin, but we are controlling LDAC manually in this example
//perform test one
if(!digitalRead(t1)) {
digitalWrite(LDAC,LOW);
//output sinewave as fast as we can
for(;;) { //run test for infinitity
for(int j=0;j<sampleCount;j++) {
dac.analogWrite(MCP4728::DAC_CH::A,signalSamples[j]);
}
}
}
else { //perform test 2
for(;;) { //run test for infinitity
for(int j=0;j<sampleCount;j++) {
int temp = j;
digitalWrite(LDAC,HIGH); //turn outputs off
// delay(1);
dac.analogWrite(MCP4728::DAC_CH::A,signalSamples[temp]);
temp += 8; //shift sigal 90 degrees
if(temp > 23) temp -= sampleCount;
dac.analogWrite(MCP4728::DAC_CH::B,signalSamples[temp]);
temp += 8; //shift sigal 90 degrees
if(temp > 23) temp -= sampleCount;
dac.analogWrite(MCP4728::DAC_CH::C,signalSamples[temp]);
temp += 8; //shift sigal 90 degrees
if(temp > 23) temp -= sampleCount;
dac.analogWrite(MCP4728::DAC_CH::D,signalSamples[temp]);
digitalWrite(LDAC,LOW); //turn outputs on all four outputs at same time
// delay(1);
}
}
}
}
void loop() {
}
Saturday, February 16, 2019
Tutorial on Digital to Analog Converters (DAC) and Example Using the MCP4728 Part 1
Link to Analog Devices detailed tutorial on converters: https://www.analog.com/media/en/training-seminars/design-handbooks/Basic-Linear-Design/Chapter6.pdf
| Kelvin Divider or String DAC Architecture |
Friday, November 23, 2018
Unboxing Particle's Mesh Network IoT Series (Boron and Xenon)
//******************Code from Video*****************************************
// -----------------------------------
// Controlling LEDs over the Internet
// -----------------------------------
// First, let's create our "shorthand" for the pins
// Same as in the Blink an LED example:
// led1 is D0, led2 is D7
int led1 = D0;
int led2 = D7;
// Last time, we only needed to declare pins in the setup function.
// This time, we are also going to register our Particle function
void setup()
{
// Here's the pin configuration, same as last time
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
// We are also going to declare a Particle.function so that we can turn the LED on and off from the cloud.
Particle.function("led",ledToggle);
// This is saying that when we ask the cloud for the function "led", it will employ the function ledToggle() from this app.
// For good measure, let's also make sure both LEDs are off when we start:
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
}
// Last time, we wanted to continously blink the LED on and off
// Since we're waiting for input through the cloud this time,
// we don't actually need to put anything in the loop
void loop()
{
// Nothing to do here
}
// We're going to have a super cool function now that gets called when a matching API request is sent
// This is the ledToggle function we registered to the "led" Particle.function earlier.
int ledToggle(String command) {
/* Particle.functions always take a string as an argument and return an integer.
Since we can pass a string, it means that we can give the program commands on how the function should be used.
In this case, telling the function "on" will turn the LED on and telling it "off" will turn the LED off.
Then, the function returns a value to us to let us know what happened.
In this case, it will return 1 for the LEDs turning on, 0 for the LEDs turning off,
and -1 if we received a totally bogus command that didn't do anything to the LEDs.
*/
if (command=="on") {
digitalWrite(led1,HIGH);
digitalWrite(led2,HIGH);
Particle.publish("LED State", "ON");
return 1;
}
else if (command=="off") {
digitalWrite(led1,LOW);
digitalWrite(led2,LOW);
Particle.publish("LED State", "OFF");
return 0;
}
else {
return -1;
}
}
