CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

State machine problem
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
rems



Joined: 02 Feb 2012
Posts: 56

View user's profile Send private message

State machine problem
PostPosted: Tue Mar 27, 2012 7:33 pm     Reply with quote

I am using a PIC16F887, MPLAB and CCS C.

I am making a combination switch that senses the combo via motion. Due to the nature of certain physical aspects, I need to treat 4 pins as 6 switches. This is why I have the function "scanfaces". It allows me to switch what is i/p and o/p. Basically, I make one pin o/p set low and the other 3 pins are i/p's. Then I make a different pin o/p set low with the rest as i/p's.

I have had luck with the state machine in the bottom of the program when I used 6 different switches. In that case, I used 6 pins, all as i/p's and it worked fine. But now, I'm trying to merge the "scanfaces" function with the state machine and am having a lot of difficulty. I want the led to turn on only when the combo is sensed. As you can see, pins B3 & B4 are shared by different o/p configurations and I think this is part of the problem. I need a way to make them more unique.
Does anyone have any ideas?

Here is my code
Code:

#include <16F887.h>
#fuses INTRC_IO //use internal oscillator
#fuses NOWDT //No watch dog timer
#fuses PUT//
#fuses BROWNOUT//reset chip if voltage falls
#fuses MCLR//master clear enabled
#fuses NOLVP
#use delay(clock=8000000)

#define resbutt pin_B5 //restart 'c' condition
#define led pin_D4   //if condition is obtained turn on led
#define sleepbutt pin_D7


/*****************************************************************Declare a function that will SCAN the custom switch*******************/

 void scanfaces (void)

   
    OUTPUT_low(pin_B1);     // Configuring cage to sense faces
   
    input(pin_B2);
    input(pin_B3);
    input(pin_B4);

    OUTPUT_low(pin_B2);     // Configuring cage to sense second 3 i/p's
    input(pin_B3);
    input(pin_B4);
   
    OUTPUT_low(pin_B3);    // Configuring cage to sense last i/p
    input(pin_B4);
   
}


void main()
{
int sh1=1,sh2,sh3,sh4,sh5,sh6;   // sh1=1 for starting first condition.

 
 while(1){

 scanfaces();


 
   
   if(!input(pin_B2)==1&&sh1==1) //if pin_B2 = 0 AND sh1=1(which it does to start) then
        sh2=1; //Allow second condition
        scanfaces();
                             

   if(!input(pin_B3)==1&&sh2==1)//if pin_B3=0 AND sh2=1(it only will if butt 1 was pressed) then
        sh3=1; //Allow third condition
        scanfaces();
         
   if(!input(pin_B4)==1&&sh3==1) 
        sh4=1;
        scanfaces();

   if(!input(pin_B3)==1&&sh4==1)   
        sh5=1;
        scanfaces();
       
   if(!input(pin_B4)==1&&sh5==1)   
        sh6=1;
        scanfaces();

   if(!input(pin_B4)==1&&sh6==1)   //if the six condition are obtained turn the led on.
      {
      sh6=0;
      output_high(led); //turn led on
      scanfaces();
      }


   else if(!input(pin_B4)==1&&sh6!=1) //if the algorithm is not executed wait for restart. (if pin_B4=0 and sh6 does NOT =1 then )
      {
       sh1=0; //set all to zero
       sh2=0; //which ensures that only the proper combo(sequence) will activate
       sh3=0;
       sh4=0;
       sh5=0;
       sh6=0;
      }
         
   if(input(resbutt)==1) //restart entering sequence of buttons. if reset button pushed
      {
      output_low(led); //led will turn off
      sh1=1;   //allow condition start again
      }
}   
}
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed Mar 28, 2012 2:25 am     Reply with quote

I don't get what you are trying to do.

Some kind of schematic might help.

Mike
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Wed Mar 28, 2012 2:59 am     Reply with quote

Yes, a circuit of the scanning would help.
However just looking at the code, can't see that 'scanfaces' is ever going to work. As it stands, it sets B1, 2, and 3 _all low_, and leaves just B4 as an input.
You need to remember that things are sequential, and happen very fast on a computer. So it starts setting B1 low, then setting B2, B3, and B4 as inputs (actually this can all be done with one instruction - this is exactly what the TRIS statement is for.....). Then only a couple of uSec latter B2 is set as an output, with B3 and B4, once again set as inputs (they already are - things are remembered....), then B3 is set as an output, and B4, once again set as input. At this point, B1, B2, and B3, are _all_ driving low, and only B4 is an input.
Then the routine is existed, and the first test done. At this, B2, is changed to being an input, and immediately read. probably won't work, since it takes _time_ for signals to change.
The similar pattern is then repeated for the other pins....

