SOLVED:Want To Read 24 Nos Switch Through AD7:0 port with RD/ Using ATMEGA162

Go To Last Post
46 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear all ,

I am using external ROM for data reading & as well as want to read the status of 24 nos. of switch through AD7...AD0 port in combination with RD & PD1,PD2,PD3 signals.

i am using 74ls138 as address decoder to read ROM & 3 nos column.

 

i am unable to read back the status of the pressed switch , As Data reading from ROM not proper.

I am using ATMEGA162 as controller.......PLS HELP

Pkdas

Last Edited: Sun. Oct 30, 2016 - 07:31 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Most people would just use a string of 74hc165s. As for your specific problem, you have not given us much information.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Welcome to AVRFreaks.

 

You will have to show us your circuit diagram and software code that you have already written if you expect anyone to be able to help because none of us are skilled in mental telepathy.

 

Ross McKenzie ValuSoft Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It sounds like you may have more then one problem.  Break them down so you can work on them one at a time, create a small program that shows us the problem and post it here, in most cases you will discover the answer while doing this, if not, ask for help.

 

Jim

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear All,

Thanks for your keen interest about my problem.

I am providing the specific code where i am facing problem herewith.Schematics for the Keyboard

 

///  THIS FUNCTION WORKS FINE

unsigned char EXTROM_read_B(unsigned int Rom_Add )//unsigned int Rom_Add
{
PORTD = PORTD |((0<<1)|(0<<2)|(0<<3));
unsigned char *p = (unsigned char *)(OFFSET+Rom_Add);
RomData_B=*p;
return *p;//RomData;
}

 

 

/////  THIS FUNCTION DISTURBING ABOVE PROGRAM  ////

unsigned char EXTROM_read_K(unsigned int Rom_Add )//unsigned int Rom_Add
{
unsigned char *p = (unsigned char *)(OFFSET+Rom_Add);
RomData_K=*p;
return *p;//RomData;
}
//-------------------------------------------------------------------------------------------

void KB_Scan()

    {
    PORTD = (PORTD |(1<<1)|(0<<2)|(0<<3));//
kk:    EXTROM_read_K(0XAAAA);
    if (RomData_K != 0xFF)
        {
        goto kk;//ANY ACTION TO PERFORM
        }    
    }
    

Pkdas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why are you bothering with an external demultiplexer?  You can do this directly with the AVR pins.  By the way, you're currently using 3x8 = 11 pins, when you can use 4x6 and use only 10 pins.  Either way, no need for the 74ls138.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear joeymorin i have no pin in my 162, 

strictly saying i am having PD1,PD2,PD3, RD/, WR/ pins to read KB status in my design.

 

If you watching the External Data ROM circuit you found , i have considered 27c010, & i have used PD0 for A16 of External rom. Another 2 pin for DAC, & another 2 pins for I2C application.

Pkdas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't know what your final application is but that RAM chip will suck up all your I/O. Could you use a serial RAM chip?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear Someguy22

it's ROM not RAM , i used it for External Data Keeping

Pkdas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Serial flash then. It is cheaper and easier than parallel flash.
You really want diodes on your switches or a open collector driver like a 74ls156.

Since you have a shared variable, hopefully you're not calling those functions from an isr or from multiple tasks if you're using a RTOS.

Last Edited: Sun. Dec 13, 2015 - 09:18 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

pkd0057 wrote:

I am using external ROM for data reading & as well as want to read the status of 24 nos. of switch through AD7...AD0 port in combination with RD & PD1,PD2,PD3 signals.

 

If you close more than one switch on any row, you short data pins.

Generally a design avoids switches loading high speed data bus, and a 27LV010A as storage is certainly unusual to see these days.

You can get i2c or SPI memory and SPI comes in QuadSPI if you want faster data rates.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear All ,

I am using this ckt for testing purpose & if success then i can manufacture it commercially, so that i have to find out proper design & availability of all components in the local market. that's why i am not using serial rom as it may not available in the eastern zone of india. 

Pkdas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I haven't studied the schematic closely ... But

Since you have the external databus , you could map some (3x) HC573 into the adress space and connect their individual chipselect's /OE to the HC138 pins.

Then trigger all 573's  with the same LE , you might use the 4'th available HC138' pin

 

Or since you use i2c , maybe use some i2c portecteders

 

/Bingo

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear All ,

I hope i am not getting the switch pressed data due to time mismatch. 

I am getting data from external ROM only when i used wait 2 cycle for bus. & this thing may happening when i am checking the status of switch pressed through the data line.

I hope it is corrupting the address of AD0...AD7 line during Read time. 

Please give your view. 

Pkdas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I had some suggestions in #10. Diodes.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I wonder if you could do something like Charlieplexing by putting diodes in series with the switches.

The largest known prime number: 282589933-1

It's easy to stop breaking the 10th commandment! Break the 8th instead. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear All now i have changed my CKT through port C instead of PORT A , now i am facing another problem--

If i activate col-1 through port D1 & what ever data i am getting through port C is replicating when ever i am activating PORT D2 & PORT D3.

Please give your suggestion.

Pkdas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you added diodes to the pushbuttons?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear Kartman ,

are you suggesting me to add diode against my post given on 31/12/2015 or in generalised you are suggesting?

I have still not used any diode for my given circuit.

Pkdas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You only mention one diode and i have no idea how you have connnected it. My suggestion is one diode for each switch. There should be plenty of examples on the interwebs as it is not a new idea. Computers back from the 1950's used the technique extensively.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am not follow answer but like you make the schema you must have only one PDx low to read if key if push.

not "high" like your code,

you have pull-up all input, than you must have only one low and read low if button active. ++

Thierry

Thierry Pottier

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is a simple switch matrix taken off internet.  Without the diodes you will get all sorts of problems when multiple switches are closed.  work out what you would see in your matrix when SW1, SW8, SW11 and SW16 are closed.

 

 

Also what is connected to the Address lines on the EPROM>

 

David 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok guys i am once again attaching my latest schematics with this code modified---

Here i am releasing port C for normal port operation & selecting 3 rows through Demultiplexer 74ls138.

 

it is working with only 1 row what ever row i am selecting first among 3 rows, after releasing full port C. Here is the code along with schematics---

 

                    DDRC = 0x00; //port C I/P
                    SFIOR = (1<<XMM2) |(1<<XMM1) | (1<<XMM0); // Release Full Port C.
                    
                    PORTD = PORTD |((1<<1)|(0<<2)|(0<<3)); //Select Row-1
                    asm("nop");
                    if (PINC != 0xFF)// check until all key release row-1
                    {
                    KB_Scan();//goto rr;
                    }
                    while (PINC != 0xFF);
                   
                   
                    PORTD = PORTD |((0<<1)|(1<<2)|(0<<3)); //Select Row-2
                    asm("nop");
                    if (PINC != 0xFF)// check until all key release row-2
                    {
                    KB_Scan();//goto rr1;
                    }
                    while (PINC != 0xFF);
                    PINC = 0xFF;
                   
                    PORTD = PORTD |((0<<1)|(0<<2)|(1<<3)); //Select Row-3
                    asm("nop");
                    if (PINC != 0xFF)// check until all key release row-3
                    {
                    KB_Scan();//goto rr2;
                    }
                    while (PINC != 0xFF);
                    PINC = 0xFF;        
                    PORTD = (PORTD |(0<<1)|(0<<2)|(0<<3)); //no Select
                    SFIOR = (0<<XMM2) |(0<<XMM1) | (0<<XMM0); // 
                    

Attachment(s): 

Pkdas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Count how many times you have this: PINC = 0xFF; line in your program. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can't download the bmp and please use code "<>" to insert your source.

                    DDRC = 0x00; //port C I/P
                    SFIOR = (1<<XMM2) |(1<<XMM1) | (1<<XMM0); // Release Full Port C.
                    
                    PORTD = PORTD |((1<<1)|(0<<2)|(0<<3)); //Select Row-1
                    asm("nop");
                    if (PINC != 0xFF)// check until all key release row-1
                    {
                    KB_Scan();//goto rr;
                    }
                    while (PINC != 0xFF);
                   
                   
                    PORTD = PORTD |((0<<1)|(1<<2)|(0<<3)); //Select Row-2
                    asm("nop");
                    if (PINC != 0xFF)// check until all key release row-2
                    {
                    KB_Scan();//goto rr1;
                    }
                    while (PINC != 0xFF);
                    PINC = 0xFF;
                   
                    PORTD = PORTD |((0<<1)|(0<<2)|(1<<3)); //Select Row-3
                    asm("nop");
                    if (PINC != 0xFF)// check until all key release row-3
                    {
                    KB_Scan();//goto rr2;
                    }
                    while (PINC != 0xFF);
                    PINC = 0xFF;        
                    PORTD = (PORTD |(0<<1)|(0<<2)|(0<<3)); //no Select
                    SFIOR = (0<<XMM2) |(0<<XMM1) | (0<<XMM0); // 
                    

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok I changed browsers and downloaded the bmp....no diodes and now no EPROM.  You are giving code snippets and incomplete schematics which makes it almost impossible to provide help.

 

