<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Setting up TWI interface between the nRF52 DK and ADS1115</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/63173/setting-up-twi-interface-between-the-nrf52-dk-and-ads1115</link><description>Hi, 
 I am trying to setup a TWI interface between the nRF52 DK and the 16-bit ADC ADS1115 from TI. I am using the breakout board from Adafruit ( https://www.adafruit.com/product/1085) . Anyway, using the TWI scanner I can see the device and the correct</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Fri, 11 Feb 2022 21:44:25 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/63173/setting-up-twi-interface-between-the-nrf52-dk-and-ads1115" /><item><title>RE: Setting up TWI interface between the nRF52 DK and ADS1115</title><link>https://devzone.nordicsemi.com/thread/352730?ContentTypeID=1</link><pubDate>Fri, 11 Feb 2022 21:44:25 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:1d2c50fa-c3d1-4dcf-9d6a-67d815d44ba5</guid><dc:creator>Abir Hossain</dc:creator><description>&lt;p&gt;So again, I know it will not help Emil anymore as its 2 years to the post but for others if they don&amp;#39;t want to bang their head like me.&lt;br /&gt;There need to be small delay between reg index write and reading back the value . That did the trick. 1ms delay worked for me, may be even less will work not sure. For reference the code here. (this is doing rough calculation for Irms, SCT013 is connected to ADS1115) &lt;br /&gt;&lt;br /&gt;Mind the 1ms delay,&amp;nbsp;&amp;nbsp;&lt;br /&gt;i2c_write(ADS1X15_ADDRESS, &amp;amp;reg, 1, true); &lt;br /&gt; nrf_delay_ms(1);&lt;br /&gt; i2c_read(ADS1X15_ADDRESS, &amp;amp;reg, ui8RxBuff, 2);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="ui-code" data-mode="text"&gt;// ====================== I2C - ADS1115 communicaiton =====================================

#define ADS1X15_ADDRESS (0x48) ///&amp;lt; 1001 000 (ADDR = GND)
#define PIN_SCL        (27)
#define PIN_SDA        (26)

static int sentbyte = 0;
void i2c_write(uint8_t addr, uint8_t *pdata, uint16_t dataSize, bool bStop)
{
  uint8_t tx_buf[2];
	int i = 0;
	if(bStop)
	{
		//NRF_TWIM0-&amp;gt;SHORTS = TWIM_SHORTS_LASTTX_SUSPEND_Msk;
		NRF_TWIM0-&amp;gt;SHORTS = TWIM_SHORTS_LASTTX_STOP_Msk;
	}
	
  NRF_TWIM0-&amp;gt;TXD.MAXCNT = dataSize;
  NRF_TWIM0-&amp;gt;TXD.PTR = (uint32_t)pdata;
	//NRF_TWIM0-&amp;gt;TXD.LIST = 1;

  NRF_TWIM0-&amp;gt;EVENTS_STOPPED = 0;
	NRF_TWIM0-&amp;gt;EVENTS_SUSPENDED = 0;
	NRF_TWIM0-&amp;gt;EVENTS_LASTTX = 0;
	if(NRF_TWIM0-&amp;gt;EVENTS_SUSPENDED){
		NRF_TWIM0-&amp;gt;TASKS_RESUME = 1;
	}else{
		NRF_TWIM0-&amp;gt;TASKS_STARTTX = 1;
	}
	if(bStop)
	{
		//while (NRF_TWIM0-&amp;gt;EVENTS_SUSPENDED == 0){};
		while (NRF_TWIM0-&amp;gt;EVENTS_STOPPED == 0){};
		sentbyte = NRF_TWIM0-&amp;gt;TXD.AMOUNT;
		while(NRF_TWIM0-&amp;gt;EVENTS_LASTTX == 0);
		NRF_TWIM0-&amp;gt;TASKS_STOP = 1;
		//NRF_TWIM0-&amp;gt;TASKS_SUSPEND = 1;
	}
}

void i2c_read(uint8_t addr, uint8_t *reg, uint8_t *pdata, uint16_t dataSize)
{
	sentbyte = 0;
  NRF_TWIM0-&amp;gt;SHORTS = TWIM_SHORTS_LASTRX_STOP_Msk;

  NRF_TWIM0-&amp;gt;RXD.MAXCNT = dataSize;
  NRF_TWIM0-&amp;gt;RXD.PTR = (uint32_t)pdata;

  NRF_TWIM0-&amp;gt;EVENTS_STOPPED = 0;
	NRF_TWIM0-&amp;gt;EVENTS_SUSPENDED = 0;
	NRF_TWIM0-&amp;gt;EVENTS_LASTRX = 0;
  NRF_TWIM0-&amp;gt;TASKS_STARTRX = 1;
  while (NRF_TWIM0-&amp;gt;EVENTS_STOPPED == 0);
	sentbyte = NRF_TWIM0-&amp;gt;RXD.AMOUNT;
//	while(NRF_TWIM0-&amp;gt;EVENTS_LASTRX == 0);
	NRF_TWIM0-&amp;gt;TASKS_STOP = 1;
}

void i2c_setup (void)
{
		
  NRF_TWIM0-&amp;gt;PSEL.SCL = PIN_SCL;
  NRF_TWIM0-&amp;gt;PSEL.SDA = PIN_SDA;

  NRF_TWIM0-&amp;gt;ADDRESS = ADS1X15_ADDRESS;
  NRF_TWIM0-&amp;gt;FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K100 &amp;lt;&amp;lt; TWIM_FREQUENCY_FREQUENCY_Pos;
 // NRF_TWIM0-&amp;gt;SHORTS = 0;

  NRF_TWIM0-&amp;gt;ENABLE = TWIM_ENABLE_ENABLE_Enabled &amp;lt;&amp;lt; TWIM_ENABLE_ENABLE_Pos;
}


/**************************************************************************/
/*!
    @brief  Reads the conversion results, measuring the voltage
            difference between the P (AIN0) and N (AIN1) input.  Generates
            a signed value since the difference can be either
            positive or negative.

    @return the ADC reading
*/
/**************************************************************************/
#define ADS1X15_REG_POINTER_CONVERT (0x00)   ///&amp;lt; Conversion

#define ADS1X15_REG_CONFIG_CQUE_NONE                                           \
  (0x0003) ///&amp;lt; Disable the comparator and put ALERT/RDY in high state (default)
#define ADS1X15_REG_CONFIG_CLAT_NONLAT                                         \
  (0x0000) ///&amp;lt; Non-latching comparator (default)
#define ADS1X15_REG_CONFIG_CPOL_ACTVLOW                                        \
  (0x0000) ///&amp;lt; ALERT/RDY pin is low when active (default)
#define ADS1X15_REG_CONFIG_CMODE_TRAD                                          \
  (0x0000) ///&amp;lt; Traditional comparator with hysteresis (default)
#define ADS1X15_REG_CONFIG_MODE_SINGLE                                         \
  (0x0100) ///&amp;lt; Power-down single-shot mode (default)

#define ADS1X15_REG_CONFIG_PGA_6_144V (0x0000) ///&amp;lt; +/-6.144V range = Gain 2/3
#define ADS1X15_REG_CONFIG_PGA_4_096V (0x0200) ///&amp;lt; +/-4.096V range = Gain 1
#define ADS1X15_REG_CONFIG_PGA_2_048V                                          \
  (0x0400) ///&amp;lt; +/-2.048V range = Gain 2 (default)
#define ADS1X15_REG_CONFIG_PGA_1_024V (0x0600) ///&amp;lt; +/-1.024V range = Gain 4
#define ADS1X15_REG_CONFIG_PGA_0_512V (0x0800) ///&amp;lt; +/-0.512V range = Gain 8
#define ADS1X15_REG_CONFIG_PGA_0_256V (0x0A00) ///&amp;lt; +/-0.256V range = Gain 16

#define RATE_ADS1015_1600SPS (0x0080) ///&amp;lt; 1600 samples per second (default)

#define ADS1X15_REG_CONFIG_MUX_SINGLE_0 (0x4000) ///&amp;lt; Single-ended AIN0
#define ADS1X15_REG_CONFIG_MUX_DIFF_0_1                                        \
  (0x0000) ///&amp;lt; Differential P = AIN0, N = AIN1 (default)
#define ADS1X15_REG_CONFIG_OS_SINGLE                                           \
  (0x8000) ///&amp;lt; Write: Set to start a single-conversion
#define ADS1X15_REG_POINTER_CONFIG (0x01)    ///&amp;lt; Configuration

/**************************************************************************/
/*!
    @brief  Writes 16-bits to the specified destination register

    @param reg register address to write to
    @param value value to write to register
*/
/**************************************************************************/

void ADS1X15_writeRegister(uint8_t reg, uint16_t value) {
	static uint8_t ui8buffer[4] = {0};
  ui8buffer[0] = reg;
  ui8buffer[1] = value &amp;gt;&amp;gt; 8;
  ui8buffer[2] = value &amp;amp; 0xFF;
  i2c_write(ADS1X15_ADDRESS, ui8buffer, 3, true);//sizeof(ui8buffer));
	
	nrf_delay_ms(2);
}

/**************************************************************************/
/*!
    @brief  Read 16-bits from the specified destination register

    @param reg register address to read from

    @return 16 bit register value read
*/
/**************************************************************************/
uint16_t ADS1X15_readRegister(uint8_t reg) {
	uint8_t ui8RxBuff[3] = {0}; 
  i2c_write(ADS1X15_ADDRESS, &amp;amp;reg, 1, true); 
	nrf_delay_ms(1);
  i2c_read(ADS1X15_ADDRESS, &amp;amp;reg, ui8RxBuff, 2);
	
	return (ui8RxBuff[0] &amp;lt;&amp;lt; 8 | ui8RxBuff[1]);
}
	
/**************************************************************************/
/*!
    @brief  Returns true if conversion is complete, false otherwise.
*/
/**************************************************************************/
bool ADS1X115_conversionComplete() {
  return (ADS1X15_readRegister(ADS1X15_REG_POINTER_CONFIG) &amp;amp; 0x8000) != 0;
}

/**************************************************************************/
/*!
    @brief  In order to clear the comparator, we need to read the
            conversion results.  This function reads the last conversion
            results without changing the config value.

    @return the last ADC reading
*/
/**************************************************************************/
int16_t ADS1X15_getLastConversionResults(void) {
  // Read the conversion results
	//ADS1X15_readRegister(0x00);
	//ADS1X15_readRegister(0x01);
	//ADS1X15_readRegister(0x10);
	//ADS1X15_readRegister(0x11);
  return ADS1X15_readRegister(ADS1X15_REG_POINTER_CONVERT);
}
	
int16_t ADS1X15_readADC_Differential_0_1(void) {
  // Start with default values
  static uint16_t config =
      ADS1X15_REG_CONFIG_CQUE_NONE |    // Disable the comparator (default val)
      ADS1X15_REG_CONFIG_CLAT_NONLAT |  // Non-latching (default val)
      ADS1X15_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low   (default val)
      ADS1X15_REG_CONFIG_CMODE_TRAD |   // Traditional comparator (default val)
      ADS1X15_REG_CONFIG_MODE_SINGLE;   // Single-shot mode (default)

  // Set PGA/voltage range
  config |= ADS1X15_REG_CONFIG_PGA_1_024V;

  // Set data rate
  config |= RATE_ADS1015_1600SPS;

  // Set channels
  config |= ADS1X15_REG_CONFIG_MUX_DIFF_0_1; // AIN0 = P, AIN1 = N

  // Set &amp;#39;start single-conversion&amp;#39; bit
  config |= ADS1X15_REG_CONFIG_OS_SINGLE;

	config = 0x818B; // Try the Arduino config 
  // Write config register to the ADC
  ADS1X15_writeRegister(ADS1X15_REG_POINTER_CONFIG, config);

  // Wait for the conversion to complete
  while (!ADS1X115_conversionComplete());
  // Read the conversion results
  return ADS1X15_getLastConversionResults();
}

const float FACTOR_1 = 20; //20A/1V from teh CT
const float multiplier_1 = 0.00005;

float getCurrent (void)
{
	float voltage_1;
  float current_1;
  float sum_1 = 0;
  long time_check_1 = 0;
  int counter_1 = 0;

  while (time_check_1++ &amp;lt; 200)
  {
    voltage_1 = (float)ADS1X15_readADC_Differential_0_1() * multiplier_1;
    current_1 = voltage_1 * FACTOR_1;

    sum_1 += pow(current_1, 2);
    counter_1 ++;
  }

  current_1 = sqrt(sum_1 / counter_1);
  return current_1;
}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Setting up TWI interface between the nRF52 DK and ADS1115</title><link>https://devzone.nordicsemi.com/thread/352466?ContentTypeID=1</link><pubDate>Fri, 11 Feb 2022 04:37:43 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:49d4c76a-1e65-438b-9cbf-e4aa1d2d4aa8</guid><dc:creator>Abir Hossain</dc:creator><description>&lt;p&gt;I know its really old thread might not be any help to respond but just in case others are checking,&lt;br /&gt;&amp;quot;&amp;nbsp;nrf_drv_twi_tx(p_instance, i2cAddress, &amp;amp;reg, sizeof(&amp;amp;reg), false);&amp;quot;&lt;br /&gt;&lt;br /&gt;shouldn&amp;#39;t it be sizeof(reg). That migh not solve the issue but its getting address size.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>