SAMD21 I2C Not Working - Arduino Zero based Board

tried the LSM9DS1 9-axis iNEMO Inertial Module connected to a Arduino Zero HW-819 clone which is a ATSAMD21 - setup
image

no problems - serial monitor displays

0xb2 0xdb 0xa1 0xff 0xf9 0x3c 0x6d 0xf6 0x3d 0xfc 0x57 0x02 0x82 0xfd 0x90 0xde 0x92 0x0a 
Accel 0xdbb2 0xffa1 0x3cf9  Mag   0xf66d 0xfc3d 0x0257  Gyro  0xfd82 0xde90 0x0a92
Acceleration X: -5.56m/s^2 Y: -0.06m/s^2 Z: 9.34m/s^2
magnetic X: -0.34m/s^2 Y: -0.13m/s^2 Z: 0.08m/s^2
Gyroscope X: -5.58m/s^2 Y: -74.90m/s^2 Z: 23.68m/s^2

0x47 0xbf 0x0d 0x00 0xac 0xf6 0x21 0xf5 0x87 0xfb 0x7f 0x10 0xe8 0xff 0x4b 0x04 0x15 0xff 
Accel 0xbf47 0x000d 0xf6ac  Mag   0xf521 0xfb87 0x107f  Gyro  0xffe8 0x044b 0xff15
Acceleration X: -9.91m/s^2 Y: 0.01m/s^2 Z: -1.43m/s^2
magnetic X: -0.39m/s^2 Y: -0.16m/s^2 Z: 0.59m/s^2
Gyroscope X: -0.21m/s^2 Y: 9.62m/s^2 Z: -2.06m/s^2

0x2b 0xd0 0xae 0x0e 0x33 0xd7 0x17 0xfc 0xf5 0xf9 0x19 0x16 0x62 0x02 0x69 0xf9 0x16 0xfe 
Accel 0xd02b 0x0eae 0xd733  Mag   0xfc17 0xf9f5 0x1619  Gyro  0x0262 0xf969 0xfe16
Acceleration X: -7.33m/s^2 Y: 2.25m/s^2 Z: -6.25m/s^2
magnetic X: -0.14m/s^2 Y: -0.22m/s^2 Z: 0.79m/s^2
Gyroscope X: 5.34m/s^2 Y: -14.76m/s^2 Z: -4.29m/s^2

0x44 0xbd 0xe2 0x03 0x54 0x0f 0xff 0xf3 0xad 0xfb 0xcf 0x0b 0x1a 0x02 0x8c 0x11 0x27 0xfb 
Accel 0xbd44 0x03e2 0x0f54  Mag   0xf3ff 0xfbad 0x0bcf  Gyro  0x021a 0x118c 0xfb27
Acceleration X: -10.22m/s^2 Y: 0.59m/s^2 Z: 2.35m/s^2
magnetic X: -0.43m/s^2 Y: -0.15m/s^2 Z: 0.42m/s^2
Gyroscope X: 4.71m/s^2 Y: 39.31m/s^2 Z: -10.86m/s^2

Which pins are you using for SDA and SCL, on the Zero clone @horace ?

Yeah, you are right! But my Wemos arduino board, point the PA22 and PA23 as the I2C pins. I just selected MKR Fox Board in order to find a solution to the non displaying serial monitor. For sure it would optimal if I get data with the zero board selected.

the HW-819 maps SDA & SCL to the standard UNO pins
image

when connected to these pins the LSM9DS1 works OK as shown in post 21

photo

I got it. I've checked everything, do you think it could be a library compatibility problem?
@horace.

Hey guys,

I'm currently trying to get data from a MPU6050 through a I2C protocol. My system is wired as the imagem below:

My MCU is a Arduino Zero Clone board called Weemos SAMD21.

There you have my code :

#include<Wire.h>//Biblioteca para comunicação I2C

const int MPU_addr=0x68; //EndereƧo do sensor

int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ; //Variaveis para pegar os valores medidos

