HX711 est un amplificateur de mesure de pont de jauge, souvent utilisé pour amplifier le signal d’un capteur de poids. ESP32 est un microcontrôleur à faible consommation d’énergie et à double cœur, doté d’une connectivité Wi-Fi et Bluetooth intégrée. Le Bluetooth est une technologie de communication sans fil couramment utilisée pour connecter des périphériques tels que des smartphones, des tablettes et des ordinateurs à d’autres périphériques.
En utilisant un ESP32, il est possible de connecter un capteur de poids équipé d’un HX711 à un appareil compatible Bluetooth, tel qu’un smartphone ou une tablette. Cela peut être utile pour surveiller le poids à distance, ou pour intégrer une balance dans un système de surveillance plus large.
Pour cela, il faut connecter l’HX711 à l’ESP32 et programmer l’ESP32 pour qu’il envoie les données de poids sur une connexion Bluetooth. La programmation de l’ESP32 peut être réalisée à l’aide de l’IDE Arduino ou d’autres outils de développement.
Il existe également des modules prêts à l’emploi qui intègrent un ESP32, un HX711 et une connexion Bluetooth, ce qui facilite l’intégration dans un projet.
Dans ce projet, on va construire une balance de pesée équipée de la carte ESP32, du module HX711 et capteur de poids pour la surveillance du poids à distance par un smartphone via bluetooth.
C’est pour cela, on va créer deux programmes: une application mobile avec App Inventor pour le smartphone et des programmes micropython pour la carte ESP32.
carte ESP32
L’ESP32 est un microcontrôleur très populaire pour les projets électroniques et l’Internet des objets. Il est fabriqué par la société Espressif et offre une grande puissance de traitement, une connectivité sans fil intégrée (Wi-Fi et Bluetooth) ainsi que de nombreuses broches d’entrée/sortie pour la connectivité avec d’autres périphériques électroniques.
module HX711
Le module HX711 est un convertisseur analogique-numérique (CAN) utilisé pour mesurer la force de traction ou de compression sur un capteur de charge. Il est souvent utilisé dans les projets de capteurs de poids ou de force, tels que les balances, les pèses-personnes et les instruments de mesure de force.
Le module HX711 est doté d’un microcontrôleur intégré et d’un amplificateur différentiel qui permet de convertir les signaux analogiques de force en données numériques. Le module peut être connecté à un microcontrôleur ou à un autre dispositif de traitement de données en utilisant une interface de communication telle que l’interface de données série (SDA) ou l’interface de données parallèle (PD).
Pour utiliser le module HX711, il est nécessaire de le connecter à un capteur de force et de lui fournir une alimentation électrique. Le module HX711 peut être configuré en utilisant des commandes de configuration simples qui lui permettent de déterminer la gamme de mesure et la sensibilité du capteur de force connecté. Une fois configuré, le module HX711 peut être utilisé pour mesurer la force en continu et envoyer les données de mesure au dispositif de traitement de données connecté.
capteur de poids
Un capteur de poids est un dispositif utilisé pour mesurer la force de gravité exercée sur un objet. Il est souvent utilisé pour mesurer le poids d’un objet, mais peut également être utilisé pour mesurer d’autres forces, comme la force de traction ou de compression.
Il existe de nombreux types de capteurs de poids différents, qui varient en fonction de la technologie utilisée pour mesurer la force. Certains capteurs de poids utilisent des technologies de pesage à réponse de force, telles que les capteurs à cellules de charge ou les capteurs à jauges de contrainte, qui mesurent la déformation d’un matériau soumis à une force. D’autres capteurs de poids utilisent des technologies de pesage à réponse de déplacement, telles que les capteurs à jauges de déplacement ou les capteurs à fils piézoélectriques, qui mesurent la déplacement d’un objet soumis à une force.
Les capteurs de poids sont souvent utilisés dans les balances, les pèses-personnes, les instruments de mesure de force et d’autres dispositifs de mesure de poids ou de force. Ils peuvent être connectés à un microcontrôleur ou à un autre dispositif de traitement de données pour fournir des données de mesure en temps réel.
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.
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.
Voici les programmes en micropython nécessaires pour connecter la carte ESP32 au smartphone et envoyer la valeur du poids mesuré par le module HX711 au smartphone.
boot.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 |
from esp_ble_uart import * import time from machine import freq #freq(160000000) from hx711 import HX711 driver = HX711(d_out=5, pd_sck=4) 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) while True: uart.irq(handler=rcp_rx) print((driver.read()-183200)/238) env_tx(round(((driver.read()-183200)/238)+15)) # le poids mesure a envoyer au Smartphone time.sleep_ms(1000) driver.power_off() |
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) |
hx711.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 141 142 143 144 145 146 |
from utime import sleep_us, time from machine import Pin from micropython import const class HX711Exception(Exception): pass class InvalidMode(HX711Exception): pass class DeviceIsNotReady(HX711Exception): pass class HX711(object): """ Micropython driver for Avia Semiconductor's HX711 24-Bit Analog-to-Digital Converter """ CHANNEL_A_128 = const(1) CHANNEL_A_64 = const(3) CHANNEL_B_32 = const(2) DATA_BITS = const(24) MAX_VALUE = const(0x7fffff) MIN_VALUE = const(0x800000) READY_TIMEOUT_SEC = const(5) SLEEP_DELAY_USEC = const(80) def __init__(self, d_out: int, pd_sck: int, channel: int = CHANNEL_A_128): self.d_out_pin = Pin(d_out, Pin.IN) self.pd_sck_pin = Pin(pd_sck, Pin.OUT, value=0) self.channel = channel def __repr__(self): return "HX711 on channel %s, gain=%s" % self.channel def _convert_from_twos_complement(self, value: int) -> int: """ Converts a given integer from the two's complement format. """ if value & (1 << (self.DATA_BITS - 1)): value -= 1 << self.DATA_BITS return value def _set_channel(self): """ Input and gain selection is controlled by the number of the input PD_SCK pulses 3 pulses for Channel A with gain 64 2 pulses for Channel B with gain 32 1 pulse for Channel A with gain 128 """ for i in range(self._channel): self.pd_sck_pin.value(1) self.pd_sck_pin.value(0) def _wait(self): """ If the HX711 is not ready within READY_TIMEOUT_SEC the DeviceIsNotReady exception will be thrown. """ t0 = time() while not self.is_ready(): if time() - t0 > self.READY_TIMEOUT_SEC: raise DeviceIsNotReady() @property def channel(self) -> tuple: """ Get current input channel in a form of a tuple (Channel, Gain) """ if self._channel == self.CHANNEL_A_128: return 'A', 128 if self._channel == self.CHANNEL_A_64: return 'A', 64 if self._channel == self.CHANNEL_B_32: return 'B', 32 @channel.setter def channel(self, value): """ Set input channel HX711.CHANNEL_A_128 - Channel A with gain 128 HX711.CHANNEL_A_64 - Channel A with gain 64 HX711.CHANNEL_B_32 - Channel B with gain 32 """ if value not in (self.CHANNEL_A_128, self.CHANNEL_A_64, self.CHANNEL_B_32): raise InvalidMode('Gain should be one of HX711.CHANNEL_A_128, HX711.CHANNEL_A_64, HX711.CHANNEL_B_32') else: self._channel = value if not self.is_ready(): self._wait() for i in range(self.DATA_BITS): self.pd_sck_pin.value(1) self.pd_sck_pin.value(0) self._set_channel() def is_ready(self) -> bool: """ When output data is not ready for retrieval, digital output pin DOUT is high. """ return self.d_out_pin.value() == 0 def power_off(self): """ When PD_SCK pin changes from low to high and stays at high for longer than 60 us , HX711 enters power down mode. """ self.pd_sck_pin.value(0) self.pd_sck_pin.value(1) sleep_us(self.SLEEP_DELAY_USEC) def power_on(self): """ When PD_SCK returns to low, HX711 will reset and enter normal operation mode. """ self.pd_sck_pin.value(0) self.channel = self._channel def read(self, raw=False): """ Read current value for current channel with current gain. if raw is True, the HX711 output will not be converted from two's complement format. """ if not self.is_ready(): self._wait() raw_data = 0 for i in range(self.DATA_BITS): self.pd_sck_pin.value(1) self.pd_sck_pin.value(0) raw_data = raw_data << 1 | self.d_out_pin.value() self._set_channel() if raw: return raw_data else: return self._convert_from_twos_complement(raw_data) |
On va créer une application mobile nommée ‘ESP32Poids’ avec App Inventor qui permet de recevoir le poids 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:
jean 13-03-2222
Bonjour, J'ai le dernier firmware micropython et cette librairie esp_ble_uart.py ne fonctionne pas avec. Avez-vous une solution ? Merci