I2C Sensors not detected

@Koepel, that did not fix it.

@wvmarie, there are no level shifters in the current setup. The sensors board is connected to the uno according to eliott954's schematic. I tried it with 10k and 5k pull-ups, same results but with 5k zeros appear even when the range is 1..127.

I may be able to get access to a scope to troubleshoot a bit.

So, to sum up, the critical issues still remaining are:

  1. The SI7021 is not detected at all
  2. The atmega328 board hangs with the I2C Scanner

Forget about the SI7021 for now - get at least one of the two other sensors working. That should be your priority.

One problem of the 3.3V levels on the I2C lines is that a HIGH is detected by the Arduino only at about 2.7V. So if your pull-up is too weak, it takes too long to reach that level and a 0 is read. A weaker pull-up should help (5k has better chance of working than 10k).

I don't see why your results would differ when running the I2C scanner with a larger range. It just doesn't make any sense to me. The only thing the symptoms are really compatible with is wiring problems. Some good photos of the actual setup may be enlightening.

I doubt the photo will be of much help, the wiring is exactly the same as the sensor board schematic together with elliott954's diagram.

Solderless breadboards are notorious for high stray capacitance (bad for I2C), and poor connections. Especially those thin resistor wires are often a problem (it would explain why 10k works, 5k not).

Try replugging everything into different rows.

Exactly the same output as before

Whenever you do something and the behavior changes, that is usually a good sign! The fact you can recognize the sensor suggests you are on the right track.

I very strongly agree with @wvmarle about forgetting about the SI7021 for the moment, and focus entirely on getting only one thing working. He's right. That is really, really, really a good strategy. If you get the temp sensor working by itself, then you can build on that success.

It seems like we aren't sure yet if the problem is in the code or the hardware, or both.

In this case, you may be able to rule out the software as the culprit by seeing if two Uno's can communicate with I2C using it. Where I used to work, we always called that a "golden system". A golden system is one that you know should work. If it doesn't, then something else is wrong.

For example, you might connect the two Uno's SDA and SCL lines correctly (pullups, etc...), then you are confident the hardware is good, and use your software. If it still doesn't work, then the software is very likely the problem. Right?

If you think that is a good idea, try it. I will check back later to see what you learned from it.

Besides that, I have only a few comments...

I believe you should forget about anything except 5Kohm or 4.7Kohm pullup resistors. The problem with larger ones is they affect the rise time on your clock and data lines, and that messes with the timing. I have heard of other people saying they fixed the problem with 10K, and I believe them, but I can also say that over hundreds of trials, I have never seen 5kohm fail to work if everything else is correct. Also, I've never seen 5K fail to work in the same systems where engineers had 10K.

