En Cocktail Project
En Cocktail Project
an espressif WROOM32
2) Sagittal diagramme 4
2.1) Description of the links 4
3) Functional diagram 5
3.1) FS1.0: Power supply 5
3.2) FS1.1: Stepper motors 5
3.3) FS1.2: RGB LED 6
3.4) FS1.3: uC wifi 6
3.5) FS1.4: Sensors 6
3.6) FS1.5: Pumps 6
3.7) FS1.6: Expansion connectors 7
4) Structural diagram 8
4.1) FS1.0: Power 9
4.1.1) Calculation of a radiator 10
4.2) FS1.1: Step motors 11
4.3) FS1.2: RGB LED 12
4.4) FS1.3 : uC wifi 13
4.4.1) Definition of the inputs, outputs of the microcontroller. 13
4.4.1.1) Inputs 13
4.4.1.2) Outputs 14
4.4.1.3) Other: 14
4.5) FS1.4: Sensors 15
4.6) FS1.5: Pumps 16
4.7) FS1.6: Expansion connectors 17
6) The software 22
6.0) Presentation of Wifi/Bluetooth WROOM-32 module and SDK-IDF 22
6.0.1) WROOM-32 module 22
6.0.2) SDK-IDF 22
6.1) Flash partition 22
6.2) The architecture 24
6.2.1) The espressif SDK 24
6.2.2) The drivers 24
6.2.3) The HAL and OSAL 24
6.2.4) The application 24
6.3) The features of the software 25
1
6.3.1) Wi-Fi connected mode 25
6.3.2) smartconfig mode 26
6.3.3) Update (OTA) 27
6.3.4) Push button 27
6.3.5) File system 28
6.3.6) End-of-run detection 29
6.3.7) Web page for the cmd cocktails 29
6.3.8) Motor control 31
6.3.9) Step motor control 31
6.3.10) RGB LED 32
6.3.11) cJson 32
6.3.12) mDNS hostname 33
6.3.13) Voice assistant (Alexa, Google Home, ...) 33
6.3.13.1) Configure NAT and dynDNS 33
6.3.13.2) Create an Applet on IFTTT 33
6.3.13.3) Open a TCP socket on the ESP32 34
6.3.14) Logs 35
6.3.15) Add-on 35
6.4) The JSON 36
6.4.1) The JSON of the location of the bottles 36
6.4.2) The JSON of the cocktail ingredient list. 36
6.5) The web page 37
6.5.1) The CSS 37
6.5.1) HTML 38
7) Mechanics 40
7.1) The wood 40
7.2) The tray 40
10) Pictures 46
2
1) Introduction
Failing to achieve an interesting feature for the espressif SDK like wi-fi mesh I will present a
fun project. The realization hardware and software of a connected cocktail machine with an
espressif WROOM32. The goal is to be able to:
- Order a cocktail via a phone or PC
- Order a cocktail via a voice assistant (Google home, Alexa, ...).
- Order a cocktail via a IFTTT trigger
For that we will see different IOT functionality proposed by the WROOM32 like:
- Connect the system to internet with smartconfig
- Create a web page
- Use a mDNS and a fixed IP.
- Use a socket for IFTTT
- Update the system with OTA and the flash partition of ESP32
- Use the hardware features on the ESP (gpio, file system, ...)
- Use the FreeRTOS operating system of the espressif SDK-IDF
- Use the cJson library
3
2) Sagittal diagramme
L2 / L2 ':
- Allows the user to order a cocktail via a web page.
- Allows the user to order a cocktail via a voice assistance (Alexa, Google Home, ...)
- Send his SSID and password with his smartphone to connect the system to the
internet.
- Allows the system update with OTA
L1:
- Allows the user to put and retrieve his glass.
- Lighting information about the state of the system.
- Allows fill the bottles and clean them.
4
3) Functional diagram
Input(s):
12V, 5ADC.
Output(s):
+ 5V, + 3.3V, 0V
Input(s):
G1: Digital signals (dir and clk) for controlling the stepper motors.
Output(s):
Physical movement of the engines
5
3.3) FS1.2: RGB LED
The RGB LED informs the user of the system status.
Input(s):
G2: Digital signals to control the RGB LED.
Output(s):
L2: Lighting signals to inform the user
Input(s):
L2 / L2 ': Wifi connection in wpa2, wep, ... smartconfig mode, http web page, socket for
IFTTT, OTA update
G4: Digital Signals for Limit Detection
Output(s):
L2 / L2 ': Wifi connection in wpa2, wep, ... smartconfig mode, http web page, socket for
IFTTT, OTA update
G1: Digital Signals for Stepper Motor Control
G2: Digital Signals for RBG LED Control
G3: Digital signals for pump control
Input(s):
L1: Physical size
Output(s):
G4: Digital signals on / off
6
Input(s):
G3: Digital signals for pump control
Output(s):
Physical movement.
Input(s):
G5: Digital Signals
Output(s):
G5: Digital Signals
7
4) Structural diagram
8
4.1) FS1.0: Power
The power function allows to create, thanks to an input voltage of 12V 5A, + 5V and + 3.3V.
C1, C11: Polarized chemical capacitors. They perform the filtering, and allow a decoupling in
case of power supply
9
U3: 5V regulator, it allows to regulate the input voltage 12V DC in a voltage of 5V DC.
According to the manufacturer's documentation of the 78XX, a minimum input voltage of the
output voltage plus Vdrop (2V) or Ve = Vs + Vdrop = 5 + 2 = 7V minimum is required for
proper operation.
U1: 3.3V LDO, it allows to regulate the input voltage 12V DC in a voltage of 3.3V DC.
P2, P4, P5: Choose the power source (internal or external) according to the current
requirement. It is physically, connecting strips on which we just connect a "jumper" to select
the desired voltage.
P6: Connect an external power supply to not use the regulators (if more power is needed).
Attention P2, P4, P5 must be connected correctly.
10
4.2) FS1.1: Step motors
The motor function allows to control the tray with the glass and to serve the cocktail via the
dosers.
IC1, IC2: are modules based on A4988 for the control of stepper motors powered by 3.3v.
MSI_x inputs are used to configure the step resolution. the STEP input is a clock that
triggers one step per clock period. the input DIR makes it possible to choose the direction of
rotation of the motor.
P16, P17, P19, P20, P22, P32: Allows you to select one of the five state resolutions
according to the truth table above. For the project I am in full step.
P18: Used to connect the motor of the tray with the glass (X axis).
P21: Used to connect the motors to serve the cocktail via the dosers (Y axis).
11
4.3) FS1.2: RGB LED
The RGB LED informs the user of the system status.
U4: Controlled switches (transistor network - ULN2803). Each of these 8 channels can be
open or closed. It is capable of driving a load up to 500mA.
P1: Connect the RGB LED. PIN 5 is not used. You have to connect the LED as follow
(source: forum.arduino.cc/index.php?topic=465854.0)
12
4.4) FS1.3 : uC wifi
Ensures thanks to a programmed treatment (software) the acquisition the treatment and the
return of the information. The smartconfig mode of WROOM32 allows to recover the SSID
and password of the internet box. The wifi allows to control the system via a smartphone or a
computer through a web page on a fixed IP address or with a voice assistance. It
communicates with the motors, the RGB LED. sensors, and offers inputs / outputs to add
additional functionality.
4.4.1.1) Inputs
Switch_MODE: Allows you to delete the Wi-Fi configuration (SSID and password)
13
ESP32-Rx: Allows to send the binaries to be saved in memory of the wroom32
4.4.1.2) Outputs
ESP32_GPIO14, 12, 13, 15: Used to control the direction of rotation of motors and the
speed of steps.
LED_RED: Used to control the red LED. When the system starts, the LED is red as long as
the system has not reached the limit
LED_BLEU: Used to control the BLUE LED. The blue fix indicates that the system is ready
for use. The blinking blue indicates that the system is in preparation for a cocktail party.
4.4.1.3) Other:
SPARE1 to SPARE6: The SPARE inputs / outputs allow you to add new features to the
cocktail machine such as milk powder dosing (of course, this implies a whole system of milk
preservation and hygiene. given as an example.)
14
4.5) FS1.4: Sensors
Allows to delete the SSID and password of the wi-fi with a push button and the end-of-run
detections.
15
4.6) FS1.5: Pumps
The pump function is used to control DC motors.
U4: Switches controlled. Each of these 8 channels can be open or closed. It is capable of
driving a load up to 500mA. After the tests the chosen pump consumes more than 500mA,
so I added an expansion board with relays. You can connect your relays on P13, P14, P15
as follow.
(source: www.brunwinkel.de/elektronik/ics/uln2803/)
16
4.7) FS1.6: Expansion connectors
Allows you to add features to the board.
17
5) The PCB and List of components
5.1) PCB
The PCB does not have any particular constraint except to respect the "hardware design"
proposed by expressif to have the best radio performances. “make sure that the module is
not covered by any metal shell. The antenna area of the module and the area 15 mm outside
the antenna should be kept clean”.
The plans of the masses were put in transparency here for a better representation.
18
5.2) PCB List of components
Comment Description Designator Footprint LibRef Quantity
HEADER 1x3 EMBASE MALE P2, P4, P5, EMBASE 3 HEADER 1x3 10
1 RANGEE P7, P16, P17, VOIES
VERT 3VOIES P19, P20,
P22, P23
HEADER 1x4 EMBASE MALE P3, P6, P18 EMBASE 4 HEADER 1x4 3
1 RANGEE VOIES
VERT 4 VOIES
HEADER 1x2 EMBASE MALE P8, P9, P10, EMBASE 2 HEADER 1x2 - 2.54 7
1 RANGEE P12, P13, VOIES - 2.54mm mm
VERT 2 VOIES P14, P15
2.54mm
19
MC 0.0625W 0402 1% RESIST.CMS R1, R2, R3, 0402 MC 0.0625W 0402 1% 17
10K 0402 1/16W 5% R4, R5, R6, 10K
10K R7, R8, R9,
R10, R11,
R12, R13,
R14, R15,
R16, R17
20
Transformateur 220Vac vers 12Vdc https://www.amazon.fr/gp/product/B06WGR
Chargeur Alimentation à découpage pour XCPK/ref=oh_aui_detailpage_o05_s00?ie=
guirlande Ruban Led Bande 5m 60W UTF8&psc=1
21
6) The software
It is available with this document in zip file and on github
https://github.com/Mras2an/cocktail-machine
6.0.2) SDK-IDF
I chose SDK-IDF on 2.1 branch instead of Arduino SDK because I already know the Arduino
SDK. The SDK-IDF has a lot of contributors and I was able to propose three patches for the
SDK-IDF. My pull requests was integrated in cind days, so the project maintainers are
responsive.
22
So we have a partitioned memory as follows:
| Addr | Binaries
-------------------------------------
| 0x001000 | Bootloader.bin
| 0x008000 | Partitions.bin
| 0x010000 | Factory.bin
| 0x110000 | OTA_0.bin
| 0x210000 | OTA_1.bin
| 0x315000 | NVS (500Ko)
| 0x3F0000 | Free
23
6.2) The architecture
The software is architectured as follows:
24
6.3) The features of the software
The Esp32_init function is used to configure an ip static on the wroom32. If your network is
not 192.168.1.x with a mask in 255.255.255.0 you must modify the code below.
tcpip_adapter_init();
ESP_ERROR_CHECK(tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA));
tcpip_adapter_ip_info_t info = { 0,};
IP4_ADDR(&info.ip, 192, 168, 1, 51);
IP4_ADDR(&info.gw, 192, 168, 1, 1);
IP4_ADDR(&info.netmask, 255, 255, 255, 0);
ESP_ERROR_CHECK(tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_STA, &info))
25
6.3.2) smartconfig mode
Allows sending the SSID and password in wi-fi broadcast. When the system has finished
smartconfig the task Esp32SmartConfig_task saves the information in memory.
if((this->pass != NULL) && (this->ssid != NULL))
{
Wifi_saveSSIDAndPass(this->ssid, this->pass);
OsFree(this->ssid);
OsFree(this->pass);
}
If the backup file exists then the smartconfig task is not enable to boot.
void Esp32SmartConfig_init(void)
{
this->smartConfigEnable = 0;
char * ssid = (char *)Wifi_getSsid();
char * pass = (char *)Wifi_getPassword();
if(ssid != NULL)
OsFree(ssid);
if(pass != NULL)
OsFree(pass);
}
void Esp32SmartConfig_createTask()
{
if(this->smartConfigEnable)
OsTaskCreate(Esp32SmartConfig_task, "Esp32SmartConfig_task", 4096, NULL,
3, NULL);
}
You can see Esp32SmartConfig.c for more informations.
I choose the smatconfig mode instead of blufi (bluetooth wifi config connection to ap)
because there is no example of smartphone application for Ios. While there are Andoid and
Ios example apps for smartconfig mode.
26
6.3.3) Update (OTA)
Allows updating via wifi. To start the OTA functionality I used the cocktail machine web page.
When you click on the Update button, the system reboot and start the update task.
char * update = Fs_read("Update", "Update");
if (update != NULL)
{
BarDebug_info("LED GREEN\n");
LedRGBHandling_ExecuteLedTaskFromISR(GREEN_LED);
Fs_delete("Update", "Update");
OsFree(update);
Ota_InitTask();
}
I have integrate the example of "classycodeoss" for the update function. We need of 3
functions, Esp32Ota_begin, Esp32Ota_writeHexData, and Esp32Ota_end. This functions
use espressif SDK OTA functions: esp_ota_begin, esp_ota_write,
esp_ota_get_boot_partition, esp_ota_end. When the connected cocktail machine boot you
can see in the log the current partition (Factory, OTA_0, OTA_1). this address partition is
laid out in the customPart file seen above.
void Esp32Ota_init()
{
const esp_partition_t * currentBootPartition = esp_ota_get_boot_partition();
memset(this->currentPartition, '\0', PART_LEN);
memcpy(this->currentPartition, currentBootPartition->label,
strlen(currentBootPartition->label));
this->addr = currentBootPartition->address;
BarDebug_info("Part: %s, addr:%08x \n", Esp32Ota_getCurrentPartition(),
Esp32Ota_getCurrentBootAddr());
}
27
6.3.5) File system
It is an abstraction of the NVS espressif SDK functions
#define Fs_write Esp32Fs_write
esp_err_t Esp32Fs_write(const char * filename, const char * data, const char * key)
{
nvs_handle my_handle;
esp_err_t err;
err = nvs_open(filename, NVS_READWRITE, &my_handle);
if(err != ESP_OK)
{
BarDebug_err("Open: %x\n", err);
return err;
}
err = nvs_commit(my_handle);
if(err != ESP_OK)
{
BarDebug_err("Commit: %x\n", err);
nvs_close(my_handle);
return err;
}
nvs_close(my_handle);
return err;
}
Lets you read or write data to a file system. Example for the SSID and password wi-fi.
if(Fs_write(SSID_WIFI_FILE, ssid, SSID_WIFI_FILE) != ESP_OK)
{
BarDebug_err("Error to save SSID\n");
}
28
6.3.6) End-of-run detection
Allows you to initialize the system using the "MotorHandling_setInitialPosition" function. This
function is called at startup and at each cocktail request.
uint32_t bp1[1], bp2[1];
BarDebug_info("Set motor at the initial position on y...\n");
Gpio_get(DETECTION_AXE_Y, bp2);
BAR_ERROR_CHECK(Gpio_set(MOTOR_AXE_Y_DIR, BAR_LEVEL_HIGH));
int end = MOTOR_LIMIT;
while(bp2[0] && (end != 0))
{
Gpio_get(DETECTION_AXE_Y, bp2);
BAR_ERROR_CHECK(Gpio_set(MOTOR_AXE_Y_CLK, BAR_LEVEL_LOW));
CpuDelay_ms(1);
BAR_ERROR_CHECK(Gpio_set(MOTOR_AXE_Y_CLK, BAR_LEVEL_HIGH));
CpuDelay_ms(1);
end--;
}
BarDebug_info("Motor is now at the initial position on y.\n");
BarDebug_info("Set motor at the initial position on x...\n");
Gpio_get(DETECTION_AXE_X, bp1);
BAR_ERROR_CHECK(Gpio_set(MOTOR_AXE_X_DIR, BAR_LEVEL_HIGH));
while(bp1[0])
{
Gpio_get(DETECTION_AXE_X, bp1);
BAR_ERROR_CHECK(Gpio_set(MOTOR_AXE_X_CLK, BAR_LEVEL_LOW));
CpuDelay_ms(1);
BAR_ERROR_CHECK(Gpio_set(MOTOR_AXE_X_CLK, BAR_LEVEL_HIGH));
CpuDelay_ms(1);
}
typedef struct
29
{
char name[MAX_NAME_SIZE];
int measure;
} sIngredient;
sCocktail cocktail[MAX_COCKTAIL];
sBottle bottle[MAX_BOTTLE];
When the "Cocktail" task has finished retrieving the information we call "Html_init". Who will
create the HTML web page.
html_indexBegin(http_index_hml);
html_indexTitle(http_index_hml);
html_tabBegin(http_index_hml);
html_tabColumnBegin(http_index_hml, "Selection");
html_tabColumnMiddle(http_index_hml, "Ajouter");
html_tabColumnEnd(http_index_hml, "Fourni");
Cocktail_createHtmlCodeForCocktails(http_index_hml);
html_tabEnd(http_index_hml);
html_indexEnd(http_index_hml);
The "QueueCocktail_receivedTask" task is called when a user selects a cocktail on the web
page. If we ask for three cocktails then they will be put on the waiting list. The variable
"goToPosition" and "currentPosition" make it possible to calculate the future position of the
tray according to the current state.
OsQueueReceive(pCtx->xQueueCocktailEventQueue, &QueueCocktail,
OsPortTimingPeriod);
LedRGBHandling_ExecuteLedTaskFromISR(BLUE_LED_FAST_BLINKING);
30
MotorHandling_setInitialPosition();
int nbIngredients = Cocktail_getDispoIngredients(bottleList.bottle, bottleList.position,
bottleList.measure, QueueCocktail);
int goToPosition = 0;
int currentPosition = 0;
for(int i = 0; i < nbIngredients; i++)
{
if(currentPosition != bottleList.position[i])
{
goToPosition = bottleList.position[i] - currentPosition;
MotorHandling_setPositionOnX(goToPosition);
currentPosition += goToPosition;
CpuDelay_ms(500);
}
if(currentPosition != 0)
{
MotorHandling_getAMeasureOnY(bottleList.measure[i]);
}
else
{
MotorHandling_getAMeasureOnPump(bottleList.measure[i]);
}
}
MotorHandling_setInitialPosition();
LedRGBHandling_ExecuteLedTaskFromISR(BLUE_LED);
31
{
BAR_ERROR_CHECK(Gpio_set(MOTOR_AXE_X_DIR, BAR_LEVEL_HIGH));
end = (position * (-1)) * MOTOR_OFFSET;
}
if(IDEL_LED == eAsyncMsg)
{
LedRGBGpioDriver_SetColor(LED_NOT_DEFINED);
}
else if((BLUE_LED_FAST_BLINKING | enableLed) == eAsyncMsg)
{
queueReceiveDelay = BLINK_FAST;
if(!LedRGBGpioDriver_ToggleColor(LED_BLUE))
{
BarDebug_info("LED NOT DEFINED");
}
}
...
6.3.11) cJson
Allows to recover the fields of JSON thanks to the cJon library. Here is an example to
retrieve information from a bottle.
cJSON * _name = cJSON_GetObjectItem(_bottle, "name");
if(_name != NULL)
{
cJSON * _note = cJSON_GetObjectItem(_bottle, "note");
if(_note != NULL)
{
cJSON * _position = cJSON_GetObjectItem(_bottle, "position");
if(_position != NULL)
{
memcpy(bottle[i].name, _name->valuestring, strlen(_name->valuestring));
32
memcpy(bottle[i].note, _note->valuestring, strlen(_note->valuestring));
bottle[i].position = (int) _position->valuedouble;
...
33
In my example I use "Google home", but you can make the same trigger with "Alexa",
"Button widget", "location", "date & time", and more. Example with "Button widget" you can
create a favorite cocktail widget on your desk phone.
34
if(numCocktail != 255)
{
write(sock, HeadPostHttp, strlen(HeadPostHttp));
QueueCocktail_received(numCocktail);
}
else
{
write(sock, HeadPostHttpErr, strlen(HeadPostHttpErr));
}
}
...
6.3.14) Logs
I have two logs level defined by "BAR_DEBUG", info level and error level. If "BAR_DEBUG"
is defined info and error logs is enable. If "BAR_DEBUG" is not defined only error level is
available.
#ifdef BAR_DEBUG
#define BarDebug_info(msg, ...) OsPrintf("[INFO: %s, L%d] "msg, __FUNCTION__,
__LINE__, ##__VA_ARGS__)
#define BarDebug_err OsDebug_err
#else
#define BarDebug_info(msg, ...)
#define BarDebug_err OsDebug_err
#endif
6.3.15) Add-on
Nothing yet.
35
6.4) The JSON
there are two JSONs in the project. The first allows to define the location of the bottles and
the second the list is ingredient of the cocktails.
36
"ingredient": {
"name": "jus de citron",
"measure": 1
}
}, {
"ingredient": {
"name": "sucre de canne",
"measure": 1
}
}, {
"ingredient": {
"name": "eau gazeuse",
"measure": 2
}
},
{
"ingredient": {
"name": "glace pilee",
"measure": 1
}
}
]
}
}, {
....
}]
}
When displaying a cocktail on the web page you can see two columns. A column for the
ingredients available in the machine and a column for the ingredients to be added manually.
37
color: white;
text-align: center;
}
p{
font-family: verdana;
font-size: 20px;
}
body {
background-color: lightblue;
}
table
{
border-collapse: collapse;
}
td
{
border: 1px solid black;
}
.button {
width:85px;
height:85px;
background:#fafafa;
box-shadow:2px 2px 8px #aaa;
font:bold 13px Arial;
border-radius:50%;
color:#555;
}
</style>
6.5.1) HTML
In the first line of the HTML code is the title and a link to an image. This line allows, when we
add the shortcut of the web page on a smartphone to have a nice shortcut with a name and
logo.
<title>Connected bar</title><link
href="https://www.bodipure.com/wp-content
/uploads/2016/09/B-favicon.png" rel="icon"
type="image/x-icon" />
The rest of the HTML code is the three-column table. Here is an example below:
38
39
7) Mechanics
License:
Robotic Bartender (https://www.thingiverse.com/thing:2478890) by DIY_Machines is
licensed under the Creative Commons - Attribution license.
http://creativecommons.org/licenses/by/3.0/
40
8) Getting started and functioning
You have to clone the git repository: https://github.com/Mras2an/cocktail-machine
1 - the motors
you have to modify the "#define" of Motor.c to calibrate the number of steps according to the
mechanics of the cocktail machine.
2 - The JSON
You have to bring in your bottles and create your cocktail.
41
8.3) Compile and program the code
1 - In a GNU / Linux terminal do an export of the SDK-IDF (branch 2.1) and the toolchain.
$ export IDF_PATH=/YOUR_PATH/esp-idf
$ export PATH=$PATH:/YOUR_PATH/xtensa-esp32-elf/bin/
3 - Connect the card with the jumper Boot. Then use the espressif flashing software.
$ python /esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 115200 --before
default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m
--flash_size detect 0x1000 bootloader.bin 0x10000 cocktail-machine.bin 0x8000
customPart.bin
4 - Now you can use OTA functionality to update your system (you have to be connected to
your home wi-fi). For that go to the web page (http://mybar.local/ or http://192.168.1.51) and
click on the button "Update" at the end of the page (the LED is green). Go to utils file and
execute the command follow:
$ python update_firmware.py 192.168.1.51 cocktail-machine.bin
2 - When you start the system for the first time, connect the system to your Wi-Fi box. To do
this download the application "ESP8266 SmartConfig" on your phone's awning. Connect
your phone to your wifi, and launch the espressif application. You just have to enter your wifi
password and click on "confirm". The module will save in flash your SSID and password.
Once saved the smartconfig mode will be disabled at startup.
42
3 - Go to http://mybar.local/ or http://192.168.1.51 and choose your cocktail.
4 - Enjoy :-)
43
8.4) Movies
You can watch videos on my youtube channel:
https://www.youtube.com/watch?v=C-QNyAYlRnY
https://www.youtube.com/watch?v=Tx3ExhTUp6A&t
https://www.youtube.com/watch?v=QJvKOMsrSR0
44
9) The future of the project
The version presented is the version 1. Many things remain to be modified and added
9.1) Modify
- Be careful, on my board (PCB) I switch the 5v in 12v on the ULN2803 but you can use the
5 volts if you want.
9.2) Add
- Detection of the glass.
45
10) Pictures
46
47