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 support@ccsinfo.com

cannot read from an input (switch) over i2c...(SOLVED)
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
elizabeth ann



Joined: 16 Feb 2008
Posts: 33

View user's profile Send private message

cannot read from an input (switch) over i2c...(SOLVED)
PostPosted: Wed Apr 30, 2008 10:35 pm     Reply with quote

i am trying to read from a microswitch (similar to a push button) over the i2c communication so i developed a code that will constantly read from the source (10 microswitches installed in Port Expander 1) and feed it to another i2c device (10 LEDs installed in Port Expander 2) in order to turn an LED off until all the 10 LEDs are OFF. for example, if i have pressed SWITCH 1, then LED 1 should be OFF.

however, this code seems to have a problem.... i have tried to load the program in my microcontroller but nothing happens....

also, i have a question about the byte received during the READ process, is it simply 0 or 1 and 0 means low, and 1 is high? i hope someone can enlighten me....

thank you.

note:
slave addresses:
0x32=10 LEDs (preconfigured as output)
0xA0=10 switches (preconfigured as input)

Code:

BYTE byte1, byte2;
do
   {
   while( !byte1 && !byte2 )
   {
   i2c_start();         
   i2c_write(0xA0);
   i2c_write(0x02);
   i2c_start();         //START READING REGISTER
   i2c_write(0xA1);     
   byte1=i2c_read(1);   //ex. if switch1 is pressed, byte1=0x7F
   byte2=i2c_read();    //READ 2ND BYTE
   i2c_read(0);         //STOP READING
   i2c_stop();
   break;
   }
 
   i2c_start();
   i2c_write(0x32);     //UPDATE LEDs WITH SWITCH STATE
   i2c_write(0x02);     //ACCESS OUTPUT REGISTER
   i2c_write(byte1);    //WRITE BYTE1 (FROM READ MODE) TO LED
   i2c_write(byte2);    //WRITE BYTE2 (FROM READ MODE) TO LED
   i2c_stop();
   } while ( (byte1!=0x00) && (byte2!=0x00) );


perhaps something is wrong with my WRITE MODE/PROCESS? corrections are very much welcomed...


Last edited by elizabeth ann on Mon May 12, 2008 7:55 am; edited 2 times in total
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu May 01, 2008 8:50 am     Reply with quote

Code:
   byte1=byte1&&0xFF;
Here you made the error of mixing the logical AND '&&' with the binary AND '&'. As the code is now it will change byte1 to TRUE or FALSE (0 or 1).
I guess you intended to do:
Code:
   byte1=byte1 & 0xFF;
Which is valid code but will do nothing as byte1 is an 8 bit variable and performing an AND with 0xFF will return the exact same result. This code only makes sense when executing on a 16 or 32-bit processor, but even then is not required.
Best is to remove these two lines from your program.

What are the type numbers of the I/O expanders?
elizabeth ann



Joined: 16 Feb 2008
Posts: 33

View user's profile Send private message

PostPosted: Thu May 01, 2008 9:52 pm     Reply with quote

oh, sorry... i was working on another loop with the slave addresses and that lines must have probably mixed up with this one. my mistake though...

by the way, as to the port expander, i am using MAX7318 [url] http://pdf1.alldatasheet.com/datasheet-pdf/view/197255/MAXIM/MAX7318.html [/url] and i have based my i2c routines on the information found in that datasheet.

since i need only 10 of each of the ports, i only used the first 5 bits of Port 1 and another 5 bits of Port 2 to make it 10. this is true for both the LED and the Switch as they have separate port expanders...

hope this helps make my problem better to understand...

by the way, i removed that line already but it still didn't work.... Sad is there anything else wrong with my code?
elizabeth ann



Joined: 16 Feb 2008
Posts: 33

View user's profile Send private message

PostPosted: Fri May 02, 2008 11:47 pm     Reply with quote

edited the code with a few modifications...

Code:

BYTE byte1, byte2;
do
   {
   i2c_start();         
   i2c_write(0xA0);
   i2c_write(0x02);
   i2c_start();         //START READING REGISTER
   i2c_write(0xA1);     
   byte1=i2c_read(1);   //ex. if switch1 is pressed, byte1=0x7F
   byte2=i2c_read();    //READ 2ND BYTE
   i2c_read(0);         //STOP READING
   i2c_stop();

   i2c_start();
   i2c_write(0x32);     //UPDATE LEDs WITH SWITCH STATE
   i2c_write(0x02);     //ACCESS OUTPUT REGISTER
   i2c_write(byte1);    //WRITE BYTE1 (FROM READ MODE) TO LED
   i2c_write(byte2);    //WRITE BYTE2 (FROM READ MODE) TO LED
   i2c_stop();
   } while ( (byte1!=0x00) & (byte2!=0x00) );



but still not a good code...it's not working any better...no response from the LED as it should be turned off by a switch press...can somebody help me Crying or Very sad Confused Crying or Very sad
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat May 03, 2008 12:39 am     Reply with quote

Post a list of your connections to the AD0, AD1, and AD2 pins on the
MAX7318 chips. There may be a problem with your interpretation of
the slave address of the MAX7318 chip. But to know for sure, I must
get the list of your connections to those three pins.


Also, you have two sections of i2c code. The 2nd section is presumably
talking to the MAX7318. What chip is the 1st section talking to ?


Finally, what PIC are you using, and what is your compiler version ?
Do you have pull-up resistors on the SDA and SCL signals ?
elizabeth ann



Joined: 16 Feb 2008
Posts: 33

View user's profile Send private message

PostPosted: Sun May 04, 2008 12:48 am     Reply with quote

Here are the pin connections:
Code:

APPLICATION    TYPE    SLAVE ADDRESS   AD0     AD1     AD2


LED indicator  output       0x32       SDA     SCL     GND   

Switch         input        0xA0       GND     SCL     SCL


By the way, i am using PIC16F877A, my compiler version is 4.057 and yes, we do have pull-up resistors in SDA and SCL (10kOhms each).

Note:
BOTH SECTIONS are talking to the MAX7318, only that the first one is talking to the SWITCH (waiting for a press) and the second section is talking to the LEDs (to be turned off when a press is detected). both sections use a separate MAX7318 but in a different application.

this is the first i2c section:
here, the MAX7318 of the SWITCHES are on a READ MODE, MAX7318 waits for a switch press and the data will be saved in byte1 and byte2, which will be fed to the MAX7318 of the LEDs in the second section of the program.
Code:

   i2c_start();
   i2c_write(0XA0);
   i2c_write(0x02);
   i2c_start();              //START READING REGISTER
   i2c_write(0XA1);      //0XA1 = IN READ MODE
   byte1=i2c_read(1);   //if switch1 is pressed,byte1=0111 1111
   byte2=i2c_read();    //READ 2ND BYTE
   i2c_read(0);            //STOP READING
   i2c_stop();


this is the second section:
here, i2c is talking to the MAX7318 of the LEDs and dictates which LEDs are to be turned off, based on the value of byte1 and byte2.
Code:

   i2c_start();
   i2c_write(0X32);     //UPDATE LEDs WITH SWITCH STATE
   i2c_write(0x02);     //ACCESS OUTPUT REGISTER
   i2c_write(byte1);    //WRITE BYTE1 (FROM READ MODE) TO LED
   i2c_write(byte2);    //WRITE BYTE2 (FROM READ MODE) TO LED
   i2c_stop();
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun May 04, 2008 2:06 am     Reply with quote

Quote:
i2c_start();
i2c_write(0XA0);
i2c_write(0x02);
i2c_start(); //START READING REGISTER
i2c_write(0XA1); //0XA1 = IN READ MODE
byte1=i2c_read(1); //if switch1 is pressed,byte1=0111 1111
byte2=i2c_read(); //READ 2ND BYTE
i2c_read(0); //STOP READING
i2c_stop();

The value in bold (0x02) is not a read command. According to the
data sheet, it's the "output Port 1" command.
You actually want to use this command:
Quote:
0x00 Input port 1



Quote:

byte1=i2c_read(1); //if switch1 is pressed,byte1=0111 1111
byte2=i2c_read(); //READ 2ND BYTE
i2c_read(0); //STOP READING

Also, the code above is not correct. There should only be two calls to
the i2c_read() function, and the 2nd call should have a parameter of 0.
The first call should not have a parameter. Get rid of the 3rd call.
Example:
Code:

byte1 = i2c_read();   //if switch1 is pressed,byte1=0111 1111
byte2 = i2c_read(0);    //READ 2ND BYTE



I noticed another problem. These MAX7318 chips power-up with all
the i/o pins configured as input pins. You have to write to a config
register, to turn them into output pins. You have to write to registers
0x06 and 0x07. You need to write 0x00 to each of them, if you want
to set all 16 bits on the MAX7318 to be output pins. You're not doing
this in the code that you posted for the LED driver chip.
Here is the required code:
Code:

i2c_start();
i2c_write(0X32);     
i2c_write(0x06);     
i2c_write(0x00);   
i2c_write(0x00);     
i2c_stop();

This code should be placed before the code that turns on the LEDs.
elizabeth ann



Joined: 16 Feb 2008
Posts: 33

View user's profile Send private message

PostPosted: Sun May 04, 2008 3:01 am     Reply with quote

[quote="PCM programmer"]
Quote:
i2c_start();
I noticed another problem. These MAX7318 chips power-up with all
the i/o pins configured as input pins. You have to write to a config
register, to turn them into output pins. You have to write to registers
0x06 and 0x07. You need to write 0x00 to each of them, if you want
to set all 16 bits on the MAX7318 to be output pins. You're not doing
this in the code that you posted for the LED driver chip.
Here is the required code:
Code:

i2c_start();
i2c_write(0X32);     
i2c_write(0x06);     
i2c_write(0x00);   
i2c_write(0x00);     
i2c_stop();

This code should be placed before the code that turns on the LEDs.


thanks a lot for your attention....
regarding the input/ouput configuration of the switches' and LEDs' MAX7318, they have been configured with the same code you posted above (only that i did not post it beforehand Smile ) anyways, that served as a verification that my preconfigurations are indeed correct. thanks....Very Happy

i have modified the code according to your corrections:

Code:

do
   {
   i2c_start();
   i2c_write(0xA0);
   i2c_write(0x00);
   i2c_start();         //START READING REGISTER
   i2c_write(0xA1);     // 0xA1 = IN READ MODE
   byte1=i2c_read(); //if switch1 is pressed, byte1=0111 1111
   byte2=i2c_read(0);    //READ 2ND BYTE
   i2c_stop();

   i2c_start();
   i2c_write(0X32);     //UPDATE LEDs WITH SWITCH STATE
   i2c_write(0x02);     //ACCESS OUTPUT REGISTER
   i2c_write(byte1);    //WRITE BYTE1 (FROM READ MODE) TO LED
   i2c_write(byte2);    //WRITE BYTE2 (FROM READ MODE) TO LED
   i2c_stop();
   }while ( (byte1!=0x00) && (byte2!=0x00) );


i have tested this new code just a few moments ago with my hardware but no response from the switch or the LEDs... Sad Crying or Very sad

is there anything wrong with my loop?
do { } while ??? is my condition of loop termination correct? (byte1 and 2)

or could it be that the problem is switch debouncing? i am running out of ideas as to where my code would have gotten wrong...please help....thanks so much!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun May 04, 2008 3:22 am     Reply with quote

Write a program to test each MAX7318 independently.
For example, write a program that only tests the MAX7318 that drives
the LEDs. With your current program, you are testing both of them at
the same time. It could be that one of the MAX7318 chips is working
perfectly. If you do independent testing, you can learn if this is true.

Also, describe the LED circuits that are connected to one of the MAX7318
chips. Give component values and all connections.
elizabeth ann



Joined: 16 Feb 2008
Posts: 33

View user's profile Send private message

PostPosted: Sun May 04, 2008 4:53 am     Reply with quote

tried that a few minutes ago...

i created two separate programs. here are the results:

the MAX7318 of the LED is working fine. i can successfully write to it as to which LEDs will be turned ON or OFF.

the MAX7318 of the Switch is okay. i can detect a LOW when i press the Switch. everything seems to be fine.

but with the two programs combined, i do not get any positive result. the MAX7318 of the Switch becomes LOW when pressed but it does not turn the LED off....

here is the schematic diagram of the LED and Switch with the MAX7318 and 16F877A... i showed only one LED and Switch for this diagram (which is supposed to be 10 each)...
[img]http://Documents and Settings\ABAD\Desktop\PIC.jpg[/img]
elizabeth ann



Joined: 16 Feb 2008
Posts: 33

View user's profile Send private message

PostPosted: Sun May 04, 2008 5:04 am     Reply with quote

ooops....

i think i have a little problem posting my scanned schematic diagram....

sorry but how do i post a JPEG picture in this forum?

really sorry....the "insert image" did not work for my diagram...how do i do this?thanks.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun May 04, 2008 10:34 am     Reply with quote

CCS doesn't allow uploading images to their server. You need to upload
the image to some other server, and then put the link to it in your post.

Some people do it on their university server. Others use a free image
hosting service. You can find them with google. You'll need a junk
email address that you can get from Yahoo.
foodwatch



Joined: 18 Apr 2006
Posts: 66

View user's profile Send private message Yahoo Messenger

PostPosted: Sun May 04, 2008 11:02 am     Reply with quote

I'm not very familiar with the Max IC, but the problem might be contact bouncing on the switches. Most (if not all) mechanical switches "bounce" badly when you press them. This causes a string of on-off-on-off for as much as 30ms or more, The code may interpret this as turn on and turn off so fast it is wreaking havoc with the IIC.

The best way is to create a loop for the switch press so that it waits for 50ms (or more) in this loop to see if it is still "high" (or low if you are active low) at the end of this period. In this way the iic bus does not see anything until you are sure it is a single keypress and not 10 of them in rapid sequence due to debouncing. Too long a debounce period will prevent rapid keypresses to have the desired effect.

Hope this helps... Many pushbutton switch issue can be traced to not having any or enough "de-bounce". It can also be done in hardware, but that wouldn't be any fun ....
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun May 04, 2008 3:56 pm     Reply with quote

Your purpose is to make the output pins follow the state of the input pins.
Change your code as shown below. Read 16 bits from the "switches" chip.
Then write it to the LED driver chip. Don't do any math or logical
operations on it. This will prove if your basic concept is working:
Code:

while(1)
  {
   i2c_start();
   i2c_write(0xA0);
   i2c_write(0x00);
   i2c_start();       
   i2c_write(0xA1);     
   byte1=i2c_read(); // if sw1 is pressed, byte1=0111 1111
   byte2=i2c_read(0); 
   i2c_stop();

   i2c_start();
   i2c_write(0X32);   
   i2c_write(0x02);   
   i2c_write(byte1);   
   i2c_write(byte2);   
   i2c_stop();

   delay_ms(100);
  }
elizabeth ann



Joined: 16 Feb 2008
Posts: 33

View user's profile Send private message

PostPosted: Mon May 05, 2008 12:39 am     Reply with quote

sorry for the delayed response...

i will try that code right away, sir Very Happy

and be back in a few minutes with good news, i hope Very Happy

thank you very much.
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