Difference between revisions of "French FX-7 robot"
(→Software Side) |
(→Software Side) |
||
Line 209: | Line 209: | ||
In both approaches, it makes sense to use a 16-bit 'binary variable' in software that is manipulated with binary logic to turn bit-positions on/off using pre-defined variable-names to reflect particular motor-positions, etc. | In both approaches, it makes sense to use a 16-bit 'binary variable' in software that is manipulated with binary logic to turn bit-positions on/off using pre-defined variable-names to reflect particular motor-positions, etc. | ||
+ | |||
+ | For the bi-directional motor-drivers, it makes sense to define things like | ||
+ | MOTOR_x_MASK=yy11yy | ||
+ | MOTOR_x_STOP=yy00yy | ||
+ | MOTOR_x_FORWARD=yy01yy | ||
+ | MOTOR_x_BACKWARDS=yy10yy | ||
+ | MOTOR_x_BRAKE=yy11yy (I think that'd be it's result; not quite sure) | ||
+ | |||
+ | where 'x' is the number/name of the motor and y is an amount of 'padding' required to get it into the right position. | ||
+ | The motor_x_mask is the 'bitmask' to use for 'AND'ing it with the motor-status variable each time you do a change. | ||
+ | For example, for 'left_tread' motor (the bits '0' and '1' on register '1'), it could be: | ||
+ | |||
+ | MOTOR_LTREAD_STOP=00000000 | ||
+ | MOTOR_LTREAD_ |
Revision as of 10:47, 29 January 2014
Projects | |
---|---|
Participants | Mi1es |
Skills | Electronics, Soldering, Programming, Creative thinking |
Status | Active |
Niche | Electronics |
Purpose | World domination |
"Contrôle système! Contrôle système!"
Contents
Overview
System
Direct Drive control via RaspPI
Machine has been taken apart.. blblblalbla
H-bridge board has all the transistors of the original board on it for 4 full H-bridges that can drive all of the four bi-directional motors.
Original 'direct drive' Layout was as follows , with the connectors of the motors facing you:
- First block, gpio18, w1, gpio4, w7, Left tread
- Second block, gpio17,w0, gpio23,w4, Right treads
- Third block: gpio27,w2, gpio22,w3, hip
- Fourth block: gpio24, w5, gpio25,w6, arms
'Direct Drive' Python code
import RPi.GPIO as gpio import time import pygame from pygame.locals import * gpio.setmode(gpio.BOARD) gpio.setup(7, gpio.OUT) gpio.setup(11, gpio.OUT) gpio.setup(13, gpio.OUT) gpio.setup(15, gpio.OUT) gpio.output(7, True) gpio.output(11, True) while True: gpio.output(13, True) gpio.output(15, False) time.sleep(2) gpio.output(13, False) gpio.output(15, True) time.sleep(2)
pygame.init() screen = pygame.display.set_mode((640,480)) pygame.display.set_caption("Pygame") pygame.mouse.set_visible(0) done = False enable = 0 direction = 0 while not done: for event in pygame.event.get(): if(event.type==KEYDOWN): print event if(event.key==273): direction=1; enable=1; if(event.key==274): direction=-1; enable=1; if(event.type==KEYUP): print event if(event.key==273): direction=0; enable=0; if(event.key==274): direction=0; enable=0; if(enable==1): if(direction==1): print "Forwards" gpio.output(13, False) gpio.output(15, True) if(direction==-1): print "Backwards" gpio.output(13, True) gpio.output(15, False) else: gpio.output(13, False) gpio.output(15, False)
With this code-shim you can test the function of your code even without having RPi.GPIO loaded (like on most PC's)
Note it doesnt implement all things yet; but enough to work for this project currently.
Working on a shift-register help-library
class FAKEGPIO: def __init__(self): self.BOARD=1 self.OUT=0 self.IN=1 def setmode(self,variant): print "Call: setmode: variant -> " + str(variant) def setup(self,pin, type): print "Call: setup : pin -> " + str(pin) + ", type -> " + str(type) def output(self,pin,state): print "Out:" + str(pin) + "-> " + str(state) gpio = FAKEGPIO()
Shift-Register driving of robot
Since the RaspPI doesnt have much IO and the robot requires 8 output-pins just for the basic motor-control already, we've started looking at driving the outputs using shift-registers instead.
The proto-board has been re-wired to have two shift-registers hosted on it, connected in series, for a total of 16 outputs.
The shift-registers in question are the 74HCT595's that has an 8-bit serial register controlled by 'data' and 'clock' lines, and an 8-bit parallel 'latch' that is controlled by a separate line; allowing you to control at which moment the 8 output pins (output A-H) should reflect the state of the internal 8-bit serial register.
By having the parallel register in between the outputs and the serially controlled register, you are able to change the contents of the serial register at your own leisure without the outputs directly following your changes.
The last control-lines on the 74HCT595 are a 'master reset' pin (active LOW; so connect to HIGH if unused) and a 'Chip enable' (active LOW, connect to GND if not used)
The motor-pins are connected to the first of the two shift-registers; this means that the last 8 bits of data shifted into the 16 bit register-space controls the motors as the first bit shifted in ends up being at the last-most position after 16 clock-cycles.
Shift-register layout | |||||
---|---|---|---|---|---|
Register | Bit | Motor | Direction | ||
1 | 0 | Left Tread | Forwards | ||
1 | Left Tread | Backwards | |||
2 | Right Tread | Forwards | |||
3 | Right Tread | Backwards | |||
4 | Hip | Forwards | |||
5 | Hip | Backwards | |||
6 | Arms | Open | |||
7 | Arms | Close | |||
2 | 0 | TBD | TBD | ||
1 | TBD | TBD | |||
2 | TBD | TBD | |||
3 | TBD | TBD | |||
4 | TBD | TBD | |||
5 | TBD | TBD | |||
6 | TBD | TBD | |||
7 | TBD | TBD |
Software Side
To drive the shift-register, two approaches can be used. Either full 'software bit-banging' or using the SPI-bus on the Raspberry PI to drive (at least) the clock, enable and data-lines of the shift-register. The 'latch' pin of the register needs to be bit-banged as there seems to be no easy way to pull this off with just SPI (unless.. perhaps, doing something smart with the 'enable' line..)
In both approaches, it makes sense to use a 16-bit 'binary variable' in software that is manipulated with binary logic to turn bit-positions on/off using pre-defined variable-names to reflect particular motor-positions, etc.
For the bi-directional motor-drivers, it makes sense to define things like MOTOR_x_MASK=yy11yy MOTOR_x_STOP=yy00yy MOTOR_x_FORWARD=yy01yy MOTOR_x_BACKWARDS=yy10yy MOTOR_x_BRAKE=yy11yy (I think that'd be it's result; not quite sure)
where 'x' is the number/name of the motor and y is an amount of 'padding' required to get it into the right position. The motor_x_mask is the 'bitmask' to use for 'AND'ing it with the motor-status variable each time you do a change. For example, for 'left_tread' motor (the bits '0' and '1' on register '1'), it could be:
MOTOR_LTREAD_STOP=00000000 MOTOR_LTREAD_