<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://www.cqrobot.wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Chenqi</id>
		<title>CQRobot-Wiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://www.cqrobot.wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Chenqi"/>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php/Special:Contributions/Chenqi"/>
		<updated>2026-04-05T17:00:56Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=TDS_(Total_Dissolved_Solids)_Meter_Sensor_SKU:_CQRSENTDS01&amp;diff=5012</id>
		<title>TDS (Total Dissolved Solids) Meter Sensor SKU: CQRSENTDS01</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=TDS_(Total_Dissolved_Solids)_Meter_Sensor_SKU:_CQRSENTDS01&amp;diff=5012"/>
				<updated>2026-03-06T06:47:35Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Connections and Examples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:TDS Meter Sensor-7F.jpg| right |thumb|100px TDS Meter Sensor]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
&lt;br /&gt;
TDS (Total Dissolved Solids), Chinese name Total Dissolved Solids, also known as Total Dissolved Solids, indicates how many milligrams of dissolved solids are dissolved in 1 liter of water. Generally speaking, the higher the TDS value, the more dissolved substances contained in the water and the less clean the water. Therefore, the value of TDS can be used as one of the basis for reflecting the cleanliness of water. The commonly used TDS testing equipment is a TDS pen. Although it is cheap and easy to use, it cannot transmit data to the control system for long-term online monitoring and water quality analysis. Using a special instrument, although it can transmit data and has high accuracy, it is very expensive.&lt;br /&gt;
&lt;br /&gt;
CQRobot has launched an arduino-compatible TDS sensor, which can be used to measure the TDS value of water after connecting to the arduino controller. This product is specially designed for arduino, plug and play, easy to use. 3.3V~5.5V wide voltage power supply, 0 to 2.3V analog signal output, making this product compatible with 5V and 3.3V control systems, it can be easily connected to existing control systems. With CQRobot ADS1115 16-bit AD conversion module (Model: CQRADS1115), it can accurately collect and convert analog signals to meet the compatibility requirements of the Raspberry Pi motherboard.&lt;br /&gt;
&lt;br /&gt;
The excitation source for measurement uses AC signals, which can effectively prevent probe polarization, extend the life of the probe, and increase the stability of the output signal. The TDS probe is a waterproof probe that can be immersed in water for long-term measurement. This product can be applied to water quality testing in areas such as domestic water and hydroponics. With this sensor, you can easily DIY a TDS detector, easily detect the cleanliness of the water, and check your water quality.&lt;br /&gt;
&lt;br /&gt;
[[image:TDS Meter Sensor-7B.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Size Display'''==&lt;br /&gt;
[[image:TDS Meter Sensor-7C1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specifications'''==&lt;br /&gt;
'''Signal Transmitter Board Specifications'''&lt;br /&gt;
*Input Voltage: 3.3V to 5.5V&lt;br /&gt;
*Output Voltage: 0 to 2.3V&lt;br /&gt;
*Working Current: 3mA to 6mA&lt;br /&gt;
*TDS Measurement Range: 0 to 1000ppm&lt;br /&gt;
*TDS Measurement Accuracy: Plus/Minus 10% F.S. (25 Degree Celsius)&lt;br /&gt;
*Module Size: 43mm * 32.2mm&lt;br /&gt;
*Module Interface: JST 2.0mm 3-Pin&lt;br /&gt;
*Electrode Interface: JST 2.54mm 2-Pin&lt;br /&gt;
'''TDS Probe Specifications'''&lt;br /&gt;
*Number of Needle: 2&lt;br /&gt;
*Total Length: 60cm&lt;br /&gt;
*Connection Interface: JTS 2.54mm 2-Pin&lt;br /&gt;
*Color: Black&lt;br /&gt;
*Other: Waterproof Probe&lt;br /&gt;
'''Ocean Interface Cable Specifications'''&lt;br /&gt;
*Cable specifications: 22AWG&lt;br /&gt;
*Material: Silicone&lt;br /&gt;
*Withstand Voltage: Less Than 50V&lt;br /&gt;
*Withstand Current: Less Than 1000MA&lt;br /&gt;
*Length: 21cm&lt;br /&gt;
*Line Sequence: Black-Negative Power Supply, Red-Positive Power Supply, Green-Signal Terminal.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
'''Attention'''&lt;br /&gt;
*The probe can not be used in water above 55 degrees centigrade.&lt;br /&gt;
*The probe can not be left too close to the edge of the container, otherwise it will affect the reading.&lt;br /&gt;
*The head and the cable of the probe are waterproof, but the connector and the signal transmitter board are not waterproof. Please be careful.&lt;br /&gt;
*When using the TDS instrument sensor, the sensor probe is immersed in liquid, and the purchaser needs to '''Separate''' the sensor '''Probe Protective Cover''' to avoid incorrect data reading and malfunction.&lt;br /&gt;
&lt;br /&gt;
[[image:TDS Meter Sensor-7D.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
*The TDS probe cannot be used in water above 55 degrees Celsius;&lt;br /&gt;
*The TDS probe should not be placed too close to the edge of the container, otherwise it will affect the sensor reading parameters;&lt;br /&gt;
*The TDS probe head and lead are made of waterproof material and can be immersed in water, but the cable interface and signal transfer board are not waterproof, please use them carefully.&lt;br /&gt;
&lt;br /&gt;
'''Arduino Connections'''&lt;br /&gt;
&lt;br /&gt;
*The DuPont female single-head wiring we distribute cannot be directly connected to the UNO R3 control board. Need to be in Stack the sensor expansion board on the UNO R3 control board, or connect the male-to-male Dupont wire to the Dupont female single-head wiring(Bread Wire).&lt;br /&gt;
&lt;br /&gt;
'''Raspberry Pi Test Code'''&lt;br /&gt;
&lt;br /&gt;
*Compatible Raspberry Pi needs to be used with ADS1115 16-bit AD conversion module. Please refer to the specific test code: http://www.cqrobot.wiki/index.php/4-CH_16-Bit_ADS1115_ADC_Module_SKU:_CQRADC001&lt;br /&gt;
*Connect the module to the Raspberry Pi 4B, and put the test code in the Raspberry Pi system in the form of a folder. Dial the ADD dial switch to the 0X48 end.&lt;br /&gt;
*In this experiment, the Raspberry Pi I2C communication function is used. You need to turn on the I2C function, enter sudo raspi-config in the Raspberry Pi system, and then perform the following operations.&lt;br /&gt;
*This kit does '''not include''' 4-CH 16-Bit ADS1115 ADC Module (Model: CQRADC001), buyers need to purchase it separately.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Arduino Application'''==&lt;br /&gt;
&lt;br /&gt;
'''Note''': The DuPont female single-ended wiring we distribute cannot be directly connected to the UNO R3 control board. When wiring, you need to stack the sensor expansion board on the UNO R3 control board, or connect the male-to-male Dupont wire (bread wire) on the Dupont wire female single-ended wire.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-107.jpg|600px]]&lt;br /&gt;
&lt;br /&gt;
'''Download and Run the Test Examples'''&lt;br /&gt;
&lt;br /&gt;
[[Media: TDS Meter Sensor-Arduino.rar]]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define TdsSensorPin A1&lt;br /&gt;
#define VREF 5.0      // analog reference voltage(Volt) of the ADC&lt;br /&gt;
#define SCOUNT  30           // sum of sample point&lt;br /&gt;
int analogBuffer[SCOUNT];    // store the analog value in the array, read from ADC&lt;br /&gt;
int analogBufferTemp[SCOUNT];&lt;br /&gt;
int analogBufferIndex = 0, copyIndex = 0;&lt;br /&gt;
float averageVoltage = 0, tdsValue = 0, temperature = 25;&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  pinMode(TdsSensorPin, INPUT);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  static unsigned long analogSampleTimepoint = millis();&lt;br /&gt;
  if (millis() - analogSampleTimepoint &amp;gt; 40U)  //every 40 milliseconds,read the analog value from the ADC&lt;br /&gt;
  {&lt;br /&gt;
    analogSampleTimepoint = millis();&lt;br /&gt;
    analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin);    //read the analog value and store into the buffer&lt;br /&gt;
    analogBufferIndex++;&lt;br /&gt;
    if (analogBufferIndex == SCOUNT)&lt;br /&gt;
      analogBufferIndex = 0;&lt;br /&gt;
  }&lt;br /&gt;
  static unsigned long printTimepoint = millis();&lt;br /&gt;
  if (millis() - printTimepoint &amp;gt; 800U)&lt;br /&gt;
  {&lt;br /&gt;
    printTimepoint = millis();&lt;br /&gt;
    for (copyIndex = 0; copyIndex &amp;lt; SCOUNT; copyIndex++)&lt;br /&gt;
      analogBufferTemp[copyIndex] = analogBuffer[copyIndex];&lt;br /&gt;
    averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF / 1024.0; // read the analog value more stable by the median filtering algorithm, and convert to voltage value&lt;br /&gt;
    float compensationCoefficient = 1.0 + 0.02 * (temperature - 25.0); //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));&lt;br /&gt;
    float compensationVolatge = averageVoltage / compensationCoefficient; //temperature compensation&lt;br /&gt;
    tdsValue = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5; //convert voltage value to tds value&lt;br /&gt;
    //Serial.print(&amp;quot;voltage:&amp;quot;);&lt;br /&gt;
    //Serial.print(averageVoltage,2);&lt;br /&gt;
    //Serial.print(&amp;quot;V   &amp;quot;);&lt;br /&gt;
    Serial.print(&amp;quot;TDS----Value:&amp;quot;);&lt;br /&gt;
    Serial.print(tdsValue, 0);&lt;br /&gt;
    Serial.println(&amp;quot;ppm&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
int getMedianNum(int bArray[], int iFilterLen)&lt;br /&gt;
{&lt;br /&gt;
  int bTab[iFilterLen];&lt;br /&gt;
  for (byte i = 0; i &amp;lt; iFilterLen; i++)&lt;br /&gt;
    bTab[i] = bArray[i];&lt;br /&gt;
  int i, j, bTemp;&lt;br /&gt;
  for (j = 0; j &amp;lt; iFilterLen - 1; j++)&lt;br /&gt;
  {&lt;br /&gt;
    for (i = 0; i &amp;lt; iFilterLen - j - 1; i++)&lt;br /&gt;
    {&lt;br /&gt;
      if (bTab[i] &amp;gt; bTab[i + 1])&lt;br /&gt;
      {&lt;br /&gt;
        bTemp = bTab[i];&lt;br /&gt;
        bTab[i] = bTab[i + 1];&lt;br /&gt;
        bTab[i + 1] = bTemp;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  if ((iFilterLen &amp;amp; 1) &amp;gt; 0)&lt;br /&gt;
    bTemp = bTab[(iFilterLen - 1) / 2];&lt;br /&gt;
  else&lt;br /&gt;
    bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;&lt;br /&gt;
  return bTemp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Test Results'''&lt;br /&gt;
&lt;br /&gt;
Connect according to the wiring diagram, upload the code on the arduino board, after power-on, open the serial monitor, set the baud rate to 115200, insert the TDS probe into the water to be measured, stir a few times, and observe the value printed on the serial monitor, This value is the TDS value of water. As shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-101.jpg|400px]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''TDS Meter Sensor vs. Xiaomi Water Quality Test Pen'''==&lt;br /&gt;
This is a sample of tap water from the urban pipe network.&lt;br /&gt;
&lt;br /&gt;
TDS value of Xiaomi's test pen: 84 ppm&lt;br /&gt;
&lt;br /&gt;
TDS value of our sensor: 92 ppm&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The test result is only responsible for the sample, but you can serve as a reference.&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|[[File:CQRSENTDS01-X22.jpg |left|300px]]&lt;br /&gt;
|[[File:CQRSENTDS01-X3.jpg |left|300px]]&lt;br /&gt;
|[[File:CQRSENTDS01-X4.jpg |left|300px]]&lt;br /&gt;
|[[File:CQRSENTDS01-X5.jpg |left|300px]]&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Raspberry Pi Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-76.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-73.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
'''Raspberry Pi 4B Pinout Diagram'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-75.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Create a folder and a “.c” file, then write the code.&lt;br /&gt;
&lt;br /&gt;
[[Media: ADS1115.zip]]&lt;br /&gt;
&lt;br /&gt;
*You can directly add to the compressed file.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-781.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
gcc -Wall -g -o ADS1115 ADS1115.c -lm&lt;br /&gt;
&lt;br /&gt;
./ADS1115&lt;br /&gt;
&lt;br /&gt;
Go to the folder created in the terminal, use GCC cross-compilation and run the file.&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/ioctl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;linux/i2c-dev.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define ADS1115_ADDR 0x48&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int fd = open(&amp;quot;/dev/i2c-1&amp;quot;, O_RDWR);&lt;br /&gt;
    if (fd &amp;lt; 0) return 1;&lt;br /&gt;
    if (ioctl(fd, I2C_SLAVE, ADS1115_ADDR) &amp;lt; 0) return 1;&lt;br /&gt;
    &lt;br /&gt;
    while(1) {&lt;br /&gt;
        unsigned char config[3] = {0x01, 0xC2, 0x83};&lt;br /&gt;
        unsigned char result[2];&lt;br /&gt;
        &lt;br /&gt;
        write(fd, config, 3);&lt;br /&gt;
        usleep(8000);&lt;br /&gt;
        &lt;br /&gt;
        unsigned char reg[1] = {0x00};&lt;br /&gt;
        write(fd, reg, 1);&lt;br /&gt;
        read(fd, result, 2);&lt;br /&gt;
        &lt;br /&gt;
        int16_t adc = (result[0] &amp;lt;&amp;lt; 8) | result[1];&lt;br /&gt;
        float voltage = adc * 0.125 / 1000.0;&lt;br /&gt;
        float ntc_r = (3.3 * 10000.0 / voltage) - 20000.0;&lt;br /&gt;
        float temp = 1.0 / (log(ntc_r / 10000.0) / 3950.0 + 1.0 / 298.15) - 273.15;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Temp: %.1fC\n&amp;quot;, temp);&lt;br /&gt;
        sleep(1);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Test Results:&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-791.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the I2C address to 0x48. You can modify this line of code as needed: #define ADS1115_ADDR 0x48.&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the input channel to AIN0. You can replace it with the following code based on actual needs:&lt;br /&gt;
&lt;br /&gt;
AIN0: 0xC2&lt;br /&gt;
&lt;br /&gt;
AIN1: 0xD2&lt;br /&gt;
&lt;br /&gt;
AIN2: 0xE2 &lt;br /&gt;
&lt;br /&gt;
AIN3: 0xF2&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Used in Conjunction with the 4-CH 16-Bit ADS1115 ADC Module (SKU: CQRADC001 / ASIN: B0GF12JQ8R)'''==&lt;br /&gt;
[[image:CQRADC001-7.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
*'''Sample Program'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-80.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Create a folder and a “.c” file, then write the code.&lt;br /&gt;
&lt;br /&gt;
[[Media: ADSTDS.zip]]&lt;br /&gt;
&lt;br /&gt;
*You can directly add to the compressed file.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-811.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
gcc -o ADSTDS ADSTDS.c -lwiringPi&lt;br /&gt;
&lt;br /&gt;
./ADSTDS&lt;br /&gt;
&lt;br /&gt;
Go to the folder created in the terminal, use GCC cross-compilation and run the file.&lt;br /&gt;
&lt;br /&gt;
*'''Example Code'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;wiringPi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;wiringPiI2C.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define VREF 5.0f           &lt;br /&gt;
#define SCOUNT 30           // Sampling points&lt;br /&gt;
#define TEMPERATURE 25.0f   // Water temperature (Celsius)&lt;br /&gt;
&lt;br /&gt;
int analogBuffer[SCOUNT];        &lt;br /&gt;
int analogBufferTemp[SCOUNT];&lt;br /&gt;
int analogBufferIndex = 0;&lt;br /&gt;
float averageVoltage = 0, tdsValue = 0;&lt;br /&gt;
&lt;br /&gt;
int ads1115_fd;&lt;br /&gt;
// Function declarations&lt;br /&gt;
int getMedianNum(int bArray[], int iFilterLen);&lt;br /&gt;
int readADS1115();&lt;br /&gt;
unsigned long my_millis();  &lt;br /&gt;
&lt;br /&gt;
unsigned long my_millis() {&lt;br /&gt;
    struct timespec ts;&lt;br /&gt;
    clock_gettime(CLOCK_MONOTONIC, &amp;amp;ts);&lt;br /&gt;
    return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int getMedianNum(int bArray[], int iFilterLen) {&lt;br /&gt;
    int bTab[iFilterLen];&lt;br /&gt;
    for (int i = 0; i &amp;lt; iFilterLen; i++) {&lt;br /&gt;
        bTab[i] = bArray[i];&lt;br /&gt;
    }&lt;br /&gt;
    int i, j, bTemp;&lt;br /&gt;
    for (j = 0; j &amp;lt; iFilterLen - 1; j++) {&lt;br /&gt;
        for (i = 0; i &amp;lt; iFilterLen - j - 1; i++) {&lt;br /&gt;
            if (bTab[i] &amp;gt; bTab[i + 1]) {&lt;br /&gt;
                bTemp = bTab[i];&lt;br /&gt;
                bTab[i] = bTab[i + 1];&lt;br /&gt;
                bTab[i + 1] = bTemp;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if ((iFilterLen &amp;amp; 1) &amp;gt; 0) {&lt;br /&gt;
        bTemp = bTab[(iFilterLen - 1) / 2];&lt;br /&gt;
    } else {&lt;br /&gt;
        bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;&lt;br /&gt;
    }&lt;br /&gt;
    return bTemp;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int readADS1115() {&lt;br /&gt;
    // Configure ADS1115: Channel 0&lt;br /&gt;
    uint16_t config = 0xC283;  &lt;br /&gt;
    wiringPiI2CWriteReg16(ads1115_fd, 0x01, (config &amp;gt;&amp;gt; 8) | (config &amp;lt;&amp;lt; 8));&lt;br /&gt;
    usleep(8000);  &lt;br /&gt;
    &lt;br /&gt;
    uint16_t result = wiringPiI2CReadReg16(ads1115_fd, 0x00);&lt;br /&gt;
    int16_t adc = ((result &amp;gt;&amp;gt; 8) &amp;amp; 0xFF) | ((result &amp;amp; 0xFF) &amp;lt;&amp;lt; 8);&lt;br /&gt;
    &lt;br /&gt;
 &lt;br /&gt;
    static int debug_count = 0;&lt;br /&gt;
    if (debug_count++ % 20 == 0) {&lt;br /&gt;
        printf(&amp;quot;[Raw ADC: %d] &amp;quot;, adc);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    int adc_abs = abs(adc);&lt;br /&gt;
    // Convert to analog value (0-1023)&lt;br /&gt;
    int arduino_value = (adc_abs * 1024) / 30000;&lt;br /&gt;
    // Limit to 0-1023 range&lt;br /&gt;
    if (arduino_value &amp;gt; 1023) arduino_value = 1023;&lt;br /&gt;
    if (arduino_value &amp;lt; 0) arduino_value = 0;&lt;br /&gt;
    return arduino_value;&lt;br /&gt;
}&lt;br /&gt;
int main() {&lt;br /&gt;
    printf(&amp;quot;=== Raspberry Pi TDS Measurement ===\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;TDS = 133.42*V^3 - 255.86*V^2 + 857.39*V * 0.5\n\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // Initialize wiringPi&lt;br /&gt;
    if (wiringPiSetup() &amp;lt; 0) {&lt;br /&gt;
        printf(&amp;quot;wiringPi initialization failed\n&amp;quot;);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Initialize ADS1115&lt;br /&gt;
    ads1115_fd = wiringPiI2CSetup(0x48);&lt;br /&gt;
    if (ads1115_fd &amp;lt; 0) {&lt;br /&gt;
        printf(&amp;quot;ADS1115 initialization failed (address 0x48)\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Please check: sudo i2cdetect -y 1\n&amp;quot;);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;✓ Hardware initialization completed\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Starting measurement...\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;----------------------------------------\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // Timepoint variables (using custom my_millis)&lt;br /&gt;
    unsigned long analogSampleTimepoint = my_millis();&lt;br /&gt;
    unsigned long printTimepoint = my_millis();&lt;br /&gt;
    &lt;br /&gt;
    while (1) {&lt;br /&gt;
        unsigned long currentMillis = my_millis();     &lt;br /&gt;
        if (currentMillis - analogSampleTimepoint &amp;gt; 40U) {&lt;br /&gt;
            analogSampleTimepoint = currentMillis;&lt;br /&gt;
            &lt;br /&gt;
            int arduinoValue = readADS1115();&lt;br /&gt;
            &lt;br /&gt;
            analogBuffer[analogBufferIndex] = arduinoValue;&lt;br /&gt;
            analogBufferIndex++;&lt;br /&gt;
            if (analogBufferIndex == SCOUNT) {&lt;br /&gt;
                analogBufferIndex = 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
         &lt;br /&gt;
        if (currentMillis - printTimepoint &amp;gt; 800U) {&lt;br /&gt;
            printTimepoint = currentMillis;&lt;br /&gt;
           &lt;br /&gt;
            for (int copyIndex = 0; copyIndex &amp;lt; SCOUNT; copyIndex++) {&lt;br /&gt;
                analogBufferTemp[copyIndex] = analogBuffer[copyIndex];&lt;br /&gt;
            }&lt;br /&gt;
   &lt;br /&gt;
            int medianValue = getMedianNum(analogBufferTemp, SCOUNT);&lt;br /&gt;
            averageVoltage = medianValue * VREF / 1024.0;&lt;br /&gt;
            float compensationCoefficient = 1.0 + 0.02 * (TEMPERATURE - 25.0);&lt;br /&gt;
            float compensationVoltage = averageVoltage / compensationCoefficient;&lt;br /&gt;
            tdsValue = (133.42 * compensationVoltage * compensationVoltage * compensationVoltage &lt;br /&gt;
                       - 255.86 * compensationVoltage * compensationVoltage &lt;br /&gt;
                       + 857.39 * compensationVoltage) * 0.5;&lt;br /&gt;
            printf(&amp;quot;TDS Value: %.0fppm&amp;quot;, tdsValue);&lt;br /&gt;
           &lt;br /&gt;
            printf(&amp;quot; (ADC:%d, Volt:%.3fV)\n&amp;quot;, medianValue, averageVoltage);&lt;br /&gt;
            &lt;br /&gt;
            fflush(stdout);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        usleep(1000);  &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Test Results:&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-821.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
The original ADC value represents the raw 16-bit analog-to-digital conversion data from the ADS1115. The ADC value is the stabilized output after median filtering. The voltage value is the calculated corresponding voltage. The TDS value indicates the dissolved solids content in the water. &lt;br /&gt;
&lt;br /&gt;
In this configuration, the I2C address is 0x48, and the analog port is AIN0.&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=TDS_(Total_Dissolved_Solids)_Meter_Sensor_SKU:_CQRSENTDS01&amp;diff=5011</id>
		<title>TDS (Total Dissolved Solids) Meter Sensor SKU: CQRSENTDS01</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=TDS_(Total_Dissolved_Solids)_Meter_Sensor_SKU:_CQRSENTDS01&amp;diff=5011"/>
				<updated>2026-03-06T06:41:56Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Raspberry Pi Application */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:TDS Meter Sensor-7F.jpg| right |thumb|100px TDS Meter Sensor]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
&lt;br /&gt;
TDS (Total Dissolved Solids), Chinese name Total Dissolved Solids, also known as Total Dissolved Solids, indicates how many milligrams of dissolved solids are dissolved in 1 liter of water. Generally speaking, the higher the TDS value, the more dissolved substances contained in the water and the less clean the water. Therefore, the value of TDS can be used as one of the basis for reflecting the cleanliness of water. The commonly used TDS testing equipment is a TDS pen. Although it is cheap and easy to use, it cannot transmit data to the control system for long-term online monitoring and water quality analysis. Using a special instrument, although it can transmit data and has high accuracy, it is very expensive.&lt;br /&gt;
&lt;br /&gt;
CQRobot has launched an arduino-compatible TDS sensor, which can be used to measure the TDS value of water after connecting to the arduino controller. This product is specially designed for arduino, plug and play, easy to use. 3.3V~5.5V wide voltage power supply, 0 to 2.3V analog signal output, making this product compatible with 5V and 3.3V control systems, it can be easily connected to existing control systems. With CQRobot ADS1115 16-bit AD conversion module (Model: CQRADS1115), it can accurately collect and convert analog signals to meet the compatibility requirements of the Raspberry Pi motherboard.&lt;br /&gt;
&lt;br /&gt;
The excitation source for measurement uses AC signals, which can effectively prevent probe polarization, extend the life of the probe, and increase the stability of the output signal. The TDS probe is a waterproof probe that can be immersed in water for long-term measurement. This product can be applied to water quality testing in areas such as domestic water and hydroponics. With this sensor, you can easily DIY a TDS detector, easily detect the cleanliness of the water, and check your water quality.&lt;br /&gt;
&lt;br /&gt;
[[image:TDS Meter Sensor-7B.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Size Display'''==&lt;br /&gt;
[[image:TDS Meter Sensor-7C1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specifications'''==&lt;br /&gt;
'''Signal Transmitter Board Specifications'''&lt;br /&gt;
*Input Voltage: 3.3V to 5.5V&lt;br /&gt;
*Output Voltage: 0 to 2.3V&lt;br /&gt;
*Working Current: 3mA to 6mA&lt;br /&gt;
*TDS Measurement Range: 0 to 1000ppm&lt;br /&gt;
*TDS Measurement Accuracy: Plus/Minus 10% F.S. (25 Degree Celsius)&lt;br /&gt;
*Module Size: 43mm * 32.2mm&lt;br /&gt;
*Module Interface: JST 2.0mm 3-Pin&lt;br /&gt;
*Electrode Interface: JST 2.54mm 2-Pin&lt;br /&gt;
'''TDS Probe Specifications'''&lt;br /&gt;
*Number of Needle: 2&lt;br /&gt;
*Total Length: 60cm&lt;br /&gt;
*Connection Interface: JTS 2.54mm 2-Pin&lt;br /&gt;
*Color: Black&lt;br /&gt;
*Other: Waterproof Probe&lt;br /&gt;
'''Ocean Interface Cable Specifications'''&lt;br /&gt;
*Cable specifications: 22AWG&lt;br /&gt;
*Material: Silicone&lt;br /&gt;
*Withstand Voltage: Less Than 50V&lt;br /&gt;
*Withstand Current: Less Than 1000MA&lt;br /&gt;
*Length: 21cm&lt;br /&gt;
*Line Sequence: Black-Negative Power Supply, Red-Positive Power Supply, Green-Signal Terminal.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
'''Attention'''&lt;br /&gt;
*The probe can not be used in water above 55 degrees centigrade.&lt;br /&gt;
*The probe can not be left too close to the edge of the container, otherwise it will affect the reading.&lt;br /&gt;
*The head and the cable of the probe are waterproof, but the connector and the signal transmitter board are not waterproof. Please be careful.&lt;br /&gt;
*When using the TDS instrument sensor, the sensor probe is immersed in liquid, and the purchaser needs to '''Separate''' the sensor '''Probe Protective Cover''' to avoid incorrect data reading and malfunction.&lt;br /&gt;
&lt;br /&gt;
[[image:TDS Meter Sensor-7D.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
*The TDS probe cannot be used in water above 55 degrees Celsius;&lt;br /&gt;
*The TDS probe should not be placed too close to the edge of the container, otherwise it will affect the sensor reading parameters;&lt;br /&gt;
*The TDS probe head and lead are made of waterproof material and can be immersed in water, but the cable interface and signal transfer board are not waterproof, please use them carefully.&lt;br /&gt;
&lt;br /&gt;
'''Arduino Connections'''&lt;br /&gt;
&lt;br /&gt;
*The DuPont female single-head wiring we distribute cannot be directly connected to the UNO R3 control board. Need to be in Stack the sensor expansion board on the UNO R3 control board, or connect the male-to-male Dupont wire to the Dupont female single-head wiring(Bread Wire).&lt;br /&gt;
&lt;br /&gt;
'''Raspberry Pi Test Code'''&lt;br /&gt;
&lt;br /&gt;
*Compatible Raspberry Pi needs to be used with ADS1115 16-bit AD conversion module. Please refer to the specific test code: http://www.cqrobot.wiki/index.php/ADS1115_16-Bit_ADC_Module_SKU:_CQRADS1115&lt;br /&gt;
*Connect the module to the Raspberry Pi 4B, and put the test code in the Raspberry Pi system in the form of a folder. Dial the ADD dial switch to the 0X48 end.&lt;br /&gt;
*In this experiment, the Raspberry Pi I2C communication function is used. You need to turn on the I2C function, enter sudo raspi-config in the Raspberry Pi system, and then perform the following operations.&lt;br /&gt;
*This kit does '''not include''' CQRobot ADS1115 16-bit AD conversion module (Model: CQRADS1115), buyers need to purchase it separately.&lt;br /&gt;
&lt;br /&gt;
[[image:TDS Meter Sensor-7E.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Arduino Application'''==&lt;br /&gt;
&lt;br /&gt;
'''Note''': The DuPont female single-ended wiring we distribute cannot be directly connected to the UNO R3 control board. When wiring, you need to stack the sensor expansion board on the UNO R3 control board, or connect the male-to-male Dupont wire (bread wire) on the Dupont wire female single-ended wire.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-107.jpg|600px]]&lt;br /&gt;
&lt;br /&gt;
'''Download and Run the Test Examples'''&lt;br /&gt;
&lt;br /&gt;
[[Media: TDS Meter Sensor-Arduino.rar]]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define TdsSensorPin A1&lt;br /&gt;
#define VREF 5.0      // analog reference voltage(Volt) of the ADC&lt;br /&gt;
#define SCOUNT  30           // sum of sample point&lt;br /&gt;
int analogBuffer[SCOUNT];    // store the analog value in the array, read from ADC&lt;br /&gt;
int analogBufferTemp[SCOUNT];&lt;br /&gt;
int analogBufferIndex = 0, copyIndex = 0;&lt;br /&gt;
float averageVoltage = 0, tdsValue = 0, temperature = 25;&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  pinMode(TdsSensorPin, INPUT);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  static unsigned long analogSampleTimepoint = millis();&lt;br /&gt;
  if (millis() - analogSampleTimepoint &amp;gt; 40U)  //every 40 milliseconds,read the analog value from the ADC&lt;br /&gt;
  {&lt;br /&gt;
    analogSampleTimepoint = millis();&lt;br /&gt;
    analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin);    //read the analog value and store into the buffer&lt;br /&gt;
    analogBufferIndex++;&lt;br /&gt;
    if (analogBufferIndex == SCOUNT)&lt;br /&gt;
      analogBufferIndex = 0;&lt;br /&gt;
  }&lt;br /&gt;
  static unsigned long printTimepoint = millis();&lt;br /&gt;
  if (millis() - printTimepoint &amp;gt; 800U)&lt;br /&gt;
  {&lt;br /&gt;
    printTimepoint = millis();&lt;br /&gt;
    for (copyIndex = 0; copyIndex &amp;lt; SCOUNT; copyIndex++)&lt;br /&gt;
      analogBufferTemp[copyIndex] = analogBuffer[copyIndex];&lt;br /&gt;
    averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF / 1024.0; // read the analog value more stable by the median filtering algorithm, and convert to voltage value&lt;br /&gt;
    float compensationCoefficient = 1.0 + 0.02 * (temperature - 25.0); //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));&lt;br /&gt;
    float compensationVolatge = averageVoltage / compensationCoefficient; //temperature compensation&lt;br /&gt;
    tdsValue = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5; //convert voltage value to tds value&lt;br /&gt;
    //Serial.print(&amp;quot;voltage:&amp;quot;);&lt;br /&gt;
    //Serial.print(averageVoltage,2);&lt;br /&gt;
    //Serial.print(&amp;quot;V   &amp;quot;);&lt;br /&gt;
    Serial.print(&amp;quot;TDS----Value:&amp;quot;);&lt;br /&gt;
    Serial.print(tdsValue, 0);&lt;br /&gt;
    Serial.println(&amp;quot;ppm&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
int getMedianNum(int bArray[], int iFilterLen)&lt;br /&gt;
{&lt;br /&gt;
  int bTab[iFilterLen];&lt;br /&gt;
  for (byte i = 0; i &amp;lt; iFilterLen; i++)&lt;br /&gt;
    bTab[i] = bArray[i];&lt;br /&gt;
  int i, j, bTemp;&lt;br /&gt;
  for (j = 0; j &amp;lt; iFilterLen - 1; j++)&lt;br /&gt;
  {&lt;br /&gt;
    for (i = 0; i &amp;lt; iFilterLen - j - 1; i++)&lt;br /&gt;
    {&lt;br /&gt;
      if (bTab[i] &amp;gt; bTab[i + 1])&lt;br /&gt;
      {&lt;br /&gt;
        bTemp = bTab[i];&lt;br /&gt;
        bTab[i] = bTab[i + 1];&lt;br /&gt;
        bTab[i + 1] = bTemp;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  if ((iFilterLen &amp;amp; 1) &amp;gt; 0)&lt;br /&gt;
    bTemp = bTab[(iFilterLen - 1) / 2];&lt;br /&gt;
  else&lt;br /&gt;
    bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;&lt;br /&gt;
  return bTemp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Test Results'''&lt;br /&gt;
&lt;br /&gt;
Connect according to the wiring diagram, upload the code on the arduino board, after power-on, open the serial monitor, set the baud rate to 115200, insert the TDS probe into the water to be measured, stir a few times, and observe the value printed on the serial monitor, This value is the TDS value of water. As shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-101.jpg|400px]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''TDS Meter Sensor vs. Xiaomi Water Quality Test Pen'''==&lt;br /&gt;
This is a sample of tap water from the urban pipe network.&lt;br /&gt;
&lt;br /&gt;
TDS value of Xiaomi's test pen: 84 ppm&lt;br /&gt;
&lt;br /&gt;
TDS value of our sensor: 92 ppm&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The test result is only responsible for the sample, but you can serve as a reference.&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|[[File:CQRSENTDS01-X22.jpg |left|300px]]&lt;br /&gt;
|[[File:CQRSENTDS01-X3.jpg |left|300px]]&lt;br /&gt;
|[[File:CQRSENTDS01-X4.jpg |left|300px]]&lt;br /&gt;
|[[File:CQRSENTDS01-X5.jpg |left|300px]]&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Raspberry Pi Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-76.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-73.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
'''Raspberry Pi 4B Pinout Diagram'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-75.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Create a folder and a “.c” file, then write the code.&lt;br /&gt;
&lt;br /&gt;
[[Media: ADS1115.zip]]&lt;br /&gt;
&lt;br /&gt;
*You can directly add to the compressed file.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-781.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
gcc -Wall -g -o ADS1115 ADS1115.c -lm&lt;br /&gt;
&lt;br /&gt;
./ADS1115&lt;br /&gt;
&lt;br /&gt;
Go to the folder created in the terminal, use GCC cross-compilation and run the file.&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/ioctl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;linux/i2c-dev.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define ADS1115_ADDR 0x48&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int fd = open(&amp;quot;/dev/i2c-1&amp;quot;, O_RDWR);&lt;br /&gt;
    if (fd &amp;lt; 0) return 1;&lt;br /&gt;
    if (ioctl(fd, I2C_SLAVE, ADS1115_ADDR) &amp;lt; 0) return 1;&lt;br /&gt;
    &lt;br /&gt;
    while(1) {&lt;br /&gt;
        unsigned char config[3] = {0x01, 0xC2, 0x83};&lt;br /&gt;
        unsigned char result[2];&lt;br /&gt;
        &lt;br /&gt;
        write(fd, config, 3);&lt;br /&gt;
        usleep(8000);&lt;br /&gt;
        &lt;br /&gt;
        unsigned char reg[1] = {0x00};&lt;br /&gt;
        write(fd, reg, 1);&lt;br /&gt;
        read(fd, result, 2);&lt;br /&gt;
        &lt;br /&gt;
        int16_t adc = (result[0] &amp;lt;&amp;lt; 8) | result[1];&lt;br /&gt;
        float voltage = adc * 0.125 / 1000.0;&lt;br /&gt;
        float ntc_r = (3.3 * 10000.0 / voltage) - 20000.0;&lt;br /&gt;
        float temp = 1.0 / (log(ntc_r / 10000.0) / 3950.0 + 1.0 / 298.15) - 273.15;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Temp: %.1fC\n&amp;quot;, temp);&lt;br /&gt;
        sleep(1);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Test Results:&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-791.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the I2C address to 0x48. You can modify this line of code as needed: #define ADS1115_ADDR 0x48.&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the input channel to AIN0. You can replace it with the following code based on actual needs:&lt;br /&gt;
&lt;br /&gt;
AIN0: 0xC2&lt;br /&gt;
&lt;br /&gt;
AIN1: 0xD2&lt;br /&gt;
&lt;br /&gt;
AIN2: 0xE2 &lt;br /&gt;
&lt;br /&gt;
AIN3: 0xF2&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Used in Conjunction with the 4-CH 16-Bit ADS1115 ADC Module (SKU: CQRADC001 / ASIN: B0GF12JQ8R)'''==&lt;br /&gt;
[[image:CQRADC001-7.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
*'''Sample Program'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-80.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Create a folder and a “.c” file, then write the code.&lt;br /&gt;
&lt;br /&gt;
[[Media: ADSTDS.zip]]&lt;br /&gt;
&lt;br /&gt;
*You can directly add to the compressed file.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-811.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
gcc -o ADSTDS ADSTDS.c -lwiringPi&lt;br /&gt;
&lt;br /&gt;
./ADSTDS&lt;br /&gt;
&lt;br /&gt;
Go to the folder created in the terminal, use GCC cross-compilation and run the file.&lt;br /&gt;
&lt;br /&gt;
*'''Example Code'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;wiringPi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;wiringPiI2C.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define VREF 5.0f           &lt;br /&gt;
#define SCOUNT 30           // Sampling points&lt;br /&gt;
#define TEMPERATURE 25.0f   // Water temperature (Celsius)&lt;br /&gt;
&lt;br /&gt;
int analogBuffer[SCOUNT];        &lt;br /&gt;
int analogBufferTemp[SCOUNT];&lt;br /&gt;
int analogBufferIndex = 0;&lt;br /&gt;
float averageVoltage = 0, tdsValue = 0;&lt;br /&gt;
&lt;br /&gt;
int ads1115_fd;&lt;br /&gt;
// Function declarations&lt;br /&gt;
int getMedianNum(int bArray[], int iFilterLen);&lt;br /&gt;
int readADS1115();&lt;br /&gt;
unsigned long my_millis();  &lt;br /&gt;
&lt;br /&gt;
unsigned long my_millis() {&lt;br /&gt;
    struct timespec ts;&lt;br /&gt;
    clock_gettime(CLOCK_MONOTONIC, &amp;amp;ts);&lt;br /&gt;
    return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int getMedianNum(int bArray[], int iFilterLen) {&lt;br /&gt;
    int bTab[iFilterLen];&lt;br /&gt;
    for (int i = 0; i &amp;lt; iFilterLen; i++) {&lt;br /&gt;
        bTab[i] = bArray[i];&lt;br /&gt;
    }&lt;br /&gt;
    int i, j, bTemp;&lt;br /&gt;
    for (j = 0; j &amp;lt; iFilterLen - 1; j++) {&lt;br /&gt;
        for (i = 0; i &amp;lt; iFilterLen - j - 1; i++) {&lt;br /&gt;
            if (bTab[i] &amp;gt; bTab[i + 1]) {&lt;br /&gt;
                bTemp = bTab[i];&lt;br /&gt;
                bTab[i] = bTab[i + 1];&lt;br /&gt;
                bTab[i + 1] = bTemp;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if ((iFilterLen &amp;amp; 1) &amp;gt; 0) {&lt;br /&gt;
        bTemp = bTab[(iFilterLen - 1) / 2];&lt;br /&gt;
    } else {&lt;br /&gt;
        bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;&lt;br /&gt;
    }&lt;br /&gt;
    return bTemp;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int readADS1115() {&lt;br /&gt;
    // Configure ADS1115: Channel 0&lt;br /&gt;
    uint16_t config = 0xC283;  &lt;br /&gt;
    wiringPiI2CWriteReg16(ads1115_fd, 0x01, (config &amp;gt;&amp;gt; 8) | (config &amp;lt;&amp;lt; 8));&lt;br /&gt;
    usleep(8000);  &lt;br /&gt;
    &lt;br /&gt;
    uint16_t result = wiringPiI2CReadReg16(ads1115_fd, 0x00);&lt;br /&gt;
    int16_t adc = ((result &amp;gt;&amp;gt; 8) &amp;amp; 0xFF) | ((result &amp;amp; 0xFF) &amp;lt;&amp;lt; 8);&lt;br /&gt;
    &lt;br /&gt;
 &lt;br /&gt;
    static int debug_count = 0;&lt;br /&gt;
    if (debug_count++ % 20 == 0) {&lt;br /&gt;
        printf(&amp;quot;[Raw ADC: %d] &amp;quot;, adc);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    int adc_abs = abs(adc);&lt;br /&gt;
    // Convert to analog value (0-1023)&lt;br /&gt;
    int arduino_value = (adc_abs * 1024) / 30000;&lt;br /&gt;
    // Limit to 0-1023 range&lt;br /&gt;
    if (arduino_value &amp;gt; 1023) arduino_value = 1023;&lt;br /&gt;
    if (arduino_value &amp;lt; 0) arduino_value = 0;&lt;br /&gt;
    return arduino_value;&lt;br /&gt;
}&lt;br /&gt;
int main() {&lt;br /&gt;
    printf(&amp;quot;=== Raspberry Pi TDS Measurement ===\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;TDS = 133.42*V^3 - 255.86*V^2 + 857.39*V * 0.5\n\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // Initialize wiringPi&lt;br /&gt;
    if (wiringPiSetup() &amp;lt; 0) {&lt;br /&gt;
        printf(&amp;quot;wiringPi initialization failed\n&amp;quot;);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Initialize ADS1115&lt;br /&gt;
    ads1115_fd = wiringPiI2CSetup(0x48);&lt;br /&gt;
    if (ads1115_fd &amp;lt; 0) {&lt;br /&gt;
        printf(&amp;quot;ADS1115 initialization failed (address 0x48)\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Please check: sudo i2cdetect -y 1\n&amp;quot;);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;✓ Hardware initialization completed\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Starting measurement...\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;----------------------------------------\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // Timepoint variables (using custom my_millis)&lt;br /&gt;
    unsigned long analogSampleTimepoint = my_millis();&lt;br /&gt;
    unsigned long printTimepoint = my_millis();&lt;br /&gt;
    &lt;br /&gt;
    while (1) {&lt;br /&gt;
        unsigned long currentMillis = my_millis();     &lt;br /&gt;
        if (currentMillis - analogSampleTimepoint &amp;gt; 40U) {&lt;br /&gt;
            analogSampleTimepoint = currentMillis;&lt;br /&gt;
            &lt;br /&gt;
            int arduinoValue = readADS1115();&lt;br /&gt;
            &lt;br /&gt;
            analogBuffer[analogBufferIndex] = arduinoValue;&lt;br /&gt;
            analogBufferIndex++;&lt;br /&gt;
            if (analogBufferIndex == SCOUNT) {&lt;br /&gt;
                analogBufferIndex = 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
         &lt;br /&gt;
        if (currentMillis - printTimepoint &amp;gt; 800U) {&lt;br /&gt;
            printTimepoint = currentMillis;&lt;br /&gt;
           &lt;br /&gt;
            for (int copyIndex = 0; copyIndex &amp;lt; SCOUNT; copyIndex++) {&lt;br /&gt;
                analogBufferTemp[copyIndex] = analogBuffer[copyIndex];&lt;br /&gt;
            }&lt;br /&gt;
   &lt;br /&gt;
            int medianValue = getMedianNum(analogBufferTemp, SCOUNT);&lt;br /&gt;
            averageVoltage = medianValue * VREF / 1024.0;&lt;br /&gt;
            float compensationCoefficient = 1.0 + 0.02 * (TEMPERATURE - 25.0);&lt;br /&gt;
            float compensationVoltage = averageVoltage / compensationCoefficient;&lt;br /&gt;
            tdsValue = (133.42 * compensationVoltage * compensationVoltage * compensationVoltage &lt;br /&gt;
                       - 255.86 * compensationVoltage * compensationVoltage &lt;br /&gt;
                       + 857.39 * compensationVoltage) * 0.5;&lt;br /&gt;
            printf(&amp;quot;TDS Value: %.0fppm&amp;quot;, tdsValue);&lt;br /&gt;
           &lt;br /&gt;
            printf(&amp;quot; (ADC:%d, Volt:%.3fV)\n&amp;quot;, medianValue, averageVoltage);&lt;br /&gt;
            &lt;br /&gt;
            fflush(stdout);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        usleep(1000);  &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Test Results:&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-821.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
The original ADC value represents the raw 16-bit analog-to-digital conversion data from the ADS1115. The ADC value is the stabilized output after median filtering. The voltage value is the calculated corresponding voltage. The TDS value indicates the dissolved solids content in the water. &lt;br /&gt;
&lt;br /&gt;
In this configuration, the I2C address is 0x48, and the analog port is AIN0.&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=TDS_(Total_Dissolved_Solids)_Meter_Sensor_SKU:_CQRSENTDS01&amp;diff=5010</id>
		<title>TDS (Total Dissolved Solids) Meter Sensor SKU: CQRSENTDS01</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=TDS_(Total_Dissolved_Solids)_Meter_Sensor_SKU:_CQRSENTDS01&amp;diff=5010"/>
				<updated>2026-03-06T06:35:36Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Raspberry Pi Example and Test Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:TDS Meter Sensor-7F.jpg| right |thumb|100px TDS Meter Sensor]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
&lt;br /&gt;
TDS (Total Dissolved Solids), Chinese name Total Dissolved Solids, also known as Total Dissolved Solids, indicates how many milligrams of dissolved solids are dissolved in 1 liter of water. Generally speaking, the higher the TDS value, the more dissolved substances contained in the water and the less clean the water. Therefore, the value of TDS can be used as one of the basis for reflecting the cleanliness of water. The commonly used TDS testing equipment is a TDS pen. Although it is cheap and easy to use, it cannot transmit data to the control system for long-term online monitoring and water quality analysis. Using a special instrument, although it can transmit data and has high accuracy, it is very expensive.&lt;br /&gt;
&lt;br /&gt;
CQRobot has launched an arduino-compatible TDS sensor, which can be used to measure the TDS value of water after connecting to the arduino controller. This product is specially designed for arduino, plug and play, easy to use. 3.3V~5.5V wide voltage power supply, 0 to 2.3V analog signal output, making this product compatible with 5V and 3.3V control systems, it can be easily connected to existing control systems. With CQRobot ADS1115 16-bit AD conversion module (Model: CQRADS1115), it can accurately collect and convert analog signals to meet the compatibility requirements of the Raspberry Pi motherboard.&lt;br /&gt;
&lt;br /&gt;
The excitation source for measurement uses AC signals, which can effectively prevent probe polarization, extend the life of the probe, and increase the stability of the output signal. The TDS probe is a waterproof probe that can be immersed in water for long-term measurement. This product can be applied to water quality testing in areas such as domestic water and hydroponics. With this sensor, you can easily DIY a TDS detector, easily detect the cleanliness of the water, and check your water quality.&lt;br /&gt;
&lt;br /&gt;
[[image:TDS Meter Sensor-7B.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Size Display'''==&lt;br /&gt;
[[image:TDS Meter Sensor-7C1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specifications'''==&lt;br /&gt;
'''Signal Transmitter Board Specifications'''&lt;br /&gt;
*Input Voltage: 3.3V to 5.5V&lt;br /&gt;
*Output Voltage: 0 to 2.3V&lt;br /&gt;
*Working Current: 3mA to 6mA&lt;br /&gt;
*TDS Measurement Range: 0 to 1000ppm&lt;br /&gt;
*TDS Measurement Accuracy: Plus/Minus 10% F.S. (25 Degree Celsius)&lt;br /&gt;
*Module Size: 43mm * 32.2mm&lt;br /&gt;
*Module Interface: JST 2.0mm 3-Pin&lt;br /&gt;
*Electrode Interface: JST 2.54mm 2-Pin&lt;br /&gt;
'''TDS Probe Specifications'''&lt;br /&gt;
*Number of Needle: 2&lt;br /&gt;
*Total Length: 60cm&lt;br /&gt;
*Connection Interface: JTS 2.54mm 2-Pin&lt;br /&gt;
*Color: Black&lt;br /&gt;
*Other: Waterproof Probe&lt;br /&gt;
'''Ocean Interface Cable Specifications'''&lt;br /&gt;
*Cable specifications: 22AWG&lt;br /&gt;
*Material: Silicone&lt;br /&gt;
*Withstand Voltage: Less Than 50V&lt;br /&gt;
*Withstand Current: Less Than 1000MA&lt;br /&gt;
*Length: 21cm&lt;br /&gt;
*Line Sequence: Black-Negative Power Supply, Red-Positive Power Supply, Green-Signal Terminal.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
'''Attention'''&lt;br /&gt;
*The probe can not be used in water above 55 degrees centigrade.&lt;br /&gt;
*The probe can not be left too close to the edge of the container, otherwise it will affect the reading.&lt;br /&gt;
*The head and the cable of the probe are waterproof, but the connector and the signal transmitter board are not waterproof. Please be careful.&lt;br /&gt;
*When using the TDS instrument sensor, the sensor probe is immersed in liquid, and the purchaser needs to '''Separate''' the sensor '''Probe Protective Cover''' to avoid incorrect data reading and malfunction.&lt;br /&gt;
&lt;br /&gt;
[[image:TDS Meter Sensor-7D.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
*The TDS probe cannot be used in water above 55 degrees Celsius;&lt;br /&gt;
*The TDS probe should not be placed too close to the edge of the container, otherwise it will affect the sensor reading parameters;&lt;br /&gt;
*The TDS probe head and lead are made of waterproof material and can be immersed in water, but the cable interface and signal transfer board are not waterproof, please use them carefully.&lt;br /&gt;
&lt;br /&gt;
'''Arduino Connections'''&lt;br /&gt;
&lt;br /&gt;
*The DuPont female single-head wiring we distribute cannot be directly connected to the UNO R3 control board. Need to be in Stack the sensor expansion board on the UNO R3 control board, or connect the male-to-male Dupont wire to the Dupont female single-head wiring(Bread Wire).&lt;br /&gt;
&lt;br /&gt;
'''Raspberry Pi Test Code'''&lt;br /&gt;
&lt;br /&gt;
*Compatible Raspberry Pi needs to be used with ADS1115 16-bit AD conversion module. Please refer to the specific test code: http://www.cqrobot.wiki/index.php/ADS1115_16-Bit_ADC_Module_SKU:_CQRADS1115&lt;br /&gt;
*Connect the module to the Raspberry Pi 4B, and put the test code in the Raspberry Pi system in the form of a folder. Dial the ADD dial switch to the 0X48 end.&lt;br /&gt;
*In this experiment, the Raspberry Pi I2C communication function is used. You need to turn on the I2C function, enter sudo raspi-config in the Raspberry Pi system, and then perform the following operations.&lt;br /&gt;
*This kit does '''not include''' CQRobot ADS1115 16-bit AD conversion module (Model: CQRADS1115), buyers need to purchase it separately.&lt;br /&gt;
&lt;br /&gt;
[[image:TDS Meter Sensor-7E.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Arduino Application'''==&lt;br /&gt;
&lt;br /&gt;
'''Note''': The DuPont female single-ended wiring we distribute cannot be directly connected to the UNO R3 control board. When wiring, you need to stack the sensor expansion board on the UNO R3 control board, or connect the male-to-male Dupont wire (bread wire) on the Dupont wire female single-ended wire.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-107.jpg|600px]]&lt;br /&gt;
&lt;br /&gt;
'''Download and Run the Test Examples'''&lt;br /&gt;
&lt;br /&gt;
[[Media: TDS Meter Sensor-Arduino.rar]]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define TdsSensorPin A1&lt;br /&gt;
#define VREF 5.0      // analog reference voltage(Volt) of the ADC&lt;br /&gt;
#define SCOUNT  30           // sum of sample point&lt;br /&gt;
int analogBuffer[SCOUNT];    // store the analog value in the array, read from ADC&lt;br /&gt;
int analogBufferTemp[SCOUNT];&lt;br /&gt;
int analogBufferIndex = 0, copyIndex = 0;&lt;br /&gt;
float averageVoltage = 0, tdsValue = 0, temperature = 25;&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  pinMode(TdsSensorPin, INPUT);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  static unsigned long analogSampleTimepoint = millis();&lt;br /&gt;
  if (millis() - analogSampleTimepoint &amp;gt; 40U)  //every 40 milliseconds,read the analog value from the ADC&lt;br /&gt;
  {&lt;br /&gt;
    analogSampleTimepoint = millis();&lt;br /&gt;
    analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin);    //read the analog value and store into the buffer&lt;br /&gt;
    analogBufferIndex++;&lt;br /&gt;
    if (analogBufferIndex == SCOUNT)&lt;br /&gt;
      analogBufferIndex = 0;&lt;br /&gt;
  }&lt;br /&gt;
  static unsigned long printTimepoint = millis();&lt;br /&gt;
  if (millis() - printTimepoint &amp;gt; 800U)&lt;br /&gt;
  {&lt;br /&gt;
    printTimepoint = millis();&lt;br /&gt;
    for (copyIndex = 0; copyIndex &amp;lt; SCOUNT; copyIndex++)&lt;br /&gt;
      analogBufferTemp[copyIndex] = analogBuffer[copyIndex];&lt;br /&gt;
    averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF / 1024.0; // read the analog value more stable by the median filtering algorithm, and convert to voltage value&lt;br /&gt;
    float compensationCoefficient = 1.0 + 0.02 * (temperature - 25.0); //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));&lt;br /&gt;
    float compensationVolatge = averageVoltage / compensationCoefficient; //temperature compensation&lt;br /&gt;
    tdsValue = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5; //convert voltage value to tds value&lt;br /&gt;
    //Serial.print(&amp;quot;voltage:&amp;quot;);&lt;br /&gt;
    //Serial.print(averageVoltage,2);&lt;br /&gt;
    //Serial.print(&amp;quot;V   &amp;quot;);&lt;br /&gt;
    Serial.print(&amp;quot;TDS----Value:&amp;quot;);&lt;br /&gt;
    Serial.print(tdsValue, 0);&lt;br /&gt;
    Serial.println(&amp;quot;ppm&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
int getMedianNum(int bArray[], int iFilterLen)&lt;br /&gt;
{&lt;br /&gt;
  int bTab[iFilterLen];&lt;br /&gt;
  for (byte i = 0; i &amp;lt; iFilterLen; i++)&lt;br /&gt;
    bTab[i] = bArray[i];&lt;br /&gt;
  int i, j, bTemp;&lt;br /&gt;
  for (j = 0; j &amp;lt; iFilterLen - 1; j++)&lt;br /&gt;
  {&lt;br /&gt;
    for (i = 0; i &amp;lt; iFilterLen - j - 1; i++)&lt;br /&gt;
    {&lt;br /&gt;
      if (bTab[i] &amp;gt; bTab[i + 1])&lt;br /&gt;
      {&lt;br /&gt;
        bTemp = bTab[i];&lt;br /&gt;
        bTab[i] = bTab[i + 1];&lt;br /&gt;
        bTab[i + 1] = bTemp;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  if ((iFilterLen &amp;amp; 1) &amp;gt; 0)&lt;br /&gt;
    bTemp = bTab[(iFilterLen - 1) / 2];&lt;br /&gt;
  else&lt;br /&gt;
    bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;&lt;br /&gt;
  return bTemp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Test Results'''&lt;br /&gt;
&lt;br /&gt;
Connect according to the wiring diagram, upload the code on the arduino board, after power-on, open the serial monitor, set the baud rate to 115200, insert the TDS probe into the water to be measured, stir a few times, and observe the value printed on the serial monitor, This value is the TDS value of water. As shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-101.jpg|400px]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''TDS Meter Sensor vs. Xiaomi Water Quality Test Pen'''==&lt;br /&gt;
This is a sample of tap water from the urban pipe network.&lt;br /&gt;
&lt;br /&gt;
TDS value of Xiaomi's test pen: 84 ppm&lt;br /&gt;
&lt;br /&gt;
TDS value of our sensor: 92 ppm&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The test result is only responsible for the sample, but you can serve as a reference.&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|[[File:CQRSENTDS01-X22.jpg |left|300px]]&lt;br /&gt;
|[[File:CQRSENTDS01-X3.jpg |left|300px]]&lt;br /&gt;
|[[File:CQRSENTDS01-X4.jpg |left|300px]]&lt;br /&gt;
|[[File:CQRSENTDS01-X5.jpg |left|300px]]&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Raspberry Pi Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-76.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-73.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
'''Raspberry Pi 4B Pinout Diagram'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-75.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Create a folder and a “.c” file, then write the code.&lt;br /&gt;
&lt;br /&gt;
[[Media: ADS1115.zip]]&lt;br /&gt;
&lt;br /&gt;
*You can directly add to the compressed file.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-781.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
gcc -Wall -g -o ADS1115 ADS1115.c -lm&lt;br /&gt;
&lt;br /&gt;
./ADS1115&lt;br /&gt;
&lt;br /&gt;
Go to the folder created in the terminal, use GCC cross-compilation and run the file.&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/ioctl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;linux/i2c-dev.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define ADS1115_ADDR 0x48&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int fd = open(&amp;quot;/dev/i2c-1&amp;quot;, O_RDWR);&lt;br /&gt;
    if (fd &amp;lt; 0) return 1;&lt;br /&gt;
    if (ioctl(fd, I2C_SLAVE, ADS1115_ADDR) &amp;lt; 0) return 1;&lt;br /&gt;
    &lt;br /&gt;
    while(1) {&lt;br /&gt;
        unsigned char config[3] = {0x01, 0xC2, 0x83};&lt;br /&gt;
        unsigned char result[2];&lt;br /&gt;
        &lt;br /&gt;
        write(fd, config, 3);&lt;br /&gt;
        usleep(8000);&lt;br /&gt;
        &lt;br /&gt;
        unsigned char reg[1] = {0x00};&lt;br /&gt;
        write(fd, reg, 1);&lt;br /&gt;
        read(fd, result, 2);&lt;br /&gt;
        &lt;br /&gt;
        int16_t adc = (result[0] &amp;lt;&amp;lt; 8) | result[1];&lt;br /&gt;
        float voltage = adc * 0.125 / 1000.0;&lt;br /&gt;
        float ntc_r = (3.3 * 10000.0 / voltage) - 20000.0;&lt;br /&gt;
        float temp = 1.0 / (log(ntc_r / 10000.0) / 3950.0 + 1.0 / 298.15) - 273.15;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Temp: %.1fC\n&amp;quot;, temp);&lt;br /&gt;
        sleep(1);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Test Results:&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-791.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the I2C address to 0x48. You can modify this line of code as needed: #define ADS1115_ADDR 0x48.&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the input channel to AIN0. You can replace it with the following code based on actual needs:&lt;br /&gt;
&lt;br /&gt;
AIN0: 0xC2&lt;br /&gt;
&lt;br /&gt;
AIN1: 0xD2&lt;br /&gt;
&lt;br /&gt;
AIN2: 0xE2 &lt;br /&gt;
&lt;br /&gt;
AIN3: 0xF2&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Raspberry Pi Application'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-108.jpg|600px]]&lt;br /&gt;
&lt;br /&gt;
'''Download and Run the Test Examples'''&lt;br /&gt;
&lt;br /&gt;
[[Media: TDS Meter Sensor-Raspberry Pi-New.zip]]&lt;br /&gt;
&lt;br /&gt;
*1. Connect the module to the Raspberry Pi 4B, and put the test code on the Raspberry Pi system in the form of a folder. Dial the ADD DIP switch to the 0X48 end.&lt;br /&gt;
&lt;br /&gt;
*2. The Raspberry Pi I2C communication function is used in this experiment. It is necessary to turn on the I2C function, enter sudo raspi-config in the Raspberry Pi system, and then perform the following operations.&lt;br /&gt;
&lt;br /&gt;
*3. '''Note''': When wiring, connect to A1 according to the tutorial.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-102.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-103.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-104.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-105.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-106.jpg|500px]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
File: '''ADS1115_Read Voltage.py'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
sys.path.append('../')&lt;br /&gt;
import time&lt;br /&gt;
from CQRobot_ADS1115 import ADS1115&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_6_144V        = 0x00 # 6.144V range = Gain 2/3&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_4_096V        = 0x02 # 4.096V range = Gain 1&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_2_048V        = 0x04 # 2.048V range = Gain 2 (default)&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_1_024V        = 0x06 # 1.024V range = Gain 4&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_0_512V        = 0x08 # 0.512V range = Gain 8&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_0_256V        = 0x0A # 0.256V range = Gain 16&lt;br /&gt;
ads1115 = ADS1115()&lt;br /&gt;
#Set the IIC address&lt;br /&gt;
ads1115.setAddr_ADS1115(0x48)&lt;br /&gt;
#Sets the gain and input voltage range.&lt;br /&gt;
ads1115.setGain(ADS1115_REG_CONFIG_PGA_6_144V)&lt;br /&gt;
&lt;br /&gt;
VREF = 5.0&lt;br /&gt;
analogBuffer = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]&lt;br /&gt;
analogBufferTemp = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]&lt;br /&gt;
analogBufferIndex = 0&lt;br /&gt;
copyIndex = 0&lt;br /&gt;
averageVoltage = 0&lt;br /&gt;
tdsValue = 0&lt;br /&gt;
temperature = 25&lt;br /&gt;
&lt;br /&gt;
def getMedianNum(iFilterLen):&lt;br /&gt;
	global analogBufferTemp&lt;br /&gt;
	bTemp = 0.0&lt;br /&gt;
	for j in range(iFilterLen-1):&lt;br /&gt;
		for i in range(iFilterLen-j-1):&lt;br /&gt;
			if analogBufferTemp[i] &amp;gt; analogBufferTemp[i+1]:&lt;br /&gt;
				bTemp = analogBufferTemp[i]&lt;br /&gt;
				analogBufferTemp[i] = analogBufferTemp[i+1]&lt;br /&gt;
				analogBufferTemp[i+1] = bTemp&lt;br /&gt;
	if iFilterLen &amp;amp; 1 &amp;gt; 0:&lt;br /&gt;
		bTemp = analogBufferTemp[(iFilterLen - 1)/2]&lt;br /&gt;
	else:&lt;br /&gt;
		bTemp = (analogBufferTemp[iFilterLen // 2] + analogBufferTemp[iFilterLen // 2 - 1]) / 2&lt;br /&gt;
	return float(bTemp)&lt;br /&gt;
&lt;br /&gt;
analogSampleTimepoint = time.time()&lt;br /&gt;
printTimepoint = time.time()&lt;br /&gt;
while True :&lt;br /&gt;
	if time.time() - analogSampleTimepoint &amp;gt; 0.04:&lt;br /&gt;
		#print(&amp;quot; test.......... &amp;quot;)&lt;br /&gt;
		analogSampleTimepoint = time.time()&lt;br /&gt;
		analogBuffer[analogBufferIndex] = ads1115.readVoltage(1)['r']&lt;br /&gt;
		analogBufferIndex = analogBufferIndex + 1&lt;br /&gt;
		if analogBufferIndex == 30:&lt;br /&gt;
			analogBufferIndex = 0&lt;br /&gt;
&lt;br /&gt;
	if time.time()-printTimepoint &amp;gt; 0.8:&lt;br /&gt;
		#print(&amp;quot; test &amp;quot;)&lt;br /&gt;
		printTimepoint = time.time()&lt;br /&gt;
		for copyIndex in range(30):&lt;br /&gt;
			analogBufferTemp[copyIndex] = ads1115.readVoltage(1)['r']&lt;br /&gt;
		print(&amp;quot; A1:%dmV &amp;quot;%getMedianNum(30))&lt;br /&gt;
		averageVoltage = getMedianNum(30) * (VREF / 1024.0)&lt;br /&gt;
		compensationCoefficient = 1.0 + 0.02 * (temperature - 25.0)&lt;br /&gt;
		compensationVolatge = averageVoltage / compensationCoefficient&lt;br /&gt;
		tdsValue = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5&lt;br /&gt;
		print(&amp;quot; A1:%dppm &amp;quot;%tdsValue)&lt;br /&gt;
&lt;br /&gt;
	#Get the Digital Value of Analog of selected channel&lt;br /&gt;
	#adc1 = ads1115.readVoltage(1)&lt;br /&gt;
	#time.sleep(0.2)&lt;br /&gt;
	#print(&amp;quot; A1:%dmV &amp;quot;%(adc1['r']))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
File: '''CQRobot_ADS1115.py'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import smbus&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
# Get I2C bus&lt;br /&gt;
bus = smbus.SMBus(1)&lt;br /&gt;
&lt;br /&gt;
# I2C address of the device&lt;br /&gt;
ADS1115_IIC_ADDRESS0				= 0x48&lt;br /&gt;
ADS1115_IIC_ADDRESS1				= 0x49&lt;br /&gt;
&lt;br /&gt;
# ADS1115 Register Map&lt;br /&gt;
ADS1115_REG_POINTER_CONVERT			= 0x00 # Conversion register&lt;br /&gt;
ADS1115_REG_POINTER_CONFIG			= 0x01 # Configuration register&lt;br /&gt;
ADS1115_REG_POINTER_LOWTHRESH		= 0x02 # Lo_thresh register&lt;br /&gt;
ADS1115_REG_POINTER_HITHRESH		= 0x03 # Hi_thresh register&lt;br /&gt;
&lt;br /&gt;
# ADS1115 Configuration Register&lt;br /&gt;
ADS1115_REG_CONFIG_OS_NOEFFECT		= 0x00 # No effect&lt;br /&gt;
ADS1115_REG_CONFIG_OS_SINGLE		= 0x80 # Begin a single conversion&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_DIFF_0_1		= 0x00 # Differential P = AIN0, N = AIN1 (default)&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_DIFF_0_3		= 0x10 # Differential P = AIN0, N = AIN3&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_DIFF_1_3		= 0x20 # Differential P = AIN1, N = AIN3&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_DIFF_2_3		= 0x30 # Differential P = AIN2, N = AIN3&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_SINGLE_0		= 0x40 # Single-ended P = AIN0, N = GND&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_SINGLE_1		= 0x50 # Single-ended P = AIN1, N = GND&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_SINGLE_2		= 0x60 # Single-ended P = AIN2, N = GND&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_SINGLE_3		= 0x70 # Single-ended P = AIN3, N = GND&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_6_144V		= 0x00 # +/-6.144V range = Gain 2/3&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_4_096V		= 0x02 # +/-4.096V range = Gain 1&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_2_048V		= 0x04 # +/-2.048V range = Gain 2 (default)&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_1_024V		= 0x06 # +/-1.024V range = Gain 4&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_0_512V		= 0x08 # +/-0.512V range = Gain 8&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_0_256V		= 0x0A # +/-0.256V range = Gain 16&lt;br /&gt;
ADS1115_REG_CONFIG_MODE_CONTIN		= 0x00 # Continuous conversion mode&lt;br /&gt;
ADS1115_REG_CONFIG_MODE_SINGLE		= 0x01 # Power-down single-shot mode (default)&lt;br /&gt;
ADS1115_REG_CONFIG_DR_8SPS			= 0x00 # 8 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_DR_16SPS			= 0x20 # 16 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_DR_32SPS			= 0x40 # 32 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_DR_64SPS			= 0x60 # 64 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_DR_128SPS		= 0x80 # 128 samples per second (default)&lt;br /&gt;
ADS1115_REG_CONFIG_DR_250SPS		= 0xA0 # 250 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_DR_475SPS		= 0xC0 # 475 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_DR_860SPS		= 0xE0 # 860 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_CMODE_TRAD		= 0x00 # Traditional comparator with hysteresis (default)&lt;br /&gt;
ADS1115_REG_CONFIG_CMODE_WINDOW		= 0x10 # Window comparator&lt;br /&gt;
ADS1115_REG_CONFIG_CPOL_ACTVLOW		= 0x00 # ALERT/RDY pin is low when active (default)&lt;br /&gt;
ADS1115_REG_CONFIG_CPOL_ACTVHI		= 0x08 # ALERT/RDY pin is high when active&lt;br /&gt;
ADS1115_REG_CONFIG_CLAT_NONLAT		= 0x00 # Non-latching comparator (default)&lt;br /&gt;
ADS1115_REG_CONFIG_CLAT_LATCH		= 0x04 # Latching comparator&lt;br /&gt;
ADS1115_REG_CONFIG_CQUE_1CONV		= 0x00 # Assert ALERT/RDY after one conversions&lt;br /&gt;
ADS1115_REG_CONFIG_CQUE_2CONV		= 0x01 # Assert ALERT/RDY after two conversions&lt;br /&gt;
ADS1115_REG_CONFIG_CQUE_4CONV		= 0x02 # Assert ALERT/RDY after four conversions&lt;br /&gt;
ADS1115_REG_CONFIG_CQUE_NONE		= 0x03 # Disable the comparator and put ALERT/RDY in high state (default)&lt;br /&gt;
&lt;br /&gt;
mygain=0x02&lt;br /&gt;
coefficient=0.125&lt;br /&gt;
addr_G=ADS1115_IIC_ADDRESS0&lt;br /&gt;
class ADS1115():&lt;br /&gt;
	def setGain(self,gain):&lt;br /&gt;
		global mygain&lt;br /&gt;
		global coefficient&lt;br /&gt;
		mygain=gain&lt;br /&gt;
		if mygain == ADS1115_REG_CONFIG_PGA_6_144V:&lt;br /&gt;
			coefficient = 0.1875&lt;br /&gt;
		elif mygain == ADS1115_REG_CONFIG_PGA_4_096V:&lt;br /&gt;
			coefficient = 0.125&lt;br /&gt;
		elif mygain == ADS1115_REG_CONFIG_PGA_2_048V:&lt;br /&gt;
			coefficient = 0.0625&lt;br /&gt;
		elif mygain == ADS1115_REG_CONFIG_PGA_1_024V:&lt;br /&gt;
			coefficient = 0.03125&lt;br /&gt;
		elif mygain == ADS1115_REG_CONFIG_PGA_0_512V:&lt;br /&gt;
			coefficient = 0.015625&lt;br /&gt;
		elif  mygain == ADS1115_REG_CONFIG_PGA_0_256V:&lt;br /&gt;
			coefficient = 0.0078125&lt;br /&gt;
		else:&lt;br /&gt;
			coefficient = 0.125&lt;br /&gt;
	def setAddr_ADS1115(self,addr):&lt;br /&gt;
		global addr_G&lt;br /&gt;
		addr_G=addr&lt;br /&gt;
	def setChannel(self,channel):&lt;br /&gt;
		global mygain&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;Select the Channel user want to use from 0-3&lt;br /&gt;
		For Single-ended Output&lt;br /&gt;
		0 : AINP = AIN0 and AINN = GND&lt;br /&gt;
		1 : AINP = AIN1 and AINN = GND&lt;br /&gt;
		2 : AINP = AIN2 and AINN = GND&lt;br /&gt;
		3 : AINP = AIN3 and AINN = GND&lt;br /&gt;
		For Differential Output&lt;br /&gt;
		0 : AINP = AIN0 and AINN = AIN1&lt;br /&gt;
		1 : AINP = AIN0 and AINN = AIN3&lt;br /&gt;
		2 : AINP = AIN1 and AINN = AIN3&lt;br /&gt;
		3 : AINP = AIN2 and AINN = AIN3&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		self.channel = channel&lt;br /&gt;
		while self.channel &amp;gt; 3 :&lt;br /&gt;
			self.channel = 0&lt;br /&gt;
		&lt;br /&gt;
		return self.channel&lt;br /&gt;
	&lt;br /&gt;
	def setSingle(self):&lt;br /&gt;
		global addr_G&lt;br /&gt;
		if self.channel == 0:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_SINGLE_0 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		elif self.channel == 1:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_SINGLE_1 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		elif self.channel == 2:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_SINGLE_2 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		elif self.channel == 3:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_SINGLE_3 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		&lt;br /&gt;
		bus.write_i2c_block_data(addr_G, ADS1115_REG_POINTER_CONFIG, CONFIG_REG)&lt;br /&gt;
	&lt;br /&gt;
	def setDifferential(self):&lt;br /&gt;
		global addr_G&lt;br /&gt;
		if self.channel == 0:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_DIFF_0_1 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		elif self.channel == 1:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_DIFF_0_3 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		elif self.channel == 2:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_DIFF_1_3 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		elif self.channel == 3:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_DIFF_2_3 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		&lt;br /&gt;
		bus.write_i2c_block_data(addr_G, ADS1115_REG_POINTER_CONFIG, CONFIG_REG)&lt;br /&gt;
	&lt;br /&gt;
	def readValue(self):&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;Read data back from ADS1115_REG_POINTER_CONVERT(0x00), 2 bytes&lt;br /&gt;
		raw_adc MSB, raw_adc LSB&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		global coefficient&lt;br /&gt;
		global addr_G&lt;br /&gt;
		data = bus.read_i2c_block_data(addr_G, ADS1115_REG_POINTER_CONVERT, 2)&lt;br /&gt;
		&lt;br /&gt;
		# Convert the data&lt;br /&gt;
		raw_adc = data[0] * 256 + data[1]&lt;br /&gt;
		&lt;br /&gt;
		if raw_adc &amp;gt; 32767:&lt;br /&gt;
			raw_adc -= 65535&lt;br /&gt;
		raw_adc = int(float(raw_adc)*coefficient)&lt;br /&gt;
		return {'r' : raw_adc}&lt;br /&gt;
&lt;br /&gt;
	def readVoltage(self,channel):&lt;br /&gt;
		self.setChannel(channel)&lt;br /&gt;
		self.setSingle()&lt;br /&gt;
		time.sleep(0.1)&lt;br /&gt;
		return self.readValue()&lt;br /&gt;
&lt;br /&gt;
	def ComparatorVoltage(self,channel):&lt;br /&gt;
		self.setChannel(channel)&lt;br /&gt;
		self.setDifferential()&lt;br /&gt;
		time.sleep(0.1)&lt;br /&gt;
		return self.readValue()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''Run the code'''&lt;br /&gt;
&lt;br /&gt;
Note: Make sure that the I2C address from its default (0x48);&lt;br /&gt;
&lt;br /&gt;
Note: Enable &amp;quot;Interfacing Options - P5 I2C&amp;quot; by typing the below command in the terminal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo raspi-config&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run the code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd TS1728&lt;br /&gt;
ls&lt;br /&gt;
sudo python3 CQRobot_ADS1115.py&lt;br /&gt;
cd ADS1115_ReadVoltage&lt;br /&gt;
ls&lt;br /&gt;
sudo python3 ADS1115_ReadVoltage.py&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:TDS Meter Sensor-Raspberry Pi-Run the code.jpg]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''Run the Video'''&lt;br /&gt;
&lt;br /&gt;
[[Media: TDS Meter Sensor-Raspberry Pi-Run the video.mp4]]&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=TDS_(Total_Dissolved_Solids)_Meter_Sensor_SKU:_CQRSENTDS01&amp;diff=5009</id>
		<title>TDS (Total Dissolved Solids) Meter Sensor SKU: CQRSENTDS01</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=TDS_(Total_Dissolved_Solids)_Meter_Sensor_SKU:_CQRSENTDS01&amp;diff=5009"/>
				<updated>2026-03-06T06:35:14Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* TDS Meter Sensor vs. Xiaomi Water Quality Test Pen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:TDS Meter Sensor-7F.jpg| right |thumb|100px TDS Meter Sensor]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
&lt;br /&gt;
TDS (Total Dissolved Solids), Chinese name Total Dissolved Solids, also known as Total Dissolved Solids, indicates how many milligrams of dissolved solids are dissolved in 1 liter of water. Generally speaking, the higher the TDS value, the more dissolved substances contained in the water and the less clean the water. Therefore, the value of TDS can be used as one of the basis for reflecting the cleanliness of water. The commonly used TDS testing equipment is a TDS pen. Although it is cheap and easy to use, it cannot transmit data to the control system for long-term online monitoring and water quality analysis. Using a special instrument, although it can transmit data and has high accuracy, it is very expensive.&lt;br /&gt;
&lt;br /&gt;
CQRobot has launched an arduino-compatible TDS sensor, which can be used to measure the TDS value of water after connecting to the arduino controller. This product is specially designed for arduino, plug and play, easy to use. 3.3V~5.5V wide voltage power supply, 0 to 2.3V analog signal output, making this product compatible with 5V and 3.3V control systems, it can be easily connected to existing control systems. With CQRobot ADS1115 16-bit AD conversion module (Model: CQRADS1115), it can accurately collect and convert analog signals to meet the compatibility requirements of the Raspberry Pi motherboard.&lt;br /&gt;
&lt;br /&gt;
The excitation source for measurement uses AC signals, which can effectively prevent probe polarization, extend the life of the probe, and increase the stability of the output signal. The TDS probe is a waterproof probe that can be immersed in water for long-term measurement. This product can be applied to water quality testing in areas such as domestic water and hydroponics. With this sensor, you can easily DIY a TDS detector, easily detect the cleanliness of the water, and check your water quality.&lt;br /&gt;
&lt;br /&gt;
[[image:TDS Meter Sensor-7B.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Size Display'''==&lt;br /&gt;
[[image:TDS Meter Sensor-7C1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specifications'''==&lt;br /&gt;
'''Signal Transmitter Board Specifications'''&lt;br /&gt;
*Input Voltage: 3.3V to 5.5V&lt;br /&gt;
*Output Voltage: 0 to 2.3V&lt;br /&gt;
*Working Current: 3mA to 6mA&lt;br /&gt;
*TDS Measurement Range: 0 to 1000ppm&lt;br /&gt;
*TDS Measurement Accuracy: Plus/Minus 10% F.S. (25 Degree Celsius)&lt;br /&gt;
*Module Size: 43mm * 32.2mm&lt;br /&gt;
*Module Interface: JST 2.0mm 3-Pin&lt;br /&gt;
*Electrode Interface: JST 2.54mm 2-Pin&lt;br /&gt;
'''TDS Probe Specifications'''&lt;br /&gt;
*Number of Needle: 2&lt;br /&gt;
*Total Length: 60cm&lt;br /&gt;
*Connection Interface: JTS 2.54mm 2-Pin&lt;br /&gt;
*Color: Black&lt;br /&gt;
*Other: Waterproof Probe&lt;br /&gt;
'''Ocean Interface Cable Specifications'''&lt;br /&gt;
*Cable specifications: 22AWG&lt;br /&gt;
*Material: Silicone&lt;br /&gt;
*Withstand Voltage: Less Than 50V&lt;br /&gt;
*Withstand Current: Less Than 1000MA&lt;br /&gt;
*Length: 21cm&lt;br /&gt;
*Line Sequence: Black-Negative Power Supply, Red-Positive Power Supply, Green-Signal Terminal.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
'''Attention'''&lt;br /&gt;
*The probe can not be used in water above 55 degrees centigrade.&lt;br /&gt;
*The probe can not be left too close to the edge of the container, otherwise it will affect the reading.&lt;br /&gt;
*The head and the cable of the probe are waterproof, but the connector and the signal transmitter board are not waterproof. Please be careful.&lt;br /&gt;
*When using the TDS instrument sensor, the sensor probe is immersed in liquid, and the purchaser needs to '''Separate''' the sensor '''Probe Protective Cover''' to avoid incorrect data reading and malfunction.&lt;br /&gt;
&lt;br /&gt;
[[image:TDS Meter Sensor-7D.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
*The TDS probe cannot be used in water above 55 degrees Celsius;&lt;br /&gt;
*The TDS probe should not be placed too close to the edge of the container, otherwise it will affect the sensor reading parameters;&lt;br /&gt;
*The TDS probe head and lead are made of waterproof material and can be immersed in water, but the cable interface and signal transfer board are not waterproof, please use them carefully.&lt;br /&gt;
&lt;br /&gt;
'''Arduino Connections'''&lt;br /&gt;
&lt;br /&gt;
*The DuPont female single-head wiring we distribute cannot be directly connected to the UNO R3 control board. Need to be in Stack the sensor expansion board on the UNO R3 control board, or connect the male-to-male Dupont wire to the Dupont female single-head wiring(Bread Wire).&lt;br /&gt;
&lt;br /&gt;
'''Raspberry Pi Test Code'''&lt;br /&gt;
&lt;br /&gt;
*Compatible Raspberry Pi needs to be used with ADS1115 16-bit AD conversion module. Please refer to the specific test code: http://www.cqrobot.wiki/index.php/ADS1115_16-Bit_ADC_Module_SKU:_CQRADS1115&lt;br /&gt;
*Connect the module to the Raspberry Pi 4B, and put the test code in the Raspberry Pi system in the form of a folder. Dial the ADD dial switch to the 0X48 end.&lt;br /&gt;
*In this experiment, the Raspberry Pi I2C communication function is used. You need to turn on the I2C function, enter sudo raspi-config in the Raspberry Pi system, and then perform the following operations.&lt;br /&gt;
*This kit does '''not include''' CQRobot ADS1115 16-bit AD conversion module (Model: CQRADS1115), buyers need to purchase it separately.&lt;br /&gt;
&lt;br /&gt;
[[image:TDS Meter Sensor-7E.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Arduino Application'''==&lt;br /&gt;
&lt;br /&gt;
'''Note''': The DuPont female single-ended wiring we distribute cannot be directly connected to the UNO R3 control board. When wiring, you need to stack the sensor expansion board on the UNO R3 control board, or connect the male-to-male Dupont wire (bread wire) on the Dupont wire female single-ended wire.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-107.jpg|600px]]&lt;br /&gt;
&lt;br /&gt;
'''Download and Run the Test Examples'''&lt;br /&gt;
&lt;br /&gt;
[[Media: TDS Meter Sensor-Arduino.rar]]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define TdsSensorPin A1&lt;br /&gt;
#define VREF 5.0      // analog reference voltage(Volt) of the ADC&lt;br /&gt;
#define SCOUNT  30           // sum of sample point&lt;br /&gt;
int analogBuffer[SCOUNT];    // store the analog value in the array, read from ADC&lt;br /&gt;
int analogBufferTemp[SCOUNT];&lt;br /&gt;
int analogBufferIndex = 0, copyIndex = 0;&lt;br /&gt;
float averageVoltage = 0, tdsValue = 0, temperature = 25;&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  pinMode(TdsSensorPin, INPUT);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  static unsigned long analogSampleTimepoint = millis();&lt;br /&gt;
  if (millis() - analogSampleTimepoint &amp;gt; 40U)  //every 40 milliseconds,read the analog value from the ADC&lt;br /&gt;
  {&lt;br /&gt;
    analogSampleTimepoint = millis();&lt;br /&gt;
    analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin);    //read the analog value and store into the buffer&lt;br /&gt;
    analogBufferIndex++;&lt;br /&gt;
    if (analogBufferIndex == SCOUNT)&lt;br /&gt;
      analogBufferIndex = 0;&lt;br /&gt;
  }&lt;br /&gt;
  static unsigned long printTimepoint = millis();&lt;br /&gt;
  if (millis() - printTimepoint &amp;gt; 800U)&lt;br /&gt;
  {&lt;br /&gt;
    printTimepoint = millis();&lt;br /&gt;
    for (copyIndex = 0; copyIndex &amp;lt; SCOUNT; copyIndex++)&lt;br /&gt;
      analogBufferTemp[copyIndex] = analogBuffer[copyIndex];&lt;br /&gt;
    averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF / 1024.0; // read the analog value more stable by the median filtering algorithm, and convert to voltage value&lt;br /&gt;
    float compensationCoefficient = 1.0 + 0.02 * (temperature - 25.0); //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));&lt;br /&gt;
    float compensationVolatge = averageVoltage / compensationCoefficient; //temperature compensation&lt;br /&gt;
    tdsValue = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5; //convert voltage value to tds value&lt;br /&gt;
    //Serial.print(&amp;quot;voltage:&amp;quot;);&lt;br /&gt;
    //Serial.print(averageVoltage,2);&lt;br /&gt;
    //Serial.print(&amp;quot;V   &amp;quot;);&lt;br /&gt;
    Serial.print(&amp;quot;TDS----Value:&amp;quot;);&lt;br /&gt;
    Serial.print(tdsValue, 0);&lt;br /&gt;
    Serial.println(&amp;quot;ppm&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
int getMedianNum(int bArray[], int iFilterLen)&lt;br /&gt;
{&lt;br /&gt;
  int bTab[iFilterLen];&lt;br /&gt;
  for (byte i = 0; i &amp;lt; iFilterLen; i++)&lt;br /&gt;
    bTab[i] = bArray[i];&lt;br /&gt;
  int i, j, bTemp;&lt;br /&gt;
  for (j = 0; j &amp;lt; iFilterLen - 1; j++)&lt;br /&gt;
  {&lt;br /&gt;
    for (i = 0; i &amp;lt; iFilterLen - j - 1; i++)&lt;br /&gt;
    {&lt;br /&gt;
      if (bTab[i] &amp;gt; bTab[i + 1])&lt;br /&gt;
      {&lt;br /&gt;
        bTemp = bTab[i];&lt;br /&gt;
        bTab[i] = bTab[i + 1];&lt;br /&gt;
        bTab[i + 1] = bTemp;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  if ((iFilterLen &amp;amp; 1) &amp;gt; 0)&lt;br /&gt;
    bTemp = bTab[(iFilterLen - 1) / 2];&lt;br /&gt;
  else&lt;br /&gt;
    bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;&lt;br /&gt;
  return bTemp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Test Results'''&lt;br /&gt;
&lt;br /&gt;
Connect according to the wiring diagram, upload the code on the arduino board, after power-on, open the serial monitor, set the baud rate to 115200, insert the TDS probe into the water to be measured, stir a few times, and observe the value printed on the serial monitor, This value is the TDS value of water. As shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-101.jpg|400px]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''TDS Meter Sensor vs. Xiaomi Water Quality Test Pen'''==&lt;br /&gt;
This is a sample of tap water from the urban pipe network.&lt;br /&gt;
&lt;br /&gt;
TDS value of Xiaomi's test pen: 84 ppm&lt;br /&gt;
&lt;br /&gt;
TDS value of our sensor: 92 ppm&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The test result is only responsible for the sample, but you can serve as a reference.&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|[[File:CQRSENTDS01-X22.jpg |left|300px]]&lt;br /&gt;
|[[File:CQRSENTDS01-X3.jpg |left|300px]]&lt;br /&gt;
|[[File:CQRSENTDS01-X4.jpg |left|300px]]&lt;br /&gt;
|[[File:CQRSENTDS01-X5.jpg |left|300px]]&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Raspberry Pi Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-76.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-73.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
'''Raspberry Pi 4B Pinout Diagram'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-75.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Create a folder and a “.c” file, then write the code.&lt;br /&gt;
&lt;br /&gt;
[[Media: ADS1115.zip]]&lt;br /&gt;
&lt;br /&gt;
*You can directly add to the compressed file.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-781.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
gcc -Wall -g -o ADS1115 ADS1115.c -lm&lt;br /&gt;
&lt;br /&gt;
./ADS1115&lt;br /&gt;
&lt;br /&gt;
Go to the folder created in the terminal, use GCC cross-compilation and run the file.&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/ioctl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;linux/i2c-dev.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define ADS1115_ADDR 0x48&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int fd = open(&amp;quot;/dev/i2c-1&amp;quot;, O_RDWR);&lt;br /&gt;
    if (fd &amp;lt; 0) return 1;&lt;br /&gt;
    if (ioctl(fd, I2C_SLAVE, ADS1115_ADDR) &amp;lt; 0) return 1;&lt;br /&gt;
    &lt;br /&gt;
    while(1) {&lt;br /&gt;
        unsigned char config[3] = {0x01, 0xC2, 0x83};&lt;br /&gt;
        unsigned char result[2];&lt;br /&gt;
        &lt;br /&gt;
        write(fd, config, 3);&lt;br /&gt;
        usleep(8000);&lt;br /&gt;
        &lt;br /&gt;
        unsigned char reg[1] = {0x00};&lt;br /&gt;
        write(fd, reg, 1);&lt;br /&gt;
        read(fd, result, 2);&lt;br /&gt;
        &lt;br /&gt;
        int16_t adc = (result[0] &amp;lt;&amp;lt; 8) | result[1];&lt;br /&gt;
        float voltage = adc * 0.125 / 1000.0;&lt;br /&gt;
        float ntc_r = (3.3 * 10000.0 / voltage) - 20000.0;&lt;br /&gt;
        float temp = 1.0 / (log(ntc_r / 10000.0) / 3950.0 + 1.0 / 298.15) - 273.15;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Temp: %.1fC\n&amp;quot;, temp);&lt;br /&gt;
        sleep(1);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Test Results:&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-791.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the I2C address to 0x48. You can modify this line of code as needed: #define ADS1115_ADDR 0x48.&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the input channel to AIN0. You can replace it with the following code based on actual needs:&lt;br /&gt;
&lt;br /&gt;
AIN0: 0xC2&lt;br /&gt;
&lt;br /&gt;
AIN1: 0xD2&lt;br /&gt;
&lt;br /&gt;
AIN2: 0xE2 &lt;br /&gt;
&lt;br /&gt;
AIN3: 0xF2&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Raspberry Pi Application'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-108.jpg|600px]]&lt;br /&gt;
&lt;br /&gt;
'''Download and Run the Test Examples'''&lt;br /&gt;
&lt;br /&gt;
[[Media: TDS Meter Sensor-Raspberry Pi-New.zip]]&lt;br /&gt;
&lt;br /&gt;
*1. Connect the module to the Raspberry Pi 4B, and put the test code on the Raspberry Pi system in the form of a folder. Dial the ADD DIP switch to the 0X48 end.&lt;br /&gt;
&lt;br /&gt;
*2. The Raspberry Pi I2C communication function is used in this experiment. It is necessary to turn on the I2C function, enter sudo raspi-config in the Raspberry Pi system, and then perform the following operations.&lt;br /&gt;
&lt;br /&gt;
*3. '''Note''': When wiring, connect to A1 according to the tutorial.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-102.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-103.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-104.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-105.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-106.jpg|500px]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
File: '''ADS1115_Read Voltage.py'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
sys.path.append('../')&lt;br /&gt;
import time&lt;br /&gt;
from CQRobot_ADS1115 import ADS1115&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_6_144V        = 0x00 # 6.144V range = Gain 2/3&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_4_096V        = 0x02 # 4.096V range = Gain 1&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_2_048V        = 0x04 # 2.048V range = Gain 2 (default)&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_1_024V        = 0x06 # 1.024V range = Gain 4&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_0_512V        = 0x08 # 0.512V range = Gain 8&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_0_256V        = 0x0A # 0.256V range = Gain 16&lt;br /&gt;
ads1115 = ADS1115()&lt;br /&gt;
#Set the IIC address&lt;br /&gt;
ads1115.setAddr_ADS1115(0x48)&lt;br /&gt;
#Sets the gain and input voltage range.&lt;br /&gt;
ads1115.setGain(ADS1115_REG_CONFIG_PGA_6_144V)&lt;br /&gt;
&lt;br /&gt;
VREF = 5.0&lt;br /&gt;
analogBuffer = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]&lt;br /&gt;
analogBufferTemp = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]&lt;br /&gt;
analogBufferIndex = 0&lt;br /&gt;
copyIndex = 0&lt;br /&gt;
averageVoltage = 0&lt;br /&gt;
tdsValue = 0&lt;br /&gt;
temperature = 25&lt;br /&gt;
&lt;br /&gt;
def getMedianNum(iFilterLen):&lt;br /&gt;
	global analogBufferTemp&lt;br /&gt;
	bTemp = 0.0&lt;br /&gt;
	for j in range(iFilterLen-1):&lt;br /&gt;
		for i in range(iFilterLen-j-1):&lt;br /&gt;
			if analogBufferTemp[i] &amp;gt; analogBufferTemp[i+1]:&lt;br /&gt;
				bTemp = analogBufferTemp[i]&lt;br /&gt;
				analogBufferTemp[i] = analogBufferTemp[i+1]&lt;br /&gt;
				analogBufferTemp[i+1] = bTemp&lt;br /&gt;
	if iFilterLen &amp;amp; 1 &amp;gt; 0:&lt;br /&gt;
		bTemp = analogBufferTemp[(iFilterLen - 1)/2]&lt;br /&gt;
	else:&lt;br /&gt;
		bTemp = (analogBufferTemp[iFilterLen // 2] + analogBufferTemp[iFilterLen // 2 - 1]) / 2&lt;br /&gt;
	return float(bTemp)&lt;br /&gt;
&lt;br /&gt;
analogSampleTimepoint = time.time()&lt;br /&gt;
printTimepoint = time.time()&lt;br /&gt;
while True :&lt;br /&gt;
	if time.time() - analogSampleTimepoint &amp;gt; 0.04:&lt;br /&gt;
		#print(&amp;quot; test.......... &amp;quot;)&lt;br /&gt;
		analogSampleTimepoint = time.time()&lt;br /&gt;
		analogBuffer[analogBufferIndex] = ads1115.readVoltage(1)['r']&lt;br /&gt;
		analogBufferIndex = analogBufferIndex + 1&lt;br /&gt;
		if analogBufferIndex == 30:&lt;br /&gt;
			analogBufferIndex = 0&lt;br /&gt;
&lt;br /&gt;
	if time.time()-printTimepoint &amp;gt; 0.8:&lt;br /&gt;
		#print(&amp;quot; test &amp;quot;)&lt;br /&gt;
		printTimepoint = time.time()&lt;br /&gt;
		for copyIndex in range(30):&lt;br /&gt;
			analogBufferTemp[copyIndex] = ads1115.readVoltage(1)['r']&lt;br /&gt;
		print(&amp;quot; A1:%dmV &amp;quot;%getMedianNum(30))&lt;br /&gt;
		averageVoltage = getMedianNum(30) * (VREF / 1024.0)&lt;br /&gt;
		compensationCoefficient = 1.0 + 0.02 * (temperature - 25.0)&lt;br /&gt;
		compensationVolatge = averageVoltage / compensationCoefficient&lt;br /&gt;
		tdsValue = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5&lt;br /&gt;
		print(&amp;quot; A1:%dppm &amp;quot;%tdsValue)&lt;br /&gt;
&lt;br /&gt;
	#Get the Digital Value of Analog of selected channel&lt;br /&gt;
	#adc1 = ads1115.readVoltage(1)&lt;br /&gt;
	#time.sleep(0.2)&lt;br /&gt;
	#print(&amp;quot; A1:%dmV &amp;quot;%(adc1['r']))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
File: '''CQRobot_ADS1115.py'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import smbus&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
# Get I2C bus&lt;br /&gt;
bus = smbus.SMBus(1)&lt;br /&gt;
&lt;br /&gt;
# I2C address of the device&lt;br /&gt;
ADS1115_IIC_ADDRESS0				= 0x48&lt;br /&gt;
ADS1115_IIC_ADDRESS1				= 0x49&lt;br /&gt;
&lt;br /&gt;
# ADS1115 Register Map&lt;br /&gt;
ADS1115_REG_POINTER_CONVERT			= 0x00 # Conversion register&lt;br /&gt;
ADS1115_REG_POINTER_CONFIG			= 0x01 # Configuration register&lt;br /&gt;
ADS1115_REG_POINTER_LOWTHRESH		= 0x02 # Lo_thresh register&lt;br /&gt;
ADS1115_REG_POINTER_HITHRESH		= 0x03 # Hi_thresh register&lt;br /&gt;
&lt;br /&gt;
# ADS1115 Configuration Register&lt;br /&gt;
ADS1115_REG_CONFIG_OS_NOEFFECT		= 0x00 # No effect&lt;br /&gt;
ADS1115_REG_CONFIG_OS_SINGLE		= 0x80 # Begin a single conversion&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_DIFF_0_1		= 0x00 # Differential P = AIN0, N = AIN1 (default)&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_DIFF_0_3		= 0x10 # Differential P = AIN0, N = AIN3&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_DIFF_1_3		= 0x20 # Differential P = AIN1, N = AIN3&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_DIFF_2_3		= 0x30 # Differential P = AIN2, N = AIN3&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_SINGLE_0		= 0x40 # Single-ended P = AIN0, N = GND&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_SINGLE_1		= 0x50 # Single-ended P = AIN1, N = GND&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_SINGLE_2		= 0x60 # Single-ended P = AIN2, N = GND&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_SINGLE_3		= 0x70 # Single-ended P = AIN3, N = GND&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_6_144V		= 0x00 # +/-6.144V range = Gain 2/3&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_4_096V		= 0x02 # +/-4.096V range = Gain 1&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_2_048V		= 0x04 # +/-2.048V range = Gain 2 (default)&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_1_024V		= 0x06 # +/-1.024V range = Gain 4&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_0_512V		= 0x08 # +/-0.512V range = Gain 8&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_0_256V		= 0x0A # +/-0.256V range = Gain 16&lt;br /&gt;
ADS1115_REG_CONFIG_MODE_CONTIN		= 0x00 # Continuous conversion mode&lt;br /&gt;
ADS1115_REG_CONFIG_MODE_SINGLE		= 0x01 # Power-down single-shot mode (default)&lt;br /&gt;
ADS1115_REG_CONFIG_DR_8SPS			= 0x00 # 8 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_DR_16SPS			= 0x20 # 16 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_DR_32SPS			= 0x40 # 32 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_DR_64SPS			= 0x60 # 64 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_DR_128SPS		= 0x80 # 128 samples per second (default)&lt;br /&gt;
ADS1115_REG_CONFIG_DR_250SPS		= 0xA0 # 250 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_DR_475SPS		= 0xC0 # 475 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_DR_860SPS		= 0xE0 # 860 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_CMODE_TRAD		= 0x00 # Traditional comparator with hysteresis (default)&lt;br /&gt;
ADS1115_REG_CONFIG_CMODE_WINDOW		= 0x10 # Window comparator&lt;br /&gt;
ADS1115_REG_CONFIG_CPOL_ACTVLOW		= 0x00 # ALERT/RDY pin is low when active (default)&lt;br /&gt;
ADS1115_REG_CONFIG_CPOL_ACTVHI		= 0x08 # ALERT/RDY pin is high when active&lt;br /&gt;
ADS1115_REG_CONFIG_CLAT_NONLAT		= 0x00 # Non-latching comparator (default)&lt;br /&gt;
ADS1115_REG_CONFIG_CLAT_LATCH		= 0x04 # Latching comparator&lt;br /&gt;
ADS1115_REG_CONFIG_CQUE_1CONV		= 0x00 # Assert ALERT/RDY after one conversions&lt;br /&gt;
ADS1115_REG_CONFIG_CQUE_2CONV		= 0x01 # Assert ALERT/RDY after two conversions&lt;br /&gt;
ADS1115_REG_CONFIG_CQUE_4CONV		= 0x02 # Assert ALERT/RDY after four conversions&lt;br /&gt;
ADS1115_REG_CONFIG_CQUE_NONE		= 0x03 # Disable the comparator and put ALERT/RDY in high state (default)&lt;br /&gt;
&lt;br /&gt;
mygain=0x02&lt;br /&gt;
coefficient=0.125&lt;br /&gt;
addr_G=ADS1115_IIC_ADDRESS0&lt;br /&gt;
class ADS1115():&lt;br /&gt;
	def setGain(self,gain):&lt;br /&gt;
		global mygain&lt;br /&gt;
		global coefficient&lt;br /&gt;
		mygain=gain&lt;br /&gt;
		if mygain == ADS1115_REG_CONFIG_PGA_6_144V:&lt;br /&gt;
			coefficient = 0.1875&lt;br /&gt;
		elif mygain == ADS1115_REG_CONFIG_PGA_4_096V:&lt;br /&gt;
			coefficient = 0.125&lt;br /&gt;
		elif mygain == ADS1115_REG_CONFIG_PGA_2_048V:&lt;br /&gt;
			coefficient = 0.0625&lt;br /&gt;
		elif mygain == ADS1115_REG_CONFIG_PGA_1_024V:&lt;br /&gt;
			coefficient = 0.03125&lt;br /&gt;
		elif mygain == ADS1115_REG_CONFIG_PGA_0_512V:&lt;br /&gt;
			coefficient = 0.015625&lt;br /&gt;
		elif  mygain == ADS1115_REG_CONFIG_PGA_0_256V:&lt;br /&gt;
			coefficient = 0.0078125&lt;br /&gt;
		else:&lt;br /&gt;
			coefficient = 0.125&lt;br /&gt;
	def setAddr_ADS1115(self,addr):&lt;br /&gt;
		global addr_G&lt;br /&gt;
		addr_G=addr&lt;br /&gt;
	def setChannel(self,channel):&lt;br /&gt;
		global mygain&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;Select the Channel user want to use from 0-3&lt;br /&gt;
		For Single-ended Output&lt;br /&gt;
		0 : AINP = AIN0 and AINN = GND&lt;br /&gt;
		1 : AINP = AIN1 and AINN = GND&lt;br /&gt;
		2 : AINP = AIN2 and AINN = GND&lt;br /&gt;
		3 : AINP = AIN3 and AINN = GND&lt;br /&gt;
		For Differential Output&lt;br /&gt;
		0 : AINP = AIN0 and AINN = AIN1&lt;br /&gt;
		1 : AINP = AIN0 and AINN = AIN3&lt;br /&gt;
		2 : AINP = AIN1 and AINN = AIN3&lt;br /&gt;
		3 : AINP = AIN2 and AINN = AIN3&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		self.channel = channel&lt;br /&gt;
		while self.channel &amp;gt; 3 :&lt;br /&gt;
			self.channel = 0&lt;br /&gt;
		&lt;br /&gt;
		return self.channel&lt;br /&gt;
	&lt;br /&gt;
	def setSingle(self):&lt;br /&gt;
		global addr_G&lt;br /&gt;
		if self.channel == 0:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_SINGLE_0 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		elif self.channel == 1:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_SINGLE_1 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		elif self.channel == 2:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_SINGLE_2 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		elif self.channel == 3:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_SINGLE_3 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		&lt;br /&gt;
		bus.write_i2c_block_data(addr_G, ADS1115_REG_POINTER_CONFIG, CONFIG_REG)&lt;br /&gt;
	&lt;br /&gt;
	def setDifferential(self):&lt;br /&gt;
		global addr_G&lt;br /&gt;
		if self.channel == 0:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_DIFF_0_1 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		elif self.channel == 1:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_DIFF_0_3 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		elif self.channel == 2:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_DIFF_1_3 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		elif self.channel == 3:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_DIFF_2_3 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		&lt;br /&gt;
		bus.write_i2c_block_data(addr_G, ADS1115_REG_POINTER_CONFIG, CONFIG_REG)&lt;br /&gt;
	&lt;br /&gt;
	def readValue(self):&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;Read data back from ADS1115_REG_POINTER_CONVERT(0x00), 2 bytes&lt;br /&gt;
		raw_adc MSB, raw_adc LSB&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		global coefficient&lt;br /&gt;
		global addr_G&lt;br /&gt;
		data = bus.read_i2c_block_data(addr_G, ADS1115_REG_POINTER_CONVERT, 2)&lt;br /&gt;
		&lt;br /&gt;
		# Convert the data&lt;br /&gt;
		raw_adc = data[0] * 256 + data[1]&lt;br /&gt;
		&lt;br /&gt;
		if raw_adc &amp;gt; 32767:&lt;br /&gt;
			raw_adc -= 65535&lt;br /&gt;
		raw_adc = int(float(raw_adc)*coefficient)&lt;br /&gt;
		return {'r' : raw_adc}&lt;br /&gt;
&lt;br /&gt;
	def readVoltage(self,channel):&lt;br /&gt;
		self.setChannel(channel)&lt;br /&gt;
		self.setSingle()&lt;br /&gt;
		time.sleep(0.1)&lt;br /&gt;
		return self.readValue()&lt;br /&gt;
&lt;br /&gt;
	def ComparatorVoltage(self,channel):&lt;br /&gt;
		self.setChannel(channel)&lt;br /&gt;
		self.setDifferential()&lt;br /&gt;
		time.sleep(0.1)&lt;br /&gt;
		return self.readValue()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''Run the code'''&lt;br /&gt;
&lt;br /&gt;
Note: Make sure that the I2C address from its default (0x48);&lt;br /&gt;
&lt;br /&gt;
Note: Enable &amp;quot;Interfacing Options - P5 I2C&amp;quot; by typing the below command in the terminal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo raspi-config&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run the code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd TS1728&lt;br /&gt;
ls&lt;br /&gt;
sudo python3 CQRobot_ADS1115.py&lt;br /&gt;
cd ADS1115_ReadVoltage&lt;br /&gt;
ls&lt;br /&gt;
sudo python3 ADS1115_ReadVoltage.py&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:TDS Meter Sensor-Raspberry Pi-Run the code.jpg]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''Run the Video'''&lt;br /&gt;
&lt;br /&gt;
[[Media: TDS Meter Sensor-Raspberry Pi-Run the video.mp4]]&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=TDS_(Total_Dissolved_Solids)_Meter_Sensor_SKU:_CQRSENTDS01&amp;diff=5008</id>
		<title>TDS (Total Dissolved Solids) Meter Sensor SKU: CQRSENTDS01</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=TDS_(Total_Dissolved_Solids)_Meter_Sensor_SKU:_CQRSENTDS01&amp;diff=5008"/>
				<updated>2026-03-06T06:34:37Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Raspberry Pi Application */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:TDS Meter Sensor-7F.jpg| right |thumb|100px TDS Meter Sensor]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
&lt;br /&gt;
TDS (Total Dissolved Solids), Chinese name Total Dissolved Solids, also known as Total Dissolved Solids, indicates how many milligrams of dissolved solids are dissolved in 1 liter of water. Generally speaking, the higher the TDS value, the more dissolved substances contained in the water and the less clean the water. Therefore, the value of TDS can be used as one of the basis for reflecting the cleanliness of water. The commonly used TDS testing equipment is a TDS pen. Although it is cheap and easy to use, it cannot transmit data to the control system for long-term online monitoring and water quality analysis. Using a special instrument, although it can transmit data and has high accuracy, it is very expensive.&lt;br /&gt;
&lt;br /&gt;
CQRobot has launched an arduino-compatible TDS sensor, which can be used to measure the TDS value of water after connecting to the arduino controller. This product is specially designed for arduino, plug and play, easy to use. 3.3V~5.5V wide voltage power supply, 0 to 2.3V analog signal output, making this product compatible with 5V and 3.3V control systems, it can be easily connected to existing control systems. With CQRobot ADS1115 16-bit AD conversion module (Model: CQRADS1115), it can accurately collect and convert analog signals to meet the compatibility requirements of the Raspberry Pi motherboard.&lt;br /&gt;
&lt;br /&gt;
The excitation source for measurement uses AC signals, which can effectively prevent probe polarization, extend the life of the probe, and increase the stability of the output signal. The TDS probe is a waterproof probe that can be immersed in water for long-term measurement. This product can be applied to water quality testing in areas such as domestic water and hydroponics. With this sensor, you can easily DIY a TDS detector, easily detect the cleanliness of the water, and check your water quality.&lt;br /&gt;
&lt;br /&gt;
[[image:TDS Meter Sensor-7B.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Size Display'''==&lt;br /&gt;
[[image:TDS Meter Sensor-7C1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specifications'''==&lt;br /&gt;
'''Signal Transmitter Board Specifications'''&lt;br /&gt;
*Input Voltage: 3.3V to 5.5V&lt;br /&gt;
*Output Voltage: 0 to 2.3V&lt;br /&gt;
*Working Current: 3mA to 6mA&lt;br /&gt;
*TDS Measurement Range: 0 to 1000ppm&lt;br /&gt;
*TDS Measurement Accuracy: Plus/Minus 10% F.S. (25 Degree Celsius)&lt;br /&gt;
*Module Size: 43mm * 32.2mm&lt;br /&gt;
*Module Interface: JST 2.0mm 3-Pin&lt;br /&gt;
*Electrode Interface: JST 2.54mm 2-Pin&lt;br /&gt;
'''TDS Probe Specifications'''&lt;br /&gt;
*Number of Needle: 2&lt;br /&gt;
*Total Length: 60cm&lt;br /&gt;
*Connection Interface: JTS 2.54mm 2-Pin&lt;br /&gt;
*Color: Black&lt;br /&gt;
*Other: Waterproof Probe&lt;br /&gt;
'''Ocean Interface Cable Specifications'''&lt;br /&gt;
*Cable specifications: 22AWG&lt;br /&gt;
*Material: Silicone&lt;br /&gt;
*Withstand Voltage: Less Than 50V&lt;br /&gt;
*Withstand Current: Less Than 1000MA&lt;br /&gt;
*Length: 21cm&lt;br /&gt;
*Line Sequence: Black-Negative Power Supply, Red-Positive Power Supply, Green-Signal Terminal.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
'''Attention'''&lt;br /&gt;
*The probe can not be used in water above 55 degrees centigrade.&lt;br /&gt;
*The probe can not be left too close to the edge of the container, otherwise it will affect the reading.&lt;br /&gt;
*The head and the cable of the probe are waterproof, but the connector and the signal transmitter board are not waterproof. Please be careful.&lt;br /&gt;
*When using the TDS instrument sensor, the sensor probe is immersed in liquid, and the purchaser needs to '''Separate''' the sensor '''Probe Protective Cover''' to avoid incorrect data reading and malfunction.&lt;br /&gt;
&lt;br /&gt;
[[image:TDS Meter Sensor-7D.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
*The TDS probe cannot be used in water above 55 degrees Celsius;&lt;br /&gt;
*The TDS probe should not be placed too close to the edge of the container, otherwise it will affect the sensor reading parameters;&lt;br /&gt;
*The TDS probe head and lead are made of waterproof material and can be immersed in water, but the cable interface and signal transfer board are not waterproof, please use them carefully.&lt;br /&gt;
&lt;br /&gt;
'''Arduino Connections'''&lt;br /&gt;
&lt;br /&gt;
*The DuPont female single-head wiring we distribute cannot be directly connected to the UNO R3 control board. Need to be in Stack the sensor expansion board on the UNO R3 control board, or connect the male-to-male Dupont wire to the Dupont female single-head wiring(Bread Wire).&lt;br /&gt;
&lt;br /&gt;
'''Raspberry Pi Test Code'''&lt;br /&gt;
&lt;br /&gt;
*Compatible Raspberry Pi needs to be used with ADS1115 16-bit AD conversion module. Please refer to the specific test code: http://www.cqrobot.wiki/index.php/ADS1115_16-Bit_ADC_Module_SKU:_CQRADS1115&lt;br /&gt;
*Connect the module to the Raspberry Pi 4B, and put the test code in the Raspberry Pi system in the form of a folder. Dial the ADD dial switch to the 0X48 end.&lt;br /&gt;
*In this experiment, the Raspberry Pi I2C communication function is used. You need to turn on the I2C function, enter sudo raspi-config in the Raspberry Pi system, and then perform the following operations.&lt;br /&gt;
*This kit does '''not include''' CQRobot ADS1115 16-bit AD conversion module (Model: CQRADS1115), buyers need to purchase it separately.&lt;br /&gt;
&lt;br /&gt;
[[image:TDS Meter Sensor-7E.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Arduino Application'''==&lt;br /&gt;
&lt;br /&gt;
'''Note''': The DuPont female single-ended wiring we distribute cannot be directly connected to the UNO R3 control board. When wiring, you need to stack the sensor expansion board on the UNO R3 control board, or connect the male-to-male Dupont wire (bread wire) on the Dupont wire female single-ended wire.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-107.jpg|600px]]&lt;br /&gt;
&lt;br /&gt;
'''Download and Run the Test Examples'''&lt;br /&gt;
&lt;br /&gt;
[[Media: TDS Meter Sensor-Arduino.rar]]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define TdsSensorPin A1&lt;br /&gt;
#define VREF 5.0      // analog reference voltage(Volt) of the ADC&lt;br /&gt;
#define SCOUNT  30           // sum of sample point&lt;br /&gt;
int analogBuffer[SCOUNT];    // store the analog value in the array, read from ADC&lt;br /&gt;
int analogBufferTemp[SCOUNT];&lt;br /&gt;
int analogBufferIndex = 0, copyIndex = 0;&lt;br /&gt;
float averageVoltage = 0, tdsValue = 0, temperature = 25;&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  pinMode(TdsSensorPin, INPUT);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  static unsigned long analogSampleTimepoint = millis();&lt;br /&gt;
  if (millis() - analogSampleTimepoint &amp;gt; 40U)  //every 40 milliseconds,read the analog value from the ADC&lt;br /&gt;
  {&lt;br /&gt;
    analogSampleTimepoint = millis();&lt;br /&gt;
    analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin);    //read the analog value and store into the buffer&lt;br /&gt;
    analogBufferIndex++;&lt;br /&gt;
    if (analogBufferIndex == SCOUNT)&lt;br /&gt;
      analogBufferIndex = 0;&lt;br /&gt;
  }&lt;br /&gt;
  static unsigned long printTimepoint = millis();&lt;br /&gt;
  if (millis() - printTimepoint &amp;gt; 800U)&lt;br /&gt;
  {&lt;br /&gt;
    printTimepoint = millis();&lt;br /&gt;
    for (copyIndex = 0; copyIndex &amp;lt; SCOUNT; copyIndex++)&lt;br /&gt;
      analogBufferTemp[copyIndex] = analogBuffer[copyIndex];&lt;br /&gt;
    averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF / 1024.0; // read the analog value more stable by the median filtering algorithm, and convert to voltage value&lt;br /&gt;
    float compensationCoefficient = 1.0 + 0.02 * (temperature - 25.0); //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));&lt;br /&gt;
    float compensationVolatge = averageVoltage / compensationCoefficient; //temperature compensation&lt;br /&gt;
    tdsValue = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5; //convert voltage value to tds value&lt;br /&gt;
    //Serial.print(&amp;quot;voltage:&amp;quot;);&lt;br /&gt;
    //Serial.print(averageVoltage,2);&lt;br /&gt;
    //Serial.print(&amp;quot;V   &amp;quot;);&lt;br /&gt;
    Serial.print(&amp;quot;TDS----Value:&amp;quot;);&lt;br /&gt;
    Serial.print(tdsValue, 0);&lt;br /&gt;
    Serial.println(&amp;quot;ppm&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
int getMedianNum(int bArray[], int iFilterLen)&lt;br /&gt;
{&lt;br /&gt;
  int bTab[iFilterLen];&lt;br /&gt;
  for (byte i = 0; i &amp;lt; iFilterLen; i++)&lt;br /&gt;
    bTab[i] = bArray[i];&lt;br /&gt;
  int i, j, bTemp;&lt;br /&gt;
  for (j = 0; j &amp;lt; iFilterLen - 1; j++)&lt;br /&gt;
  {&lt;br /&gt;
    for (i = 0; i &amp;lt; iFilterLen - j - 1; i++)&lt;br /&gt;
    {&lt;br /&gt;
      if (bTab[i] &amp;gt; bTab[i + 1])&lt;br /&gt;
      {&lt;br /&gt;
        bTemp = bTab[i];&lt;br /&gt;
        bTab[i] = bTab[i + 1];&lt;br /&gt;
        bTab[i + 1] = bTemp;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  if ((iFilterLen &amp;amp; 1) &amp;gt; 0)&lt;br /&gt;
    bTemp = bTab[(iFilterLen - 1) / 2];&lt;br /&gt;
  else&lt;br /&gt;
    bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;&lt;br /&gt;
  return bTemp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Test Results'''&lt;br /&gt;
&lt;br /&gt;
Connect according to the wiring diagram, upload the code on the arduino board, after power-on, open the serial monitor, set the baud rate to 115200, insert the TDS probe into the water to be measured, stir a few times, and observe the value printed on the serial monitor, This value is the TDS value of water. As shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-101.jpg|400px]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''TDS Meter Sensor vs. Xiaomi Water Quality Test Pen'''==&lt;br /&gt;
This is a sample of tap water from the urban pipe network.&lt;br /&gt;
&lt;br /&gt;
TDS value of Xiaomi's test pen: 84 ppm&lt;br /&gt;
&lt;br /&gt;
TDS value of our sensor: 92 ppm&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The test result is only responsible for the sample, but you can serve as a reference.&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|[[File:CQRSENTDS01-X22.jpg |left|300px]]&lt;br /&gt;
|[[File:CQRSENTDS01-X3.jpg |left|300px]]&lt;br /&gt;
|[[File:CQRSENTDS01-X4.jpg |left|300px]]&lt;br /&gt;
|[[File:CQRSENTDS01-X5.jpg |left|300px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Raspberry Pi Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-76.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-73.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
'''Raspberry Pi 4B Pinout Diagram'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-75.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Create a folder and a “.c” file, then write the code.&lt;br /&gt;
&lt;br /&gt;
[[Media: ADS1115.zip]]&lt;br /&gt;
&lt;br /&gt;
*You can directly add to the compressed file.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-781.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
gcc -Wall -g -o ADS1115 ADS1115.c -lm&lt;br /&gt;
&lt;br /&gt;
./ADS1115&lt;br /&gt;
&lt;br /&gt;
Go to the folder created in the terminal, use GCC cross-compilation and run the file.&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/ioctl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;linux/i2c-dev.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define ADS1115_ADDR 0x48&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int fd = open(&amp;quot;/dev/i2c-1&amp;quot;, O_RDWR);&lt;br /&gt;
    if (fd &amp;lt; 0) return 1;&lt;br /&gt;
    if (ioctl(fd, I2C_SLAVE, ADS1115_ADDR) &amp;lt; 0) return 1;&lt;br /&gt;
    &lt;br /&gt;
    while(1) {&lt;br /&gt;
        unsigned char config[3] = {0x01, 0xC2, 0x83};&lt;br /&gt;
        unsigned char result[2];&lt;br /&gt;
        &lt;br /&gt;
        write(fd, config, 3);&lt;br /&gt;
        usleep(8000);&lt;br /&gt;
        &lt;br /&gt;
        unsigned char reg[1] = {0x00};&lt;br /&gt;
        write(fd, reg, 1);&lt;br /&gt;
        read(fd, result, 2);&lt;br /&gt;
        &lt;br /&gt;
        int16_t adc = (result[0] &amp;lt;&amp;lt; 8) | result[1];&lt;br /&gt;
        float voltage = adc * 0.125 / 1000.0;&lt;br /&gt;
        float ntc_r = (3.3 * 10000.0 / voltage) - 20000.0;&lt;br /&gt;
        float temp = 1.0 / (log(ntc_r / 10000.0) / 3950.0 + 1.0 / 298.15) - 273.15;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Temp: %.1fC\n&amp;quot;, temp);&lt;br /&gt;
        sleep(1);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Test Results:&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-791.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the I2C address to 0x48. You can modify this line of code as needed: #define ADS1115_ADDR 0x48.&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the input channel to AIN0. You can replace it with the following code based on actual needs:&lt;br /&gt;
&lt;br /&gt;
AIN0: 0xC2&lt;br /&gt;
&lt;br /&gt;
AIN1: 0xD2&lt;br /&gt;
&lt;br /&gt;
AIN2: 0xE2 &lt;br /&gt;
&lt;br /&gt;
AIN3: 0xF2&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Raspberry Pi Application'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-108.jpg|600px]]&lt;br /&gt;
&lt;br /&gt;
'''Download and Run the Test Examples'''&lt;br /&gt;
&lt;br /&gt;
[[Media: TDS Meter Sensor-Raspberry Pi-New.zip]]&lt;br /&gt;
&lt;br /&gt;
*1. Connect the module to the Raspberry Pi 4B, and put the test code on the Raspberry Pi system in the form of a folder. Dial the ADD DIP switch to the 0X48 end.&lt;br /&gt;
&lt;br /&gt;
*2. The Raspberry Pi I2C communication function is used in this experiment. It is necessary to turn on the I2C function, enter sudo raspi-config in the Raspberry Pi system, and then perform the following operations.&lt;br /&gt;
&lt;br /&gt;
*3. '''Note''': When wiring, connect to A1 according to the tutorial.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-102.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-103.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-104.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-105.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRSENTDS01-106.jpg|500px]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
File: '''ADS1115_Read Voltage.py'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
sys.path.append('../')&lt;br /&gt;
import time&lt;br /&gt;
from CQRobot_ADS1115 import ADS1115&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_6_144V        = 0x00 # 6.144V range = Gain 2/3&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_4_096V        = 0x02 # 4.096V range = Gain 1&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_2_048V        = 0x04 # 2.048V range = Gain 2 (default)&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_1_024V        = 0x06 # 1.024V range = Gain 4&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_0_512V        = 0x08 # 0.512V range = Gain 8&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_0_256V        = 0x0A # 0.256V range = Gain 16&lt;br /&gt;
ads1115 = ADS1115()&lt;br /&gt;
#Set the IIC address&lt;br /&gt;
ads1115.setAddr_ADS1115(0x48)&lt;br /&gt;
#Sets the gain and input voltage range.&lt;br /&gt;
ads1115.setGain(ADS1115_REG_CONFIG_PGA_6_144V)&lt;br /&gt;
&lt;br /&gt;
VREF = 5.0&lt;br /&gt;
analogBuffer = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]&lt;br /&gt;
analogBufferTemp = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]&lt;br /&gt;
analogBufferIndex = 0&lt;br /&gt;
copyIndex = 0&lt;br /&gt;
averageVoltage = 0&lt;br /&gt;
tdsValue = 0&lt;br /&gt;
temperature = 25&lt;br /&gt;
&lt;br /&gt;
def getMedianNum(iFilterLen):&lt;br /&gt;
	global analogBufferTemp&lt;br /&gt;
	bTemp = 0.0&lt;br /&gt;
	for j in range(iFilterLen-1):&lt;br /&gt;
		for i in range(iFilterLen-j-1):&lt;br /&gt;
			if analogBufferTemp[i] &amp;gt; analogBufferTemp[i+1]:&lt;br /&gt;
				bTemp = analogBufferTemp[i]&lt;br /&gt;
				analogBufferTemp[i] = analogBufferTemp[i+1]&lt;br /&gt;
				analogBufferTemp[i+1] = bTemp&lt;br /&gt;
	if iFilterLen &amp;amp; 1 &amp;gt; 0:&lt;br /&gt;
		bTemp = analogBufferTemp[(iFilterLen - 1)/2]&lt;br /&gt;
	else:&lt;br /&gt;
		bTemp = (analogBufferTemp[iFilterLen // 2] + analogBufferTemp[iFilterLen // 2 - 1]) / 2&lt;br /&gt;
	return float(bTemp)&lt;br /&gt;
&lt;br /&gt;
analogSampleTimepoint = time.time()&lt;br /&gt;
printTimepoint = time.time()&lt;br /&gt;
while True :&lt;br /&gt;
	if time.time() - analogSampleTimepoint &amp;gt; 0.04:&lt;br /&gt;
		#print(&amp;quot; test.......... &amp;quot;)&lt;br /&gt;
		analogSampleTimepoint = time.time()&lt;br /&gt;
		analogBuffer[analogBufferIndex] = ads1115.readVoltage(1)['r']&lt;br /&gt;
		analogBufferIndex = analogBufferIndex + 1&lt;br /&gt;
		if analogBufferIndex == 30:&lt;br /&gt;
			analogBufferIndex = 0&lt;br /&gt;
&lt;br /&gt;
	if time.time()-printTimepoint &amp;gt; 0.8:&lt;br /&gt;
		#print(&amp;quot; test &amp;quot;)&lt;br /&gt;
		printTimepoint = time.time()&lt;br /&gt;
		for copyIndex in range(30):&lt;br /&gt;
			analogBufferTemp[copyIndex] = ads1115.readVoltage(1)['r']&lt;br /&gt;
		print(&amp;quot; A1:%dmV &amp;quot;%getMedianNum(30))&lt;br /&gt;
		averageVoltage = getMedianNum(30) * (VREF / 1024.0)&lt;br /&gt;
		compensationCoefficient = 1.0 + 0.02 * (temperature - 25.0)&lt;br /&gt;
		compensationVolatge = averageVoltage / compensationCoefficient&lt;br /&gt;
		tdsValue = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5&lt;br /&gt;
		print(&amp;quot; A1:%dppm &amp;quot;%tdsValue)&lt;br /&gt;
&lt;br /&gt;
	#Get the Digital Value of Analog of selected channel&lt;br /&gt;
	#adc1 = ads1115.readVoltage(1)&lt;br /&gt;
	#time.sleep(0.2)&lt;br /&gt;
	#print(&amp;quot; A1:%dmV &amp;quot;%(adc1['r']))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
File: '''CQRobot_ADS1115.py'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import smbus&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
# Get I2C bus&lt;br /&gt;
bus = smbus.SMBus(1)&lt;br /&gt;
&lt;br /&gt;
# I2C address of the device&lt;br /&gt;
ADS1115_IIC_ADDRESS0				= 0x48&lt;br /&gt;
ADS1115_IIC_ADDRESS1				= 0x49&lt;br /&gt;
&lt;br /&gt;
# ADS1115 Register Map&lt;br /&gt;
ADS1115_REG_POINTER_CONVERT			= 0x00 # Conversion register&lt;br /&gt;
ADS1115_REG_POINTER_CONFIG			= 0x01 # Configuration register&lt;br /&gt;
ADS1115_REG_POINTER_LOWTHRESH		= 0x02 # Lo_thresh register&lt;br /&gt;
ADS1115_REG_POINTER_HITHRESH		= 0x03 # Hi_thresh register&lt;br /&gt;
&lt;br /&gt;
# ADS1115 Configuration Register&lt;br /&gt;
ADS1115_REG_CONFIG_OS_NOEFFECT		= 0x00 # No effect&lt;br /&gt;
ADS1115_REG_CONFIG_OS_SINGLE		= 0x80 # Begin a single conversion&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_DIFF_0_1		= 0x00 # Differential P = AIN0, N = AIN1 (default)&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_DIFF_0_3		= 0x10 # Differential P = AIN0, N = AIN3&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_DIFF_1_3		= 0x20 # Differential P = AIN1, N = AIN3&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_DIFF_2_3		= 0x30 # Differential P = AIN2, N = AIN3&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_SINGLE_0		= 0x40 # Single-ended P = AIN0, N = GND&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_SINGLE_1		= 0x50 # Single-ended P = AIN1, N = GND&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_SINGLE_2		= 0x60 # Single-ended P = AIN2, N = GND&lt;br /&gt;
ADS1115_REG_CONFIG_MUX_SINGLE_3		= 0x70 # Single-ended P = AIN3, N = GND&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_6_144V		= 0x00 # +/-6.144V range = Gain 2/3&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_4_096V		= 0x02 # +/-4.096V range = Gain 1&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_2_048V		= 0x04 # +/-2.048V range = Gain 2 (default)&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_1_024V		= 0x06 # +/-1.024V range = Gain 4&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_0_512V		= 0x08 # +/-0.512V range = Gain 8&lt;br /&gt;
ADS1115_REG_CONFIG_PGA_0_256V		= 0x0A # +/-0.256V range = Gain 16&lt;br /&gt;
ADS1115_REG_CONFIG_MODE_CONTIN		= 0x00 # Continuous conversion mode&lt;br /&gt;
ADS1115_REG_CONFIG_MODE_SINGLE		= 0x01 # Power-down single-shot mode (default)&lt;br /&gt;
ADS1115_REG_CONFIG_DR_8SPS			= 0x00 # 8 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_DR_16SPS			= 0x20 # 16 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_DR_32SPS			= 0x40 # 32 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_DR_64SPS			= 0x60 # 64 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_DR_128SPS		= 0x80 # 128 samples per second (default)&lt;br /&gt;
ADS1115_REG_CONFIG_DR_250SPS		= 0xA0 # 250 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_DR_475SPS		= 0xC0 # 475 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_DR_860SPS		= 0xE0 # 860 samples per second&lt;br /&gt;
ADS1115_REG_CONFIG_CMODE_TRAD		= 0x00 # Traditional comparator with hysteresis (default)&lt;br /&gt;
ADS1115_REG_CONFIG_CMODE_WINDOW		= 0x10 # Window comparator&lt;br /&gt;
ADS1115_REG_CONFIG_CPOL_ACTVLOW		= 0x00 # ALERT/RDY pin is low when active (default)&lt;br /&gt;
ADS1115_REG_CONFIG_CPOL_ACTVHI		= 0x08 # ALERT/RDY pin is high when active&lt;br /&gt;
ADS1115_REG_CONFIG_CLAT_NONLAT		= 0x00 # Non-latching comparator (default)&lt;br /&gt;
ADS1115_REG_CONFIG_CLAT_LATCH		= 0x04 # Latching comparator&lt;br /&gt;
ADS1115_REG_CONFIG_CQUE_1CONV		= 0x00 # Assert ALERT/RDY after one conversions&lt;br /&gt;
ADS1115_REG_CONFIG_CQUE_2CONV		= 0x01 # Assert ALERT/RDY after two conversions&lt;br /&gt;
ADS1115_REG_CONFIG_CQUE_4CONV		= 0x02 # Assert ALERT/RDY after four conversions&lt;br /&gt;
ADS1115_REG_CONFIG_CQUE_NONE		= 0x03 # Disable the comparator and put ALERT/RDY in high state (default)&lt;br /&gt;
&lt;br /&gt;
mygain=0x02&lt;br /&gt;
coefficient=0.125&lt;br /&gt;
addr_G=ADS1115_IIC_ADDRESS0&lt;br /&gt;
class ADS1115():&lt;br /&gt;
	def setGain(self,gain):&lt;br /&gt;
		global mygain&lt;br /&gt;
		global coefficient&lt;br /&gt;
		mygain=gain&lt;br /&gt;
		if mygain == ADS1115_REG_CONFIG_PGA_6_144V:&lt;br /&gt;
			coefficient = 0.1875&lt;br /&gt;
		elif mygain == ADS1115_REG_CONFIG_PGA_4_096V:&lt;br /&gt;
			coefficient = 0.125&lt;br /&gt;
		elif mygain == ADS1115_REG_CONFIG_PGA_2_048V:&lt;br /&gt;
			coefficient = 0.0625&lt;br /&gt;
		elif mygain == ADS1115_REG_CONFIG_PGA_1_024V:&lt;br /&gt;
			coefficient = 0.03125&lt;br /&gt;
		elif mygain == ADS1115_REG_CONFIG_PGA_0_512V:&lt;br /&gt;
			coefficient = 0.015625&lt;br /&gt;
		elif  mygain == ADS1115_REG_CONFIG_PGA_0_256V:&lt;br /&gt;
			coefficient = 0.0078125&lt;br /&gt;
		else:&lt;br /&gt;
			coefficient = 0.125&lt;br /&gt;
	def setAddr_ADS1115(self,addr):&lt;br /&gt;
		global addr_G&lt;br /&gt;
		addr_G=addr&lt;br /&gt;
	def setChannel(self,channel):&lt;br /&gt;
		global mygain&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;Select the Channel user want to use from 0-3&lt;br /&gt;
		For Single-ended Output&lt;br /&gt;
		0 : AINP = AIN0 and AINN = GND&lt;br /&gt;
		1 : AINP = AIN1 and AINN = GND&lt;br /&gt;
		2 : AINP = AIN2 and AINN = GND&lt;br /&gt;
		3 : AINP = AIN3 and AINN = GND&lt;br /&gt;
		For Differential Output&lt;br /&gt;
		0 : AINP = AIN0 and AINN = AIN1&lt;br /&gt;
		1 : AINP = AIN0 and AINN = AIN3&lt;br /&gt;
		2 : AINP = AIN1 and AINN = AIN3&lt;br /&gt;
		3 : AINP = AIN2 and AINN = AIN3&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		self.channel = channel&lt;br /&gt;
		while self.channel &amp;gt; 3 :&lt;br /&gt;
			self.channel = 0&lt;br /&gt;
		&lt;br /&gt;
		return self.channel&lt;br /&gt;
	&lt;br /&gt;
	def setSingle(self):&lt;br /&gt;
		global addr_G&lt;br /&gt;
		if self.channel == 0:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_SINGLE_0 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		elif self.channel == 1:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_SINGLE_1 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		elif self.channel == 2:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_SINGLE_2 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		elif self.channel == 3:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_SINGLE_3 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		&lt;br /&gt;
		bus.write_i2c_block_data(addr_G, ADS1115_REG_POINTER_CONFIG, CONFIG_REG)&lt;br /&gt;
	&lt;br /&gt;
	def setDifferential(self):&lt;br /&gt;
		global addr_G&lt;br /&gt;
		if self.channel == 0:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_DIFF_0_1 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		elif self.channel == 1:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_DIFF_0_3 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		elif self.channel == 2:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_DIFF_1_3 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		elif self.channel == 3:&lt;br /&gt;
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_DIFF_2_3 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]&lt;br /&gt;
		&lt;br /&gt;
		bus.write_i2c_block_data(addr_G, ADS1115_REG_POINTER_CONFIG, CONFIG_REG)&lt;br /&gt;
	&lt;br /&gt;
	def readValue(self):&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;Read data back from ADS1115_REG_POINTER_CONVERT(0x00), 2 bytes&lt;br /&gt;
		raw_adc MSB, raw_adc LSB&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		global coefficient&lt;br /&gt;
		global addr_G&lt;br /&gt;
		data = bus.read_i2c_block_data(addr_G, ADS1115_REG_POINTER_CONVERT, 2)&lt;br /&gt;
		&lt;br /&gt;
		# Convert the data&lt;br /&gt;
		raw_adc = data[0] * 256 + data[1]&lt;br /&gt;
		&lt;br /&gt;
		if raw_adc &amp;gt; 32767:&lt;br /&gt;
			raw_adc -= 65535&lt;br /&gt;
		raw_adc = int(float(raw_adc)*coefficient)&lt;br /&gt;
		return {'r' : raw_adc}&lt;br /&gt;
&lt;br /&gt;
	def readVoltage(self,channel):&lt;br /&gt;
		self.setChannel(channel)&lt;br /&gt;
		self.setSingle()&lt;br /&gt;
		time.sleep(0.1)&lt;br /&gt;
		return self.readValue()&lt;br /&gt;
&lt;br /&gt;
	def ComparatorVoltage(self,channel):&lt;br /&gt;
		self.setChannel(channel)&lt;br /&gt;
		self.setDifferential()&lt;br /&gt;
		time.sleep(0.1)&lt;br /&gt;
		return self.readValue()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''Run the code'''&lt;br /&gt;
&lt;br /&gt;
Note: Make sure that the I2C address from its default (0x48);&lt;br /&gt;
&lt;br /&gt;
Note: Enable &amp;quot;Interfacing Options - P5 I2C&amp;quot; by typing the below command in the terminal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo raspi-config&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run the code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd TS1728&lt;br /&gt;
ls&lt;br /&gt;
sudo python3 CQRobot_ADS1115.py&lt;br /&gt;
cd ADS1115_ReadVoltage&lt;br /&gt;
ls&lt;br /&gt;
sudo python3 ADS1115_ReadVoltage.py&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:TDS Meter Sensor-Raspberry Pi-Run the code.jpg]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''Run the Video'''&lt;br /&gt;
&lt;br /&gt;
[[Media: TDS Meter Sensor-Raspberry Pi-Run the video.mp4]]&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=5007</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=5007"/>
				<updated>2026-01-29T04:23:43Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Raspberry Pi Example and Test Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-711.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-721.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-73.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-75.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Assuming the VCC is now 5V, set A3-A0 to the 1 0 0 0 mode (A3 inverting while A2-A0 not). This requires VOXRL/VCC to be 0.53125±0.015, general formula: [VCC/（R1+R2）]R1=VXORL. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Given the VCC of 5V and RLB of 100kΩ, the target VXORL should be 0.53125×5V=2.65625V. Substituting all parameters into the formula yields R2 ≈ 88.23529kΩ. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Since this calculated R2 is not the exact common resistance, it should be matched with the closest common resistance value and verified through formula validation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under this circumstance, the closest common resistance value to 88.23529kΩ is 86.6kΩ, so VXORL≈2.67953V, or VXORL/VCC≈0.53906. This ratio falls within 0.53125±0.015, making 86.6kΩ a suitable resistance value for RLT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-76.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-7.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Arduino Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  Wire.begin();&lt;br /&gt;
  Serial.println(&amp;quot;Scan available I2C devices:&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  for(int addr = 1; addr &amp;lt; 127; addr++) {&lt;br /&gt;
    Wire.beginTransmission(addr);&lt;br /&gt;
    if(Wire.endTransmission() == 0) {&lt;br /&gt;
      if(Wire.requestFrom(addr, (byte)1) &amp;gt; 0) {&lt;br /&gt;
        Serial.print(&amp;quot;✅ Available devices: 0x&amp;quot;);&lt;br /&gt;
        if(addr &amp;lt; 16) Serial.print(&amp;quot;0&amp;quot;);&lt;br /&gt;
        Serial.println(addr, HEX);&lt;br /&gt;
        while(Wire.available()) Wire.read();&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  delay(3000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Test Results:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-78.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set the serial port to 9600. Open the serial port debugger to view the bidirectional I2C address. After toggling the DIP switch to change the address, power on again. The new address will appear in the serial port debugger.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Raspberry Pi Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
'''First, visit the Raspberry Pi official website to download the system. You must select the download option in the frame below; otherwise, the sensor will not function properly.'''&lt;br /&gt;
&lt;br /&gt;
*Download link: https://www.raspberrypi.com/software/operating-systems/#raspberry-pi-os-legacy-64-bit&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-791.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Schematic Diagram of Raspberry Pi 4B pins:&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-80.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-81.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-82.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
Create a folder and a “.c” file, then write the code.&lt;br /&gt;
&lt;br /&gt;
[[Media: I2C.rar]]&lt;br /&gt;
&lt;br /&gt;
You can directly add to the compressed file.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-83.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
gcc -Wall -g -o I2C I2C.c -lm&lt;br /&gt;
&lt;br /&gt;
./I2C&lt;br /&gt;
&lt;br /&gt;
Go to the folder created in the terminal, use GCC cross-compilation and run the file.&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/ioctl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;linux/i2c-dev.h&amp;gt;&lt;br /&gt;
int main() {&lt;br /&gt;
    int file;&lt;br /&gt;
    char filename[20];&lt;br /&gt;
    &lt;br /&gt;
    printf(&amp;quot;Scan available I2C devices...\n\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    snprintf(filename, 19, &amp;quot;/dev/i2c-1&amp;quot;);&lt;br /&gt;
    file = open(filename, O_RDWR);&lt;br /&gt;
    if (file &amp;lt; 0) {&lt;br /&gt;
        printf(&amp;quot;Error: Unable to open I2C bus\n&amp;quot;);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    printf(&amp;quot;The discovered I2C device address:\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (int addr = 0x03; addr &amp;lt;= 0x77; addr++) {&lt;br /&gt;
        if (ioctl(file, I2C_SLAVE, addr) &amp;gt;= 0) {&lt;br /&gt;
            unsigned char buffer[1];&lt;br /&gt;
            if (read(file, buffer, 1) == 1) {&lt;br /&gt;
                printf(&amp;quot;0x%02X\n&amp;quot;, addr);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    close(file);&lt;br /&gt;
    printf(&amp;quot;\nScan completed\n&amp;quot;);&lt;br /&gt;
return 0;}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Test Results:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-85.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After toggling the DIP switch to change the address, power on again.&lt;br /&gt;
----&lt;br /&gt;
=='''Sensor Does Not Work Properly'''==&lt;br /&gt;
&lt;br /&gt;
'''Answer:''' &lt;br /&gt;
&lt;br /&gt;
*Ensure the sensor wiring is correctly connected to the development board;&lt;br /&gt;
&lt;br /&gt;
*Verify that the board program is properly burned.&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-85.jpg&amp;diff=5006</id>
		<title>File:CQRADDR001-85.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-85.jpg&amp;diff=5006"/>
				<updated>2026-01-29T04:20:10Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=5005</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=5005"/>
				<updated>2026-01-29T04:19:54Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Raspberry Pi Example and Test Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-711.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-721.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-73.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-75.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Assuming the VCC is now 5V, set A3-A0 to the 1 0 0 0 mode (A3 inverting while A2-A0 not). This requires VOXRL/VCC to be 0.53125±0.015, general formula: [VCC/（R1+R2）]R1=VXORL. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Given the VCC of 5V and RLB of 100kΩ, the target VXORL should be 0.53125×5V=2.65625V. Substituting all parameters into the formula yields R2 ≈ 88.23529kΩ. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Since this calculated R2 is not the exact common resistance, it should be matched with the closest common resistance value and verified through formula validation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under this circumstance, the closest common resistance value to 88.23529kΩ is 86.6kΩ, so VXORL≈2.67953V, or VXORL/VCC≈0.53906. This ratio falls within 0.53125±0.015, making 86.6kΩ a suitable resistance value for RLT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-76.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-7.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Arduino Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  Wire.begin();&lt;br /&gt;
  Serial.println(&amp;quot;Scan available I2C devices:&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  for(int addr = 1; addr &amp;lt; 127; addr++) {&lt;br /&gt;
    Wire.beginTransmission(addr);&lt;br /&gt;
    if(Wire.endTransmission() == 0) {&lt;br /&gt;
      if(Wire.requestFrom(addr, (byte)1) &amp;gt; 0) {&lt;br /&gt;
        Serial.print(&amp;quot;✅ Available devices: 0x&amp;quot;);&lt;br /&gt;
        if(addr &amp;lt; 16) Serial.print(&amp;quot;0&amp;quot;);&lt;br /&gt;
        Serial.println(addr, HEX);&lt;br /&gt;
        while(Wire.available()) Wire.read();&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  delay(3000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Test Results:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-78.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set the serial port to 9600. Open the serial port debugger to view the bidirectional I2C address. After toggling the DIP switch to change the address, power on again. The new address will appear in the serial port debugger.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Raspberry Pi Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
'''First, visit the Raspberry Pi official website to download the system. You must select the download option in the frame below; otherwise, the sensor will not function properly.'''&lt;br /&gt;
&lt;br /&gt;
*Download link: https://www.raspberrypi.com/software/operating-systems/#raspberry-pi-os-legacy-64-bit&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-791.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Schematic Diagram of Raspberry Pi 4B pins:&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-80.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-81.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-82.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
Create a folder and a “.c” file, then write the code.&lt;br /&gt;
&lt;br /&gt;
[[Media: I2C.rar]]&lt;br /&gt;
&lt;br /&gt;
You can directly add to the compressed file.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-83.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
gcc -Wall -g -o I2C I2C.c -lm&lt;br /&gt;
&lt;br /&gt;
./I2C&lt;br /&gt;
&lt;br /&gt;
Go to the folder created in the terminal, use GCC cross-compilation and run the file.&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/ioctl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;linux/i2c-dev.h&amp;gt;&lt;br /&gt;
int main() {&lt;br /&gt;
    int file;&lt;br /&gt;
    char filename[20];&lt;br /&gt;
    &lt;br /&gt;
    printf(&amp;quot;Scan available I2C devices...\n\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    snprintf(filename, 19, &amp;quot;/dev/i2c-1&amp;quot;);&lt;br /&gt;
    file = open(filename, O_RDWR);&lt;br /&gt;
    if (file &amp;lt; 0) {&lt;br /&gt;
        printf(&amp;quot;Error: Unable to open I2C bus\n&amp;quot;);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    printf(&amp;quot;The discovered I2C device address:\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    for (int addr = 0x03; addr &amp;lt;= 0x77; addr++) {&lt;br /&gt;
        if (ioctl(file, I2C_SLAVE, addr) &amp;gt;= 0) {&lt;br /&gt;
            unsigned char buffer[1];&lt;br /&gt;
            if (read(file, buffer, 1) == 1) {&lt;br /&gt;
                printf(&amp;quot;0x%02X\n&amp;quot;, addr);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    close(file);&lt;br /&gt;
    printf(&amp;quot;\nScan completed\n&amp;quot;);&lt;br /&gt;
return 0;}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Test Results:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-85.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After toggling the DIP switch to change the address, power on again.&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-83.jpg&amp;diff=5004</id>
		<title>File:CQRADDR001-83.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-83.jpg&amp;diff=5004"/>
				<updated>2026-01-29T04:15:12Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:I2C.rar&amp;diff=5003</id>
		<title>File:I2C.rar</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:I2C.rar&amp;diff=5003"/>
				<updated>2026-01-29T04:14:49Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-82.jpg&amp;diff=5002</id>
		<title>File:CQRADDR001-82.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-82.jpg&amp;diff=5002"/>
				<updated>2026-01-29T04:14:19Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=5001</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=5001"/>
				<updated>2026-01-29T04:13:54Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Raspberry Pi Example and Test Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-711.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-721.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-73.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-75.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Assuming the VCC is now 5V, set A3-A0 to the 1 0 0 0 mode (A3 inverting while A2-A0 not). This requires VOXRL/VCC to be 0.53125±0.015, general formula: [VCC/（R1+R2）]R1=VXORL. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Given the VCC of 5V and RLB of 100kΩ, the target VXORL should be 0.53125×5V=2.65625V. Substituting all parameters into the formula yields R2 ≈ 88.23529kΩ. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Since this calculated R2 is not the exact common resistance, it should be matched with the closest common resistance value and verified through formula validation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under this circumstance, the closest common resistance value to 88.23529kΩ is 86.6kΩ, so VXORL≈2.67953V, or VXORL/VCC≈0.53906. This ratio falls within 0.53125±0.015, making 86.6kΩ a suitable resistance value for RLT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-76.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-7.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Arduino Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  Wire.begin();&lt;br /&gt;
  Serial.println(&amp;quot;Scan available I2C devices:&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  for(int addr = 1; addr &amp;lt; 127; addr++) {&lt;br /&gt;
    Wire.beginTransmission(addr);&lt;br /&gt;
    if(Wire.endTransmission() == 0) {&lt;br /&gt;
      if(Wire.requestFrom(addr, (byte)1) &amp;gt; 0) {&lt;br /&gt;
        Serial.print(&amp;quot;✅ Available devices: 0x&amp;quot;);&lt;br /&gt;
        if(addr &amp;lt; 16) Serial.print(&amp;quot;0&amp;quot;);&lt;br /&gt;
        Serial.println(addr, HEX);&lt;br /&gt;
        while(Wire.available()) Wire.read();&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  delay(3000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Test Results:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-78.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set the serial port to 9600. Open the serial port debugger to view the bidirectional I2C address. After toggling the DIP switch to change the address, power on again. The new address will appear in the serial port debugger.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Raspberry Pi Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
'''First, visit the Raspberry Pi official website to download the system. You must select the download option in the frame below; otherwise, the sensor will not function properly.'''&lt;br /&gt;
&lt;br /&gt;
*Download link: https://www.raspberrypi.com/software/operating-systems/#raspberry-pi-os-legacy-64-bit&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-791.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Schematic Diagram of Raspberry Pi 4B pins:&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-80.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-81.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-82.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
Create a folder and a “.c” file, then write the code.&lt;br /&gt;
&lt;br /&gt;
[[Media: I2C.rar]]&lt;br /&gt;
&lt;br /&gt;
You can directly add to the compressed file.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-83.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
gcc -Wall -g -o I2C I2C.c -lm&lt;br /&gt;
&lt;br /&gt;
./I2C&lt;br /&gt;
&lt;br /&gt;
Go to the folder created in the terminal, use GCC cross-compilation and run the file.&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-81.jpg&amp;diff=5000</id>
		<title>File:CQRADDR001-81.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-81.jpg&amp;diff=5000"/>
				<updated>2026-01-29T04:07:21Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-80.jpg&amp;diff=4999</id>
		<title>File:CQRADDR001-80.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-80.jpg&amp;diff=4999"/>
				<updated>2026-01-29T04:06:52Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4998</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4998"/>
				<updated>2026-01-29T04:06:27Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Raspberry Pi Example and Test Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-711.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-721.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-73.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-75.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Assuming the VCC is now 5V, set A3-A0 to the 1 0 0 0 mode (A3 inverting while A2-A0 not). This requires VOXRL/VCC to be 0.53125±0.015, general formula: [VCC/（R1+R2）]R1=VXORL. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Given the VCC of 5V and RLB of 100kΩ, the target VXORL should be 0.53125×5V=2.65625V. Substituting all parameters into the formula yields R2 ≈ 88.23529kΩ. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Since this calculated R2 is not the exact common resistance, it should be matched with the closest common resistance value and verified through formula validation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under this circumstance, the closest common resistance value to 88.23529kΩ is 86.6kΩ, so VXORL≈2.67953V, or VXORL/VCC≈0.53906. This ratio falls within 0.53125±0.015, making 86.6kΩ a suitable resistance value for RLT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-76.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-7.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Arduino Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  Wire.begin();&lt;br /&gt;
  Serial.println(&amp;quot;Scan available I2C devices:&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  for(int addr = 1; addr &amp;lt; 127; addr++) {&lt;br /&gt;
    Wire.beginTransmission(addr);&lt;br /&gt;
    if(Wire.endTransmission() == 0) {&lt;br /&gt;
      if(Wire.requestFrom(addr, (byte)1) &amp;gt; 0) {&lt;br /&gt;
        Serial.print(&amp;quot;✅ Available devices: 0x&amp;quot;);&lt;br /&gt;
        if(addr &amp;lt; 16) Serial.print(&amp;quot;0&amp;quot;);&lt;br /&gt;
        Serial.println(addr, HEX);&lt;br /&gt;
        while(Wire.available()) Wire.read();&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  delay(3000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Test Results:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-78.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set the serial port to 9600. Open the serial port debugger to view the bidirectional I2C address. After toggling the DIP switch to change the address, power on again. The new address will appear in the serial port debugger.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Raspberry Pi Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
'''First, visit the Raspberry Pi official website to download the system. You must select the download option in the frame below; otherwise, the sensor will not function properly.'''&lt;br /&gt;
&lt;br /&gt;
*Download link: https://www.raspberrypi.com/software/operating-systems/#raspberry-pi-os-legacy-64-bit&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-791.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Schematic Diagram of Raspberry Pi 4B pins:&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-80.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-81.jpg|700px]]&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-791.jpg&amp;diff=4997</id>
		<title>File:CQRADDR001-791.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-791.jpg&amp;diff=4997"/>
				<updated>2026-01-29T04:02:46Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4996</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4996"/>
				<updated>2026-01-29T04:02:34Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Raspberry Pi Example and Test Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-711.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-721.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-73.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-75.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Assuming the VCC is now 5V, set A3-A0 to the 1 0 0 0 mode (A3 inverting while A2-A0 not). This requires VOXRL/VCC to be 0.53125±0.015, general formula: [VCC/（R1+R2）]R1=VXORL. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Given the VCC of 5V and RLB of 100kΩ, the target VXORL should be 0.53125×5V=2.65625V. Substituting all parameters into the formula yields R2 ≈ 88.23529kΩ. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Since this calculated R2 is not the exact common resistance, it should be matched with the closest common resistance value and verified through formula validation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under this circumstance, the closest common resistance value to 88.23529kΩ is 86.6kΩ, so VXORL≈2.67953V, or VXORL/VCC≈0.53906. This ratio falls within 0.53125±0.015, making 86.6kΩ a suitable resistance value for RLT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-76.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-7.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Arduino Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  Wire.begin();&lt;br /&gt;
  Serial.println(&amp;quot;Scan available I2C devices:&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  for(int addr = 1; addr &amp;lt; 127; addr++) {&lt;br /&gt;
    Wire.beginTransmission(addr);&lt;br /&gt;
    if(Wire.endTransmission() == 0) {&lt;br /&gt;
      if(Wire.requestFrom(addr, (byte)1) &amp;gt; 0) {&lt;br /&gt;
        Serial.print(&amp;quot;✅ Available devices: 0x&amp;quot;);&lt;br /&gt;
        if(addr &amp;lt; 16) Serial.print(&amp;quot;0&amp;quot;);&lt;br /&gt;
        Serial.println(addr, HEX);&lt;br /&gt;
        while(Wire.available()) Wire.read();&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  delay(3000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Test Results:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-78.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set the serial port to 9600. Open the serial port debugger to view the bidirectional I2C address. After toggling the DIP switch to change the address, power on again. The new address will appear in the serial port debugger.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Raspberry Pi Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
'''First, visit the Raspberry Pi official website to download the system. You must select the download option in the frame below; otherwise, the sensor will not function properly.'''&lt;br /&gt;
&lt;br /&gt;
Download link: https://www.raspberrypi.com/software/operating-systems/#raspberry-pi-os-legacy-64-bit&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-791.jpg|700px]]&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-79.jpg&amp;diff=4995</id>
		<title>File:CQRADDR001-79.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-79.jpg&amp;diff=4995"/>
				<updated>2026-01-29T04:01:22Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4994</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4994"/>
				<updated>2026-01-29T04:01:11Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Raspberry Pi Example and Test Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-711.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-721.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-73.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-75.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Assuming the VCC is now 5V, set A3-A0 to the 1 0 0 0 mode (A3 inverting while A2-A0 not). This requires VOXRL/VCC to be 0.53125±0.015, general formula: [VCC/（R1+R2）]R1=VXORL. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Given the VCC of 5V and RLB of 100kΩ, the target VXORL should be 0.53125×5V=2.65625V. Substituting all parameters into the formula yields R2 ≈ 88.23529kΩ. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Since this calculated R2 is not the exact common resistance, it should be matched with the closest common resistance value and verified through formula validation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under this circumstance, the closest common resistance value to 88.23529kΩ is 86.6kΩ, so VXORL≈2.67953V, or VXORL/VCC≈0.53906. This ratio falls within 0.53125±0.015, making 86.6kΩ a suitable resistance value for RLT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-76.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-7.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Arduino Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  Wire.begin();&lt;br /&gt;
  Serial.println(&amp;quot;Scan available I2C devices:&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  for(int addr = 1; addr &amp;lt; 127; addr++) {&lt;br /&gt;
    Wire.beginTransmission(addr);&lt;br /&gt;
    if(Wire.endTransmission() == 0) {&lt;br /&gt;
      if(Wire.requestFrom(addr, (byte)1) &amp;gt; 0) {&lt;br /&gt;
        Serial.print(&amp;quot;✅ Available devices: 0x&amp;quot;);&lt;br /&gt;
        if(addr &amp;lt; 16) Serial.print(&amp;quot;0&amp;quot;);&lt;br /&gt;
        Serial.println(addr, HEX);&lt;br /&gt;
        while(Wire.available()) Wire.read();&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  delay(3000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Test Results:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-78.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set the serial port to 9600. Open the serial port debugger to view the bidirectional I2C address. After toggling the DIP switch to change the address, power on again. The new address will appear in the serial port debugger.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Raspberry Pi Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
'''First, visit the Raspberry Pi official website to download the system. You must select the download option in the frame below; otherwise, the sensor will not function properly.'''&lt;br /&gt;
&lt;br /&gt;
Download link: https://www.raspberrypi.com/software/operating-systems/#raspberry-pi-os-legacy-64-bit&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-79.jpg|700px]]&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4993</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4993"/>
				<updated>2026-01-29T03:58:56Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Raspberry Pi Example and Test Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-711.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-721.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-73.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-75.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Assuming the VCC is now 5V, set A3-A0 to the 1 0 0 0 mode (A3 inverting while A2-A0 not). This requires VOXRL/VCC to be 0.53125±0.015, general formula: [VCC/（R1+R2）]R1=VXORL. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Given the VCC of 5V and RLB of 100kΩ, the target VXORL should be 0.53125×5V=2.65625V. Substituting all parameters into the formula yields R2 ≈ 88.23529kΩ. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Since this calculated R2 is not the exact common resistance, it should be matched with the closest common resistance value and verified through formula validation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under this circumstance, the closest common resistance value to 88.23529kΩ is 86.6kΩ, so VXORL≈2.67953V, or VXORL/VCC≈0.53906. This ratio falls within 0.53125±0.015, making 86.6kΩ a suitable resistance value for RLT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-76.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-7.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Arduino Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  Wire.begin();&lt;br /&gt;
  Serial.println(&amp;quot;Scan available I2C devices:&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  for(int addr = 1; addr &amp;lt; 127; addr++) {&lt;br /&gt;
    Wire.beginTransmission(addr);&lt;br /&gt;
    if(Wire.endTransmission() == 0) {&lt;br /&gt;
      if(Wire.requestFrom(addr, (byte)1) &amp;gt; 0) {&lt;br /&gt;
        Serial.print(&amp;quot;✅ Available devices: 0x&amp;quot;);&lt;br /&gt;
        if(addr &amp;lt; 16) Serial.print(&amp;quot;0&amp;quot;);&lt;br /&gt;
        Serial.println(addr, HEX);&lt;br /&gt;
        while(Wire.available()) Wire.read();&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  delay(3000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Test Results:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-78.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set the serial port to 9600. Open the serial port debugger to view the bidirectional I2C address. After toggling the DIP switch to change the address, power on again. The new address will appear in the serial port debugger.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Raspberry Pi Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
'''First, visit the Raspberry Pi official website to download the system. You must select the download option in the frame below; otherwise, the sensor will not function properly.'''&lt;br /&gt;
&lt;br /&gt;
Download link: https://www.raspberrypi.com/software/operating-systems/#raspberry-pi-os-legacy-64-bit&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4992</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4992"/>
				<updated>2026-01-29T03:57:09Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Sample Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-711.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-721.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-73.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-75.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Assuming the VCC is now 5V, set A3-A0 to the 1 0 0 0 mode (A3 inverting while A2-A0 not). This requires VOXRL/VCC to be 0.53125±0.015, general formula: [VCC/（R1+R2）]R1=VXORL. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Given the VCC of 5V and RLB of 100kΩ, the target VXORL should be 0.53125×5V=2.65625V. Substituting all parameters into the formula yields R2 ≈ 88.23529kΩ. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Since this calculated R2 is not the exact common resistance, it should be matched with the closest common resistance value and verified through formula validation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under this circumstance, the closest common resistance value to 88.23529kΩ is 86.6kΩ, so VXORL≈2.67953V, or VXORL/VCC≈0.53906. This ratio falls within 0.53125±0.015, making 86.6kΩ a suitable resistance value for RLT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-76.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-7.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Arduino Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  Wire.begin();&lt;br /&gt;
  Serial.println(&amp;quot;Scan available I2C devices:&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  for(int addr = 1; addr &amp;lt; 127; addr++) {&lt;br /&gt;
    Wire.beginTransmission(addr);&lt;br /&gt;
    if(Wire.endTransmission() == 0) {&lt;br /&gt;
      if(Wire.requestFrom(addr, (byte)1) &amp;gt; 0) {&lt;br /&gt;
        Serial.print(&amp;quot;✅ Available devices: 0x&amp;quot;);&lt;br /&gt;
        if(addr &amp;lt; 16) Serial.print(&amp;quot;0&amp;quot;);&lt;br /&gt;
        Serial.println(addr, HEX);&lt;br /&gt;
        while(Wire.available()) Wire.read();&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  delay(3000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Test Results:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-78.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set the serial port to 9600. Open the serial port debugger to view the bidirectional I2C address. After toggling the DIP switch to change the address, power on again. The new address will appear in the serial port debugger.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Raspberry Pi Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4991</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4991"/>
				<updated>2026-01-29T03:56:59Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Arduino Example and Test Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-711.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-721.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-73.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-75.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Assuming the VCC is now 5V, set A3-A0 to the 1 0 0 0 mode (A3 inverting while A2-A0 not). This requires VOXRL/VCC to be 0.53125±0.015, general formula: [VCC/（R1+R2）]R1=VXORL. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Given the VCC of 5V and RLB of 100kΩ, the target VXORL should be 0.53125×5V=2.65625V. Substituting all parameters into the formula yields R2 ≈ 88.23529kΩ. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Since this calculated R2 is not the exact common resistance, it should be matched with the closest common resistance value and verified through formula validation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under this circumstance, the closest common resistance value to 88.23529kΩ is 86.6kΩ, so VXORL≈2.67953V, or VXORL/VCC≈0.53906. This ratio falls within 0.53125±0.015, making 86.6kΩ a suitable resistance value for RLT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-76.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-7.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Arduino Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  Wire.begin();&lt;br /&gt;
  Serial.println(&amp;quot;Scan available I2C devices:&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  for(int addr = 1; addr &amp;lt; 127; addr++) {&lt;br /&gt;
    Wire.beginTransmission(addr);&lt;br /&gt;
    if(Wire.endTransmission() == 0) {&lt;br /&gt;
      if(Wire.requestFrom(addr, (byte)1) &amp;gt; 0) {&lt;br /&gt;
        Serial.print(&amp;quot;✅ Available devices: 0x&amp;quot;);&lt;br /&gt;
        if(addr &amp;lt; 16) Serial.print(&amp;quot;0&amp;quot;);&lt;br /&gt;
        Serial.println(addr, HEX);&lt;br /&gt;
        while(Wire.available()) Wire.read();&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  delay(3000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Test Results:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-78.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set the serial port to 9600. Open the serial port debugger to view the bidirectional I2C address. After toggling the DIP switch to change the address, power on again. The new address will appear in the serial port debugger.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Raspberry Pi Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Sample Code'''==&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4990</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4990"/>
				<updated>2026-01-29T03:34:12Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Arduino Example and Test Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-711.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-721.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-73.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-75.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Assuming the VCC is now 5V, set A3-A0 to the 1 0 0 0 mode (A3 inverting while A2-A0 not). This requires VOXRL/VCC to be 0.53125±0.015, general formula: [VCC/（R1+R2）]R1=VXORL. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Given the VCC of 5V and RLB of 100kΩ, the target VXORL should be 0.53125×5V=2.65625V. Substituting all parameters into the formula yields R2 ≈ 88.23529kΩ. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Since this calculated R2 is not the exact common resistance, it should be matched with the closest common resistance value and verified through formula validation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under this circumstance, the closest common resistance value to 88.23529kΩ is 86.6kΩ, so VXORL≈2.67953V, or VXORL/VCC≈0.53906. This ratio falls within 0.53125±0.015, making 86.6kΩ a suitable resistance value for RLT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-76.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-7.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Arduino Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  Wire.begin();&lt;br /&gt;
  Serial.println(&amp;quot;Scan available I2C devices:&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  for(int addr = 1; addr &amp;lt; 127; addr++) {&lt;br /&gt;
    Wire.beginTransmission(addr);&lt;br /&gt;
    if(Wire.endTransmission() == 0) {&lt;br /&gt;
      if(Wire.requestFrom(addr, (byte)1) &amp;gt; 0) {&lt;br /&gt;
        Serial.print(&amp;quot;✅ Available devices: 0x&amp;quot;);&lt;br /&gt;
        if(addr &amp;lt; 16) Serial.print(&amp;quot;0&amp;quot;);&lt;br /&gt;
        Serial.println(addr, HEX);&lt;br /&gt;
        while(Wire.available()) Wire.read();&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  delay(3000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Test Results:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-78.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set the serial port to 9600. Open the serial port debugger to view the bidirectional I2C address. After toggling the DIP switch to change the address, power on again. The new address will appear in the serial port debugger.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Sample Code'''==&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-78.jpg&amp;diff=4989</id>
		<title>File:CQRADDR001-78.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-78.jpg&amp;diff=4989"/>
				<updated>2026-01-29T03:33:38Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-77.jpg&amp;diff=4988</id>
		<title>File:CQRADDR001-77.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-77.jpg&amp;diff=4988"/>
				<updated>2026-01-29T03:31:27Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4987</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4987"/>
				<updated>2026-01-29T03:30:27Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Connections and Examples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-711.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-721.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-73.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-75.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Assuming the VCC is now 5V, set A3-A0 to the 1 0 0 0 mode (A3 inverting while A2-A0 not). This requires VOXRL/VCC to be 0.53125±0.015, general formula: [VCC/（R1+R2）]R1=VXORL. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Given the VCC of 5V and RLB of 100kΩ, the target VXORL should be 0.53125×5V=2.65625V. Substituting all parameters into the formula yields R2 ≈ 88.23529kΩ. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Since this calculated R2 is not the exact common resistance, it should be matched with the closest common resistance value and verified through formula validation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under this circumstance, the closest common resistance value to 88.23529kΩ is 86.6kΩ, so VXORL≈2.67953V, or VXORL/VCC≈0.53906. This ratio falls within 0.53125±0.015, making 86.6kΩ a suitable resistance value for RLT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-76.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-7.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=='''Arduino Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  Wire.begin();&lt;br /&gt;
  Serial.println(&amp;quot;Scan available I2C devices:&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  for(int addr = 1; addr &amp;lt; 127; addr++) {&lt;br /&gt;
    Wire.beginTransmission(addr);&lt;br /&gt;
    if(Wire.endTransmission() == 0) {&lt;br /&gt;
      if(Wire.requestFrom(addr, (byte)1) &amp;gt; 0) {&lt;br /&gt;
        Serial.print(&amp;quot;✅ Available devices: 0x&amp;quot;);&lt;br /&gt;
        if(addr &amp;lt; 16) Serial.print(&amp;quot;0&amp;quot;);&lt;br /&gt;
        Serial.println(addr, HEX);&lt;br /&gt;
        while(Wire.available()) Wire.read();&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  delay(3000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Test Results:'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADDR001-78.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
Set the serial port to 9600. Open the serial port debugger to view the bidirectional I2C address. After toggling the DIP switch to change the address, power on again. The new address will appear in the serial port debugger.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Sample Code'''==&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4986</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4986"/>
				<updated>2026-01-29T03:24:03Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Connections and Examples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-711.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-721.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-73.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-75.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Assuming the VCC is now 5V, set A3-A0 to the 1 0 0 0 mode (A3 inverting while A2-A0 not). This requires VOXRL/VCC to be 0.53125±0.015, general formula: [VCC/（R1+R2）]R1=VXORL. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Given the VCC of 5V and RLB of 100kΩ, the target VXORL should be 0.53125×5V=2.65625V. Substituting all parameters into the formula yields R2 ≈ 88.23529kΩ. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Since this calculated R2 is not the exact common resistance, it should be matched with the closest common resistance value and verified through formula validation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under this circumstance, the closest common resistance value to 88.23529kΩ is 86.6kΩ, so VXORL≈2.67953V, or VXORL/VCC≈0.53906. This ratio falls within 0.53125±0.015, making 86.6kΩ a suitable resistance value for RLT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-76.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-7.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Sample Code'''==&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4985</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4985"/>
				<updated>2026-01-29T03:21:39Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Address Configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-711.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-721.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-73.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-75.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Assuming the VCC is now 5V, set A3-A0 to the 1 0 0 0 mode (A3 inverting while A2-A0 not). This requires VOXRL/VCC to be 0.53125±0.015, general formula: [VCC/（R1+R2）]R1=VXORL. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Given the VCC of 5V and RLB of 100kΩ, the target VXORL should be 0.53125×5V=2.65625V. Substituting all parameters into the formula yields R2 ≈ 88.23529kΩ. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Since this calculated R2 is not the exact common resistance, it should be matched with the closest common resistance value and verified through formula validation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under this circumstance, the closest common resistance value to 88.23529kΩ is 86.6kΩ, so VXORL≈2.67953V, or VXORL/VCC≈0.53906. This ratio falls within 0.53125±0.015, making 86.6kΩ a suitable resistance value for RLT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-76.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-7.jpg|1100px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-8.jpg|1050px|right]]&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Sample Code'''==&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4984</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4984"/>
				<updated>2026-01-29T03:20:59Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Address Configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-711.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-721.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-73.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-75.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Assuming the VCC is now 5V, set A3-A0 to the 1 0 0 0 mode (A3 inverting while A2-A0 not). This requires VOXRL/VCC to be 0.53125±0.015, general formula: [VCC/（R1+R2）]R1=VXORL. &lt;br /&gt;
&lt;br /&gt;
Given the VCC of 5V and RLB of 100kΩ, the target VXORL should be 0.53125×5V=2.65625V. Substituting all parameters into the formula yields R2 ≈ 88.23529kΩ. &lt;br /&gt;
&lt;br /&gt;
Since this calculated R2 is not the exact common resistance, it should be matched with the closest common resistance value and verified through formula validation.&lt;br /&gt;
&lt;br /&gt;
Under this circumstance, the closest common resistance value to 88.23529kΩ is 86.6kΩ, so VXORL≈2.67953V, or VXORL/VCC≈0.53906. This ratio falls within 0.53125±0.015, making 86.6kΩ a suitable resistance value for RLT.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-76.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-7.jpg|1100px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-8.jpg|1050px|right]]&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Sample Code'''==&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-75.jpg&amp;diff=4983</id>
		<title>File:CQRADDR001-75.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-75.jpg&amp;diff=4983"/>
				<updated>2026-01-29T03:20:19Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-73.jpg&amp;diff=4982</id>
		<title>File:CQRADDR001-73.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-73.jpg&amp;diff=4982"/>
				<updated>2026-01-29T03:20:00Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4981</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4981"/>
				<updated>2026-01-29T03:18:54Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Address Configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-711.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-721.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-73.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-75.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
Assuming the VCC is now 5V, set A3-A0 to the 1 0 0 0 mode (A3 inverting while A2-A0 not). This requires VOXRL/VCC to be 0.53125±0.015, general formula: [VCC/（R1+R2）]R1=VXORL. &lt;br /&gt;
&lt;br /&gt;
Given the VCC of 5V and RLB of 100kΩ, the target VXORL should be 0.53125×5V=2.65625V. Substituting all parameters into the formula yields R2 ≈ 88.23529kΩ. &lt;br /&gt;
&lt;br /&gt;
Since this calculated R2 is not the exact common resistance, it should be matched with the closest common resistance value and verified through formula validation.&lt;br /&gt;
&lt;br /&gt;
Under this circumstance, the closest common resistance value to 88.23529kΩ is 86.6kΩ, so VXORL≈2.67953V, or VXORL/VCC≈0.53906. This ratio falls within 0.53125±0.015, making 86.6kΩ a suitable resistance value for RLT.&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-76.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-7.jpg|1100px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-8.jpg|1050px|right]]&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Sample Code'''==&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-721.jpg&amp;diff=4980</id>
		<title>File:CQRADDR001-721.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-721.jpg&amp;diff=4980"/>
				<updated>2026-01-29T03:17:45Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-711.jpg&amp;diff=4979</id>
		<title>File:CQRADDR001-711.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-711.jpg&amp;diff=4979"/>
				<updated>2026-01-29T03:17:23Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4978</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4978"/>
				<updated>2026-01-29T03:17:04Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Address Configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-711.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-721.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
Assuming the VCC is now 5V, set A3-A0 to the 1 0 0 0 mode (A3 inverting while A2-A0 not). This requires VOXRL/VCC to be 0.53125±0.015, general formula: [VCC/（R1+R2）]R1=VXORL. &lt;br /&gt;
&lt;br /&gt;
Given the VCC of 5V and RLB of 100kΩ, the target VXORL should be 0.53125×5V=2.65625V. Substituting all parameters into the formula yields R2 ≈ 88.23529kΩ. &lt;br /&gt;
&lt;br /&gt;
Since this calculated R2 is not the exact common resistance, it should be matched with the closest common resistance value and verified through formula validation.&lt;br /&gt;
&lt;br /&gt;
Under this circumstance, the closest common resistance value to 88.23529kΩ is 86.6kΩ, so VXORL≈2.67953V, or VXORL/VCC≈0.53906. This ratio falls within 0.53125±0.015, making 86.6kΩ a suitable resistance value for RLT.&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-76.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-7.jpg|1100px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-8.jpg|1050px|right]]&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Sample Code'''==&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-76.jpg&amp;diff=4977</id>
		<title>File:CQRADDR001-76.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-76.jpg&amp;diff=4977"/>
				<updated>2026-01-29T03:07:15Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4976</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4976"/>
				<updated>2026-01-29T03:03:52Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Address Configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-71.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-72.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
Assuming the VCC is now 5V, set A3-A0 to the 1 0 0 0 mode (A3 inverting while A2-A0 not). This requires VOXRL/VCC to be 0.53125±0.015, general formula: [VCC/（R1+R2）]R1=VXORL. &lt;br /&gt;
&lt;br /&gt;
Given the VCC of 5V and RLB of 100kΩ, the target VXORL should be 0.53125×5V=2.65625V. Substituting all parameters into the formula yields R2 ≈ 88.23529kΩ. &lt;br /&gt;
&lt;br /&gt;
Since this calculated R2 is not the exact common resistance, it should be matched with the closest common resistance value and verified through formula validation.&lt;br /&gt;
&lt;br /&gt;
Under this circumstance, the closest common resistance value to 88.23529kΩ is 86.6kΩ, so VXORL≈2.67953V, or VXORL/VCC≈0.53906. This ratio falls within 0.53125±0.015, making 86.6kΩ a suitable resistance value for RLT.&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-76.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-7.jpg|1100px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-8.jpg|1050px|right]]&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Sample Code'''==&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4975</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4975"/>
				<updated>2026-01-29T02:59:43Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Address Configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-71.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-72.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
Assuming the VCC is now 5V, set A3-A0 to the 1 0 0 0 mode (A3 inverting while A2-A0 not). This requires VOXRL/VCC to be 0.53125±0.015, general formula: [VCC/（R1+R2）]R1=VXORL. &lt;br /&gt;
&lt;br /&gt;
Given the VCC of 5V and RLB of 100kΩ, the target VXORL should be 0.53125×5V=2.65625V. Substituting all parameters into the formula yields R2 ≈ 88.23529kΩ. &lt;br /&gt;
&lt;br /&gt;
Since this calculated R2 is not the exact common resistance, it should be matched with the closest common resistance value and verified through formula validation.&lt;br /&gt;
&lt;br /&gt;
Under this circumstance, the closest common resistance value to 88.23529kΩ is 86.6kΩ, so VXORL≈2.67953V, or VXORL/VCC≈0.53906. This ratio falls within 0.53125±0.015, making 86.6kΩ a suitable resistance value for RLT.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-7.jpg|1100px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-8.jpg|1050px|right]]&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Sample Code'''==&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4974</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4974"/>
				<updated>2026-01-28T08:04:23Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Address Configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-71.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-72.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''How to determine the resistance of welding resistor:'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, based on the data sheet, the module determines whether a specific bit in the I2C address is inverted by the voltage of the XORH or XORL pins (i.e., VXORH or VORL relative to VCC). In Table 2 and 3, a bit value of 1 indicates inversion, while 0 indicates no inversion.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-7.jpg|1100px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-8.jpg|1050px|right]]&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Sample Code'''==&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-72.jpg&amp;diff=4973</id>
		<title>File:CQRADDR001-72.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-72.jpg&amp;diff=4973"/>
				<updated>2026-01-28T08:01:57Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4972</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4972"/>
				<updated>2026-01-28T08:01:44Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Address Configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-71.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-72.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-7.jpg|1100px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-8.jpg|1050px|right]]&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Sample Code'''==&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4971</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4971"/>
				<updated>2026-01-28T08:00:34Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Address Configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-71.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-7.jpg|1100px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-8.jpg|1050px|right]]&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Sample Code'''==&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-71.jpg&amp;diff=4970</id>
		<title>File:CQRADDR001-71.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:CQRADDR001-71.jpg&amp;diff=4970"/>
				<updated>2026-01-28T07:59:45Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4969</id>
		<title>I2C Address Converter Module SKU: CQRADDR001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=I2C_Address_Converter_Module_SKU:_CQRADDR001&amp;diff=4969"/>
				<updated>2026-01-28T07:59:18Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Address Configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADDR001.jpg|thumb|200px|right|I2C Address Converter Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
LTC4316 I2C Address Translation Module is a practical I2C bus expansion tool designed to resolve I2C device address conflicts. This module can translate the fixed hardware address of an I2C device into a different communication address, enabling multiple devices with identical addresses to operate simultaneously on the same I2C bus.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''Efficient Address Conflict Solution:''' Based on the LTC4316IMS chip, it can translate the fixed hardware address of an I2C device into 127 distinct communication addresses, effectively resolving address conflicts on the I2C bus.&lt;br /&gt;
*'''Wide Voltage Operating Range:''' Supports power supply voltages from 2.25V to 5.5V, ensuring compatibility with various logic level systems.&lt;br /&gt;
*'''Hardware-Level Transparent Translation:''' Configures address offsets through a resistive voltage divider network and performs real-time address translation, remaining entirely transparent to both master and slave devices.&lt;br /&gt;
*'''Flexible Address Configuration:''' Enables independent configuration of the high 3-bit and low 4-bit address offsets via the XORH/XORL pins using resistor voltage division, with support for quick switching via DIP switches.&lt;br /&gt;
*'''Industrial-Grade Protection Design:''' Features separate interfaces for the master side (SCLIN/SDAIN) and slave side (SCLOUT/SDAOUT), providing clear signal flow isolation.&lt;br /&gt;
*'''Standard Interface Compatibility:''' Equipped with dual interfaces—HY2.0mm 4P connectors and 2.54mm pin headers—for easy connection to various development boards and sensor modules.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADDR001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADDR001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-4.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADDR001-5-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Address Configuration'''==&lt;br /&gt;
&lt;br /&gt;
The module sets the address conversion value through voltage divider resistors at the XORH and XORL pins.&lt;br /&gt;
&lt;br /&gt;
[[image:CQRADDR001-71.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-7.jpg|1100px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADDR001-8.jpg|1050px|right]]&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Sample Code'''==&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:CQRADC001-821.jpg&amp;diff=4968</id>
		<title>File:CQRADC001-821.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:CQRADC001-821.jpg&amp;diff=4968"/>
				<updated>2026-01-27T08:46:41Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=4-CH_16-Bit_ADS1115_ADC_Module_SKU:_CQRADC001&amp;diff=4967</id>
		<title>4-CH 16-Bit ADS1115 ADC Module SKU: CQRADC001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=4-CH_16-Bit_ADS1115_ADC_Module_SKU:_CQRADC001&amp;diff=4967"/>
				<updated>2026-01-27T08:46:25Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Used in Conjunction with the TDS Meter Sensor (SKU: CQRSENTDS01 / ASIN: B08KXRHK7H) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADC001.jpg|thumb|200px|right|4-CH 16-Bit ADS1115 ADC Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
The 4-channel 16-bit ADS1115 ADC Module is a high-precision analog-to-digital conversion solution based on the TI ADS1115IDGSR chip. This module provides four 16-bit precision analog input channels, supports both 3.3V and 5V operation, and features a hardware-configurable I2C address. The module also integrates an NTC temperature measurement interface, enabling multi-channel signal acquisition and temperature monitoring.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''High-Precision 16-bit ADC Chip:''' Based on the TI ADS1115IDGSR chip, it provides four 16-bit resolution analog input channels, enabling high-precision signal acquisition.&lt;br /&gt;
*'''Flexible Input Modes:''' Supports 4 single-ended inputs or 2 differential inputs, suitable for various sensor signal measurement scenarios.&lt;br /&gt;
*'''Configurable I2C Address:''' Configurable via the ADDR pin, supporting 4 I2C addresses to facilitate multi-device networking.&lt;br /&gt;
*'''Wide Sampling Rate Range:''' Supports programmable sampling rates from 8 SPS to 860 SPS, meeting the requirements of different applications.&lt;br /&gt;
*'''Integrated NTC Temperature Measurement Interface:''' Onboard MF52AT 10KΩ NTC temperature sensor interface with a B value of 3950K, ideal for temperature monitoring applications.&lt;br /&gt;
*'''Dual-Voltage Compatible Design:''' Supports 3.3V/5V dual-voltage operation, with a built-in LP5907 LDO providing stable 3.3V power.&lt;br /&gt;
*'''Automatic Level Conversion:''' I2C signals are automatically converted to 3.3V levels when powered by 5V, allowing direct connection to 3.3V microcontrollers.&lt;br /&gt;
*'''Standard Interface Design:''' Equipped with HY2.0mm 4P connectors and 2.54mm pin headers for easy connection to various development boards.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADC001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADC001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADC001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADC001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADC001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADC001-8.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADC001-4-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Power Supply and Sensor Compatibility'''==&lt;br /&gt;
This module supports dual-voltage operation at 3.3V/5V. When powered at 3.3V, all I/Os are at 3.3V level; when powered at 5V, the I2C signals are automatically converted to 3.3V for communication with the host, while also allowing measurement of 5V sensor signals. The module includes built-in protection circuits to prevent damage from overvoltage and provides a 3.3V LDO output to power external sensors.&lt;br /&gt;
&lt;br /&gt;
Important: When measuring 5V sensors, the module must be powered at 5V. In this case, the I2C signals remain at 3.3V level and can be directly connected to 3.3V host GPIO. Note that the SDA and SCL pins on this module are limited to 3.3V.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
*'''Configuration Method:'''&lt;br /&gt;
Use a jumper cap to connect the ADDR pin to the corresponding voltage level point. After configuration, restart the power for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
*'''Using an I2C Address Conversion Module for Configuration:'''&lt;br /&gt;
When using an I2C address conversion module, all ADS1115 modules can be set to the same hardware address. Address differentiation is achieved by selecting channels on the conversion module, eliminating the need to modify hardware jumper configurations.&lt;br /&gt;
[[image:CQRADC001-5.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
=='''Arduino Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-72.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Adafruit_ADS1X15.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adafruit_ADS1115 ads;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  ads.begin(0x48);&lt;br /&gt;
  ads.setGain(GAIN_ONE);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  int16_t adc = ads.readADC_SingleEnded(0);&lt;br /&gt;
  float voltage = adc * 0.125 / 1000.0;&lt;br /&gt;
  float ntc_r = (3.3 * 10000.0 / voltage) - 20000.0;&lt;br /&gt;
  float temp = 1.0 / (log(ntc_r / 10000.0) / 3950.0 + 1.0 / 298.15) - 273.15;&lt;br /&gt;
  &lt;br /&gt;
  Serial.print(&amp;quot;Temp: &amp;quot;);&lt;br /&gt;
  Serial.print(temp, 1);&lt;br /&gt;
  Serial.println(&amp;quot;C&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Example Results Explanation:'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-711.jpg|600px]]&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the I2C address to 0x48. You can modify this line of code as needed: ads.begin(0x48).&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the input channel to AIN0. You can modify this line of code as needed: int16_t adc = ads.readADC_SingleEnded(0).&lt;br /&gt;
&lt;br /&gt;
*To use the 5V measurement device, replace the conversion formula with the following:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
float ntc_r = (5.0 * 10000.0 / voltage) - 20000.0;  // Modify to 5V&lt;br /&gt;
&lt;br /&gt;
float temp = 1.0 / (log(ntc_r / 10000.0) / 3950.0 + 1.0 / 298.15) - 273.15;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Raspberry Pi Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-76.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-73.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
'''Raspberry Pi 4B Pinout Diagram'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-75.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Create a folder and a “.c” file, then write the code.&lt;br /&gt;
&lt;br /&gt;
[[Media: ADS1115.zip]]&lt;br /&gt;
&lt;br /&gt;
*You can directly add to the compressed file.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-781.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
gcc -Wall -g -o ADS1115 ADS1115.c -lm&lt;br /&gt;
&lt;br /&gt;
./ADS1115&lt;br /&gt;
&lt;br /&gt;
Go to the folder created in the terminal, use GCC cross-compilation and run the file.&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/ioctl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;linux/i2c-dev.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define ADS1115_ADDR 0x48&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int fd = open(&amp;quot;/dev/i2c-1&amp;quot;, O_RDWR);&lt;br /&gt;
    if (fd &amp;lt; 0) return 1;&lt;br /&gt;
    if (ioctl(fd, I2C_SLAVE, ADS1115_ADDR) &amp;lt; 0) return 1;&lt;br /&gt;
    &lt;br /&gt;
    while(1) {&lt;br /&gt;
        unsigned char config[3] = {0x01, 0xC2, 0x83};&lt;br /&gt;
        unsigned char result[2];&lt;br /&gt;
        &lt;br /&gt;
        write(fd, config, 3);&lt;br /&gt;
        usleep(8000);&lt;br /&gt;
        &lt;br /&gt;
        unsigned char reg[1] = {0x00};&lt;br /&gt;
        write(fd, reg, 1);&lt;br /&gt;
        read(fd, result, 2);&lt;br /&gt;
        &lt;br /&gt;
        int16_t adc = (result[0] &amp;lt;&amp;lt; 8) | result[1];&lt;br /&gt;
        float voltage = adc * 0.125 / 1000.0;&lt;br /&gt;
        float ntc_r = (3.3 * 10000.0 / voltage) - 20000.0;&lt;br /&gt;
        float temp = 1.0 / (log(ntc_r / 10000.0) / 3950.0 + 1.0 / 298.15) - 273.15;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Temp: %.1fC\n&amp;quot;, temp);&lt;br /&gt;
        sleep(1);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Test Results:&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-791.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the I2C address to 0x48. You can modify this line of code as needed: #define ADS1115_ADDR 0x48.&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the input channel to AIN0. You can replace it with the following code based on actual needs:&lt;br /&gt;
&lt;br /&gt;
AIN0: 0xC2&lt;br /&gt;
&lt;br /&gt;
AIN1: 0xD2&lt;br /&gt;
&lt;br /&gt;
AIN2: 0xE2 &lt;br /&gt;
&lt;br /&gt;
AIN3: 0xF2&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Used in Conjunction with the TDS Meter Sensor (SKU: CQRSENTDS01 / ASIN: B08KXRHK7H)'''==&lt;br /&gt;
[[image:CQRADC001-7.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
*'''Sample Program'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-80.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Create a folder and a “.c” file, then write the code.&lt;br /&gt;
&lt;br /&gt;
[[Media: ADSTDS.zip]]&lt;br /&gt;
&lt;br /&gt;
*You can directly add to the compressed file.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-811.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
gcc -o ADSTDS ADSTDS.c -lwiringPi&lt;br /&gt;
&lt;br /&gt;
./ADSTDS&lt;br /&gt;
&lt;br /&gt;
Go to the folder created in the terminal, use GCC cross-compilation and run the file.&lt;br /&gt;
&lt;br /&gt;
*'''Example Code'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;wiringPi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;wiringPiI2C.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define VREF 5.0f           &lt;br /&gt;
#define SCOUNT 30           // Sampling points&lt;br /&gt;
#define TEMPERATURE 25.0f   // Water temperature (Celsius)&lt;br /&gt;
&lt;br /&gt;
int analogBuffer[SCOUNT];        &lt;br /&gt;
int analogBufferTemp[SCOUNT];&lt;br /&gt;
int analogBufferIndex = 0;&lt;br /&gt;
float averageVoltage = 0, tdsValue = 0;&lt;br /&gt;
&lt;br /&gt;
int ads1115_fd;&lt;br /&gt;
// Function declarations&lt;br /&gt;
int getMedianNum(int bArray[], int iFilterLen);&lt;br /&gt;
int readADS1115();&lt;br /&gt;
unsigned long my_millis();  &lt;br /&gt;
&lt;br /&gt;
unsigned long my_millis() {&lt;br /&gt;
    struct timespec ts;&lt;br /&gt;
    clock_gettime(CLOCK_MONOTONIC, &amp;amp;ts);&lt;br /&gt;
    return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int getMedianNum(int bArray[], int iFilterLen) {&lt;br /&gt;
    int bTab[iFilterLen];&lt;br /&gt;
    for (int i = 0; i &amp;lt; iFilterLen; i++) {&lt;br /&gt;
        bTab[i] = bArray[i];&lt;br /&gt;
    }&lt;br /&gt;
    int i, j, bTemp;&lt;br /&gt;
    for (j = 0; j &amp;lt; iFilterLen - 1; j++) {&lt;br /&gt;
        for (i = 0; i &amp;lt; iFilterLen - j - 1; i++) {&lt;br /&gt;
            if (bTab[i] &amp;gt; bTab[i + 1]) {&lt;br /&gt;
                bTemp = bTab[i];&lt;br /&gt;
                bTab[i] = bTab[i + 1];&lt;br /&gt;
                bTab[i + 1] = bTemp;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if ((iFilterLen &amp;amp; 1) &amp;gt; 0) {&lt;br /&gt;
        bTemp = bTab[(iFilterLen - 1) / 2];&lt;br /&gt;
    } else {&lt;br /&gt;
        bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;&lt;br /&gt;
    }&lt;br /&gt;
    return bTemp;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int readADS1115() {&lt;br /&gt;
    // Configure ADS1115: Channel 0&lt;br /&gt;
    uint16_t config = 0xC283;  &lt;br /&gt;
    wiringPiI2CWriteReg16(ads1115_fd, 0x01, (config &amp;gt;&amp;gt; 8) | (config &amp;lt;&amp;lt; 8));&lt;br /&gt;
    usleep(8000);  &lt;br /&gt;
    &lt;br /&gt;
    uint16_t result = wiringPiI2CReadReg16(ads1115_fd, 0x00);&lt;br /&gt;
    int16_t adc = ((result &amp;gt;&amp;gt; 8) &amp;amp; 0xFF) | ((result &amp;amp; 0xFF) &amp;lt;&amp;lt; 8);&lt;br /&gt;
    &lt;br /&gt;
 &lt;br /&gt;
    static int debug_count = 0;&lt;br /&gt;
    if (debug_count++ % 20 == 0) {&lt;br /&gt;
        printf(&amp;quot;[Raw ADC: %d] &amp;quot;, adc);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    int adc_abs = abs(adc);&lt;br /&gt;
    // Convert to analog value (0-1023)&lt;br /&gt;
    int arduino_value = (adc_abs * 1024) / 30000;&lt;br /&gt;
    // Limit to 0-1023 range&lt;br /&gt;
    if (arduino_value &amp;gt; 1023) arduino_value = 1023;&lt;br /&gt;
    if (arduino_value &amp;lt; 0) arduino_value = 0;&lt;br /&gt;
    return arduino_value;&lt;br /&gt;
}&lt;br /&gt;
int main() {&lt;br /&gt;
    printf(&amp;quot;=== Raspberry Pi TDS Measurement ===\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;TDS = 133.42*V^3 - 255.86*V^2 + 857.39*V * 0.5\n\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // Initialize wiringPi&lt;br /&gt;
    if (wiringPiSetup() &amp;lt; 0) {&lt;br /&gt;
        printf(&amp;quot;wiringPi initialization failed\n&amp;quot;);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Initialize ADS1115&lt;br /&gt;
    ads1115_fd = wiringPiI2CSetup(0x48);&lt;br /&gt;
    if (ads1115_fd &amp;lt; 0) {&lt;br /&gt;
        printf(&amp;quot;ADS1115 initialization failed (address 0x48)\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Please check: sudo i2cdetect -y 1\n&amp;quot;);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;✓ Hardware initialization completed\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Starting measurement...\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;----------------------------------------\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // Timepoint variables (using custom my_millis)&lt;br /&gt;
    unsigned long analogSampleTimepoint = my_millis();&lt;br /&gt;
    unsigned long printTimepoint = my_millis();&lt;br /&gt;
    &lt;br /&gt;
    while (1) {&lt;br /&gt;
        unsigned long currentMillis = my_millis();     &lt;br /&gt;
        if (currentMillis - analogSampleTimepoint &amp;gt; 40U) {&lt;br /&gt;
            analogSampleTimepoint = currentMillis;&lt;br /&gt;
            &lt;br /&gt;
            int arduinoValue = readADS1115();&lt;br /&gt;
            &lt;br /&gt;
            analogBuffer[analogBufferIndex] = arduinoValue;&lt;br /&gt;
            analogBufferIndex++;&lt;br /&gt;
            if (analogBufferIndex == SCOUNT) {&lt;br /&gt;
                analogBufferIndex = 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
         &lt;br /&gt;
        if (currentMillis - printTimepoint &amp;gt; 800U) {&lt;br /&gt;
            printTimepoint = currentMillis;&lt;br /&gt;
           &lt;br /&gt;
            for (int copyIndex = 0; copyIndex &amp;lt; SCOUNT; copyIndex++) {&lt;br /&gt;
                analogBufferTemp[copyIndex] = analogBuffer[copyIndex];&lt;br /&gt;
            }&lt;br /&gt;
   &lt;br /&gt;
            int medianValue = getMedianNum(analogBufferTemp, SCOUNT);&lt;br /&gt;
            averageVoltage = medianValue * VREF / 1024.0;&lt;br /&gt;
            float compensationCoefficient = 1.0 + 0.02 * (TEMPERATURE - 25.0);&lt;br /&gt;
            float compensationVoltage = averageVoltage / compensationCoefficient;&lt;br /&gt;
            tdsValue = (133.42 * compensationVoltage * compensationVoltage * compensationVoltage &lt;br /&gt;
                       - 255.86 * compensationVoltage * compensationVoltage &lt;br /&gt;
                       + 857.39 * compensationVoltage) * 0.5;&lt;br /&gt;
            printf(&amp;quot;TDS Value: %.0fppm&amp;quot;, tdsValue);&lt;br /&gt;
           &lt;br /&gt;
            printf(&amp;quot; (ADC:%d, Volt:%.3fV)\n&amp;quot;, medianValue, averageVoltage);&lt;br /&gt;
            &lt;br /&gt;
            fflush(stdout);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        usleep(1000);  &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Test Results:&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-821.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
The original ADC value represents the raw 16-bit analog-to-digital conversion data from the ADS1115. The ADC value is the stabilized output after median filtering. The voltage value is the calculated corresponding voltage. The TDS value indicates the dissolved solids content in the water. &lt;br /&gt;
&lt;br /&gt;
In this configuration, the I2C address is 0x48, and the analog port is AIN0.&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:CQRADC001-811.jpg&amp;diff=4966</id>
		<title>File:CQRADC001-811.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:CQRADC001-811.jpg&amp;diff=4966"/>
				<updated>2026-01-27T08:43:32Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=4-CH_16-Bit_ADS1115_ADC_Module_SKU:_CQRADC001&amp;diff=4965</id>
		<title>4-CH 16-Bit ADS1115 ADC Module SKU: CQRADC001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=4-CH_16-Bit_ADS1115_ADC_Module_SKU:_CQRADC001&amp;diff=4965"/>
				<updated>2026-01-27T08:43:15Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Used in Conjunction with the TDS Meter Sensor (SKU: CQRSENTDS01 / ASIN: B08KXRHK7H) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADC001.jpg|thumb|200px|right|4-CH 16-Bit ADS1115 ADC Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
The 4-channel 16-bit ADS1115 ADC Module is a high-precision analog-to-digital conversion solution based on the TI ADS1115IDGSR chip. This module provides four 16-bit precision analog input channels, supports both 3.3V and 5V operation, and features a hardware-configurable I2C address. The module also integrates an NTC temperature measurement interface, enabling multi-channel signal acquisition and temperature monitoring.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''High-Precision 16-bit ADC Chip:''' Based on the TI ADS1115IDGSR chip, it provides four 16-bit resolution analog input channels, enabling high-precision signal acquisition.&lt;br /&gt;
*'''Flexible Input Modes:''' Supports 4 single-ended inputs or 2 differential inputs, suitable for various sensor signal measurement scenarios.&lt;br /&gt;
*'''Configurable I2C Address:''' Configurable via the ADDR pin, supporting 4 I2C addresses to facilitate multi-device networking.&lt;br /&gt;
*'''Wide Sampling Rate Range:''' Supports programmable sampling rates from 8 SPS to 860 SPS, meeting the requirements of different applications.&lt;br /&gt;
*'''Integrated NTC Temperature Measurement Interface:''' Onboard MF52AT 10KΩ NTC temperature sensor interface with a B value of 3950K, ideal for temperature monitoring applications.&lt;br /&gt;
*'''Dual-Voltage Compatible Design:''' Supports 3.3V/5V dual-voltage operation, with a built-in LP5907 LDO providing stable 3.3V power.&lt;br /&gt;
*'''Automatic Level Conversion:''' I2C signals are automatically converted to 3.3V levels when powered by 5V, allowing direct connection to 3.3V microcontrollers.&lt;br /&gt;
*'''Standard Interface Design:''' Equipped with HY2.0mm 4P connectors and 2.54mm pin headers for easy connection to various development boards.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADC001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADC001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADC001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADC001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADC001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADC001-8.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADC001-4-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Power Supply and Sensor Compatibility'''==&lt;br /&gt;
This module supports dual-voltage operation at 3.3V/5V. When powered at 3.3V, all I/Os are at 3.3V level; when powered at 5V, the I2C signals are automatically converted to 3.3V for communication with the host, while also allowing measurement of 5V sensor signals. The module includes built-in protection circuits to prevent damage from overvoltage and provides a 3.3V LDO output to power external sensors.&lt;br /&gt;
&lt;br /&gt;
Important: When measuring 5V sensors, the module must be powered at 5V. In this case, the I2C signals remain at 3.3V level and can be directly connected to 3.3V host GPIO. Note that the SDA and SCL pins on this module are limited to 3.3V.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
*'''Configuration Method:'''&lt;br /&gt;
Use a jumper cap to connect the ADDR pin to the corresponding voltage level point. After configuration, restart the power for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
*'''Using an I2C Address Conversion Module for Configuration:'''&lt;br /&gt;
When using an I2C address conversion module, all ADS1115 modules can be set to the same hardware address. Address differentiation is achieved by selecting channels on the conversion module, eliminating the need to modify hardware jumper configurations.&lt;br /&gt;
[[image:CQRADC001-5.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
=='''Arduino Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-72.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Adafruit_ADS1X15.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adafruit_ADS1115 ads;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  ads.begin(0x48);&lt;br /&gt;
  ads.setGain(GAIN_ONE);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  int16_t adc = ads.readADC_SingleEnded(0);&lt;br /&gt;
  float voltage = adc * 0.125 / 1000.0;&lt;br /&gt;
  float ntc_r = (3.3 * 10000.0 / voltage) - 20000.0;&lt;br /&gt;
  float temp = 1.0 / (log(ntc_r / 10000.0) / 3950.0 + 1.0 / 298.15) - 273.15;&lt;br /&gt;
  &lt;br /&gt;
  Serial.print(&amp;quot;Temp: &amp;quot;);&lt;br /&gt;
  Serial.print(temp, 1);&lt;br /&gt;
  Serial.println(&amp;quot;C&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Example Results Explanation:'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-711.jpg|600px]]&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the I2C address to 0x48. You can modify this line of code as needed: ads.begin(0x48).&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the input channel to AIN0. You can modify this line of code as needed: int16_t adc = ads.readADC_SingleEnded(0).&lt;br /&gt;
&lt;br /&gt;
*To use the 5V measurement device, replace the conversion formula with the following:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
float ntc_r = (5.0 * 10000.0 / voltage) - 20000.0;  // Modify to 5V&lt;br /&gt;
&lt;br /&gt;
float temp = 1.0 / (log(ntc_r / 10000.0) / 3950.0 + 1.0 / 298.15) - 273.15;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Raspberry Pi Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-76.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-73.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
'''Raspberry Pi 4B Pinout Diagram'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-75.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Create a folder and a “.c” file, then write the code.&lt;br /&gt;
&lt;br /&gt;
[[Media: ADS1115.zip]]&lt;br /&gt;
&lt;br /&gt;
*You can directly add to the compressed file.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-781.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
gcc -Wall -g -o ADS1115 ADS1115.c -lm&lt;br /&gt;
&lt;br /&gt;
./ADS1115&lt;br /&gt;
&lt;br /&gt;
Go to the folder created in the terminal, use GCC cross-compilation and run the file.&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/ioctl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;linux/i2c-dev.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define ADS1115_ADDR 0x48&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int fd = open(&amp;quot;/dev/i2c-1&amp;quot;, O_RDWR);&lt;br /&gt;
    if (fd &amp;lt; 0) return 1;&lt;br /&gt;
    if (ioctl(fd, I2C_SLAVE, ADS1115_ADDR) &amp;lt; 0) return 1;&lt;br /&gt;
    &lt;br /&gt;
    while(1) {&lt;br /&gt;
        unsigned char config[3] = {0x01, 0xC2, 0x83};&lt;br /&gt;
        unsigned char result[2];&lt;br /&gt;
        &lt;br /&gt;
        write(fd, config, 3);&lt;br /&gt;
        usleep(8000);&lt;br /&gt;
        &lt;br /&gt;
        unsigned char reg[1] = {0x00};&lt;br /&gt;
        write(fd, reg, 1);&lt;br /&gt;
        read(fd, result, 2);&lt;br /&gt;
        &lt;br /&gt;
        int16_t adc = (result[0] &amp;lt;&amp;lt; 8) | result[1];&lt;br /&gt;
        float voltage = adc * 0.125 / 1000.0;&lt;br /&gt;
        float ntc_r = (3.3 * 10000.0 / voltage) - 20000.0;&lt;br /&gt;
        float temp = 1.0 / (log(ntc_r / 10000.0) / 3950.0 + 1.0 / 298.15) - 273.15;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Temp: %.1fC\n&amp;quot;, temp);&lt;br /&gt;
        sleep(1);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Test Results:&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-791.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the I2C address to 0x48. You can modify this line of code as needed: #define ADS1115_ADDR 0x48.&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the input channel to AIN0. You can replace it with the following code based on actual needs:&lt;br /&gt;
&lt;br /&gt;
AIN0: 0xC2&lt;br /&gt;
&lt;br /&gt;
AIN1: 0xD2&lt;br /&gt;
&lt;br /&gt;
AIN2: 0xE2 &lt;br /&gt;
&lt;br /&gt;
AIN3: 0xF2&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Used in Conjunction with the TDS Meter Sensor (SKU: CQRSENTDS01 / ASIN: B08KXRHK7H)'''==&lt;br /&gt;
[[image:CQRADC001-7.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
*'''Sample Program'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-80.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Create a folder and a “.c” file, then write the code.&lt;br /&gt;
&lt;br /&gt;
[[Media: ADSTDS.zip]]&lt;br /&gt;
&lt;br /&gt;
*You can directly add to the compressed file.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-811.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
gcc -o ADSTDS ADSTDS.c -lwiringPi&lt;br /&gt;
&lt;br /&gt;
./ADSTDS&lt;br /&gt;
&lt;br /&gt;
Go to the folder created in the terminal, use GCC cross-compilation and run the file.&lt;br /&gt;
&lt;br /&gt;
*'''Example Code'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;wiringPi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;wiringPiI2C.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define VREF 5.0f           &lt;br /&gt;
#define SCOUNT 30           // Sampling points&lt;br /&gt;
#define TEMPERATURE 25.0f   // Water temperature (Celsius)&lt;br /&gt;
&lt;br /&gt;
int analogBuffer[SCOUNT];        &lt;br /&gt;
int analogBufferTemp[SCOUNT];&lt;br /&gt;
int analogBufferIndex = 0;&lt;br /&gt;
float averageVoltage = 0, tdsValue = 0;&lt;br /&gt;
&lt;br /&gt;
int ads1115_fd;&lt;br /&gt;
// Function declarations&lt;br /&gt;
int getMedianNum(int bArray[], int iFilterLen);&lt;br /&gt;
int readADS1115();&lt;br /&gt;
unsigned long my_millis();  &lt;br /&gt;
&lt;br /&gt;
unsigned long my_millis() {&lt;br /&gt;
    struct timespec ts;&lt;br /&gt;
    clock_gettime(CLOCK_MONOTONIC, &amp;amp;ts);&lt;br /&gt;
    return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int getMedianNum(int bArray[], int iFilterLen) {&lt;br /&gt;
    int bTab[iFilterLen];&lt;br /&gt;
    for (int i = 0; i &amp;lt; iFilterLen; i++) {&lt;br /&gt;
        bTab[i] = bArray[i];&lt;br /&gt;
    }&lt;br /&gt;
    int i, j, bTemp;&lt;br /&gt;
    for (j = 0; j &amp;lt; iFilterLen - 1; j++) {&lt;br /&gt;
        for (i = 0; i &amp;lt; iFilterLen - j - 1; i++) {&lt;br /&gt;
            if (bTab[i] &amp;gt; bTab[i + 1]) {&lt;br /&gt;
                bTemp = bTab[i];&lt;br /&gt;
                bTab[i] = bTab[i + 1];&lt;br /&gt;
                bTab[i + 1] = bTemp;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if ((iFilterLen &amp;amp; 1) &amp;gt; 0) {&lt;br /&gt;
        bTemp = bTab[(iFilterLen - 1) / 2];&lt;br /&gt;
    } else {&lt;br /&gt;
        bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;&lt;br /&gt;
    }&lt;br /&gt;
    return bTemp;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int readADS1115() {&lt;br /&gt;
    // Configure ADS1115: Channel 0&lt;br /&gt;
    uint16_t config = 0xC283;  &lt;br /&gt;
    wiringPiI2CWriteReg16(ads1115_fd, 0x01, (config &amp;gt;&amp;gt; 8) | (config &amp;lt;&amp;lt; 8));&lt;br /&gt;
    usleep(8000);  &lt;br /&gt;
    &lt;br /&gt;
    uint16_t result = wiringPiI2CReadReg16(ads1115_fd, 0x00);&lt;br /&gt;
    int16_t adc = ((result &amp;gt;&amp;gt; 8) &amp;amp; 0xFF) | ((result &amp;amp; 0xFF) &amp;lt;&amp;lt; 8);&lt;br /&gt;
    &lt;br /&gt;
 &lt;br /&gt;
    static int debug_count = 0;&lt;br /&gt;
    if (debug_count++ % 20 == 0) {&lt;br /&gt;
        printf(&amp;quot;[Raw ADC: %d] &amp;quot;, adc);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    int adc_abs = abs(adc);&lt;br /&gt;
    // Convert to analog value (0-1023)&lt;br /&gt;
    int arduino_value = (adc_abs * 1024) / 30000;&lt;br /&gt;
    // Limit to 0-1023 range&lt;br /&gt;
    if (arduino_value &amp;gt; 1023) arduino_value = 1023;&lt;br /&gt;
    if (arduino_value &amp;lt; 0) arduino_value = 0;&lt;br /&gt;
    return arduino_value;&lt;br /&gt;
}&lt;br /&gt;
int main() {&lt;br /&gt;
    printf(&amp;quot;=== Raspberry Pi TDS Measurement ===\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;TDS = 133.42*V^3 - 255.86*V^2 + 857.39*V * 0.5\n\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // Initialize wiringPi&lt;br /&gt;
    if (wiringPiSetup() &amp;lt; 0) {&lt;br /&gt;
        printf(&amp;quot;wiringPi initialization failed\n&amp;quot;);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Initialize ADS1115&lt;br /&gt;
    ads1115_fd = wiringPiI2CSetup(0x48);&lt;br /&gt;
    if (ads1115_fd &amp;lt; 0) {&lt;br /&gt;
        printf(&amp;quot;ADS1115 initialization failed (address 0x48)\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Please check: sudo i2cdetect -y 1\n&amp;quot;);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;✓ Hardware initialization completed\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Starting measurement...\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;----------------------------------------\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // Timepoint variables (using custom my_millis)&lt;br /&gt;
    unsigned long analogSampleTimepoint = my_millis();&lt;br /&gt;
    unsigned long printTimepoint = my_millis();&lt;br /&gt;
    &lt;br /&gt;
    while (1) {&lt;br /&gt;
        unsigned long currentMillis = my_millis();     &lt;br /&gt;
        if (currentMillis - analogSampleTimepoint &amp;gt; 40U) {&lt;br /&gt;
            analogSampleTimepoint = currentMillis;&lt;br /&gt;
            &lt;br /&gt;
            int arduinoValue = readADS1115();&lt;br /&gt;
            &lt;br /&gt;
            analogBuffer[analogBufferIndex] = arduinoValue;&lt;br /&gt;
            analogBufferIndex++;&lt;br /&gt;
            if (analogBufferIndex == SCOUNT) {&lt;br /&gt;
                analogBufferIndex = 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
         &lt;br /&gt;
        if (currentMillis - printTimepoint &amp;gt; 800U) {&lt;br /&gt;
            printTimepoint = currentMillis;&lt;br /&gt;
           &lt;br /&gt;
            for (int copyIndex = 0; copyIndex &amp;lt; SCOUNT; copyIndex++) {&lt;br /&gt;
                analogBufferTemp[copyIndex] = analogBuffer[copyIndex];&lt;br /&gt;
            }&lt;br /&gt;
   &lt;br /&gt;
            int medianValue = getMedianNum(analogBufferTemp, SCOUNT);&lt;br /&gt;
            averageVoltage = medianValue * VREF / 1024.0;&lt;br /&gt;
            float compensationCoefficient = 1.0 + 0.02 * (TEMPERATURE - 25.0);&lt;br /&gt;
            float compensationVoltage = averageVoltage / compensationCoefficient;&lt;br /&gt;
            tdsValue = (133.42 * compensationVoltage * compensationVoltage * compensationVoltage &lt;br /&gt;
                       - 255.86 * compensationVoltage * compensationVoltage &lt;br /&gt;
                       + 857.39 * compensationVoltage) * 0.5;&lt;br /&gt;
            printf(&amp;quot;TDS Value: %.0fppm&amp;quot;, tdsValue);&lt;br /&gt;
           &lt;br /&gt;
            printf(&amp;quot; (ADC:%d, Volt:%.3fV)\n&amp;quot;, medianValue, averageVoltage);&lt;br /&gt;
            &lt;br /&gt;
            fflush(stdout);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        usleep(1000);  &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Test Results Explanation:'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-82.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
The raw ADC value is the raw 16-bit analog-to-digital conversion data from the ADS1115; the ADC value is the stable value after median filtering; the voltage value is the calculated corresponding voltage value; and the TDS value represents the total dissolved solids content of the water. The I2C address is 0x48; the analog port is AIN0.&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=4-CH_16-Bit_ADS1115_ADC_Module_SKU:_CQRADC001&amp;diff=4964</id>
		<title>4-CH 16-Bit ADS1115 ADC Module SKU: CQRADC001</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=4-CH_16-Bit_ADS1115_ADC_Module_SKU:_CQRADC001&amp;diff=4964"/>
				<updated>2026-01-27T08:40:16Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: /* Arduino Example and Test Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CQRADC001.jpg|thumb|200px|right|4-CH 16-Bit ADS1115 ADC Module]]&lt;br /&gt;
=='''Description'''==&lt;br /&gt;
The 4-channel 16-bit ADS1115 ADC Module is a high-precision analog-to-digital conversion solution based on the TI ADS1115IDGSR chip. This module provides four 16-bit precision analog input channels, supports both 3.3V and 5V operation, and features a hardware-configurable I2C address. The module also integrates an NTC temperature measurement interface, enabling multi-channel signal acquisition and temperature monitoring.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Features'''==&lt;br /&gt;
*'''High-Precision 16-bit ADC Chip:''' Based on the TI ADS1115IDGSR chip, it provides four 16-bit resolution analog input channels, enabling high-precision signal acquisition.&lt;br /&gt;
*'''Flexible Input Modes:''' Supports 4 single-ended inputs or 2 differential inputs, suitable for various sensor signal measurement scenarios.&lt;br /&gt;
*'''Configurable I2C Address:''' Configurable via the ADDR pin, supporting 4 I2C addresses to facilitate multi-device networking.&lt;br /&gt;
*'''Wide Sampling Rate Range:''' Supports programmable sampling rates from 8 SPS to 860 SPS, meeting the requirements of different applications.&lt;br /&gt;
*'''Integrated NTC Temperature Measurement Interface:''' Onboard MF52AT 10KΩ NTC temperature sensor interface with a B value of 3950K, ideal for temperature monitoring applications.&lt;br /&gt;
*'''Dual-Voltage Compatible Design:''' Supports 3.3V/5V dual-voltage operation, with a built-in LP5907 LDO providing stable 3.3V power.&lt;br /&gt;
*'''Automatic Level Conversion:''' I2C signals are automatically converted to 3.3V levels when powered by 5V, allowing direct connection to 3.3V microcontrollers.&lt;br /&gt;
*'''Standard Interface Design:''' Equipped with HY2.0mm 4P connectors and 2.54mm pin headers for easy connection to various development boards.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Certification Documents'''==&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADC001-CE-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
[[Media:CQRADC001-FCC-SDOC-Certification.rar]]&lt;br /&gt;
&lt;br /&gt;
=='''Pin Description and Size'''==&lt;br /&gt;
[[image:CQRobot.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADC001-1.jpg|thumb|1000px| center]]&lt;br /&gt;
[[image:CQRADC001-2.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Specification'''==&lt;br /&gt;
{|&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADC001-3.jpg|1150px|left]]&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | [[File:CQRADC001-8.jpg|1150px|right]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=='''Working Principle'''==&lt;br /&gt;
[[image:CQRADC001-4-1.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Power Supply and Sensor Compatibility'''==&lt;br /&gt;
This module supports dual-voltage operation at 3.3V/5V. When powered at 3.3V, all I/Os are at 3.3V level; when powered at 5V, the I2C signals are automatically converted to 3.3V for communication with the host, while also allowing measurement of 5V sensor signals. The module includes built-in protection circuits to prevent damage from overvoltage and provides a 3.3V LDO output to power external sensors.&lt;br /&gt;
&lt;br /&gt;
Important: When measuring 5V sensors, the module must be powered at 5V. In this case, the I2C signals remain at 3.3V level and can be directly connected to 3.3V host GPIO. Note that the SDA and SCL pins on this module are limited to 3.3V.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Connections and Examples'''==&lt;br /&gt;
*'''Configuration Method:'''&lt;br /&gt;
Use a jumper cap to connect the ADDR pin to the corresponding voltage level point. After configuration, restart the power for the changes to take effect.&lt;br /&gt;
&lt;br /&gt;
*'''Using an I2C Address Conversion Module for Configuration:'''&lt;br /&gt;
When using an I2C address conversion module, all ADS1115 modules can be set to the same hardware address. Address differentiation is achieved by selecting channels on the conversion module, eliminating the need to modify hardware jumper configurations.&lt;br /&gt;
[[image:CQRADC001-5.jpg|thumb|1000px| center]]&lt;br /&gt;
----&lt;br /&gt;
=='''Arduino Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-72.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Adafruit_ADS1X15.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adafruit_ADS1115 ads;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  ads.begin(0x48);&lt;br /&gt;
  ads.setGain(GAIN_ONE);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  int16_t adc = ads.readADC_SingleEnded(0);&lt;br /&gt;
  float voltage = adc * 0.125 / 1000.0;&lt;br /&gt;
  float ntc_r = (3.3 * 10000.0 / voltage) - 20000.0;&lt;br /&gt;
  float temp = 1.0 / (log(ntc_r / 10000.0) / 3950.0 + 1.0 / 298.15) - 273.15;&lt;br /&gt;
  &lt;br /&gt;
  Serial.print(&amp;quot;Temp: &amp;quot;);&lt;br /&gt;
  Serial.print(temp, 1);&lt;br /&gt;
  Serial.println(&amp;quot;C&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Example Results Explanation:'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-711.jpg|600px]]&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the I2C address to 0x48. You can modify this line of code as needed: ads.begin(0x48).&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the input channel to AIN0. You can modify this line of code as needed: int16_t adc = ads.readADC_SingleEnded(0).&lt;br /&gt;
&lt;br /&gt;
*To use the 5V measurement device, replace the conversion formula with the following:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
float ntc_r = (5.0 * 10000.0 / voltage) - 20000.0;  // Modify to 5V&lt;br /&gt;
&lt;br /&gt;
float temp = 1.0 / (log(ntc_r / 10000.0) / 3950.0 + 1.0 / 298.15) - 273.15;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Raspberry Pi Example and Test Code'''==&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-76.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-73.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
'''Raspberry Pi 4B Pinout Diagram'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-75.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-77.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Create a folder and a “.c” file, then write the code.&lt;br /&gt;
&lt;br /&gt;
[[Media: ADS1115.zip]]&lt;br /&gt;
&lt;br /&gt;
*You can directly add to the compressed file.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-781.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
gcc -Wall -g -o ADS1115 ADS1115.c -lm&lt;br /&gt;
&lt;br /&gt;
./ADS1115&lt;br /&gt;
&lt;br /&gt;
Go to the folder created in the terminal, use GCC cross-compilation and run the file.&lt;br /&gt;
&lt;br /&gt;
*'''Sample Code:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/ioctl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;linux/i2c-dev.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define ADS1115_ADDR 0x48&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int fd = open(&amp;quot;/dev/i2c-1&amp;quot;, O_RDWR);&lt;br /&gt;
    if (fd &amp;lt; 0) return 1;&lt;br /&gt;
    if (ioctl(fd, I2C_SLAVE, ADS1115_ADDR) &amp;lt; 0) return 1;&lt;br /&gt;
    &lt;br /&gt;
    while(1) {&lt;br /&gt;
        unsigned char config[3] = {0x01, 0xC2, 0x83};&lt;br /&gt;
        unsigned char result[2];&lt;br /&gt;
        &lt;br /&gt;
        write(fd, config, 3);&lt;br /&gt;
        usleep(8000);&lt;br /&gt;
        &lt;br /&gt;
        unsigned char reg[1] = {0x00};&lt;br /&gt;
        write(fd, reg, 1);&lt;br /&gt;
        read(fd, result, 2);&lt;br /&gt;
        &lt;br /&gt;
        int16_t adc = (result[0] &amp;lt;&amp;lt; 8) | result[1];&lt;br /&gt;
        float voltage = adc * 0.125 / 1000.0;&lt;br /&gt;
        float ntc_r = (3.3 * 10000.0 / voltage) - 20000.0;&lt;br /&gt;
        float temp = 1.0 / (log(ntc_r / 10000.0) / 3950.0 + 1.0 / 298.15) - 273.15;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Temp: %.1fC\n&amp;quot;, temp);&lt;br /&gt;
        sleep(1);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Test Results:&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-791.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the I2C address to 0x48. You can modify this line of code as needed: #define ADS1115_ADDR 0x48.&lt;br /&gt;
&lt;br /&gt;
*Temporarily set the input channel to AIN0. You can replace it with the following code based on actual needs:&lt;br /&gt;
&lt;br /&gt;
AIN0: 0xC2&lt;br /&gt;
&lt;br /&gt;
AIN1: 0xD2&lt;br /&gt;
&lt;br /&gt;
AIN2: 0xE2 &lt;br /&gt;
&lt;br /&gt;
AIN3: 0xF2&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=='''Used in Conjunction with the TDS Meter Sensor (SKU: CQRSENTDS01 / ASIN: B08KXRHK7H)'''==&lt;br /&gt;
[[image:CQRADC001-7.jpg|thumb|1000px| center]]&lt;br /&gt;
&lt;br /&gt;
*'''Sample Program'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-80.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
*Create a folder and a “.c” file, then write the code.&lt;br /&gt;
&lt;br /&gt;
[[Media: ADSTDS.zip]]&lt;br /&gt;
&lt;br /&gt;
*You can directly add to the compressed file.&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-81.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
gcc -o ADSTDS ADSTDS.c -lwiringPi&lt;br /&gt;
&lt;br /&gt;
./ADSTDS&lt;br /&gt;
&lt;br /&gt;
Go to the folder created in the terminal, use GCC cross-compilation and run the file.&lt;br /&gt;
&lt;br /&gt;
*'''Example Code'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;wiringPi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;wiringPiI2C.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define VREF 5.0f           &lt;br /&gt;
#define SCOUNT 30           // number of sampling points&lt;br /&gt;
#define TEMPERATURE 25.0f   // water temperature (degrees celsius)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int analogBuffer[SCOUNT];        &lt;br /&gt;
int analogBufferTemp[SCOUNT];&lt;br /&gt;
int analogBufferIndex = 0;&lt;br /&gt;
float averageVoltage = 0, tdsValue = 0;&lt;br /&gt;
&lt;br /&gt;
int ads1115_fd;&lt;br /&gt;
&lt;br /&gt;
// function declaration&lt;br /&gt;
int getMedianNum(int bArray[], int iFilterLen);&lt;br /&gt;
int readADS1115();&lt;br /&gt;
unsigned long my_millis();  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
unsigned long my_millis() {&lt;br /&gt;
    struct timespec ts;&lt;br /&gt;
    clock_gettime(CLOCK_MONOTONIC, &amp;amp;ts);&lt;br /&gt;
    return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int getMedianNum(int bArray[], int iFilterLen) {&lt;br /&gt;
    int bTab[iFilterLen];&lt;br /&gt;
    for (int i = 0; i &amp;lt; iFilterLen; i++) {&lt;br /&gt;
        bTab[i] = bArray[i];&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    int i, j, bTemp;&lt;br /&gt;
    for (j = 0; j &amp;lt; iFilterLen - 1; j++) {&lt;br /&gt;
        for (i = 0; i &amp;lt; iFilterLen - j - 1; i++) {&lt;br /&gt;
            if (bTab[i] &amp;gt; bTab[i + 1]) {&lt;br /&gt;
                bTemp = bTab[i];&lt;br /&gt;
                bTab[i] = bTab[i + 1];&lt;br /&gt;
                bTab[i + 1] = bTemp;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if ((iFilterLen &amp;amp; 1) &amp;gt; 0) {&lt;br /&gt;
        bTemp = bTab[(iFilterLen - 1) / 2];&lt;br /&gt;
    } else {&lt;br /&gt;
        bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;&lt;br /&gt;
    }&lt;br /&gt;
    return bTemp;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int readADS1115() {&lt;br /&gt;
    // configuration ADS1115: aisle 0&lt;br /&gt;
    uint16_t config = 0xC283;  &lt;br /&gt;
    wiringPiI2CWriteReg16(ads1115_fd, 0x01, (config &amp;gt;&amp;gt; 8) | (config &amp;lt;&amp;lt; 8));&lt;br /&gt;
    usleep(8000);  &lt;br /&gt;
    &lt;br /&gt;
    uint16_t result = wiringPiI2CReadReg16(ads1115_fd, 0x00);&lt;br /&gt;
    int16_t adc = ((result &amp;gt;&amp;gt; 8) &amp;amp; 0xFF) | ((result &amp;amp; 0xFF) &amp;lt;&amp;lt; 8);&lt;br /&gt;
    &lt;br /&gt;
 &lt;br /&gt;
    static int debug_count = 0;&lt;br /&gt;
    if (debug_count++ % 20 == 0) {&lt;br /&gt;
        printf(&amp;quot;[original ADC: %d] &amp;quot;, adc);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    int adc_abs = abs(adc);&lt;br /&gt;
    &lt;br /&gt;
    // convert to estimated value (0-1023)&lt;br /&gt;
    int arduino_value = (adc_abs * 1024) / 30000;&lt;br /&gt;
    &lt;br /&gt;
    // limited to 0-1023 scope&lt;br /&gt;
    if (arduino_value &amp;gt; 1023) arduino_value = 1023;&lt;br /&gt;
    if (arduino_value &amp;lt; 0) arduino_value = 0;&lt;br /&gt;
    &lt;br /&gt;
    return arduino_value;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    printf(&amp;quot;=== Raspberry Pi TDS measurement ===\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;TDS = 133.42*V^3 - 255.86*V^2 + 857.39*V * 0.5\n\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // initialization wiringPi&lt;br /&gt;
    if (wiringPiSetup() &amp;lt; 0) {&lt;br /&gt;
        printf(&amp;quot;wiringPi initialization failed\n&amp;quot;);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // initialization ADS1115&lt;br /&gt;
    ads1115_fd = wiringPiI2CSetup(0x48);&lt;br /&gt;
    if (ads1115_fd &amp;lt; 0) {&lt;br /&gt;
        printf(&amp;quot;ADS1115 initialization failed (address 0x48)\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;check, please: sudo i2cdetect -y 1\n&amp;quot;);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    printf(&amp;quot;✓ hardware initialization complete\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;start measuring...\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;----------------------------------------\n&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // time point variable (using custom my_millis)&lt;br /&gt;
    unsigned long analogSampleTimepoint = my_millis();&lt;br /&gt;
    unsigned long printTimepoint = my_millis();&lt;br /&gt;
    &lt;br /&gt;
    while (1) {&lt;br /&gt;
        unsigned long currentMillis = my_millis();&lt;br /&gt;
        &lt;br /&gt;
    &lt;br /&gt;
        if (currentMillis - analogSampleTimepoint &amp;gt; 40U) {&lt;br /&gt;
            analogSampleTimepoint = currentMillis;&lt;br /&gt;
            &lt;br /&gt;
            int arduinoValue = readADS1115();&lt;br /&gt;
            &lt;br /&gt;
            analogBuffer[analogBufferIndex] = arduinoValue;&lt;br /&gt;
            analogBufferIndex++;&lt;br /&gt;
            if (analogBufferIndex == SCOUNT) {&lt;br /&gt;
                analogBufferIndex = 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
       &lt;br /&gt;
        if (currentMillis - printTimepoint &amp;gt; 800U) {&lt;br /&gt;
            printTimepoint = currentMillis;&lt;br /&gt;
           &lt;br /&gt;
            for (int copyIndex = 0; copyIndex &amp;lt; SCOUNT; copyIndex++) {&lt;br /&gt;
                analogBufferTemp[copyIndex] = analogBuffer[copyIndex];&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            &lt;br /&gt;
            int medianValue = getMedianNum(analogBufferTemp, SCOUNT);&lt;br /&gt;
            &lt;br /&gt;
            averageVoltage = medianValue * VREF / 1024.0;&lt;br /&gt;
            &lt;br /&gt;
         &lt;br /&gt;
            float compensationCoefficient = 1.0 + 0.02 * (TEMPERATURE - 25.0);&lt;br /&gt;
            float compensationVoltage = averageVoltage / compensationCoefficient;&lt;br /&gt;
            &lt;br /&gt;
            &lt;br /&gt;
            tdsValue = (133.42 * compensationVoltage * compensationVoltage * compensationVoltage &lt;br /&gt;
                       - 255.86 * compensationVoltage * compensationVoltage &lt;br /&gt;
                       + 857.39 * compensationVoltage) * 0.5;&lt;br /&gt;
            &lt;br /&gt;
           &lt;br /&gt;
            printf(&amp;quot;TDS Value: %.0fppm&amp;quot;, tdsValue);&lt;br /&gt;
           &lt;br /&gt;
            printf(&amp;quot; (ADC:%d, Volt:%.3fV)\n&amp;quot;, medianValue, averageVoltage);&lt;br /&gt;
            &lt;br /&gt;
            fflush(stdout);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        usleep(1000);  &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Test Results Explanation:'''&lt;br /&gt;
&lt;br /&gt;
[[File:CQRADC001-82.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
The raw ADC value is the raw 16-bit analog-to-digital conversion data from the ADS1115; the ADC value is the stable value after median filtering; the voltage value is the calculated corresponding voltage value; and the TDS value represents the total dissolved solids content of the water. The I2C address is 0x48; the analog port is AIN0.&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	<entry>
		<id>http://www.cqrobot.wiki/index.php?title=File:ADSTDS.zip&amp;diff=4963</id>
		<title>File:ADSTDS.zip</title>
		<link rel="alternate" type="text/html" href="http://www.cqrobot.wiki/index.php?title=File:ADSTDS.zip&amp;diff=4963"/>
				<updated>2026-01-27T08:39:41Z</updated>
		
		<summary type="html">&lt;p&gt;Chenqi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chenqi</name></author>	</entry>

	</feed>