Arduino and Wire.endTransmission() - Page 1
Forum section: electronics / beginners

author: Dajgoro
author_rank: Frequent Contributor
timestamp: April 11, 2014, 01:08:16 am
content: 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?

author: linux-works
author_rank: Super Contributor
timestamp: April 11, 2014, 01:21:49 am
content: 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.

author: scott216
author_rank: Regular Contributor
timestamp: April 11, 2014, 02:28:24 am
content: 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-libraryand here:https://github.com/DSSCircuits/I2C-Master-Library

author: Legion
author_rank: Frequent Contributor
timestamp: April 11, 2014, 02:37:12 am
content: 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.inoOn 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.95Diagnostic.Sensor B RH%: 99.9 Sensor B Temperature: 256.95Average RH%: 99.93 Average Temperature: 256.95

author: scott216
author_rank: Regular Contributor
timestamp: April 11, 2014, 02:40:39 am
content: You probably now this, but just in case: The Arduino's have dedicated pins for I2C communicationSee:http://www.arduino.cc/en/Reference/Wire

author: Dajgoro
author_rank: Frequent Contributor
timestamp: April 11, 2014, 03:06:10 am
content: Quote from: Legion on April 11, 2014, 02:37:12 amI uploaded the code, and I get this:Code:??????????????????????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.QuoteThanks, I'll try that.

author: m12lrpv
author_rank: Regular Contributor
timestamp: April 11, 2014, 03:13:18 am
content: 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 onehttp://playground.arduino.cc/Main/I2cScannerYou should be able to run it without any devices connected and have it work without crashing. Always a good starting point.

author: linux-works
author_rank: Super Contributor
timestamp: April 11, 2014, 03:13:47 am
content: 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.

author: m12lrpv
author_rank: Regular Contributor
timestamp: April 11, 2014, 03:15:51 am
content: Try a serial test. Looks like your baud rate might be wrong.

author: Legion
author_rank: Frequent Contributor
timestamp: April 11, 2014, 03:26:04 am
content: Quote from: Dajgoro on April 11, 2014, 03:06:10 amIt's definitely not the code then. Which arduino are you using?

author: Dajgoro
author_rank: Frequent Contributor
timestamp: April 11, 2014, 04:18:45 am
content: 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.

author: linux-works
author_rank: Super Contributor
timestamp: April 11, 2014, 04:31:21 am
content: 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)

author: m12lrpv
author_rank: Regular Contributor
timestamp: April 11, 2014, 04:42:45 am
content: 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?

author: Dajgoro
author_rank: Frequent Contributor
timestamp: April 11, 2014, 11:41:57 am
content: Quote from: m12lrpv on April 11, 2014, 04:42:45 amIt always crashes, devices or no devices, pullups or no pullups.Edit: The mcu is brand new.

author: Legion
author_rank: Frequent Contributor
timestamp: April 11, 2014, 12:10:05 pm
content: 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.

author: Dajgoro
author_rank: Frequent Contributor
timestamp: April 11, 2014, 12:38:04 pm
content: Quote from: Legion on April 11, 2014, 12:10:05 pmI'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...

author: m12lrpv
author_rank: Regular Contributor
timestamp: April 11, 2014, 01:14:09 pm
content: Quote from: Legion on April 11, 2014, 12:10:05 pmI 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.

author: Dajgoro
author_rank: Frequent Contributor
timestamp: April 11, 2014, 02:51:28 pm
content: Quote from: m12lrpv on April 11, 2014, 01:14:09 pmFor the fuse programming i use the buspirateefuse 0xFF hfuse 0xDA lfuse 0xFF @ 3.3V, 16MHzthe 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.

