|
|
View previous topic :: View next topic |
Author |
Message |
rems
Joined: 02 Feb 2012 Posts: 56
|
|
Posted: Wed Mar 28, 2012 10:46 am |
|
|
John P wrote: | Here's what I think the schematic should be:
http://dl.dropbox.com/u/28291527/sws.jpg
First you would set all 4 outputs low, with the TRIS bits set high (pins hi-Z) and the pullups turned on.
Then set a as the active output, and see if b, c or d go low.
If not, set b as the active output, and see if c or d go low.
If not, set c as the active output, and see if d goes low.
If not, nothing is pressed.
If you had switches to ground as well, you'd insert an initial step where you'd check for anything pulled low while all the TRIS bits were high, before doing anything else.
Actually, if you use connections to Gnd, you could do this job with only 3 pins. 3 switches would connect between the pins (using b, c and d) and 3 would go between each of the pins and Gnd. I don't see why that wouldn't work. |
I appreciate your help. The reason it won't work is because of the nature of my switch. It is a custom made cage that holds a ball bearing. This is tilt switch that will sense motion. It will be mounted inside of a box. When the box is turned 6 different ways, the mcu will activate a switch to open it. The reason I need to use this custom cage is because if I used 6 separate tilt switches, more than one may be activated at a time (due to the physical nature of the box holding them ie. at any time some tilt switches will be in the horizontal position and may turn on or off at will.). If more than one is activated at a time, then my state machine will no longer work. The cage is my solution to this physical dilemma. The cage only allows the ball bearing to be in one of six places at a time. Due to the nature of the cage, it uses 4 custom posts (each one connected to a different pin of mcu) It is these posts that the ball bearing will connect together and thus connect 2 mcu pins together.
I am constrained to using 4 pins, no less and no more.
Why don't I simply make 2 posts gnd and the others as i/p's? Because then I would only make use of 2 possibilities and not the 6 I would like. eg
with a and b connected to mcu as i/p's
and c and d connected to gnd
if a connects to c then one postion sensed
if b connects to d then another position sensed
if a connects to d or b connects to c, then this is no different to mcu than first condition
furthermore, if a connects to b or c connects to d, then mcu wont even know it.
This all being said, I think I understand where you were going with the a, b, c & d. As of now I have been using my "scanface" function repeatedly if the test condition were true. You are telling me to use it when the condition is false. That is a great idea. I think that will help a lot. I'm going to try it right now.
Thanks |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Wed Mar 28, 2012 3:16 pm |
|
|
OK.
Tell us what the six connection patterns are. Call the 4 connections A,B,C,D. Then for the six positions tell us what combinations are connected.
A nice little table....
Realistically it sounds as if the whole scan could be done a lot more simply than you are trying to make it, but the exact sequence needed will depend on the patterns involved.
Best Wishes |
|
|
rems
Joined: 02 Feb 2012 Posts: 56
|
|
Posted: Wed Mar 28, 2012 3:46 pm |
|
|
Ttelmah wrote: | OK.
Tell us what the six connection patterns are. Call the 4 connections A,B,C,D. Then for the six positions tell us what combinations are connected.
A nice little table....
Realistically it sounds as if the whole scan could be done a lot more simply than you are trying to make it, but the exact sequence needed will depend on the patterns involved.
Best Wishes |
I believe you are correct about my solution being simpler than I think.
o/p i/p
1) A - B
2) A - C
3) A - D
4) B - C
5) B - D
6) C - D
Where A is set as o/p= low scanning B, C D ( B, C & D as i/p)
Then B is set as o/p= low scanning C & D ( A, C & D as i/p--including A as i/p even though not scanning for it so as to drop out of state machine if wrong position is sensed.)
Finally C is set as o/p= low scanning D ) A, B & C as i/p)
My cage has 6 positions. It holds a ball-bearing which will sit in one of six positions depending which side of the cage is face up. The cage is made up of 4 main posts. Depending which face of the cage is up will determine where the ball sits. Where the ball sits will determine which posts are connected to each other. That connection pattern is above.
For now, I am simulating my cage with the four pin dip switch as in the schematic.
The following code is a state machine that works for 6 separate switches. I need to merge this state machine with other code to scan the position of the cage.
Code: |
void main()
{
int sw1=1,sw2,sw3,sw4,sw5,sw6; // sw1=1 for starting first condition.
while(true)
{
if(input(butt1)==1&&sw1==1) //if butt 1 = 1 AND sw1=1(which it does to start) then
sw2=1; //Allow second condition
if(input(butt2)==1&&sw2==1)//if butt 2=1 AND sw2=1(it only will if butt 1 was pressed) then
sw3=1; //Allow third condition
if(input(butt3)==1&&sw3==1) //if the three condition are obtained turn the led on.
sw4=1;
if(input(butt4)==1&&sw4==1) //if the three condition are obtained turn the led on.
sw5=1;
if(input(butt5)==1&&sw5==1) //if the three condition are obtained turn the led on.
sw6=1;
if(input(butt6)==1&&sw6==1) //if the three condition are obtained turn the led on.
{
sw6=0;
output_high(led); //turn led on
}
else if(input(butt6)==1&&sw6!=1) //if the algorithm is not executed wait for restart. (if butt 3=1 and sh3 does NOT =1 then )
{
sw1=0; //set all to zero
sw2=0; //which ensures that only the proper combo(sequence) will activate
sw3=0;
sw4=0;
sw5=0;
sw6=0;
}
|
I am continuing to try my best here. I really appreciate all the insight from everyone. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Thu Mar 29, 2012 1:53 am |
|
|
OK.
Assuming A=B0, B=B1, C=B2, D=B3.
Code: |
#use fast_io(b)
int8 scanpins(void) {
int8 port_val;
//Used so I/O operations don't change other pins.
set_tris_b(0b11111110); //B0 only as output
output_low(PIN_B0);
delay_us(2); //Allow a fraction of time for the inputs to reflect output
port_val=(input_b()>>1)|0b11111000;
set_tris_b(0b11111101); //B1 only as output
output_low(PIN_B1);
delay_us(2);
port_val=((input_b()<<1)|0b11100111))&port_val;
set_tris_b(0b11111011);
output_low(PIN_B2);
delay_us(2);
if (input(PIN_B3)==0) bit_clear(port_val,5);
return(port_val);
}
|
Now you just call scanpins, and it returns a byte, with the bottom bit =0 for your first state, next bit=0 for the second etc..
Best Wishes |
|
|
rems
Joined: 02 Feb 2012 Posts: 56
|
|
Posted: Thu Mar 29, 2012 6:57 am |
|
|
I see the beauty in this line " port_val=(input_b()>>1)|0b11111000;"
setting port_val to = whatever port b is = to.
port b will = what ever button is pressed because the ">>1" will shift through the entire port and be "ORED" with the 3 possible button presses.
That is awesome. I tried to do that in so many different ways that now make no sense compared to the sense that this makes.
And now I can just use "port_val" in my state machine.
Do I understand that correctly?
essentially, I needed 6 buttons from 4 and "port_val" comes to the rescue and says" USE ME, I can hold a value for your state machine"
Well sure, Thank you port_val, that would be great.
And Thank you Ttelmah
You actually made my head spin a little bit. I just learned so much more about programming.
using a function to control a variable
using that variable to return a value
using that value for something else
the simplicity of the tris register compared to doing it manually
an application for "bit masking" (I think that's what we call it when ORing a port with something else)
Have I understood properly?
Thank you again for your time. I will not waste the learning experience from this. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Thu Mar 29, 2012 7:50 am |
|
|
I have no idea at all if it'll work!.
It was posted 'off the cuff', based on what you gave about the connections, but you have spotted basically exactly what I was trying to do, and hopefully it'll lead to a good solution.
It shifts in each of the possible patterns from the 'wanted' bits, and combines them into one value it returns.
Since the last output, only returns one bit, it is quicker just to test this, and combine it with the five bits already generated.
I allow a couple of uSec, since the wires will have significant capacitance, and in the real world, you might want to add some 'debounce' to what happens.
Have fun. |
|
|
rems
Joined: 02 Feb 2012 Posts: 56
|
|
Posted: Thu Mar 29, 2012 9:20 am |
|
|
I am having trouble understanding one part of the function
Code: |
#use fast_io(b)
int8 scanfaces(void) {
int8 port_val;
//Used so I/O operations don't change other pins.
set_tris_b(0b11111110); //B0 only as output
output_low(PIN_B0);
delay_us(2); //Allow a fraction of time for the inputs to reflect output
port_val=(input_b()>>1)|0b11111000;
set_tris_b(0b11111101); //B1 only as output
output_low(PIN_B1);
delay_us(2);
port_val=((input_b()<<1)|0b11100111))&port_val;
set_tris_b(0b11111011);
output_low(PIN_B2);
delay_us(2);
if (input(PIN_B3)==0) bit_clear(port_val,5);
return(port_val);
}
|
port_val=((input_b()<<1)|0b11100111))&port_val; // I get an error on this line...
It says I need a semi colon. What is "&port_val" doing?
Likewise, what does "if (input(PIN_B3)==0) bit_clear(port_val,5); " do?
I understand everything except those lines. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Thu Mar 29, 2012 9:48 am |
|
|
port_val, arrives, with all bits '1', _except_ any of the low three bits that already may have found required patterns.
Then the new incoming value (C or D may be low), is masked so only those bits are taken, shifted left one to move them to bits 3 & 4, and then 'anded' with the previous result.
The problem is one too many close brackets. Line should be:
port_val=((input_b()<<1)|0b11100111)&port_val;
if (input(PIN_B3)==0) bit_clear(port_val,5);
Drops bit 5, if the last possible switch pattern is seen.
Best Wishes |
|
|
John P
Joined: 17 Sep 2003 Posts: 331
|
|
Posted: Thu Mar 29, 2012 9:58 am |
|
|
That's not the way I visualized it. I think there should be successive tests for the various conditions, and if a test succeeds, you have your result and you can return from the function.
I've never seen much reason to use the input and output instructions. I just set and test port pins, so that's the way it's written. More untested code, worth what you're paying for it (and a line or two stolen from Ttelmah).
Code: |
#use fast_io(b)
int8 scanfaces(void) {
trisb |= 0b00011110;
bit_clear(portb, 1);
bit_clear(trisb, 1);
delay_us(2); //Allow a fraction of time for the inputs to reflect output
if (!bit_test(portb, 2))
return(1);
if (!bit_test(portb, 3))
return(2);
if (!bit_test(portb, 4))
return(3);
bit_clear(portb, 2);
bit_set(trisb, 1);
bit_clear(trisb, 2);
delay_us(2); //Allow a fraction of time for the inputs to reflect output
if (!bit_test(portb, 3))
return(4);
if (!bit_test(portb, 4))
return(5);
bit_clear(portb, 3);
bit_set(trisb, 2);
bit_clear(trisb, 3);
delay_us(2); //Allow a fraction of time for the inputs to reflect output
if (!bit_test(portb, 4))
return(6);
return(0);
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Thu Mar 29, 2012 10:06 am |
|
|
Yes, a good alternative, and gives much easier to use output.
However the first bit that needs to be low is B0, not B1. Just needs a fractional 'tweak' in the logic.
Best Wishes |
|
|
rems
Joined: 02 Feb 2012 Posts: 56
|
|
Posted: Thu Mar 29, 2012 10:33 am |
|
|
I appreciate all the suggestions and insight. I am now trying to do something with all his information.
Thanks to both of you |
|
|
John P
Joined: 17 Sep 2003 Posts: 331
|
|
Posted: Thu Mar 29, 2012 10:44 am |
|
|
I used portb 1-4 because that's the way Rems did it in his first message. |
|
|
rems
Joined: 02 Feb 2012 Posts: 56
|
|
Posted: Thu Mar 29, 2012 10:47 am |
|
|
That's great..everything has been a great help |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|