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.

[参考译文] ADS1119:ADC 读数错误

Guru**** 1689980 points
Other Parts Discussed in Thread: ADS1119, ADS1219
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/1194088/ads1119-wrong-adc-reading

器件型号:ADS1119
主题中讨论的其他器件: ADS1219

您好!
 使用 ADS1119读取 ADC 值时遇到问题。

对于 I2C、接收到来自 ADS1119的 ACK 响应。 我可以发送 CMD、对配置寄存器0x00进行写入、也可以读回我写的内容。

但是、读取 ADC 值始终是恒定的、并且与预期的值完全不同。 (预期:2.5V -读数:5V 满量程)。

ADC 配置 如下:输入2.5V AIN2-AGND、增益 1、90SPS、 连续转换模式、外部基准(5V)。

我不确定这里是否有任何问题。  如果对这一概念有任何误解,请告诉我。

P/s: 我的另一个观察结果是、当我尝试读回5个字节、3个前字节包含值(我期望 ADS1119数据表之后只有2个字节)。

我在尝试 从 ADC 读取5个字节时附加了通信的屏幕截图。

希望很快收到您的回复。 谢谢!

下面是我用于设置和读取 ADC 数据的代码:

// ADC set up
   // Reset device by common I2C 0x00 call
  Wire.beginTransmission(0x00);
  Wire.write(0x06);
  Serial.println(Wire.endTransmission());
  delay(500);
 
  // Read the value from the register 0x00 - should return 0 as default
  Wire.beginTransmission(0x40);
  Wire.write(0x20);
  Serial.println(Wire.endTransmission());
  Wire.requestFrom(0x40, 1);
  if (Wire.available() == 1) {
    int value = Wire.read();
    Serial.println(value);
  }
  delay(100);

  // Write a value to the register 0x00 - 0xA7 - 1010 0111 : AIN2AGND, GAIN 1, 90SPS, Continuous conversion mode, External ref 
  Wire.beginTransmission(0x40);
  Wire.write(0x40);
  Wire.write(0xA7);
  Serial.println(Wire.endTransmission());
  delay(100);

  // Read the value from the register 0x00 - should return 0xA37= 0d167
  Wire.beginTransmission(0x40);
  Wire.write(0x20);
  Serial.println(Wire.endTransmission());
  Wire.requestFrom(0x40, 1);
  if (Wire.available() == 1) {
    int value = Wire.read();
    Serial.println(value);
  }
  delay(100);

  // Start conversion
  Wire.beginTransmission(0x40);
  Wire.write(0x08);
  Serial.println(Wire.endTransmission());
  delay(1000);