author: m12lrpv
author_rank: Regular Contributor
timestamp: April 11, 2014, 10:59:34 pm
content: Quote from: Dajgoro on April 11, 2014, 02:51:28 pmSo 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:atmega328bbA.name=ATmega328 breadboard (8 MHz internal clock)(via ArduinoISP)atmega328bbA.upload.protocol=stk500atmega328bbA.upload.maximum_size=30720atmega328bbA.upload.using=arduino:arduinoispatmega328bbA.upload.speed=57600atmega328bbA.bootloader.low_fuses=0xE2atmega328bbA.bootloader.high_fuses=0xDA# BOD on#atmega328bbA.bootloader.extended_fuses=0x05# BOD OFFatmega328bbA.bootloader.extended_fuses=0x07atmega328bbA.bootloader.path=arduino:atmegaatmega328bbA.bootloader.file=ATmegaBOOT_168_atmega328_pro_8MHz.hexatmega328bbA.bootloader.unlock_bits=0x3Fatmega328bbA.bootloader.lock_bits=0x0Fatmega328bbA.build.mcu=atmega328patmega328bbA.build.f_cpu=8000000Latmega328bbA.build.core=arduino:arduinoIt'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 shiftingStill not clear there but if that's the case you could be injecting 5v into your 3.3v circuit which would be bad.

author: Rick Law
author_rank: Super Contributor
timestamp: April 11, 2014, 11:27:46 pm
content: Quote from: Legion on April 11, 2014, 12:10:05 pmI 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/

author: David_AVD
author_rank: Super Contributor
timestamp: April 11, 2014, 11:41:14 pm
content: Quote from: linux-works on April 11, 2014, 01:21:49 am2K 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?

author: linux-works
author_rank: Super Contributor
timestamp: April 11, 2014, 11:52:17 pm
content: 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.

author: m12lrpv
author_rank: Regular Contributor
timestamp: April 12, 2014, 06:31:03 am
content: 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 interrupthence the bit banging

author: Rick Law
author_rank: Super Contributor
timestamp: April 13, 2014, 06:48:24 pm
content: Quote from: m12lrpv on April 12, 2014, 06:31:03 amBut 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.

author: David_AVD
author_rank: Super Contributor
timestamp: April 13, 2014, 09:25:15 pm
content: Quote from: Rick Law on April 13, 2014, 06:48:24 pmThat'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.

author: m12lrpv
author_rank: Regular Contributor
timestamp: April 13, 2014, 10:38:28 pm
content: Quote from: Rick Law on April 13, 2014, 06:48:24 pmI've generally found the atmels with the arduino wire library to be quite robust except for where there are interrupts involved (because their I2C relies on interrupts to work). It certainly doesn't let you overflow the buffer.Still, you can get a slave device that clock stretches or just a badly wired signal lines which could slow things down. Haven't encountered one yet but there are ways around it when I do.

author: tiborsimon
author_rank: Contributor
timestamp: April 14, 2014, 06:26:43 am
content: If you communicate a 3.3V device with a 5V Arduino make sure you turn off the pullup resistors. These are turned on by default and pull up the lines to 5V. That's why you don't need external pullup resistors when playing with the Arduino in normal cases.Turn off the internal pullups(digitalWrite(A4,LOW);digitalWrite(A5,LOW); on UNO R3)and pull up the SDA and SCL lines externally to 3.3V otherwise you can damage the 3.3V device. I killed several accelerometers before I realized this issue

author: Dajgoro
author_rank: Frequent Contributor
timestamp: April 14, 2014, 01:31:29 pm
content: I tried using the I2C library, on 3.3V and 5V (without any sensors) and it is the same thing, pulls the signal for a cycle low, and restarts. I even tried without any other stuff, just a simple write loop, no serial link, I just probed the I2C lines with the scope.

author: Dajgoro
author_rank: Frequent Contributor
timestamp: April 14, 2014, 07:03:24 pm
content: Ha!?I tried software bitbanging, and it works, but odd thing, if I use the pins 3 and 4 as outputs it crashes in the same way as the wire library, but on 6 and 7 it works. Ha? why setting a pin low causes the mcu to crash? What is going on here?Edit: Pulling down a 2k resistor causes the crash!Edit: I don't want to think about it!NOooooooooooooAdding extra bypass caps doesn't help.Edit: I used 8k resistors, and it works now, everything works!Why a ~1mA current causes the mcu to restart?

author: m12lrpv
author_rank: Regular Contributor
timestamp: April 14, 2014, 10:19:19 pm
content: Quote from: Dajgoro on April 14, 2014, 07:03:24 pmIt doesn't, but something in your circuit does.

author: Dajgoro
author_rank: Frequent Contributor
timestamp: April 15, 2014, 01:21:07 pm
content: Quote from: m12lrpv on April 14, 2014, 10:19:19 pmBut what could that be, the circuit has only those extra two pullups added to it.It is the same thing on 3.3V and 5V. There are no extra devices/circuits connected to the mcu.

