Problems reading io pins as a group

I’m trying to read a group of 4 io pins to get a numerical value as the status of an outboard device. I’m trying it out using the edubot controller so I’m looking at io pins 1-4 which translates to PortA bits 0-3. I was trying to do the following:

sensor_value = (PORTA & 0x0f);

iIt compiles ok, but the result is always 0. I double-checked that I have set the pins to INPUT, and have set the number of analog channels to NO_ANALOG. sensor_value is an unsigned char.

I also tried reading the pins individually as rc_dit_in01 through rc_dig_in04 and got the proper values, so I know the hardware is ok. Anyone know what gives here? Any help would be appreciated.

On another note, I often have problems getting the edubot to take to a program upload. Sometimes it takes 2 or 3 tries before it will run. And it won’t hold through a power-down. Do I just have a bad machine? this is true for a fresh load of the Default Code as well as my own, and the same behavior with both versions of the IFI Loader.

worse case scenario, you could always just do this:


portAvalue = (rc_dig_in01 << 3) & (rc_dig_in02 << 2) & (rc_dig_in03 << 1) & rc_dig_in04;

We’re doing the same thing with a BCD switch.

I tested this on the EDU controller and it worked.
With unconnected pins you get 0x0F
With dig I/O 1 signal-to-gnd you get 0x0E
With dig I/O 1&2 connected you get 0x0C

 
in user_routines.c, User_Initialization()
 
Set_Number_of_Analog_Channels(NO_ANALOG);	 /* See ifi_aliases.h */
 
IO1 = IO2 = INPUT;	 
IO3 = IO4 = IO5 = INPUT;
IO6 = IO8 = IO10 = INPUT; 
 
// IO3 = IO4 = OUTPUT;
// IO5 = IO7 = IO9 = OUTPUT; 
 
IO7 = IO9 = OUTPUT; 
IO11 = IO13 = IO15 = OUTPUT; 
 
// rc_dig_out03 = rc_dig_out04 = 0;
// rc_dig_out05 = 0;
 
 
in user_routines.c, Process_Data_From_Master_uP()
 
	PrintString((char *) "PORTA = ");
	PrintByte(PORTA & 0x0f);
 

Shouldn’t it be


portAvalue = (rc_dig_in01 << 3) + (rc_dig_in02 << 2) + (rc_dig_in03 << 1) + rc_dig_in04;

[EDIT]
actually it should be


portAvalue = (rc_dig_in04 << 3) + (rc_dig_in03 << 2) + (rc_dig_in02 << 1) + rc_dig_in01;

since rc_dig_in01 is in bit0 (least significant) of PORTA
[/EDIT]

whichever - it depends on what direction you hooked the device up in :slight_smile:

The point was to make the routine as fast as possible by not taking the time and space to read each line individually. I’ve already got that to work, but it makes for messy code.

Mark’s post has the greatest similarity to mine in code structure. I wonder why PrintByte worked for him, but using PORTA to transfer a value to another variable doesn’t seem to?

Steve

All around, False means closed (On) True means open (off).

You can add, or just OR it (| I think), Which makes more sense to me. You’re merging bits, not adding values.

the way it works out, either will work. you’re right though, bitwise OR is probably faster.

The problem is that you are using bitwise and(&), you should be using logical AND(&&).
the difference is this:

“&” (bitwise and) ANDs each corresponding bit individually.
11110000 & 11111111 = 11110000
10101010 & 10101010 = 10101010

“&&” (logical and) ANDs the entire word at a time. (it will only be true if the two arguements are the same.)
11110000 && 11111111 = 00000000
10101010 && 10101010 = 11111111

I don’t believe that’s what he’s trying to do - he’s using the & to mask off the four bits he’s trying to read, which is correct.

Technically bit0 would be the MSB, because of the endianness.

Btw jsut wxactly what are you trying to do? mask off bits or compare values?

I originally ran:


unsigned char port_a;
 
port_a = PORTA & 0x0f;  /* mask off unused bits */
PrintByte(port_a);

to more closely emulate what you were doing. I simplified it to the minimum number of lines before posting.
This works as well, so it isn’t an assignment problem.

I believe that is wrong - && returns 1 if both arguments are true (non-zero). This is because the logical and works on two boolean values, and returns a third. Anything except 0 is treated as true in C.

steven is correct - anything with a set bit qualifies as the “true” state, the only false state being 0.

you cannot really show how the boolean && works using bits - it’s a logical operator, versus the bitwise operator &.

Ahh… I found the problem…

Mark, if you notice, tested his code on the EDU controller, where PORTA0-3, is bits 1-4

However on the fullsize RC, bits1-4 are PORTB2-5. Infact PORTA isn’t even used on the outputs at all.

The full size RC uses parts of Ports B,H,& J
The EDU controller uses parts of Ports A,F,H.

And they actually use different halves of Port H, so I really would suggest against using the port names directly.

Hope this helps…

emusteve is doing his testing using the EDU controller, so that isn’t it.
That is a good caution to others who might be reading this thread though.

He may have discovered his problem by now though.

Yes, YES! I got it to work last night.

Thanks for all the comments and help! As it turns out, the original statement was working, the problem was apparentlywith the way I was trying to view the result through a printf statement. Still not sure what I was doing wrong there, as when I substituted a pwm variable I would get a real number. In frustration, I ended up echoing the result to a set of output pins, and there it was!

For those who are curious, I am using the “& 0x0f” as a mask to keep only the lower 4 bits. What I’m doing is implementing an outboard i/o expansion scheme so we can read numerical values from outboard hardware. PORTA will translate to PORTH on the FRC. For those who are interested, e-mail me directly and I’ll be happy to share schematics and code (once I get the code finished). If there is enough interest, I’ll post it as a white paper.

Thanks Again,
Steve Martin
smartin@emich.edu