4

First off, this will probably be long winded so bear with me and sorry in advance if my description may not be correctly worded, I wasn't sure how to explain it.

I am new here and new to programming(except for a high school course in Pascal and a college course in C++, both many moons ago.) I am currently teaching myself Python and trying to code a small project for a problem I am having at work. Surprisingly, I am faring pretty well so far with my project and pretty much have it working but I am trying to make it slightly better. Basically I am taking a reading from the serial port, stripping the carriage return from said reading, then I try to match my serial output to a record in a SQL database table and depending on the results perform necessary action. I have all of that working reasonably well but I have run into an issue which I am not sure how to solve.

I am using "ctypes" to interface with a DLL file provided by a hardware manufacturer. The hardware in question is a digital I/O card which has 8 digital inputs and 8 relay outputs. The DLL allows me to read the status of the inputs and outputs and also I can control the outputs(turn relays on and off). Basically this is done like so:

mydll = cdll.LoadLibrary("acces32.dll")
input_status = mydll.InPortB(0xDC7C+1)

Where DC7C is the base address of the card in HEX, and the +1 is how the input status is returned. The input status is returned as a decimal from 0 - 255, which when converted to binary represents the status of the 8 inputs, i.e.:

0 0 0 0 0 0 0 0 - decimal=0 - all inputs off
0 0 0 0 0 0 0 1 - decimal=1 - input 1 on
1 0 0 0 0 0 0 1 - decimal=129 - input 8 and 1 on
etc, etc, etc

MY equipment is currently using the first two inputs at the moment, so my possible outcomes are 0, 1, 2 or 3. But it would be nice to account for all possibilities but I am not wrapping my head math involved to easily determine which inputs are on or off. What I am trying to accomplish is to monitor input one's status to see if it is off or on(0 or 1). Here is my current code snippet:

def input():
    mydll = cdll.LoadLibrary("acces32.dll")
    input_status = mydll.InPortB(0xDC7C+1)

    while input_status != 1 or 3:
        arming = mydll.InPortB(0xDC7C+1)
        print "System is idle" #input 1 off
        #added the sleep as without it was using alot of CPU time
        time.sleep(0.5)
    print "Waiting for user input..." # then call bar_code function
    #calls another function which reads data from a serial connected bar code reader
    bar_code_reader()

While this more or less works it very obviously is not ideal and doesn't account for what happens if the state of input 1 changes after the "bar_code_reader" function is run. So more or less what is the proper way to achieve a constant monitoring of these inputs so even if I am in bar_code_reader mode and then input 1 changes to off the program will go back to a "System is idle state".

Secondly I am not accounting for all possible values of "input_status" where input 1 is on, currently I am just accounting for the use of two inputs so I know the value will be 0, 1, 2 or 3 but if I happen to use other inputs in the future I should account for this now I suppose. Is there a simple way to account for all the possible values when input 1 is on? I am sure there is some simple math for this that I am forgetting. I was thinking of converting the decimal output to binary and checking that way but wasn't sure if that was the best way to go about it. I did figure out how to convert to binary but that's as far as I went with it.

Basically to sum it up:

While input 1 is 0 then the system remains idle, While input 1 is 1 then proceed with gathering user input(in the form of a bar code) but if input 1 returns to 0 return back to an idle state.

If you need to see more code or whatever please let me know. I know this was long and I am probably doing everything backwards....

Thanks in advance,

Kevin

8
  • 1
    input_status != 1 or 3 is always true Commented Mar 8, 2012 at 19:55
  • it should be while input_status != 1 or input_status != 3: Commented Mar 8, 2012 at 20:00
  • bar_code_reader() is a function: it does something. It's not a "mode" that you can switch out of! Are you saying you want to interrupt it if the mode changes halfway? That's complicated, because it means you need to do two things at once, which leads you to Python's threading or multiprocessing libraries. Commented Mar 8, 2012 at 20:04
  • @vikki actually it should be while input_status not in (1,3). Commented Mar 8, 2012 at 20:04
  • @ J.F. Sebastien Yes I mistakenly added the 3 in != statement without fully thinking about it. My code actually just had the 1 in there originally. Then I had a doh! moment realizing it would always be true. I came here to adjust it accordingly. Rookie mistake, I feel like a bit of a tool now.... Commented Mar 8, 2012 at 20:44

3 Answers 3

2

Sounds like you have two issues -- how to know if input 1 is on, and aborting bar_code_reader if input 1 goes off.

The first is easy: input_status & 1 will evaluate to True if that first bit is on, False otherwise.

The second is a little trickier.

Under normal circumstances, will bit 0 still be on ofter bar_code_reader() successfully returns?

  • If yes, just check the bit after attempting to read the barcode and if it is still on you have good data.

  • If no, then you'll have to put the check in bar_code_reader itself (possibly more than once), and then have bar_code_reader return a good value when bit 0 stayed on the whole time, and None otherwise. (You can use any sentinal besides None, it's just the most common.)

Oh, and so you don't have to remember which bit field equals what number:

BIT0 = 2 ** 0
BIT1 = 2 ** 1
BIT2 = 2 ** 2
BIT3 = 2 ** 3
BIT4 = 2 ** 4
BIT5 = 2 ** 5
BIT6 = 2 ** 6
BIT7 = 2 ** 7
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot for the answers. They are most helpful. To answer your questions. Yes under normal circumstances bit 0 should be on after bar_code_reader() finishes but there are instances where it may not be or where bit 0 may go on and bar_code_reader is not used during the duration and then bit 0 will be off again so I am trying to account for those instances.
2

To check whether input 1 is on you could input_status & 0x1 if input_status is an integer.

3 Comments

Thanks. this sounds super simple to implement. How about for example if I wanted to monitor input 4 instead(just to cover any future needs.)
@ouldsmobile: Change the bitmask
@ouldsmobile: For readability you could use binary literals: input_status & 0b00001000 or in general ison = lambda status, n: bool(status & (1 << (n-1)))
1

Given that you only have 8 possible bits, I would suggest the easiest thing to do is just to bitwise and and or operations with masks you format as binary integers in your code (ex 0b00000001). You could set up a series of values if you wanted too, like:

inputs = []
for i in range(0, 8):
    input[i] = 2**i

then use inputs[i] in bitwise operations instead of an explicit value.

As to your other issue, you'd have to handle breaking out of your scanning method inside of the scanning method, as others have pointed out. You'd put the whole mess in a while True loop, then have if inputs[0] & input_status: bar_code_reader() in the body of the loop.

1 Comment

I am now reading up on bitwise operations. Might come in handy. Thanks for pointing me in the right direction.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.