I put here at the beginning the zipped file containing the sketh for ESP32, the .aia file for Mit inventor the LTSpice files (if you want to make the LC circuit) and the compiled .apk app
ZipFiles.zip (5.5 MB)
Hello everyone
I decided to develop this software to avoid using a dedicated touch screen for each project used on ESP32 or Arduino
Especially on Arduino the use of a touch screen takes up a considerable number of pins which are already less than on an ESP32 and very few remain free.
I tested the program both with ESP32 Wroom and with ESP32-D Wroom, the differences I found between the two are that ESP32 must be bound to the phone, while on ESP32-D binding is not necessary, furthermore, when you upload a new sketch on ESP32-D, you do not need to press the reset button every time (really boring), and the serial monitor starts directly.
What you need:
ESP32 or Arduino with BLE
Phone with BLE
Arduino Ide + MIT App Inventor 2 for Android (https://code.appinventor.mit.edu/login/?locale=en) as a browser they recommend using Chrome or Firefox, I, who used the USB connection, found Chrome better, even if every now and then they lose the connection and you have to re-establish it (I recommend closing the app on the phone, then give the reset connection command in the MIT menu and then re-establish a new connection).
If you want to use the project as is, you will need a CL tank circuit connected to ESP32 (pins 16 and 17) and the AD9833 waveform generator that uses the pins SCLK = 18, MISO = 19, MOSI = 23, SELECT = 5 and a pin of your choice (I used pin 4) for the LedC output that can vary the Duty cycle and therefore change the lighting of a LED or the speed of a motor.
The CL circuit allows you to measure the inductance of a connected inductor, in addition to the resonance frequency (useful for example for a metal detector to get the most out of the generated magnetic field) and the cycle length (useful to determine the minimum space between an ON signal and the next).
Unfortunately AD9833, which is great for generating a clean sine wave up to 12500 Hz, does not have commands available to vary the Duty cycle, so for the type of square wave with variable Duty I used the LedC function of ESP32 high speed (up to 19000 Hz with 12 bit resolution) which is used in my sketch if you select 3 as the wave type.
Why Mit inventor and not Android studio or something else?
Because everything runs better and faster and is more accessible to everyone..the only thing I criticize is the automatic saving that cannot be disabled, and this forces you to save your work often, so if you make a mistake it loads the previous version.
Android Studio is always evolving and when you load a program made a year before (always with Android Studio) it generates a ton of errors and you have to waste hours to solve them, if then you try to import pieces of code found online the thing becomes even more complicated also because maybe that instruction is no longer supported by the new Android versions, or because those privacy settings (ridiculous) continue to change.... making programming on that tool truly a stress and a huge waste of time.
Closing this parenthesis, let's first examine the Android side with this image that displays the first page of the 3 that I have set in the program (selectable with the B1-B2-B3 button on the phone), each page has 6 slots available (you can increase both the buttons and the slots and then review all the code on both the Android and ESP32 sides to adapt it to your needs) and below I include a screenshot of the first page
You can use these pages both to receive data from Arduino (for example, page B1 in my example receives data from the CL circuit connected to ESP32, while page B2 I used to send data to ESP32, so I can select the type of wave of AD9833, frequency etc. (or if I select wave type 3 ESP32 will execute the high speed software routine that is based on the ledc instruction of Espressif, which generates a square wave with duty cycle modifiable), and the Duty selectable in index 10 will only work on wave type 3 because AD9833 does not allow you to set this field.
Below I put two images, the first displays page 2 (B2) and the second is taken from the oscilloscope (and then displayed in my program developed in .net) that shows the 2 waveforms activated by the program, in channel 1 a sinusoidal generated by AD9833 and in channel 2 the square wave generated by ESP32 with duty cycle 25%
The files that set the 3 fields of each line are read when the app starts (loaded by the MEDIA section of MIT) and are List1Field.csv List2Field.csv and List3Field.csv.
In MIT, if you click with the mouse on for example in MEDIA List1Field.csv you can download this file to your PC and modify it with a text editor and then reload it after the modifications in MIT with the same name and it will replace the previous one.
The first file (List1Field.csv) is an index list (first column), the second file is the name that will appear on the button (second column) and the third field is the editable data for sending to ESP32 (third column with white background) or to display the data arriving from ESP32.
The third field can be useful to set a starting variable for that given field (if it is a data sending field and not a receiving field), but let's take an example: if for example, on page 2 (B2) in the first line (choice of waveform) 1 is set, by clicking on the WaveForm 1-2-3-4 button, 1 will automatically appear in the text field to be sent, so just press SEND and the waveform change command will send 1 to ESP32, i.e. sine wave selection; if instead you enter 2 in the text field, it will be saved until the app is restarted.
To activate the waveform output you have to press on the waveform selection, otherwise it will remain in OFF mode, and then you can choose the frequency etc..
Unfortunately in the ASSETS we can only read the files and not save them from the program (for example when exiting the app, so we would have found them the same the next time we use the APP) and going to save them in other FileScope (App, Cache, Legacy, Private and Shared) we clash with the various Android versions and with the Privacy settings, so I preferred to use Assets and not other directories scattered on SD, internal memory etc. at least everything remains internal to the app for easier portability on other phones.
Below the 6 lines there is a start/stop button, this is used to tell ESP32 to start sending data through routine1 which is in the main loop, this routine only works if we are viewing page B1 (the page position is controlled by ESP32 which uses routine1 only if page B1 is displayed on the phone), but if you want you can also disable this control, since, through the index of the message sent by ESP32, the data will only arrive at the line of the relative index.
Below this start/stop button there is a label that displays the index to which we will send the data in the text box next to it (clicking on this text box displays a keyboard with only numeric data that we can send to ESP32 by pressing the SEND button).
Also in this case there is a check to see if we are actually on the right page, that is, we can send data to AD9833 only if we are on page 2 (B2).
The text field can send a maximum of 10 digits not exceeding 2147483647.
I have already documented the sketch for ESP32 quite a bit in the rem, let's say that in the initial routines we find the one that interprets the data string arriving from the phone which are practically 2, that is an INDEX (the first 2 characters) and a Value which are the numbers coming from the third column of the phone (text box).
If the second value is null, it is a command string, for example to communicate to ESP32 that I have changed page on the phone (B1-B2-B3).
If instead the second value is present, then it is processed with switch (Identity) {
case...
Other subroutines are for the BLE connection/disconnection and after the SETUP we arrive at the LOOP where the sending of data from the ESP32 to the phone is managed, which in my project only concerns the first page of the program of which I report a screenshot below:
The Loop first checks if we are connected to the BLE and then every second, depending on the ROUTINE variable, jumps to one of the 3 possible routines.
In my example it is only routine 1 that sends data to the first page of the phone and I report the code here:
void routine1() { // routine 1 that send 3 parameters to phone, so Freq/Period/inductance of CL circuit
numPulses = 0;
digitalWrite(16, HIGH);
Delay(10); // I charge the capacitor
digitalWrite(16, LOW);
delayMicroseconds(30); // <<<<<<< Time lapse between ESP32 signal end and CL tank circuit oscillation start
readTime();
inductance = (float)(pow(1.0 / (6.283185307 * freq), 2)) / capacitance;
inductance *= 100000L; // uF
if (numPulses > 0) {
stringVal = String(freq);
T_buff[(stringVal.length() + 1)]; // string + null terminated char
dtostrf(freq, 1, 2, T_buff); // 1 is mininum width, 2 is number ofdecimals
stringVal = String(T_buff);
stringSend = "01" + stringVal;
pCharacteristic->setValue(stringSend);
pCharacteristic->notify();
Delay(10);
stringVal = String(Periodo);
T_buff[(stringVal.length() + 1)];
dtostrf(Periodo, 1, 0, T_buff); //1 is mininum width, 2 is precision
stringVal = String(T_buff);
stringSend = "02" + stringVal;
pCharacteristic->setValue(stringSend);
pCharacteristic->notify();
Delay(10);
The first part sends a start signal to the CL circuit ( digitalWrite (16, HIGH) ) and then queries the readTime() routine
void IRAM_ATTR isr() {
unsigned long now = micros();
if (numPulses == 0) {
Time1 = now;
} else {
Time2 = now;
detachInterrupt(17); // disable interrupt after second signal from CL wave
}
++numPulses;
}
void readTime() {
// Opzioni: DISABLED RISING FALLING CHANGE ONLOW ONHIGH ONLOW_WE ONHIGH_WE (wake up the ESP32 from light sleep)
attachInterrupt(17, isr, CHANGE);
Delay(5);
//formula frequenza = 1 / Periodo
Periodo = (float)(Time2 - Time1) * 2.0;
freq = 1.0 / Periodo;
freq *= 1000000.0; // Hz
}
which activates an interrupt and examines the changes (CHANGE) on pin 17, and at the second signal the interrupt is interrupted and the length is evaluated and therefore the frequency and induction.
And then this data is sent, one string at a time because the default BLE (but they can be increased) has a maximum of 20 bytes of sending (3bytes of header and 20 of data) and, importantly, a delay is needed (20 milliseconds) between one sending and the next so as not to overload the BLE which is not very fast in sending.
In my example, every 10 readings, I also calculate the average duration of the Period that I need to determine the Calibration, because the circuit also works as a metal detector (5-6 cm away since the start signal coming from ESP32 is only 3.3 Volts and therefore the magnetic field generated by the inductor is really low) and in the Metal Detection field on the phone I will see negative numbers if I bring non-ferrous metals close to the inductor and positive numbers if I bring ferrous metals close.
I think I have listed the essential things of this project, then it is up to you to adapt the MIT part and the ESP32 part to your project, but basically you will have a working BLE connection using only 2 UUIDs, and a very respectable touch display even using an old phone and a considerable energy saving on ESP32 without a display, and many free GPIOs.
I am calmly making a video and will soon put the link below.
Hello everyone and have fun









