L298n Motor Driver to control room vent

Hi,

I would like to open a room vent when temperature is above 23 degres C and close when below 15 degrees. I have the vent which is a large window in a greenhouse connected to a Linear Actuator. Can I use an L298n motor driver and change it’s direction based on a temperature input? Or is this just for Pumps that only run in one direction all the time?

Thanks
Craig

1 Like

Whether you can use it will depend on the motor. The driver can operate DC motors in either direction, but the voltage and max current must not exceed the limits of the driver.

Hi Kyle,

The hardware is working ok, I have the motor working on Mycodo but in just the direction set on the L298N output page.

How would I change the motor direction based on a temperature reading input?

I was hoping to open the window with temps above 22 celcius and close below 12.

Thanks

I haven’t experimented much with direction, but you should be able to create two outputs, one for each direction, then use either output depending on the direction you want to rotate. You may also be able to rotate in the opposite direction that is set by the output by passing a negative value to the output, but I am not looking at the code and may be mistaken about that functionality.

Thanks, I didn’t think I could duplicate pin numbers but creating two outputs works a treat.

1 Like

Could you please have a look and see if I have done something silly in the conditional function it’s not working the motor controller at all.

# Example code for learning how to use a Conditional. See the manual for more information.

self.logger.info(“This INFO log entry will appear in the Daemon Log”)

self.loop_count += 1 # Counts how many times the run code has been executed

measurement = self.condition(“b34a5009”) # Replace ID with correct Conditional ID
self.logger.info(f"Measurement value is {measurement}")

if measurement is not None: # If a measurement exists
self.message += “This message appears in email alerts and notes.\n”

if measurement < 14:  # If the measurement is less than 23
    self.message += f"Measurement is too Low! Measurement is {measurement}\n"
    self.run_action("05c02534", message=self.message) # Run close vent for cold temps.
    # self.run_all_actions(message=self.message)  # Run all actions sequentially

elif measurement > 23:  # Else If the measurement is greater than 27
    self.message += f"Measurement is too High! Measurement is {measurement}\n"
    # Replace "qwer5678" with an Action ID
    self.run_action("4fde443f", message=self.message)  # Run a single specific Action

Example code to provide a return status for other controllers and widgets.

status_dict = {
‘string_status’: f"The controller has looped {self.loop_count} times at {datetime.now()}",
‘loop_count’: self.loop_count,
‘error’:
}
return status_dict

Conditions

[Condition] Measurement (Single, Last): self.condition(“b34a5009”) returns the last value found within the Max Age, otherwise returns None.
Measurement

[Input 09 CH0] AM2315/AM2320 Temperature (°C)
Max Age (Seconds)
360

Actions

Usage:: self.run_all_actions() will sequentially execute all the actions below.

[Action] Output: On/Off/Duration: Turn an On/Off Output On, Off, or On for a duration.
Usage: Executing self.run_action(“05c02534”) will actuate an output. Executing self.run_action(“05c02534”, value={“output_id”: “959019d1-c1fa-41fe-a554-7be3366a9c5b”, “channel”: 0, “state”: “on”, “duration”: 300}) will set the state of the output with the specified ID and channel. Don’t forget to change the output_id value to an actual Output ID that exists in your system. If state is on and a duration is set, the output will turn off after the duration.
Output

[Output 06 CH0] Vent Control Close: Vent CLOSE
State

On
Duration (Seconds)
40.0

[Action] Output: On/Off/Duration: Turn an On/Off Output On, Off, or On for a duration.
Usage: Executing self.run_action(“4fde443f”) will actuate an output. Executing self.run_action(“4fde443f”, value={“output_id”: “959019d1-c1fa-41fe-a554-7be3366a9c5b”, “channel”: 0, “state”: “on”, “duration”: 300}) will set the state of the output with the specified ID and channel. Don’t forget to change the output_id value to an actual Output ID that exists in your system. If state is on and a duration is set, the output will turn off after the duration.

This is from the log files. Is based on room temp which was 10 degrees celsius at the time I ran this.

