Showing posts with label ESP32. Show all posts
Showing posts with label ESP32. Show all posts

25 July 2025

A GNSS Disciplined CTCSS, DCS and DTMF generator based on ESP32

Let me present a project to both show off and because it might be useful to others, a GNSS disciplined CTCSSDCS and DTMF generator.

 


Why? How?

This is the "bottom of the well" (from "out of the frying pan into the fire") because I initially started with a repeater controller (also ESP32 based), to which I wanted to add CTCSS/DCS/DTMF detection and generation (DSP based over ESP32 - still work in progress). 

After creating the detector (based on DSP on the ESP32 dual-core platform), I found that I had no means at hand to verify the accuracy of the detection!

Industry standard in CTCSS require precision of less than 1% (typically 0.5%), so I needed a laboratory instrument to validate the decoder results.

So, after a brainstorming session with myself, the solution emerged from smoke and beer - a GPS-disciplined oscillator. Twenty years ago, this would have been difficult to implement, requiring far too much effort on the hardware side and at a prohibitive cost.

Hey, but now we have very capable development boards, with the very board I was developing the repeater on sitting on my desk. The same one I was developing the decoder on...

Well, I thought, why not a signal generator disciplined with a GNSS PPS signal?

Signal generation, sinusoidal (well, approximately), would fall to one of the two DACs available on the ESP32 platform.

 

I consulted with ChatGPT to check if the ESP32 performance allows implementing such a generator and if it's possible to use a WEB interface for control (GUI) to get rid of HW accessories like encoders, buttons, display, etc...

The "debates" were interesting and helped me crystallize the development direction of the project. It's really good to have "matches" with this artificial intelligence, it can help you put your thoughts in order when you go off track!


  

Getting to Work!

However, I shifted the difficulties from hardware to software. During development, I encountered a phenomenon similar to the wave-particle duality, namely, "observing" the ESP32 software oscillator introduced completely random and impossible-to-compensate errors.

The most sensitive processing is made in ISR functions and observing what was happening inside them was sometimes pretty delicate. In other points, introducing Serial Debugging lines delayed the execution of some other delicate functions.

Signal generation is a time-based thing and calculations of the time in the ISR was simply impossible, delaying the execution and producing malformed wave-forms. Calculations made outside were simply, lacked on precision even using dinamically calculated correction factor. 

For those understanding this aspect, the solution was seemingly simple but drained my energy for about two days (summer days, until evening).

Instead of time-difference-based measurements, the timers were based on cycle counting and these were used as references. For an engineer probably this was the right choise from the beginning but for me, as a full-time lawyer, this was a real milestone.

I'll close this overly-extended technical parenthesis. Similarly, I won't go into boring details about disciplining the software DDS based on the pulse received from the GPS receiver, but I'll present a few aspects, as I'm proud of them!

Most receivers provide a pulse-type signal with a duration of about 100 msec, every second, with the precision imposed by the GNSS signal, which in turn is provided by atomic clock sources.

The "disciplining" algorithm works like this: the timer that forms the basis of signal generation provides one pulse per cycle; at each pulse received from the GNSS receiver, the theoretically calculated value is compared with the practical value. From the difference, a correction factor is calculated which is then applied.

It seems simple, but in this algorithm, there are a series of self-adaptive functions that ensure that changes are progressive, applied at zero crossings, and other such interesting tricks, discovered through repeated wall-hitting during the project...

 

The Nail in the Shoe

I spent a healthy number of hours on a series of problems whose cause I couldn't identify and which kept the process stalled.

The paradox: compilation ran without any problem, but the functionality of the code was non-existent in certain absolutely necessary processes!

