Author Topic: Arduino and Wire.endTransmission()  (Read 17052 times)

0 Members and 1 Guest are viewing this topic.

Offline DajgoroTopic starter

  • Frequent Contributor
  • **
  • Posts: 322
  • Country: hr
    • hackaday.io
Arduino and Wire.endTransmission()
« on: April 11, 2014, 01:08:16 am »
Hi.

Today I poked a bit with arudinos I2C library, and the thing won't work, as usually.

I got a I2C scanner sketch from the web, and uploaded it to the thing, and it crashes upon Wire.endTransmission().
I tried another sketch, same thing.

I am running the arduino at 3.3V, 2k pullup. No difference with or without devices on the bus.

On one occasion the I2C scanner started detecting I2C devices on all addresses.

I googled the issue, and I found other posts complaining about the issue, but I didn't find any definitive answer.

What could be the issue?
 

Offline linux-works

  • Super Contributor
  • ***
  • Posts: 1999
  • Country: us
    • netstuff
Re: Arduino and Wire.endTransmission()
« Reply #1 on: April 11, 2014, 01:21:49 am »
2k is a bit low.  why 2k?

for breadboard testing, I have not needed pullups for i2c on my arduinos.  if you run the i2c cable longer than 2 feet, say, then a pullup would help.

I would remove it and try again.

