I2C Soft TWI i2c_start_wait problem

Hi,

I have a problem connecting a GY-521 gyro module to an Arduino Uno R3. When I connect it to the SDA & SCL pins and use <wire.h> everything works fine. But I need the 2 pins (A4 & A5) so I want to implement soft TWI. So I use SoftI2CMaster.h> and pin 8 & 7.

Whatever I try: I do not get passed the first i2c_start_wait. The program never returns from this statement. Just to give you an idea:

//Soft-TWI setup--------------------------------------------------------------
#ifdef SOFT //Only include this software if the SOFT has been defined above
i2c_init();
i2c_start_wait(MPU_addr && I2C_WRITE);

The entire sketch is enclosed.

Thanks for any suggestions in advance,

Richard.

Sorry, You can find the software here:

www.uwvervoerder.nl/robotigs/software/45in1/GY-521-soft.htm

Why do you need all 6 analog inputs ? Perhaps there is a way to reduce that.
Or use an arduino Leonardo, which has more analog inputs.

There are many software-I2C libraries for Arduino. But there is not an official supported fully working library for software-I2C. There is a software drop-in replacement for the Wire library, it is in the library manager in the Arduino IDE, it's called "SoftwareWire". But I strongly advise to use the normal Wire library. Please use also the normal function pinMode() and digitalWrite() instead of the DDRB and PORTB.

You use direct register access to toggle a led for fast code, and after that you wait 1 second. To toggle a led can be faster anyway, with a single instruction. The ATmega328P has an extra option to toggle an output when writing a '1' to that bit of the PINB register. But please, don't do that. If something is not working, you need to get out of the trouble, not dive into more trouble. Use the normal Arduino functions.

Dank je Koepel :slight_smile: ,

In fact I need to free up pins on an Arduino Mega 2560 which uses 2 of its 5 external interrupts for hard TWI. And those external interrupts are really needed for other purposes. Besides, I have a second reason to want to implement soft TWI. I also own 4 pieces of SonarRF10. I cannot get them to run with the <wire.h>. But it needs a twi-restart and that seems to be a problem with <wire.h>. Just testing that now.

I only used the low level LED toggle in this sketch just to be sure nothing was interfering with the <SoftI2CMaster.h.h>, since I am trying to figure out why it is not working. So thanks, but indeed you are right. Oh and by the way, in my sketching style, a delay in the main loop means that more activities still can be added to this controller :).

So I will try your other suggestion of using SoftwareWire. Thanks again and I will report back.

Kind regards,

Richard

Long long time ago, the Arduino Wire library did not support a repeated start. But it does now.

The Arduino Mega 2560 has 6 real interrupts : https://www.arduino.cc/en/Reference/AttachInterrupt

And the Arduino Mega 2560 has PCINT interrupts.
I use this pinmapping picture (click on the picture) : https://www.arduino.cc/en/Hacking/PinMapping2560
This is the main library for PCINT interrupts : GitHub - GreyGnome/EnableInterrupt: New Arduino interrupt library, designed for Arduino Uno/Mega 2560/Leonardo/Due

Do you have a link to "SonarRF10" ?

Embedded programmers often use interrupts for keyboard and all kind of other things. The Arduino has other possibilities, and the use of interrupts can often be avoided. Can you tell why you need the interrupts ?

You may notice, that I'm trying everything to keep you away from software I2C. That could introduce new problems.

Ok thanks Koepel,

I will try to follow your line of avoiding soft TWI. I have 5 interrupts in use in this project as follows: INT2 and INT3 are occupied (and covered) by the motorshield. 2 more interrupts (INT18 and INT19) are used by the rotary wheel encoders to make the robot drive straight. The 5th (INT20) is used by my IR TV remote receiver. Whereas the use of many interrupts generally may lead to timing problems, up till now this works fine. Well, except the TWI connections.

SO did I understand you right? Can I use the GreyGnome PCINT library to extend the number of available interrupts? In that case all of my problems would be solved!

You may have noticed that I am just entering (4 months) the Arduino world. I used to work with Atmel controllers and write programs in assembler. So now I am trying to develop a style of writing as compatible to the Arduino IDE as possible. So thanks again. Below I will give you some links but please don`t judge too hard since I am in the process of moving this entire site to a new domain: robotigs.com.

RobotIgs.com is for sale | HugeDomains (link to SRF10 page)
RobotIgs.com is for sale | HugeDomains (link to the above mentioned robot)

Thanks in advance
Richard Boekamp

The GreyGnome library has large documentation (click 'Wiki'), there is also a list of pins for the ATmega2560 that support PCINT.
The PCINT interrupts require some extra code, and the GreyGnome library adds a little extra code as well.

I started with an ATtiny13A and was at http://www.avrfreaks.net/, but I don't want to go back. I even changed the hardware of project to make it Arduino compatible, so I could burn a bootloader and use the Arduino IDE.
It is possible to add your own board definition to boards.txt, and add custom compiler options there as well, for example the -flto option :o

One of your links is to the manufacturer of the SRF10 : SRF10 Ultra sonic range finder

I suggest to use the Wire library for the SRF10. Is the "SR-010.ino" working ?
There is no repeated start in that code (see the links in my Reply #4).

To Wire.requestFrom() can be more straightforward:

  Wire.requestFrom(115, 2);    // request 2 bytes from slave device #112

  if( Wire.available() == 2)   // received the same amount as requested ?
  {
    reading = Wire.read();  // receive high byte (overwrites previous reading)
    reading = reading << 8;    // shift high byte to be high 8 bits
    reading |= Wire.read(); // receive low byte as lower 8 bits
    Serial.println(reading);   // print the reading
  }
  else
  {
    Serial.println("bus error");
  }

Or shorter:

  int n = Wire.requestFrom(115, 2);    // request 2 bytes from slave device #112
  if( n == 2)                   // received the same amount as requested ?
  {
    reading = Wire.read();  // receive high byte (overwrites previous reading)
    reading = reading << 8;    // shift high byte to be high 8 bits
    reading |= Wire.read(); // receive low byte as lower 8 bits
    Serial.println(reading);   // print the reading
  }
  else
  {
    Serial.println("bus error");
  }

The Arduino has many things already defined : F_CPU, SDA, SCL, MOSI, and so on.
You can do this : pinMode( MOSI, OUTPUT);
The avr gcc library has also many things already defined, but you probably know that.

Do you still use that old motor shield. There is simplified code for it : Arduino Playground - AdafruitMotorShield

The SDA and SCL of the MPU-6050 may not be connected to the Arduino Mega 2560 !
You must use a I2C level shifter to create a 3.3V I2C bus.

Thanks Koepel,

Making progress here. You wrote:
quote
I suggest to use the Wire library for the SRF10. Is the "SR-010.ino" working ?
unquote
It is now. I adapted it a bit and it is completely functional now and optimized for speed, including Gain and Range. My next step will be to study your tips on the interrupts.

I actually use the GY-521 brick in my 5Vdc robot which is in fact a MPU6050 with voltage shifting included.

That "old motor-shield" was my first purchase of Arduino hardware, well gift by Santa. I really had no idea at all :slight_smile: . I would not buy it again. In fact I think in general that shields are not really practically. But since I have this one I will have a look at your tip.

Thanks again from a happy roboteer

The GY-521 has a voltage regulator for 3.3V, but not level shifters for the SDA and SCL.
I'm serious, you may not connect those SDA and SCL to the Arduino Mega 2560.

I used that motor shield to automate Fischertechnik. It was good enough for that. The newer motor shield with mosfet drivers are a lot better. Pololu.com has many motor drivers.

Oooops,

Studying the schedule a bit more precise http://robotigs.com/robotigs/documentatie/plaatjes/gyroSchem.png tells me you are absolutely right. I think I have been saved from frying by the 2 on board 4k7 resistor pull-ups to 3.3 Vdc.

Thanks for your sustained warnings.