it is the total length of all your I2C lines that matters, not the maximum distance of any single line. If your total line length exceeds 70cm, you might start encountering problems. ( I think the I2C spec says something like 76cm.. but I can't remember for sure)

Last but not least, trying to trouble shoot problems like this with voltmeters and guess work is like trying to use a weather vane to predict the weather! LOL... An oscilloscope is a great investment. In your case, the problem probably is not, but could be something like switching noise coming from a flaky chip. The only way you can rule it out is by using a scope.

elliott954:
it is the total length of all your I2C lines that matters, not the maximum distance of any single line. If your total line length exceeds 70cm, you might start encountering problems. ( I think the I2C spec says something like 76cm.. but I can't remember for sure)

That also depends on the type of cable, which conductor is which signal (this matters a lot, especially in UTP type cables), general environment, transmission speed and pull-up resistor strength. A few meters can work quite well with I2C. The main problem is the rise time due to the cable's capacitance, and cross talk between SDA and SCL.

In general it's best to keep the wires short, especially in this case. The image posted doesn't show excessive cable length so that part should be OK.

Proper level shifters to get 5V signals on the Arduino side is another thing that I would want to add in this situation. With the high stray capacitance of the breadboard there may be as much as 3-5µs of rise time before a definite HIGH level is reached with 3.3V on the 5V pins.

@wvmarle, you could be right about the 5V, but if so, doesn't that run into a potential problem with the TMP112? The datasheet says the absolute max voltage on the TMP112 is 5V and operation at absolute max is never recommended. If he wants to stick with that sensor, then his best option is to somehow make it work at 3.3V.

I suspect that if the total line length stays small, then 3.3V is probably ok. Even with breadboard, I doubt there is enough stray capacitance to matter. Could be, but I doubt it.

Before trying it with 5V, my vote is to first prove the software is not the problem by connecting two Arduino Uno's via I2C. If the software works with two Uno's, you will know the problem is not the software. If it does not work, fiddle with the software until the two Uno's can talk. You probalby should still pull the Uno's up to 3.3V, just to keep as much as possible the same between the two arduinos and the arduino with sensor design.

Bottom line is that after all is said and done, if you find you must to pullup to 5V, then you might want to find a different temp sensor than TMP112, and use one that is designed to operate with 5V.

However, I suspect that there is only a small chance that you will have to use 5V (I always try to leave a little wiggle room since I could be wrong.. hehe..)

elliott954:
@wvmarle, you could be right about the 5V, but if so, doesn't that run into a potential problem with the TMP112?

That's what the level shifters are for.

Before trying it with 5V, my vote is to first prove the software is not the problem by connecting two Arduino Uno's via I2C.

That doesn't prove the software to communicate with the sensors is OK. It just proves that the software you use to communicate with the other Arduino works, and that your I2C bus works at 5V levels. Well, you could of course use pull-ups to 3.3V to see if that is reliable.

Also the attachment to #17 is to me quite clear proof that the software and sensor do work, as otherwise there would never have been any temperature output. Occasionally the sensor did in fact return a sensible value.

That's what the level shifters are for.

Ok, but it is still worth a try.

Also the attachment to #17 is to me quite clear proof that the software and sensor do work, as otherwise there would never have been any temperature output. Occasionally the sensor did in fact return a sensible value.

To me the point is that everything is intermittent, and no solid results. Get two arduino's talking solid and reliably, then work up from a known good configuration still seems like a good strategy.

I tested the atmega board and it appears the level shifter is not working properly.

First of all, by setting A5, A4 (as OUTPUTS) to HIGH and LOW respectively, I get 3.28 and 2.88V on the 3.3V lines (shouldn't it be 3.3 and 0V ??).

Secondly, I connected the SCL and SDA 3.3V lines to a scope to see what the waveform is when the code hangs. Below is the scope output (same for SDA and SCL) with 20us/div and 1V/div.

Lastly, I tested the level shifter with a 100Hz 0-5V square pulse from a function generator as input and expected a 0-3.3V square pulse as output on the 3.3V line. Below is 5V line input (for some reason not identical as the function generator output) with 20us/div and 2v/div.

And the - unexpected - 3.3V line output with 20us/div and 1V/div.

alex_poupakis:
First of all, by setting A5, A4 (as OUTPUTS) to HIGH and LOW respectively, I get 3.28 and 2.88V on the 3.3V lines (shouldn't it be 3.3 and 0V ??).

Yes - they're not pulled down properly.

This level shifting circuit (courtesy Sparkfun) definitely works correctly:

Compare that with your circuit. It's a bidirectional shifter, and goes directly in the I2C bus; one for SDA, one for SCL. LV1 is the 3.3V lines of SDA resp. SCL, HV1 is the 5V side. LV and HV connect to 3.3V and 5V respectively.

Your image links are broken.

I fixed the links.

My circuit is the same as sparkfun's. In mine, i simply offer more pullup resistor value choices with the pcb jumpers. But, currently, the 10K pullups are soldered to +5V and +3.3V, so both circuits are the same.

alex_poupakis:
I fixed the links.

Images in #30 still don't show up.

You sure your MOSFETs are good, and wired the correct way around?

I am attaching them here.

The MOSFETs were brand new and I have checked the circuit many times.

I just tossed out a strip of MOSFETs as they wouldn't switch off... after the third of the same strip didn't work, I just tossed the rest. Dunno what's wrong with them. The second strip of the same is less bad, with a 100k resistance when switched "off"... so even brand new, that's apparently not a guarantee of a MOSFET being good.

Hi Alex,

I hope you have already solved the problem, but just in case not, here are some ideas for proceeding...

(Sorry I have been out of touch for a while! It couldn't be helped, but hopefully I will be around more the next several days)

First, let me apologize in advance for asking what might sound like "dumb" questions. I need to do that because it is kind of hard to solve these things over forum boards, and yet I need to be sure I understand exactly where you are. Unfortunately, sometimes, only dumb sounding questions work for that.

Here's the list:

  • What voltage are you pulling up to?
  • What is the supply voltage for the S17021?
  • How long are the wires on your databus?
  • finally, can you attach a drawing (even hand-drawn) of your schematic

I will check back within 24 hours.

After studying more what you guys were saying, I came up with some potentially helpful ideas.

Alex,
I can't tell if this is part of the problem, but it is worth mentioning because you said somewhere above you were expecting a 0volts for a low. That isn't completely accurate. The right way to look at it is that the "low" level you need is whatever the minimum of all your hardware is expecting according to the datasheets. For example, the Si7021 datasheet says a "low" is 0.3 x your supply voltage (e.g., if you are using 3.3V to power the Si7012, then your need to make sure you are below .3 X 3.3, or .99 volts. to be recognized as low). It also says that a High is 0.7 X supply voltage (or in this case, 2.3Volts). Anything between those two levels is "indeterminate".

An Arduino recognizes anything below 1.5 volts as "low", but notice, your Arduino can recognize a something as a "Low" that the Si7021 will consider indeterminate. Therefore, if the voltage on the wire is 1.2V, the Arduino will consider that low, but the Si7021 will not reliably interpret it's meaning.

Look at your datasheets for the TMP112, and get the low voltage for that device as well. You have to achieve whatever the lowest of all three devices is to be sure they all think it is low. Similarly, for high, you have to achieve the highest voltage of the three devices for them all to recognize it is high.

Second thing is this: While they might work, I don't yet think you need to introduce MOSFET, because I think your pull up voltages are all the same. I've only ever needed MOSFETs when two devices were expecting different pull up voltages.

It seems like you said above the TMP112 by itself works. (Is that true?) You might try the Si7021 by itself now.

Big question on your wiring for the Si7021: Where is your ADD0 line connected? The datasheet says it can be connected to one of four places to get one of four different I2C addresses. It should be connected to one of these places (see attachments), because if left floating, it might be causing the address to jump around.

I think you should forget 10 K resistors, and use 5K. This isn't causing your voltage problem on the Low side, but it appears to me your scope is showing way too much latency on the rise time. Way too much. This is probably going to affect timing, and 5K will allow a faster rise time. The datasheet shows 10K on the Si7017 typical application, but 5K should be ok.

Third thing is you have to isolate your low voltage problem. One strategy for doing that would be to disconnect the TMP112 and Si7021 devices, but leave your pullup resistors in place. then, put a scope on your clock and data lines, and have the Uno scan the bus. You might see the expected voltages. If not, you might make sure you are using the scope right, e.g., are you using 10x probes with the the corresponding setting on your scope?

if you get the correct voltage in the configuration with only an Uno, add things in one at a time until you see which one is providing the DC offset.

Lastly, you might want to add .01 mf caps on your circuit near the voltage and ground of the TMP112 and Si7021. These will eliminate switching noise cause by the internals of the respective chips. Above 400Khz, these are almost required, but at lower speeds, probably not. If you add them, place them as close as possible to the power and ground on the chips, keeping lines as short as possible.

Good luck, I'll check back later.

I forgot to attach these to my last post.

I2CStuff.zip (956 KB)