24 aprilie 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...










09 aprilie 2024

ADC. Rezolutii si Volti

ADC-urile convertesc eșantioanele unui semnal analogic în valori digitale.

Rezoluția ADC-ului este numărul de biți pe care îl utilizează în vederea digitizării eșantioanelor de intrare. 

Pentru un ADC pe n biți, numărul de niveluri digitale discrete care pot fi produse este 2n. 

Astfel, un digitizor pe 12 biți poate rezolva 212 sau 4096 niveluri. 

Cel mai puțin semnificativ bit (lsb) reprezintă cel mai mic interval care poate fi detectat și, în cazul unui digitizor pe 12 biți, este 1/4096 sau 2,4 x 10-4. 

Pentru a converti lsb într-o tensiune, luăm intervalul de intrare al digitizorului și îl împărțim la doi, ridicat la rezoluția digitizorului.

27 martie 2024

VFO Encoder selection for Xiegu G90

 From time to time someone start searching for part number of the VFO encoder.

Here is a selection of part numbers for encoders without detent (no clicks).

As a personal observation, with more than 18 pulses per revolution it is a pain to use a no detents encoder...

For no detent encoders:


From BOURNS:



PEC11R-4020K-S0018 with knurled shaft, 20mm lenght, no detents, momentary switch and 18 pulses per revolution.

PEC1R-4025F-S0018 with flatted shaft. From ALPS, EC11E, 20mm long flatted shaft (only) momentary switch.

 

 

From ALPS: 


EC11E153440D with 15 pulses per revolution.

EC11E18344Oc with 18 pulses per revolution.

 

For both producers I reccoment study their product selection datasheets which can be downloaded as pdf clicking on their names.

 

I usually like to have longer shafts and cut them to my needs so, if you want a shorter one, just check the datasheets for the part number. 

Both are producing compatible encoders for VFO, VOL and FUNCTION. 

 

23 martie 2024

Simplyfying the code by using a tic-tac machine

Playing with Arduino and it's C++ I often use timed tasks.

Basically, in Arduino you can do things at specific interval either by adding delay() at some strategic points or using wellknown non-blocking code:

const unsigned long interval = 1000; // Interval for LED blink (in milliseconds)
unsigned long previousMillis = 0;    // Variable to store time since last LED update

int ledPin = 13; // Pin for the LED

void setup() {
                    pinMode(ledPin, OUTPUT); // Initialize LED pin as an output
  }

void loop() {

                  unsigned long currentMillis = millis(); // Get the current time

  // Check if it's time to update the LED
  if (currentMillis - previousMillis >= interval) {
                    previousMillis = currentMillis; // Save the last time LED was updated
                    digitalWrite(ledPin, !digitalRead(ledPin)); // Toggle the LED state
          }

      // Other non-blocking tasks can be added here
}
 
What if, the code need more than one timer?
Well, we  can use multiple timers like that!
While this is the simple and easy way, in a big code we start loosing track of what does what and if the code is big, each byte counts! Let's not forget that  each unsigned long type variable cost us 4 bytes of precious memory; each byte consists of 8 bits, and an unsigned long on Arduino is a 32-bit data type, so it occupies 4 bytes (32 bits / 8 bits per byte = 4 bytes).
I have a program in which I have to test multiple timers with multiple distinct intervals and the memory cost was huge.
So, I stayed and think and found a very elegant solution.
While I may reinvented the wheel, I think it is nice to share it with you!
It is all about making a single time measuring function and asign boolean variables to keep track of various things.
  unsigned long previousMillis_ONESECOND = 0; // Variable to store the last time the ONESECOND was flipped
  const unsigned long interval_ONESECOND = 1000; // Interval at which to flip the ONESECOND (in milliseconds)
    bool ONESECOND = false;

void loop(){
    updateONESECOND(); }

void updateONESECOND(){
          unsigned long currentMillis = millis(); // Get the current time
 
          // Check if it's time to flip ONESECOND
          if (currentMillis - previousMillis_ONESECOND >= interval_ONESECOND) {
            // Save the last time ONESECOND was flipped
            previousMillis_ONESECOND = currentMillis;

           // Flip ONESECOND
            ONESECOND = !ONESECOND;
      }
}
then, I have other functions that check various conditions AND bool.
For example, a function that blink a special character on a LCD: 
 
bool ProcessSTART = false;
 
void fLCD(){  // alternate symbol at a rate of one second while StartLog is activated
            if (ONESECOND && ProcessSTART){
                     printFN_Char();
                            }
                else {
                     printFP_Char();
                }
}

the other bool ProcessSART is flipped in other part of the program.
In other functions you can count the number of seconds using this tic-tac function and get other intervals derived from it, using less bytes in a simple arithmetic function.
It's like using an external time generator for all the functions in the code.

06 martie 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




 



23 ianuarie 2024

MESHTASTIC TTGO T-Beam V.1.1 Power On issues

 A few weeks ago, I start to play with Meshtastic using two TTGO - TBeam V.1.1 LoRa boards based on ESP32 MCU.

Because plans are to use them as ROUTER_CLIENT, I choose to recharge the battery using a separate TP4035 module and a solar panel.

Of course, I could very well use the built-in AXP192 battery management but the circuit was pretty unsuitable for small solar panels and the TP4056 offers a more stable configuration. 

In the tests I observed a strange behaviour that can negate the usage of these boards as a reliable remote installed device: 

if the battery voltage drops under the Low voltage treshold, the board will not boot into operating mode.

The same behaviour was consistently observed even the charging was resume on the USB port on the T-Beam board itself.

The ESP32 datasheet have some clues about why this issue occurs and how to mitigate it.

Once the power is supplied to the chip, its power rails need a short time to stabilize. After that, CHIP_PU – the
pin used for power-up and reset – is pulled high to activate the chip. For information on CHIP_PU as well as power-up and reset timing, see Figure 2-4 and Table 2-2.


• In scenarios where ESP32 is powered up and down repeatedly by switching the power rails, while there is a
large capacitor on the VDD33 rail and CHIP_PU and VDD33 are connected, simply switching off the
CHIP_PU power rail and immediately switching it back on may cause an incomplete power discharge cycle
and failure to reset the chip adequately.
An additional discharge circuit may be required to accelerate the discharge of the large capacitor on rail
VDD33, which will ensure proper power-on-reset when the ESP32 is powered up again.
• When a battery is used as the power supply for the ESP32 series of chips and modules, a supply voltage
supervisor is recommended, so that a boot failure due to low voltage is avoided. Users are recommended
to pull CHIP_PU low if the power supply for ESP32 is below 2.3 V.

I run some tests and found that if the above hints are observed, the recovery of the ESP32 from transient voltage induced coma is 100% so a supervisor chip was ordered.

The STM1001 microprocessor reset circuit is a low-power supervisory device used to monitor power supplies. It performs a single function: asserting a reset signal whenever the VCC supply voltage drops below a preset value and keeping it asserted until VCC has risen above the preset threshold for a minimum period of time (trec).

To be continued...

LATER EDIT:

The STM1001 finally arrived (after three days) and I was eager to test the validity of my rationale.

 
So, I installed it on the board; the Vss was soldered on a little island of Copper exposed by a sharp razor and the Vcc was tied to the Source pin of the P-channel NCE3401 MOSFET.

 

 

This transistor is there to protect the board against reverse polarity from the battery.

The RST of the STM1001 was tied to RST of the T-Beam board.

And here it is, the final installation:



Now, for the tests...

There are two distinct situations, depending on how the battery is charged; internal or external.

 

FIRST VARIANT - battery charged internally, using the AXP192

The battery is directly installed on the board and the AXP192 circuit is used at it's full. 

The battery is a small capacity one (1.28 Wh), to be able to have it quicly charged to observe the parameters.

The battery is charged by AXP192.

Going from a flat battery (around 2.5V), the  voltage of the cell, measured at STM1001 Vcc and Vss.

The blue LED is signalling the charging, the voltage is rising and when it reached 3.19V (on my DVM), the RST is released from Vss to 3.2 V (the Vcc of the ESP32).

The ESP32 start to run, the LoRa RTX is sending the first beacon.

This was consistent during a set of 5 tests.

SECOND VARIANT - battery charged externally through a TP4053 board.

The same battery is connected to a TP4053 board with protection and the output of the board is connected to the T-Beam board in place of it's battery.

The AXP192 is not able to manage the charging process because it cannot detect the external power presence.

Therefore, the AXP192 will not start and will not be able to Power On the T-Beam board, at least in the current firmware used for Meshtastic.

Due to the way it works (it is a very complicate process - if you don't believe me, read the AXP192 datasheet) it is mandatory to simulate PEK press (Power Enable Key) after the voltage reach 3.2V which is beyond my scope.

I did some crude tests and it is doable but the solution will be more complicate than the one I am searching for.





 


Most viewed posts in last 30 days