View previous topic :: View next topic |
Author |
Message |
AlanGHosler
Joined: 25 Jan 2011 Posts: 109
|
Posted: Fri Dec 11, 2015 4:07 am Post subject: Use of the MCS I2C Slave Library |
|
|
The following are portions of coding from I2C master and I2C slave programs using the add on library available from MCS. I have not found many examples of the use of this library so I am posting this information. I have not attached the complete codes as they are long and very much a repeat of what I have posted before. Nonetheless if this doesn't work for you and you would like the complete codes please let me know.
The first program functions as an I2C master to read the measured septic tank level from a I2C slave (using ATtiny861A). It then transmits the received datum by the Short Message Service (SMS) using a SIM900 GSM/GPRS modem. This occurs once a day at midnight. This is currently working at my remote cabin without problems. An early version of this code posted on the forum also transmitted pictures via Multimedia Messaging Service (MMS).
The second code functions as the I2C slave. It operates the sonic range finder.
Because if have had some problem in maintaining the I2C connection (i.e., the slave will start responding with only 11111111) the slave is re-powered by the master when this occurs.
Because of the short remaining life of the AT&T 2G system in the US I am currently revising the master to use a SIM5215/5216 3G module. For that version the master will directly control the sonic ranging device so I will no longer be using the I2C slave. That is why I decided to post this now as it will disappear from later versions. I will also put back in the transmission of pictures via MMS.
In the master
Config SCL = PortC.5
Config SDA = PortC.4
Dim AA(2) as Byte 'headspace - timer1 returns 16 bit data in
Dim Headspace as Word at AA(1) Overlay 'two 8 bit registers
....
Get_data: 'get cabin data; currently headspace and inside temperature
'get headspace from ATtiny861A I2C slave
I2cinit
I2cstart
I2cwbyte &H40
I2cstop
I2cstart
I2cwbyte &H41
I2crbyte AA(1) , Ack 'low byte of headspace
I2crbyte AA(2) , Nack 'high byte of headspace
I2cstop
'headspace dimensioned as Word is overlay at byte AA(1)
Print #1, "Headspace = "; headspace; 'in inches * 10
Print #1, " WDT = "; Wdt_count ; " Ping RS = "; Ping_count;
Print #1, " Temperature = "; temperature_byte(1); " ";
If headspace = 65535 Then 'repower ping
Print #1, Chr(cr); Chr(lf); "I2C error, headsace = "; headspace;
Ping_count = Ping_count + 1
Stop Watchdog
Set PWRPING '
Wait 1
Reset PWRPING
'get headspace again from ATtiny861A I2C slave
Wait 3
I2cinit
I2cstart
I2cwbyte &H40
I2cstop
I2cstart
I2cwbyte &H41
I2crbyte AA(1) , Ack 'low byte of headspace
I2crbyte AA(2) , Nack 'high byte of headspace
I2cstop
Print #1, " Have reset ping, Headspace = " ; headspace
Waitms 10
Start Watchdog
End If
Return
In the slave:
$lib "i2c_USI_slave.lib" 'add on library from MCS, edited for the ATtiny861
....
Const test = 0 '= 1 for display of debugging data
....
Do not put in config statements in the slave like
Config SCL = PortC.5
Config SDA = PortC.4
Not only are they not needed but for me they seemed to interfere with the program.
....
Dim AA(2) as Byte 'headspace - timer1 returns 16 bit data in
Dim Headspace as Word at AA(1) Overlay 'two 8 bit registers
....
Config usi = twislave , address = &H40
Enable Interrupts
....
'The following coding is based on the MCS example except as noted
'the following labels are called from the library when master send stop or start
'- note, not necessary for this slave address
Twi_stop_rstart_received:
#If Test = 1
Print #1, chr(esc);chr(clr_lcd);
Print # 1, chr(esc); Chr(pos_cur);
Printbin #1, &H00; 'line 1
Print #1, "Twi_stop_rst_rec'd";
#Endif
Return
'master sent our slave address and will not send data
Twi_addressed_goread:
#If Test = 1
Print # 1, chr(esc); Chr(pos_cur);
Printbin #1, &H40; 'line 2
Print #1, "Twi_addres'd_goread";
#Endif
Return
Twi_addressed_gowrite:
#If Test = 1
Print # 1, chr(esc); Chr(pos_cur);
Printbin #1, &H14; 'line 3
Print #1, "Twi_addres'd_gowrit";
#Endif
Return
'this label is called when the master sends data and the slave has received the byte
'the variable TWI holds the received value
Twi_gotdata:
#If Test = 1
Print # 1, chr(esc); Chr(pos_cur);
Printbin #1, &H54; 'line 4
Print #1, "received : " ; Twi ; " byte no : " ; Twi_btw;
#Endif
Select Case Twi_btw
Case 1 : Portb = Twi ' first byte
Case 2: 'you can set another port here for example
End Select
Return
'the following label is called when the master receives data and needs a byte
'the variable twi_btr is a byte variable that holds the index of the needed byte
'so when sending multiple bytes from an array, twi_btr can be used for the index
(only in this label have I made coding changes from the MCS example)
Twi_master_needs_byte:
#If Test = 1
Print # 1, chr(esc); Chr(pos_cur);
Printbin #1, &H54; 'line 4
Print #1,"Master needs byte : " ; Twi_btr;
#Endif
Select Case Twi_btr
Case 1: ' first byte
Twi = Low(headspace)
Case 2 ' send second byte
Twi = High(headspace)
End Select
#If Test = 1
Print #1, " TWI="; Twi;
#Endif
Return
'when the master has received all bytes received this label will be called
Twi_master_need_nomore_byte:
#If Test = 1
Print #1,"Master does not need anymore bytes";
#Endif
Return |
|
Back to top |
|
|
hgrueneis
Joined: 04 Apr 2009 Posts: 902 Location: A-4786 Brunnenthal
|
Posted: Tue Dec 15, 2015 6:07 pm Post subject: |
|
|
Alan,
why do you initiate a write cycle, if you are not going to write anything?
like this:
'
I2cstart
I2cwbyte &H40
I2cstop
'
Also, you do not need the case statement if you read high and low,
the byte count would take care of that.
If an array is used with the byte count, then you can consecutively read as many bytes as predetermined in one session.
Best regards
Hubert |
|
Back to top |
|
|
AlanGHosler
Joined: 25 Jan 2011 Posts: 109
|
Posted: Thu Jan 26, 2017 4:55 pm Post subject: Update to I2C Slave Program |
|
|
Previously I only included a portion of my program. Attached is the latest version of the entire program that uses the MSC I2C slave library. In a separated posting I will provide the circuit diagram.
Be certain when writing slave code that you do not include I2CInit, Cofig Sci or Config Sda statements in the coding; leave these for the coding of the master.
I had a problem when trying to write updates to the slave. I found that with the master continuing to interrogate the slave it interfered with writing to the eeprom. So when I am going to update the slave code I first disconnect the I2C connection between the master and the slave. |
|
Back to top |
|
|
|
|
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 You cannot attach files in this forum You cannot download files in this forum
|
|