are you also sure about the i2c addr?  you know that its not a normal i2c address right?  one bit is for send or receive (direction) and its a bit odd how arduino lib does it.  see if shifting left or right 1 bit helps (ie, try diff addr's).  I forget the details but this is always a sticking point for new arduino guys.

Offline scott216

  • Regular Contributor
  • *
  • Posts: 112
  • Country: us
Re: Arduino and Wire.endTransmission()
« Reply #2 on: April 11, 2014, 02:28:24 am »
I've used I2C with Arduino's several times and it works well for me.  But like the previous post said, the wires can't be very long.  Also, I prefer to use a different library then wire.h that comes with the Arduino IDE.  Plus the library I use has a timeout feature.  With wire.h library, if there is a problem, then it just hangs indefinitely, which sucks.  You can find the library here: http://dsscircuits.com/index.php/articles/66-arduino-i2c-master-library
and here: https://github.com/DSSCircuits/I2C-Master-Library
 

Offline Legion

  • Frequent Contributor
  • **
  • Posts: 360
Re: Arduino and Wire.endTransmission()
« Reply #3 on: April 11, 2014, 02:37:12 am »
I haven't tried scanning for I2C devices, but I did just write a program that talks to both a 7 segment display and two humidity sensors all over I2C and never had any crashes. Could you link to the code you're running?

Here's the program I wrote: https://dl.dropboxusercontent.com/u/91808950/Humidity.ino

On an Arduino Uno with nothing hooked up, this is the output you should see. Try it and see if it crashes.

>>>>>>>>>>>>>>>>>>>>>>>>
Diagnostic.
Sensor A RH%: 99.9  Sensor A Temperature: 256.95
Diagnostic.
Sensor B RH%: 99.9  Sensor B Temperature: 256.95

Average RH%: 99.93     Average Temperature: 256.95
 

Offline scott216

  • Regular Contributor
  • *
  • Posts: 112
  • Country: us
Re: Arduino and Wire.endTransmission()
« Reply #4 on: April 11, 2014, 02:40:39 am »
You probably now this, but just in case: The Arduino's have dedicated pins for I2C communication
See: http://www.arduino.cc/en/Reference/Wire
 

Offline DajgoroTopic starter

  • Frequent Contributor
  • **
  • Posts: 322
  • Country: hr
    • hackaday.io
Re: Arduino and Wire.endTransmission()
« Reply #5 on: April 11, 2014, 03:06:10 am »
I haven't tried scanning for I2C devices, but I did just write a program that talks to both a 7 segment display and two humidity sensors all over I2C and never had any crashes. Could you link to the code you're running?

Here's the program I wrote: https://dl.dropboxusercontent.com/u/91808950/Humidity.ino

On an Arduino Uno with nothing hooked up, this is the output you should see. Try it and see if it crashes.

>>>>>>>>>>>>>>>>>>>>>>>>
Diagnostic.
Sensor A RH%: 99.9  Sensor A Temperature: 256.95
Diagnostic.
Sensor B RH%: 99.9  Sensor B Temperature: 256.95

Average RH%: 99.93     Average Temperature: 256.95

I uploaded the code, and I get this:
Code: [Select]
??????????????????????
That is because it start transmitting the >>>>>>>>>>>>>>>>>>>>>>>> string, and it crashes.
If I add a extra delay, it prints out >>>>>>>>>>>>>>>>>>>>>>>>, and then it restarts in a infinite reboot loop.

It is the same thing with every sketch.

As for the I2C lines, they are 10cm long.

When checking with a scope, I can see some small voltage drop on the bus before the transmission, and after that the signal goes low for a cycle, and then it crashes.


Quote
With wire.h library, if there is a problem, then it just hangs indefinitely, which sucks.  You can find the library here: http://dsscircuits.com/index.php/articles/66-arduino-i2c-master-library
and here: https://github.com/DSSCircuits/I2C-Master-Library
Thanks, I'll try that.
 

Offline m12lrpv

  • Regular Contributor
  • *
  • Posts: 175
  • Country: au
Re: Arduino and Wire.endTransmission()
« Reply #6 on: April 11, 2014, 03:13:18 am »
Wire.endTransmission() is when it actually does the transmission. Up to that it's just preparing the instruction, commands and buffering your data.

I play a bit with I2C and arduino's, atmega328 and attiny's and because i'm lazy about checking which wire is which I often get them back to front which is my biggest issue. If it doesn't work I switch them and try again.

The scanning sketch is the simplest and always a first start.

I'm intrigued that you're running at 3.3v which indicates that you're not running an uno so you might want to tell us what you're actually using.

Also you should tell us what I2C device you're trying to connect to.

Hopefully the scanner you're using is this one
http://playground.arduino.cc/Main/I2cScanner

You should be able to run it without any devices connected and have it work without crashing. Always a good starting point.
 

Offline linux-works

  • Super Contributor
  • ***
  • Posts: 1999
  • Country: us
    • netstuff
Re: Arduino and Wire.endTransmission()
« Reply #7 on: April 11, 2014, 03:13:47 am »
which chip are you using, again?  did I miss that?  328 or something else?

why 3.3v?  are the i2c devices also 3.3v based?

can your cpu run at 5v?

I have not done any arduino 3.3v work, all my arduino experience is with 328 chips and 5v/16mhz.  I've not had any problems doing i2c i/o with a variety of i2c port expanders, dacs, etc.  the arduino wire.h library does work and works fine, you should not need to use another unless you need to support timeouts.  I have not found the need for that, in a system that does not change.

Offline m12lrpv

  • Regular Contributor
  • *
  • Posts: 175
  • Country: au
Re: Arduino and Wire.endTransmission()
« Reply #8 on: April 11, 2014, 03:15:51 am »
Try a serial test. Looks like your baud rate might be wrong.
 

Offline Legion

  • Frequent Contributor
  • **
  • Posts: 360
Re: Arduino and Wire.endTransmission()
« Reply #9 on: April 11, 2014, 03:26:04 am »
I uploaded the code, and I get this:
Code: [Select]
??????????????????????
That is because it start transmitting the >>>>>>>>>>>>>>>>>>>>>>>> string, and it crashes.
If I add a extra delay, it prints out >>>>>>>>>>>>>>>>>>>>>>>>, and then it restarts in a infinite reboot loop.

It is the same thing with every sketch.

As for the I2C lines, they are 10cm long.

When checking with a scope, I can see some small voltage drop on the bus before the transmission, and after that the signal goes low for a cycle, and then it crashes.

It's definitely not the code then. Which arduino are you using?
 

Offline DajgoroTopic starter

  • Frequent Contributor
  • **
  • Posts: 322
  • Country: hr
    • hackaday.io
Re: Arduino and Wire.endTransmission()
« Reply #10 on: April 11, 2014, 04:18:45 am »
It is a arduino uno, but with the chip itself on a separate board with a 3.3V reg.
I connected the atmega328 to the arduino with no chip, so I can use the arduino serial programmer.
The atmega runs the stock bootloader, with modified fuse settings so that the brownout detector doesn't disable the thing on 3.3V.

I have to use 3.3V because all of the I2C and pheripherals are 3.3V, and the battery on which is this supposed to run from is 3.7V. As for the regulator it is a MIC2900-3.3.
The I2C devices are the classical mems devices, accelerometer, magnetometer, etc... + a rtc, which is not even connected yet.
Connected or not, it is always the same thing, when probing with the scope it only pulls the bus lines low for a brief moment and that is it.

The serial port works just fine, the problem is that when it crashes it doesn't finish to write the string, which corrupts the serial stream.

When I remove the I2C stuff it works just fine.
 

Offline linux-works

  • Super Contributor
  • ***
  • Posts: 1999
  • Country: us
    • netstuff
Re: Arduino and Wire.endTransmission()
« Reply #11 on: April 11, 2014, 04:31:21 am »
I've used level converters before and so the devices can all be 3.3, but they hang on one end of the level converter.  the other end goes to a 5v arduino.  I seem to remember that if you don't run at 5v/16mhz then timing may be off for many things.  maybe that's why your serial i/o is not working, as well?

I have not used arduino chips at 3.3v and I've stayed at the most travelled route of 5v/16mhz.  things just plain work, then, I guess.  I've done literally dozens of arduino projects, most using i2c, and they all just plain work.  but again, I'm sticking with the most common arduino ever, the 328 dip at 5v/16mhz.  v22 of the IDE or even v1.x of that 'new stuff' that they now do (.ino or something?  lol)


Offline m12lrpv

  • Regular Contributor
  • *
  • Posts: 175
  • Country: au
Re: Arduino and Wire.endTransmission()
« Reply #12 on: April 11, 2014, 04:42:45 am »
If you run the scanning program I linked to with no devices connected does it crash? This confirms that there isn't an internal problem with the micro.

It sounds like your program is more involved that just a basic test. You wouldn't be trying to do the I2C from within an interrupt would you?
 

Offline DajgoroTopic starter

  • Frequent Contributor
  • **
  • Posts: 322
  • Country: hr
    • hackaday.io
Re: Arduino and Wire.endTransmission()
« Reply #13 on: April 11, 2014, 11:41:57 am »
If you run the scanning program I linked to with no devices connected does it crash? This confirms that there isn't an internal problem with the micro.

It sounds like your program is more involved that just a basic test. You wouldn't be trying to do the I2C from within an interrupt would you?

It always crashes, devices or no devices, pullups or no pullups.

Edit: The mcu is brand new.
 

Offline Legion

  • Frequent Contributor
  • **
  • Posts: 360
Re: Arduino and Wire.endTransmission()
« Reply #14 on: April 11, 2014, 12:10:05 pm »
Have you tried resetting the fuse settings to default and running at 5V? Then try 5V with modified fuse settings, then 3.3V. Basically, start with the only difference between your setup and the UNO being the chip is off the board. Then change one thing at a time and see what specifically causes the problem.
 

Offline DajgoroTopic starter

  • Frequent Contributor
  • **
  • Posts: 322
  • Country: hr
    • hackaday.io
Re: Arduino and Wire.endTransmission()
« Reply #15 on: April 11, 2014, 12:38:04 pm »
Have you tried resetting the fuse settings to default and running at 5V? Then try 5V with modified fuse settings, then 3.3V. Basically, start with the only difference between your setup and the UNO being the chip is off the board. Then change one thing at a time and see what specifically causes the problem.
I'll try that too. I am going away for the weekend, but keep posting, I'll try every suggestion as soon as I get back...
 

Offline m12lrpv

  • Regular Contributor
  • *
  • Posts: 175
  • Country: au
Re: Arduino and Wire.endTransmission()
« Reply #16 on: April 11, 2014, 01:14:09 pm »
Have you tried resetting the fuse settings to default and running at 5V? Then try 5V with modified fuse settings, then 3.3V. Basically, start with the only difference between your setup and the UNO being the chip is off the board. Then change one thing at a time and see what specifically causes the problem.

I agree.

There's so much that you're not saying. Like the actual fuse settings? How you set them given that you're serial programming? Your frequency? How you're level shifting your serial out?

All these things matter.

Even post the relevant part of your boards.txt that you're using and a good photo of your circuit and I can program a chip to those settings and try and reproduce your issue here.

 

Offline DajgoroTopic starter

  • Frequent Contributor
  • **
  • Posts: 322
  • Country: hr
    • hackaday.io
Re: Arduino and Wire.endTransmission()
« Reply #17 on: April 11, 2014, 02:51:28 pm »
Have you tried resetting the fuse settings to default and running at 5V? Then try 5V with modified fuse settings, then 3.3V. Basically, start with the only difference between your setup and the UNO being the chip is off the board. Then change one thing at a time and see what specifically causes the problem.

I agree.

There's so much that you're not saying. Like the actual fuse settings? How you set them given that you're serial programming? Your frequency? How you're level shifting your serial out?

All these things matter.

Even post the relevant part of your boards.txt that you're using and a good photo of your circuit and I can program a chip to those settings and try and reproduce your issue here.
For the fuse programming i use the buspirate
efuse 0xFF   hfuse 0xDA  lfuse 0xFF  @ 3.3V, 16MHz

the board.txt is the same for the aruino uno, and there is no level shifting for the serial port.
I checked the serial com with other sketches and it works perfectly, there is not any problem with the serial port.
 

Offline m12lrpv

  • Regular Contributor
  • *
  • Posts: 175
  • Country: au
Re: Arduino and Wire.endTransmission()
« Reply #18 on: April 11, 2014, 10:59:34 pm »
Have you tried resetting the fuse settings to default and running at 5V? Then try 5V with modified fuse settings, then 3.3V. Basically, start with the only difference between your setup and the UNO being the chip is off the board. Then change one thing at a time and see what specifically causes the problem.

I agree.

There's so much that you're not saying. Like the actual fuse settings? How you set them given that you're serial programming? Your frequency? How you're level shifting your serial out?

All these things matter.

Even post the relevant part of your boards.txt that you're using and a good photo of your circuit and I can program a chip to those settings and try and reproduce your issue here.
For the fuse programming i use the buspirate
efuse 0xFF   hfuse 0xDA  lfuse 0xFF  @ 3.3V, 16MHz

the board.txt is the same for the aruino uno, and there is no level shifting for the serial port.
I checked the serial com with other sketches and it works perfectly, there is not any problem with the serial port.

So you're running at 3.3v at 16MHz which is not supported and probably the main source of your problems. I'm not going to try that because I know it won't work. Look up (29.3) Speed Grades in the datasheet.

I use 0xE2 for the low fuse for my 3.3v projects.

Code: [Select]
atmega328bbA.name=ATmega328 breadboard (8 MHz internal clock)(via ArduinoISP)

atmega328bbA.upload.protocol=stk500
atmega328bbA.upload.maximum_size=30720
atmega328bbA.upload.using=arduino:arduinoisp
atmega328bbA.upload.speed=57600

atmega328bbA.bootloader.low_fuses=0xE2
atmega328bbA.bootloader.high_fuses=0xDA
# BOD on
#atmega328bbA.bootloader.extended_fuses=0x05
# BOD OFF
atmega328bbA.bootloader.extended_fuses=0x07
atmega328bbA.bootloader.path=arduino:atmega
atmega328bbA.bootloader.file=ATmegaBOOT_168_atmega328_pro_8MHz.hex
atmega328bbA.bootloader.unlock_bits=0x3F
atmega328bbA.bootloader.lock_bits=0x0F

atmega328bbA.build.mcu=atmega328p
atmega328bbA.build.f_cpu=8000000L
atmega328bbA.build.core=arduino:arduino

It's also a good idea to put a bit of a delay into your setup procedure like 5 seconds to give everything a chance to start up fully but not until you've sorted out your clock speeds.

You're doing serial out to what's presumably 5v without level shifting ??? Still not clear there but if that's the case you could be injecting 5v into your 3.3v circuit which would be bad.
 

Offline Rick Law

  • Super Contributor
  • ***
  • Posts: 3442
  • Country: us
Re: Arduino and Wire.endTransmission()
« Reply #19 on: April 11, 2014, 11:27:46 pm »
Have you tried resetting the fuse settings to default and running at 5V? Then try 5V with modified fuse settings, then 3.3V. Basically, start with the only difference between your setup and the UNO being the chip is off the board. Then change one thing at a time and see what specifically causes the problem.

I think the 3.3V and/or noise may be an issue.

First, the 3.3V - I am using 5V and I have a couple of LCD 20x4.  I found that if I loaded the board down and pull the power below about 4.8V, my LCD and other devices go nuts frequently.  I am wondering if you have devices not being happy at 3.3V.

Second, noise.  I did some extensive tests back around Christmas time after making a DS1307 clock.    I was trying to minimize noise impact on my devices.  I have 3 I2C devices (not including the MCU) and found the I2C rather works reliable when noise is low.

My test was to write than read back the 56 bytes of nvram on the DS1307.  The noise I was trying to reduce was when the DS1307 has squarewave turned on.

When noise was very low (no square wave), I was able to do 11 million read-after-write with 3 errors (total) - I encounter my error after 10million, so 11 million became the bar for the second run.  With the two tests that took hours and hours to finish, the average was 3 errors in 11 million.

When noise is high (32MHz square wave on, square wave line running close to I2C lines), I would hit error error within a minute or two.  With 8MHz wave on, I would hit errors in minutes. 

I swapped devices (I have a "real" Arduino, and a home made), swapped I2C clock, and swapped I2C LCD.  When noise is low (and power is good), things run well.

I was trying to get some idea about how to reduce noise, so I posted it back then and had a discussion with fellow forum members.  That post may give you some ideas.
https://www.eevblog.com/forum/beginners/sloppy-hardware-work-or-to-be-expected/
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2806
  • Country: au
Re: Arduino and Wire.endTransmission()
« Reply #20 on: April 11, 2014, 11:41:14 pm »
2k is a bit low.  why 2k?

for breadboard testing, I have not needed pullups for i2c on my arduinos.  if you run the i2c cable longer than 2 feet, say, then a pullup would help.

2K seems a perfectly reasonable value and 1K is often seen in 3v3 systems.

As far as I know pullup resistors are a requirement for any I2C comms.  How else are you going to get a high logic level when the open collector (or drain) pins release?

Do the Arduinos rely on the micro's weak pullups?  Maybe the library doesn't really tri-state the lines when it should?
 

Offline linux-works

  • Super Contributor
  • ***
  • Posts: 1999
  • Country: us
    • netstuff
Re: Arduino and Wire.endTransmission()
« Reply #21 on: April 11, 2014, 11:52:17 pm »
I am not a big fan of internal pullups (lol) but, fwiw, I've had good luck with pullups locally on the arduino for i2c (I think the lib does enable them by default) and then I have PU's on the far end, usually 47k or 10k.  my i2c length often goes 1-2' and I have not had any errors or problems.  this is with a 328 chip at 5v standard.

but even for a short half-foot breadboard test, the internal PU's are good enough to demo and play with things.  I still would have some remote ones but for short testing the internal ones do seem sufficient.

Offline m12lrpv

  • Regular Contributor
  • *
  • Posts: 175
  • Country: au
Re: Arduino and Wire.endTransmission()
« Reply #22 on: April 12, 2014, 06:31:03 am »
I've use a number of I2C projects with both the atmega328 and the attiny's at 3 and 5 volt and for most 5v systems at the default arduino @ 100kHz using internal pullups is fine for the atmega328. The attiny needs pullups with tinywire.

In a noisy environment running over 400kHz on atmega328 (bit banging) I found that I needed pullups or things would go strange. Never had it "crash" though unless it was while trying to run the I2C functionality inside a timer overflow interrupt  :palm:  hence the bit banging
 

Offline Rick Law

  • Super Contributor
  • ***
  • Posts: 3442
  • Country: us
Re: Arduino and Wire.endTransmission()
« Reply #23 on: April 13, 2014, 06:48:24 pm »
I've use a number of I2C projects with both the atmega328 and the attiny's at 3 and 5 volt and for most 5v systems at the default arduino @ 100kHz using internal pullups is fine for the atmega328. The attiny needs pullups with tinywire.

In a noisy environment running over 400kHz on atmega328 (bit banging) I found that I needed pullups or things would go strange. Never had it "crash" though unless it was while trying to run the I2C functionality inside a timer overflow interrupt  :palm:  hence the bit banging

But since any I2C device going down can take down the whole I2C bus, hanging would therefore depend on every I2C device/code not going crazy and hang the system.

I can imagine an MCU program merely queue up bytes until the I2C bus is available, and it keep queuing, and queuing, until memory overwrite somewhere.
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2806
  • Country: au
Re: Arduino and Wire.endTransmission()
« Reply #24 on: April 13, 2014, 09:25:15 pm »
I can imagine an MCU program merely queue up bytes until the I2C bus is available, and it keep queuing, and queuing, until memory overwrite somewhere.

That's why you should have timeouts and deal with the errors (such as SDA or SCL stuck low) instead of assuming every transaction will work.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf