on DUE - I2C Wire library / TWI crash

WIRE library and I2C causes hard crash and below error:

assertion "(address & 0x80) == 0" failed: file "../source/twi.c", line 271, function: TWI_StartWrite
Exiting with status 1.

On a DUE accessing ADS1115 via I2C and the WIRE library. I've already verified that the address that I am passing the ADS1115 lib is correct but I have not yet verified the address that it is passing to wire, etc. However, the other threads appear to lean towards a cpu frequency issue.

Made all kinds of mods to address the cpu speed of the DUE. Tried TWI frequency at 200,000 and 50,000 both in program via Wire1.setClock(50000L); and 200000L and in twi.h - #define TWI_FREQ 200000L and 50000L

The odd thing is that this program has worked fine for quite a while running for days at a time and now it does the same thing for about 15 minutes and then...crashes as above.

I would be happy to trap the error if possible and not crash the program and reset I2C but how can you trap this?

Not sure if this is related but...checking to see if I have the correct version of Wire library and saw someone say that it was supposed to be in hardware/arduino/sam/libraries/Wire...but I don't have sam. Running 1.6.5 Arduino IDE and 1.6.4 DUE board version. ...but no sam...so I remove and reinstall the DUE board and still no sam.

Any direction or suggestion greatly appreciated!

Thanks!

Came across your post to see if it could help me with a I2C issue I am having with a problematic PCF8574 port expander.

I notice you have it connected to Wire1, the second I2C interface, correct ?
On my Taijuino board, the first I2C port has pullups on the board, but not for the second I2C port I believe. Do you have the pullups installed ?

For my testing, I am trying lower speeds with Wire.setClock(31000L) in an attempt to find the issue.
Are you certain the address is 0x80 and not 0x40 or 0x41, as that looks to me as bit 8 is set and I2C uses 7 bit addressing.

Check this link to the Wire library reference, where it mentions Note.

I don't use the Aruino IDE itself, but the the wire library that comes with the Arduino IDE package seems to work for me, at least 1.6.1 does.


Paul

Hi Paul,

Thanks for the reply!

Yes the error is a copy/paste from my serial monitor output where I received the error message. It's odd because I don't trap that error but it crashes the program so it must be somewhere in Wire.

I've tried it on Wire and Wire1 with the same symptoms but most of my testing has been on Wire1. Yes I believe that pins 20/21 on DUE have the pullups installed and SDA1/SCL1 do not. I have tested with various pullups and no additional pullups, also been told although I can't prove it, that the ADS1115 board has them built in already. The odd thing is that this has been working fine and this problem just popped up. I have used the i2cscanner program to confirm communications with the i2c devices but I guess they could still fail periodically. If I could trap the error and not crash the program I think I could reset the i2c bus and continue or at least that is a hopeful possibility. This crashing is not going to be acceptable.

There is also a WSWire library that has a very interesting feature that handles the situation where Wire just freezes with no error. I did quite a bit of testing with it prior to DUE when I was having that problem. Fortunately that symptom was resolved by shortening the wires to the i2c devices and soldering the connections.

I'm beginning to think that it may be caused by a memory leak because I have confirmed that I do have memory being overwritten. I think that may be causing other problems as well. This began when I added some new functionality. I'm getting it narrowed down but haven't fixed it yet. Oddly enough I have used the DUE freemem function but it doesn't change so I'm not sure about that.

I'm not sure about the 7 bit or 8 bit addressing on the DUE. Do you know about Arduino Playground - WireLibraryDetailedReference AND Arduino Playground - ATMELTWI? They are VERY detailed explanations of the wire library. Unfortunately it is not geared towards DUE directly but they do confirm some things that I have found out the hard way ie pullups 2.2k for 3.3V.

How did you come up with the 31,000 ? I know that is the minimum speed for i2c on 5V arduino but not sure about on DUE. Has that been working? I have tried 50,000 but it didn't seem to make any difference. I don't have access to a scope to confirm that speed did change. A previous post with the same error referenced changing the speed but it wasn't very detailed re how or what changes were made and if that resolved the problem.

One thing that has seemed to make a difference is a 1000ms delay after each call but unfortunately that will not work in production because it would make the program too slow.

There appear to have been a lot of Due related fixes since 1.6.1 however I've seen a number of people with Due issues with 1.6.5 of the board and 1.6.7 of the ide.

David,

With you saying the issue recently occurring, is it worthwhile going back to an earlier code version where you know it was stable ?

It's hard to believe that the issue just came about for no reason, and if you made no changes to the hardware, then logically, the problem must have come about in a change in your code.

Memory leaks, are you using assigning to memory without correct use of malloc or beyond the bounds of a variable ?

For the I2C speed, I selected 31000 for no specific reason. There is no lower limit for I2C, theoretically, it can be clocked down to DC, but device times-outs may need to be considered. I'm unaware of any speed limitations on 5 volts and with AVR. I have yet to confirm if reducing the speed has had any effect on my system, but the cable I use to connect the DUE to my controller board is just under 1 metre and CAT6 cable.

