0

I'm a student working on a project for my college's chemistry department. Last year I wrote a C++ program to control a picomotor stage and have it communicate with a force pressure sensor, moving the stage up and down until it touched the sensor. I used the DLL the company provided to write this program. It took me a while, but I got everything to work.

This year, I'm incorporating a second stage to the program and updating the entire program into a GUI using C#. The second stage and the force sensor only provide DLLs that work with C#, whereas the old stage was meant for C++. I was able to get all three to work in the new C# GUI program, it's all almost done save this problem:

In the old program, I was able to determine if the motors on the stage were moving via this function:

#define MOTOR_MOVING 0x01 byte isMoving = LdcnGetStat(pico_addr) & MOTOR_MOVING; 

byte LdcnGetStat(byte address) returns the last status byte of the module at the given address. According to the instructional manual I have, bit 0 is suppose to be set when the motor is moving. So, if I test it in my C++ program, using a bool variable, isMoving is 0 when the motors aren't moving, and 1 when they are, and it promptly returns to 0 after the motors stop moving. Works fine.

But in C#, I'm having problems incorporating this.

byte isMoving = LdcnGetStat(pico_addr) & MOTOR_MOVING; 

doesn't work, I have to do some explicit casting. So I changed it to this:

bool isMoving = Convert.ToBoolean(LdcnGetStat(pico_addr) & Convert.ToBoolean(MOTOR_MOVING); 

That doesn't give me an error, but LdcnGetStat(pico_addr) will always return "true" because it's never 0. If I just test the values that LdcnGetStat() spits out, when the motor is not moving, it returns 28, when it's moving, it return s 98. If I test again post-move, it returns 23.

Is there a proper way to deal with this in C#? I'm thinking of checking to see if LdcnGetStat returns the right numerical value, but that doesn't seem like the right way to handle it, especially since the values seem to change post-move.

Thanks

2 Answers 2

2

Conditionals in C/C++ effectively compile down to comparisons against zero. So the expression LdcnGetStat(pico_addr) & MOTOR_MOVING is equivalent to (LdcnGetStat(pico_addr) & MOTOR_MOVING) != 0. In C# however, conditionals are done with actual bools, so you can only use the second expression.

I can explain more if you need me to.

Sign up to request clarification or add additional context in comments.

Comments

1

I think what you're looking for is:

bool isMoving = (LdcnGetStat(pico_addr) & MOTOR_MOVING) != 0; 

The expression:

byte isMoving = LdcnGetStat(pico_addr) & MOTOR_MOVING; 

Probably gives you an error about implicitly converting int to byte. You have to cast it:

byte isMoving = (byte)(LdcnGetStat(pico_addr) & MOTOR_MOVING); 

In that case, isMoving will be equal to 0x01 when the motor is moving.

6 Comments

It really irks me that the & operator seems to assume the result type is the longer of its operands. If either of the operands will fit in an unsigned type, there is no way the result can fail to fit within that type. The | operator generally should assume the result type to be the longer of its operands, but perhaps with an exception if one of them is a negative constant (in which case the result is guaranteed to fit in any type that could hold that constant).
BTW, I also really wish that C# had a convenient operator or method defined on int and enum types which would test whether the "bitwise and" of two integer values was non-zero. In C, I would say if (myFlags & THIS_FLAG) do_something();. I don't think that having to write it as if ((myFlags & THIS_FLAG) != 0) do_something();` particularly improves legibility.
@supercat: Actually, the bitwise and even arithmetic operators on byte return Int32. For example, byte b3 = b1 & b2; will give an error even when b1 and b2 are declared as byte. byte b3 = b1 + b2 will give the same error. On the other issue, I'm ambivalent. Probably because I did a lot of work in Pascal before C#.
Requiring a narrowing cast for byte1 = byte2 and byte3 is obnoxious, IMHO. I also really dislike the notion that float to double conversions are widening, but conversions the other way are not. If anything, double to float conversions should be the widening ones, since casting an int64 to double and then to float will either yield the float value which is closest to the original value, or one of two values that are essentially equally good. It's possible that the cast to float may cause distinct values to become indistinguishable, but values which remain distinct...
...will rank correctly with regard to int64 values that were cast directly to float. By contrast, converting int64 values to float and then double only requires "widening" conversions, but most of the resulting double values will be wrong. Further, given double d=UInt64.MaxValue; float f=UInt64.MaxValue;, which is larger, f*f or Math.Pow(d,15)? Each expressions will yield the best representation in its type for the correct mathematical value. Which is more correct--comparison as float, or as double?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.