Introduction
Test de i2c
Clase ina3221 en voltmètre
Classe ina3221 complete
#
from machine import SoftI2C,Pin
from micropython import const
import time
from time import sleep
# Définir les broches SCL et SDA pour le bus I2C
scl = Pin(22)
sda = Pin(21)
# Créer un objet I2C
i2c = SoftI2C(scl=scl, sda=sda, freq=400000)
"""
# Scanner le bus I2C et afficher les adresses trouvées
adresses_trouvees = i2c.scan()
print("Adresses I2C trouvées :")
for adresse in adresses_trouvees:
print(f" - Adresse décimale : {adresse}")
print(f" - Adresse hexadécimale : {hex(adresse)}")
#
"""
# Adresse I2C du INA3221
INA3221_ADDR = 0x40
# Registres
CONFIG_REG = 0x00
BUS_VOLTAGE_CH = (None, const(0x02), const(0x04), const(0x06))
BUS_ADC_LSB = 0.008 # VBus ADC LSB is 8mV
class INA3221:
def __init__(self,
scl=22,
sda=21,
CHen="111"):
# Définir les broches SCL et SDA pour le bus I2C
pscl = Pin(scl)
psda = Pin(sda)
self.i2c = SoftI2C(scl=pscl, sda=psda, freq=400000)
self.config(CHen[0],CHen[1],CHen[2])
def scan(self):
# Scanner le bus I2C et afficher les adresses trouvées
adresses_trouvees = self.i2c.scan()
print("Adresses I2C trouvées :")
for adresse in adresses_trouvees:
print(f" - Adresse décimale : {adresse}")
print(f" - Adresse hexadécimale : {hex(adresse)}")
def config(self,cH1en=1,cH2en=1,cH3en=1,):
RST = "0" #15
CH1en = str(cH1en) #14
CH2en = str(cH2en) #13
CH3en = str(cH3en) #12
AVG = "000" #11-9 Average
VBUSCT= "001" #8-6 Conv. Time
VSHCT = "000" #5-3 Conv. Time
MODE = "110" #2-0
config_value = RST+CH1en+CH2en+CH3en+AVG+VBUSCT+VSHCT+MODE
#print(config_value)
config_value = self.bin_to_int(config_value)
self.i2c.writeto_mem(INA3221_ADDR, CONFIG_REG, config_value.to_bytes(2, 'big'))
def read_config(self):
reg = self.i2c.readfrom_mem(INA3221_ADDR,CONFIG_REG , 2)
reg = int.from_bytes(reg, 'big')
reg = hex(reg)
print("conf: ",reg)
def bin_to_int(self,strbin):
sum = 0
puis = len(strbin)-1
for i,c in enumerate(strbin):
#print(i,c)
sum+= 2**(puis-i)*int(c)
#a=hex(sum)
#print(a)
return sum
def voltmeter(self, channel=1):
"""Returns the channel's bus voltage in Volts"""
assert 1 <= channel <= 3, "channel argument must be 1, 2, or 3"
value_reg = self.i2c.readfrom_mem(INA3221_ADDR, BUS_VOLTAGE_CH[channel] , 2)
bus_voltage = int.from_bytes(value_reg, 'big') >> 3 # Conversion en 13 bits
#print(bus_voltage)
# convert to volts - LSB = 8mV
return bus_voltage * BUS_ADC_LSB
ina = INA3221(CHen="101")
#ina.scan()
#ina.read_config()
while True:
v1 = ina.voltmeter(3)
print(v1)
sleep(1)
break
# imports
from micropython import const
__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/neaxi/MicroPython_INA3221"
# pylint: disable=bad-whitespace
_DEFAULT_ADDRESS = const(0x40)
#
# Registers and bits definitions
#
# Config register
C_REG_CONFIG = const(0x00)
C_RESET = const(0x8000)
C_ENABLE_CH = (None,const(0x4000),const(0x2000),const(0x1000)) # default set
C_AVERAGING_MASK = const(0x0E00)
C_AVERAGING_NONE = const(0x0000) # 1 sample, default
C_AVERAGING_4_SAMPLES = const(0x0200)
C_AVERAGING_16_SAMPLES = const(0x0400)
C_AVERAGING_64_SAMPLES = const(0x0600)
C_AVERAGING_128_SAMPLES = const(0x0800)
C_AVERAGING_256_SAMPLES = const(0x0A00)
C_AVERAGING_512_SAMPLES = const(0x0C00)
C_AVERAGING_1024_SAMPLES = const(0x0E00)
C_VBUS_CONV_TIME_MASK = const(0x01C0)
C_VBUS_CONV_TIME_140US = const(0x0000)
C_VBUS_CONV_TIME_204US = const(0x0040)
C_VBUS_CONV_TIME_332US = const(0x0080)
C_VBUS_CONV_TIME_588US = const(0x00C0)
C_VBUS_CONV_TIME_1MS = const(0x0100) # 1.1ms, default
C_VBUS_CONV_TIME_2MS = const(0x0140) # 2.116ms
C_VBUS_CONV_TIME_4MS = const(0x0180) # 4.156ms
C_VBUS_CONV_TIME_8MS = const(0x01C0) # 8.244ms
C_SHUNT_CONV_TIME_MASK = const(0x0038)
C_SHUNT_CONV_TIME_140US = const(0x0000)
C_SHUNT_CONV_TIME_204US = const(0x0008)
C_SHUNT_CONV_TIME_332US = const(0x0010)
C_SHUNT_CONV_TIME_588US = const(0x0018)
C_SHUNT_CONV_TIME_1MS = const(0x0020) # 1.1ms, default
C_SHUNT_CONV_TIME_2MS = const(0x0028) # 2.116ms
C_SHUNT_CONV_TIME_4MS = const(0x0030) # 4.156ms
C_SHUNT_CONV_TIME_8MS = const(0x0038) # 8.244ms
C_MODE_MASK = const(0x0007)
C_MODE_POWER_DOWN = const(0x0000) # Power-down
C_MODE_SHUNT_VOLTAGE_TRIGGERED = const(0x0001) # Shunt voltage, single-shot (triggered)
C_MODE_BUS_VOLTAGE_TRIGGERED = const(0x0002) # Bus voltage, single-shot (triggered)
C_MODE_SHUNT_AND_BUS_TRIGGERED = const(0x0003) # Shunt and bus, single-shot (triggered)
C_MODE_POWER_DOWN2 = const(0x0004) # Power-down
C_MODE_SHUNT_VOLTAGE_CONTINUOUS = const(0x0005) # Shunt voltage, continous
C_MODE_BUS_VOLTAGE_CONTINUOUS = const(0x0006) # Bus voltage, continuous
C_MODE_SHUNT_AND_BUS_CONTINOUS = const(0x0007) # Shunt and bus, continuous (default)
# Other registers
C_REG_SHUNT_VOLTAGE_CH = (None, const(0x01), const(0x03), const(0x05))
C_REG_BUS_VOLTAGE_CH = (None, const(0x02), const(0x04), const(0x06))
C_REG_CRITICAL_ALERT_LIMIT_CH = (None, const(0x07), const(0x09), const(0x0B))
C_REG_WARNING_ALERT_LIMIT_CH = (None, const(0x08), const(0x0A), const(0x0C))
C_REG_SHUNT_VOLTAGE_SUM = const(0x0D)
C_REG_SHUNT_VOLTAGE_SUM_LIMIT = const(0x0E)
# Mask/enable register
C_REG_MASK_ENABLE = const(0x0F)
C_SUM_CONTROL_CH = (None,const(0x4000),const(0x2000),const(0x1000)) # def. not set
C_WARNING_LATCH_ENABLE = const(0x0800) # default not set
C_CRITICAL_LATCH_ENABLE = const(0x0400) # default not set
C_CRITICAL_FLAG_CH = (None,const(0x0200),const(0x0100),const(0x0080))
C_SUM_ALERT_FLAG = const(0x0040)
C_WARNING_FLAG_CH = (None,const(0x0020),const(0x0010),const(0x0008))
C_POWER_ALERT_FLAG = const(0x0004)
C_TIMING_ALERT_FLAG = const(0x0002)
C_CONV_READY_FLAG = const(0x0001)
# Other registers
C_REG_POWER_VALID_UPPER_LIMIT = const(0x10)
C_REG_POWER_VALID_LOWER_LIMIT = const(0x11)
C_REG_MANUFACTURER_ID = const(0xFE)
C_REG_DIE_ID = const(0xFF)
# Constants for manufacturer and device ID
C_MANUFACTURER_ID = const(0x5449) # "TI"
C_DIE_ID = const(0x3220)
# General constants
C_BUS_ADC_LSB = 0.008 # VBus ADC LSB is 8mV
C_SHUNT_ADC_LSB = 0.00004 # VShunt ADC LSB is 40µV
class INA3221:
"""Driver class for Texas Instruments INA3221 3 channel current sensor device"""
IS_FULL_API = True
@staticmethod
def _to_signed(val):
if val > 32767:
return val - 65536
return val
@staticmethod
def _to_unsigned(val):
if val < 0:
return val + 65536
return val
def write(self, reg, value):
"""Write value in device register"""
seq = bytearray([reg, (value >> 8) & 0xFF, value & 0xFF])
print(reg,value,seq)
self.i2c_device.write(seq)
def read(self, reg):
"""Return value from device register"""
buf = bytearray(3)
buf[0] = reg
self.write_then_readinto(buf, buf, out_end=1, in_start=1)
value = (buf[1] << 8) | (buf[2])
return value
def update(self, reg, mask, value):
"""Read-modify-write value in register"""
regvalue = self.read(reg)
regvalue &= ~mask
value &= mask
self.write(reg, regvalue | value)
def writeto_then_readfrom(
self,
address,
buffer_out,
buffer_in,
*,
out_start=0,
out_end=None,
in_start=0,
in_end=None,
stop=False
):
"""Write data from buffer_out to an address and then
read data from an address and into buffer_in
"""
if out_end:
self.i2c_device.writeto(address, buffer_out[out_start:out_end], stop)
else:
self.i2c_device.writeto(address, buffer_out[out_start:], stop)
if not in_end:
in_end = len(buffer_in)
read_buffer = memoryview(buffer_in)[in_start:in_end]
self.i2c_device.readfrom_into(address, read_buffer, stop)
def write_then_readinto(
self,
out_buffer,
in_buffer,
*,
out_start=0,
out_end=None,
in_start=0,
in_end=None
):
"""
Write the bytes from ``out_buffer`` to the device, then immediately
reads into ``in_buffer`` from the device. The number of bytes read
will be the length of ``in_buffer``.
If ``out_start`` or ``out_end`` is provided, then the output buffer
will be sliced as if ``out_buffer[out_start:out_end]``. This will
not cause an allocation like ``buffer[out_start:out_end]`` will so
it saves memory.
If ``in_start`` or ``in_end`` is provided, then the input buffer
will be sliced as if ``in_buffer[in_start:in_end]``. This will not
cause an allocation like ``in_buffer[in_start:in_end]`` will so
it saves memory.
:param bytearray out_buffer: buffer containing the bytes to write
:param bytearray in_buffer: buffer containing the bytes to read into
:param int out_start: Index to start writing from
:param int out_end: Index to read up to but not include; if None, use ``len(out_buffer)``
:param int in_start: Index to start writing at
:param int in_end: Index to write up to but not include; if None, use ``len(in_buffer)``
"""
if out_end is None:
out_end = len(out_buffer)
if in_end is None:
in_end = len(in_buffer)
self.writeto_then_readfrom(
self.i2c_addr,
out_buffer,
in_buffer,
out_start=out_start,
out_end=out_end,
in_start=in_start,
in_end=in_end,
)
def __init__(self, i2c_instance, i2c_addr = _DEFAULT_ADDRESS, shunt_resistor = (0.1, 0.1, 0.1)):
self.i2c_device = i2c_instance
self.i2c_addr = i2c_addr
self.shunt_resistor = shunt_resistor
#self.write(C_REG_CONFIG, C_AVERAGING_NONE | \
# C_VBUS_CONV_TIME_1MS | \
# C_MODE_BUS_VOLTAGE_CONTINUOUS )
self.write(C_REG_CONFIG, C_MODE_BUS_VOLTAGE_CONTINUOUS )
def is_channel_enabled(self, channel=1):
"""Returns if a given channel is enabled or not"""
assert 1 <= channel <= 3, "channel argument must be 1, 2, or 3"
bit = C_ENABLE_CH[channel]
return self.read(C_REG_CONFIG) & bit != 0
def enable_channel(self, channel=1, enable=True):
"""Enables or disable a given channel"""
assert 1 <= channel <= 3, "channel argument must be 1, 2, or 3"
bit = C_ENABLE_CH[channel]
value = 0
if enable:
value = bit
self.update(C_REG_CONFIG, bit, value)
def shunt_voltage(self, channel=1):
"""Returns the channel's shunt voltage in Volts"""
assert 1 <= channel <= 3, "channel argument must be 1, 2, or 3"
value = self._to_signed(self.read(C_REG_SHUNT_VOLTAGE_CH[channel])) / 8.0
# convert to volts - LSB = 40uV
return value * C_SHUNT_ADC_LSB
def current(self, channel=1):
"""Return's the channel current in Amps"""
assert 1 <= channel <= 3, "channel argument must be 1, 2, or 3"
return self.shunt_voltage(channel) / self.shunt_resistor[channel-1]
def bus_voltage(self, channel=1):
"""Returns the channel's bus voltage in Volts"""
assert 1 <= channel <= 3, "channel argument must be 1, 2, or 3"
value = self._to_signed(self.read(C_REG_BUS_VOLTAGE_CH[channel])) / 8
# convert to volts - LSB = 8mV
return value * C_BUS_ADC_LSB
def shunt_critical_alert_limit(self, channel=1):
"""Returns the channel's shunt voltage critical alert limit in Volts"""
assert 1 <= channel <= 3, "channel argument must be 1, 2, or 3"
value = self._to_signed(self.read(C_REG_CRITICAL_ALERT_LIMIT_CH[channel])) / 8
# convert to volts - LSB = 40uV
return value * C_SHUNT_ADC_LSB
def set_shunt_critical_alert_limit(self, channel, voltage):
"""Sets the channel's shunt voltage critical alert limit in Volts"""
assert 1 <= channel <= 3, "channel argument must be 1, 2, or 3"
value = self._to_unsigned(round(voltage * C_SHUNT_ADC_LSB) * 8)
self.write(C_REG_CRITICAL_ALERT_LIMIT_CH[channel], value)
def shunt_warning_alert_limit(self, channel=1):
"""Returns the channel's shunt voltage warning alert limit in Volts"""
assert 1 <= channel <= 3, "channel argument must be 1, 2, or 3"
value = self._to_signed(self.read(C_REG_WARNING_ALERT_LIMIT_CH[channel])) / 8
# convert to volts - LSB = 40uV
return value * C_SHUNT_ADC_LSB
def set_shunt_warning_alert_limit(self, channel, voltage):
"""Sets the channel's shunt voltage warning alert limit in Volts"""
assert 1 <= channel <= 3, "channel argument must be 1, 2, or 3"
value = self._to_unsigned(round(voltage * C_SHUNT_ADC_LSB) * 8)
self.write(C_REG_WARNING_ALERT_LIMIT_CH[channel], value)
@property
def is_ready(self):
"""Returns the CVRF (ConVersion Ready Flag) from the mask/enable register """
regvalue = self.read(C_REG_MASK_ENABLE)
print(regvalue)
test = (regvalue & C_CONV_READY_FLAG) != 0x0
print(test)
return test
import sys
from machine import Pin, SoftI2C
#from ina3221 import *
ina = INA3221(i2c)
ina.enable_channel(3)
volt = ina.bus_voltage(3)
print(volt)
from machine import I2C, Pin
# Initialisation de l'I2C
i2c = I2C(1, scl=Pin(22), sda=Pin(21), freq=100000)
# Adresse I2C du INA3221
INA3221_ADDR = 0x40
def int_to_binary(num):
if num == 0:
return "0"
binary_string = ""
while num > 0:
remainder = num % 2
binary_string = str(remainder) + binary_string
num //= 2
return binary_string
def bin_to_int(strbin):
sum = 0
puis = len(strbin)-1
for i,c in enumerate(strbin):
#print(i,c)
sum+= 2**(puis-i)*int(c)
a=hex(sum)
print(a)
return sum
RST = "0" #15
CH1en = "1" #14
CH2en = "0" #13
CH3en = "1" #12
AVG = "000" #11-9
VBUSCT= "001" #8-6
VSHCT = "000" #5-3
MODE = "110" #2-0
config_value = RST+CH1en+CH2en+CH3en+AVG+VBUSCT+VSHCT+MODE
#print(config_value)
#config_value = bin_to_int(config_value)
# Registres
CONFIG_REG = 0x00
BUS_VOLTAGE_REG_CH1 = 0x06
"""
# Configuration du registre de configuration
#config_value = 0x5006 # Exemple de valeur de configuration
#print(config_value)
#config_value = C_RESET
#print(len(config_value))
i2c.writeto_mem(INA3221_ADDR, CONFIG_REG, config_value.to_bytes(2, 'big'))
reg = i2c.readfrom_mem(INA3221_ADDR,CONFIG_REG , 2)
#reg = int.from_bytes(reg, 'big') >> 3 # Conversion en 13 bits
reg = int.from_bytes(reg, 'big')
reg = hex(reg)
print("a",reg)
while True:
# Lecture de la tension de bus du canal 1
bus_voltage_raw = i2c.readfrom_mem(INA3221_ADDR, BUS_VOLTAGE_REG_CH1, 2)
reg = int.from_bytes(bus_voltage_raw, 'big')
print(reg)
binary = int_to_binary(reg)
print(binary)
binary = binary[:-3]
print(binary)
volt = bin_to_int(binary)
print(volt)
print(volt*0.008)
bus_voltage = int.from_bytes(bus_voltage_raw, 'big') >> 3 # Conversion en 13 bits
print(bus_voltage)
bus_voltage *= 0.008 # Conversion en volts (1 LSB = 8 mV)
print("Tension de bus du canal 1 : {:.3f} V".format(bus_voltage))
time.sleep(2)
break
"""
- Détails
- Écrit par : Richard GAUTHIER
- Clics : 220
## Module INA3221 (WCMCU 3221) : Moniteur de tension et de courant 3 canaux avec interface I2C
Le module INA3221 (WCMCU 3221) est un moniteur de tension et de courant polyvalent qui offre une interface I2C compatible SMBUS pour une communication facile avec les microcontrôleurs et autres systèmes embarqués. Il dispose de trois canaux indépendants pour mesurer simultanément la tension et le courant sur plusieurs charges ou alimentations.
**Fonctionnalités principales:**
* **Mesure précise de la tension et du courant :** Le INA3221 peut mesurer la tension sur les shunts de courant (In+ et In-) et la tension de bus (Vin-) pour chaque canal, permettant des calculs précis du courant et de la puissance consommés.
* **Large plage de mesure :** Le module peut mesurer des tensions de bus allant de 0 V à 26 V et des courants jusqu'à 3 A (limités par la résistance de shunt).
* **Interface I2C flexible :** L'interface I2C permet une communication simple et efficace avec les microcontrôleurs, offrant quatre adresses programmables (0x40, 0x41, 0x44 et 0x45) pour une configuration aisée.
* **Alertes programmables :** Le INA3221 dispose de sorties d'alertes configurables (PV, CRI, WAR et TC) pour signaler les conditions hors plage et protéger vos systèmes contre les dommages.
* **Consommation d'énergie optimisée :** Le module consomme un faible courant de 350 µA typiques, le rendant idéal pour les applications alimentées par batterie.
**Applications:**
* Surveillance de la consommation d'énergie dans les ordinateurs, les équipements de télécommunication, les chargeurs de batterie et les alimentations
* Gestion de l'alimentation des systèmes embarqués et des circuits électroniques
* Détection de pannes et protection des circuits
* Test et mesure d'équipements électroniques
**Spécifications techniques:**
* Alimentation du circuit de contrôle : 2,7 V à 5,5 V
* Alimentation de la charge : 0 V à 26 V
* Type de sortie : Numérique
* Interface de communication : I2C, compatible SMBUS
* Adresses programmables : 4 (via des cavaliers)
* Résistance de shunt : 0,1 Ω 1% 1 W (limite le courant maximum à moins de 3 A)
**Connexions:**
* CH1 : Sortie pour charge 1
* CH2 : Sortie pour charge 2
* CH3 : Sortie pour charge 3
* GND : Masse commune des alimentations
* POW : Entrée d'alimentation pour la charge
* VPU : Tension d'alimentation pull-up pour polariser les sorties
* VS : Alimentation du circuit de contrôle (2,7 V à 5,5 V)
* SCL : Horloge I2C
* SDA : Données I2C
* PV : Sortie d'alerte de tension valide (drain ouvert)
* CRI : Sortie d'alerte critique (drain ouvert)
* WAR : Sortie d'alerte d'avertissement (drain ouvert)
* TC : Sortie d'alerte de séquence de conversion (drain ouvert)
Le module INA3221 (WCMCU 3221) offre une solution complète et économique pour la mesure précise de la tension et du courant dans une large gamme d'applications. Sa simplicité d'utilisation, sa flexibilité et sa fiabilité en font un choix idéal pour les concepteurs de systèmes embarqués et les amateurs.
- Détails
- Écrit par : Richard GAUTHIER
- Clics : 206
ESP32-DevKitC V4 Getting Started Guide
This guide shows how to start using the ESP32-DevKitC V4 development board.
What You Need
-
USB A/micro USB B cable
-
Computer running Windows, Linux, or macOS
You can skip the introduction sections and go directly to Section Start Application Development.
Overview
ESP32-DevKitC V4 is a small-sized ESP32-based development board produced by Espressif. Most of the I/O pins are broken out to the pin headers on both sides for easy interfacing. Developers can either connect peripherals with jumper wires or mount ESP32-DevKitC V4 on a breadboard.
To cover a wide range of user requirements, the following versions of ESP32-DevKitC V4 are available:
-
different ESP32 modules
-
male or female pin headers.
For details please refer to ESP Product Selector.
Functional Description
The following figure and the table below describe the key components, interfaces and controls of the ESP32-DevKitC V4 board.
Key Component |
Description |
---|---|
ESP32-WROOM-32 |
A module with ESP32 at its core. For more information, see ESP32-WROOM-32 Datasheet. |
EN |
Reset button. |
Boot |
Download button. Holding down Boot and then pressing EN initiates Firmware Download mode for downloading firmware through the serial port. |
USB-to-UART Bridge |
Single USB-UART bridge chip provides transfer rates of up to 3 Mbps. |
Micro USB Port |
USB interface. Power supply for the board as well as the communication interface between a computer and the ESP32-WROOM-32 module. |
5V Power On LED |
Turns on when the USB or an external 5V power supply is connected to the board. For details see the schematics in Related Documents. |
I/O |
Most of the pins on the ESP module are broken out to the pin headers on the board. You can program ESP32 to enable multiple functions such as PWM, ADC, DAC, I2C, I2S, SPI, etc. |
Power Supply Options
There are three mutually exclusive ways to provide power to the board:
-
Micro USB port, default power supply
-
5V and GND header pins
-
3V3 and GND header pins
Warning
The power supply must be provided using one and only one of the options above, otherwise the board and/or the power supply source can be damaged.
Header Block
The two tables below provide the Name and Function of I/O header pins on both sides of the board, as shown in ESP32-DevKitC V4 with ESP32-WROOM-32 module soldered.
No. |
Name |
Type 1 |
Function |
---|---|---|---|
1 |
3V3 |
P |
3.3 V power supply |
2 |
EN |
I |
CHIP_PU, Reset |
3 |
VP |
I |
GPIO36, ADC1_CH0, S_VP |
4 |
VN |
I |
GPIO39, ADC1_CH3, S_VN |
5 |
IO34 |
I |
GPIO34, ADC1_CH6, VDET_1 |
6 |
IO35 |
I |
GPIO35, ADC1_CH7, VDET_2 |
7 |
IO32 |
I/O |
GPIO32, ADC1_CH4, TOUCH_CH9, XTAL_32K_P |
8 |
IO33 |
I/O |
GPIO33, ADC1_CH5, TOUCH_CH8, XTAL_32K_N |
9 |
IO25 |
I/O |
GPIO25, ADC1_CH8, DAC_1 |
10 |
IO26 |
I/O |
GPIO26, ADC2_CH9, DAC_2 |
11 |
IO27 |
I/O |
GPIO27, ADC2_CH7, TOUCH_CH7 |
12 |
IO14 |
I/O |
GPIO14, ADC2_CH6, TOUCH_CH6, MTMS |
13 |
IO12 |
I/O |
GPIO12, ADC2_CH5, TOUCH_CH5, MTDI |
14 |
GND |
G |
Ground |
15 |
IO13 |
I/O |
GPIO13, ADC2_CH4, TOUCH_CH4, MTCK |
16 |
D2 |
I/O |
GPIO9, D2 2 |
17 |
D3 |
I/O |
GPIO10, D3 2 |
18 |
CMD |
I/O |
GPIO11, CMD 2 |
19 |
5V |
P |
5 V power supply |
No. |
Name |
Type 1 |
Function |
---|---|---|---|
1 |
GND |
G |
Ground |
2 |
IO23 |
I/O |
GPIO23 |
3 |
IO22 |
I/O |
GPIO22 |
4 |
TX |
I/O |
GPIO1, U0TXD |
5 |
RX |
I/O |
GPIO3, U0RXD |
6 |
IO21 |
I/O |
GPIO21 |
7 |
GND |
G |
Ground |
8 |
IO19 |
I/O |
GPIO19 |
9 |
IO18 |
I/O |
GPIO18 |
10 |
IO5 |
I/O |
GPIO5 |
11 |
IO17 |
I/O |
GPIO17 3 |
12 |
IO16 |
I/O |
GPIO16 3 |
13 |
IO4 |
I/O |
GPIO4, ADC2_CH0, TOUCH_CH0 |
14 |
IO0 |
I/O |
GPIO0, ADC2_CH1, TOUCH_CH1, Boot |
15 |
IO2 |
I/O |
GPIO2, ADC2_CH2, TOUCH_CH2 |
16 |
IO15 |
I/O |
GPIO15, ADC2_CH3, TOUCH_CH3, MTDO |
17 |
D1 |
I/O |
GPIO8, D1 2 |
18 |
D0 |
I/O |
GPIO7, D0 2 |
19 |
CLK |
I/O |
GPIO6, CLK 2 |
- 1(1,2)
-
P: Power supply; I: Input; O: Output.
- 2(1,2,3,4,5,6)
-
The pins D0, D1, D2, D3, CMD and CLK are used internally for communication between ESP32 and SPI flash memory. They are grouped on both sides near the USB connector. Avoid using these pins, as it may disrupt access to the SPI flash memory/SPI RAM.
- 3(1,2)
-
The pins GPIO16 and GPIO17 are available for use only on the boards with the modules ESP32-WROOM and ESP32-SOLO-1. The boards with ESP32-WROVER modules have the pins reserved for internal use.
Pin Layout
- Détails
- Écrit par : Richard GAUTHIER
- Clics : 541
Comprendre LangChain
LangChain est bien plus qu'un simple framework ; c'est un écosystème complet composé de plusieurs éléments indissociables.
Tout d'abord, il y a les bibliothèques LangChain, disponibles en Python et en JavaScript. Ces bibliothèques sont la colonne vertébrale de LangChain, offrant des interfaces et des intégrations pour divers composants. Elles fournissent un environnement d'exécution de base pour combiner ces composants en chaînes et agents cohérents, ainsi que des implémentations prêtes à l'emploi pour une utilisation immédiate.
Ensuite, nous avons les modèles LangChain. Il s'agit d'un ensemble d'architectures de référence déployables et adaptées à un large éventail de tâches. Que vous construisiez un chatbot ou un outil d'analyse complexe, ces modèles offrent un point de départ solide.
LangServe intervient comme une bibliothèque polyvalente pour le déploiement des chaînes LangChain en tant qu'API REST. Cet outil est essentiel pour transformer vos projets LangChain en services Web accessibles et évolutifs.
Enfin, LangSmith sert de plate-forme de développement. Il est conçu pour déboguer, tester, évaluer et surveiller les chaînes construites sur n'importe quel framework LLM. L'intégration transparente avec LangChain en fait un outil indispensable pour les développeurs qui souhaitent affiner et perfectionner leurs applications.
Ensemble, ces composants vous permettent de développer, de mettre en production et de déployer des applications en toute simplicité. Avec LangChain, vous commencez par écrire vos applications à l'aide des bibliothèques, en vous référant aux modèles pour vous guider. LangSmith vous aide ensuite à inspecter, tester et surveiller vos chaînes, en garantissant que vos applications s'améliorent constamment et sont prêtes à être déployées. Enfin, avec LangServe, vous pouvez facilement transformer n'importe quelle chaîne en une API, ce qui rend le déploiement simple.
Dans les prochaines sections, nous approfondirons la configuration de LangChain et votre voyage vers la création d'applications intelligentes basées sur des modèles de langage.
Installation et configuration
Prêt à plonger dans l'univers de LangChain ? La configuration est simple, et ce guide vous guidera pas à pas.
La première étape de votre voyage LangChain consiste à l'installer. Vous pouvez le faire facilement en utilisant pip ou conda. Exécutez la commande suivante dans votre terminal :
```
pip install langchain
```
Pour ceux qui préfèrent les fonctionnalités les plus récentes et sont à l'aise avec un peu plus d'aventure, vous pouvez installer LangChain directement à partir de la source. Clonez le dépôt et naviguez vers le répertoire `langchain/libs/langchain`. Ensuite, lancez :
```
pip install -e .
```
Pour les fonctionnalités expérimentales, envisagez d'installer `langchain-experimental`. Il s'agit d'un package qui contient du code de pointe et est destiné à la recherche et à l'expérimentation. Installez-le en utilisant :
```
pip install langchain-experimental
```
L'interface de ligne de commande (CLI) de LangChain est un outil pratique pour travailler avec les modèles LangChain et les projets LangServe. Pour installer la CLI LangChain, utilisez :
```
pip install langchain-cli
```
LangServe est essentiel pour déployer vos chaînes LangChain en tant qu'API REST. Il est installé en même temps que la CLI LangChain.
LangChain nécessite souvent des intégrations avec des fournisseurs de modèles, des magasins de données, des API, etc. Dans cet exemple, nous utiliserons les API de modèles d'OpenAI. Installez le package Python OpenAI en utilisant :
```
pip install openai
```
Pour accéder à l'API, définissez votre clé API OpenAI en tant que variable d'environnement :
```
export OPENAI_API_KEY="votre_clé_api"
```
Vous pouvez également passer la clé directement dans votre environnement Python :
```python
import os
os.environ['OPENAI_API_KEY'] = 'votre_clé_api'
```
LangChain permet la création d'applications de modèles de langage via des modules. Ces modules peuvent être autonomes ou composés pour des cas d'utilisation complexes. Ces modules sont :
* **E/S de modèle** : Facilite l'interaction avec divers modèles de langage, en gérant efficacement leurs entrées et sorties.
* **Récupération** : Permet l'accès et l'interaction avec des données spécifiques à l'application, cruciales pour l'utilisation dynamique des données.
* **Agents** : Permet aux applications de sélectionner les outils appropriés en fonction de directives de haut niveau, améliorant ainsi les capacités de prise de décision.
* **Chaînes** : Offre des compositions prédéfinies et réutilisables qui servent de blocs de construction pour le développement d'applications.
* **Mémoire** : Maintient l'état de l'application sur plusieurs exécutions de chaîne, essentiel pour les interactions sensibles au contexte.
Chaque module répond à des besoins de développement spécifiques, faisant de LangChain une boîte à outils complète pour la création d'applications avancées de modèles de langage.
En plus des composants ci-dessus, nous disposons également du LangChain Expression Language (LCEL), qui est un moyen déclaratif de composer facilement des modules ensemble, et cela permet d'enchaîner des composants à l'aide d'une interface Runnable universelle.
Le LCEL ressemble à ceci :
```python
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema import BaseOutputParser
# Exemple de chaîne
chain = ChatPromptTemplate() | ChatOpenAI() | CustomOutputParser()
```
Maintenant que nous avons couvert les bases, nous allons continuer à :
* Approfondir chaque module Langchain en détail.
* Apprendre à utiliser LangChain Expression Language.
* Explorer les cas d'utilisation courants et les implémenter.
* Déployer une application de bout en bout avec LangServe.
* Découvrir LangSmith pour le débogage, les tests et la surveillance.
Commençons !
Module I : E/S de modèle
Dans LangChain, l'élément central de toute application est le modèle de langage. Ce module fournit les éléments de base essentiels pour interagir efficacement avec n'importe quel modèle de langage, garantissant une intégration et une communication fluides.
## Composants clés de l'E/S de modèle
**MLL et modèles de discussion (utilisés de manière interchangeable):**
* **MLL** : Définition : Modèles de complétion de texte brut.
* Entrée/Sortie : Prendre une chaîne de texte en entrée et renvoyer une chaîne de texte en sortie.
* **Modèles de discussion** : Définition : Modèles qui utilisent un modèle de langage comme base, mais diffèrent des formats d'entrée et de sortie.
* Entrée/Sortie : Accepter une liste de messages de discussion en entrée et renvoyer un message de discussion.
**Paramètres:** Modéliser, sélectionner dynamiquement et gérer les entrées du modèle. Permet la création d'invites flexibles et contextuelles qui guident les réponses du modèle de langage.
**Analyseurs de sortie:** Extraire et formater les informations des sorties du modèle. Utile pour convertir la sortie brute des modèles de langage en données structurées ou en formats spécifiques nécessaires à l'application.
Intégration de LangChain avec les MLL**
L'intégration de LangChain avec les grands modèles de langage (MLL) comme OpenAI, Cohere et Hugging Face est un aspect fondamental de sa fonctionnalité. LangChain lui-même n'héberge pas de MLL, mais offre une interface uniforme pour interagir avec divers MLL.
Cette section donne un aperçu de l'utilisation de l'encapsuleur OpenAI LLM dans LangChain, applicable également à d'autres types de MLL. Nous l'avons déjà installé dans la section "Démarrage". Initialisons le MLL.
python
from langchain.llms import OpenAI
llm = OpenAI()
```
# LLMs implémentent l'interface Runnable, l'élément de base du LangChain Expression Language (LCEL). Cela signifie qu'ils prennent en charge les appels `invoke`, `ainvoke`, `stream`, `astream`, `batch`, `abatch`, `astream_log`.
# Les MLL acceptent des chaînes de caractères en entrée, ou des objets qui peuvent être transformés en chaînes d'invite, y compris `List[BaseMessage]` et `PromptValue` (plus de détails plus tard).
# Voyons quelques exemples.
response = llm.invoke("Lister les sept merveilles du monde.")
print(response)
# Vous pouvez également appeler la méthode `stream` pour diffuser la réponse textuelle en continu.
for chunk in llm.stream("Où se sont tenus les Jeux olympiques de 2012 ?"):
print(chunk, end="", flush=True)
3.2. Modèles de discussion
L'intégration de LangChain avec les modèles de discussion, une variante spécialisée des modèles de langage, est essentielle pour la création d'applications de chat interactives. Bien qu'ils utilisent des modèles de langage en interne, les modèles de discussion présentent une interface distincte centrée sur les messages de chat comme entrées et sorties. Cette section fournit un aperçu détaillé de l'utilisation du modèle de discussion OpenAI dans LangChain.
python
Les modèles de discussion dans LangChain fonctionnent avec différents types de messages tels que AIMessage, HumanMessage, SystemMessage, FunctionMessage et ChatMessage (avec un paramètre de rôle arbitraire). En général, HumanMessage, AIMessage et SystemMessage sont les plus fréquemment utilisés.
Les modèles de discussion acceptent principalement des listes de `BaseMessage` en entrée. Les chaînes de caractères peuvent être converties en `HumanMessage`, et `PromptValue` est également pris en charge.
python
from langchain.schema.messages import HumanMessage, SystemMessage
messages = [
SystemMessage(content="Vous êtes Micheal Jordan."),
HumanMessage(content="À quel fabricant de chaussures êtes-vous associé ?"),
]
response = chat.invoke(messages)
print(response.content)
3.3. Prompts : Invite de commandes
Les invites de commande sont essentielles pour guider les modèles de langage vers la génération de sorties pertinentes et cohérentes. Elles peuvent aller de simples instructions à des exemples complexes à quelques coups. Dans LangChain, la gestion des invites de commande peut être un processus très rationalisé grâce à plusieurs classes et fonctions dédiées.
La classe `PromptTemplate` de LangChain est un outil polyvalent pour créer des invites de commande sous forme de chaîne de caractères. Elle utilise la syntaxe `str.format` de Python, permettant la génération dynamique d'invites de commande. Vous pouvez définir un modèle avec des espaces réservés et les remplir avec des valeurs spécifiques selon vos besoins.
```python
from langchain.prompts import PromptTemplate
# Invite de commande simple avec des espaces réservés
prompt_template = PromptTemplate.from_template(
"Raconte-moi une blague {adjective} sur {content}."
)
# Remplir les espaces réservés pour créer une invite de commande
filled_prompt = prompt_template.format(adjective="drôle", content="robots")
print(filled_prompt)
```
Pour les modèles de chat, les invites de commande sont plus structurées et impliquent des messages avec des rôles spécifiques. LangChain propose `ChatPromptTemplate` à cet effet.
```python
from langchain.prompts import ChatPromptTemplate
# Définition d'une invite de commande de chat avec différents rôles
chat_template = ChatPromptTemplate.from_messages(
[
("système", "Vous êtes un assistant AI serviable. Votre nom est {name}."),
("humain", "Bonjour, comment allez-vous ?"),
("ia", "Je vais bien, merci !"),
("humain", "{user_input}"),
]
)
# Formatage de l'invite de commande de chat
formatted_messages = chat_template.format_messages(name="Bob", user_input="Quel est votre nom ?")
for message in formatted_messages:
print(message)
```
Cette approche permet la création de chatbots interactifs et engageants avec des réponses dynamiques.
`PromptTemplate` et `ChatPromptTemplate` s'intègrent parfaitement au LangChain Expression Language (LCEL), ce qui leur permet de faire partie de workflows plus vastes et complexes. Nous en discuterons plus en détail plus tard.
Des modèles d'invite de commande personnalisés sont parfois essentiels pour des tâches nécessitant un formatage unique ou des instructions spécifiques. La création d'un modèle d'invite de commande personnalisé implique la définition de variables d'entrée et d'une méthode de formatage personnalisée. Cette flexibilité permet à LangChain de répondre à un large éventail d'exigences spécifiques aux applications. En savoir plus ici: link to LangChain documentation about custom prompt templates.
LangChain prend également en charge les invites de commande à quelques coups, permettant au modèle d'apprendre à partir d'exemples. Cette fonction est essentielle pour les tâches nécessitant une compréhension contextuelle ou des modèles spécifiques. Les modèles d'invite de commande à quelques coups peuvent être construits à partir d'un ensemble d'exemples ou en utilisant un objet `ExampleSelector`. En savoir plus ici: link to LangChain documentation about few-shot prompting.
**Analyseurs de sortie**
Les analyseurs de sortie jouent un rôle crucial dans Langchain, permettant aux utilisateurs de structurer les réponses générées par les modèles de langage. Dans cette section, nous explorerons le concept d'analyseurs de sortie et fournirons des exemples de code en utilisant `PydanticOutputParser`, `SimpleJsonOutputParser`, `CommaSeparatedListOutputParser`, `DatetimeOutputParser` et `XMLOutputParser` de LangChain.
3.4. PydanticOutputParser : Parseur de sortie Pydantic
Langchain fournit le `PydanticOutputParser` pour analyser les réponses en structures de données Pydantic. Voici un exemple pas à pas de son utilisation :
python
from typing import List
from langchain_community.llms import Ollama
from langchain.output_parsers import PydanticOutputParser
from langchain.prompts import PromptTemplate
from langchain.pydantic_v1 import BaseModel, Field, validator
# Initialize the language model
model = Ollama(model = model_name, temperature=0)
# Define your desired data structure using Pydantic
class Joke(BaseModel):
setup: str = Field(description="question to set up a joke")
punchline: str = Field(description="answer to resolve the joke")
@validator("setup")
def question_ends_with_question_mark(cls, field):
if field[-1] != "?":
raise ValueError("Badly formed question!")
return field
# Set up a PydanticOutputParser
parser = PydanticOutputParser(pydantic_object=Joke)
# Create a prompt with format instructions
prompt = PromptTemplate(
template="Answer the user query.\n{format_instructions}\n{query}\n",
input_variables=["query"],
partial_variables={"format_instructions": parser.get_format_instructions()},
)
# Define a query to prompt the language model
query = "Tell me a joke."
# Combine prompt, model, and parser to get structured output
prompt_and_model = prompt | model
output = prompt_and_model.invoke({"query": query})
# Parse the output using the parser
parsed_result = parser.invoke(output)
# The result is a structured object
print(parsed_result)
**Sortie attendue :**
... (résultat de l'impression de l'objet `parsed_result`)
3.5 SimpleJsonOutputParser en français
Le `SimpleJsonOutputParser` de Langchain est utilisé lorsque vous souhaitez analyser des sorties de type JSON. Voici un exemple :
```python
from langchain.output_parsers.json import SimpleJsonOutputParser
from langchain_community.llms import Ollama
model = Ollama(model = model_name, temperature=0)
# Create a JSON prompt
json_prompt = PromptTemplate.from_template(
"Return a JSON object with `birthdate` and `birthplace` key that answers the following question: {question}"
)
# Initialize the JSON parser
json_parser = SimpleJsonOutputParser()
# Create a chain with the prompt, model, and parser
json_chain = json_prompt | model | json_parser
# Stream through the results
result_list = list(json_chain.stream({"question": "When and where was Elon Musk born?"}))
# The result is a list of JSON-like dictionaries
print(result_list)
```
**Explications techniques:**
* Le code utilise la bibliothèque Langchain et son analyseur `SimpleJsonOutputParser` pour traiter des sorties en format JSON.
* Un modèle `json_prompt` est créé pour spécifier la structure de la sortie JSON souhaitée, incluant les clés "date_de_naissance" et "lieu_de_naissance".
* L'analyseur `json_parser` est initialisé pour traiter les sorties JSON.
* Une chaîne est construite en reliant le modèle, le modèle de langage (représenté par "model") et l'analyseur.
* La méthode `stream` est utilisée pour parcourir les résultats de la chaîne, en fournissant la question "Quand et où est né Elon Musk ?" comme entrée.
* Le résultat final est une liste de dictionnaires contenant les informations demandées, au format JSON.
3.6. CommaSeparatedListOutputParser en français
Le `CommaSeparatedListOutputParser` de Langchain est pratique pour extraire des listes séparées par des virgules des réponses des modèles de langage. Voici un exemple :
```python
from langchain.output_parsers import CommaSeparatedListOutputParser
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI (remplacer par le modèle de langage que vous utilisez)
# Initialiser l'analyseur
analyseur_liste_virgule = CommaSeparatedListOutputParser()
# Obtenir les instructions de formatage de l'analyseur
instructions_formatage = analyseur_liste_virgule.get_format_instructions()
# Créer un modèle demandant une liste
modele = PromptTemplate(
modèle="Lister cinq {sujet}.\n{instructions_formatage}",
variables_entrantes=["sujet"],
variables_partielles={"instructions_formatage": instructions_formatage}
)
# Définir une requête pour le modèle
requete = "Equipes de Premier League anglaise"
# Générer la sortie
sortie = model(modele.format(sujet=requete))
# Analyser la sortie à l'aide de l'analyseur
resultat_analyse = analyseur_liste_virgule.parse(sortie)
# Le résultat est une liste d'éléments
print(resultat_analyse)
```
**Explications techniques:**
* Le code utilise la bibliothèque Langchain et son analyseur `CommaSeparatedListOutputParser` pour extraire des listes séparées par des virgules des réponses d'un modèle de langage.
* Un modèle `modele` est créé pour formuler la requête demandant une liste au modèle, en incluant les instructions de formatage fournies par l'analyseur.
* L'analyseur `analyseur_liste_virgule` est initialisé pour traiter les sorties contenant des listes séparées par des virgules.
* Une requête "Equipes de Premier League anglaise" est définie pour être fournie au modèle.
* La méthode `model` (remplacez par le modèle de langage que vous utilisez) génère la sortie en réponse à la requête et au modèle.
* La sortie est ensuite analysée par `analyseur_liste_virgule.parse` pour extraire la liste des éléments.
* Le résultat final est une liste contenant les éléments extraits de la réponse du modèle.
3.7. DatetimeOutputParser
Le `DatetimeOutputParser` de Langchain est conçu pour analyser les informations de date et d'heure. Voici comment l'utiliser :
```python
from langchain.prompts import PromptTemplate
from langchain.output_parsers import DatetimeOutputParser
from langchain.chains import LLMChain
from langchain.llms import OpenAI (remplacer par le modèle de langage que vous utilisez)
# Initialiser le DatetimeOutputParser
analyseur_datetime = DatetimeOutputParser()
# Créer un modèle avec des instructions de formatage
modele = PromptTemplate.from_template(
modele="""
Répondez à la question de l'utilisateur :
{question}
{instructions_formatage}
""",
variables_partielles={"instructions_formatage": analyseur_datetime.get_format_instructions()},
)
# Créer une chaîne avec le modèle et le modèle de langage
chaine = LLMChain(prompt=modele, llm=OpenAI()) # Remplacer 'OpenAI' par le modèle à utiliser
# Définir une requête pour interroger le modèle
requete = "Quand Neil Armstrong a-t-il atterri sur la Lune en termes de GMT ?"
# Exécuter la chaîne
sortie = chaine.run(requete)
# Analyser la sortie à l'aide de l'analyseur datetime
resultat_analyse = analyseur_datetime.parse(sortie)
# Le résultat est un objet datetime
print(resultat_analyse)
```
**Explications techniques:**
* Le code utilise la bibliothèque Langchain et son analyseur `DatetimeOutputParser` pour extraire des informations de date et d'heure des réponses d'un modèle de langage.
* Un modèle `modele` est créé pour formuler la requête demandant une information de date et d'heure au modèle, en incluant les instructions de formatage fournies par l'analyseur.
* L'analyseur `analyseur_datetime` est initialisé pour traiter les sorties contenant des informations de date et d'heure.
* Une requête "Quand Neil Armstrong a-t-il atterri sur la Lune en termes de GMT ?" est définie pour interroger le modèle.
* La chaîne `chaine` exécute le modèle avec la requête et génère la sortie.
* La sortie est ensuite analysée par `analyseur_datetime.parse` pour extraire l'objet datetime.
* Le résultat final est un objet datetime représentant la date et l'heure extraites de la réponse du modèle.
**Conclusion**
Ces exemples illustrent comment les analyseurs de sortie de Langchain peuvent être utilisés pour structurer différents types de réponses de modèles, les rendant adaptés à différentes applications et formats. Les analyseurs de sortie sont un outil précieux pour améliorer la convivialité et l'interprétabilité des sorties de modèles de langage dans Langchain.
**Nanonets : Automatisation des tâches et workflows avec l'IA**
Nanonets propose un outil de création de workflows basé sur l'IA, conçu pour automatiser les tâches manuelles et les workflows au sein de vos équipes. Pour en savoir plus, vous pouvez consulter la documentation ou demander une démonstration.
- Détails
- Écrit par : Richard GAUTHIER
- Clics : 1925
Description :
- Détails
- Écrit par : Richard GAUTHIER
- Clics : 2629
Lire la suite : ParcourSup - Comment trouver ta formation avec ChatGPT et ton IKIGAÏ ?