L3gd20h data ready(DRDY) pin

Status
Not open for further replies.

thanos

Well-known member
Hello,
i wrote a simple program to check if i can read the drdy signal through the interrupt pin

Code:
#include "SPI.h"

#define DRDY_PIN  30  // labeled DRDY
#define CS_PIN    10  // labeled CS
#define GYRO_MOSI 11  // labeled SA0
#define GYRO_MISO 12  // labeled SDA
#define GYRO_SCK  13  // labeled SCL
  
const uint8_t L3GD20_REGISTER_CTRL_REG1           = 0x20;   
const uint8_t L3GD20_REGISTER_CTRL_REG3           = 0x22; 

///////////////////////////////////////////////////////////////////

void writeReg(uint8_t reg, uint8_t value) {
  digitalWrite(CS_PIN, LOW);
  SPI.transfer(reg);
  value = SPI.transfer(value);
  digitalWrite(CS_PIN, HIGH);
}

///////////////////////////////////////////////////////////////////

void interrupt(){
  
  f++;
  
  if(f == 5000){
    
  value = 5000;
  f = 0;
  
  }
  
}

///////////////////////////////////////////////////////////////////

volatile long f = 0, value = 0;

void setup() {
  Serial.begin(115200);

  Serial.println("Type any chaaracter to start");
  
  while (!Serial.available()) {}
  
  pinMode(CS_PIN, OUTPUT);
  digitalWrite(CS_PIN, HIGH);
  pinMode(DRDY_PIN, INPUT_PULLUP);
  
  attachInterrupt(DRDY_PIN, interrupt, RISING);
  
  SPI.begin();
  SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE3));
 
  /* Switch to normal mode and enable all three channels at 400 Hz */
  writeReg(L3GD20_REGISTER_CTRL_REG1, 0b10001111);

  /* Enable I2_DRDY */
  writeReg(L3GD20_REGISTER_CTRL_REG3, 0b00001000);
  
  do {
    delay(10);
  } while (Serial.read() >= 0);
  
}

///////////////////////////////////////////////////////////////////

void loop() {
  
  Serial.print("value =");
  Serial.println(value);
  delay(250);
  
}

Datasheet l3gd20h

it shows on the serial screen always “value = 0”.
What am I doing wrong?
 
Last edited:
I don't know why it's always giving you zero.

But I did give your program a try here on Teensy 3.5. As-is it does not compile. But with a minor fix and change to print "f" instead of "value", and with a function generator feeding a 20 Hz square wave to pin 30, I can see it's getting the interrupts.

sc.png

DSC_0729_web.jpg

Here's the slightly edited code. Hope this helps?

Code:
#include "SPI.h"

#define DRDY_PIN  30  // labeled DRDY
#define CS_PIN    10  // labeled CS
#define GYRO_MOSI 11  // labeled SA0
#define GYRO_MISO 12  // labeled SDA
#define GYRO_SCK  13  // labeled SCL

const uint8_t L3GD20_REGISTER_CTRL_REG1           = 0x20;
const uint8_t L3GD20_REGISTER_CTRL_REG3           = 0x22;

volatile long f = 0, value = 0;

///////////////////////////////////////////////////////////////////

void writeReg(uint8_t reg, uint8_t value) {
  digitalWrite(CS_PIN, LOW);
  SPI.transfer(reg);
  value = SPI.transfer(value);
  digitalWrite(CS_PIN, HIGH);
}

///////////////////////////////////////////////////////////////////

void interrupt() {

  f++;

  if (f == 5000) {

    value = 5000;
    f = 0;

  }

}

///////////////////////////////////////////////////////////////////



void setup() {
  Serial.begin(115200);

  //while (!Serial.available()) {}
  while (!Serial) {}

  Serial.println("Type any chaaracter to start");

  //while (1) ;

  pinMode(CS_PIN, OUTPUT);
  digitalWrite(CS_PIN, HIGH);
  pinMode(DRDY_PIN, INPUT_PULLUP);

  attachInterrupt(DRDY_PIN, interrupt, RISING);

  SPI.begin();
  SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE3));

  /* Switch to normal mode and enable all three channels at 400 Hz */
  writeReg(L3GD20_REGISTER_CTRL_REG1, 0b10001111);

  /* Enable I2_DRDY */
  writeReg(L3GD20_REGISTER_CTRL_REG3, 0b00001000);

  do {
    delay(10);
  } while (Serial.read() >= 0);

}