2023-08-26 21:10:35,819 - DEBUG - mycodo.controllers.controller_conditional_49791357 - Run Python Code (pre-replacement):

Example code for learning how to use a Conditional. See the manual for more information.

self.logger.info(“This INFO log entry will appear in the Daemon Log”)

self.loop_count += 1 # Counts how many times the run code has been executed

measurement = self.condition(“b34a5009”) # Replace ID with correct Conditional ID
self.logger.info(f"Measurement value is {measurement}")

if measurement is not None: # If a measurement exists
self.message += “This message appears in email alerts and notes.\n”

if measurement < 14:  # If the measurement is less than 23
    self.message += f"Measurement is too Low! Measurement is {measurement}\n"
    self.run_action("05c02534", message=self.message) # Run close vent for cold temps.
    # self.run_all_actions(message=self.message)  # Run all actions sequentially

elif measurement > 23:  # Else If the measurement is greater than 27
    self.message += f"Measurement is too High! Measurement is {measurement}\n"
    # Replace "qwer5678" with an Action ID
    self.run_action("4fde443f", message=self.message)  # Run a single specific Action

2023-08-26 21:10:35,820 - DEBUG - mycodo.controllers.controller_conditional_49791357 - Run Python Code (post-replacement):
import os
import sys
sys.path.append(os.path.abspath(‘/var/mycodo-root’))
from mycodo.controllers.base_conditional import AbstractConditional
from mycodo.mycodo_client import DaemonControl
control = DaemonControl(pyro_timeout=30.0)

from datetime import datetime

class ConditionalRun(AbstractConditional):
def init(self, logger, function_id, message):
super().init(logger, function_id, message, timeout=30.0)

    self.logger = logger
    self.function_id = function_id
    self.variables = {}
    self.message = message
    self.running = True
    self.loop_count = 0

def conditional_code_run(self):
    # Example code for learning how to use a Conditional. See the manual for more information.
    self.logger.info("This INFO log entry will appear in the Daemon Log")

    self.loop_count += 1  # Counts how many times the run code has been executed

    measurement = self.condition("b34a5009")  # Replace ID with correct Conditional ID
    self.logger.info(f"Measurement value is {measurement}")

    if measurement is not None:  # If a measurement exists
        self.message += "This message appears in email alerts and notes.\n"

        if measurement < 14:  # If the measurement is less than 23
            self.message += f"Measurement is too Low! Measurement is {measurement}\n"
            self.run_action("05c02534", message=self.message) # Run close vent for cold temps.
            # self.run_all_actions(message=self.message)  # Run all actions sequentially

        elif measurement > 23:  # Else If the measurement is greater than 27
            self.message += f"Measurement is too High! Measurement is {measurement}\n"
            # Replace "qwer5678" with an Action ID
            self.run_action("4fde443f", message=self.message)  # Run a single specific Action

def function_status(self):
    # Example code to provide a return status for other controllers and widgets.
    status_dict = {
        'string_status': f"The controller has looped {self.loop_count} times at {datetime.now()}",
        'loop_count': self.loop_count,
        'error': []
    }
    return status_dict

2023-08-26 21:10:35,820 - INFO - mycodo.controllers.controller_conditional_49791357 - Activated in 58.6 ms
2023-08-26 21:10:35,821 - DEBUG - mycodo - Conditional controller with ID 49791357-8eb2-465c-ae94-c4526aa470f1 activated.
2023-08-26 21:10:36,951 - DEBUG - mycodo.influx - Write point success: b’C,channel=0,device_id=c9ea36ba-07b9-493c-94fb-fd7b6c6332a7,measure=temperature value=10\npercent,channel=1,device_id=c9ea36ba-07b9-493c-94fb-fd7b6c6332a7,measure=humidity value=89.5\nC,channel=2,device_id=c9ea36ba-07b9-493c-94fb-fd7b6c6332a7,measure=dewpoint value=8.351670389206383\nPa,channel=3,device_id=c9ea36ba-07b9-493c-94fb-fd7b6c6332a7,measure=vapor_pressure_deficit value=128.9117764288182’
2023-08-26 21:10:38,957 - DEBUG - mycodo.influx - query_flux() query: ‘from(bucket: “mycodo_db/autogen”) |> range(start: -360s) |> filter(fn: (r) => r[“_measurement”] == “C”) |> filter(fn: (r) => r[“device_id”] == “ca5c5b2c-4221-46ed-b585-2c2672c6df58”) |> filter(fn: (r) => r[“channel”] == “0”) |> filter(fn: (r) => r[“measure”] == “temperature”) |> last()’
2023-08-26 21:10:40,318 - DEBUG - mycodo.lockfile - Acquiring lock for /var/lock/atlas_mycodo_devices_atlas_scientific_i2c_1_102.lock (10 sec timeout)
2023-08-26 21:10:40,319 - DEBUG - mycodo.lockfile - Lock acquired for /var/lock/atlas_mycodo_devices_atlas_scientific_i2c_1_102.lock in 0.001 seconds
2023-08-26 21:10:41,831 - DEBUG - mycodo.lockfile - Releasing lock for /var/lock/atlas_mycodo_devices_atlas_scientific_i2c_1_102.lock
2023-08-26 21:10:41,954 - DEBUG - mycodo.influx - Write point success: b’C,channel=0,device_id=ca5c5b2c-4221-46ed-b585-2c2672c6df58,measure=temperature value=16.408’
2023-08-26 21:10:42,497 - DEBUG - mycodo.influx - query_flux() query: ‘from(bucket: “mycodo_db/autogen”) |> range(start: -360s) |> filter(fn: (r) => r[“_measurement”] == “pH”) |> filter(fn: (r) => r[“device_id”] == “318a6161-04e2-4682-8911-3af9aac928d3”) |> filter(fn: (r) => r[“channel”] == “0”) |> filter(fn: (r) => r[“measure”] == “ion_concentration”) |> last()’
2023-08-26 21:10:42,622 - DEBUG - mycodo.lockfile - Acquiring lock for /var/lock/atlas_mycodo_devices_atlas_scientific_i2c_1_80.lock (10 sec timeout)
2023-08-26 21:10:42,626 - DEBUG - mycodo.lockfile - Lock acquired for /var/lock/atlas_mycodo_devices_atlas_scientific_i2c_1_80.lock in 0.004 seconds
2023-08-26 21:10:42,775 - DEBUG - mycodo.influx - query_flux() query: ‘from(bucket: “mycodo_db/autogen”) |> range(start: -360s) |> filter(fn: (r) => r[“_measurement”] == “uS_cm”) |> filter(fn: (r) => r[“device_id”] == “14756b3c-7508-4582-bc32-4d17d4863677”) |> filter(fn: (r) => r[“channel”] == “0”) |> filter(fn: (r) => r[“measure”] == “electrical_conductivity”) |> last()’
2023-08-26 21:10:43,028 - DEBUG - mycodo.influx - query_flux() query: ‘from(bucket: “mycodo_db/autogen”) |> range(start: -360s) |> filter(fn: (r) => r[“_measurement”] == “C”) |> filter(fn: (r) => r[“device_id”] == “ca5c5b2c-4221-46ed-b585-2c2672c6df58”) |> filter(fn: (r) => r[“channel”] == “0”) |> filter(fn: (r) => r[“measure”] == “temperature”) |> last()’
2023-08-26 21:10:43,281 - DEBUG - mycodo.influx - query_flux() query: ‘from(bucket: “mycodo_db/autogen”) |> range(start: -360s) |> filter(fn: (r) => r[“_measurement”] == “None”) |> filter(fn: (r) => r[“device_id”] == “b61d34ff-d8e9-4811-8b9c-2d7af11a7e96”) |> last()’
2023-08-26 21:10:44,132 - DEBUG - mycodo.lockfile - Releasing lock for /var/lock/atlas_mycodo_devices_atlas_scientific_i2c_1_80.lock
2023-08-26 21:10:44,253 - DEBUG - mycodo.influx - Write point success: b’pH,channel=0,device_id=318a6161-04e2-4682-8911-3af9aac928d3,measure=ion_concentration value=6.01’
2023-08-26 21:10:45,109 - DEBUG - mycodo.influx - query_flux() query: ‘from(bucket: “mycodo_db/autogen”) |> range(start: -120s) |> filter(fn: (r) => r[“_measurement”] == “C”) |> filter(fn: (r) => r[“device_id”] == “ca5c5b2c-4221-46ed-b585-2c2672c6df58”) |> filter(fn: (r) => r[“channel”] == “0”) |> filter(fn: (r) => r[“measure”] == “temperature”) |> last()’
2023-08-26 21:10:45,191 - DEBUG - mycodo.lockfile - Acquiring lock for /var/lock/atlas_mycodo_devices_atlas_scientific_i2c_1_100.lock (10 sec timeout)
2023-08-26 21:10:45,192 - DEBUG - mycodo.lockfile - Lock acquired for /var/lock/atlas_mycodo_devices_atlas_scientific_i2c_1_100.lock in 0.001 seconds
2023-08-26 21:10:45,698 - DEBUG - mycodo.lockfile - Releasing lock for /var/lock/atlas_mycodo_devices_atlas_scientific_i2c_1_100.lock
2023-08-26 21:10:45,873 - INFO - mycodo.controllers.controller_conditional_49791357 - This INFO log entry will appear in the Daemon Log
2023-08-26 21:10:46,019 - DEBUG - mycodo.influx - query_flux() query: ‘from(bucket: “mycodo_db/autogen”) |> range(start: -360s) |> filter(fn: (r) => r[“_measurement”] == “C”) |> filter(fn: (r) => r[“device_id”] == “c9ea36ba-07b9-493c-94fb-fd7b6c6332a7”) |> filter(fn: (r) => r[“channel”] == “0”) |> filter(fn: (r) => r[“measure”] == “temperature”) |> last()’
2023-08-26 21:10:46,085 - INFO - mycodo.controllers.controller_conditional_49791357 - Measurement value is 10.0
2023-08-26 21:10:46,200 - DEBUG - mycodo.lockfile - Acquiring lock for /var/lock/atlas_mycodo_devices_atlas_scientific_i2c_1_100.lock (10 sec timeout)
2023-08-26 21:10:46,205 - DEBUG - mycodo.lockfile - Lock acquired for /var/lock/atlas_mycodo_devices_atlas_scientific_i2c_1_100.lock in 0.005 seconds
2023-08-26 21:10:47,713 - DEBUG - mycodo.lockfile - Releasing lock for /var/lock/atlas_mycodo_devices_atlas_scientific_i2c_1_100.lock
2023-08-26 21:10:47,893 - DEBUG - mycodo.influx - Write point success: b’uS_cm,channel=0,device_id=14756b3c-7508-4582-bc32-4d17d4863677,measure=electrical_conductivity value=1877\nppm,channel=1,device_id=14756b3c-7508-4582-bc32-4d17d4863677,measure=total_dissolved_solids value=1014\nppt,channel=2,device_id=14756b3c-7508-4582-bc32-4d17d4863677,measure=salinity value=0.95\nunitless,channel=3,device_id=14756b3c-7508-4582-bc32-4d17d4863677,measure=specific_gravity value=1.001’
2023-08-26 21:10:49,727 - INFO - mycodo.controllers.controller_conditional_ad12c8df - This INFO log entry will appear in the Daemon Log
2023-08-26 21:10:49,854 - DEBUG - mycodo.influx - query_flux() query: ‘from(bucket: “mycodo_db/autogen”) |> range(start: -120s) |> filter(fn: (r) => r[“_measurement”] == “C”) |> filter(fn: (r) => r[“device_id”] == “ca5c5b2c-4221-46ed-b585-2c2672c6df58”) |> filter(fn: (r) => r[“channel”] == “0”) |> filter(fn: (r) => r[“measure”] == “temperature”)’
2023-08-26 21:10:49,918 - INFO - mycodo.controllers.controller_conditional_ad12c8df - Measurement value is 16.419249999999998

Please format the code, as it’s currently incomprehensible and difficult to even look at. Also, please explain your issue in detail rather than just code and logs.