Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Micropython
#6
A few more code snippets which could come in handy for someone.

Cycle relays
Code:
from machine import SoftI2C, Pin
import uasyncio as asyncio
# Set I2C address and initialize SoftI2C
i2c = SoftI2C(scl=Pin(15), sda=Pin(4))  # Adjust the pins as needed
PCF8574_ADDRESS = 0x24
# Function to write to a pin
async def digital_write(pin, value):
    # Read current state
    current_state = i2c.readfrom(PCF8574_ADDRESS, 1)[0]
   
    # Set or clear the specific pin
    if value == 1:
        current_state |= (1 << pin)  # Set the pin
    else:
        current_state &= ~(1 << pin)  # Clear the pin
   
    # Write back the new state
    i2c.writeto(PCF8574_ADDRESS, bytes([current_state]))

# Function to initialize the PCF8574
async def init_pcf8574():
    print("Init PCF8574...")
    try:
        # Attempt to read from the device to check if it's connected
        i2c.readfrom(PCF8574_ADDRESS, 1)
        print("OK")
    except OSError:
        print("KO")

# Main loop
async def main():
    await init_pcf8574()   
    while True:
        for pin in range(6):
            await digital_write(pin, 1)  # Set pin HIGH
            await asyncio.sleep(0.2)
        for pin in range(6):
            await digital_write(pin, 0)  # Set pin LOW
            await asyncio.sleep(0.2)

# Run the main function
asyncio.run(main())

All relays off
Code:
from machine import Pin, SoftI2C
import uasyncio as asyncio  # Use uasyncio for MicroPython

# PCF8574 I2C address
PCF8574_ADDRESS = 0x24

# Initialize SoftI2C
scl_pin = Pin(15)  # Adjust according to your wiring
sda_pin = Pin(4)   # Adjust according to your wiring
i2c = SoftI2C(scl=scl_pin, sda=sda_pin, freq=100000)

# Function to write to a pin
async def digital_write(pin, value):
    # Read current state
    current_state = i2c.readfrom(PCF8574_ADDRESS, 1)[0]
   
    # Set or clear the specific pin
    if value == 1:
        current_state |= (1 << pin)  # Set the pin HIGH
    else:
        current_state &= ~(1 << pin)  # Set the pin LOW
   
    # Write back the new state
    i2c.writeto(PCF8574_ADDRESS, bytes([current_state]))

# Function to turn off all relays
async def turn_off_all_relays():
    # Set all pins to HIGH (0xFF) to turn OFF all relays
    for pin in range(8):  # Assuming PCF8574 has 8 pins
        await digital_write(pin, 1)  # Set each pin HIGH to turn off the relay
    print("All relays are turned OFF.")

async def main():
    await turn_off_all_relays()

# Run the main loop
asyncio.run(main())

All relays on
Code:
from machine import Pin, SoftI2C
import uasyncio as asyncio  # Use uasyncio for MicroPython

# PCF8574 I2C address
PCF8574_ADDRESS = 0x24

# Initialize SoftI2C
scl_pin = Pin(15)  # Adjust according to your wiring
sda_pin = Pin(4)   # Adjust according to your wiring
i2c = SoftI2C(scl=scl_pin, sda=sda_pin, freq=100000)

# Function to write to a pin
async def digital_write(pin, value):
    # Read current state
    current_state = i2c.readfrom(PCF8574_ADDRESS, 1)[0]
   
    # Set or clear the specific pin
    if value == 1:
        current_state |= (1 << pin)  # Set the pin HIGH
    else:
        current_state &= ~(1 << pin)  # Set the pin LOW
   
    # Write back the new state
    i2c.writeto(PCF8574_ADDRESS, bytes([current_state]))

# Function to turn off all relays
async def turn_off_all_relays():
    # Set all pins to LOW (0x00) to turn ON all relays
    for pin in range(6):  # Assuming PCF8574 has 6 pins
        await digital_write(pin, 0)  # Set each pin LOW to turn on the relay
    print("All relays are turned ON.")

async def main():
    await turn_off_all_relays()

# Run the main loop
asyncio.run(main())

I had to do a bit of black magic to get the onboard RTC working with Micropython, so the method to read the time and the method to set the RTC are slightly unusual. Quite a few other methods gave me the same unreliable results I was seeing with Arduino code to use clock functions on this board but this method is working for me with no hardware changes.

24 hour relay timer and working onboard RTC
Code:
from machine import Pin, SoftI2C
import uasyncio as asyncio  # Use uasyncio for MicroPython

# DS1307 I2C address
DS1307_ADDRESS = 0x68
# PCF8574 I2C address
PCF8574_ADDRESS = 0x24

def bcd_to_decimal(bcd):
    return (bcd >> 4) * 10 + (bcd & 0x0F)

async def safe_writeto_mem(i2c, address, mem_address, data):
    try:
        i2c.writeto_mem(address, mem_address, bytes(data))
    except Exception as e:
        print("Error writing to I2C:", e)

async def safe_readfrom_mem(i2c, address, mem_address, num_bytes):
    try:
        return i2c.readfrom_mem(address, mem_address, num_bytes)
    except Exception as e:
        print("Error reading from I2C:", e)
        return None