///////////////////////////////////////////////////////////////////

void loop() {

  Serial.print("f = ");
  Serial.println(f);
  delay(250);

}
 
Hello paul,all this time i could not test your code.
I tried it now but it still show the serial monitor the value "f = 0".
Why can not I read this signal?
 
MKaybe there is no signal ? Are you sure your hardware works ? How do you know ? Did you measure it ?
You can be sure that the Teensy-pin-interrupts work. Thousands of people use them..
 
The gyroscope works properly,on the thread SdFs - a New SD Library for FAT16/FAT32/exFAT(post #64) the bill greiman wrote an example program that shows how to enable and use DRDY with the L3GD20H.

code
Code:
#include "SPI.h"
#define INT1_PIN  8
#define DRDY_PIN  30  // labeled DRDY
#define CS_PIN    10  // labeled CS
#define GYRO_MOSI 11  // labeled SA0
#define GYRO_MISO 12  // labeled SDA
#define GYRO_SCK  13  // labeled SCL
  
const uint8_t L3GD20_REGISTER_WHO_AM_I            = 0x0F;   // 11010100   r
const uint8_t L3GD20_REGISTER_CTRL_REG1           = 0x20;   // 00000111   rw
const uint8_t L3GD20_REGISTER_CTRL_REG2           = 0x21;   // 00000000   rw
const uint8_t L3GD20_REGISTER_CTRL_REG3           = 0x22;   // 00000000   rw
const uint8_t L3GD20_REGISTER_CTRL_REG4           = 0x23;   // 00000000   rw
const uint8_t L3GD20_REGISTER_CTRL_REG5           = 0x24;   // 00000000   rw
const uint8_t L3GD20_REGISTER_REFERENCE           = 0x25;   // 00000000   rw
const uint8_t L3GD20_REGISTER_OUT_TEMP            = 0x26;   //            r
const uint8_t L3GD20_REGISTER_STATUS_REG          = 0x27;   //            r
const uint8_t L3GD20_REGISTER_OUT_X_L             = 0x28;   //            r
const uint8_t L3GD20_REGISTER_OUT_X_H             = 0x29;   //            r
const uint8_t L3GD20_REGISTER_OUT_Y_L             = 0x2A;   //            r
const uint8_t L3GD20_REGISTER_OUT_Y_H             = 0x2B;   //            r
const uint8_t L3GD20_REGISTER_OUT_Z_L             = 0x2C;   //            r
const uint8_t L3GD20_REGISTER_OUT_Z_H             = 0x2D;   //            r
const uint8_t L3GD20_REGISTER_FIFO_CTRL_REG       = 0x2E;   // 00000000   rw
const uint8_t L3GD20_REGISTER_FIFO_SRC_REG        = 0x2F;   //            r
const uint8_t L3GD20_REGISTER_INT1_CFG            = 0x30;   // 00000000   rw
const uint8_t L3GD20_REGISTER_INT1_SRC            = 0x31;   //            r
const uint8_t L3GD20_REGISTER_TSH_XH              = 0x32;   // 00000000   rw
const uint8_t L3GD20_REGISTER_TSH_XL              = 0x33;   // 00000000   rw
const uint8_t L3GD20_REGISTER_TSH_YH              = 0x34;   // 00000000   rw
const uint8_t L3GD20_REGISTER_TSH_YL              = 0x35;   // 00000000   rw
const uint8_t L3GD20_REGISTER_TSH_ZH              = 0x36;   // 00000000   rw
const uint8_t L3GD20_REGISTER_TSH_ZL              = 0x37;   // 00000000   rw
const uint8_t L3GD20_REGISTER_INT1_DURATION       = 0x38;   // 00000000   rw

uint8_t readData(int16_t* xyz) {
  digitalWrite(CS_PIN, LOW);
  SPI.transfer(L3GD20_REGISTER_STATUS_REG | 0x80 | 0x40); // SPI read, autoincrement
  uint8_t status = SPI.transfer(0xFF);
  xyz[0] = SPI.transfer(0xFF) | (SPI.transfer(0xFF) << 8);
  xyz[1] = SPI.transfer(0xFF) | (SPI.transfer(0xFF) << 8);
  xyz[2] = SPI.transfer(0xFF) | (SPI.transfer(0xFF) << 8);
  digitalWrite(CS_PIN, HIGH);
  return status;
}

void printRegs() {
  Serial.print(F("WHO_AM_I: 0x"));
  Serial.println(readReg(L3GD20_REGISTER_WHO_AM_I), HEX);
  Serial.print(F("CTRL_REG1: 0b"));
  Serial.println(readReg(L3GD20_REGISTER_CTRL_REG1), 2);
  Serial.print(F("CTRL_REG2: 0b"));
  Serial.println(readReg(L3GD20_REGISTER_CTRL_REG2), 2);  
  Serial.print(F("CTRL_REG3: 0b"));
  Serial.println(readReg(L3GD20_REGISTER_CTRL_REG3), 2);  
}

uint8_t readReg(uint8_t reg) {
  uint8_t value;
  digitalWrite(CS_PIN, LOW);
  SPI.transfer((uint8_t)reg | 0x80); // set READ bit
  value = SPI.transfer(0xFF);
  digitalWrite(CS_PIN, HIGH);
  return value;
}

void writeReg(uint8_t reg, uint8_t value) {
  digitalWrite(CS_PIN, LOW);
  SPI.transfer(reg);
  value = SPI.transfer(value);
  digitalWrite(CS_PIN, HIGH);
}

void setup() {
  Serial.begin(9600);
  Serial.println("Type any chaaracter to start");
  while (!Serial.available()) {}
  pinMode(CS_PIN, OUTPUT);
  digitalWrite(CS_PIN, HIGH);
  SPI.begin();
  
  // Try Mode 3 - looks like data sheet timing.
  SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE3));
  printRegs();
  /* Set CTRL_REG1 (0x20)
   ====================================================================
   BIT  Symbol    Description                                   Default
   ---  ------    --------------------------------------------- -------
   7-6  DR1/0     Output data rate                                   00
   5-4  BW1/0     Bandwidth selection                                00
     3  PD        0 = Power-down mode, 1 = normal/sleep mode          0
     2  ZEN       Z-axis enable (0 = disabled, 1 = enabled)           1
     1  YEN       Y-axis enable (0 = disabled, 1 = enabled)           1
     0  XEN       X-axis enable (0 = disabled, 1 = enabled)           1 */

  /* Switch to normal mode and enable all three channels at 400 Hz */
  writeReg(L3GD20_REGISTER_CTRL_REG1, 0b10001111);

   /* Set CTRL_REG3 (0x22)
   ====================================================================
   BIT  Symbol    Description                                   Default
   ---  ------    --------------------------------------------- -------
     7  I1_Int1   Interrupt enable on INT1 (0=disable,1=enable)       0
     6  I1_Boot   Boot status on INT1 (0=disable,1=enable)            0
     5  H-Lactive Interrupt active config on INT1 (0=high,1=low)      0
     4  PP_OD     Push-Pull/Open-Drain (0=PP, 1=OD)                   0
     3  I2_DRDY   Data ready on DRDY/INT2 (0=disable,1=enable)        0
     2  I2_WTM    FIFO wtrmrk int on DRDY/INT2 (0=dsbl,1=enbl)        0
     1  I2_ORun   FIFO overrun int on DRDY/INT2 (0=dsbl,1=enbl)       0
     0  I2_Empty  FIFI empty int on DRDY/INT2 (0=dsbl,1=enbl)         0 */

  /* Enable I2_DRDY */
  writeReg(L3GD20_REGISTER_CTRL_REG3, 0b1000);
  pinMode(DRDY_PIN, INPUT);

  do {
    delay(10);
  } while (Serial.read() >= 0);
}

