1

I am writing a program to emulate a LCD driver chip (PCF8576) in a piece of equipment where I need to replace an unobtainable LCD display.

I have wire.h set up and the code in place to decode chip commands and load the segment data to an array. That all works, and I can take that data and drive a new LCD just fine.

My problem is that the onReceive handler only triggers once. To get it to be armed and trigger again I need to press the reset button on the Uno board. I put code in to pulse an output pin and can verify with a scope that the onReceive only runs once.

When I just began the coding last week the handler would trigger each time the equipment would write to this particular I2C address, and I can tell the equipment is operating correctly since an Arduino reset will then result in the onReceive event triggering again.

Does anyone have any clue what's happening here? I tried commenting out most of my code but it still won't trigger on each receive. Obviously there's something subtle I changed that I'm missing, but what?

1

You are correct and that was the second part of the problem. The first part was that my code wasn't always retrieving every byte and this was hanging up the OnReceive function. Once I fixed that bug I found something very close to what you mentioned. On rapid device writes my handler routine didn't finish fast enough and thus could miss updates. What I did was to streamline the routine to take minimum time and that worked as the sending processor needed time between updates itself. In testing this works fine, what I did was to toggle a port pin and look at the I2C bus and that pin and could verify I was cleared out of the routine before the next update could come in. If it was close I would have gone to assembly for that routine but it turned out ok in this case. Thank you for your analysis!

|improve this answer|||||
  • If you have solved your own problem, please accept your own answer. – Nick Gammon Jul 23 '17 at 4:12
0

I looked at what docs I can find (not much) for 'onReceive' handler, but have not looked at the code itself. I would ask, does the system keep running in spite of the fact that your handler isn't being invoked? I'm asking if the bus is actually working after the first invocation of the handler? My guess is no. I also guess this ("onReceive" handler) has never worked as designed (hoped for?)

Also it sounds like you have a DSO scope, neat. Decades in electronics and I still get fooled by them (or the software:) now and then. So make sure it's setup properly. Sounds like you do... but...

Does the i2c bus have only this one device?

I've found that 99.99% of my problems turn out to be chip configuration. Improper interrupt or mask bits, etc. If it's driven by an interrupt, then it almost has to be the chip's interrupt configuration. Of course if your code goes awry then it could change some of these bits that control the micro's operation and most can also write over the interrupt vector table.

Since it works after a reset, once, it may be wise to track down what happens in your particular micro's configuration after the reset, compared to what you change to get it to work. Some of the parts of the micro I use (328p, maybe you also) have to be reset after an interrupt.

A last but not least option, since I'm not familiar with the function is to look at the assembler and see if it's resetting the required interrupt enable flags or masks. Most of these handlers end with some type of return from interrupt instruction that enables the interrupts and returns. Generally alleviating the programmer of that task.

Best of luck :)

|improve this answer|||||
0

An Arduino as a I2C Slave to replace something in a device often fails. The Arduino uses hardware and software, while I2C chips use only hardware. The Arduino as Slave is often recognized on the I2C bus because it acknowledges to its I2C address. However, as soon as data needs to be transferred, the Arduino stretches the clock signal to create some time to call the onReceive function. Do you know if the I2C Master controller is able to handle the clock pulse stretching ? Sometimes it is a software I2C, and almost no software implementation takes care of clock stretching.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.