Drive fault above 18 volts
Forums:
Dear Piborg,
I have a problem with my script that is use. normally when i have my output voltage to the motors set to 18v everything works fine. But when i set it to 20v or higher i get the fault failed sending motor drive level.
Do you know how this is possible? This is the script im using.
#!/usr/bin/env python ### # # diabloJoystick.py: A script for controlling motors with the Diablo using a joystick. # # 04-07-2019 # Thieu Verstijnen ### # Load library functions we want from __future__ import print_function from diablo import * from time import sleep from os import environ from sys import exit, stdout, stderr import pygame import RPi.GPIO as GPIO GPIO.setwarnings(False) GPIO.setmode(GPIO.BOARD) GPIO.setup(8, GPIO.OUT, initial=GPIO.LOW) # Power settings voltageIn = 24.0 # Total battery voltage to the Diablo voltageOut = 18.0 # Maximum motor voltage # Setup the power limits if voltageOut > voltageIn: maxPower = 1.0 else: maxPower = voltageOut / float(voltageIn) # Re-direct our output to standard error, we need to ignore standard out to hide some nasty print statements from pygame stdout = stderr # Setup the left Diablo DIABLO1 = Diablo() DIABLO1.i2cAddress = 38 DIABLO1.Init() if not DIABLO1.foundChip: boards = ScanForDiablo() if len(boards) == 0: print('No Diablo found, check you are attached :)') else: print('No Diablo at address %02X, but we did find boards:' % (DIABLO1.i2cAddress)) for board in boards: print(' %02X (%d)' % (board, board)) print('If you need to change the I2C address change the set-up line so it is correct, e.g.') print('DIABLO1.i2cAddress = 0x%02X' % (boards[0])) exit() #DIABLO1.SetEpoIgnore(True) # Uncomment to disable EPO latch, needed if you do not have a switch / jumper DIABLO1.ResetEpo() # Setup the right Diablo DIABLO2 = Diablo() DIABLO2.i2cAddress = 55 DIABLO2.Init() if not DIABLO2.foundChip: boards = ScanForDiablo() if len(boards) == 0: print('No Diablo found, check you are attached :)') else: print('No Diablo at address %02X, but we did find boards:' % (DIABLO2.i2cAddress)) for board in boards: print(' %02X (%d)' % (board, board)) print('If you need to change the I2C address change the set-up line so it is correct, e.g.') print('DIABLO2.i2cAddress = 0x%02X' % (boards[0])) exit() #DIABLO2.SetEpoIgnore(True) # Uncomment to disable EPO latch, needed if you do not have a switch / jumper DIABLO2.ResetEpo() # Settings for the joystick axisUpDown = 1 # Joystick axis to read for up / down position axisUpDownInverted = False # Set this to True if up and down appear to be swapped axisLeftRight = 2 # Joystick axis to read for left / right position axisLeftRightInverted = False # Set this to True if left and right appear to be swapped buttonResetEpo = 16 # Joystick button number to perform an EPO reset (Start) buttonSlow = 8 # Joystick button number for driving fast whilst held (L2) slowFactor = 1.0 # Speed to slow to when the drive fast button is not held, e.g. 0.5 would be half speed buttonFastTurn = 9 # Joystick button number for turning fast (R2) buttoncross = 14 # Button cross for lights on buttoncircle = 13 # Button circle for lights off buttonsquare = 15 # Button square for claxon on buttontriangle = 12 # Button triangle for claxon off interval = 0.00 # Time between updates in seconds, smaller responds faster but uses more processor time # Setup pygame and wait for the joystick to become available environ["SDL_VIDEODRIVER"] = "dummy" # Removes the need to have a GUI window pygame.init() print ('Waiting for joystick... (press CTRL+C to abort)') while True: try: try: pygame.joystick.init() # Attempt to setup the joystick if pygame.joystick.get_count() < 1: pygame.joystick.quit() else: # We have a joystick, attempt to initialise it! joystick = pygame.joystick.Joystick(0) break except pygame.error: # Failed to connect to the joystick pygame.joystick.quit() time.sleep(0.1) except KeyboardInterrupt: # CTRL+C exit, give up print ('\nUser aborted') print ('Joystick found') joystick.init() try: print('Motors are ready to drive.') print('Press CTRL+C to quit') driveLeft = 0.0 driveRight = 0.0 running = True hadEvent = False upDown = 0.0 leftRight = 0.0 # Loop indefinitely while running: # Get the latest events from the system hadEvent = False events = pygame.event.get() # Handle each event individually for event in events: if event.type == pygame.QUIT: # User exit running = False elif event.type == pygame.JOYBUTTONDOWN: # A button on the joystick just got pushed down hadEvent = True if event.button == buttoncross: GPIO.output(8, GPIO.HIGH) if event.button == buttoncircle: GPIO.output(8, GPIO.LOW) elif event.type == pygame.JOYAXISMOTION: # A joystick has been moved hadEvent = True if hadEvent: # Read axis positions (-1 to +1) if axisUpDownInverted: upDown = -joystick.get_axis(axisUpDown) else: upDown = joystick.get_axis(axisUpDown) if axisLeftRightInverted: leftRight = -joystick.get_axis(axisLeftRight) else: leftRight = joystick.get_axis(axisLeftRight) # Apply steering speeds if not joystick.get_button(buttonFastTurn): leftRight *= 0.5 # Determine the drive power levels driveLeft = -upDown driveRight = -upDown if leftRight < -0.05: # Turning left driveLeft *= 1.0 + (2.0 * leftRight) elif leftRight > 0.05: # Turning right driveRight *= 1.0 - (2.0 * leftRight) # Check for button presses if joystick.get_button(buttonResetEpo): DIABLO.ResetEpo() if not joystick.get_button(buttonSlow): driveLeft *= slowFactor driveRight *= slowFactor # Set the motors to the new speeds # Set the motors to the new speeds DIABLO1.SetMotors(driveLeft * maxPower) DIABLO2.SetMotors(driveRight * maxPower) # Wait for the interval period sleep(interval) # Disable all drives DIABLO1.MotorsOff() DIABLO2.MotorsOff() except KeyboardInterrupt: # CTRL+C exit, disable all drives DIABLO1.ResetEpo() DIABLO2.ResetEpo() print('Terminated') print() GPIO.cleanup()
Greetings Thieu
piborg
Tue, 06/02/2020 - 12:03
Permalink
Failed sending motor drive level
There are two main reasons for getting the "Failed sending motor X drive level" errors:
Since things work properly at lower power we can rule out anything related to wiring problems.
The most likely problem is the 5V power stability. If this is the case it suggests the 5V regulator is unable to get enough power from the battery when the motors are running at higher power levels. We often see this kind of problem as batteries are starting to get flat. If you have not already I would suggest fully recharging the battery and try again. It is also possible that the battery cannot provide enough current for both the motors and the regulator at the same time.
I2C problems are less likely, but still possible. It is possible that the electrical "noise" generated by the motors is being picked up by the I2C lines like an antenna would. It might sound odd, but we have seen this twice before with other robots. If this is the case you can shield the 3-pin cables by carefully wrapping them in tinfoil - be careful to ensure that the foil cannot come into contact with any of the boards. Shorter cables between the Raspberry Pi and Diablo may also help.
Thieu
Tue, 06/02/2020 - 12:33
Permalink
Many thanks, this evening i
Many thanks, this evening i will fully charge the batteries. I will let you know if it works
Thieu
Wed, 06/03/2020 - 19:42
Permalink
The batteries are now fully
The batteries are now fully charged and everything works fine again thanks. I have 2 lead baterries of 12v parralel 7ah each, what kind of lipo battery do you recommend as replacing battery?
piborg
Wed, 06/03/2020 - 21:58
Permalink
Great news
Great news :)
For bigger projects (such as DoodleBorg) we have stuck with lead-acid because they are easy to get in higher capacities and relatively safe when handled properly.
Based on your code I presume you meant the batteries are in serial to produce a 24V battery:
Source: http://beautyinscience.com/ms-sem-4-physical-science.html
The best options would be either a 6S LiPo - 22.2V, or a 7S LiPo - 25.9V. The 6S will have a slightly lower maximum output and you would need the full 7Ah / 7000mAh for the same running time. The 7S would run at about 93% to get a 24V output so you can have a lower capacity, 6.5Ah / 6500mAh would give about the same running time.
Remember that you will also need an appropriate charger for the LiPo that supports the correct type.