Yes, the other links to TWI I have looked at, in regards to searching the reason as to why my I2C device is not reliable, when it absolutely needs to be, (solar charge controller, controlling power MOSFTES).

The delay after each TWI call, have you tried reducing that to find a point where it plays up ?
How often are you polling the ADS1115 ADC ?
My calls to the PCF8574 port expander device are around every 5 seconds.

Is your code using any form of a library for the ADS1115 or is it using native TWI commands ?


Paul

The solar charge controller application is very cool. I have about 1400 watts of solar on my boat. Love it! I wouldn't think a meter of cat6 would be a problem but trying to use a breadboard certainly was for me however my i2c are now down to about six inches and no more breadboards, especially with I2C. You may want to check to see that you are using contiguous wires (a pair) or maybe even better would be two different pairs with the other wire being grounded. Another problem that I had was a poor ground connection to one of the ads1115s at one time. That one drove me crazy.

You're absolutely correct. The ADS1115/I2C stuff has not changed but other parts of the program and hardware certainly has. I am currently using the Adafruit ADS1115 library that uses wire or wire1. I'm seriously considering changing to another library for a number of other reasons as well. I was using WSWire which has a fix for the hanging write-end in wire but since I changed a lot of the
hardware and went to the DUE I went back to the WIRE that comes with the ide. Do you know of a fix or a better one?

Not using any Malloc etc. I WAS using "String" functions but removed almost all of that and replaced with fixed length character arrays because I read that the "String" functions had memory leaks. I'm not sure if that did much if any good. The reason I believe there was or is a memory problem is that I had a couple of global variables that were being overwritten when they hadn't been touched yet ...so I put serial.prints of them throughout the code to see what and when they were changed. Turned out there were some limited fixed size global arrays that were causing them to be clobberred. I'm still not sure how, but after I moved the arrays to static in a function the overwriting of the global variables went away. Later I commented that function out and have gotten other things running again.

Apparently I still have some additional related issue because I can use the I2C/ADS1115 for some functions without a problem but when I turn it on full blast the program freezes or hangs midstream. I may have made some progress because I haven't gotten the original TWI error lately.

To better explain, I can use it or the analogread interchangeably or concurrently but only the ADS1115 for current shunt reads. 500 current shunt reads at a time is no problem and 1000 single ended voltage reads are not a problem but when I run another 12,000 in the cycle it chokes. The really
odd thing is that really it's almost continuous except for a little break to check some temps every minute or so. The only difference in the code is whether it hits the analog read or the ads1115. I may give the slower i2c speed a try too. The problem is that the ADS1115 is so much more accurate. Do you know about the I2c scanner? There is also a scanner that supposedly checks at different speeds
but it didn't work on DUE and I haven't fixed it yet.

The array function that had to be commented out even after moving the limited size fixed arrays to static is really very straight forward so I think I am running into some limits or some other memory related issue.

I have been using the following code, in a function executed at various points to determine what the available memory is. I got it off a previous post on the forum and it seems to work fine.

#include <malloc.h>
#include <stdlib.h>
#include <stdio.h>

extern char _end;
extern "C" char *sbrk(int i);
char *ramstart=(char *)0x20070000;
char *ramend=(char *)0x20088000;

void setup() {
char *heapend=sbrk(0);
register char * stack_ptr asm ("sp");
struct mallinfo mi=mallinfo();
printf("\nDynamic ram used: %d\n",mi.uordblks);
printf("Program static ram used %d\n",&_end - ramstart);
printf("Stack ram used %d\n\n",ramend - stack_ptr);
printf("My guess at free mem: %d\n",stack_ptr - heapend + mi.fordblks);
}

void loop() {

}

Below is my results near where the program freezes. It looks good from here but I don't really know how to interpret it. Where would I run into a problem or what are the maximum values? I know that we are supposed to have 96K sram and it looks like they are subtracting the other values from
96k to get the free mem. I doubt I am having a flash problem with 512k but I don't know how to check that after compile. I am using a lot of F functions in serial.print and a few other progmem things to store some LCD constant arrays.

Dynamic ram used: 20
Program static ram used 6620
Stack ram used 392
My guess at free mem: 91272

Hi David,

Interesting post. Curious if that boat of yours is something in the order of 44' with sails :slight_smile:

Starting at the bottom, yes, I have the exact same code as you for displaying the resource usage, but for now, I have commented it out. To use the 'printf' statement I believe you also need to 'undef' it, like this;

#undef printf

