Society of Robots - Robot Forum
Software => Software => Topic started by: vialick on April 05, 2009, 12:37:15 AM
-
While waiting for a programmer to be delivered that may actually work with slightly modern hardware (modern hardware being a computer with no parallel or serial ports) I thought it may be a good idea to try and use up some of the leftover components from making the $50 robot to make a little 6-bit display (6 LEDs, each one representing 1 bit). As I'm fairly unexperienced in electronics (studied it in high-school, made some guitar FX pedals that didn't work and some audio cables) and programming (I think I have a half-finished C++ battleships program lying around somewhere) I thought I'd make sure what I'm wanting to do may be capable of doing something.
I've started to make a connector that would go from the 6 servo outputs (and ground) to a spare piece of perfboard, each out hooking up to a 330 ohm resistor and LED. Assuming this will work I'd like it to be able to display various things, such as the photoresistor readings, and comparisons of them. In the future I think it would be a good way to test some ideas.
Software wise my programming skills have gone rusty, but I've managed to do a basic prototype of the functions in python3k (probably backward compatable though). I guess I'll need to port it over to C, any help to do this would be super-appreciated, especially the outputting parts, and conversion to binary (last time I encountered binary conversion in C it was using bitwise logic operators, which I'm not exactly the best at using...or understanding even).
The way I've set it to work is so that the display functions return a 6 bit code, that code would then be interpreted in binary as: 1 = light on, 0 = light off
So here's the python code:
def strengthdisplay (data):
"""turn 8 bit data into a number between 0 and 6"""
data = int(data / 37)
led = 0
if data == 0: led = 0b000000
elif data == 1: led = 0b000001
elif data == 2: led = 0b000011
elif data == 3: led = 0b000111
elif data == 4: led = 0b001111
elif data == 5: led = 0b011111
else: led = 0b111111
return led
def doublestrengthdisplay (data1, data2):
"""turn two lots of 8 bit data into 2 numbers between 0 and 3"""
data1 = int(data1/64)
data2 = int(data2/64)
led = 0
#process the first signal
if data1 == 0: led = 0b000000
elif data1 == 1: led = 0b000001
elif data1 == 2: led = 0b000011
else: led = 0b000111
#now append the second signal
if data2 == 0: led += 0b000000
elif data2 ==1: led += 0b100000
elif data2 ==2: led += 0b110000
else: led += 0b111000
return led
def sigdifference (data1, data2):
"""compares data1 to data2 and plots the difference"""
#subtracting an 8 bit number from another 8 bit number can have a
#difference of 511, we need to create a number between -3 and 3
number = (int(data1 / 64) - int(data2 / 64))
led = 0
if number ==-3: led = 0b000001
elif number ==-2: led = 0b000010
elif number ==-1: led = 0b000100
elif number == 0: led = 0b000000
elif number == 1: led = 0b001000
elif number == 2: led = 0b010000
elif number == 3: led = 0b100000
return led
def display (ledout):
"""switch on the lights"""
#create a binary listing of ledout
ledout = bin(ledout)
# something to remove the "0b" prefix should go here, this may just be python
#also it should make sure that all the '0's are there
#ledno = 0 #used to chose which led should be switched on
for x in (bin(5)):
if x > "0": print ("x") #portoff(ledno)
elif x < "1": print ("O")#proton(ledno)
#ledno += 1
#a bit of code here to give an example of the functions
import random
print ("strengthdisplay:")
for x in range(20): print (bin((strengthdisplay(random.randint(0, 255)))))
print ("doublestrengthdisplay:")
for x in range(20): print (bin(doublestrengthdisplay(random.randint(0,255),random.randint(0,255))))
print ("sigdifference:")
for x in range(20): print (bin(sigdifference(random.randint(0,255),random.randint(0,255))))
Does anyone think this may work?
Is there a better design I could use for the code?
-
In the C code, say you are using the D ports on the microcontroller. In the set-up phase, you would do the following to set all the D ports to output. This is located in the configure_ports method in SoR_Utils.h
DDRD = 0xFF;
In the main code, to turn LEDs on or off, you would do
PORTD = 0b00001111;
To turn half the ports high and half the ports low. I am unsure how you wired the LEDs up, so 0 might be on or 1 might be on. In the code, the 1 turns the signal port high.
-
so I can just send the binary form to PORTD and it will light up as I want? (If so that's bloody brilliant)
say I have 6 LEDs and want them to light up as follows:
XooXXX (x is on, o is off)
I would just write
PORTD = 0b100111
-
Make sure you declare port D as output.
-
yes it will work just as easy as that.
If you had 8 LED's to represent full 8-bit binary it would be better than 6. say you made a reading with the analog module you could just say PORTD = ADRESL and the led's would light up with the binary representation of the reading (where ADRESL is the register where the analog reading is). you can assign hex directly to it or a char variable directly to it.
so the decimal number 45 can be represeted by binary (00101101) or by hex (2D)
so you could : PORTD = 45
or PORTD = 0b00101101
or PORTD = 0x2D
all of these will light the leds in the binary representation.
also if you have a 8 bit variable you can directly get the value from this.
char myvar = 45;
PORTD = myvar
etc..
-
Yeah I'd thought about the binary representation, started trying to code for it (when I thought I'd have to run it through a loop using bitwise logic and that just sent shivers down my spine)...I only just realised that there were 8 D ports (and that on the $50 robot board there are only 5 servo outputs, not 6)
anyway I think I might keep it to 6 as I've already made the board and a cable for the display, also I could then have it running while the robot drives around, and it would be easy to hook up 2 more LEDs later (though there's no more space on the board)
which leads to annother question, if I want to have servos on d ports 0 and 1, and the led display on 2 - 7, when I display a value would it cause any problems for the servo (I imagine if I were to call the display function before anything involving movement it wouldn't matter, but I would like to know).
Would the best way be to have the functions return the display value shifted up two bits, ie. instead of 0b111111 have 0b00111111
Well, my programmer has arrived, I'll report back on how it goes.