An INTerrupt refused to trigger... Just like that, as stubborn spoiled kid! I spent two days trying to understand what was happening and was even thinking I was approaching the third day (when if the problem doesn't solve itself, projects must be abandoned)!

I already write about this stupid moment in my life...

After reverting to an "outdated" version, I overcame the first major hurdle.

 

Verification

It wasn't as simple as it seems, but at some point, the signals started to be visible on the oscilloscope, and another question emerged from the fog and beer: How the heck do I objectively verify what comes out of the DACs?


The solution, again elegant (I think), was comparing a derived reference (brutally square) from the GPS signal but with high frequency (5KHz) with the signals generated by the DAC and with the signal from the GPS using a multichannel oscilloscope.

And the result... mmmm, the result was exceptional and encouraging, with deviations beyond the observation limit, within the signal noise limits!

The heat kept me away from the journey to the laboratory where I have more sophisticated equipment, but for something done "on the table," I'm more than satisfied.

 

DCS Signal: 

 
 SINE Signal:

 

 

Web Interface

The eye must also be satisfied somehow, and here I heavily involved Artificial Intelligence because, on one hand, I don't master the domain, and on the other hand, the complexity of the graphical interface (GUI) and the Front-end (the code executed in the browser, which communicates with the Back-end - the actual program in the ESP32) requires coordinated interventions in many parts of code. Exactly what AI is good for! Except that sometimes it hallucinates!

Seriously, AI, I discovered, hallucinates, which is why it often ruined what I had laboriously built. An opportunity for it to learn some genuine Romanian curses, the kind Păcală would say to make the Devil's eyes pop out of his head!

In the end, from the confrontation, I emerged a little more knowledgeable in these aspects and at least can give the LLM (Large Language Model - AI that is) very precise instructions, which keep it awake and from which I can get what I want!

I tried to make the interface as simple to use as possible, like a laboratory device - which is what this project actually is - but also easy to use for anyone who wants to transform an ESP32 into a CTCSS/DCS/DTMF signal source for various projects.

The usage is intuitive, and there may still be some bugs; "the master's eye fattens the calf," so it's hard for me to discover them myself, it remains for users to shout out what's not OK here and there.

In principle, the user interface reflects the internal architecture:

 

It's divided into logically organized sections that provide control and feedback... what more can I tell you?

It also has an interface for uploading files necessary for the graphical interface; anyone who wants can make their own interface!

 


You have no idea how much I struggled to make batch file uploading work! It was murder to keep uploading them one by one!

 

A Few Words About Performance:

- Accuracy in generating CTCSS and DCS signals, better than 1% (I'd say better than 0.5%) but I don't want to boast too much!

- I also attached a tone generator with frequency between 40 Hz and 1.2 KHz, but above 900 Hz the signal begins to degrade due to digital-to-analog converter limitations.

- DAC1 and DAC2 signal level:

* max 2.35 Vpp.

* med: 1.6 Vpp.

* min: 850 mVpp.

- 0-3V logic signal outputs for various signals, also disciplined with GNSS.

 


Laboratory Integration

For the project to become a laboratory equipment, it's useful to connect a GNSS module that has visibility to the sky. The code doesn't use any other information transmitted by this module except PPS, so a connector with 3 wires can do the job just fine.

Even in the absence of the GNSS receiver, the precision is quite high, demonstrated by observing the correction factor applied following the 1PPS signal; this was a surprise because I expected larger errors but it seems that the architecture and non-blocking code it helps a lot.

Regarding the signal in the analog domain, i.e., the outputs, minimal filtering on each of the two outputs could improve signal quality by reducing possible artifacts produced by digital generation. Although there is a digital "volume" on each of the two DACs, it would be useful to have potentiometers for fine adjustment of the level to the DUT (the equipment benefiting from the signal).

A low-pass filter for frequencies below 1 KHz for DAC 1 and one with a limit at 2 KHz for DAC 2 would be welcome; in their absence, at least a network of 1 Kohm and a capacitor of about 1 nF to ground could reduce artifacts at the cost of some loss from the useful signal.

The generator can be integrated into the existing WiFi network or can generate its own Access Point.

 See? Have you forgotten what it started from?

Yes, I forgot too; I needed something that would very precisely generate a CTCSS tone...

 

I'll leave you a link to the GitHub page of theproject where you can find it already compiled, so you don't have to bother with the necessary libraries:

 


OK, so the project was completed at the cost of a few sleepless nights.

While searching for a board to mount the potentiometers to unify the two audio channels, I found at the bottom of one of the many boxes that accumulate with "you might need it someday" a board with an FX365 circuit, CTCSS Decoder/Encoder. Life has mysterious ways of pulling the rug out from under you!

Oh, well... Sometimes life sucks! 

Anyway, for me was a real technical journey into some unknown territories and I am really happy I could see it working at the end. After all, we are hams for this kind of exploration into "hic sunt leones", uncharted  areas of technology...

Feel free to test and drop a comment if you liked or not and if you have suggestions but keep in mind this is a tool for a small lab with the main scope of generating a precise frequency to help the tests of a CTCSS/DCS/DTMF decoder for a ham radio repeater... :-)

73 from Adrian, YO3HJV

24 April 2024

Expansion board for ESP32 D1Mini

 


Well, after testing a lot of ESP32 development boards, I found that the little ESP32 D1 Mini is an excellent one.


 

First of all, it is very fast when programming!

Second, you don't have to fuss around with pressing BOOT, EN/RST or other complicated procedures!

Third, never, but never the programming stopped due to communication errors (like a lot of DevKit boards).

The single inconvenient I can found, and is a big one, is the dual rows of pins!

They are hard to access, I always misread the labels because they are very crammed and I found stupid to have them on the back of the board, but this is, of course, because there is no space on the upper side.

Anyway, you get the ideea: very good boards but pretty hard to use Dupont wires to test various hardware with them.

So, I was looking to an expansion board for Arduino Nano and asked myself if I can find a similar board for D1 Mini! Back in the old days when i start with Arduino (and Nano was a cheap thing) this expansion board was a gem and help me with a lot of projects....


So, I searched for a similar one but all that I found were little boards with some sh$%# on them, none being what I was really needed!

But then, I asked myself, "why not MAKING one"?

First step is to make a PLAN! What are my expectations? How do I mostly use this dev boards? What accessories I often use? 

So, the requirements were written on a paper:

-Power supply from a various sources; both from USB and from external 6-20V.

-Multiple I2C configured to use I2C LCD with SCL, SDA, +, GND.

-I2C for 3V3 and 5V accessories.

-Every GPIO to have it's 3V3 and GND pins near for easy wiring.

-If the board is external powered, the regulated voltages to be available for other accessories.

-Multiple SPI.

-Accessible UART for ... things...

Using EasyEDA I made the schematic:

... and while waiting for the boards ordered in China, I also ordered the components.



Well, yeah, a close inspection will reveal that I made a mistake with the coaxial power Jack... I wired the wrong pin to Vcc :-( but the cutter fixed the little annoyance.


 

The 3V3 can be selected from the external power supply or from the ESP regulator:

 

I have two 3V3 I2C and two 5V I2C. Yes, i know the best practice is to have level translators but a 220 Ohm on each SDA and SCL will do the job very well...


 

3 SPI, one with the CS0 at GPIO5


UART and two regulated power outputs:

 

... and each GPIO have its GND and +3V3 near...



All files can be found on Github.








06 March 2024

Frecventmetru 0-1GHz cu ESP32

Uneori am avut nevoie de un frecventmetru cu precizie ridicata pentru verificarea unor montaje facute acasa.

Cum spatiul pe masa de lucru este limitat, nevoia m-a impins sa caut un echipament miniaturizat.

Sigur ca exista produse industriale dar, unde mai este placerea de a construi ceva?

Un frecventmetru cu ESP32 ar rezolva problema, mai ales ca, teoretic, poate masura frecvente pana la 40 MHz.

Cu ajutorul unui prescaler, gama de frecvente masurate poate fi extinsa, cu mentinerea unei precizii satisfacatoare in pseudo-laboratorul de acasa.

 






 

Schema electrica (click pentru o versiune marita a imaginii):

Cateva precizari:

-Nivelul maxim al semnalului la borne este de 10dbm, adica 10mW/50 Ohm.

-Montajul poate fi simplificat prin utilizarea doar a placii ESP32 si a condensatorului de decuplare la intrarea de semnal dar recomand, totusi, utilizarea unui divizor pentru a proteja intrarea de semnalele mai mari de 3V varf la varf.

Pentru a obtine fisierele .bin necesare scrierii programului, va rog sa ma contactati prin email



 



Programarea unui ESP32 fara Arduino IDE

Placile Arduino deja fac parte din istorie iar hobbystii deja au la dispozitie platforme de experimentare tot mai puternice din punct de vedere al interfetelor oferite.



Espressif a iesit pe piata cu ESP32, un MCU ce incorporeaza periferice IO digitale, ADC-uri de inalta rezolutie si WiFi/BLE, totul intr-un pachet miniaturizat si cu consum extrem de redus ce il face deosebit de versatil pentru proiectele care incorporau pana acum platforma ATMEGA.


Pretul comparabil sau chiar mai scazut al placilor de dezvoltare  bazate pe SOC-ul ESP32 a determinat migrarea multor proiecte spre aceasta platforma iar  IDE-ul Arduino a primit bibliotecile necesare pentru a fi compatibil.


Uneori insa, suntem in situatia de a avea fisierele gata compilate, exportate din IDE Arduino sau alt mediu de dezvoltare si dorim sa facem programarea cu un alt calculator ori am primit fisierele de la altcineva care nu doreste sa faca public codul sursa. 

Cu ajutorul aplicației ESP Download Tool este posibilă încărcarea programelor compilate (fișiere BIN) în ESP.
Acest articol se referă la pregătirea utilitarului și la diferiți parametri necesari pentru transferarea cu succes a acestor fișiere.


Pasul 1, descarcarea aplicatiei ESP Download Tool

Programul este oferit chiar de producatorul Espressif iar descarcarea se face sub forma unei arhive.

Dupa descarcare, dezarhivam fisierele; vom obtine un folder in care se gaseste un fisier .exe si alte subfoldere necesare functionarii aplicatiei.

 


Pasul 2, rularea aplicatiei.

Este de retinut ca aplicatia ruleaza direct, fara a fi necesara instalarea ei. 

Programarea cipului are loc insa pe o interfata UART, seriala, asadar, daca calculatorul nostru nu are port COM nativ sau programarea se realizeaza prin intermediul unui adaptor USB<>UART, este posibil sa fie nevoie sa instalam unele drivere in cazul in care Windows nu le instaleaza automat. 

In general, placile de dezvoltare au deja acest adaptor USB<>UART incorporat in design; in imagine, o placa MCU32 Devkit cu circuitul adaptor CP2102.


Pornim aplicatia ESP Download Tool din executabilul flash_download_tool_3.x.x.exe; se vor deschide doua ferestre; una de tip Terminal (care va afisa datele in timpul operatiunii de upload) si a doua, pentru selectarea tipului de MCU ESP. Cu acest software se pot programa si ESP8266 precum si toata gama ESP32.

 

 

Chip Type: Daca lucram cu un modul ESP32 WROOM (atentie la inscriptia de pe ecranul metalic), atunci selectam
"ESP32-D2WR" iar pentru restul, in marea majoritate a cazurilor putem folosi optiunea generica "ESP32".


WorkMode:  Intotdeauna alegem "Develop". Modul "Factory" este destinat programarii mai multor MCU simultan.

 



Pasul 3, conectarea ESP32 la calculator.

Acum este momentul sa conectam placa de dezvoltare la USB  direct sau prin intermediul adaptorului USB<>UART.

Verificam in Device Manager daca driverul este instalat si functioneaza.

Unele placi de dezvoltare necesita apasarea unui buton in timp ce sunt conectate la USB; acesta este notat "FLASH" sau "BOOT" si nu trebuie confundat cu "RESET" sau "EN"!



Pasul 4, setarile aplicatiei.


Înainte de a selecta fișierele BIN și adresele sectoarelor de memorie, trebuie selectați unii parametri pentru ESP32.
Practic, majoritatea plăcilor ESP32 ar trebui să funcționeze cu următoarele setări:

SPI SPEED: 80 MHz
SPI MODE: DIO
Dimensiunea Flash: 32 Mbit (4 Mbyte)

În plus, trebuie să se specifice portul COM în software.
Viteza de transmisie (BAUD rate) este setată la 921600.
Abia după aceea este necesar să fie specificate căile către fișierele BIN și sectoarele de memorie.


Pasul 5, selectarea fisierelor BIN si a adreselor locatiilor de memorie unde trebuie incarcate.

Programul oferă posibilitatea de a încărca mai multe fișiere BIN în același timp. 

Astfel, nu numai programul propriu-zis, ci și bootloaderul sau partițiile pot fi încărcate în ESP32. 

Deoarece, în principiu, un bootloader este întotdeauna deja instalat pe plăcile de dezvoltare înainte de livrare, in cele mai multe cazuri, acesta nu va trebui încărcat. 

Este suficient să încărcați doar fișierul BIN cu programul principal.

Aria pentru programul principal începe întotdeauna de la:: 0X10000
Ambele câmpuri vor deveni verzi dacă datele au fost introduse corect. 

Cu un clic pe "Start" începe procesul de încărcare. 

Dacă acesta a avut succes, acest lucru este confirmat cu "FINISH" (Terminare). 

De îndată ce se apasă butonul de Reset (sau EN) de pe controler, programul încărcat ar trebui să pornească.

2024, Copyright YO3HJV




 



Most viewed posts in last 30 days