Have I already said...you need diodes.

 

David  

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Diodes, diodes, diodes...........

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

your code is wrong!

read col 1 :

PORTD = PORTD |((0<<1)|(1<<2)|(1<<3)); //Select Row-1

you must pull down the line you want read.

Thierry

Thierry Pottier

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear TPE ,

thanks for your comments,

in reality i have used 3 PNP transistor for row select through collector line,

Code is working , but only first row detecting.

Pkdas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

in reality i have used 3 PNP transistor for row select through collector line,

So the schematic you posted does not represent what you actually have.  Is that correct?

 

Have you fitted diodes? 

 

Code is working , but only first row detecting. 

So if only the first row is being detected the code cannot be working can it?

 

Why not post the actual code and the actual schematic?

 

David  

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The selects would normally be active low by convention. So you would have npn transistors. Open collector drive solves one of your problems, but you still need a diode for each switch.
Such a simple problem made difficult!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't suppose anyone has suggested that diodes might help....

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DAFlippers wrote:

I don't suppose anyone has suggested that diodes might help....

 

You know what they say about sarcasm? devil

Ross McKenzie ValuSoft Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Diodes might add too much cost for this commercial venture.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One day I aspire to reach the lowest form of wit.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Diodes would certainly rectify the issue.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi every one thanks everyone for your valuable suggestion.

Once again i am attaching the code & actual drawing for the key board ckt.

 

 

Row-1: PORTD = PORTD |(1<<1)|(0<<2)|(0<<3); //Select Row-1

        asm("nop");
        asm("nop");
        if (PINC != 0xFF)
        {
        goto xx1;
        }
        PORTD = PORTD |(0<<1)|(0<<2)|(0<<3);// Blank out
        asm("nop");
        asm("nop");
        

 Row-2:PORTD = PORTD |(0<<1)|(1<<2)|(0<<3); //Select Row-2
        asm("nop");
        asm("nop");
        if (PINC != 0xFF)
        {
        goto xx2;
        }
        PORTD = PORTD |(0<<1)|(0<<2)|(0<<3);// Blank out
        asm("nop");
        asm("nop");
    

 Row-3:PORTD = PORTD |(0<<1)|(0<<2)|(1<<3); //Select Row-3
        asm("nop");
        asm("nop");
        
        if (PINC != 0xFF)
         {
        goto xx3;
        }
        PORTD = PORTD |(0<<1)|(0<<2)|(0<<3);// Blank out
        asm("nop");
        asm("nop");
        
        goto xxreturn;// if not pressed then out
    

 

 

 

Main problem iam facing that :

If i am pressing any key of ROW-1 by selecting  PORTD = PORTD |(0<<1)|(0<<2)|(0<<3) i am able to read PIN C.all function of ROW-1 working fine.

and if i am pressing other key of ROW-2 or ROW-3 after release of previous switch of ROW-1 i am getting the same result as i got for ROW-1.

I hope the transistor what i am using BC547B is not de-selecting at the time of selecting ROW-2/ROW3.

 

What i am suspecting is is it not due to propagation delay of transistor BC547B. please give your view.

Attachment(s): 

Pkdas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
Row-1: PORTD &= ~((1<<2) | (1<<3));
        PORTD |= (1<<1); //Select Row-1
        asm("nop");
        asm("nop");
        if (PINC != 0xFF)
        {
        goto xx1;
        }

 Row-2: PORTD &= ~((1<<1) | (1<<3));
        PORTD |= (1<<2; //Select Row-2
        asm("nop");
        asm("nop");
        if (PINC != 0xFF)
        {
        goto xx2;
        }

 Row-3:PORTD &= ~((1<<1) | (1<<2));
        PORTD |= (1<<3); //Select Row-
        asm("nop");
        asm("nop");
        
        if (PINC != 0xFF)
         {
        goto xx3;
        }

        goto xxreturn;// if not pressed then out
        
        
        
        
        
        //If you get rid of the transistors:
        
        PORTD &= ~((1<<1) | (1<<2) | (1<<3));  //pd1,2,3 low
        DDRD &= ~((1<<1) | (1<<2) | (1<<3));    //pd1,2,3 as inputs (floating)
        .....
        
Row-1:  DDRD &= ~((1<<2) | (1<<3))
        DDRD |= (1<<1); //Select Row-1 
        asm("nop");
        asm("nop");
        if (PINC != 0xFF)
        {
        goto xx1;
        }

 Row-2: DDRD &= ~((1<<1) | (1<<3));
        DDRD |= (1<<2; //Select Row-2
        asm("nop");
        asm("nop");
        if (PINC != 0xFF)
        {
        goto xx2;
        }

 Row-3: DDRD &= ~((1<<1) | (1<<2));
        DDRD |= (1<<3); //Select Row-
        asm("nop");
        asm("nop");
        
        if (PINC != 0xFF)
         {
        goto xx3;
        }

        goto xxreturn;// if not pressed then out

Personally, I'd avoid using gotos - no need here. I'd also use a timer tick to scan the keypad.

The 'or' operator only sets bits. Nowhere do you reset the bits. (0< Why did you add the transistors? You can do the same with the port pins directly. Rather than toggle PORT bits, set the PORT bits to 0. Then use DDR to select between input and output. For output the port pin pulls low,when input it floats - just like what your transistor does. i mentioned this earlier.

Last Edited: Sat. Jan 23, 2016 - 12:13 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Kartman ,

I will test it today & update u accordingly

Pkdas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear Kartman & All

I have tested as per your suggestion,  and after modification a bit i succeeded to read back all the key switch.here are the code:

 

 

                    DDRC = 0x00; //port C I/P
                    PORTC = 0xFF;//
                    SFIOR = (1<<XMM2)|(1<<XMM1)|(1<<XMM0); // Release Full Port C.
                    asm("nop");

                    PORTD &= ~((1<<2) | (1<<3));
                    PORTD |= (1<<1); //Select Row-1
                    asm("nop");
                    asm("nop");
                    asm("nop");
                    asm("nop");
                    if (PINC != 0xFF)
                    {
                    KB_Scan_R1();
                    }
                    PORTD &= ~((1<<1) | (1<<2) | (1<<3));// Blank out
                    asm("nop");
                    asm("nop");
                    asm("nop");
                    asm("nop");
                            

                    PORTD &= ~((1<<1) | (1<<3));
                    PORTD |= (1<<2); //Select Row-2
                    asm("nop");
                    asm("nop");
                    asm("nop");
                    asm("nop");
                    if (PINC != 0xFF)
                    {
                    KB_Scan_R2();
                    }
                    PORTD &= ~((1<<1) | (1<<2) | (1<<3));// Blank out
                    asm("nop");
                    asm("nop");
                    asm("nop");
                    asm("nop");

                    PORTD &= ~((1<<1) | (1<<2));
                    PORTD |= (1<<3); //Select Row-3
                    asm("nop");
                    asm("nop");
                    asm("nop");
                    asm("nop");
                    if (PINC != 0xFF)
                    {
                    KB_Scan_R3();
                    }
                    PORTD &= ~((1<<1) | (1<<2) | (1<<3));// Blank out
                    asm("nop");
                    asm("nop");
                    asm("nop");
                    asm("nop");                
                    
                    SFIOR = (0<<XMM2) |(0<<XMM1) | (0<<XMM0); // 
                    asm("nop");

/////////////////////////////////////////////////////////////////////////////////////////

What i was suspecting is true the key switch not able to detect due to time mismatch of the row vs Column & it is due to propagation delay of transistor BC547B. And the transistor was taking time to settle up at its collector side after issuing command at base side. and hence i am using repeatedly  asm("nop"); and PORTD &= ~((1<<1) | (1<<2) | (1<<3));// Blank out.

 

This kind of problem was seen by me when i was involve in writing code of some led display with row/column based scanning system. Some ghost image was observed, so that day i was using "nop" after sending row data & col data.

 

 

 

Pkdas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think you might find it is stray capacitance is the problem, not propagation delay.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes May be , Thanks once again for your support

Pkdas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Once again
in continuation with this topic i would like to inform you all , i have tested successfully Danne code for debounce with this 24 nos. of key switch & its working excellently beyond my expectation.

Thanks to JohanEkdahl & Danne & others too for their excellent result oriented topic. 

Pkdas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

pkd0057 wrote:
PORTD = PORTD |(0<<1)|(0<<2)|(0<<3);// Blank out

You can not clear bits with an OR...

 

Use something like:

PORTD &= ~((1<<PD0)|(1<<PD1)|(1<<PD2));

 

David (aka frog_jr)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can not clear bits with an OR...

Pointed out by Kartman in #38, acknowledged by OP in #39, fixed in #40.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
Pointed out by Kartman in #38

Interestingly, I got this thread as a NEW this morning and the last message I saw was #37. I saw it (#37) was dated 22, 2016 (missing that it was Jan, not Jun), and wrote my reply. I don't know if my wireless missed something, or if I just needed more caffeine, or what, I just responded to a 6mo old message as new.

Sorry guys!blush

David (aka frog_jr)