See:
[// Arduino Playground - Printf](Arduino Forum Arduino Playground - Printf)
printf on DUE - Arduino Due - Arduino Forum

I don't recall what my values were, but free mem was about 80KB.

I also ordered a few of those ADS1115 from element14 which arrived yesterday,.
All I need to do is somehow solder these tiny SOP10 things to a carrier board that give me a larger DIP10 that I can then mount to vero board.

No, I don't have my I2C device in bread-board, I soldered it directly to the vero board of my solar charge controller.

Actually, your point of the CAT6 cable and using discrete wires rather than pairs is a god point.
I currently have SDA and SLC on a single pair, and now that I realise it, that is not a good idea.
So, before I throw these I2C port expander out and use direct I/O from the DUE, I will pull it all out again and make the cable change.

I went away from using a library and just using direct Wire commands and capture the errors and error count from the TWI commands to the device.

It works for some period of time and then it appears to get stuck and I get TWI error code 2, which is a NAK.
To rectify, I need to power cycle the I2C device.
This is totally not acceptable for my situation, where I need to have reliable control of the power from the solar panels going into 400Ahr of Lithium cells.

I don't know in regards to the Wire library, if there are any other solutions.
I am still on 1.6.1 at present and I could look at the change log for the Arduino libraries to see if any improvements or fixes have been made.
But I think it is not a library problem, even in your case.

The other thing that I thought of is that with the wire library, when a request is made to a device, the wire code does seem to go into a wait loop, to wait for the response from the device. Now, with my code, I also use timer interrupts to provide accurate timing for other functions such as PID, and have been thinking that it may be possible that when one of these interrupts occur during a wire wait loop, that that may well mess things up.

For me, it really looks like I will end up using DUE I/O rather than the port expander, and already have the multi-core cable ready to solder into the situation.

Using the ADS1115, for me, shouldn't be a problem as I will use it for non-critical functions.

If you are using the ADS1115 for voltage and shunt measurements, then you may be interested in the following device, a INA219, which can be bought on a board from Adafruit.

I had a few arrive last week, though haven't used them yet.
I also got some INA226, which can measure the bus voltage up to 36 volts dc, which suits my solar setup as I'm on 25.6 Volts, and that would exceed what a INA219 can take. The INA219 is for another project.
They can measure current, volts and then calculate power as well in Watts.

Yes, I used the I2C scanner initially to verify the device was being seen by the DUE.
I better go and check on what is happening with those power MOSFETs :slight_smile:


Paul

Paul,

Paul,
Well I'm clearly at a loss...yes it is ... and I'd like to hear about that Lithium bank. Send me a message.

The ADS1115 is also available from Adafruit on a breakout ...of course also available from China. Dig out your wrist strap because those things will go poof if you get a bright idea. I'm embarrassed to say I've burned a pile of them. I know I am a tenacious sob glutton for punishment. Soldering the breakout is more than enough challenge. I'll leave the sop to you. I hope you ordered a number of them. Check out the data sheet because they have almost NO margin for error...espcially at 3.3V. I haven't had very good luck with the hard reset yet.

I have a couple of the INA2s but haven't gotten to them yet. Would love to hear what you think about them when you get to them. There is a hack to use them to read external shunts too.

I think I have things at least more manageable now if not totally solved with all of the memory changes I was able to narrow down the problem area and quarantine it.

Thanks for the ideas!

David,

Well, first, your idea of the cable, to make sure I have the SDA and SLC on separate pairs with a the other wire in the twist as a ground wire has worked like a charm, thank you. I have had no errors in the past 24 hours and have been able to progress with the rest of the solar controller code.

In fact, it's mostly going now and looking good, so I'm pleased.
The I2C is at normal 100khz again.

I got a few of the ADS1115 chips, 2 or 4, not sure, they're still in their anti-staic bags, but I'll head your advice in regards to these parts not liking static.

I don't recall ever destroying a chip of any sort in 30 years, and I've used a fair amount of cmos in the past.
I guess there is always the first time.

I have seen the Adafruity boards and did think to get them a month back, but while I was making an order with element14, I decided to get them as chips, tiny tiny chips, they are so tiny.

I take it you still have a problem with the ADS115 which you would really like to solve ?
When you say:

500 current shunt reads at a time is no problem and 1000 single ended voltage reads are not a problem but when I run another 12,000 in the cycle it chokes.

Are you doing 500 reads in fast succession and then doing some averaging ?

With 12,000 reads, do you need to do so many reads in what could be such a short time?
What exactly 'chokes', the processor ?

I'll send you a PM soon.


Paul

Paul,
Glad to hear that the cable helped. There is also shielded cat5 and 6 cable and that might really help if you ground the shield. At least my environment has a lot of noise to guard against and I2C is picky. OneWire was even worse!

Yes, I've been doing a lot of averaging. The problem is the TWI error I mentioned earlier which causes the board to freeze. At least there is an error first but no way I know of to trap it. I thought it was memory but I don't think so anymore. There is also a stage where the ads1115 returns all zeros until it is reset.

I've written some better rolling average of modes routine which is going to reduce the number of needed samples but they're not in production yet...and the samples sure make things accurate even with all that noise. Even with all of these headaches you will be amazed how much more consistent the 1115 is than the Arduino even with an external reference.