Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : I2C String transfer
Author | Message | ||||
Justplayin Guru Joined: 31/01/2014 Location: United StatesPosts: 313 |
I've just started playing around with I2C with the idea of transferring data back and forth between a Maximite and a Micromite. I can successfully transfer a 5 character string at 400K. At 200K and slower characters are lost. Scale up the 400K transfer to 10 characters and it starts dropping characters too. I am sure I am doing this all wrong since I have no idea what I'm doing. I would like to reliably transfer 128 bytes or more at a time. Below is the two programs I'm testing with. The Maximite sends some characters to the Micromite. The Micromite receives the string and prints what is received then sends it back to the Maximite which prints the string. So... What am I doing wrong? Maximite Master: I2C OPEN 400, 500
k$ = "12345" looper: I2C WRITE &H26, 0, 5, k$ pause 50 I2C read &H26, 0, 5, j$ Print j$ j$="" goto looper Micromite Slave: I2C SLAVE OPEN &H26, 0, 0, WriteD, ReadD
Do WatchDog 1000 Loop ReadD: I2C SLAVE READ 5, msg$, recvd x$ = msg$ Print x$;" "; Len(x$), recvd IReturn WriteD: I2C SLAVE WRITE 5, x$ IReturn Is there a bug in the SLAVE WRITE command? If I try to send a single character the program crashes with a message saying expecting a number. Two characters or more works fine. --Curtis I am not a Mad Scientist... It makes me happy inventing new ways to take over the world!! |
||||
Chris Roper Senior Member Joined: 19/05/2015 Location: South AfricaPosts: 280 |
If you have a PICKit Programmer you could use the Logic Tool to capture the Clock and Data signals during the transfer. I have not tried it with the MicroMite yet but it has helped me debug I2C on other PIC32 applications in the past. The PICKit logic tool is often overlooked but I personalty think it is worth buying a PICKit 2 for the Logic tool alone. That is why I keep mine even though I have an ICD3 for programming and debugging. Cheers Chris http://caroper.blogspot.com/ |
||||
Bizzie Senior Member Joined: 06/07/2014 Location: AustraliaPosts: 185 |
See this post Is almost the same problem, you need a pause after the I2C read. Rob White |
||||
Justplayin Guru Joined: 31/01/2014 Location: United StatesPosts: 313 |
I tried adding pauses after every read and write... same results. Increased values until the watchdog kicked in then I upped the watchdog time too. --Curtis I am not a Mad Scientist... It makes me happy inventing new ways to take over the world!! |
||||
Justplayin Guru Joined: 31/01/2014 Location: United StatesPosts: 313 |
Hey Rob, after looking through the thread again I came to a conclusion... Duh! The pause works better BEFORE the read to give the data time to arrive. I kept putting the pauses after. Things are now working much better, but I have a lot more testing to do. --Curtis I am not a Mad Scientist... It makes me happy inventing new ways to take over the world!! |
||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9078 |
I realise you have pretty much settled this issue down, but I have always has isses with sending long strings with the I2C. SHORT strings are no problem, but if you are trying to send long strings like you are, I found that byte-at-a-time with acknowledge works exteremely well, with zero dropped characters, and pretty respectible speed. This is how I am doing it: I2C MASTER: DTA$=L1$+L2$+L3$+L4$+L5$+Chr$(250) P=1 I2C open 100,100 Timer=0 Do BYTE=Asc(Mid$(DTA$,P,1)) I2C write &B1010101,0,1,BYTE 'Transmit byte I2C read &B1010101,0,1,BUF 'Wait for acknowledge byte P=P+1 Loop Until BYTE=250 Print "Done. (";Timer;")" End The master code sends one byte at a time, and waits for the slave to acknowledge. This byte can be anything really, but I chose 250 decimal. This EOM(End Of Message) byte must be added to the end of the string to send as in the example above. In this example, L1$-L5$ were just lines of text, and they are added together to make one big string for the purposes of testing. I2C SLAVE: TESTI2C: Flag=0 Open "com1:19200" As #1 Open "com2:2400" As #2 I2C SLAVE OPEN &B1010101,0,0,I2C_OUT,I2C_IN Print "Waiting for I2C data..." Do If BITE=250 Then Print DTA$ DTA$="":BITE=0:B=0 EndIf Loop I2C_OUT: I2C SLAVE WRITE 1,75 'Send K acknowledge byte IReturn I2C_IN: I2C SLAVE READ 1,BITE,BUF DTA$=DTA$+Chr$(BITE) B=B+1 IReturn End The slave code sends a "K" for every character it receives from the master, and the master WAITS till it gets this "K" back from the slave before it tries to send another byte to the slave. This goes around in circles until the EOM, at which point the main loop picks up on that and prints out the message. This was just for testing purposes, and was further expanded to suit my purposes, but this method seems to work flawlessly for long strings - I have not been able to find any errors in data during my testing, and yes - also runs at 400kHz.(provided your I2C interconnecting is done correctly) Smoke makes things work. When the smoke gets out, it stops! |
||||
Justplayin Guru Joined: 31/01/2014 Location: United StatesPosts: 313 |
Thanks Grogster, I'll have to wait and take a look at your code tomorrow... It's getting late here. --Curtis I am not a Mad Scientist... It makes me happy inventing new ways to take over the world!! |
||||
Print this page |