void loop() {
  int16_t data[3];
  uint8_t status;
  //delay(1000);
  readData(data);
  // Syncronize with DRDY signal.
  while (!digitalRead(DRDY_PIN)) {}  
  readData(data);
  while (!digitalRead(DRDY_PIN)) {}
  // Time period between DRDY signals.
  uint32_t m = micros();
  readData(data);    
  while (!digitalRead(DRDY_PIN)) {}
  m = micros() - m;
  status = readData(data);
  Serial.print(m);
  Serial.print(',');  
  Serial.print("0b");
  Serial.print(status, 2);  
  Serial.print(','); 
  Serial.print(data[0]);
  Serial.print(',');
  Serial.print(data[1]);
  Serial.print(',');
  Serial.println(data[2]);
  // stop print if Serial.available().
  while (Serial.available()) {}
}

the code is working,the bill has written

I have attached a rough program that shows how to enable and use DRDY with the L3GD20H. I just use a loop waiting for DRDY. You could use an interrupt connected to DRDY to read the Gyro.

i want now to use an interrupt to read the gyroscope.
I used a logic analyzer,in the code that greiman wrote to me i get the signal right,in my code i do not get any signal.
How can I read the gyroscope using an interrupt??What am i doing wrong in my code and i cannot read the signal to the pin drdy?
 