void setup(){
  digitalWrite(SDA, 1);
  digitalWrite(SCL, 1);
  Wire.begin(); //Inicia a comunicação I2C
  Wire.beginTransmission(MPU_addr); //ComeƧa a transmissao de dados para o sensor
  Wire.write(0x6B); // registrador PWR_MGMT_1
  Wire.write(0); // Manda 0 e "acorda" o MPU 6050
  Wire.endTransmission(true);

  Serial.begin(9600); //Inicia a comunicaƧao serial (para exibir os valores lidos)
}
void loop(){
  Wire.beginTransmission(MPU_addr); //ComeƧa a transmissao de dados para o sensor
  Wire.write(0x3B); // registrador dos dados medidos (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true); // faz um "pedido" para ler 14 registradores, que serão os registrados com os dados medidos
  AcX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  AcY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

  //Agora escreve os valores no monitor serial
  Serial.print("AcX = "); Serial.print(AcX);
  Serial.print(" | AcY = "); Serial.print(AcY);
  Serial.print(" | AcZ = "); Serial.print(AcZ);
  Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53); //Equação da temperatura em Cº de acordo com o datasheet
  Serial.print(" | GyX = "); Serial.print(GyX);
  Serial.print(" | GyY = "); Serial.print(GyY);
  Serial.print(" | GyZ = "); Serial.println(GyZ);
  delay(333);
}

As you can see I'm using internal pull-ups, in the I2C line, but i've tried to add 4k7 resistors in order to see different results.

But my serial monitor just give the values :

AcX = -1 | AcY = -1 | AcZ = -1 | Tmp = 36.53 | GyX = -1 | GyY = -1 | GyZ = -1
AcX = -1 | AcY = -1 | AcZ = -1 | Tmp = 36.53 | GyX = -1 | GyY = -1 | GyZ = -1
AcX = -1 | AcY = -1 | AcZ = -1 | Tmp = 36.53 | GyX = -1 | GyY = -1 | GyZ = -1
AcX = -1 | AcY = -1 | AcZ = -1 | Tmp = 36.53 | GyX = -1 | GyY = -1 | GyZ = -1
AcX = -1 | AcY = -1 | AcZ = -1 | Tmp = 36.53 | GyX = -1 | GyY = -1 | GyZ = -1
AcX = -1 | AcY = -1 | AcZ = -1 | Tmp = 36.53 | GyX = -1 | GyY = -1 | GyZ = -1
AcX = -1 | AcY = -1 | AcZ = -1 | Tmp = 36.53 | GyX = -1 | GyY = -1 | GyZ = -1
AcX = -1 | AcY = -1 | AcZ = -1 | Tmp = 36.53 | GyX = -1 | GyY = -1 | GyZ = -1
AcX = -1 | AcY = -1 | AcZ = -1 | Tmp = 36.53 | GyX = -1 | GyY = -1 | GyZ = -1

The values stay the same, even when I move the MPU.

I tested the same code and the same MPU6050 with my Arduino UNO and it worked perfectly.

Do you guys have an idea of whats happening with the MPU output?

With new I2C modules, it is best to test your connection with the I2C Address Scanner, and make sure it recognizes a device with the correct I2C address, before moving on.

Have you done that in this case?

This should not be necessary. The Wire library turns on the internal pullups.

  digitalWrite(SDA, 1);
  digitalWrite(SCL, 1);

When posting output or error messages, please copy and paste into your post (with code tags), rather than posting an illegible screen shot.

@samuellfm,

Your two topics on the same or similar subject have been merged.

Please do not duplicate your questions as doing so wastes the time and effort of the volunteers trying to help you as they are then answering the same thing in different places.

Please create one topic only for your question and choose the forum category carefully. If you have multiple questions about the same project then please ask your questions in the one topic as the answers to one question provide useful context for the others, and also you won’t have to keep explaining your project repeatedly.

Repeated duplicate posting could result in a temporary or permanent ban from the forum.

Could you take a few moments to Learn How To Use The Forum

It will help you get the best out of the forum in the future.

Thank you.

1 Like

I edited my post and inserted the values from the serial monitor in the correct way.

I runned the I2C Scanner and I'm getting the same adress in the I2C line:

