cannot read from an input (switch) over i2c..pls help

Status
Not open for further replies.

elizabeth ann

Junior Member level 2
Joined
Feb 16, 2008
Messages
21
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,468
read switches i2c

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.(by the way i am using CCS C as my compiler, and MAX7318 for my port expanders)

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;
   }
   byte1=byte1&&0xFF;
   byte2=byte2&&0xFF;

   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...
 

cannot read i2c

Hi,

What happens if the program is modified as follows?
Remove the following:
{
while( !byte1 && !byte2 )

and

break;
}
byte1=byte1&&0xFF;
byte2=byte2&&0xFF;

Regards,
Laktronics
 

thanks for the correction. i must have overlooked the code. here is the revised one, however it is still not working anyhow...

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) );

i still can't turn the LEDs OFF with my switch... is there anything wrong with my i2c routine?
 

Hi,
I thought you were sure of I2C part, the sequence of functions appears to be alright, but you have to carefully check the detailed working of each function.

1.You can output byte1/byte2 to a port and check if the data is correctly read.

2.One more point is that since you have only ten switches, in one of the bytes, only two bits of infomation will be present and if other bits are read as high, you have to make them zero by bitwise anding (&) with 0XC0 or 0X03 depending upon where your two bits of information in the byte is present.

3. How is your LED connected, does it turn on with a low bit or a high bit?

4. while ( (byte1!=0x00) & (byte2!=0x00) ); here logical double AND (&&) should be used.

Regards,
Laktronics
 

hey,
thanks for the reply....

1.You can output byte1/byte2 to a port and check if the data is correctly read.
i have already tried displaying the byte1/byte2 values in my 16x2 LCD Module but it does not display anything, no ouput (rest assured that my LCD is working fine.)

2.One more point is that since you have only ten switches, in one of the bytes, only two bits of infomation will be present and if other bits are read as high......
this is not the case for my MAX7318 for the switches...since it has TWO bytes, i used 5 out of 8 bits of the FIRST byte, and another 5 out of 8 bits of the SECOND byte, making it 10 bits for the 2 bytes ( 5 bits each byte).

3. How is your LED connected, does it turn on with a low bit or a high bit?
the LEDs are turned ON with a high bit. the switch press is supposed to send a low bit to the LED to turn it OFF.

4. while ( (byte1!=0x00) & (byte2!=0x00) ); here logical double AND (&&) should be used.
i have already modified the code according to this...but nothing happens...

with my posted code, the i2c routine is divided into two sections. BOTH sections, however, 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.


FIRST i2c SECTION:
here, the MAX7318 of the SWITCHES (with the address of 0xA0) 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 (with the address of 0x32) 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();
 

Hi,

i have already tried displaying the byte1/byte2 values in my 16x2 LCD Module but it does not display anything, no ouput (rest assured that my LCD is working fine.)

You have to make it work first, without this portion working, the display portion will not work. Did you covert the data to ASCII while displaying on LCD?

byte1=i2c_read(1); // I suppose this includes issue of ACK-
byte2=i2c_read(); // I assume there is no ACK here
i2c_read(0); // and here you ONLY issue a +ve ACK

Are the above assumptions correct?

How about the speed matching, does these routines allow adjustment of clock speeds to match the peripherals if required? I have nothing more to suggest now.

Regards,
Laktronics
 

I can't see, how the code is reading from the switch inputs. To my opinion, the output port is read back (command byte 0x02) rather than reading from the input (command byte 0x00). To check, if the I2C communication is functional at all, I would start with a more basic test. Also debugging with CCS or Microchip ICD would be a suitable method to find the apparently existing code and/or hardware errors.

Byt the way, i2c_read() and i2c_read(1) is identically performing an ACK with CCS.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…