// main loop

  //Reading data by cmd
  uint16_t value;

  Wire.beginTransmission(0x40);
  Wire.write(0x10);
  Wire.endTransmission();
  Serial.print("Number of bytes requested :"); Serial.println(Wire.requestFrom(0x40, 2));
  Serial.println();
  value = (Wire.read() << 8 | Wire.read());
  if (value > 0x7FFF)
  {
     value = 0x0;
  }
  float voltage = 5.0 * (float(value) / 32767) * 1;
  Serial.println(voltage);
  delay(1000);
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    // ADC 设置
      //通过通用 I2C 0x00调用重置器件
     Wire.beginTransmission(0x00);
     Wire.write (0x06);
     serial.println (Wire.endTransmission ());
     延迟(500);
     
     //从寄存器0x00读取值-应该返回0作为默认值
     Wire.beginTransmission(0x40);
     Wire.write (0x20);
     serial.println (Wire.endTransmission ());
     Wire.requestFrom (0x40、1);
     if (Wire.available ()= 1){
      int 值= Wire.read();
      serial.println (value);
     }
     延迟(100);

     //向寄存器0x00 - 0xA7 - 1010 0111写入一个值:AIN2AGND、增益1、90SPS、连续转换模式、外部基准  
     Wire.beginTransmission(0x40);
     Wire.write (0x40);
     Wire.write (0xA7);
     serial.println (Wire.endTransmission ());
     延迟(100);

     //从寄存器0x00读取值-应该返回0xA37=0d167
     Wire.beginTransmission(0x40);
     Wire.write (0x20);
     serial.println (Wire.endTransmission ());
     Wire.requestFrom (0x40、1);
     if (Wire.available ()= 1){
      int 值= Wire.read();
      serial.println (value);
     }
     延迟(100);

     //开始转换
     Wire.beginTransmission(0x40);
     Wire.write (0x08);
     serial.println (Wire.endTransmission ());
     延迟(1000);

    //主循环

     //通过 cmd 读取数据
     uint16_t 值;

     Wire.beginTransmission(0x40);
     Wire.write (0x10);
     wire.endTransmission ();
     serial.print ("请求的字节数:");serial.println (Wire.requestFrom (0x40、2));
     serial.println();
     值=(Wire.read()<< 8 | Wire.read());
     如果(值> 0x7FFF)
     {
       值= 0x0;
     }
     浮点电压= 5.0 *(浮点(值)/ 32767)* 1;
     serial.println (电压);
     延迟(1000);
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Thanh DAT LE、

    欢迎来到 E2E 论坛!  我没有看到任何特定于您的代码的问题。  您说您正在对输入施加2.5V 电压、但 ADS1119返回的代码是什么?  最好查看实际代码值、以便在计算之前能够捕获每个被传输的字节?  这有助于消除计算误差。

    不清楚为什么您尝试读取的数据比 ADC 转换结果的大小多。  如果怀疑返回的数据更多、请确保使用的是 ADS1119 (16位)而不是 ADS1219 (24位)。

    示波器快照很有用、但很难确定结果。  它看起来是0x6F61。  对于2.5V 输入、这似乎太高。  确保您的电源电压为5V 而不是3.3V。  如果它是3.3V、则返回的值会更接近2.5V。

    另外、请确保输入源与 ADS1119处于相同的接地电位。

    此致、

    Bob B

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Bob:

    非常感谢您的快速响应。  

    对于2.5V 输入、ADC 始终返回0x7FFF。 我尝试将 ADC 配置为单次触发模式并每1秒发送一次 START cmd、返回的结果相同。

    下面是从 ADC 读取2个字节时的通信屏幕截图、似乎与我得到的通信匹配(0x7FFF)。  

    我已验证电源电压5V、基准电压5V 和输入2.5V。 所有货物都具有相同的地面潜力。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我不是很熟悉 Arduino,但我相信 wire.endtransmission ();默认情况下会发送停止位。  在您的 RDATA (写入0x10)之后、尝试使用 wire.endtransmission (false);根据数据表的要求发送重复起始。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Thanh DAT LE、

    正如 Ben 所说的、首选使用重复启动、因为它可防止其他器件在写入和读取之间抓取 I2C 总线。  但是、这不是必需的、在我看来也不是问题。  当您获取数据时、更有可能读取使用内部基准而非外部基准的转换数据。  您能否为配置寄存器的寄存器写入和寄存器读取显示示波器截图?  对寄存器进行写入的另一个验证是检查 DRDY 引脚以查看其是否以所需的数据输出速率切换。  在发出 START 命令后、您应该会看到该引脚切换。

    我之前没有注意到这一点、但您声明变量名称"value"两次。  一次作为'int'、之后作为'uint16_t'。  此外、"uint16_t"不是标准 Arduino 数据类型。  对于转换数据、您可以直接将结果存储到"短"数据类型中。  由于返回的转换数据是二进制补码、因此正确的值将作为有符号值存储在"短整型"中。  对于寄存器数据、您可以将变量设置为8位无符号的"字节"类型。

    此致、

    Bob B

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Bob:  

    感谢您对变量名称和数据类型的建议!

    以下是我在配置寄存器中写入和读取0xA7时的通信屏幕截图:  

    写作  

    读数

    以下是我发送 START cmd 之后每1秒读取 cmd 时的 DRDY 引脚:

    一切似乎都很好。  我不确定这里是否有任何问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Ben、  

    我尝试 使用 wire.endtransmission (false)发送重复起始、似乎无法解决问题。

    感谢您的支持!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Thanh DAT LE、

    我对您的 DRDY 示波器图感到困惑。  我看到的似乎只是每秒一次转换。   您可能需要放大、因为我无法判断 ADC 是否在示波器图中的低电平周期期间切换 DRDY 引脚。  您应该看到的是、如果 ADC 处于连续转换模式、DRDY 会一直切换。

    可能发生的情况是电源问题、或者可能是某种形式的 ESD 或将 ADS1119复位的瞬态事件。  您似乎没有任何模拟输入保护或输入滤波器。  瞬态事件可以复位 ADS1119、这也会将配置复位回默认值。

    另一种可能是您的代码中的某些内容无法正常工作。  您能否将您的草图作为文件附加以供我审阅?

    此致、

    Bob B

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Bob:

    以下是 ADC 处于 连续转换模式(90SPS)时 DRDY 的屏幕截图。

     

    我们期望 DRDY 每1000/90 = 11ms 切换一次、但似乎信号始终处于高电平(无转换)。  

    您对此 ADS 的行为有什么结论吗?

    P/s:我还每1秒检查一次 CONFIG 寄存器的内容、非常确定 ADC 未被复位为默认值。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这些器件很容易死区-在执行 START 命令后、在连续转换模式下、没有太多因素会阻止它们至少切换 DRDY。  只要复位由于某种原因未被拉低、我倾向于认为器件已损坏。

    如果您将 MUX 设置为0b111、会发生什么情况?  您应该得到接近于零的 ADC 值。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Thanh DAT LE、

    我想您正在使用某种形式的原型设计系统。  您可以发送设置的照片吗?  此外、我再次要求提供作为文件附加的代码、以便我可以尝试复制。

    此致、

    Bob B

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Bob:  

    下面是测试代码和我的测试设置:使用外部 Arduino Uno 从板载 ADC 读取数据。 模拟输入信号(2.5V)由 STM32生成。 只有一个 ADS1119连接到 I2C 线路(使用1K 电阻器上拉至 Vcc)。 我们之所以使用 Arduino 进行测试、是因为在以前使用 STM32读取 ADC 值时、我们也会收到相同的错误值(0x7FFF)。

      e2e.ti.com/.../ADS1119.txt

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我想 Bob 所要求的是您的实际身体状况的图片。  例如、工作台的相机-手机图片、其中显示了您的设备和连接。

    如果您看到 MUX=0b111的结果、仍然会有所帮助

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Thanh DAT LE、

    我将回顾并在明天回来。

    此致、

    Bob B

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Ben、  

    如果 MUX=0b111、则返回的结果为常数0xFFFF (~0)、但是 DRDY 根本不会切换、因此我不确定是否为真值。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Bob:  

    我还通过直接邮件向您发送了实际设置的图片、请检查。 谢谢!  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Ben、Bob

    我们似乎是由一组克隆芯片提供的。 非常感谢您今天为我提供的帮助。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗯、我想我认为器件损坏的倾向不是太远。

    很高兴您对其进行了分类。