Well, Paul says his code works - if you get no results with this code, there something wrong with your setup (hardware). Needless to look for programming errors in your programm, if Pauls program does not work for you.
 
I tried again the program that paul wrote it always shows me "f = 1",does not increase.
I tried another gyroscope without any change.
 
Are you sure there really is a pulsing signal on pin 30?

I tested your code, with only minor fixes (the exact code I tested is in message #2) using a signal generator to apply a known 20 Hz signal to pin 30. It did indeed work.

Perhaps you could get a signal generator? Or use analogWriteFrequency() and analogWrite() to cause another pin on Teensy to generate a pulsing signal at known frequency, if you don't have a function generator capable of making a 0 to 3.3V waveform. Then you could connect a wire from that PWM output to pin 30, for the sake of testing with a known-good signal.

If you slow the pulsing to 5 Hz or less, you could connect a LED+resistor to verify the signal really is pulsing.

Yes, I know you really want to get these gyroscopes working. But if you're stuck, spending a little time testing with known-good signals instead of the gyroscope hardware could really help you with the troubleshooting of this project!
 
From the pin 43 sent a square pulse to the pin 30 and i read it correctly to the logic analyzer.
 
Last edited:
From the pin 43 sent a square pulse to the pin 30 and i read it correctly to the logic analyzer.

? This test says only, that the teensy sends pulses. Have you tried that with the interrupt on pin 30 ?

Maybe post a photo of your wiring ? Pin 43 is on the backside ?

Edit: You must help us and give as much information as possible... otherwise we can not help YOU :)
Please post the sketch which sends pulses and does something with the interrupt on pin 30.
 
Last edited:
Perhaps you could get a signal generator? Or use analogWriteFrequency() and analogWrite() to cause another pin on Teensy to generate a pulsing signal at known frequency, if you don't have a function generator capable of making a 0 to 3.3V waveform. Then you could connect a wire from that PWM output to pin 30, for the sake of testing with a known-good signal.

I read this page but i can not understand how i can make a signal generator 20 Hz square wave.
Can somebody help me?
 
Use this code. It will create a 20 Hz waveform on pin 6. Hopefully this is easy to understand?

Code:
void setup() {
  analogWriteFrequency(6, 20);
  analogWrite(6, 128);
}
void loop() {
}
 
Thanks paul,i tested the program(post#2)

Code:
#include "SPI.h"

#define DRDY_PIN  43  // labeled DRDY
#define CS_PIN    10  // labeled CS
#define GYRO_MOSI 11  // labeled SA0
#define GYRO_MISO 12  // labeled SDA
#define GYRO_SCK  13  // labeled SCL

const uint8_t L3GD20_REGISTER_CTRL_REG1           = 0x20;
const uint8_t L3GD20_REGISTER_CTRL_REG3           = 0x22;

volatile long f = 0, value = 0;

///////////////////////////////////////////////////////////////////

void writeReg(uint8_t reg, uint8_t value) {
  digitalWrite(CS_PIN, LOW);
  SPI.transfer(reg);
  value = SPI.transfer(value);
  digitalWrite(CS_PIN, HIGH);
}

///////////////////////////////////////////////////////////////////

void interrupt() {

  f++;

  if (f == 5000) {

    value = 5000;
    f = 0;

  }

}

///////////////////////////////////////////////////////////////////



void setup() {
  Serial.begin(115200);

  //while (!Serial.available()) {}
  while (!Serial) {}

  Serial.println("Type any chaaracter to start");

  //while (1) ;

  pinMode(CS_PIN, OUTPUT);
  digitalWrite(CS_PIN, HIGH);
  pinMode(DRDY_PIN, INPUT_PULLUP);

  attachInterrupt(DRDY_PIN, interrupt, RISING);

  SPI.begin();
  SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE3));

  /* Switch to normal mode and enable all three channels at 400 Hz */
  writeReg(L3GD20_REGISTER_CTRL_REG1, 0b10001111);

  /* Enable I2_DRDY */
  writeReg(L3GD20_REGISTER_CTRL_REG3, 0b00001000);

  analogWriteFrequency(30, 20);
  analogWrite(30, 128);

  do {
    delay(10);
  } while (Serial.read() >= 0);

}

///////////////////////////////////////////////////////////////////

void loop() {

  Serial.print("f = ");
  Serial.println(f);
  delay(250);

}

on the serial screen showed me

https://imgur.com/a/JXhOk

therefore i can see it's getting the interrupts.
 
About the initial problem what we can do??
The drdy signal can be read through the interrupt pin??
 
You see, not the teensy is the problem.
Post a photo of your wiring ? use JPG and a reduce the size - but it must large enough that we can see the details.
 
Perhaps your code isn't properly talking with the L3GD20H chip?

Or maybe the L3GD20H is damaged? Or maybe the connections are not good?

You *still* have not shown us a photo of how you're really connecting everything. Maybe there's some simple connection problem or misunderstanding? It's a long-shot, but photos are easy and if there's a simple mistake that can be seen in the photo, odds are good one of us will notice. If you read the other thread on this forum, you'll see we have a pretty good history of noticing problems when photos are posted.

If the hardware really is good, perhaps your code isn't doing something the chip needs? Realistically, your best chance is to search for known-good Arduino libraries for this chip or very similar parts. Or if one can't be found, perhaps switching to a different chip which does have well tested code would be the simplest path?
 
The connections are as follows



they are connected to breadboard with jumper wire

Perhaps your code isn't properly talking with the L3GD20H chip?...Maybe the L3GD20H is damaged?
Τhe bill greiman wrote an example program(post #5) and i get the right values from the sensor,think it works properly.In his program i used a logic analyzer and i get the signal right,in my code i do not get any signal.

If the hardware really is good, perhaps your code isn't doing something the chip needs?Realistically, your best chance is to search for known-good Arduino libraries for this chip or very similar parts.
I have searched for known-good libraries no one uses the pin drdy,perhaps the code isn't properly talking with the chip,there is a case where this signal cannot be read from the interrupt??

L3GD20H DATASHEET

L3GD20H APPLICATION NOTE
 
Last edited:
That's not a photo.. a photo would show problems with the wiring or wrong pin numbers.

Anyway, the pins on your shematic and the pin - numbers in your sketch in post #1 do not match.
#define DRDY_PIN 30 // labeled DRDY
#define CS_PIN 10 // labeled CS
#define GYRO_MOSI 11 // labeled SA0
#define GYRO_MISO 12 // labeled SDA
#define GYRO_SCK 13 // labeled SCL

In the schematic, pin 24 is used for DRDY.
What is Vin on the board ? Is it a 5V input ? - looks like, because there is a 3V input nearby (what does this "o" mean - or is an output?). Do you have a description (link) of this board ?
Does it work with 3V ?
If not, make sure that the ouputs of this board are NOT 5V - it would damage the Teensy.

Have you checked, that there is a connection between DRDY an the Teensy-pin ? Sometimes, jumper-wires or even breadboards are faulty.
 
Last edited:
That's not a photo.. a photo would show problems with the wiring or wrong pin numbers.

Anyway, the pins on your shematic and the pin - numbers in your sketch in post #1 do not match.
As you can see the photo so i've made the connections at the breadboard,does not change anything.
I changed the pin drdy and i put it on pin 24,sorry i didn't mention it.

What is Vin on the board ? Is it a 5V input ? - looks like, because there is a 3V input nearby (what does this "o" mean - or is an output?). Do you have a description (link) of this board ?
Does it work with 3V ?
If not, make sure that the ouputs of this board are NOT 5V - it would damage the Teensy.

The pin Vin is it a 3.3v or 5V input,i have put 3.3v, the pin 3Vo is an output we can take 3.3v.Link of this board.

Have you checked, that there is a connection between DRDY an the Teensy-pin ? Sometimes, jumper-wires or even breadboards are faulty.
The cables i have checked them many times,i have changed sensor and braedboard without any change.
If there is any problem in my wiring or at the sensor or...or...how does the program that the greiman(post#5) wrote it works??
Maybe the problem is in the program and not in my wiring??There is a case where the drdy signal cannot be read from the interrupt??
 
Hell, if there arrive pulses at the pin, the interrupt will for sure be triggered. Did you check with an oscilloscope if the L3GD20 feeds really pulses into the Teensy?
 
Apparently no camera either? Not even a smart phone with built in camera?

Seriously, post a real photo, even if you believe it is redundant. Many times on this forum we've answered these sorts of questions, and then a real photo showed some simple misunderstanding. Not soldering the pins is a common case.
 
Status
Not open for further replies.
Back
Top