### Install BME280 Library Source: https://easymcp2221.readthedocs.io/en/latest/_sources/smbus.rst.txt Install the necessary libraries for the BME280 weather station example. This includes the BME280 Python library and EasyMCP2221. ```console pip install pimoroni-bme280 EasyMCP2221 ``` -------------------------------- ### Setup Virtual Environment and Update Pip Source: https://easymcp2221.readthedocs.io/en/latest/_sources/install.rst.txt Commands to create and activate a Python virtual environment, and upgrade pip. This is a prerequisite for local installation and development. ```console > python -m venv init easymcp_dev > cd easymcp_dev > Scripts\activate > python -m pip install --upgrade pip ``` -------------------------------- ### Install Sphinx and RTD Theme for Documentation Source: https://easymcp2221.readthedocs.io/en/latest/install.html Install Sphinx and the Read the Docs theme using pip, required for compiling the project's documentation locally. ```bash pip install -U sphinx pip install -U sphinx_rtd_theme ``` -------------------------------- ### Basic Weather Station Example Source: https://easymcp2221.readthedocs.io/en/latest/_sources/smbus.rst.txt Read temperature, pressure, and humidity from a BME280 sensor using the SMBus class. This example assumes the sensor is connected and the necessary libraries are installed. ```python import time from EasyMCP2221 import SMBus from bme280 import BME280 bus = SMBus(1) bme280 = BME280(i2c_dev=bus) while True: temperature = bme280.get_temperature() pressure = bme280.get_pressure() humidity = bme280.get_humidity() print('{:05.2f}*C {:05.2f}hPa {:05.2f}%'.format(temperature, pressure, humidity)) time.sleep(1) ``` -------------------------------- ### Install Sphinx and RTD Theme for Local Documentation Source: https://easymcp2221.readthedocs.io/en/latest/_sources/install.rst.txt Commands to install Sphinx and the Read the Docs theme, which are required for compiling the project's documentation locally. ```console pip install -U sphinx pip install -U sphinx_rtd_theme ``` -------------------------------- ### Example 2: Real Time Clock with LCD Source: https://easymcp2221.readthedocs.io/en/latest/smbus.html This example demonstrates setting up a digital clock using a DS1307 RTC and a PCF8574-based LCD, utilizing the `SMBus` class and re-using the `bus.mcp` object for MCP2221 configuration. ```APIDOC ## Example 2: Real Time Clock with LCD ### Description This example sets up a digital clock using a DS1307 Real Time Clock and an LCD display connected via a PCF8574 I2C adapter. It showcases how to re-use the `bus.mcp` object for advanced MCP2221 configuration, including I2C speed, pin functions, and interrupt-on-change. ### Code ```python from EasyMCP2221 import SMBus from lcd_driver import LCD from DS1307 import DS1307 # Create SMBus and instances bus = SMBus() lcd = LCD(bus, addr=0x3F) ds = DS1307(bus, addr=0x68) bus.mcp.I2C_speed(100_000) # DS1307 only supports 100kHz bus.mcp.set_pin_function( gp0 = "GPIO_IN", # unused gp1 = "IOC", # trigger update LCD each second gp2 = "DAC", # simulate backup battery gp3 = "LED_I2C") # i2c traffic indicator bus.mcp.DAC_write(21) # about 3.28V with 5V Vcc bus.mcp.IOC_config(edge = "rising") # Initialization after a complete power loss if ds.halted(): ds.write_now() ds._write(0x07, 0b0001_0000) # sqwe 1Hz print("RTC initialized with current timestamp") else: print("RTC was already initialized") lcd.clear() # Update only when GP1 changes using Interrupt On Change while True: if bus.mcp.IOC_read(): bus.mcp.IOC_clear() (year, month, day, dow, hours, minutes, seconds) = ds.read_all() lcd.display_string("%02d/%02d/20%02d" % (day, month, year), 1) lcd.display_string("%02d:%02d:%02d" % (hours, minutes, seconds), 2) ``` ``` -------------------------------- ### Example 1: Basic weather station Source: https://easymcp2221.readthedocs.io/en/latest/smbus.html This example shows how to use the SMBus class with a BME280 sensor to read temperature, pressure, and humidity. It requires the `pimoroni-bme280` and `EasyMCP2221` libraries. ```APIDOC ## Example 1: Basic weather station ### Description This example demonstrates reading data from a BME280 sensor using the `SMBus` class from `EasyMCP2221`. The BME280 library is designed for systems supporting SMBus protocol. ### Installation ```bash pip install pimoroni-bme280 EasyMCP2221 ``` ### Code ```python import time from EasyMCP2221 import SMBus from bme280 import BME280 bus = SMBus(1) bme280 = BME280(i2c_dev=bus) while True: temperature = bme280.get_temperature() pressure = bme280.get_pressure() humidity = bme280.get_humidity() print('{:05.2f}*C {:05.2f}hPa {:05.2f}%'.format(temperature, pressure, humidity)) time.sleep(1) ``` ### Output Example ``` 17.93*C 933.76hPa 51.57% 17.92*C 933.76hPa 51.57% 17.91*C 933.77hPa 51.53% ``` ``` -------------------------------- ### Basic Weather Station Example Source: https://easymcp2221.readthedocs.io/en/latest/_sources/smbus.rst.txt An example demonstrating how to use the SMBus class with a BME280 sensor to read temperature, pressure, and humidity. This showcases compatibility with libraries designed for Raspberry Pi. ```APIDOC ## Basic Weather Station Example ### Description This example uses the `SMBus` class to interface with a BME280 sensor, reading environmental data. It highlights the compatibility with standard I2C Python libraries. ### Installation ```console pip install pimoroni-bme280 EasyMCP2221 ``` ### Code Example ```python import time from EasyMCP2221 import SMBus from bme280 import BME280 bus = SMBus(1) bme280 = BME280(i2c_dev=bus) while True: temperature = bme280.get_temperature() pressure = bme280.get_pressure() humidity = bme280.get_humidity() print('{:05.2f}*C {:05.2f}hPa {:05.2f}%'.format(temperature, pressure, humidity)) time.sleep(1) ``` ### Output Example ```console 17.93*C 933.76hPa 51.57% 17.92*C 933.76hPa 51.57% 17.91*C 933.77hPa 51.53% ... ``` ``` -------------------------------- ### Install EasyMCP2221 via PIP (Linux) Source: https://easymcp2221.readthedocs.io/en/latest/_sources/install.rst.txt Use this command to install the EasyMCP2221 library on Linux systems using pip. ```console $ pip install EasyMCP2221 ``` -------------------------------- ### Install EasyMCP2221 via PIP on Windows Source: https://easymcp2221.readthedocs.io/en/latest/install.html Use this command to install the EasyMCP2221 library on Windows systems using the 'py' launcher. ```bash > py -m pip install EasyMCP2221 ``` -------------------------------- ### Upgrade Pip to Resolve Installation Errors Source: https://easymcp2221.readthedocs.io/en/latest/_sources/install.rst.txt If you encounter errors like 'File "setup.py" not found' or 'neither 'setup.py' nor 'pyproject.toml' found' during editable installation, upgrade pip using this command. ```console > python -m pip install --upgrade pip ``` -------------------------------- ### Example ImportError for HIDAPI Source: https://easymcp2221.readthedocs.io/en/latest/_sources/install.rst.txt This error indicates that the HIDAPI backend libraries are not found on your system. Ensure the necessary backend packages are installed. ```console ImportError: Unable to load any of the following libraries:libhidapi-hidraw.so libhidapi-hidraw.so.0 libhidapi-libusb.so libhidapi-libusb.so.0 libhidapi-iohidmanager.so libhidapi-iohidmanager.so.0 libhidapi.dylib hidapi.dll libhidapi-0.dll ``` -------------------------------- ### Install EasyMCP2221 via PIP (Windows) Source: https://easymcp2221.readthedocs.io/en/latest/_sources/install.rst.txt Use this command to install the EasyMCP2221 library on Windows systems using the Python interpreter. ```console > py -m pip install EasyMCP2221 ``` -------------------------------- ### Real Time Clock with LCD Example Source: https://easymcp2221.readthedocs.io/en/latest/_sources/smbus.rst.txt An example demonstrating the use of the SMBus class with a DS1307 Real Time Clock and an LCD display. It also shows how to re-use the `mcp` object for configuring MCP2221 pins and I2C speed. ```APIDOC ## Real Time Clock with LCD Example ### Description This example sets up a digital clock using a DS1307 RTC and an LCD display. It demonstrates advanced usage of the `SMBus` class, including setting I2C speed, configuring MCP2221 pins, and using interrupt-on-change for updates. ### Code Example ```python from EasyMCP2221 import SMBus from lcd_driver import LCD from DS1307 import DS1307 # Create SMBus and instances bus = SMBus() lcd = LCD(bus, addr=0x3F) ds = DS1307(bus, addr=0x68) bus.mcp.I2C_speed(100_000) # DS1307 only supports 100kHz bus.mcp.set_pin_function( gp0 = "GPIO_IN", # unused gp1 = "IOC", # trigger update LCD each second gp2 = "DAC", # simulate backup battery gp3 = "LED_I2C") # i2c traffic indicator bus.mcp.DAC_write(21) # about 3.28V with 5V Vcc bus.mcp.IOC_config(edge = "rising") # Initialization after a complete power loss if ds.halted(): ds.write_now() ds._write(0x07, 0b0001_0000) # sqwe 1Hz print("RTC initialized with current timestamp") else: print("RTC was already initialized") lcd.clear() # Update only when GP1 changes using Interrupt On Change while True: if bus.mcp.IOC_read(): bus.mcp.IOC_clear() (year, month, day, dow, hours, minutes, seconds) = ds.read_all() lcd.display_string("%02d/%02d/20%02d" % (day, month, year), 1) lcd.display_string("%02d:%02d:%02d" % (hours, minutes, seconds), 2) ``` ### Further Information Full code available at: `EasyMCP2221 examples/clock `_ ``` -------------------------------- ### Clone Repository and Install in Editable Mode Source: https://easymcp2221.readthedocs.io/en/latest/_sources/install.rst.txt Clone the EasyMCP2221 GitHub repository and install it in editable mode using pip. This is useful for development and testing. ```console $ git clone https://github.com/electronicayciencia/EasyMCP2221 $ pip install -e EasyMCP2221 ``` -------------------------------- ### Install EasyMCP2221 via PIP on Linux Source: https://easymcp2221.readthedocs.io/en/latest/install.html Use this command to install the EasyMCP2221 library on Linux systems using pip. Additional troubleshooting may be required. ```bash $ pip install EasyMCP2221 ``` -------------------------------- ### Upgrade PIP to Resolve Installation Errors Source: https://easymcp2221.readthedocs.io/en/latest/install.html If you encounter errors like 'File "setup.py" not found' or 'neither 'setup.py' nor 'pyproject.toml' found', upgrade pip using this command. ```bash > python -m pip install --upgrade pip ``` -------------------------------- ### Clone Repository and Install in Editable Mode Source: https://easymcp2221.readthedocs.io/en/latest/install.html Clone the EasyMCP2221 GitHub repository and install it in editable mode using pip. Ensure you are in the correct directory. ```bash $ git clone https://github.com/electronicayciencia/EasyMCP2221 $ pip install -e EasyMCP2221 ``` -------------------------------- ### Example ImportError for Hidapi Backend Source: https://easymcp2221.readthedocs.io/en/latest/install.html This is an example of an ImportError that may occur if the hidapi backend libraries are not found. Ensure necessary backend packages are installed. ```python ImportError: Unable to load any of the following libraries:libhidapi-hidraw.so libhidapi-hidraw.so.0 libhidapi-libusb.so libhidapi-libusb.so.0 libhidapi-iohidmanager.so libhidapi-iohidmanager.so.0 libhidapi.dylib hidapi.dll libhidapi-0.dll ``` -------------------------------- ### Digital Input: Mirror GPIO States Source: https://easymcp2221.readthedocs.io/en/latest/_sources/examples.rst.txt Sets up GP2 and GP3 as digital inputs to mirror the states of GP0 and GP1, respectively. This example demonstrates reading digital input pins. ```python import EasyMCP2221 mcp = EasyMCP2221.Device() # Configure GP0 and GP1 as digital outputs mcp.set_pin_function(EasyMCP2221.GP0, EasyMCP2221.GPIO_OUT) mcp.set_pin_function(EasyMCP2221.GP1, EasyMCP2221.GPIO_OUT) # Configure GP2 and GP3 as digital inputs mcp.set_pin_function(EasyMCP2221.GP2, EasyMCP2221.GPIO_IN) mcp.set_pin_function(EasyMCP2221.GP3, EasyMCP2221.GPIO_IN) while True: # Read state of GP0 and write to GP2 mcp.GPIO_write(EasyMCP2221.GP2, mcp.GPIO_read(EasyMCP2221.GP0)) # Read state of GP1 and write to GP3 mcp.GPIO_write(EasyMCP2221.GP3, mcp.GPIO_read(EasyMCP2221.GP1)) ``` -------------------------------- ### Light Level Indicator with ADC and GPIO Source: https://easymcp2221.readthedocs.io/en/latest/examples.html This example uses ADC to read a potentiometer's value and controls LEDs based on the light level. Ensure GP0, GP1, and GP2 are configured as outputs and GP3 as an ADC input. ```python # make a light level indicator. # import EasyMCP2221 from time import sleep # Connect to device mcp = EasyMCP2221.Device() # GP0 and GP1 are inputs, GP2 and GP3 are outputs. mcp.set_pin_function( gp0 = "GPIO_OUT", gp1 = "GPIO_OUT", gp2 = "GPIO_OUT", gp3 = "ADC") mcp.ADC_config(ref="VDD") while True: pot = mcp.ADC_read()[2] # ADC channel 2 is GP3 pot_pct = pot / 1024 * 100 if pot_pct < 25: red_led_status = mcp.GPIO_read()[0] mcp.GPIO_write( gp0 = not red_led_status, gp1 = False, gp2 = False) sleep(0.1) elif 25 < pot_pct < 50: mcp.GPIO_write( gp0 = True, gp1 = False, gp2 = False) elif 50 < pot_pct < 75: mcp.GPIO_write( gp0 = True, gp1 = True, gp2 = False) elif pot_pct > 75: mcp.GPIO_write( gp0 = True, gp1 = True, gp2 = True) ``` -------------------------------- ### Console Output for ADC Basics Source: https://easymcp2221.readthedocs.io/en/latest/_sources/examples.rst.txt Example console output demonstrating the percentage values read from analog inputs (ADC0, ADC1, ADC2) as a variable resistor's value changes. ```console ADC0: 0.3% ADC1: 0.2% ADC2: 0.0% ADC0: 0.3% ADC1: 0.1% ADC2: 0.0% ADC0: 0.3% ADC1: 0.2% ADC2: 9.9% ADC0: 0.2% ADC1: 0.1% ADC2: 21.7% ADC0: 0.3% ADC1: 0.3% ADC2: 31.7% ADC0: 0.2% ADC1: 0.0% ADC2: 38.2% ADC0: 0.4% ADC1: 0.3% ADC2: 45.5% ADC0: 0.2% ADC1: 0.0% ADC2: 52.3% ADC0: 0.3% ADC1: 0.3% ADC2: 56.2% ADC0: 0.1% ADC1: 0.0% ADC2: 58.8% ADC0: 0.4% ADC1: 0.2% ADC2: 61.6% ADC0: 0.1% ADC1: 0.0% ADC2: 64.6% ADC0: 0.3% ADC1: 0.2% ADC2: 67.1% ADC0: 0.2% ADC1: 0.2% ADC2: 70.4% ADC0: 0.3% ADC1: 0.1% ADC2: 74.5% ADC0: 0.2% ADC1: 0.1% ADC2: 79.2% ADC0: 0.2% ADC1: 0.1% ADC2: 80.6% ``` -------------------------------- ### Python I2C Slave Example Output Source: https://easymcp2221.readthedocs.io/en/latest/examples.html This output shows the result of running the I2C_Slave_example.py script, indicating data was stored and then read. ```bash $ python I2C_Slave_example.py Storing... Data: [78, 78, 78, 78, 82, 102, 81, 31, 56, 77] ``` -------------------------------- ### Digital Output: LED Blinking Example Source: https://easymcp2221.readthedocs.io/en/latest/_sources/examples.rst.txt Illustrates how to control a digital output pin to blink an LED. This involves configuring a pin as output and then repeatedly writing high and low states. ```python import time import EasyMCP2221 mcp = EasyMCP2221.Device() # Configure pin GP0 as digital output mcp.set_pin_function(EasyMCP2221.GP0, EasyMCP2221.GPIO_OUT) while True: # Turn LED on mcp.GPIO_write(EasyMCP2221.GP0, 1) time.sleep(0.5) # Turn LED off mcp.GPIO_write(EasyMCP2221.GP0, 0) time.sleep(0.5) ``` -------------------------------- ### Use I2C Slave Helper Class Source: https://easymcp2221.readthedocs.io/en/latest/examples.html Demonstrates using the EasyMCP2221.I2C_Slave class for object-oriented interaction with I2C devices. This example logs 10 ADC values from a PCF8591 to an EEPROM at 1-second intervals. ```python # How to use I2C Slave helper class. # Data logger: Read 10 ADC values from a PCF8591 with 1 second interval # and store them in an EEPROM. Then, print the stored values. import EasyMCP2221 from time import sleep # Connect to MCP2221 mcp = EasyMCP2221.Device() # Create two I2C Slaves pcf = mcp.I2C_Slave(0x48) # 8 bit ADC eeprom = mcp.I2C_Slave(0x50) # serial memory # Setup analog reading (and ignore the first value) pcf.read_register(0b00000001) print("Storing...") for position in range (0, 10): v = pcf.read() eeprom.write_register(position, v, reg_bytes=2) sleep(1) ``` -------------------------------- ### Real Time Clock and LCD Setup Source: https://easymcp2221.readthedocs.io/en/latest/_sources/smbus.rst.txt Initialize SMBus, LCD, and DS1307 RTC, and configure MCP2221 pins for a clock display. Note that DS1307 has a specific I2C speed requirement. ```python from EasyMCP2221 import SMBus from lcd_driver import LCD from DS1307 import DS1307 # Create SMBus and instances bus = SMBus() lcd = LCD(bus, addr=0x3F) ds = DS1307(bus, addr=0x68) bus.mcp.I2C_speed(100_000) # DS1307 only supports 100kHz bus.mcp.set_pin_function( gp0 = "GPIO_IN", # unused gp1 = "IOC", # trigger update LCD each second gp2 = "DAC", # simulate backup battery gp3 = "LED_I2C") # i2c traffic indicator bus.mcp.DAC_write(21) # about 3.28V with 5V Vcc bus.mcp.IOC_config(edge = "rising") # Initialization after a complete power loss if ds.halted(): ds.write_now() ds._write(0x07, 0b0001_0000) # sqwe 1Hz print("RTC initialized with current timestamp") else: print("RTC was already initialized") lcd.clear() ``` -------------------------------- ### ADC Console Output Example Source: https://easymcp2221.readthedocs.io/en/latest/examples.html This is the console output when a variable resistor is moved in GP3, demonstrating the changing ADC values read from the analog input. ```text ADC0: 0.3% ADC1: 0.2% ADC2: 0.0% ADC0: 0.3% ADC1: 0.1% ADC2: 0.0% ADC0: 0.3% ADC1: 0.2% ADC2: 9.9% ADC0: 0.2% ADC1: 0.1% ADC2: 21.7% ADC0: 0.3% ADC1: 0.3% ADC2: 31.7% ADC0: 0.2% ADC1: 0.0% ADC2: 38.2% ADC0: 0.4% ADC1: 0.3% ADC2: 45.5% ADC0: 0.2% ADC1: 0.0% ADC2: 52.3% ADC0: 0.3% ADC1: 0.3% ADC2: 56.2% ADC0: 0.1% ADC1: 0.0% ADC2: 58.8% ADC0: 0.4% ADC1: 0.2% ADC2: 61.6% ADC0: 0.1% ADC1: 0.0% ADC2: 64.6% ADC0: 0.3% ADC1: 0.2% ADC2: 67.1% ADC0: 0.2% ADC1: 0.2% ADC2: 70.4% ADC0: 0.3% ADC1: 0.1% ADC2: 74.5% ADC0: 0.2% ADC1: 0.1% ADC2: 79.2% ADC0: 0.2% ADC1: 0.1% ADC2: 80.6% ``` -------------------------------- ### Interact with I2C Slave Device Source: https://easymcp2221.readthedocs.io/en/latest/_sources/examples.rst.txt Demonstrates using the I2C_Slave class for object-oriented interaction with I2C devices. This example shows storing data, which can then be retrieved. ```python from EasyMCP2221 import * mcp2221 = MCP2221() # Example data to store data_to_store = [78, 78, 78, 78, 82, 102, 81, 31, 56, 77] # Create an I2C_Slave instance and store data # Assuming the slave device is at address 0x50 slave = I2C_Slave(mcp2221, 0x50) slave.store(data_to_store) print("Storing...") # Retrieve and print the stored data retrieved_data = slave.data print("Data:") print(retrieved_data) ``` -------------------------------- ### Mixed Signal: Level Meter Example Source: https://easymcp2221.readthedocs.io/en/latest/_sources/examples.rst.txt Uses an analog input (GP3) to read a level and controls three LEDs connected to GP0, GP1, and GP2 based on the analog input's value, creating a simple level meter. ```python import time import EasyMCP2221 mcp = EasyMCP2221.Device() # Configure GP3 as analog input mcp.set_pin_function(EasyMCP2221.GP3, EasyMCP2221.ADC_IN) # Configure GP0, GP1, GP2 as digital outputs mcp.set_pin_function(EasyMCP2221.GP0, EasyMCP2221.GPIO_OUT) mcp.set_pin_function(EasyMCP2221.GP1, EasyMCP2221.GPIO_OUT) mcp.set_pin_function(EasyMCP2221.GP2, EasyMCP2221.GPIO_OUT) # Set ADC reference voltage mcp.ADC_config(EasyMCP2221.ADC_REF_3V3) while True: level = mcp.ADC_read(EasyMCP2221.GP3) # Control LEDs based on analog level if level < 0.33: mcp.GPIO_write(EasyMCP2221.GP0, 1) mcp.GPIO_write(EasyMCP2221.GP1, 0) mcp.GPIO_write(EasyMCP2221.GP2, 0) elif level < 0.66: mcp.GPIO_write(EasyMCP2221.GP0, 1) mcp.GPIO_write(EasyMCP2221.GP1, 1) mcp.GPIO_write(EasyMCP2221.GP2, 0) else: mcp.GPIO_write(EasyMCP2221.GP0, 1) mcp.GPIO_write(EasyMCP2221.GP1, 1) mcp.GPIO_write(EasyMCP2221.GP2, 1) time.sleep(0.1) ``` -------------------------------- ### DAC: LED Fading Example Source: https://easymcp2221.readthedocs.io/en/latest/_sources/examples.rst.txt Uses the DAC to fade an LED connected to GP3 or GP2 in and out using a triangular wave. This demonstrates configuring and writing to DAC pins. ```python import time import EasyMCP2221 mcp = EasyMCP2221.Device() # Configure GP3 as DAC output mcp.set_pin_function(EasyMCP2221.GP3, EasyMCP2221.DAC_OUT) # Configure DAC reference voltage mcp.DAC_config(EasyMCP2221.DAC_REF_3V3) # Fade in for i in range(32): mcp.DAC_write(EasyMCP2221.GP3, i) time.sleep(0.05) # Fade out for i in range(31, -1, -1): mcp.DAC_write(EasyMCP2221.GP3, i) time.sleep(0.05) ``` -------------------------------- ### Example OSError for Open Failed on Linux Source: https://easymcp2221.readthedocs.io/en/latest/install.html This traceback shows an OSError indicating 'open failed', which typically occurs on Linux when running without root privileges to access the device. A udev rule is required to grant permissions. ```python $ python3 pruebas.py Traceback (most recent call last): File "pruebas.py", line 7, in mcp = EasyMCP2221.Device(trace_packets = False) File "/home/pi/EasyMCP2221/EasyMCP2221/MCP2221.py", line 82, in __init__ self.hidhandler.open_path(hid.enumerate(VID, PID)[devnum]["path"]) File "hid.pyx", line 142, in hid.device.open_path OSError: open failed ``` -------------------------------- ### Sinusoidal Wave Generator with DAC Source: https://easymcp2221.readthedocs.io/en/latest/examples.html This advanced example generates a sine wave using the DAC with a period of 1 second. It utilizes a recurrence relation for efficiency and `time.perf_counter` for stable timing. Note the DAC's 5-bit resolution and potential for USB noise. ```python # DAC output, advanced example. # Generate SIN signal using a recurrence relation to avoid calculate sin(x) in the main loop. import EasyMCP2221 import time from math import sqrt, cos, pi # Output freq sample_rate = 500 # Hz (unstable above 500Hz) freq = 1 # Hz # Configure device pins and DAC reference. # MCP2221 have only 1 DAC, connected to GP2 and/or GP3. mcp = EasyMCP2221.Device() mcp.set_pin_function(gp2 = "DAC", gp3 = "DAC") mcp.DAC_config(ref="VDD") # Initial values W = cos(2*pi*freq/sample_rate) last_s = sqrt(1-W**2) # y_n-1 (y1) before_last_s = 0 # y_n-2 (y0) # No trigonometric function in the main loop while True: # set-up next sample time before doing anything else next_sample = time.perf_counter() + 1/sample_rate # Calculate next output value and write it to DAC s = 2*W*last_s - before_last_s # s between -1 and 1 out = (s + 1) / 2 # out between 0 and 1 now out = out * 31 # 5 bit DAC, 0 to 31 out = round(out) # integer mcp.DAC_write(out) # Update recurrence values (before_last_s, last_s) = (last_s, s) # Warn if we can't keep up with the sample rate! if time.perf_counter() > next_sample: print("Undersampling!") # Wait fixed delay for next sample (do not use sleep) while time.perf_counter() < next_sample: pass ``` -------------------------------- ### Example OSError for Non-Root Users (Linux) Source: https://easymcp2221.readthedocs.io/en/latest/_sources/install.rst.txt This error occurs on Linux when a non-root user attempts to open the MCP2221 device, which requires elevated privileges. A udev rule is needed to grant access. ```console $ python3 pruebas.py Traceback (most recent call last): File "pruebas.py", line 7, in mcp = EasyMCP2221.Device(trace_packets = False) File "/home/pi/EasyMCP2221/EasyMCP2221/MCP2221.py", line 82, in __init__ self.hidhandler.open_path(hid.enumerate(VID, PID)[devnum]["path"]) File "hid.pyx", line 142, in hid.device.open_path OSError: open failed ``` -------------------------------- ### Compile Local Documentation Source: https://easymcp2221.readthedocs.io/en/latest/install.html Navigate to the 'docs' directory and run 'make html' to compile the project documentation locally. The main HTML file will be in 'build/html/index.html'. ```bash cd docs make html ``` -------------------------------- ### Compile Local Documentation Source: https://easymcp2221.readthedocs.io/en/latest/_sources/install.rst.txt Navigate to the 'docs' directory and run 'make html' to compile the project documentation locally. The main HTML file will be located in the 'build/html' directory. ```console cd docs make html ``` -------------------------------- ### Create and Activate Virtual Environment Source: https://easymcp2221.readthedocs.io/en/latest/install.html Commands to create a new virtual environment named 'easymcp_dev', navigate into it, activate it, and upgrade pip. ```bash > python -m venv init easymcp_dev > cd easymcp_dev > Scripts\activate > python -m pip install --upgrade pip ``` -------------------------------- ### Initialize EasyMCP2221 Device Source: https://easymcp2221.readthedocs.io/en/latest/_sources/examples.rst.txt Demonstrates the minimum code required to import the library and create a Device object with default parameters. Ensure the MCP2221A is connected and recognized. ```python >>> import EasyMCP2221 >>> mcp = EasyMCP2221.Device() >>> print(mcp) { "Chip settings": { "Power management options": "enabled", "USB PID": "0x00DD", "USB VID": "0x04D8", "USB requested number of mA": 100 }, "Factory Serial": "01234567", "GP settings": {}, "USB Manufacturer": "Microchip Technology Inc.", "USB Product": "MCP2221 USB-I2C/UART Combo", "USB Serial": "0000000000" } ``` -------------------------------- ### Write to I2C Slave Register Source: https://easymcp2221.readthedocs.io/en/latest/i2c_slave.html Write data to a specific register on the I2C slave device. This method handles the sequence of start, device address, register address, repeated start, and data transmission. It supports specifying the register address size and byte order. ```python >>> pcf.write_register(0b01000000, 255) ``` ```python >>> eeprom = mcp.I2C_Slave(0x50, reg_bytes = 2) >>> eeprom.write_register(0x1A00, b'Testing 123...') >>> eeprom.read_register(0x1A00, 14) b'Testing 123...' ``` -------------------------------- ### Get Hardware and Firmware Revision Source: https://easymcp2221.readthedocs.io/en/latest/api_reference.html Retrieves the mayor and minor revision numbers for both the hardware and firmware of the device. ```python >>> mcp.revision() {'firmware': {'mayor': 'A', 'minor': '6'}, 'hardware': {'mayor': '1', 'minor': '2'}} ``` -------------------------------- ### Get I2C Status Source: https://easymcp2221.readthedocs.io/en/latest/api_reference.html Returns the I2C status based on the POLL_STATUS_SET_PARAMETERS command. This is a private method and its API may change. ```python >>> mcp._i2c_status() { ``` -------------------------------- ### SMBus Class Initialization Source: https://easymcp2221.readthedocs.io/en/latest/_sources/smbus.rst.txt Demonstrates how to initialize the SMBus class for use with I2C devices. It can be imported directly or from the smbus submodule. ```APIDOC ## SMBus Class Initialization ### Description Initializes the SMBus compatible class. This class allows you to use I2C Python libraries designed for Raspberry Pi with the MCP2221. ### Method Signature `SMBus()` ### Usage Examples ```python from EasyMCP2221 import SMBus bus = SMBus() ``` ```python from EasyMCP2221 import smbus bus = smbus.SMBus() ``` ### Warning To use other MCP functions in addition to SMBus, do not create a new MCP Device. Always re-use the `bus.mcp` object to avoid unpredictable behavior. ``` -------------------------------- ### Mirror GPIO State with Input/Output Source: https://easymcp2221.readthedocs.io/en/latest/examples.html Demonstrates reading from a digital input pin and writing to a digital output pin. GP3 is configured as an input, and its state will mirror the state of GP0, which is configured as an output. ```python # GPIO output and input. # GP0 is an output, but GP3 will be an input. # The state of GP3 will mirror GP0. import EasyMCP2221 from time import sleep # Connect to device mcp = EasyMCP2221.Device() # GP0 and GP1 are inputs, GP2 and GP3 are outputs. mcp.set_pin_function( gp0 = "GPIO_OUT", gp3 = "GPIO_IN") while True: inputs = mcp.GPIO_read() mcp.GPIO_write( gp0 = inputs[3]) ``` -------------------------------- ### Read 10 Values from EEPROM Source: https://easymcp2221.readthedocs.io/en/latest/examples.html Reads 10 bytes of data from the EEPROM starting at address 0x0000. Ensure the EEPROM is correctly connected and initialized. ```python v = eeprom.read_register(0x0000, 10, reg_bytes=2) print("Data: ") print(list(v)) ``` -------------------------------- ### Read SMBus Block Data Source: https://easymcp2221.readthedocs.io/en/latest/smbus.html Reads a block of up to 32 bytes from a specified register on the I2C device. Requires the I2C address and the starting register. ```python bus.read_block_data(_i2c_addr_, _register_, _force=None_) ``` -------------------------------- ### Write SMBus Block Data Source: https://easymcp2221.readthedocs.io/en/latest/smbus.html Writes a block of byte data to a given register on the I2C device. Requires the I2C address, starting register, and a list of bytes to write. ```python bus.write_block_data(_i2c_addr_, _register_, _data_, _force=None_) ``` -------------------------------- ### Device Initialization Source: https://easymcp2221.readthedocs.io/en/latest/api_reference.html Creates an instance of the MCP2221(A) device. Allows selection by VID/PID/devnum or VID/PID/usbserial. Supports serial number scanning and various timeout/retry configurations. ```APIDOC ## Device Initialization ### Description Creates a MCP2221(A) device instance. Device selection is done by VID/PID/devnum or by VID/PID/usbserial. To use Serial Number you should enable serial USB enumeration. See `enable_cdc_serial()`. This ensures the device informs its serial number to the operating system, both for the CDC and the HID interfaces. You still can select by Serial Number a device with disabled serial enumeration using `scan_serial` parameter. This will open every device and reads the flash one by one looking for the serial. However, this may interfere with any other MCP2221 working in the system. If more than one device with the same Serial is found, the first one will be selected. ### Class Signature `Device(_VID =1240_, _PID =221_, _devnum =0_, _usbserial =None_, _scan_serial =False_, _open_timeout =0_, _read_timeout =-1_, _cmd_retries =1_, _debug_messages =0_, _trace_packets =False_) ### Parameters #### Optional Parameters - **VID** (int) - Vendor Id (default is `0x04D8`) - **PID** (int) - Product Id (default is `0x00DD`) - **devnum** (int) - Device index if multiple device found with the same PID and VID. Default is first device (index 0). - **usbserial** (str) - Device’s USB serial to open. Default is not to use Serial Number (`None`). - **scan_serial** (bool) - Look for a given USB serial even if the device does not use serial USB enumeration. Default is `False`. - **open_timeout** (int) - Open timeout. Default is quit immediately. - **read_timeout** (int) - Read timeout (ms). Default is no timeout (block indefinitely). - **cmd_retries** (int) - Times to retry an USB command if it fails. - **debug_messages** (bool) - Print debugging messages. - **trace_packets** (bool) - For debug only. Print all binary commands and responses. ### Raises - **RuntimeError** - if no device found with given VID and PID, devnum index or USB serial. ### Example ```python import EasyMCP2221 mcp = EasyMCP2221.Device() print(mcp) ``` ### Response Example ```json { "Chip settings": { "Interrupt detection edge": "both", "Power management options": "enabled", "USB PID": "0x00DD", "USB VID": "0x04D8", "USB requested number of mA": 100 }, "Factory Serial": "01234567", "GP settings": {}, "USB Manufacturer": "Microchip Technology Inc.", "USB Product": "MCP2221 USB-I2C/UART Combo", "USB Serial": "0000000000" } ``` ``` -------------------------------- ### Run All Tests Source: https://easymcp2221.readthedocs.io/en/latest/_sources/install.rst.txt Execute all unit tests in the project. This command is useful for a comprehensive test run. ```console $ python -m unittest ``` -------------------------------- ### Configure ADC and Read All Channels Source: https://easymcp2221.readthedocs.io/en/latest/api_reference.html Configures all specified pins (gp1, gp2, gp3) as ADC inputs and reads their analog values. Ensure ADC reference is set, especially if using VDD. ```python >>> mcp.ADC_config(ref = "VDD") >>> mcp.set_pin_function( ... gp1 = "ADC", ... gp2 = "ADC", ... gp3 = "ADC") >>> mcp.ADC_read() (185, 136, 198) ``` -------------------------------- ### Write SMBus I2C Block Data Source: https://easymcp2221.readthedocs.io/en/latest/smbus.html Writes a block of byte data to a given register on the I2C device. Requires the I2C address, starting register, and a list of bytes to write. ```python bus.write_i2c_block_data(_i2c_addr_, _register_, _data_, _force=None_) ``` -------------------------------- ### Instantiate SMBus Class Source: https://easymcp2221.readthedocs.io/en/latest/_sources/smbus.rst.txt Import and instantiate the SMBus class from EasyMCP2221. This is the primary way to begin using SMBus compatible libraries. ```python from EasyMCP2221 import SMBus bus = SMBus() ``` ```python from EasyMCP2221 import smbus bus = smbus.SMBus() ``` -------------------------------- ### Read SMBus I2C Block Data Source: https://easymcp2221.readthedocs.io/en/latest/smbus.html Reads a block of byte data from a given register on the I2C device. Requires the I2C address, starting register, and the desired block length. ```python bus.read_i2c_block_data(_i2c_addr_, _register_, _length_, _force=None_) ``` -------------------------------- ### Create I2C Slave Instance via EasyMCP2221.Device Source: https://easymcp2221.readthedocs.io/en/latest/i2c_slave.html Instantiate an I2C_Slave object using the EasyMCP2221.Device.I2C_Slave() method. This is the recommended way to create slave instances. ```python >>> import EasyMCP2221 >>> mcp = EasyMCP2221.Device() >>> eeprom = mcp.I2C_Slave(0x50, reg_bytes = 2) >>> eeprom EasyMCP2221's I2C slave device at bus address 0x50. ``` -------------------------------- ### open Source: https://easymcp2221.readthedocs.io/en/latest/smbus.html Opens a given I2C bus. This method is for compatibility only and has no effect. ```APIDOC ## open(_bus_) ### Description (For compatibility only, no effects) Open a given i2c bus. ### Parameters * **bus** (_int_ _or_ _str_) – i2c bus number (e.g. 0 or 1) or an absolute file path (e.g. ‘/dev/i2c-42’). ### Raises * **TypeError** – if type(bus) is not in (int, str) ``` -------------------------------- ### Run All Unit Tests Source: https://easymcp2221.readthedocs.io/en/latest/install.html Execute the entire test suite for EasyMCP2221, which checks ADC, DAC, I2C, and other features. Requires a working MCP2221/MCP2221A and a serial EEPROM. ```python $ python -m unittest ``` -------------------------------- ### Read Data from EEPROM via I2C Source: https://easymcp2221.readthedocs.io/en/latest/examples.html Reads data from an EEPROM starting at the first memory position (0x0000). It reads up to 100 bytes and prints the data until the first null terminator is encountered. Requires prior writing to the EEPROM. ```python # Simple EEPROM reading. import EasyMCP2221 # Connect to MCP2221 mcp = EasyMCP2221.Device() # Configure GP3 to show I2C bus activity. mcp.set_pin_function(gp3 = "LED_I2C") MEM_ADDR = 0x50 MEM_POS = 0 # Seek EEPROM to position mcp.I2C_write( addr = MEM_ADDR, data = MEM_POS.to_bytes(2, byteorder = 'little')) # Read max 100 bytes data = mcp.I2C_read( addr = MEM_ADDR, size = 100) data = data.split(b'\0')[0] print("Phrase stored was: " + data.decode('utf-8')) ``` -------------------------------- ### Initialize MCP2221(A) Device Source: https://easymcp2221.readthedocs.io/en/latest/api_reference.html Creates an instance of the MCP2221(A) device. Device selection can be done by VID/PID/devnum or VID/PID/usbserial. Ensure serial USB enumeration is enabled if using a serial number. ```python import EasyMCP2221 mcp = EasyMCP2221.Device() print(mcp) ``` -------------------------------- ### Read Flash Information Source: https://easymcp2221.readthedocs.io/en/latest/api_reference.html Reads and returns parsed or raw flash data, including USB enumeration strings, power-up GPIO settings, and internal chip configuration. Set `human` to `True` to get human-readable variable names. ```python >>> mcp.read_flash_info() { "CHIP_SETTINGS": { "adc_ref": "VDD", "clk_duty": 50, "clk_freq": "12MHz", "dac_ref": "VDD", "dac_val": 0, "ioc": "both", "ma": 100, "pid": "0x00DD", "pwr": "disabled", "vid": "0x04D8", "cdcsnen": "enabled" }, "GP_SETTINGS": { "GP0": { "func": "GPIO_IN", "outval": 0 }, "GP1": { "func": "GPIO_IN", "outval": 0 }, "GP2": { "func": "GPIO_IN", "outval": 0 }, "GP3": { "func": "GPIO_IN", "outval": 0 } }, "USB_FACT_SERIAL": "01234567", "USB_PRODUCT": "MCP2221 USB-I2C/UART Combo", "USB_SERIAL": "0000033333", "USB_VENDOR": "Microchip Technology Inc." } ``` -------------------------------- ### Initialize SMBus Class Source: https://easymcp2221.readthedocs.io/en/latest/smbus.html Import and instantiate the SMBus class for I2C communication. Ensure to reuse the existing MCP device if other MCP functions are needed. ```python from EasyMCP2221 import SMBus bus = SMBus() ``` ```python from EasyMCP2221 import smbus bus = smbus.SMBus() ```