Grove I2C Motor driver support

The library is not 1.3, but for my specific board

Hmm, for the love of god I dont understand why the output switch state==off condition is not triggered. Below is the logfile. I get the confirmation that the output_switch is fired up, though I dont understand where its called from in the first place and also how to pass on to the MotorDrive object which channel is being triggered. I guess im in over my head here:)

2021-04-20 21:18:52,150 - DEBUG - mycodo.outputs.grove_i2c_motor_driver_tb6612fng_01_b2cdb11a - output_on_off(on, 0, sec, 2.0, 0.0, True)
2021-04-20 21:18:52,150 - DEBUG - mycodo.outputs.grove_i2c_motor_driver_tb6612fng_01_b2cdb11a - state: on, output_type: sec, amount: 2.0 (direction: CW)
2021-04-20 21:18:52,151 - DEBUG - mycodo.outputs.grove_i2c_motor_driver_tb6612fng_01_b2cdb11a - Output turned on CW
2021-04-20 21:18:52,172 - DEBUG - mycodo.outputs.grove_i2c_motor_driver_tb6612fng_01_b2cdb11a - Output b2cdb11a-a365-4ab5-96e2-fb7afd3a1a5b CH0 (Name) on for 2.0 seconds. Output returned: None
2021-04-20 21:18:54,199 - DEBUG - mycodo.outputs.grove_i2c_motor_driver_tb6612fng_01_b2cdb11a - output_on_off(off, 0, None, 0.0, 0.0, True)

Is this the code you’re currently running and not having your “off” code executed?

This is the newest version (16.9 KB)

Just wanted to post a picture of my setup. Trying to keep it pretty lean, still need to route a lot of cables, but everything is connected with grove connectors and most will be I2C.

I added a GrovePi+ on top of the pi 4. I probably wont be using a lot of the non-I2C channels, so its just a very expensive grove I2C connector hat:)

So far we have pH, EC, ORP, DO and PT1000 for the water and a SDC30 CO2/Temp/Humid sensor for the air. Plus some light meters, just for fun. The one in the photo is a TCS34372, not supported yet, so I have some others in the mail. The DHT22 is non-I2C but it looks like there is a grove input for it already. Lucky me.

I have a couple of 4 channel I2C relays in the mail as well.

1 Like

Hello jacobguldberg,

today my grove i2c motor drivers boards Version 1.0 arrived,and i have tried the v1_3_01 driver software. I can find my board in the i2c system info, in the output view it is not configured. Do you have also a driver for the 1.0 Version board, or can you tell me what i have to do to get it working.

Hi bartonio

There is not output for the smaller grove I2C motor driver yet. I started on modifying the 1.3, but still without success. Haven’t had to much time to look into it.

Allright, thankmyou for your quick response, i will order the 1.3 boards and then try it again to get it working.

So, I got the driver working outside mycode, had to change the stop to write_word_data instead of write_i2c_block_data.

This code will start and stop channel A. Now it comes down to my lack of knowledge python syntax and mycodo. But atleast I know how to fire up and brake the motor. So maybe somebody more skilled in python can spot the obvious errors.

import smbus
import time

# I2C channel 1 is connected to the GPIO pins
channel = 1

#  MCP4725 defaults to address 0x60
address = 0x13

# Register addresses (with "normal mode" power-down bits)
reg_write_run = 0x02
reg_write_off = 0x00

# Initialize I2C (SMBus)
bus = smbus.SMBus(channel)

bus.write_i2c_block_data(address, reg_write_run, [0,50])


bus.write_word_data(address, reg_write_off , 0)
1 Like

Adding a little bit of information. This is the log I get when I try to dispense by volume

2021-04-25 12:41:11,696 - DEBUG - mycodo.outputs.grove_i2c_motor_driver_tb6612fng_01_8f65ca24 - output_on_off(on, 0, vol, 13.0, 0.0, True)
2021-04-25 12:41:11,696 - DEBUG - mycodo.outputs.grove_i2c_motor_driver_tb6612fng_01_8f65ca24 - state: on, output_type: vol, amount: 13.0 (direction: CW)
2021-04-25 12:41:11,696 - ERROR - mycodo.outputs.grove_i2c_motor_driver_tb6612fng_01_8f65ca24 - Invalid parameters: State: on, Type: vol, Mode: specify_flow_rate, Amount: 13.0, Flow Rate: 15.0

Looking at the parameters, I dont understand why it doesnt triggers any of the if statements, but is going directly to the last else and triggers an error.

How would one do the same for Channel B?

Channel and speed. Pretty much like the 1.3 example. I just changed it below to illustrate it. What I dont understand in mycodo is, how to parse the mycodo channel to the motor run function. Im pretty sure these function would run the motor and brake it, I just cant figure out, how mycodo execute them with the correct parameters.

I just tested with the 1.3 that you sent kyle and I am getting the same error. Im starting to think that it might be my mycodo that is corrupt somehow

2021-04-25 16:50:20,510 - DEBUG - mycodo.outputs.grove_i2c_motor_driver_01_2749ba61 - output_on_off(on, 0, vol, 13.0, 0.0, True)
2021-04-25 16:50:20,510 - DEBUG - mycodo.outputs.grove_i2c_motor_driver_01_2749ba61 - state: on, output_type: vol, amount: 13.0 (direction: CW)
2021-04-25 16:50:20,511 - ERROR - mycodo.outputs.grove_i2c_motor_driver_01_2749ba61 - Invalid parameters: State: on, Type: vol, Mode: specify_flow_rate, Amount: 13.0, Flow Rate: 20.0

Here is a test module for board v1.0 (Test 01). When attaching files, be sure to be very clear about what hardware/board version it is for. I noticed some attachments that were supposedly for the v1.0 board but had the filename v1.3. There will be people finding these threads and trying to use this code, so we should be as careful to appropriately label things so we don’t cause confusion or worse, damage hardware. (14.7 KB)

I get an error while trying to import the output module

Error: Import Output: Could not load uploaded file as a python module:
Traceback (most recent call last):
  File "/home/pi/Mycodo/mycodo/mycodo_flask/utils/", line 682, in settings_output_import
    output_info = load_module_from_file(full_path_tmp, 'outputs')
  File "/home/pi/Mycodo/mycodo/utils/", line 17, in load_module_from_file
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/pi/Mycodo/mycodo/outputs/tmp_outputs/", line 15, in <module>
    from mycodo.utils.constraints_pass import constraints_pass_positive_value
ModuleNotFoundError: No module named 'mycodo.utils.constraints_pass'

I deleted the import reference and directly inserted the constrains_pass function into the code. When I run it I get the following error:

2021-04-25 18:46:37,822 - ERROR - mycodo.daemon - Could not query output state: 0
Traceback (most recent call last):
  File "/var/mycodo-root/mycodo/", line 849, in output_states_all
    return self.controller['Output'].output_states_all()
  File "/var/mycodo-root/mycodo/controllers/", line 340, in output_states_all
    states[output_id][each_channel] = self.output[output_id].output_state(each_channel)
  File "/var/mycodo-root/mycodo/outputs/", line 677, in output_state
    state = self.is_on(output_channel)
  File "/home/pi/Mycodo/mycodo/outputs/custom_outputs/", line 380, in is_on
    if self.currently_dispensing[output_channel]:
KeyError: 0

Output Module (Board v1.0) Test 02: (14.8 KB)

Upgrade to the latest Mycodo release. You are likely running an old version.

I was 1 version behind :slight_smile:

I’ll do the upgrade and give it another try

The motor is running, but again the log is not showing that state=‘off’ is being triggered.

2021-04-25 19:13:25,117 - DEBUG - mycodo.outputs.grove_i2c_motor_driver_v1_0_02_8c565a35 - output_on_off(on, 0, sec, 2.0, 0.0, True)
2021-04-25 19:13:25,118 - DEBUG - mycodo.outputs.grove_i2c_motor_driver_v1_0_02_8c565a35 - state: on, channel: 0, output_type: sec, amount: 2.0 (direction: CW)
2021-04-25 19:13:25,118 - DEBUG - mycodo.outputs.grove_i2c_motor_driver_v1_0_02_8c565a35 - Speed: 255.0
2021-04-25 19:13:25,118 - DEBUG - mycodo.outputs.grove_i2c_motor_driver_v1_0_02_8c565a35 - Output turned on CW
2021-04-25 19:13:25,120 - DEBUG - mycodo.outputs.grove_i2c_motor_driver_v1_0_02_8c565a35 - Output 8c565a35-a67f-473c-9bfb-114fa6dee845 CH0 (Name) on for 2.0 seconds. Output returned: None
2021-04-25 19:13:27,129 - DEBUG - mycodo.outputs.grove_i2c_motor_driver_v1_0_02_8c565a35 - output_on_off(off, 0, None, 0.0, 0.0, True)

For some reason the output_switch is not called, if it was the

self.logger.debug("state: {}, channel: {}, output_type: {}, amount: {} (direction: {})".format(
    state, output_channel, output_type, amount, direction))

would be visible in the log

I outcommented the return statement of the output_switch function. My guess is that the when its called to turn of the motor after the set number of seconds, there is no amount parameter, so the return is called and terminates the function.

As it no turns on and off, I think it will be easier for my to get the last stuff working and ill post a working version when im done.

def output_switch(self, state, output_type=None, amount=None, output_channel=None):

#        if amount > 0:

        speed = 50

        direction = "CW"

#        elif amount < 0:

#            speed = -255

#            direction = "CCW"

#        else:

#            return

Can you be more detailed about describing what you’re doing? There are multiple ways to turn the output on (on button, duration value, volume value). I need to know exactly what you’re doing in order to be able to determine a potential issue.