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

KeyCode door problem - PIC16F628a

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Somor



Joined: 18 Dec 2014
Posts: 12

View user's profile Send private message

KeyCode door problem - PIC16F628a
PostPosted: Fri Apr 10, 2015 10:43 am     Reply with quote

I'm trying to make KeyCode door with key that is chosen manually with DIP-Switches - 9.
Here is the scheme of my project:
http://imagizer.imageshack.us/a/img673/7744/QyOV6M.png

With 4 pieces of DIP-Switch - 9 I'm making the valid key that is 4 digits. The demultiplexer helps PIC reading the key and when the job is done it turns off demultiplexer's power (it's wired to RA3). Then with keypad user can enter the key and if the combination is right green LED IS ON. If the led is already ON on next successful entry it powers off the led. On the scheme LED is not connected, but it should be on RA7.

Here is my program's source:

Code:
int8 pressed[] = {10,10,10,10};      //Съхранява бутоните, които са натиснати
int8 key[] = {10,10,10,10};         // съхранява ключа
int8 row = 10;                       //редове
int8 column = 0;                    // колони
int8 num = 0;                      // колко бутона са натиснати
int8 demux[]={8,9,10,11};           //числа отговарящи на таблицата на истиност
                                    // на демултиплексора + 1 бит за захранване
                                    // на демултилексора

void out()                           
{

if (column==0) output_b(6);          // подава нула само на един ред
if (column==1) output_b(5);          //на останалите редове - единица
if (column==2) output_b(3);
 
}
 
void read()                           //четене на редовете
{
  int i;
  int in = 0;
  for (i=0;i<4;i++)
  {
    in = 8*6 + 3 + i;               //за извеждане на високо/ниско ниво на даден пин, използвам адреса на пина.
    if (input(in)==0)              //проверка за нула на дадения ред
    {
      delay_ms(32);               //елиминиране на претрепвания
      if (input(in)==0)           //запаметяване на числото
      {
      while(input(in)==0)
      {
        row = i;                 
      }
      }
    }
  }
}

void press()
{
   if(num<4)
   {
   
   pressed[num] = (column+1) + 3*row;              //формула за изчисляване позицията на бутона
   if(pressed[num] == 11) pressed[num] = 0;         //за нулата има изключение
   num++;
    }
}

void valid()                                     //функция за отключване/заключване
{
  int i;
  int sum=0;
  for(i=0;i<4;i++)
  {
    sum = key[i] - pressed[i];
    pressed[i]=10;
  }
  if (sum == 0) output_toggle(47);           //ако на изходния пин имаме 1 ще стане нула и обратно.
  num = 0;
}

void start()                               //ф-ция за четене на DIP-switches
{
   
int8 i,inb,ina,outa;
for(num=0;num<4;num++)                    //4 цифри
{
    outa = demux[num];                     //управление на демултиплексора
    output_a(outa);
    delay_ms(10);
  for(i=0;i<8;i++)
  {
   
   inb = 6*8 + i;
   if(input(inb)==0)
     {
        delay_ms(32);
        if(input(inb) == 0) key[num] = i;
     }
   }
   if(key[num] == 10)
   {
   
     ina = 46;
     if(input(ina)==0)
     {
       delay_ms(32);
       if(input(ina)==0) key[num] = 8;
     }
     
   }
     delay_ms(10);
  }
  num = 0;
  output_low(PIN_A3);
}
void main()
{
   setup_oscillator(OSC_4MHZ);
   port_b_pullups(0xFF);        //вътрешните пул-ъп резистори
   set_tris_a(0x40);
   SET_TRIS_B(0xFF);
   delay_ms(10);
   start();
   delay_ms(10);
   SET_TRIS_B(0xF8);
   set_tris_a(0x00);
   output_a(0);
   delay_ms(10);
   
   while(true)
   {
     if(num<4)
     {
       for(column=0;column<3;column++)
       {
         out();
         read();
         if(row!=10)
         {
          press();
          row=10;
         }
       }
     
     }
    else valid();
   
     row = 10;
   
         
   }
     
}


On PROTEUS it works, but on my real stuff not... as I played a little bit with the simulation I discovered that if my key is 0,2,7,8 it doesn't matter what button i will press when the last button is 8.
So let me clear this:
My combination is 0,2,7,8. If i enter that digits - it works
if I also try 8,8,8,8 - works
0248 - works, and so on.
that's my problem.

EDIT: I forgot to mention that RA3 is connected to the VDD of 74HC139, so when I use output_low(PIN_A3) and in main() where i set output_a(0); the power of 74HC139 is OFF. I checked with analyzer and multiplexer is working fine.


Last edited by Somor on Fri Apr 10, 2015 11:55 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Fri Apr 10, 2015 10:59 am     Reply with quote

Awful code.

However you don't turn off the multiplexer.

The enable pin needs to go _high_ to disable it. Nowhere in the code is there an output_high(PIN_A3);
Somor



Joined: 18 Dec 2014
Posts: 12

View user's profile Send private message

PostPosted: Fri Apr 10, 2015 11:46 am     Reply with quote

If you turn the enable pin HIGH, than you have on the Outputs High state, that means on PORTB pins you will receive HIGH state and you can/will mess up the keypad things.
PIN A3 is connected to the power of demultiplexer, that means when i use output_a(0); it will power of the IC 74HC139 .
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Fri Apr 10, 2015 12:38 pm     Reply with quote

what is the purpose of SW1,2,3,4 ??

do you EVER set more than ONE switch in the bank CLOSED ??
Somor



Joined: 18 Dec 2014
Posts: 12

View user's profile Send private message

PostPosted: Fri Apr 10, 2015 12:55 pm     Reply with quote

Every SW presents one digit of the key combination. SW1 presents first digit, sw 2 second and so on.
On each SW only one switch is enabled, i.e SW1 - 9 is ON SW 2 - 4 ON, SW3 - 5 ON, SW4, 1 ON

So the key is 8,3,4,0

Any SW is turned on, only when it has LOW STATE coming from the Output of the demultiplexer that it is connected to.

Like If O1 is LOW - SW1 is active
O2 is LOW - SW2 is active
and so on. When each SW is active all others are deactivated they have HIGH state on the demultiplexer's outputs.
PORTB has enabled inner PULL-UPS that means only when 0's are coming to the PINS they will change their state.
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Fri Apr 10, 2015 1:28 pm     Reply with quote

Your circuit shows A3 connected to the enable pin of the multiplexer, not the power pin. We can only base our comments on this.....

However if you are turning the power off, the internal protection diodes in the multiplexer will result in it being powered by any signal you enable on it's outputs. This will result in the lines all becoming active. I'd suspect Isis does not know about this. A switched 'off' circuit will still have all it's electronics present. You need to find a different multiplexer, that does have tri-state outputs, and leave the chip powered, but disable the outputs.

Then the problem being pointed to by Asmboy, is the common one of keyboard decoding, which is why you need diodes on the lines. If two switches are made, they short the two lines involved together, preventing any other switch using the same lines from being decoded correctly.
Somor



Joined: 18 Dec 2014
Posts: 12

View user's profile Send private message

PostPosted: Fri Apr 10, 2015 4:22 pm     Reply with quote

A3 on the scheme i uploaded is not connect RA0 --> A1 ; RA1 -->B1 ; RA2--> Enable, however RA3 I connect with Demultiplexer's VDD.
So if i want to keep that demultiplexer if I put diodes on the outputs like:



O1 ----Anode Cathode ---- SW1
O2 ----Anode Cathode ---- SW2
and etc. Would that work?
Or if it's not solution i will search for 3-state demultiplexer.
About the KeyPad decoding i would be happy if you see my decoding algorithm and give me advice or if you can see some error.
I thought that the problem is in the verify(), where i substract the key[] elements with pressed[] elements and if sum is zero i can output_toggle. I tried to use opposite procedure if pressed[i] == key[i] then sum++; and
if sum != 0 output_toggle, but no effect.
I still think that this might be hardware problem, but i don't exclude that my source has bugs.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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