Tuesday, August 1, 2023

Very Simple Timer with PIC16F18313

Recently I was asked for gerber files for one of my old projects - "Simple Timer with PIC16F628A", but unfortunately the files of that project were lost. I decided to make a new project with more modern and smaller microcontroller - PIC16F18313, which have 8 pin only. To make that possible the display has to be with 2 wire serial communication. I already had such a display - a 4 digit 7 segment module with TM1637, and I already learned how to use it.

Here is the schematic:

The circuit is extremely simple, but it can be simplified even further. If the active buzzer is a piezo type with less than 15 mA consumption, the transistor Q1 can be removed and the buzzer and the LED can be connected directly between the microcontroller pin 3 (RA4) and the ground. Also if the timer is used only for the alarm, the second transistor and the relay can also be scrapped. 

There is a jumper (JP1 that can switch the voltage to the relay circuit between 5V and the input voltage. This is useful if one don't have 5V relay, there can be used 12V or 24V relays instead.
The supply voltage can be between 7 and 30V. When using higher supply voltage the regulator 7805 can get hot so some sort of heatsink may be needed.

Here is the 3D view of the PCB:

I designed the PCB single sided and with only through hole elements so to be easy made at home.

The schematic uses the internal 32 MHz oscillator of the microcontroller - there is no way to connect external crystal - no enough pins for this luxury :) The internal oscillator is good enough in most cases, but there is a way to tune the frequency with the register OSCTUNE to make it more precise. 

As the schematic uses pin4 as input for the Button2, this pin cannot be used as reset pin so when programming the microcontroller the programmer have to use high voltage to initiate the programming.

The operation of the timer is simple: Button1 cycles between four modes: "Idle/Stop", "Edit minutes", "Edit seconds", Timer On. When in "Edit minutes" and "Edit seconds", clicking the Button2 will increase the minutes or the seconds. Long press will trigger repeat function of Button2. Pressing both buttons in "Idle/Stop" will clear the set time, in "Edit minutes" will clear only the minutes and in "Edit seconds" will clear only the seconds. The timer can be set from 1 second up to 99 minutes and 59 seconds. If the set time is 00:00 the timer will count 100 minutes.

The relay contact are connected to the terminal block J1 and can be used to control any external appliance. The relay used in the schematic is something like this: LCSC 
It can switch up to 10A and voltages up to 30VDC or 250VAC. 
Please be careful if using the timer with high voltages and/or high currents!

Here is short video demonstrating how to operate the timer:

Here the archive with all project files: Timer_PIC16F18313

I only test the schematic on a breadboard, so there is always a possibility for errors in the PCB. Check everything for yourself and use the files on your own responsibility.

Wednesday, July 12, 2023

Triangle and Trapezoid Wave Generator

 I was searching the web for schematic which can generate a trapezoidal waveform. None of the results was suitable for my needs, so i started to experiment in LTspice (still learning it), and I designed an interesting circuit, that has great flexibility and it's not very complex.

The left side of the circuit is standard square wave oscillator made with U1 opamp. It can be replaced with 555 oscillator.

The next stage consist of two identical constant current sources (CCS), one with PNP transistor and the other with NPN transistor which alternatively charge  and discharge a capacitor. The upper CCS starts to charge the capacitor C1 when the square wave goes down and the lower CCS starts to discharge the capacitor when the square wave goes up. The up slope angle is determined by the R2 and C1 and the down slope angle - by R4 and C1. The two slopes can have different angles (here the duty cycle is also adjusted):

 If we increase the two slopes enough or increase the frequency, the output signal will become triangle wave:

The third stage is just a buffer.

Friday, June 2, 2023

Mini sine wave oscillator

This project is a variant of the 'Miniature Audio Oscillator' by the great Rod Elliott.

I have made very few changes to the core schematic. I removed the potentiometer used for adjusting the frequency and replaced it with a DIP switch, allowing for easy switching between three different frequencies: 20 Hz, 1 kHz, and 20 kHz. These options should be sufficient for quickly testing various audio equipment.

Additionally, I added a third dual opamp. One half of the opamp is used as an output buffer, while the other half serves as a voltage rail splitter and virtual ground. The schematic is designed for a single rail voltage: a 9V battery should be sufficient, but it can also work with higher voltages up to 30V (depending on the opamps used). If Li-ion batteries need to be used, then it is recommended to connect 3 or 4 batteries in series.

The output signal, as stated in the original article, has very low Total Harmonic Distortion (THD) at approximately 0.12%. While I do not have the necessary measurement equipment to gauge the distortion of my variant, I estimate it to be below 0.5%.

I created this project using the EasyEDA software, with the aim of making it relatively easy to replicate at home. The design employs a single-sided PCB and through-hole components.

This is the schematic:

And this is 3D view of the PCB:

For this project, I used a photosensitive dry film for the first time. It wasn't easy, but after a number of trials and errors, I finally managed to produce a fairly good PCB. Here's how it turned out:

The oscillator utilizes a 4-channel DIP switch to control the activation of different value capacitors, thereby altering the output frequency.

The formula for calculating the frequency is F = 1 / (2π × R × C),

where R = R6 = R7 = 10k and

C = C1_A = C2_A = 680 pF when all switches are OFF. These two capacitors can also be 820 pF. To achieve a frequency close to 20 kHz, I handpicked two 680 pF capacitors with higher actual values.

When the left two switches are ON, C = C1_A + C1_B = C2_A + C2_B = 680 pF + 15 nF ≈ 15.7 pF.

When all switches are ON, C = C1_A + C1_B + C1_C + C1_D = C2_A + C2_B + C2_C + C2_D = 680 pF + 15 nF + 680 nF + 100 nF ≈ 795 nF. Note that C1_D and C2_D are included for fine-tuning the lowest frequency of 20 Hz. While not strictly necessary, omitting these capacitors will result in a slightly higher lowest frequency, around 23-24 Hz.

The output voltage measures approximately 3.5 Vpp or 1.24 Vrms and can be adjusted with the potentiometer.

The schematic is compatible with various types of opamps. I tested it with TL072 and NE5532. The current consumption with the TL072 is approximately 10-11 mA, whereas with the NE5532, it is around 34 mA. For extended battery life, the TL062 is the optimal choice; however, I do not have any available at the moment. With the TL072, the output signal begins to visibly distort when the supply voltage drops below 8V.

Here some screenshots from the oscilloscope:

And here is a video of the oscillator at work:

Project files can be downloaded from here: MiniOsc. Use them on your own responsibility!

Monday, December 19, 2022

Shaker for PCB etching

This is an old project, that was sitting in the cabinet for a very long time and I just finished it a week ago. It uses an old computer DVD drive (no one ever uses them anymore). It is completely stripped from all electronics and mechanics except for the parts that move the tray in and out. The motor inside is a simple DC motor.

The shaker uses an 8-pin microcontroller PIC16F15313 and a motor driver module based on DVR8833 chip.

There are two NO reed switches that are mounted on the case and two magnets glued on the moving tray. When one of the switches is closed by the magnet the microcontroller reverse the direction of the tray. There is also an potentiometer connected to an analog pin which control the movement speed of the tray.

The shaker is supplied with 12Vdc from an power adapter. It will work with voltages from 6V to 12V. For the microcontroller there is a 78L05 voltage regulator.

At first there was an power resistor mounted on the bottom of the aluminium sheet and connected directly to the 12V rail. The idea was to heat up the container with the etch solution, but because the container is plastic there was not much heat transfer going on and I removed it. Now I heat up the solution in the microwave oven first, and then I put the PCB in and use the shaker.

The circuit is assembled on piece of perfboard.


When using this shaker make sure the speed is not too high, because there is a risk of spilling potentially dangerous liquid around.

The code for the microcontroller is created in MPLAB X v6.08 and can be downloaded from here: Shaker_Source_Code.

Sunday, November 27, 2022

IR remote code reader (NEC protocol)

This is a quick project on breadboard for decoding and displaying the signals from a IR remote.

The technical details of the NEC IR transmission protocol can be read here.

The project uses PIC16F628A microcontroller and 4 digit 7-segment common cathode LED display for showing the codes. The first two digits represent the address for the receiving device, and the next two digits represent the command code. The format of the codes on the display is hexadecimal.

The schematic is extremely simple:

The program is written in C using MPLAB X IDE 6.0 and compiled with the xc8 compiler.

The source code can be downloaded from here.

Wednesday, April 6, 2022

Driving NeoPixel type ARGB LEDs with PIC

 I have ordered 10 pcs of addressable LED from Aliexpress some time ago and tested them with my Arduino boards and the library from Adafruit and they work as expected. But of course I am more a PIC guy, so I start to thinker with some PIC microcontrollers trying to drive these LEDs. And it is not easy! So the major difference between 8-bit PIC micro and a ATMEGA 328P is that the ATMEGA command rate of ATMEGA is the same as clock rate, so it has 16 MHz clock frequency and 16 MHz command rate but the PICs have command rate 4 times slower than clock frequency. So a PIC clocked at 16 MHz will have 4 MHz command rate and 32 MHz PIC will have 8 MHz command rate. In order to achieve similar performance as ATMEGA, the PIC must be clocked at 64 MHz. 

The difficulty comes from the very high frequency and the format of the output signal. The frequency of NeoPixel signal is ≈800 kHz and the "1" have 800 ns high followed by 400 ns low. The "0" is 400 ns high followed by 800 ns low. And 1 instruction of 32 MHz PIC microcontroller take 125 ns to execute. It is impossible to write a C code that can create such signal in 9-10 instructions. This is achievable only with carefully written Assembler. I had success with PIC16F1847 clocked at 32 MHz.

It was pain in the a**, because there are very little info and tutorials about writing mixed code (C and assembler) for xc8. For example I couldn't find a way to declare a variable in BANK0 in assembly code because the variables in C code evidently take precedence and occupy all the free space in BANK0 first. And it is important the variables to in the same memory bank as PORTB, because changing banks takes one additional instruction. So I has to declare the variables in the C code specifying the exact address... 

The above code has two subroutines _sendByteASM and _sendByteASM2. The first one use a cycle to check and send the bits to the serial output pin (in this case RB4). The best timing I was able to achieve this way was "0" - 375ns/875ns, "1" - 875ns/500ns. And it worked.

The second subroutine check and send every bit separately and there I was able to achieve timing much closer to the required. "0" - 375ns/875ns, "1" - 875ns/375ns. 

Then I got a more modern PIC - PIC16F15344, which have 4 very interesting modules: Configurable Logic Cell (CLC) each of which can be set as 4-input AND, AND-OR, D-type flip flop, J-K flip flop and couple of other types. Also I saw a video from the great Ben Heck where he is using the SPI output from ESP32 with some external logical chips to form the output signal compatible with NeoPixel. 

My thought was to feed the color bytes to the SPI module (configured to work at 800 kHz) and the output (clock and data) to use somehow to form impulses with different length and then combine them with CLC. The following screenshots are the settings of different modules used in this project.

The CLC1 is configured as AND-OR and the signal from the SPI is directly routed to the output. This will be needed later. 

For creating the waveforms of "0" and "1" I used the Complementary Waveform Generator (CWG). This module is used to create a signal for driving half-bridge or full bridge circuits and among other setting there can be set a dead time. So I fed the signal from CLC1 (which is a copy of SCK signal and have 50% duty cycle or 600 ns high) to the CWG module and set the dead time of the rising edge to be about 400 ns and when inverted this will be the "0". The dead time of the falling edge is set to be around 200 ns increasing low time to 800 ns and when inverted form the "1" waveform.

CLC2 is configured as 4-input AND. There I combine the inverted output from CWG1A, CLC1 and SDO from SPI to create the "0" signal:

Finally, all is combined at CLC3 which is set as AND-OR cell:

Here the inverted signal from CWG1B is "AND"-ed with the SDO signal to produce the "1" signal. Then both "0" (from CLC2) and "1" are "OR"-ed to form the final output signal which is routed to one of the pins - in my case RC4/pin6. 

Here some scope screenshots:

The timing here is much better and the beauty of this solution is that there is no interrupts, no assembler code. All of the above is just setup of registers. I am using MPLAB Code Configurator to generate all the code and the actual work is done by the hardware modules and for sending a single byte to the NeoPixels are needed only 2 lines of code. Here is the function to send the 3 bytes for red, green and blue:

Bellow is a video demonstration how it work with the assembler code. I adapted some of Adafruit library functions for this demo: rainbow, their table for gama8 function and the function for HSV color.