Odd problem with an MCP23017 - Page 1
Forum section: electronics / beginners

author: HwAoRrDk
author_rank: Super Contributor
timestamp: March 23, 2016, 05:44:38 pm
content: I am using an MCP23017 I2C I/O expander in a circuit, and I'm having a frustratingly odd problem with it that I can't figure out.The circuit is as in the schematic attached below. I have the MCP23017 interfacing to an L293E motor driver, plus some status LEDs. The I2C bus is hooked up to an Arduino (there is also an MCP23008 on the bus, with a pair of 10K pull-ups). The L293E is connected to a pair of motors, via the usual flyback diodes to +12V and ground.If I leave all the wires from the MCP23017 to the motor driver disconnected, leaving just the LEDs, I can operate the MCP23017 just fine; writing values to GPIOA, turning the LEDs on/off, etc. - as if I were making the desired inputs to the motor driver. Conversely, if I connect the motor driver input lines straight to the I/O pins of the Arduino (ignoring the MCP23017), I can drive the motors perfectly fine. So, I know that both my I2C communications and the motor driver are working properly.However, if everything is hooked up exactly as in the schematic (or even without the LEDS), with the GPIOA pins controlling the motor driver, I get some strange behaviour. The very first time I write values to GPIOA - bits 0 and 2 high (for the L293's EN1 and IN2), for example - the relevant pins go high, the motor driver begins to run the motor, but then after a fraction of second, the pins unexpectedly drop low again, and the MCP23017 then effectively goes dead to the world until everything is reset!I can't figure out what's causing this behaviour. It's very frustrating!What the hell is it about having the MCP23017's I/O pins controlling the L293E's inputs that makes it do this?The other annoying thing is that at some point during all my troubleshooting and countless experimentation trying to solve this, pin GPIOA2 is now fried and doesn't work any more, which is just icing on the cake!

author: HwAoRrDk
author_rank: Super Contributor
timestamp: March 24, 2016, 05:46:54 pm
content: No-one with any ideas?

author: Andy Watson
author_rank: Super Contributor
timestamp: March 24, 2016, 06:10:33 pm
content: The inductive kick-back from a motor can play havoc with uC outputs, although, I would hope that the 293 would provide sufficient isolation I would suspect some form of ground-bounce.Have you taken precautions to ensure that the path of the motor current does not interact with the ground/Vcc of the MCP23017?Can you hang a scope on the lines between the MCP23017 and the 293?Can you replace the motors with similar resistive loads?

author: HwAoRrDk
author_rank: Super Contributor
timestamp: March 24, 2016, 06:38:30 pm
content: I can certainly try to isolate the motor power and ground from the MCP23017 as much as I can. At the moment, I have the +12V being provided by an AC adapter into the jack on the Arduino, and then from the VIN pin on there to a rail on the breadboard, where it is feeding the L293E's VS pin; the ground path for the motor current (which I believe is through the SENx pins, not the GND pins, right?) is just going back to the same ground rail as everything else. Would running a separate jumper wire from the current-sense resistor back to one of the GND pins on the Arduino provide enough separation? I'm not sure what else I should/could do...I have already put a scope on the lines between the MCP23017 and the L293E, which was how I found in the first place what was going on. The behaviour is as I described earlier. First attempt at a high output from one or more of the MCP's I/O pins results in a short 'blip' high to 5V (about 10-15ms), then back low again to 0V. The MCP then appears to 'lock up', with any further attempts at manipulating the outputs over I2C inducing no activity until it's either reset or power cycled. Anything else I should be looking for?How would I determine what a similar resistive load would be, and what would that test? I'm not sure how I'd go about that. I don't think there's anything wrong with the motors, as the L293E can drive them just fine when under control from the Arduino directly.

author: Andy Watson
author_rank: Super Contributor
timestamp: March 24, 2016, 07:39:40 pm
content: The point about using the resistors is that they should not have any inductive component and hence no possibility of generating over voltage. It would be a means of eliminating one of the possible causes. The resistor value should be such that it will cause a similar current to the motor (whatever that is).QuoteWith no other action/events! Can you simultaneously hang the scope on the Vcc line?

author: HwAoRrDk
author_rank: Super Contributor
timestamp: March 24, 2016, 09:17:18 pm
content: Ah, I see. Should I be aiming to duplicate peak current or steady-state current? The former is about 800-900mA, the latter about 200-300mA. I will have to see what I can rustle up with the resistors I have at hand; most definitely will need to use some in a serial/parallel combination to handle the power dissipation.Yes, no external action or events. No other communication on the I2C bus. The MCP23017 is dropping the output low again of it's own accord for some reason.I only have a single-channel 'toy' scope, so can't monitor both output pin and VCC at once. But, of course, the LEDs show me what's happening with the outputs - the high 'blip' it does manage is long enough to briefly flash one. I shall have a look at what the VCC is doing. I suppose I'm looking for some kind of spike or drop-out? Also, I guess it might be worth checking what's happening with the reset line too.

author: HwAoRrDk
author_rank: Super Contributor
timestamp: March 25, 2016, 04:35:54 pm
content: I put a scope on the VCC pin of the MCP23017, and the only thing I found was that it would drop about 0.8V for approx. 10-20ms while the output pins go high. No over-voltage spikes at all, nor severe under-voltage spikes.Then I decided to check the reset pin. That would drop about 0.2V during output, over a period of about 1ms. It seemed to me that such a voltage drop was fairly insignificant, but just in case I decided to try putting a 0.1uF cap between reset and ground. I've seen it done elsewhere (in particular an app note from Atmel where they recommend such a thing for AVRs), but there is no mention of anything to do with caps on the Microchip datasheet or app notes I could find.SUCCESS! It works!So I guess the MCP23017 was resetting itself, and because when it comes up all the ports are by default configured as inputs, that's why any further port writes over I2C didn't have any effect.I put the scope back on the reset line to see what exactly the difference was. But I'm puzzled, because as far as I can see, there's barely any change. The voltage still sags, by about the same amount. The drop-off is alittlesmoother, perhaps? I dunno. If somebody could take a look at the attached shots of scope captures before/after and tell me if there is any significant difference there, because I can't see any.

author: HwAoRrDk
author_rank: Super Contributor
timestamp: March 26, 2016, 05:33:04 pm
content: Sigh. Now I have the cap on the reset pin of the MCP23017, my Arduino won't auto-reset when attempting to upload.I can see on the scope the reset line doesn't go low at all. It seems like it tries, as there is the very tiniest of dips, but obviously nothing significant enough.What can I do to remedy this situation? Seems like I'm damned if I do and damned if I don't.

author: Andy Watson
author_rank: Super Contributor
timestamp: March 26, 2016, 09:09:10 pm
content: Quote from: HwAoRrDk on March 25, 2016, 04:35:54 pmWork out why this is happening:Quote0.8 V is a substantial proportion of the supply voltage - I wouldn't be surprised if this dip was causing some sort-of brown-out condition. Also:-Quote0.8 - 0.2V, that's enough to turn on a silicon junction. Is it possible that the chip is deriving power from one of its other pins whilst the dip in the power supply occurs? Injecting enough current, even for the briefest of moments, into the wrong pin whilst the Vcc is too low, could put the chip into an indeterminate state.

author: AndrewDojo
author_rank: Contributor
timestamp: March 27, 2016, 07:57:37 pm
content: Suggest that you:1. Add the protection diodes across the motor(s) as per the L293E datasheet reference schematics;2. Add 100uF and 0.1uF local caps to the 12V line at the L293E (see Fig 11 as example);3. Connect the SENx pins direct to ground. Sense resistor is used by an external current control circuit that you aren't providing. [Take or leave this]

author: mikerj
author_rank: Super Contributor
timestamp: March 28, 2016, 11:17:38 am
content: Quote from: HwAoRrDk on March 25, 2016, 04:35:54 pmWhat oscilloscope are you using? Without wishing to be rude, it looks very much like one of those toy oscilloscope kits, in which case it's most unlikely to have anything like enough bandwidth to see the edge which is causing the reset.

author: HwAoRrDk
author_rank: Super Contributor
timestamp: March 28, 2016, 01:11:29 pm
content: Quote from: AndrewDojo on March 27, 2016, 07:57:37 pm1. I do have protection diodes. I did note that on the schematic I originally posted.2. I'll give that a try.3. I am in fact doing current-sensing, but I omitted that from the schematic for brevity.Quote from: mikerj on March 28, 2016, 11:17:38 amYou would be right.It says it's good for 200KHz, but I take that with a large pinch of salt. Perhaps I should have captured at a much smaller timebase (< 1ms) and and vertical sensitivity to see the difference. Wish I had a proper 'scope, but can't justify the expense for a hobby project that may or may not bear fruit.I think Andy Watson is right, I need to look at my power supply and see if it is good enough.

author: HwAoRrDk
author_rank: Super Contributor
timestamp: April 13, 2016, 05:06:57 pm
content: Hello again. After a short break I am revisiting this problem.I decided that messing around with solderless breadboard and AC power adapters of unknown provenance was too much of a headache. So, in an effort to discount any connection/interference/power problems, I have done two things: a) procured some stripboard and soldered up my circuit in a more permanent fashion; b) found a spare PC ATX power supply and used that to power everything.So, all good now, right? No! I was extremely exasperated to find I apparently still had thesamedamn problem with the MCP23017 resetting itself!But, I think I have found the cause in this instance, which is kind of similar in nature to what was happening before, but not quite.I checked with the scope again for any kind of sagging on the reset pin of the 23017, but didn't see anything at all - it was rock-steady. Confused that I wasn't having precisely the same issue as last time, I decided to apply Dave's rule #1: "Thou shalt measure voltages". I found that my ATX PSU is actually a little off-spec with the voltage levels at such low loads; +5V is actually 5.3V, and +12V is actually 11.5V, although at least both are solid and interference/ripple-free. The reset line voltage on the Arduino, however, is for some reason only 4.85V in the high state. That's nearly 0.5V lower than the MCP23017's +5V supply voltage. Aha!So, what I guess is happening is that the 23017 is seeing this voltage difference and interpreting that as a reset. To check this, I tied the 23017's reset pin with a 10K pull-up resistor to the 'full' +5V, and the problem goes away.As to why it reset only when I tried todoanything with the 23017, I can only theorise that perhaps the whole chip is running according to the I2C clock, and it only checks the reset pin state once per cycle (or some similar mechanism). Can anyone comment on that? Also, the datasheet says the reset pin's low threshold is supposed to be 20% of VDD - 1.06V in my case. That's quite a way below what it appears to be doing in practice.But, back to the nub of the problem: my Arduino's reset line 'high' voltage is too low. Why? The 5V pin is at 4.99V, so pretty much spot-on, so it's not as if the Arduino's 5V regulator is dodgy.However, I suppose I have to address the more general problem that my Arduino's '5V' is not at the same level as '5V' of the rest of my circuit. I need to make them equal. I can think of several possible ways to go, but each seems to have a drawback:Supply the PSU's +12V to the Vin pin - doesn't help, as the on-board regulator's 5V output will still be lower.Supply the PSU's +5V to the Vin pin - can't, as the on-board regulator has a dropout of about 1.1V, so needs > 6V.Supply the PSU's +5V to the 5V pin, bypassing the on-board regulator - have read that this is not recommended, as it also bypasses the automatic Vin/USB power source selection, leaving the 5V being fed both externallyandfrom USB. Not only that, but I also read that 'backfeeding' a higher voltage (5.3 vs. 5V) to a linear regulator's output is not good for the regulator.In summary, I am now stuck in a catch-22 situation. Could tie the 23017's reset pin to VCC, but then I lose the facility to have it reset itself whenever the Arduino does. Could 'force-feed' the Arduino with external 5V, but then I cannot simultaneously use the USB connection, and it might be bad for the on-board regulator chip.I don't know how to solve this situation. Anybody got any ideas?

author: Kjelt
author_rank: Super Contributor
timestamp: April 13, 2016, 08:56:04 pm
content: If I look at the datasheet in the electical section it clearly states for the reset pin:a low input is max 0.2 Vdd so max 1 Va high input is min 0.8 Vdd so min 4VSince the /RESET is schmitt triggered it will NOT reset unless the input voltage will reach below 1 V.To be 100% sure the voltage should not be lower than 4V in your case it is absolutely fine.So I really have no idea why you say that below 4.85V it would resetMy own experience with the 23016 (without reset) was horrible. I got all kinds of stuck situations were the I2C data line was kept low by the expander and I had to clock it free again. To unreliable to trust in my case and I switched to a simple serial to parallel shift register that works as it should.Now I know a lot of people having no problems and using it in products so do not let it put you off.

author: Kjelt
author_rank: Super Contributor
timestamp: April 13, 2016, 09:08:34 pm
content: And your question about the reset being polled is also in the datasheet: noIt clearly states that 1us reset pulse low will directly reset the device (delay 0 ns) and the high impedance output state will be reached within 1usTable 2.2 and figure 2.1Check your Vdd rise time after power on, how long does it take?

author: HwAoRrDk
author_rank: Super Contributor
timestamp: April 14, 2016, 01:13:23 am
content: If that is the case for the reset pin - that it should not be triggering unless it sees a voltage below 1V - then I am confused, as at no point have I seen that occurring. Since I've been using a proper power supply, the reset line voltage is rock-steady at all times - regardless of source it's connected to (Arduino or +5V w/pull-up). The only difference I can see between not-working and working is the Arduino gives a reset line around 0.45V less than VDD, whereas with reset = VDD, it works.I can try and measure VDD rise time after power-on, but I'm not sure why it would be different between the two scenarios. Anyway, I am fairly sure the 23017 is powering-up just fine, as all my I2C setup code (e.g. setting GPIO ports to output, etc.) executes fine, and for a brief moment the GPIO portsdoactuate as they should when I give the command, butsomethingcauses it to reset.Was originally going to use shift registers, but unfortunately I ran out of I/O pins on the Atmega. Plus I2C vastly simplifies the PCB layout. So I really need to persevere and try and solve this problem with the MCP23017.

author: Kjelt
author_rank: Super Contributor
timestamp: April 14, 2016, 11:57:58 am
content: Well the chance that you found such a major bug in that silicon without anyone in the world having noticed this till now is less than winning some lottery.So I suggest you isolate the chip from the motor application, leave the leds on.Put a 100nF cap between /Reset and ground and a small 10k or 5k or something potentiometer with onle leg to Vdd the other leg to ground and the runner to the reset pin.Set the potmeter that Reset line (runner) gets the 5V. Start your test application lighting up one or more leds , stop and now slowly turn the potentiometer till the leds go out (reset).Measure the voltage on the reset line (runner) to ground. This should be around 1V or less, if this is indeed 4,6V or more something fried your chip. Garbagecan buy a new one.

author: HwAoRrDk
author_rank: Super Contributor
timestamp: April 15, 2016, 12:20:48 am
content: Yeah, I know it's extremely unlikely there's a bug in the chip. Which makes it all the more frustrating to think there's something I'm not doing right, or missing out, or external factors at play.I already know that putting a 100nF cap on the reset line cures the problem, as I did this the first time round. But that causes yet another problem: the Arduino then can't auto-reset when programming over USB. I tried that again just now, but same result: my circuit works, but Arduino won't auto-reset. Reset could only be pulled down as low as 2.7V, which is obviously not good enough.A thought just occurred: would perhaps a smaller value capacitor avoid this? I think I have some 47nF and 10nF I could try.Just for kicks, I measured my VDD rise time on the 23017. It takes 14ms, for a rate of 0.38V/ms - substantially quicker than the 0.05V/ms specified as a minimum in the datasheet. No problems there then.Oh, and I don't think I mentioned this before: the 23017 I'm using at the moment is a brand-new chip, different to the one I used previously. Literally the first thing I did with it after taking it out of the package was to put it in the socket, power on my board... and problem occurred.

author: Kjelt
author_rank: Super Contributor
timestamp: April 15, 2016, 08:06:00 am
content: Ok I never used the Arduino stuff but are you saying that the reset line of your host microcontroller is connected to the reset line of the 23017?Because personally (tastes differ) I always design that peripheral ic's like the port expanders can be reset by the host microcontroller without resetting it self.Port expanders esp. I2C versions have a tendency to hang the I2C bus, you can than reclock it till it gets loose again but a quick reset might as well be a better and more definitive solution.(ofcourse this means that you need to design your hardware such that at any point in time of operation a hard reset of the 23017 can cause no harm to the rest of the system)Also I do not understand why you can not go lower then 2,7V with a 100nF cap attached, only thing I can come up with it is that the low reset pulse it too short, not able to drain the capacitor. If that is the case some extra small helping circuit like a mosfet could do the trick, the fet could short the capacitor with a larger current (low ohm resistor). Something like that.

author: HwAoRrDk
author_rank: Super Contributor
timestamp: April 15, 2016, 03:40:44 pm
content: Yes, the reset lines are connected together. Sorry if that wasn't obvious from all my previous posts.I hadn't thought about having the I/O expanders reset being controlled by an MCU I/O pin. I can see how that might be useful. Although, I haven't experienced any I2C communication problems, so being able to independently reset slave devices is not something I really have a need for (yet - touch wood!). Not sure how I'd even detect I2C hangs, as the Arduino's Wire library is fairly high level, and you only get a pretty abstract status code as return status for transmission.Yeah, I guessed the low reset pulse coming from the USB interface controller is too short. Pity I can't measure it by probing that circuit on the Arduino, as the TQFP pins of the Atmega16U2 (which controls the USB interface) are far too small. And, of course, I have no control over that anyway, as the pulse length will either be defined by code in the Arduino IDE or perhaps the firmware of the 16U2.Anyway... I tried a couple of smaller capacitor values earlier, and I actually got the auto-reset working properly!With a 47nF cap, the voltage was able to be pulled down to 1.8V. Not being sure if that would be enough to reset the MCP23017 as well, I also tried a 10nF. That also worked, with the voltage pulled down to around 0.9V. I think this should do the trick of resetting everything, although I shall have to properly test it. I might try a slightly smaller capacitor value (perhaps 4.7nF), just to be sure.

author: Kjelt
author_rank: Super Contributor
timestamp: April 15, 2016, 05:13:52 pm
content: Keep us posted how it is going.Concerning a hanging I2C bus, your software should recognize it and handle it. The I2C data line will be stuck low, you can read it when in idle state and if it is low you have a problem.Hope you will not have problems with it as I did, I read a lot of data from the expander, writing now and then was no problem, but reading with 100's times a second was a bit much although it should be able to handle it (probably more nuisance from my ST- I2C peripheral that caused this).