author: m12lrpv
author_rank: Regular Contributor
timestamp: April 15, 2014, 10:16:12 pm
content: Quote from: Dajgoro on April 15, 2014, 01:21:07 pmHard to say given that you won't show your circuit.On the plus side you've successfully confirmed that I2C is not the problem since you've been able to reproduce the issue while simply using the GPIO pins.

author: Dajgoro
author_rank: Frequent Contributor
timestamp: April 16, 2014, 12:12:36 am
content: Quote from: m12lrpv on April 15, 2014, 10:16:12 pmIt all works now, but the mystery remains.As I said, there is not much to show, it is just an atmega328 on a separate pcb with a 3.3v reg, with the rst, tx, rx pins tied to the original arduino uno board.Well, once I finished poking with the sw, I separated it, so now I have a stand alone device.

author: m12lrpv
author_rank: Regular Contributor
timestamp: April 16, 2014, 01:27:45 am
content: Quote from: Dajgoro on April 16, 2014, 12:12:36 amBased on the information provided the original arduino uno board would be 5 volt which means you're putting 5 volt into your reset pin as well as your RX and TX pins.That will cause problems. Wouldn't be surprised if the chip was damaged too.

author: Dajgoro
author_rank: Frequent Contributor
timestamp: April 17, 2014, 11:57:52 pm
content: Wouldn't that also mean that sending a signal to an unpowered mcu would also damage it?

author: Rick Law
author_rank: Super Contributor
timestamp: April 18, 2014, 01:47:04 am
content: Quote from: David_AVD on April 13, 2014, 09:25:15 pmI guess I did not express my point. I was hypothesizing the reason for "I don't understand why it would hang."Since I2C communicates between devices, one may not control all the codes running in all the devices. You can program the cleanest program in the world, but the I2C bus requires that all the devices are playing good or at least good enough.So, a well written program hangs not because of the codes not written right, but the system itself not feeling well - such as the MCU may be lacking oxygen (power) because the LCD that normally draw 30mA starting to draw 100mA and sucked all the oxygen in the room. The LCD draws 100mA because it's code got stuck somewhere due to another device hanging the I2C bus... possibility is endless.Come to think of it, it may not even be "quick and dirty." Given the limited space in firmware, it may well be not having the space to implement defensive programming. I just took out a chuck of code that tests the selected options against conflict - precisely because I am running out of RAM. But my stuff is just for fun, so no airplane is at risk of going off the runway killing hundreds...

author: m12lrpv
author_rank: Regular Contributor
timestamp: April 18, 2014, 07:52:54 am
content: Quote from: Dajgoro on April 17, 2014, 11:57:52 pmPossibly. In the end it comes down to how much current is running the wrong way through the MCU and for how long.

author: Dajgoro
author_rank: Frequent Contributor
timestamp: April 18, 2014, 08:17:30 pm
content: Quote from: m12lrpv on April 18, 2014, 07:52:54 amwhat about a mcu that usually operates at 5V, but when unpowered there is still a serial tx signal left high on a pin?

author: m12lrpv
author_rank: Regular Contributor
timestamp: April 18, 2014, 09:21:04 pm
content: Quote from: Dajgoro on April 18, 2014, 08:17:30 pmSame as before.In the end it comes down to how much current is running the wrong way through the MCU and for how long.It will also depend on the input off state of the TX pin. If in the off state it goes high impedance then it will limit the current flow. If in the off state it's high impedance with a pullup active then current will feed through that pullup into the rest of the device.For example many devices can stand over voltage on the wrong pins if you have large resistors limiting the current flow to a safe level. It's how the ebay sellers can get away with claiming 3.3v SD card shields are usable at 5v because they put 10k resistors on them that keeps the current low enough that it won't burn anything out.If you can't maintain supply current you will find it sucking current in through your other pins depending on their configuration hence bypass caps can be critical too. It's all about different of potential.Probably a good reason to leave things like brownout detection on albeit at a lower level.After blowing up my first Arduino by putting voltage through it the wrong wayI tend to pay more attention to the state of the circuit I'm putting, it in particularly now that most of my projects are now on standalone circuits and not on Arduino boards.