April 25, 2024, 08:40:30 PM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


Talk to I2C chips through the RS232 serial port

Started by Johnny, June 29, 2009, 07:01:22 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Johnny

For those (probably only few) interested in electronics, there is an easy way to connect I2C integrated circuits trough the serial port, and this without a separate library.
The only thing that is needed is an on board RS232 port, unfortunately, they are becoming rare these days!   >:(
Only a few components more are needed as a voltage limiter (see circuit diagram below).
This demo shows that an EEPROM can be easily written and read this way, but there are many more types of circuits that use the I2C bus, so there is a lot of potential to use this somehow.
It is not the intension to use this program as it is, but only to give a skeleton with the necessary subroutines to make your own program with it.

By the way, I saw here recently somewhere a question about I2C over the serial port, but I don't find that topic back for the moment, maybe this can also help out there, not sure...
If it is useful for somebody, please let me know, enjoy!

Kind regards,
Johnny


'Demo program: I2C bus through serial port COM1, this writes 4 random Bytes to a 24C04 EEPROM, and reads 8 Bytes from it

DECLARE "Kernel32",CreateFileA(name:STRING,access:INT,share:INT,security:INT,create:INT,flags:INT,handle:INT),INT
DECLARE "Kernel32",CloseHandle(handle:INT),INT
DECLARE "Kernel32",GetCommModemStatus(handle:INT, lpModemStat:POINTER),INT
DECLARE "kernel32",EscapeCommFunction(handle:INT, nFunc:INT),INT
DECLARE "kernel32",Sleep(dwMilliseconds:INT)

SETID "I2C_SCL_H",3:'Set SCL line High   (RTS line)
SETID "I2C_SCL_L",4:'Set SCL line Low    (RTS line)
SETID "I2C_SDA_H",5:'Set SDA line High   (DTR line)
SETID "I2C_SDA_L",6:'Set SDA line Low    (DTR line)
SETID "I2C_InSCL",16:'Read mask SCL line (RTS line)
SETID "I2C_InSDA",32:'Read mask SDA line (DTR line)
SETID "I2C_InButton",64:'Read mask button (RI line)
SETID "I2C_Write",0
SETID "I2C_Read",1

AUTODEFINE "OFF"
DEF hcom,Status,Acknowledge,X,Byte:INT
DEF Key$:STRING

'*****************************************************************************
OPENCONSOLE
CLS:PRINT "I2C Test on serial port by Johnny (press Escape to exit)":PRINT

'Initialize the I2C bus via COM1
hcom = CreateFileA("COM1",0,0,0,3,0,0)
IF hcom = -1
MESSAGEBOX 0,"Could not open com port","Error"
CLOSECONSOLE
END
ENDIF
EscapeCommFunction(hcom,@I2C_SDA_H)
EscapeCommFunction(hcom,@I2C_SCL_H)
Sleep(300)

'Write 4 random bytes to the 24C04 EEPROM
PRINT "Start W160 :      Error= ", I2Cstart(160,@I2C_Write)
PRINT USING("Address    : ###  Ackn = ",I2C(0,1)),:PRINT Acknowledge
PRINT USING("Write #    : ###  Ackn = ",0, I2C(RAND(255),1)),:PRINT Acknowledge
PRINT USING("Write #    : ###  Ackn = ",1, I2C(RAND(255),1)),:PRINT Acknowledge
PRINT USING("Write #    : ###  Ackn = ",2, I2C(RAND(255),1)),:PRINT Acknowledge
PRINT USING("Write #    : ###  Ackn = ",3, I2C(RAND(255),1)),:PRINT Acknowledge
PRINT "Stop       :      Error= ", I2Cstop()

WHILE INKEY$ = ""
Sleep(100)
LOCATE 11,1

'Test for button press, this could be usefull for something in the future...
GetCommModemStatus(hcom,Status)
IF Status & @I2C_InButton THEN PRINT "Button pressed!" ELSE PRINT "               "

'Read 8 bytes from the 24C04 EEPROM
PRINT "Start W160 :      Error= ", I2Cstart(160,@I2C_Write)
PRINT USING("Address    : ###  Ackn = ",I2C(0,1)),:PRINT Acknowledge
PRINT "Start R161 :      Error= ", I2Cstart(160,@I2C_Read)
FOR X = 0 TO 7
PRINT USING("Read ##    : ###  Ackn = ",X,I2C(255,X = 7)),:PRINT Acknowledge
NEXT X
PRINT "Stop       :      Error= ", I2Cstop()
ENDWHILE

'Close the I2C bus via COM1
CloseHandle(hcom)
CLOSECONSOLE
END
'*****************************************************************************
SUB I2Cstart(SlaveAddr:INT,R_W:INT),INT
DEF SendVal,RetVal:INT
EscapeCommFunction(hcom,@I2C_SDA_H)
EscapeCommFunction(hcom,@I2C_SCL_H)
GetCommModemStatus(hcom,Status)
RetVal = (Status & (@I2C_InSCL | @I2C_InSDA)) < (@I2C_InSCL | @I2C_InSDA)
EscapeCommFunction(hcom,@I2C_SDA_L)
EscapeCommFunction(hcom,@I2C_SCL_L)
GetCommModemStatus(hcom,Status)
RetVal = ((Status & (@I2C_InSCL | @I2C_InSDA)) > 0) | RetVal
SendVal = (SlaveAddr & 254) | (R_W & 1)
RetVal = (I2C(SendVal,1) <> SendVal) | RetVal
RetVal = Acknowledge | RetVal
RETURN RetVal:'Result 0 = OK
ENDSUB
'*****************************************************************************
SUB I2Cstop()
EscapeCommFunction(hcom,@I2C_SCL_L)
EscapeCommFunction(hcom,@I2C_SDA_L)
EscapeCommFunction(hcom,@I2C_SCL_H)
EscapeCommFunction(hcom,@I2C_SDA_H)
GetCommModemStatus(hcom,Status)
RETURN (Status & (@I2C_InSCL | @I2C_InSDA)) < (@I2C_InSCL | @I2C_InSDA):'Result 0 = OK
ENDSUB
'*****************************************************************************
SUB I2Cbit(BitOut:INT),INT
IF BitOut = 0
EscapeCommFunction(hcom,@I2C_SDA_L)
ELSE
EscapeCommFunction(hcom,@I2C_SDA_H)
ENDIF
EscapeCommFunction(hcom,@I2C_SCL_H)
GetCommModemStatus(hcom,Status)
EscapeCommFunction(hcom,@I2C_SCL_L)
RETURN (Status & @I2C_InSDA) > 0:'Result = Received Bit
ENDSUB
'*****************************************************************************
SUB I2C(BusWord:INT,AcknOut:INT),INT
DEF Bitcounter:INT
FOR Bitcounter = 1 to 8
BusWord = (BusWord << 1) & 254 | I2Cbit(BusWord & 128)
NEXT Bitcounter
Acknowledge = I2Cbit(AcknOut):'Acknowledge = Bit 9
RETURN BusWord:'Result = Received Byte
ENDSUB
'*****************************************************************************

Egil

Quote from: Johnny on June 29, 2009, 07:01:22 AM
The only thing that is needed is an on board RS232 port, unfortunately, they are becoming rare these days!   >:(
There is a cheap and effective solution to this. Most computer stores have a supply of USB-to-RS232 cables, with the hardware level converter built into the D-SUB plug housing. This summer I have had great fun controlling an ICOM PC-1500R receiver from my newest toy, an Asus EEE PC-1000HE. I was warned about eratic behaviour of htese cables, but I have tried three cables from differrent manufacturers. All with good results.

I like your demo, and I think that many of the forum members  are into this kind of electronics. Thanks for sharing!
Support Amateur Radio  -  Have a ham  for dinner!

Techno

Hi, 

I try to compile with IWBasic v2.0 or v3.0 but it fails on my computer. What's wrong here?



'Demo program: I2C bus through serial port COM1, this writes 4 random Bytes to a 24C04 EEPROM, and reads 8 Bytes from it

DECLARE "Kernel32",CreateFileA(name:STRING,access:INT,share:INT,security:INT,create:INT,flags:INT,handle:INT),INT
DECLARE "Kernel32",CloseHandle(handle:INT),INT
DECLARE "Kernel32",GetCommModemStatus(handle:INT, lpModemStat:POINTER),INT
DECLARE "kernel32",EscapeCommFunction(handle:INT, nFunc:INT),INT
DECLARE "kernel32",Sleep(dwMilliseconds:INT)

SETID "I2C_SCL_H",3:'Set SCL line High   (RTS line)
SETID "I2C_SCL_L",4:'Set SCL line Low    (RTS line)
SETID "I2C_SDA_H",5:'Set SDA line High   (DTR line)
SETID "I2C_SDA_L",6:'Set SDA line Low    (DTR line)
SETID "I2C_InSCL",16:'Read mask SCL line (RTS line)
SETID "I2C_InSDA",32:'Read mask SDA line (DTR line)
SETID "I2C_InButton",64:'Read mask button (RI line)
SETID "I2C_Write",0
SETID "I2C_Read",1

AUTODEFINE "OFF"
DEF hcom,Status,Acknowledge,X,Byte:INT
DEF Key$:STRING

'*****************************************************************************
OPENCONSOLE
CLS:PRINT "I2C Test on serial port by Johnny (press Escape to exit)":PRINT

'Initialize the I2C bus via COM1
hcom = CreateFileA("COM1",0,0,0,3,0,0)
IF hcom = -1
MESSAGEBOX 0,"Could not open com port","Error"
CLOSECONSOLE
END
ENDIF
EscapeCommFunction(hcom,@I2C_SDA_H)
EscapeCommFunction(hcom,@I2C_SCL_H)
Sleep(300)

'Write 4 random bytes to the 24C04 EEPROM
PRINT "Start W160 :      Error= ", I2Cstart(160,@I2C_Write)
PRINT USING("Address    : ###  Ackn = ",I2C(0,1)),:PRINT Acknowledge
PRINT USING("Write #    : ###  Ackn = ",0, I2C(RAND(255),1)),:PRINT Acknowledge
PRINT USING("Write #    : ###  Ackn = ",1, I2C(RAND(255),1)),:PRINT Acknowledge
PRINT USING("Write #    : ###  Ackn = ",2, I2C(RAND(255),1)),:PRINT Acknowledge
PRINT USING("Write #    : ###  Ackn = ",3, I2C(RAND(255),1)),:PRINT Acknowledge
PRINT "Stop       :      Error= ", I2Cstop()

WHILE INKEY$ = ""
Sleep(100)
LOCATE 11,1

'Test for button press, this could be usefull for something in the future...
GetCommModemStatus(hcom,Status)
IF Status & @I2C_InButton THEN PRINT "Button pressed!" ELSE PRINT "               "

'Read 8 bytes from the 24C04 EEPROM
PRINT "Start W160 :      Error= ", I2Cstart(160,@I2C_Write)
PRINT USING("Address    : ###  Ackn = ",I2C(0,1)),:PRINT Acknowledge
PRINT "Start R161 :      Error= ", I2Cstart(160,@I2C_Read)
FOR X = 0 TO 7
PRINT USING("Read ##    : ###  Ackn = ",X,I2C(255,X = 7)),:PRINT Acknowledge
NEXT X
PRINT "Stop       :      Error= ", I2Cstop()
ENDWHILE

'Close the I2C bus via COM1
CloseHandle(hcom)
CLOSECONSOLE
END
'*****************************************************************************
SUB I2Cstart(SlaveAddr:INT,R_W:INT),INT
DEF SendVal,RetVal:INT
EscapeCommFunction(hcom,@I2C_SDA_H)
EscapeCommFunction(hcom,@I2C_SCL_H)
GetCommModemStatus(hcom,Status)
RetVal = (Status & (@I2C_InSCL | @I2C_InSDA)) < (@I2C_InSCL | @I2C_InSDA)
EscapeCommFunction(hcom,@I2C_SDA_L)
EscapeCommFunction(hcom,@I2C_SCL_L)
GetCommModemStatus(hcom,Status)
RetVal = ((Status & (@I2C_InSCL | @I2C_InSDA)) > 0) | RetVal
SendVal = (SlaveAddr & 254) | (R_W & 1)
RetVal = (I2C(SendVal,1) <> SendVal) | RetVal
RetVal = Acknowledge | RetVal
RETURN RetVal:'Result 0 = OK
ENDSUB
'*****************************************************************************
SUB I2Cstop()
EscapeCommFunction(hcom,@I2C_SCL_L)
EscapeCommFunction(hcom,@I2C_SDA_L)
EscapeCommFunction(hcom,@I2C_SCL_H)
EscapeCommFunction(hcom,@I2C_SDA_H)
GetCommModemStatus(hcom,Status)
RETURN (Status & (@I2C_InSCL | @I2C_InSDA)) < (@I2C_InSCL | @I2C_InSDA):'Result 0 = OK
ENDSUB
'*****************************************************************************
SUB I2Cbit(BitOut:INT),INT
IF BitOut = 0
EscapeCommFunction(hcom,@I2C_SDA_L)
ELSE
EscapeCommFunction(hcom,@I2C_SDA_H)
ENDIF
EscapeCommFunction(hcom,@I2C_SCL_H)
GetCommModemStatus(hcom,Status)
EscapeCommFunction(hcom,@I2C_SCL_L)
RETURN (Status & @I2C_InSDA) > 0:'Result = Received Bit
ENDSUB
'*****************************************************************************
SUB I2C(BusWord:INT,AcknOut:INT),INT
DEF Bitcounter:INT
FOR Bitcounter = 1 to 8
BusWord = (BusWord << 1) & 254 | I2Cbit(BusWord & 128)
NEXT Bitcounter
Acknowledge = I2Cbit(AcknOut):'Acknowledge = Bit 9
RETURN BusWord:'Result = Received Byte
ENDSUB
'*****************************************************************************



Compiling Resources...
No Errors

Compiling...
iwb_i2c_serialport_v1.1.iwb
File: C:\Users\Public\Documents\Development\IWBasic\Projects\roundtable\I2C and SerialPort\iwb_i2c_serialport_v1.1.iwb (20) Error: syntax error - Byte
File: C:\Users\Public\Documents\Development\IWBasic\Projects\roundtable\I2C and SerialPort\iwb_i2c_serialport_v1.1.iwb (20) Error: syntax error
File: C:\Users\Public\Documents\Development\IWBasic\Projects\roundtable\I2C and SerialPort\iwb_i2c_serialport_v1.1.iwb (28) Error: Undefined variable hcom
File: C:\Users\Public\Documents\Development\IWBasic\Projects\roundtable\I2C and SerialPort\iwb_i2c_serialport_v1.1.iwb (29) Error: Undefined variable hcom
File: C:\Users\Public\Documents\Development\IWBasic\Projects\roundtable\I2C and SerialPort\iwb_i2c_serialport_v1.1.iwb (34) Error: Undefined variable hcom
Error(s) in compiling "C:\Users\Public\Documents\Development\IWBasic\Projects\roundtable\I2C and SerialPort\iwb_i2c_serialport_v1.1.iwb"
Build Failed

LarryMc

change this line
DEF hcom,Status,Acknowledge,X,Byte:INT
to this
DEF hcom,Status,Acknowledge,X,Bytez:INT

or you can delete it since Byte is not being used in the program.


NOTE: You need to start reading the error messages and making an attempt to fixing these simple fixes yourself.
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Techno


Bill-Bo

Johnny,

Please do not ignore my post.

It's been awhile, is it a 9-pin or 25-pin serial port?

Bill

Techno

Quote from: Bill-Bo on May 27, 2015, 10:29:21 AM
Johnny,

Please do not ignore my post.

It's been awhile, is it a 9-pin or 25-pin serial port?

Bill

9 pins connector