Scanning...
I2C device found at address 0x01  !
done

Even when I change the MPU i gets the same address. It was supposed to find 0x68 MPU address.

The MPU6050 is obsolete and has not been manufactured for years. If you have a module from some Asian vendor, it is probably a counterfeit or fake.

If you want something that works, buy a modern IMU from a reliable reseller that supports their products.

I used the same MPU with an Arduino Uno and i got perfect results.

That suggests you have a wiring problem, or perhaps the module does not work on 3.3V (it won't, if you apply 3.3V to the 5V regulator on the module).

Try the Uno again.

Some of the SAMD21 boards have "Serial" as the first hardware serial port, rather than the virtual USB Serial port. if you want to be sure to send debugging info on the USB port, Use SERIAL_PORT_USBVIRTUAL.println() and etc.
(I think "Arduino Zero" is one of them. I can't tell, from a quick glance, whether that switches when you use the "native usb port" instead of the debug port.)

AcX... of -1 means that Wire.read() is reading an empty buffer. Probably IIC bus problem.

with the Arduino Zero clone HW-819 used in post 21 I set up Serial so

#define Serial SerialUSB

Hey guys, i have good news!

I update my board bootloader with this one GitHub - BLavery/SAMD21-M0-Mini: Notes on using the Chinese "SAMD21-M0-Mini" board, and the I2C line started to work.

Now I have a suitable data in the serial monitor:

AcX = 2436 | AcY = 68 | AcZ = -16804 | Tmp = 30.69 | GyX = -109 | GyY = 58 | GyZ = -77
AcX = 2316 | AcY = 88 | AcZ = -16728 | Tmp = 30.74 | GyX = -97 | GyY = 51 | GyZ = -63
AcX = 2412 | AcY = 48 | AcZ = -16660 | Tmp = 30.74 | GyX = -99 | GyY = 41 | GyZ = -82
AcX = 2400 | AcY = 8 | AcZ = -16788 | Tmp = 30.84 | GyX = -85 | GyY = 35 | GyZ = -78
AcX = 2420 | AcY = 92 | AcZ = -16740 | Tmp = 30.74 | GyX = -97 | GyY = 58 | GyZ = -77
AcX = 2348 | AcY = 64 | AcZ = -16740 | Tmp = 30.79 | GyX = -87 | GyY = 48 | GyZ = -88

I also used @horace and @westfw for SerialUSB as you guys can se in my code:

#include<Wire.h>//Biblioteca para comunicação I2C

const int MPU_addr=0x68; //EndereƧo do sensor

int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ; //Variaveis para pegar os valores medidos

void setup(){
  Wire.begin(); //Inicia a comunicação I2C
  Wire.beginTransmission(MPU_addr); //ComeƧa a transmissao de dados para o sensor
  Wire.write(0x6B); // registrador PWR_MGMT_1
  Wire.write(0); // Manda 0 e "acorda" o MPU 6050
  Wire.endTransmission(true);

  SerialUSB.begin(9600); //Inicia a comunicaƧao serial (para exibir os valores lidos)
}
void loop(){
  Wire.beginTransmission(MPU_addr); //ComeƧa a transmissao de dados para o sensor
  Wire.write(0x3B); // registrador dos dados medidos (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true); // faz um "pedido" para ler 14 registradores, que serão os registrados com os dados medidos
  AcX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  AcY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

  //Agora escreve os valores no monitor serial
   SerialUSB.print("AcX = "); SerialUSB.print(AcX);
   SerialUSB.print(" | AcY = ");  SerialUSB.print(AcY);
   SerialUSB.print(" | AcZ = ");  SerialUSB.print(AcZ);
   SerialUSB.print(" | Tmp = "); SerialUSB.print(Tmp/340.00+36.53); //Equação da temperatura em Cº de acordo com o datasheet
   SerialUSB.print(" | GyX = ");  SerialUSB.print(GyX);
   SerialUSB.print(" | GyY = ");  SerialUSB.print(GyY);
   SerialUSB.print(" | GyZ = ");  SerialUSB.println(GyZ);
  delay(333);
}

Thank you all!!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.