As a comment, the logic of the code layout also doesn't help understanding. After the 'if' tests, scanfaces is indented, which is normally used as a signe to say 'this is only executed if the test is true', but in fact it is only the single line after the 'if' that if dependant on the test.

It is also 'odd', that you drive the lines 'low', yet seem to test for 'high' as a button made combination.

Post a circuit.

Best Wishes
temtronic



Joined: 01 Jul 2010
Posts: 9226
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Mar 28, 2012 5:23 am     Reply with quote

You should lookup 'Charlieplexing'....though most use it for outputs, I've used it for input as well.You can get 6 inputs from 3 pins.
John P



Joined: 17 Sep 2003
Posts: 331

View user's profile Send private message

PostPosted: Wed Mar 28, 2012 9:03 am     Reply with quote

Seems pretty trivial. You can get 4 switches where (I'm calling the lines a, b, c and d, nothing to do with port names) a and b cross c and d, and 2 more where a could cross b and c could cross d. Then you can get 4 more where each of a-d can connect to Gnd. If you use pins with internal pullups, there's no need for any external components except the switches. If you can't trust the user to avoid pushing multiple switches, you might need to test for that.

Wouldn't Charlieplexing need diodes? There's no point in using added parts.
rems



Joined: 02 Feb 2012
Posts: 56

View user's profile Send private message

PostPosted: Wed Mar 28, 2012 9:04 am     Reply with quote

Ttelmah,

Thank you, I completely understand your pointers. I was afraid "scanfaces" was happening so fast that it wasn't working. Wow, I didn't realize that the first line after the if is the only one valid for the test condition. That explains a lot. Since my original post, I actually split up "scanfaces" into 3 separate functions.
Code:

 void scanfaces1 (void)

   
    OUTPUT_low(pin_B1);     // Configuring cage to sense faces
   
    input(pin_B2);
    input(pin_B3);
    input(pin_B4);
}   
void scanfaces2 (void)
{
    OUTPUT_low(pin_B2);     // Configuring cage to sense second 3 i/p's
    input(pin_B3);
    input(pin_B4);

void scanfaces3 (void)
{
    OUTPUT_low(pin_B3);    // Configuring cage to sense last i/p
    input(pin_B4);
   
}

My goal is to separate the function to make it so B4 isn't the only i/p essentially. Then I used the following if statements to operate them
Code:

void main()
{
int sh1=1,sh2,sh3,sh4,sh5,sh6;   // sh1=1 for starting first condition.

scanfaces1();

while(1){ 
   
   if(!input(pin_B2)==1&&sh1==1)  //if pin_B2 = 0 AND sh1=1(which it does to start) then
        sh2=1; //Allow second condition
        scanfaces1();

   if(!input(pin_B3)==1&&sh2==1)//if pin_B3=0 AND sh2=1(it only will if butt 1 was pressed) then
        sh3=1; //Allow third condition
       
   if(!input(pin_B4)==1&&sh3==1) 
        sh4=1;
        output_high(pin_D2);
        scanfaces2();

 
   if(!input(pin_B3)==1&&sh4==1) { 
        sh5=1;
        output_high(pin_D3);
        scanfaces2();
}
       
   if(!input(pin_B4)==1&&sh5==1){   
        sh6=1;
        output_low(pin_C4);
        scanfaces3();
}

   if(!input(pin_B4)==1&&sh6==1)   //if the six condition are obtained turn the led on.
      {
       sh6=0;
      output_high(pin_C5);
      scanfaces3();
     
      }


   else if(!input(pin_B4)==1&&sh6!=1) //if the algorithm is not executed wait for restart. (if pin_B4=0 and sh6 does NOT =1 then )
      {
       sh1=0; //set all to zero
       sh2=0; //which ensures that only the proper combo(sequence) will activate
       sh3=0;
       sh4=0;
       sh5=0;
       sh6=0;
      }

Can I simply put multiple statements on the same line that follows the if statement separated by a comma? Or how can I execute multiple "tasks" with on if statement test?

As far as I know, I do test for "low". The "!" does that. But maybe you are referring to the fact that I say " ==1" after. I was experimenting with "==0" and it didn't work. Maybe that part isn't needed at all? After my experiments, I concluded that "==1" basically says "if true" and "==0" says "if false". I'm not sure, but I'll try to take it out.


I don't know how to post the circuit, so Ill draw it below

code:

Code:

#include16F887.h
__________
          |
          |--B1----|------10k----------------------VCC
          |        |
          |        |
          |--B2----|------|------10K---------------VCC
   mcu    |        |      |
          |        |      |
          |--B3----|------|------|------10K--------VCC
          |        |      |      |
          |        |      |      |
          |--B4----|------|------|------|---10K----VCC
          |        |      |      |      |
          |        |      |      |      |
__________|        |      |      |      |
                   |      |      |      |
                   |      |      |      |
                   \      \      \      \
                    \      \      \      \
                     \      \      \      \
                   |      |      |      |
              _____1______2______3______4_____     
                         

That is the best I can do with my keyboard. The "10k's" are external pull-ups. I know I can use internal but that will be after I figure everything else out. The weird looking thing at the bottom is a 4 pin dip switch with one complete side shorted together. This is how I connect 2 mcu pins together at a time to "sense". My intention is that for eg. in the first cycle, "1" will be close when "B1" is set as o/p=low. at the same time, pins_2, 3 & 4 will be i/p's. Now when I close either "2, 3 or 4" on the switch, the mcu can sense what is happening. This is how I am using four pins of mcu to "see" 6 switches.
Does this help?
I appreciate the advice you have already given. Any additional direction would be fantastic.
Thanks again


Last edited by rems on Wed Mar 28, 2012 9:10 am; edited 3 times in total
rems



Joined: 02 Feb 2012
Posts: 56

View user's profile Send private message

PostPosted: Wed Mar 28, 2012 9:06 am     Reply with quote

WOW, my schematic did not look like that when I drew it in the text box before I posted.


++++++++++++++++++++
Schematic fixed by Mod.

How to do:
- Edit text not in forum, but in Windows NotePad (monospaced font).
- Copy & Paste into forum post.
- Enclose in Code Block.
- Preview for correctness.

- Forum Moderator
++++++++++++++++++++
rems



Joined: 02 Feb 2012
Posts: 56

View user's profile Send private message

PostPosted: Wed Mar 28, 2012 9:11 am     Reply with quote

I will look into charlieplexing as well. Thank you for that.
John P



Joined: 17 Sep 2003
Posts: 331

View user's profile Send private message

PostPosted: Wed Mar 28, 2012 9:17 am     Reply with quote

If you want to waste components and your time to wire them up, go ahead.
rems



Joined: 02 Feb 2012
Posts: 56

View user's profile Send private message

PostPosted: Wed Mar 28, 2012 9:30 am     Reply with quote

Here is a link to the schematic.

http://i1249.photobucket.com/albums/hh515/remsphotos/ccs_pic_schematic.jpg
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Wed Mar 28, 2012 9:33 am     Reply with quote

This is where {} brackets come in.
Everything inside a pair of these, is (logically) treated as a single statement. So:
Code:

if (fred)
    this;
that;

//executes 'this' if fred is true, but 'that' is always executed

if (fred) {
    this;
    that;
    theother;
}
more;

//executes 'this', 'that' and 'theother' if fred is true
//then 'more' is always executed

',' has a slightly different meaning. If you have something that uses a value:

if (fred,dick)

or

val=fred,dick;

Then both 'fred', and 'dick' are evaluated, and the value returned by 'dick' is the one used.

Best Wishes
John P



Joined: 17 Sep 2003
Posts: 331

View user's profile Send private message

PostPosted: Wed Mar 28, 2012 9:39 am     Reply with quote

Re the schematic, you can eliminate the resistors. Then consider what you can achieve if you don't just use switches to connect the pins to Gnd, but also to each other.
rems



Joined: 02 Feb 2012
Posts: 56

View user's profile Send private message

PostPosted: Wed Mar 28, 2012 9:49 am     Reply with quote

John P wrote:
Re the schematic, you can eliminate the resistors. Then consider what you can achieve if you don't just use switches to connect the pins to Gnd, but also to each other.


I will be getting rid of the resistors in place of internal pullups. The switch doesn't connect anything to ground. The switch is intended to only connect pins together. It is my hope that one of those pins will be set as o/p=low, while the other three are i/p's. The o/p=low will be there ground. In that scenario, I have 3 "switches" of 6 taken care of. I then need to make a different pin as o/p=low and the rest as i/p's to take care of 2 more switches. Then I need to do it a third and last time to take care of the final "switch". In the end, 4 pins that act as 6 switches.
rems



Joined: 02 Feb 2012
Posts: 56

View user's profile Send private message

PostPosted: Wed Mar 28, 2012 9:51 am     Reply with quote

Ttelmah wrote:
This is where {} brackets come in.
Everything inside a pair of these, is (logically) treated as a single statement. So:
Code:

if (fred)
    this;
that;

//executes 'this' if fred is true, but 'that' is always executed

if (fred) {
    this;
    that;
    theother;
}
more;

//executes 'this', 'that' and 'theother' if fred is true
//then 'more' is always executed

',' has a slightly different meaning. If you have something that uses a value:

if (fred,dick)

or

val=fred,dick;

Then both 'fred', and 'dick' are evaluated, and the value returned by 'dick' is the one used.

Best Wishes


Okay great. That answers other questions I had as well. I get it now. Thank you.
John P



Joined: 17 Sep 2003
Posts: 331

View user's profile Send private message

PostPosted: Wed Mar 28, 2012 10:23 am     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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