i've been tinkering around, and i have googled and searched about bitwise operations.
and i think i understand some of it, however i have a piece of code i have copied from someone online which allows it to move a 28byj-48 5v motor and driver in python. its actually the only code i've found in python that it would allow it to work.
however, i tried breaking it down with my own code and cant seem to figure out why mine wont work but this one does.
here it is, the working one:
import RPi.GPIO as GPIO
from time import sleep
#configuring pins and motors
motorPin = (18,23,24,25) #GPIO pin in BCM mode refer to map
rolePerMinute =13
stepsPerRevolution = 2048
stepSpeed = (60/rolePerMinute)/stepsPerRevolution
#setup the pins to the motor
def setup():
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
for i in motorPin:
GPIO.setup(i, GPIO.OUT)
def rotary1():
n =1
while n < 10000:
for j in range(4):
for i in range(4):
GPIO.output(motorPin[i],0x99>>j & (0x08>>i))
sleep(stepSpeed)
n +=1
and here is mine:
import RPi.GPIO as GPIO
from time import sleep
#configuring pins and motors
motorPin = (18,23,24,25) #GPIO pin in BCM mode refer to map
rolePerMinute =13
stepsPerRevolution = 2048
stepSpeed = (60/rolePerMinute)/stepsPerRevolution
#setup the pins to the motor
def setup():
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
for i in motorPin:
GPIO.setup(i, GPIO.OUT)
def rotary():
n = 1
while n < 10000:
GPIO.output(18,0x99>>1 & (0x08>>1))
sleep(stepSpeed)
GPIO.output(23,0x99>>2 & (0x08>>2))
sleep(stepSpeed)
GPIO.output(24,0x99>>3 & (0x08>>3))
sleep(stepSpeed)
GPIO.output(25,0x99>>4 & (0x08>>4))
sleep(stepSpeed)
n+= 1
if im understanding this correctly, 0X99 is transformed into a bit "10011001" and its ">>" bit wise operator is pushing it by 1 to the left?
this is where im confused, and also why wouldn't my stepped version work versus the first version.
if someone could help me understand this, i would be greatful.
many thanks.
i've tried googling how bitwise work and watched a very informative video, however i still couldnt understand how << or >> works in this case with Hex values.
I also couldn't get my stepped version to work, versus the other.
The working code uses nested loops, so it's processing the cartesian product of 0 through 3. Unrolled, it's equivalent to
GPIO.output(18,0x99>>0 & (0x08>>0))
sleep(stepSpeed)
GPIO.output(18,0x99>>0 & (0x08>>1))
sleep(stepSpeed)
GPIO.output(18,0x99>>0 & (0x08>>2))
sleep(stepSpeed)
GPIO.output(18,0x99>>0 & (0x08>>3))
sleep(stepSpeed)
GPIO.output(18,0x99>>1 & (0x08>>0))
sleep(stepSpeed)
GPIO.output(18,0x99>>1 & (0x08>>1))
sleep(stepSpeed)
GPIO.output(18,0x99>>1 & (0x08>>2))
sleep(stepSpeed)
GPIO.output(18,0x99>>1 & (0x08>>3))
sleep(stepSpeed)
GPIO.output(18,0x99>>2 & (0x08>>0))
sleep(stepSpeed)
GPIO.output(18,0x99>>2 & (0x08>>1))
sleep(stepSpeed)
GPIO.output(18,0x99>>2 & (0x08>>2))
sleep(stepSpeed)
GPIO.output(18,0x99>>2 & (0x08>>3))
sleep(stepSpeed)
GPIO.output(18,0x99>>3 & (0x08>>0))
sleep(stepSpeed)
GPIO.output(18,0x99>>3 & (0x08>>1))
sleep(stepSpeed)
GPIO.output(18,0x99>>3 & (0x08>>2))
sleep(stepSpeed)
GPIO.output(18,0x99>>3 & (0x08>>3))
sleep(stepSpeed)
Your version only performs the steps where i == j. It's also going from 1 to 4 instead of 0 to 3.
Looks like You don't use 'n' parameter:
in your code:
n = 1
while n < 10000:
GPIO.output(18,0x99>>1 & (0x08>>1))
sleep(stepSpeed)
GPIO.output(23,0x99>>2 & (0x08>>2))
sleep(stepSpeed)
GPIO.output(24,0x99>>3 & (0x08>>3))
sleep(stepSpeed)
GPIO.output(25,0x99>>4 & (0x08>>4))
sleep(stepSpeed)
n+= 1
try with follow:
n = 1
while n < 10000:
GPIO.output(18,0x99>>n+1 & (0x08>>n+1))
sleep(stepSpeed)
GPIO.output(23,0x99>>n+2 & (0x08>>n+2))
sleep(stepSpeed)
GPIO.output(24,0x99>>n+3 & (0x08>>n+3))
sleep(stepSpeed)
GPIO.output(25,0x99>>n+4 & (0x08>>n+4))
sleep(stepSpeed)
n+= 1
Related
What I'm trying to accomplish: if the room lights go off, the monitor should dim. If the room lights go back on, the monitor should get brighter.
On a Rpi4B, I'm trying to use ddcutil in combination with a photoresistor and capacitor to automatically adjust monitor brightness depending on ambient light in the room. I really only need 3 brightness settings; one each for bright, average, and dim light conditions.
I've been editing some code I found and I have the code responding to three different levels of brightness (just text verification telling me the if the light is dim, medium, or bright.) The issue is that it keeps printing the result over and over and I only need it to print (or eventually run my ddcutil routine) once, but STILL continue to check the ambient light level and react accordingly. How do I continually check input from the sensor without continually passing an instruction to ddcutil? I know very little about writing code and I suspect a Boolean flag may be the answer that I don't understand. Thanks for any help.
#!/usr/local/bin/python
import RPi.GPIO as GPIO
import time
__author__ = 'Gus (Adapted from Adafruit)'
__license__ = "GPL"
__maintainer__ = "pimylifeup.com"
GPIO.setmode(GPIO.BOARD)
#define the pin that goes to the circuit
pin_to_circuit = 3
def rc_time (pin_to_circuit):
count = 0
#Output on the pin for
GPIO.setup(pin_to_circuit, GPIO.OUT)
GPIO.output(pin_to_circuit, GPIO.LOW)
time.sleep(.2)
#Change the pin back to input
GPIO.setup(pin_to_circuit, GPIO.IN)
#Count until the pin goes high
while (GPIO.input(pin_to_circuit) == GPIO.LOW):
count += 1
return count
#Catch when script is interupted, cleanup correctly
try:
# Main loop
while True:
if(rc_time(pin_to_circuit)) > 4000:
print("Too dark. Frame off.")
if(rc_time(pin_to_circuit)) < 4000 and (rc_time(pin_to_circuit)) > 1000:
print("Good light. Medium brightness.")
if(rc_time(pin_to_circuit)) < 1000:
print("Bright day. Maximum brightness set.")
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
I would store the last light value in a variable and in your loop compare that to the current value. I would also move the checking logic to it's own method so it can be re-used elsewhere if required.
def get_light_value():
pin_rc_time = rc_time(pin_to_circuit)
if pin_rc_time > 4000:
return "low"
elif pin_rc_time <= 4000 and pin_rc_time > 1000:
return "medium"
else:
return "high"
Notice here that we also only call rc_time once per loop. That will avoid any weirdness if the value changes while the conditions are being determined. I changed the logic to check for <= 4000 which will cover the missing condition in your code where the value is exactly 4000. And I also used elif/else to ensure only one branch is evaluated.
Using this in the main loop:
last_light_value = None
curr_light_value = None
while True:
last_light_value = curr_light_value
curr_light_value = get_light_value()
# Do nothing if the value did not change
if last_light_value == curr_light_value:
time.sleep(1)
continue
if curr_light_value == "low":
print("Too dark. Frame off.")
elif curr_light_value == "medium":
print("Good light. Medium brightness.")
else: # Value must be high.
print("Bright day. Maximum brightness set.")
Homework for you:
To take this further, you might also want to think about what will happen if the pin value is very close to the threshold of the cutoffs. This will most likely cause the value to flip back and between categories, as some sensors are not extremely precise, and things like florescent lighting can oscillate in intensity.
To combat this, you could implement a filter that to only change the value if it is in a different category and has at least changed some delta of value since the last check. You can use a similar trick to the while loop which takes into account the last value seen before making a determination on if a value should be changed.
I am trying to write a program that will return True if the white king on a chess board is in check. The pieces on the board are generated as a string and formatted as such, where the lowercase values are white and the uppercase are black.:
r*x***k****p***P*****Q*****kp****K*****p***Pb****p***PP***X***KR
| | |X| | | |K|R|
| |p| | | |P|P| |
| | | |P|b| | | |
| |K| | | | | |p|
| | | |k|p| | | |
| | | | | |Q| | |
| | | |p| | | |P|
|r| |x| | | |k| |
I understand how to transform the units on the board into x and y coordinates, and the mathematical operations of the pieces on the board (check pawns on +7 and +9, check rooks on ...-2, -1, +1,+2... and ...-16, -8, +8, +16..., but i can't translate this to python, or stop the check if it hits another piece or before it goes "past" the board and loops around again. Here is my code so far, but nothing really working correctly:
def white_check(coded_position):
w_king = coded_position.find("x")
w_king_x = w_king%8
w_king_y = w_king//8
result = False
print(w_king)
# This doesn't work if king is on x = 0 or 8
# Returns true if pawn checks
# if coded_position[w_king+7] == "P" or coded_position[w_king+9] == "P":
#result = True
# try using for loops and going up 1 / 8 at a time and trying each case for rooks / and bishops
# checks right side for rooks
for i in range(w_king,w_king-w_king_x+8):
if coded_position[i] != "*" and coded_position[i] != "K":
result = False
break
if coded_position[i] == "K":
result = True
# checks left side for rooks
for i in range(w_king,w_king-w_king_x,-1):
if coded_position[i] != "*" and coded_position[i] != "K":
result = False
break
if coded_position[i] == "K":
result = True
print(result)
return result
I think I am really over-complicating this, is there anything obvious that I am missing?
I'm not going to give you code (right now at least), but I can give some steps.
Currently looks like you are storing everything as an index on the long input line. This makes it harder, so step one is to represent the board as a list of strings, where is one is 8 long.
The result you want is
board = ["r*x***k*",
"***p***P",
"*****Q**",
"***kp***",
"*K*****p",
"***Pb***",
"*p***PP*",
"**X***KR"]
So now the white king is at board[0][2], and black is moving up the board. Let's call this (0, 2).
Now you need to work out if (0, 2) is in check. The way I would do this is work out for each type of piece, where one could be, to put this position in check. You could store this as a list of differences from the current king location, and for each of those you check if the thing that's in them is the piece that can cause check.
movements = {
"P": [(1,-1), (1,1)],
"R": [*[(0, i), (0, -i), (i, 0), (-i, 0)] for i in range(7)],
}
Here are movements for a pawn and rook. If there is a pawn on (0, 2)+(1, 1) or (0, 2)+(1,-1), and those positions are inside the grid, the pawn is checking (0, 2).
To be inside the grid, both numbers have to be between 0 and 7 inclusive.
For the rook it's a bit more complicated. Positions a rook can attack from are when either the row is the same or the column is the same, that's why there's always a 0 in one of the movements above. With the rook you have the added complexity, that you have to discount anything that's in the way. It might be easier to search everything left of the king, right of, above, and below, and stop searching that when
You reach the edge of the board - not being checked from this direction
You meet a piece that's not a rook - not being checked from this direction by a rook
You meet a rook - you're in check...
I think that's enough to complete this. Remember, you don't have to check every single location, you just need to find one piece that's threatening the king.
Afterwards it's fairly simple to work out if a king is in checkmate, because it's just if a king is in check, and all the places around it are also in check, or invalid places.
I think you are making this more complicated than it is. Here are the steps I would use:
Find the king positions.
Loop through all 8 directions from that location in a nested loop.
When you reach a white piece (uppercase letter), break that direction.
When you reach end of board, break that direction.
If you reach a black piece (lowercase) you have 4 options to check:
a. Piece is orthogonally from king and is a rook
b. Piece is diagonally from king and is a bishop
c. Piece is 1 square away diagonally from king and is a pawn
d. Any direction and piece is a queen
If any of a-d is True, then return True (king is in check). If the entire loop ends, return False.
If you need I can give you the code for my checker.
I have a LED-board which is powered with python.
To turn on the LED's a script has to continue running. But how do I influence the color variables of a running script?
I could read an sql(lite?) db, read the values of a file. Get values of some rest api. Or maybe something completely else.
What is the most neat way to do this?
I'm new to python so feel free to point out I'm completely doing it wrong.
Or provide alternative.
Please do provide sample code which I could follow.
#!/usr/bin/env python
import time
import unicornhat as unicorn
unicorn.set_layout(unicorn.AUTO)
unicorn.rotation(0)
unicorn.brightness(0.3)
count = 0
while True:
# somehow change these color values
# syqlite? reading a file? rest requesting some url? or some signal? how to do this?
color=[
[255,0,0], #red
[255,255,0], #yellow
[0,255,0], #green
[0,255,255], #light blue
[0,0,255], # blue
[255,0,255], #purple
[255,255,255], #white
[0,0,0], #off
]
unicorn.clear()
for y in xrange(8):
# make it "scroll"
row = y+count
if row>7:
row -= 8
for x in xrange(8):
unicorn.set_pixel(y, x, color[row][0], color[row][1], color[row][2])
unicorn.show()
if count == 7:
count = 0
else:
count = count + 1
time.sleep(0.2)
I am connected to a PLC with Python. This PLC, gives alarm conditions in an 8-bit representation. For example:
0110 0010
bit 0 = lights on/off
bit 1 = fan is on/off
bit 2 = alarm on/off
bit 3 = door on/off
...
Each bit tells different conditions.
I want to create a list of conditions and print them together, like: door is on, alarms is off , lights are off, etc..
In the above example there are three different conditions. I want to show them together, all of them can be 1 or 0. How can I associate faults/conditions with bits?
For these types of tasks I like to set up a dictionary with the bits mapped to the nice text representation. Because Python supports binary literals it's quite nicely self-documenting...
Something like:
status_lookup = { 0b00000001 : "Lights",
0b00000010 : "Fan",
0b00000100 : "Alarm",
0b00001000 : "Door"}
Then if you wanted a list of the currently "on" statuses:
bits = 0x0a # or whatever your input value was
currently_on = [status_lookup[i] for i in status_lookup if i & bits]
If you want to join them together in a string:
print("; ".join(currently_on))
As an alternative, if you're using Python 3.4+ you could do something similar using the new enum module:
from enum import IntEnum
class Status(IntEnum):
Lights = 0b00000001
Fan = 0b00000010
Alarm = 0b00000100
Door = 0b00001000
bits = 0x0a
currently_on = [x for x in Status if x & bits]
There are more elegant ways of doing it, but this will get you going:
s = ''
if value & 1:
s += "lights on"
else:
s += "lights off"
if value & 2:
s += ", fan on"
else:
s += ", fan off"
if value & 4:
s += ", alarm on"
else:
s += ", alarm off"
if value & 8:
s += ", door on" #? "door open"?
else:
s += ", door off"
I have 4 LEDs connected to GPIO outputs of a Raspberry Pi. I want to use the argv command so that I can select the LEDs using a simple binary code. For example:
python test.py 1010
This would light up the first and third LEDs in the row. The problem is I don't think Im approaching this correctly. Here is my code so far
from sys import argv
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.OUT)
GPIO.setup(12, GPIO.OUT)
GPIO.setup(13, GPIO.OUT)
GPIO.setup(15, GPIO.OUT)
x, y = argv
print "Script:", x
if y == '0000':
GPIO.output(11, 0)
GPIO.output(12, 0)
GPIO.output(13, 0)
GPIO.output(15, 0)
if y == '0001':
GPIO.output(11, 0)
GPIO.output(12, 0)
GPIO.output(13, 0)
GPIO.output(15, 1)
GPIO.cleanup()
Im leaving out the rest of the combinations so I dont bloat this question. Im running into several syntax issues, but Im wondering if I should just scrap this and go about it another way. Im new and any advice would be appreciated.
It sounds very much like what you really want is to map the pieces of your input string to the values of your calls to GPIO.output. You can do that easily (and with far less code than you currently have) by iterating over the control string:
led_map = {
# This maps each "bit" of your input string to the correct ID for GPIO.
0 : 11,
1 : 12,
2 : 13,
3 : 15
}
for i in xrange(len(y)):
bit = y[i]
GPIO.output(led_map[i], int(bit))
This setup prevents you from having to code each permutation separately (which quickly becomes terrible even with only two or three bits, let alone four or more). Rather than thinking in terms of permutations, you can just consider the bits individually, and perform the appropriate functions on each of them in turn.