![]() |
Forum Index : Microcontroller and PC projects : I2C
Author | Message | ||||
smudge Newbie ![]() Joined: 04/12/2014 Location: United KingdomPosts: 16 |
I’m experimenting with I2C and seem to be stuck. I’ve connected two 28 pin chips running v5.1 with 17 and 18 connected with pull-ups as in the manual. On the slave I’ve put an led on pin 15 and a DS18B20 on pin 26 I ran a small program to make sure they were both working ok. I’ then installed the slave program that is listed in the manual but when I run the subroutines, that are in the manual, on the master I don’t seem to be able to either read the DS18B20 or turn the LED on Can anyone throw any light on where I’m going wrong? |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9585 |
Are you able to post you code for both chips please? There may be a programming error, and we can't know that the program is OK or not, without seeing what you have. ![]() I have used I2C between MM chips before on a few occasions, and it does work, so it is all in the way you handle the code. I assume your pull-ups are 4k7? Smoke makes things work. When the smoke gets out, it stops! |
||||
Bizzie Senior Member ![]() Joined: 06/07/2014 Location: AustraliaPosts: 192 |
I tried the example some 6 months ago and it worked fine. I have to ask the obvious which has caught me several times :- Do you have ground connected between the MM chips? Rob White |
||||
smudge Newbie ![]() Joined: 04/12/2014 Location: United KingdomPosts: 16 |
Hi Thanks for the replies. I do have a common ground between the two chips and I'm using 10k Pullups. I'm sure I must have made a silly error in the program. The following is the code I'm using on the Master. ' Program to run on I2C Master option autorun on 'SSETPIN 15,8 I2C open 100,1000 i2c WRITE &h26,0,3,1,15,8 SSETPIN 15,8 Do SPIN 15,1 PAUSE 300 SPIN 15, 0 PAUSE 300 LOOP and the slave OPTION AUTORUN ON DIM msg(2) ' array used to hold the message I2CSLAVEOPEN&H26,0,0,WriteD,ReadD 'slave'saddressis26(hex) DO WATCHDOG 1000 LOOP SUB ReadD I2C SLAVE READ 3, msg(), recvd IF msg(0) = 1 THEN SETPIN msg(1), msg(2) ELSEIF msg(0) = 2 THEN PIN(msg(1)) = msg(2) ELSE s$ = str$(pin(msg(1))) + Space$(12) ENDIF END SUB SUB WriteD I2C SLAVE WRITE 12, s$ END SUB Thanks |
||||
smudge Newbie ![]() Joined: 04/12/2014 Location: United KingdomPosts: 16 |
Sorry forgot to mention the LED is on pin 15 and DS18B20 is on pin 26 but the code obviously is aimed at flashing the led, thought I'd tackle the DS18B20 later! |
||||
Bizzie Senior Member ![]() Joined: 06/07/2014 Location: AustraliaPosts: 192 |
Smudge, Somehow the open statement has been commented out and spaces removed! DIM msg(2) ' array used to hold the message I2CSLAVEOPEN&H26,0,0,WriteD,ReadD 'slave'saddressis26(hex)
It should read :- DIM msg(2) ' array used to hold the message I2C SLAVE OPEN &H26,0,0,WriteD,ReadD 'slave'saddressis26(hex) Rob White |
||||
panky![]() Guru ![]() Joined: 02/10/2012 Location: AustraliaPosts: 1114 |
Smudge, Also, you don't show the subroutines on the master for SSETPIN and SPIN - do you have these entered? In the slave code, you have the statement near the end ENDIF END SUB all on the same line. I think that the END SUB will not be processed but haven't tested that yet. panky ... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it! |
||||
smudge Newbie ![]() Joined: 04/12/2014 Location: United KingdomPosts: 16 |
Thanks for pointing out the silly errors, I have made progress as now whilst the following code is being run. When i disconnect power to the slave it throws up the error "Slave did not respond" so there is communication between the two but I must still have a bug in the code as the led on pin 15 doesn't flash. Slave code:- OPTION AUTORUN ON DIM msg(2) ' array used to hold the message I2C SLAVE OPEN &H26,0,0,WriteD,ReadD 'slave'saddressis26(hex) DO WATCHDOG 1000 LOOP SUB ReadD I2C SLAVE READ 3, msg(), recvd IF msg(0) = 1 THEN SETPIN msg(1), msg(2) ELSEIF msg(0) = 2 THEN PIN(msg(1)) = msg(2) ELSE s$ = str$(pin(msg(1))) + Space$(12) ENDIF END SUB SUB WriteD I2C SLAVE WRITE 12, s$ END SUB -------------------------------------- Master code:- option autorun on cls text 30,30,"Test" PINNBR=15 CNFG=8 DAT=1 I2C open 100,1000 SSETPIN PINNBR,CNFG Do SPIN PINNBR,1 PAUSE 300 SPIN PINNBR,0 PAUSE 300 A=A+1 text 30,50,str$(A) LOOP SUB SPIN PINNBR,DAT I2C OPEN 100, 1000 I2C WRITE &H26, 0, 3, 2,PINNBR,DAT IF MM.I2C THEN ERROR "Slave did not respond" I2C CLOSE END SUB SUB SSETPIN PINNBR,CNFG I2C OPEN 100, 1000 I2C WRITE &H26, 0, 3, 1,PINNBR, CNFG IF MM.I2C THEN ERROR "Slave did not respond" I2C CLOSE END SUB Any help gratefully received. Smudge |
||||
archeocomp Newbie ![]() Joined: 17/04/2016 Location: SlovakiaPosts: 4 |
Not sure what you are doing, but DS18B20 is a one-wire thermometer, not a I2C one. |
||||
smudge Newbie ![]() Joined: 04/12/2014 Location: United KingdomPosts: 16 |
Yes I know about the DS18B20 I've used it in a few projects and wondered if it could be used over I2c. Concerning the above I'm trying to use the I2c to control the outputs of the slave to start with. |
||||
smudge Newbie ![]() Joined: 04/12/2014 Location: United KingdomPosts: 16 |
Thanks for all your help and after a lot of head scratching and experimenting i've solved the problem. I inserted a pause at the beginning of the read on the slave and it works, not sure why but I'm not complaining ![]() |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6266 |
The I2C interrupt occurs as soon as any bytes are received. You have to allow a delay for all the expected bytes to finish being sent. The size of the pause is determined by the speed of the I2C and the number of bytes. Alternatively, you can read whats there and keep adding onto the end of a buffer string until the 'end of transmission' byte is received. It is up to the programmer to decide if he is going to send variable length data with end of data characters or fixed length strings. Exactly the same issues occur with normal serial communications. Jim VK7JH MMedit |
||||
MicroBlocks![]() Guru ![]() Joined: 12/05/2012 Location: ThailandPosts: 2209 |
Also a pause in a interrupt routine is best not done. Best practice (as Jim already said) is to use a buffer. That can be as simple as a string you add characters to. In the main loop you then check if the buffer contains characters and process them. Microblocks. Build with logic. |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9585 |
I agree. One of the ten interrupt commandments is: "Thou shalt not hang around or process code in interrupts." ![]() Do what the interrupt needs to do at the very least, then get the hell out of there. ![]() In your case, that wee delay in the interrupt probably won't hurt, but it is not good practise. I use flags in the interrupt, and let the main loop check those flags and act on anything that needs attention. The serial port buffers have the same issue, and you have to throttle-back the MM to allow the data to arrive. I used to make that mistake with the serial ports all the time when I was new to MMBASIC. As soon as something was in the buffer, I would loop to the code to process it, expecting the data to have arrived by the time the code got to the loop. Problem was that the MM was so bloody fast, that not all data had arrived by the time it looped, and so the testing for the correct data failed, and it dropped out of that loop not doing what was expected. ![]() MM and MM+ are faster then you think. ![]() Smoke makes things work. When the smoke gets out, it stops! |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |