This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PGA460-Q1: Unable to read bursts at OUTA PIN

Part Number: PGA460-Q1
Other Parts Discussed in Thread: PGA460

Hello All,

I am working on a project for my thesis involving distance ranging. The measurement range required is 6 meters and I have chosen the PGA460-Q1 with Arduino Uno as the microcontroller. The Uno and PGA460-Q1 are interfaced through UART. The PROWAVE Air-coupled Ultrasonic transducer 400EP14D which is of mono-static type is used along with the PROWAVE transformer K4000002 (3370).

The above circuit was rigged and referred from Figure 136 and Table 101 of PGA460-Q1 datasheet.

  • C(INN) and C(INP) values were calculated according to the formula in Table 101 for 40KHz frequency. Capacitor values close to the calculated values were added due to immediate unavailability.
  • PIN 12 (SCLK) was pulled HIGH with 5V as instructed in the Page 4 of the PGA460 Software Development Guide to configured 5V UART logic level.
  • PIN 9 (TEST PIN) is pulled HIGH to 5V or 3.3V through a 150kE resistor to select 5V UART logic level as instructed in the TEST Pin Functionality section (7.3.12) of the PGA460-Q1 datasheet.

The Transformer-Transducer combination was obtained from the SRM400 Application Circuit. This circuit is in working status and detects objects upto 1.5 meter.

I am trying to read bursts at PIN5 (OUTA) with the following Arduino sketch. The DEV_STAT0 Register value is read (128 value) and the THR_CRC_ERR parameter is 0 (i.e., No Error) and the VPWR_OV_TH parameter is set to 00b (i.e., 12.3V) and VIN is at 8.5V. The REGMAP register read and write UART Commands are working properly, but the Burst and Listen command for both Presets (CMD 0 and 1) don't give bursts at OUTA.

Please help me out with some valuable suggestions. Some important comments in the Arduino sketch are in bold.

Thank you.

Arduino Sketch:

byte ChecksumInput[44];
byte regAddr;
byte regData;
int c;
int m;
byte Numobjects = 0x02;

byte P1_THR_0 = 0x88;
byte P1_THR_1 = 0x88;
byte P1_THR_2 = 0x88;
byte P1_THR_3 = 0x88;
byte P1_THR_4 = 0x88;
byte P1_THR_5 = 0x88;
byte P1_THR_6 = 0x42;
byte P1_THR_7 = 0x10;
byte P1_THR_8 = 0x84;
byte P1_THR_9 = 0x21;
byte P1_THR_10 = 0x08;
byte P1_THR_11 = 0x40;
byte P1_THR_12 = 0x40;
byte P1_THR_13 = 0x40;
byte P1_THR_14 = 0x40;
byte P1_THR_15 = 0x00;
byte P2_THR_0 = 0x88;
byte P2_THR_1 = 0x88;
byte P2_THR_2 = 0x88;
byte P2_THR_3 = 0x88;
byte P2_THR_4 = 0x88;
byte P2_THR_5 = 0x88;
byte P2_THR_6 = 0x42;
byte P2_THR_7 = 0x10;
byte P2_THR_8 = 0x84;
byte P2_THR_9 = 0x21;
byte P2_THR_10 = 0x08;
byte P2_THR_11 = 0x40;
byte P2_THR_12 = 0x40;
byte P2_THR_13 = 0x40;
byte P2_THR_14 = 0x40;
byte P2_THR_15 = 0x00;

void setup()
{
      Serial.begin(19200, SERIAL_8N2);
      delay(10);
      c = 1;
      m = 1;
}

/*CHECKSUM FUNCTION*/


byte calcChecksum(byte cmd)
{
            int checksumLoops = 0;
            cmd = cmd & 0x001F;

            if(cmd == 16)
                          {
                            ChecksumInput[0] = cmd;
                            ChecksumInput[1] = P1_THR_0;
                            ChecksumInput[2] = P1_THR_1;
                            ChecksumInput[3] = P1_THR_2;
                            ChecksumInput[4] = P1_THR_3;
                            ChecksumInput[5] = P1_THR_4;
                            ChecksumInput[6] = P1_THR_5;
                            ChecksumInput[7] = P1_THR_6;
                            ChecksumInput[8] = P1_THR_7;
                            ChecksumInput[9] = P1_THR_8;
                            ChecksumInput[10] = P1_THR_9;
                            ChecksumInput[11] = P1_THR_10;
                            ChecksumInput[12] = P1_THR_11;
                            ChecksumInput[13] = P1_THR_12;
                            ChecksumInput[14] = P1_THR_13;
                            ChecksumInput[15] = P1_THR_14;
                            ChecksumInput[16] = P1_THR_15;
                            ChecksumInput[17] = P2_THR_0;
                            ChecksumInput[18] = P2_THR_1;
                            ChecksumInput[19] = P2_THR_2;
                            ChecksumInput[20] = P2_THR_3;
                            ChecksumInput[21] = P2_THR_4;
                            ChecksumInput[22] = P2_THR_5;
                            ChecksumInput[23] = P2_THR_6;
                            ChecksumInput[24] = P2_THR_7;
                            ChecksumInput[25] = P2_THR_8;
                            ChecksumInput[26] = P2_THR_9;
                            ChecksumInput[27] = P2_THR_10;
                            ChecksumInput[28] = P2_THR_11;
                            ChecksumInput[29] = P2_THR_12;
                            ChecksumInput[30] = P2_THR_13;
                            ChecksumInput[31] = P2_THR_14;
                            ChecksumInput[32] = P2_THR_15;
                            checksumLoops = 33;
                          }

            if (cmd == 0) // Burst and listen (Preset1) command
                          {
                            ChecksumInput[0] = cmd;
                            ChecksumInput[1] = Numobjects;
                            checksumLoops = 2;
                          }
                      
            if( cmd == 9) // Register Read
                          {
                            ChecksumInput[0] = cmd;
                            ChecksumInput[1] = regAddr;
                            checksumLoops = 2;
                          }
            if (cmd == 10)  // Register write
                          {
                            ChecksumInput[0] = cmd;
                            ChecksumInput[1] = regAddr;
                            ChecksumInput[2] = regData;
                            checksumLoops = 3;
                          }

            uint16_t carry = 0;

            for (int i = 0; i < checksumLoops; i++)
                          {
                                  if ((ChecksumInput[i] + carry) < carry)
                                  {
                                  carry = carry + ChecksumInput[i] + 1;
                                  }
                                  else
                                  {
                                    carry = carry + ChecksumInput[i];
                                  }
                                  if (carry > 0xFF)
                                  {
                                    carry = carry - 255;
                                  }
                          }
            carry = (~carry & 0x00FF);
            return carry;
}

/*MAIN LOOP*/

void loop()
{
        Serial.flush();
        if (c)
                {
                      byte buf16[35] = {0x55, 0x10, P1_THR_0, P1_THR_1, P1_THR_2, P1_THR_3, P1_THR_4,P1_THR_5, P1_THR_6,P1_THR_7, P1_THR_8, P1_THR_9, P1_THR_10, P1_THR_11, P1_THR_12, P1_THR_13,P1_THR_14, P1_THR_15,P2_THR_0, P2_THR_1, P2_THR_2, P2_THR_3, P2_THR_4, P2_THR_5, P2_THR_6,P2_THR_7, P2_THR_8, P2_THR_9, P2_THR_10, P2_THR_11, P2_THR_12, P2_THR_13,P2_THR_14, P2_THR_15,calcChecksum(0x10)};
                      Serial.println("\nWrite Threshold Resistors\n");
                      Serial.write(buf16,sizeof(buf16));// No Response Operation (Threshold Bulk Write)


                      regAddr = 0x1c; //Frequency register
                      regData = 0x32;//50
                      byte buf[5] = {0x55, 0x0a, 0x1c, 0x32, calcChecksum(0x0a)};//85,10(cmd-),28,50
                      Serial.println("\nWrite Frequency Resistor\n");
                      Serial.write(buf,sizeof(buf));// No Response Operation (Register Write)
                      delay(10);
                        {
                          regAddr = 0x1e; //PULSE_P1 Register
                          regData = 0x30;//0011 0000
                          byte buf1[5] = {0x55, 0x0a, regAddr, regData, calcChecksum(0x0a)};
                          Serial.write(buf1,sizeof(buf1));// No Response Operation (Register Write)
                        }
                        {
                          regAddr = 0x23;//FREQ_DIAG Register
                          regData = 0x33;//0011 0011
                          byte buf1[5] = {0x55, 0x0a, regAddr, regData, calcChecksum(0x0a)};
                          Serial.write(buf1,sizeof(buf1));// No Response Operation (Register Write)
                        }
                        {
                          regAddr = 0x25;//FVOLT_DEC Register
                          regData = 0x1c;//0001 1100
                          byte buf1[5] = {0x55, 0x0a, regAddr, regData, calcChecksum(0x0a)};
                          Serial.write(buf1,sizeof(buf1)); // No Response Operation (Register Write)
                        }    
                        {
                          regAddr = 0x1f;//PULSE_P2 Register
                          regData = 0x10;//0001 0000
                          byte buf1[5] = {0x55, 0x0a, regAddr, regData, calcChecksum(0x0a)};
                          Serial.write(buf1,sizeof(buf1)); // No Response Operation (Register Write)
                        }                   
                      c = 0;
                }

//       if (m)
//       {
//       for (int l=0;l<6;l++)
//               {
                     

                      Serial.flush();
                      delay(10);
                      
                      {
                         byte buf2[4] = {0x55, 0x00, Numobjects, calcChecksum(0x00)};
                         Serial.println("\nSending Burst and Listen Command for Preset 1\n");
                         Serial.write(buf2,sizeof(buf2)); // No Response Operation (Burst and listen (Preset1))
                      }
                      
                      delay(10);
                      Serial.flush();
                      
                      if(m)
                      {
                            byte sensorValue;
                            byte buf4[2] = {0x55, 0x08};//, calcChecksum(0x08)};
                            Serial.write(buf4,sizeof(buf4)); //Response Operation (All Except Register Read)
                            //delay(1);
                            for(int n=0;n<4;n++)
                                    {
                                      delay(10);
                                      if (n ==1)
                                        sensorValue = Serial.read();
                                      else
                                        Serial.read();
                                    }
                            
                            Serial.println("\nReading the second byte of response frame for System Diagnostics command\n");
                            Serial.println(sensorValue);
                            m=0;
                      }

                     
                      byte sensorValue;
                      regAddr = 0x40; //Enter any address of a REGMAP Register to read its value
                      byte buf[4] = {0x55, 0x09, regAddr, calcChecksum(0x09)};
                      Serial.write(buf,sizeof(buf)); //Response Operation (Register Read)
                      
                      for(int n=0;n<3;n++)
                              {
                                delay(10);
                                if (n == 1)
                                  sensorValue = Serial.read();
                                else
                                  Serial.read();
                              }
                      
                      Serial.println("\nReading the second byte of response frame for Register Read command\n");
                      Serial.println(sensorValue);
                     

//               }
//               m=0;
//        }


}

  • Hi Varun,

    Typically, the gating items that prevent the PGA460 from bursting include: threshold CRC error flagged, VPWR overvoltage threshold exceeded, or communication/checksum failure.
    However, you appear to have confirmed that none of these items are at fault.

    Can you clarify if it is only OUTA that does not respond/toggle (while OUTB does toggle)?

    Just to be certain, can you provide the raw hex transmit sequence for your burst/listen command to ensure there are no transmit errors? I assume that your ability to read/write data indicates the checksum function is working properly. What is the diagnostic field value of a subsequent read command after attempting to send a burst/listen command? Is it 0x40 indicating no previous command error?

    One correction to your hardware setup: if SCLK is not used, it should be pulled down by a 10kOhm resistor or left floating.
  • Links:
    PROWAVE Ultrasonic Transducer 400EP14D (www.prowave.com.tw/.../40ep14d.htm)
    PROWAVE Matching Transformer for 400EP14D (www.prowave.com.tw/.../transf.htm)
    PROWAVE SRM400 Module whose datasheet consists of the Application circuit that works for 1.5 meters (www.prowave.com.tw/.../srm400.htm)
  • Hi Akeem,

    Thank you for your reply.

    Test Condition:

    • VIN=8.5V.
    • TX-RX of PGA460-Q1 connected to RX-TX of Uno.
    • UNO powered through USB port.
    • TEST pin connected to 3.3V. 
    • SCLK pin is floating.

    1) Can you clarify if it is only OUTA that does not respond/toggle (while OUTB does toggle)?

    (Referring the rigged circuit image)

    When PIN 4 of IFT3370 was connected to OUTA (PIN 5 of PGA460-Q1), there is an 8.1V offset at OUTA pin and no toggle was observed, while at OUTB neither an offset nor a toggle was observed.

    When PIN 4 of IFT3370 was connected to OUTB (PIN 7 of PGA460-Q1), there is an 8.1V offset at OUTB pin and no toggle was observed, while at OUTA neither an offset nor a toggle was observed.

    2) Just to be certain, can you provide the raw hex transmit sequence for your burst/listen command to ensure there are no transmit errors?

    3) What is the diagnostic field value of a subsequent read command after attempting to send a burst/listen command?

    The below figure is screenshot of Arduino Sketch having the raw HEX transmit sequence

    Also, from the screenshot, the UART Diagnostic Data Field of the SYSTEM DIAGNOSTIC command (highlighted in the screenshot) is 69 (i.e., 0x45 or 0100 0101b). This value is inconsistent every time I upload the sketch. The other value I recieve is 101 (i.e.0x65 or 0110 0101b)

    On the other hand, The UART Diagnostic Data Field of the REGISTER READ command is consistently 69 (also evident in the screenshot).

    4) Is it 0x40 indicating no previous command error?

    Nope, 0x45 (i.e., 69 or 0100 0101b) is the value indicating Error status [0] and Error status [2] of Table 4 in PGA460-Q1 datasheet.

    UART_DIAG Parameter of PULSE_P1 Register (Address = 1Eh) is 0b.

    Apart from PGA460-Q1 Device Busy Error and consecutive sync field bit widths mismatch Error (i.e., Error status [0] and Error status [2] respectively),  Error status [5] also occurs for the SYSTEM DIAGNOSTIC command.

    Please guide me further in overcoming these issues.

    Thanks a lot Akeem.

    Best regards,

    Varun

    Arduino Sketch.txt
    byte ChecksumInput[44];
    byte regAddr;
    byte regData;
    int c;
    int m;
    byte Numobjects = 0x02;
    
    byte P1_THR_0 = 0x88;
    byte P1_THR_1 = 0x88;
    byte P1_THR_2 = 0x88;
    byte P1_THR_3 = 0x88;
    byte P1_THR_4 = 0x88;
    byte P1_THR_5 = 0x88;
    byte P1_THR_6 = 0x42;
    byte P1_THR_7 = 0x10;
    byte P1_THR_8 = 0x84;
    byte P1_THR_9 = 0x21;
    byte P1_THR_10 = 0x08;
    byte P1_THR_11 = 0x40;
    byte P1_THR_12 = 0x40;
    byte P1_THR_13 = 0x40;
    byte P1_THR_14 = 0x40;
    byte P1_THR_15 = 0x00;
    byte P2_THR_0 = 0x88;
    byte P2_THR_1 = 0x88;
    byte P2_THR_2 = 0x88;
    byte P2_THR_3 = 0x88;
    byte P2_THR_4 = 0x88;
    byte P2_THR_5 = 0x88;
    byte P2_THR_6 = 0x42;
    byte P2_THR_7 = 0x10;
    byte P2_THR_8 = 0x84;
    byte P2_THR_9 = 0x21;
    byte P2_THR_10 = 0x08;
    byte P2_THR_11 = 0x40;
    byte P2_THR_12 = 0x40;
    byte P2_THR_13 = 0x40;
    byte P2_THR_14 = 0x40;
    byte P2_THR_15 = 0x00;
    
    void setup()
    {
          Serial.begin(19200, SERIAL_8N2);
          delay(10);
          c = 1;
          m = 1;
    }
    
    /*CHECKSUM FUNCTION*/
    
    
    byte calcChecksum(byte cmd)
    {
                int checksumLoops = 0;
                cmd = cmd & 0x001F;
    
                if(cmd == 16)
                              {
                                ChecksumInput[0] = cmd;
                                ChecksumInput[1] = P1_THR_0;
                                ChecksumInput[2] = P1_THR_1;
                                ChecksumInput[3] = P1_THR_2;
                                ChecksumInput[4] = P1_THR_3;
                                ChecksumInput[5] = P1_THR_4;
                                ChecksumInput[6] = P1_THR_5;
                                ChecksumInput[7] = P1_THR_6;
                                ChecksumInput[8] = P1_THR_7;
                                ChecksumInput[9] = P1_THR_8;
                                ChecksumInput[10] = P1_THR_9;
                                ChecksumInput[11] = P1_THR_10;
                                ChecksumInput[12] = P1_THR_11;
                                ChecksumInput[13] = P1_THR_12;
                                ChecksumInput[14] = P1_THR_13;
                                ChecksumInput[15] = P1_THR_14;
                                ChecksumInput[16] = P1_THR_15;
                                ChecksumInput[17] = P2_THR_0;
                                ChecksumInput[18] = P2_THR_1;
                                ChecksumInput[19] = P2_THR_2;
                                ChecksumInput[20] = P2_THR_3;
                                ChecksumInput[21] = P2_THR_4;
                                ChecksumInput[22] = P2_THR_5;
                                ChecksumInput[23] = P2_THR_6;
                                ChecksumInput[24] = P2_THR_7;
                                ChecksumInput[25] = P2_THR_8;
                                ChecksumInput[26] = P2_THR_9;
                                ChecksumInput[27] = P2_THR_10;
                                ChecksumInput[28] = P2_THR_11;
                                ChecksumInput[29] = P2_THR_12;
                                ChecksumInput[30] = P2_THR_13;
                                ChecksumInput[31] = P2_THR_14;
                                ChecksumInput[32] = P2_THR_15;
                                checksumLoops = 33;
                              }
    
                if (cmd == 0) // Burst and listen (Preset1) command
                              {
                                ChecksumInput[0] = cmd;
                                ChecksumInput[1] = Numobjects;
                                checksumLoops = 2;
                              }
                          
                if( cmd == 9) // Register Read
                              {
                                ChecksumInput[0] = cmd;
                                ChecksumInput[1] = regAddr;
                                checksumLoops = 2;
                              }
                if (cmd == 10)  // Register write
                              {
                                ChecksumInput[0] = cmd;
                                ChecksumInput[1] = regAddr;
                                ChecksumInput[2] = regData;
                                checksumLoops = 3;
                              }
    
                uint16_t carry = 0;
    
                for (int i = 0; i < checksumLoops; i++)
                              {
                                      if ((ChecksumInput[i] + carry) < carry)
                                      {
                                      carry = carry + ChecksumInput[i] + 1;
                                      }
                                      else
                                      {
                                        carry = carry + ChecksumInput[i];
                                      }
                                      if (carry > 0xFF)
                                      {
                                        carry = carry - 255;
                                      }
                              }
                carry = (~carry & 0x00FF);
                return carry;
    }
    
    /*MAIN LOOP*/
    
    void loop()
    {
            Serial.flush();
            if (c)
                    {
                          byte buf16[35] = {0x55, 0x10, P1_THR_0, P1_THR_1, P1_THR_2, P1_THR_3, P1_THR_4,P1_THR_5, P1_THR_6,P1_THR_7, P1_THR_8, P1_THR_9, P1_THR_10, P1_THR_11, P1_THR_12, P1_THR_13,P1_THR_14, P1_THR_15,P2_THR_0, P2_THR_1, P2_THR_2, P2_THR_3, P2_THR_4, P2_THR_5, P2_THR_6,P2_THR_7, P2_THR_8, P2_THR_9, P2_THR_10, P2_THR_11, P2_THR_12, P2_THR_13,P2_THR_14, P2_THR_15,calcChecksum(0x10)};
                          Serial.println("\nWrite Threshold Resistors\n");
                          Serial.write(buf16,sizeof(buf16));// No Response Operation (Threshold Bulk Write)
    
    
                          regAddr = 0x1c; //Frequency register
                          regData = 0x32;//50
                          byte buf[5] = {0x55, 0x0a, 0x1c, 0x32, calcChecksum(0x0a)};//85,10(cmd-),28,50
                          Serial.println("\nWrite Frequency Resistor\n");
                          Serial.write(buf,sizeof(buf));// No Response Operation (Register Write)
                          delay(10);
                            {
                              regAddr = 0x1e; //PULSE_P1 Register
                              regData = 0x30;//0011 0000
                              byte buf1[5] = {0x55, 0x0a, regAddr, regData, calcChecksum(0x0a)};
                              Serial.write(buf1,sizeof(buf1));// No Response Operation (Register Write)
                            }
                            {
                              regAddr = 0x23;//FREQ_DIAG Register
                              regData = 0x33;//0011 0011
                              byte buf1[5] = {0x55, 0x0a, regAddr, regData, calcChecksum(0x0a)};
                              Serial.write(buf1,sizeof(buf1));// No Response Operation (Register Write)
                            }
                            {
                              regAddr = 0x25;//FVOLT_DEC Register
                              regData = 0x1c;//0001 1100
                              byte buf1[5] = {0x55, 0x0a, regAddr, regData, calcChecksum(0x0a)};
                              Serial.write(buf1,sizeof(buf1)); // No Response Operation (Register Write)
                            }    
                            {
                              regAddr = 0x1f;//PULSE_P2 Register
                              regData = 0x10;//0001 0000
                              byte buf1[5] = {0x55, 0x0a, regAddr, regData, calcChecksum(0x0a)};
                              Serial.write(buf1,sizeof(buf1)); // No Response Operation (Register Write)
                            }                   
                          c = 0;
                    }
    
    //       if (m)
    //       {
    //       for (int l=0;l<6;l++)
    //               {
                         
    
                          Serial.flush();
                          delay(10);
                          
                          {
                             byte buf2[4] = {0x55, 0x00, Numobjects, calcChecksum(0x00)};
                             Serial.println("\nSending Burst and Listen Command for Preset 1\n");
                             Serial.write(buf2,sizeof(buf2)); // No Response Operation (Burst and listen (Preset1))
                          }
                          
                          delay(10);
                          Serial.flush();
                          
                          if(m)
                          {
                                byte sensorValue;
                                byte buf4[2] = {0x55, 0x08};//, calcChecksum(0x08)};
                                Serial.write(buf4,sizeof(buf4)); //Response Operation (All Except Register Read)
                                delay(1);
                                for(int n=0;n<4;n++)
                                        {
                                          delay(10);
                                          if (n == 0)
                                            sensorValue = Serial.read();
                                          else
                                            Serial.read();
                                        }
                                
                                Serial.println("\nReading the FIRST byte of response frame for SYSTEM DIAGNOSTICS command\n");
                                Serial.println(sensorValue);
                                m=0;
                          }
    
                         
                          byte sensorValue;
                          regAddr = 0x40; //Enter any address of a REGMAP Register to read its value
                          byte buf[4] = {0x55, 0x09, regAddr, calcChecksum(0x09)};
                          Serial.write(buf,sizeof(buf)); //Response Operation (Register Read)
                          delay(1);
                          for(int n=0;n<3;n++)
                                  {
                                    delay(10);
                                    if (n == 0)
                                      sensorValue = Serial.read();
                                    else
                                      Serial.read();
                                  }
                          
                          Serial.println("\nReading the FIRST byte of response frame for REGISTER READ command\n");
                          Serial.println(sensorValue);
                         
    
    //               }
    //               m=0;
    //        }
    
    
    }

  • Hi Varun,

    Based on your Arduino sketch file, your preset record length time must be either 4.096ms or 8.192ms given you are only waiting up to 10ms after sending a burst/listen command. However, since the read command subsequent to the burst/listen command indicates the device is busy, you may be disrupting the burst/listen command before it is complete. Can you confirm that your delay time is equal to or greater than the millisecond value of your preset burst/listen command? You should attempt to read or write with the PGA450 until the record time length has expired.

    The record length or disrupting the record time should not impact the driver though; you should still be seeing some activity at OUTA.

    Unfortunately, none of the circuit image links you've provided are working. If you are able to communicate to the device, but unable to burst, I suspect there is an error in your transformer connection, or you have a defective transformer. Can you share the full schematic of your circuit (you can send to me in a private message if not to be made public). Alternatively, can you confirm this is how you have connected your single-ended transformer to the PGA460:

    I have tested the same single-ended transformer on the PGA460-Q1 EVM, so I can confirm it is possible to get it to work.

  • Hello Akeem,

    I'm sorry about the reference links and the image. I have updated the circuit image and the hyperlinks for the datasheets of SRM400 Application circuit (with 1.5 meter range capability), 400EP14D transducer and the matching transformer K000002(3370) in my first post.

    I was able to receive bursts at OUTA pin as well as in OUTB when pin. It was due to a faulty probe and probe attenuation setting in the oscilloscope. As you stated, I observed that record time length(set at REC_LENGTH Register) didn't have any impact on the driver.

    The burst repetition period was decreased to 75 milli seconds after removing all 'delay();' in the Arduino Sketch.

    PGA460-Q1 - Transformer connection:

    The Transformer-Transducer section of the circuit image was derived from SRM400 Application circuit  (Page 2 of the datasheet). The VPWR pin and the OUTA pin are connected to the primary ends of the transformer but, only the ground (GND) connection is different from what you have suggested in the Single-Ended Transformer circuit image which didn't affect the driving capability.

    Current Limit Feature in PGA460-Q1:

    The default value of the CURR_LIM_P1 Register and  CURR_LIM_P2 Register are 47H and FFH, which corresponds to driver current limit configured to 99mA and 491mA for Preset1 and Preset2 respectively.

    I am unable to determine the maximum current for the driver section from the transformer datasheet. What is the current limit that I can configure to obtain the maximum distance ranging?

    Can I disable the DIS_CL parameter (CURR_LIM_P1 Register) to drive the transducer?

    Best Regards,

    Varun

     

  • Hi Varun,

    Thanks for your debug to confirm that OUTA is toggling. To clarify, are you now able to see a sinusoidal waveform at the transducer to successfully generate an ultrasonic echo?

    If the transformer datasheet does not specify a maximum current rating, I recommend that you sweep the driver current limit to optimize the sound pressure level (SPL) output with maximum power efficiency. This will also ensure that you do not sink excess current through the transformer, which may damage the transformer or dissipate as heat (wasted energy). Most transformers we've experimented with are rated for ~500mA, but I still recommend taking precaution as a best practice for the sake of optimization.

    To execute this parameter sweep of the driver current limit, you should initialize your current limit to 50mA. Set an object at a fixed burst count and distance (1m for example). To determine when the transducer has generated maximum sound pressure level, monitor the peak amplitude of the 1m object using the echo data dump. Most transducers will approach saturation at >=300mA. If this is true for your transformer, then I recommend keeping your driven current limit in the 300~350mA range. I do not recommend disabling the current limit for this use-case, as you may damage the PGA460-Q1 OUTA/B pins without external current limiting.

    The PGA460-Q1 EVM GUI includes a Parameter Sweep feature on the Test Page to automatically sweep these values. You can use the background exporter to save each echo data dump plot, then use the GUI's File-->DataPlotter feature to import and overlap each data plot for comparison. You can see an example of how the peak amplitude value follows a logarithmic like curve as it approaches the maximum value in Figure 9 of the PGA460 Ultrasonic Module Hardware and Software Optimization app note at: www.ti.com/.../slaa732

  • Hi Akeem,

    1) To clarify, are you now able to see a sinusoidal waveform at the transducer to successfully generate an ultrasonic echo?


    Yes, we are able to see sinusoidal waveform after issuing burst and listen command.

    2) Regarding  parameter sweep of the driver current limit - We are working on it. Currently we are using default current limit and are able to see echo for both presets.

    Meanwhile, we took the echo data dump from the PGA460 after issuing P2BL command. As we have not initialized TVG and Digital gain properly we are seeing a sudden jump to 255 in EDD after sometime.

    Record time set for Preset 2 is 53ms 

    The above plot was obtained when an object was placed at 130cm distance. I'm able to detect it in the EED plot. 

    We want to determine the correct TVG values, so we looked into the FAQs (5.3 and 5.4) mentioning the automatic calculation of TVG but we are not able to understand NOLO command. Similarly case with NOBAL command.

    We set the number of objects as zero in P2BL as well as P2LO UART commands and obtained an invalid error from diagnostic field. Kindly tell us how to implement NOLO and NOBAL profile.

    Thank you for the insights.

    Best regards

    Varun P

  • Hi Varun,

    The reason your echo data dump saturates in the later half is most likely due to the digital gain multiplier. The short range (SR) digital gain multiplier is low enough to enable object detection of your 130cm object. First, to eliminate the saturated echo data dump, set your long range (LR) digital gain multiplier to the same level as the SR. A single step of the digital gain multiplier will have a greater impact on the scaling of the echo data dump than a single step of the time-varying gain level. By setting the SR and LR digital gain multipliers to the same values, this feature is effectively disabled. A digital gain multiplier of x1 at both will fully disable this feature.

    After disabling the digital gain multiplier, I recommend that you start with a fixed single value time varying gain profile. As you start to move your object further away from the sensor, check the echo data dump levels. If the levels start to drop significantly (SNR is <3:1), begin to ramp the time-varying gain.

    The NOLO is a no-object listen only command profile. This means that no-object is placed in front of the transducer, and no burst is generated for echo transmit. Though you have set your pulse count to 0, there is a command (the listen only command) already available on the Data Monitor page which disables the driver block regardless of the pulse count. Evaluation of NOLO allows you to isolate the performance of the analog front end receiver block. As noted in the FAQ, the noise floor should be maintained at a value of less than or equal to a third of the maximum echo data dump amplitude (255). Auto time varying gain is not necessary as described in the FAQ, but mentioned as a recommendation and example of how to ramp the time varying profile is necessary.

    The NOBAL is a no-object burst-and-listen command profile. After you have optimized the time varying using the NOLO profile, you can then introduce the burst energy with no object in place to ensure the noise floor does not significantly change. You can place sound absorbing material (i.e. a sponge) in front of the transducer to emulate a NOBAL environment in case you do not have enough vacant floor space to run the NOBAL as intended.

    The end goal is to keep the noise floor as low as possible with as little gain as possible, but also provide enough gain to see an echo peak three times greater than the noise floor. You should prevent saturation of the return echo as this artificially reduces the SNR by only increasing the noise floor. This is explained in section 4.4 Time-Varying Gain and Digital Gain of the PGA460 Ultrasonic Module Hardware and Software Optimization appnote. 

    The digital gain multiplier will help scale the echo data dump profile, especially at long range, but is not required if the echo SNR is stable enough across time to properly set the threshold map.

  • Hello Akeem,

    Thank you for your a reply. 

    Digital Gain Multiplier:


    Akeem Whitehead said:
    First, to eliminate the saturated echo data dump, set your long range (LR) digital gain multiplier to the same level as the SR.

    1. I set the P2_GAIN_CTRL Register with the following values and plotted the EDD. For all the configurations in the table shown below, I observed that the later half of the the Record Length to be saturated. I also decreased the record length below 53mS (Default for Preset2) and observed saturation for the half of the set record length. 
    2. As you stated, I'm unable to disable the Digital Gain Multiplier and proceed further.
    3. The saturated EDD is observed even when the TVG is disabled (which implies the EDD saturation is not because of the AFE)

    P2_GAIN_CTRL Register Parameter Settings
    P2_DIG_GAIN_LR_ST P2_DIG_GAIN_LR P2_DIG_GAIN_SR Implication CorrespondingHEX Values written at P2_GAIN_CTRL Register (Address = 2Ah)
    TH9 multiplied by 1 multiplied by 1 Same level for SR and LR 0x00
    TH9 multiplied by 2 multiplied by 2 Same level for SR and LR 0x09
    TH12 multiplied by 1 multiplied by 1 Same level for SR and LR 0xC0
    TH9 multiplied by 2 multiplied by 1 Different level for SR and LR 0x08
    TH12 multiplied by 2 multiplied by 1 Different level for SR and LR 0xC8

    Could you please guide me further with this issue.

    Thank you,

    Best Regards,

    Varun P

  • Hi Varun,

    You understanding of the Px_GAIN_CTRL register is correct based on your table. If you have confirmed that both P1_GAIN_CTRL and P2_GAIN_CTRL are both 0x00, and you have tried both a preset 1 and 2 burst+listen command, here are my recommended next steps:

    1. Set all of your time varying gain and preset 1 and 2 digital gain multipliers to index 0 to ensure you are able to see a stable, non-saturated echo data dump. This means setting registers TVGAIN3, TVGGAIN4, TVGAIN5, TVGAIN6, INIT_GAIN, P1_GAIN_CTRL, and P2_GAIN_CTRL to a value of 0x00. This will ensure the TVG is fixed at the minimum value of the selected AFE_GAIN_RNG. Set the value of the AFE_GAIN_RNG bits to 11b for the absolute minimum TVG gain of 32.5dB. If this resolves your issue, you can then start to increase the TVG or DGM to better scale your SNR for object detection.
    2. Try running a listen only command. Is the echo data dump still saturated?
    3. Does the saturation occur at the same time marker as the long range starting threshold (TH9-12)?
    4. Are you waiting long enough to allow the record interval to complete before attempting to read the echo data dump? For absolute margin, wait 100ms to ensure it is not a wait/read issue.
    5. Can you read the individual echo data dump registers to confirm the echo data dump is actually saturated at the second half? You can perform 128 individual register read commands of the address range 0x80 to 0xFF to read the entire echo data dump alternatively to the single echo data dump read command. This is just for debug purposes.

    I still suspect this is a digital gain or time varying gain issue. Please ensure you are using the correct preset 1 or 2 command with respect to the Px_GAIN_CTRL register.