async def get_time(i2c):
    data = await safe_readfrom_mem(i2c, DS1307_ADDRESS, 0x00, 7)
    if data is not None:
        second = bcd_to_decimal(data[0] & 0x7F)
        minute = bcd_to_decimal(data[1])
        hour = bcd_to_decimal(data[2] & 0x3F)
        day = bcd_to_decimal(data[4])
        month = bcd_to_decimal(data[5])
        year = bcd_to_decimal(data[6]) + 2000
        return year, month, day, hour, minute, second
    return None, None, None, None, None, None

# Initialize SoftI2C
scl_pin = Pin(15)
sda_pin = Pin(4)
i2c = SoftI2C(scl=scl_pin, sda=sda_pin, freq=100000)

# Function to write to a pin
async def digital_write(pin, value):
    # Read current state
    current_state = await safe_readfrom_mem(i2c, PCF8574_ADDRESS, 0x00, 1)
    if current_state is not None:
        current_state = current_state[0]
       
        # Invert the logic: Set or clear the specific pin
        if value == 1:  # Turn ON the relay (set pin LOW)
            current_state &= ~(1 << pin)  # Set the pin LOW
        else:  # Turn OFF the relay (set pin HIGH)
            current_state |= (1 << pin)  # Set the pin HIGH
       
        # Write back the new state
        await safe_writeto_mem(i2c, PCF8574_ADDRESS, 0x00, [current_state])
        print(f"Relay {pin} is {'ON' if value == 1 else 'OFF'}")

async def main():
    # Turn off all relays initially
    await safe_writeto_mem(i2c, PCF8574_ADDRESS, 0x00, [0xFF])  # Set all pins HIGH (turn OFF all relays)
    print("All relays are turned OFF.")

    # Define the target time to turn on and off the relay
    target_on_hour = 16  # Set to the desired hour to turn ON
    target_on_minute = 32  # Set to the desired minute to turn ON
    target_off_hour = 16  # Set to the desired hour to turn OFF
    target_off_minute = 34  # Set to the desired minute to turn OFF

    # Loop to read time asynchronously
    while True:
        year, month, day, hour, minute, second = await get_time(i2c)
        if year is not None:
            print(f"Time: {hour:02}:{minute:02}:{second:02}, Date: {year:04}/{month:02}/{day:02}")

            # Check if the current time matches the target time to turn ON the relay
            if hour == target_on_hour and minute == target_on_minute:
                # Turn off all relays first
                await safe_writeto_mem(i2c, PCF8574_ADDRESS, 0x00, [0xFF])  # Set all pins HIGH (turn OFF all relays)
               
                # Now turn on Relay 0
                await safe_writeto_mem(i2c, PCF8574_ADDRESS, 0x00, [0xFE])  # Set pin 0 LOW (turn ON Relay 0)
                print("Relay 0 is turned ON.")

            # Check if the current time matches the target time to turn OFF the relay
            if hour == target_off_hour and minute == target_off_minute:
                # Turn off Relay 0 using safe_writeto_mem
                await safe_writeto_mem(i2c, PCF8574_ADDRESS, 0x00, [0xFF])  # Set all pins HIGH (turn OFF all relays)
                print("Relay 0 is turned OFF.")

            # Sleep for a short duration before checking the time again
            await asyncio.sleep(30)  # Check every 30 seconds

# Run the main loop
asyncio.run(main())

So set the RTC first with the get/set script (in my first post in this thread) and then adjust the on & off times in the code above. All these scripts can be saved on the 868-A6 at the same time, so upload the ones you need and run the get/set time script to set the clock.

I plan on integrating these functions into a package with a webserver interface but I don't have the time to work on it right now but if anyone else buys this board and has trouble with the RTC it could give you a few options. Just piece together the functions you need into one script.

A Micropython I2C scanner, a handy little utility that I upload to any microcontroller I'm working with along with whatever code I'm working on. SCL & SDA pins set for the 868_A6 board.

I2C scanner
Code:
# I2C Scanner MicroPython
from machine import Pin, SoftI2C

# You can choose any other combination of I2C pins
i2c = SoftI2C(scl=Pin(15), sda=Pin(4))

print('I2C SCANNER')
devices = i2c.scan()

if len(devices) == 0:
  print("No i2c device !")
else:
  print('i2c devices found:', len(devices))

  for device in devices:
    print("I2C hexadecimal address: ", hex(device))
Reply


Messages In This Thread
Micropython - by ghazidrira - 11-03-2023, 09:04 AM
RE: Micropython - by admin - 11-03-2023, 11:13 AM
RE: Micropython - by Shadowboxer - 03-15-2025, 10:45 PM
RE: Micropython - by admin - 03-15-2025, 11:20 PM
RE: Micropython - by Shadowboxer - 03-15-2025, 11:26 PM
RE: Micropython - by Shadowboxer - 03-16-2025, 05:28 AM
RE: Micropython - by admin - 03-16-2025, 08:00 AM
RE: Micropython - by Shadowboxer - 03-16-2025, 05:55 PM

Forum Jump:


Users browsing this thread: