La mesure du niveau de liquide dans les réservoirs de traitement pour la surveillance et/ou le contrôle est essentielle dans les industries de traitement.
Dans les usines de traitement, les réservoirs contiennent divers liquides généralement coûteux. Certains liquides sont également inflammables et corrosifs.
Par conséquent, il est très important de surveiller le niveau de liquide dans un réservoir afin qu’il ne déborde pas du réservoir.
Il existe plusieurs méthodes pour mesurer le niveau de liquides, notamment :
Il est important de choisir la bonne méthode de mesure en fonction des caractéristiques du liquide, du récipient et des conditions de mesure. Par exemple, certaines méthodes ne sont pas adaptées à certains liquides qui sont conducteurs électriques (comme l’eau) ou qui sont opaques (comme l’huile).
Dans ce projet, on va construire un système de mesure du niveau de l’eau d’une bouteille basé sur Smartphone utilisant la carte ESP32.
Notre travail proposé sera facile pour la mesure du niveau du liquide en temps réel utilisant la technologie sans fil Bluetooth.
C’est pour cela, on va créer deux programmes: une application mobile avec App Inventor pour le smartphone et un programme pour la carte ESP32.
On sait que l’eau comme toute autre liquide est conductrice du courant électrique.
La détection du niveau de l’eau remplie dans la bouteille est basée sur cette idée.
Lorsque le niveau d’eau monte, ce liquide arrive en contact avec l’extrémité du fil de connexion fixé dans la bouteille, le circuit électrique est alors fermé et un courant électrique sous très basse tension est détecté par la carte ESP32.
Lorsque le niveau d’eau diminue, le circuit électrique est ouvert. Par conséquence il n’y a plus de courant électrique.
Ensuite la carte ESP32 envoie cette information au Smartphone via Bluetooth.
Carte ESP32
ESP32 est une carte de développement électronique basée sur le microcontrôleur ESP32 de la société Espressif. Il s’agit d’un microcontrôleur à double cœur avec un processeur principal Xtensa LX6 et un processeur secondaire dedié au traitement du signal. La carte ESP32 est conçue pour être utilisée dans les applications IoT (Internet des objets) et comprend une variété de fonctionnalités pour faciliter la communication avec d’autres dispositifs et l’accès à Internet.
Voici quelques-unes des principales caractéristiques de la carte ESP32 :
Plaque d’essai
Une plaque d’essai est un type de carte de développement électronique qui permet aux développeurs de tester et de prototyper facilement des circuits électroniques. Elles sont souvent utilisées par les développeurs pour tester rapidement des idées et des conceptions avant de les intégrer à un projet plus important ou de les intégrer dans une carte de développement plus permanente.
Les plaques d’essai sont généralement basées sur un microcontrôleur, qui est un processeur facile à utiliser et à programmer qui peut être utilisé pour contrôler une variété de circuits électroniques. Les plaques d’essai incluent généralement des broches d’extension qui permettent de connecter facilement des composants électroniques tels que des capteurs, des afficheurs, des moteurs et d’autres composants.
Les fils de connexion sont des fils électriques utilisés pour connecter des composants électroniques à une carte de développement ESP32. Ils sont généralement utilisés pour connecter des capteurs, des actionneurs, des afficheurs et d’autres composants à la carte ESP32 afin de créer des circuits électroniques.
Il existe deux types de fils de connexion: les fils de connexion mâle-mâle et les fils de connexion mâle-femelle. Les fils de connexion mâle-mâle sont utilisés pour connecter des composants qui ont tous deux des broches mâles, tandis que les fils de connexion mâle-femelle sont utilisés pour connecter des composants avec une broche mâle et une broche femelle.
Les fils de connexion sont généralement fabriqués en cuivre ou en alliage de cuivre et sont revêtus d’un isolant en plastique pour protéger les fils électriques et empêcher les courts-circuits. Ils sont disponibles dans une variété de couleurs pour aider à identifier et organiser les différents fils dans un circuit.
4 résistances de 10Kohm
La résistance ohmique est une mesure de la résistance d’un matériau à la circulation de l’électricité. Elle est symbolisée par la lettre grecque omega (Ω).
La résistance ohmique est utilisée pour mesurer la résistance d’un conducteur et pour calculer la puissance dissipée dans un circuit électrique. Elle est également utilisée pour dimensionner les conducteurs et les dispositifs de protection dans les circuits électriques afin de garantir la sécurité et le bon fonctionnement des systèmes électriques.
Tout d’abord On perce 5 trous dans la bouteille. Puis on fixe un fil de connexion dans chaque trous.
On branche les 4 resistances à la broche GND de la carte ESP32.
Ensuite on connecte:
Voici les programmes micropython qui permettent de détecter le niveau d’eau remplie dans la bouteille et envoyer cette information au Smartphone via Bluetooth.
esp32-water-level.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
from esp_ble_uart import * import time from machine import Pin, ADC from machine import freq #freq(160000000) level_1 = ADC(Pin(33)) level_1.atten(ADC.ATTN_11DB) level_2 = ADC(Pin(32)) level_2.atten(ADC.ATTN_11DB) level_3 = ADC(Pin(35)) level_3.atten(ADC.ATTN_11DB) level_4 = ADC(Pin(34)) level_4.atten(ADC.ATTN_11DB) nom = 'ESP32-ble-uart-gcworks' UUID_UART = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E' UUID_TX = '6E400003-B5A3-F393-E0A9-E50E24DCCA9E' UUID_RX = '6E400002-B5A3-F393-E0A9-E50E24DCCA9E' val_rx = "12" uart = Bleuart(nom, UUID_UART, UUID_TX, UUID_RX) uart.close() def rcp_rx(): global val_rx if uart.any(): while uart.any(): val_rx = uart.read().decode().strip() print('sur rx: ', val_rx) def env_tx(val_tx): uart.write(str(val_tx) + '\n') print("tx", val_tx) send_1=0 send_2=0 send_3=0 send_4=0 while True: #uart.irq(handler=rcp_rx) level_1_value = level_1.read() print("niveau 1",level_1_value) level_2_value = level_2.read() print("niveau 2",level_2_value) level_3_value = level_3.read() print("niveau 3",level_3_value) level_4_value = level_4.read() print("niveau 4",level_4_value) if (level_1.read()==0) and (level_2.read()==0) and (level_3.read()==0) and (level_4.read()==0): env_tx("0") # envoyer le niveau 0 d'eau au Smartphone send_1=0 if (level_1.read()!=0) and (level_2.read()==0) and (level_3.read()==0) and (level_4.read()==0) and send_1==0: env_tx("25") # envoyer le niveau 1 d'eau au Smartphone send_1=1 send_2=0 if (level_1.read()!=0) and (level_2.read()!=0) and (level_3.read()==0) and (level_4.read()==0) and send_2==0: env_tx("50") # envoyer le niveau 2 d'eau au Smartphone send_1=0 send_2=1 send_3=0 if (level_1.read()!=0) and (level_2.read()!=0) and (level_3.read()!=0) and (level_4.read()==0) and send_3==0: env_tx("75") # envoyer le niveau 3 d'eau au Smartphone send_2=0 send_3=1 send_4=0 if (level_1.read()!=0) and (level_2.read()!=0) and (level_3.read()!=0) and (level_4.read()!=0) and send_4==0: env_tx("100") # envoyer le niveau 4 d'eau au Smartphone send_3=0 send_4=1 time.sleep_ms(500) |
esp_ble_uart.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
from micropython import const import struct import bluetooth # Advertising payloads are repeated packets of the following form: # 1 byte data length (N + 1) # 1 byte type (see constants below) # N bytes type-specific data _ADV_TYPE_FLAGS = const(0x01) _ADV_TYPE_NAME = const(0x09) _ADV_TYPE_UUID16_COMPLETE = const(0x3) _ADV_TYPE_UUID32_COMPLETE = const(0x5) _ADV_TYPE_UUID128_COMPLETE = const(0x7) _ADV_TYPE_UUID16_MORE = const(0x2) _ADV_TYPE_UUID32_MORE = const(0x4) _ADV_TYPE_UUID128_MORE = const(0x6) _ADV_TYPE_APPEARANCE = const(0x19) _IRQ_CENTRAL_CONNECT = const(1 << 0) _IRQ_CENTRAL_DISCONNECT = const(1 << 1) _IRQ_GATTS_WRITE = const(1 << 2) # org.bluetooth.characteristic.gap.appearance.xml _ADV_APPEARANCE_GENERIC_COMPUTER = const(128) # Generate a payload to be passed to gap_advertise(adv_data=...). def advertising_payload(limited_disc=False, br_edr=False, name=None, services=None, appearance=0): payload = bytearray() def _append(adv_type, value): nonlocal payload payload += struct.pack('BB', len(value) + 1, adv_type) + value _append(_ADV_TYPE_FLAGS, struct.pack('B', (0x01 if limited_disc else 0x02) + (0x00 if br_edr else 0x04))) if name: _append(_ADV_TYPE_NAME, name) if services: for uuid in services: b = bytes(uuid) if len(b) == 2: _append(_ADV_TYPE_UUID16_COMPLETE, b) elif len(b) == 4: _append(_ADV_TYPE_UUID32_COMPLETE, b) elif len(b) == 16: _append(_ADV_TYPE_UUID128_COMPLETE, b) # See org.bluetooth.characteristic.gap.appearance.xml _append(_ADV_TYPE_APPEARANCE, struct.pack('<h', appearance)) return payload def decode_field(payload, adv_type): i = 0 result = [] while i + 1 < len(payload): if payload[i + 1] == adv_type: result.append(payload[i + 2:i + payload[i] + 1]) i += 1 + payload[i] return result def decode_name(payload): n = decode_field(payload, _ADV_TYPE_NAME) return str(n[0], 'utf-8') if n else '' def decode_services(payload): services = [] for u in decode_field(payload, _ADV_TYPE_UUID16_COMPLETE): services.append(bluetooth.UUID(struct.unpack('<h', u)[0])) for u in decode_field(payload, _ADV_TYPE_UUID32_COMPLETE): services.append(bluetooth.UUID(struct.unpack('<d', u)[0])) for u in decode_field(payload, _ADV_TYPE_UUID128_COMPLETE): services.append(bluetooth.UUID(u)) return services class Bleuart: def __init__(self, name, UUID_UART, UUID_TX, UUID_RX, rxbuf=100): _UART_UUID = bluetooth.UUID(UUID_UART,) _UART_TX = (bluetooth.UUID(UUID_TX), bluetooth.FLAG_NOTIFY,) _UART_RX = (bluetooth.UUID(UUID_RX), bluetooth.FLAG_WRITE,) _UART_SERVICE = (_UART_UUID, (_UART_TX, _UART_RX,),) self._ble = bluetooth.BLE() self._ble.active(True) self._ble.irq(handler=self._irq) ((self._tx_handle, self._rx_handle,),) = self._ble.gatts_register_services((_UART_SERVICE,)) # Increase the size of the rx buffer and enable append mode. self._ble.gatts_set_buffer(self._rx_handle, rxbuf, True) self._connections = set() self._rx_buffer = bytearray() self._handler = None # Optionally add services=[_UART_UUID], but this is likely to make the payload too large. self._payload = advertising_payload(name=name, appearance=_ADV_APPEARANCE_GENERIC_COMPUTER) self._advertise() def irq(self, handler): self._handler = handler def _irq(self, event, data): # Track connections so we can send notifications. if event == _IRQ_CENTRAL_CONNECT: conn_handle, _, _, = data self._connections.add(conn_handle) elif event == _IRQ_CENTRAL_DISCONNECT: conn_handle, _, _, = data if conn_handle in self._connections: self._connections.remove(conn_handle) # Start advertising again to allow a new connection. self._advertise() elif event == _IRQ_GATTS_WRITE: conn_handle, value_handle, = data if conn_handle in self._connections and value_handle == self._rx_handle: self._rx_buffer += self._ble.gatts_read(self._rx_handle) if self._handler: self._handler() def any(self): return len(self._rx_buffer) def read(self, sz=None): if not sz: sz = len(self._rx_buffer) result = self._rx_buffer[0:sz] self._rx_buffer = self._rx_buffer[sz:] return result def write(self, data): for conn_handle in self._connections: self._ble.gatts_notify(conn_handle, self._tx_handle, data) def close(self): for conn_handle in self._connections: self._ble.gap_disconnect(conn_handle) self._connections.clear() def _advertise(self, interval_us=500000): self._ble.gap_advertise(interval_us, adv_data=self._payload) |
On va créer une application mobile nommée ‘esp32_water_level’ avec App Inventor qui permet de recevoir le niveau d’eau dans la bouteille mesuré par la carte ESP32.
On vous propose donc de réaliser le design de l’application, avec le visuel suivant:
Pour programmer l’application, App Inventor nous propose d’utiliser L’espace Blocs qui permet de créer un programme sous forme de schéma bloc. Très simple d’utilisation mais nécessitant un peu de logique de programmation.
Voici le programme de l’application réalisée dans l’espace Blocs de l’App Inventor:
Ken 09-09-2222
Woah! I'm reakly enjoying tthe template/theme off this blog. It's simple, yyet effective. A lot of tijmes it's hasrd too gett that "perfect balance" between usavility aand vvisual appearance. I mmust ssay that you've dne a supperb jjob with this. In addition, thee bllg lloads exyremely quick for mme on Internet explorer. Exceptionazl Blog!