KPM12-J High-Resolution Resistance-Based Displacement Sensor

In this video I show you another displacement sensor. The KPM12-J is a resistance-based, high-resolution displacement sensor. This makes it very simple to read it because you only need a good AD-converter.



Wiring diagram

Both the ADS1115 and the 16x2 LCD are using the i2C protocol. I did not find the model for the KPM12-J sensor, so I substituted it with a regular potentiometer. Technically, there is no difference between them from the ADC’s point of view: both are …

Both the ADS1115 and the 16x2 LCD are using the i2C protocol. I did not find the model for the KPM12-J sensor, so I substituted it with a regular potentiometer. Technically, there is no difference between them from the ADC’s point of view: both are just some voltage dividers.



Arduino source code

#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Adafruit_ADS1X15.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

Adafruit_ADS1115 ads;  

int cin1; //for reading the instructions from serial
int samplingfreq; //sampling frequency [milliseconds]
float distance = 0; //for the calibrated distance
float adcRead; //for the raw data

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

  //some info to know what is on the Arduino
  Serial.println("KP12M-25mm Displacement sensor, LCD, Button.");
  Serial.println("Getting differential reading from AIN0 (P) and AIN1 (N)");
  Serial.println("ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)");

  // The ADC input range (or gain) can be changed via the following
  // functions, but be careful never to exceed VDD +0.3V max, or to
  // exceed the upper and lower limits if you adjust the input range!
  // Setting these values incorrectly may destroy your ADC!
  //                                                                ADS1015  ADS1115
  //                                                                -------  -------
  // ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default)
  // ads.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV
  // ads.setGain(GAIN_TWO);        // 2x gain   +/- 2.048V  1 bit = 1mV      0.0625mV
  // ads.setGain(GAIN_FOUR);       // 4x gain   +/- 1.024V  1 bit = 0.5mV    0.03125mV
  // ads.setGain(GAIN_EIGHT);      // 8x gain   +/- 0.512V  1 bit = 0.25mV   0.015625mV
  // ads.setGain(GAIN_SIXTEEN);    // 16x gain  +/- 0.256V  1 bit = 0.125mV  0.0078125mV


  //----Set default------
  ads.setDataRate(RATE_ADS1015_920SPS ); //Sampling speed

  ads.setGain(GAIN_TWOTHIRDS); // Gain (set to max now)
  ads.begin();

  //-----------------Taking care of LCD-------------------
  //NOTE: if you cannot see the text on the LCD, try to change the potmeter on the back of it.
  //Sometimes you just have wrong contrast settings and nothing shows up on the screen because of it.
  lcd.begin();                      // initialize the lcd
  lcd.backlight(); //initialize backlight
  //------------------------------------------------------
  lcd.clear(); //clear the LCD
  lcd.setCursor(0, 0); //Defining positon to write from first row,first column .
  lcd.print("KP12M-25mm"); //some message
  lcd.setCursor(0, 1); //Cursor is moved to the 2nd line of the LCD
  lcd.print("Reading displ."); //You can write 16 Characters per line .
  delay(3000); //wait 3 sec

}

void loop(void)
{

  //--------------------------------------------------------------------------------------------------------
  double startTime = millis(); //define the time NOW. This will be useful when we need some time readings

  if (Serial.available() > 0) {

    char cin = Serial.read();    

    switch (cin) //Our usuial SWITCH-CASE method
    {
      //-------------------------Changing SPS settings---------------------------------------------------
      case 'd':
        delay(50);
        while (!Serial.available());

        SPSifchecker(cin1); //we change the SPS (sampling frequency) by sending and integer between 0-7 (Check the function below)
        //Example: the message "d 2" sets the SPS to 2 which is: 490 samples per second
        break;
      //-------------------------------------------------------------------------------------------------
      //-------------------------Changing PGA settings---------------------------------------------------
      case 'w':
        delay(50);
        while (!Serial.available());

        PGAifchecker(cin1); //we change the PGA (onboard amplifier) by sending an integer between 0-6.(Check the function below)
        //Example: the message "w 2" sets PGA to 2 which is: 2x gain   +/- 2.048V  1 bit = 1mV      0.0625mV 
        break;
      //-------------------------------------------------------------------------------------------------
      //--------------------------Reading data and sending to PC-----------------------------------------
      case 's': //s: Start

        while (Serial.read() != 'N') { //While we don't interrupt it by sending 'N' to the Arduino
          
          double elapsedTime = millis() - startTime; //start another timer 
          adcRead = ads.readADC_Differential_0_1(); //read the ADC 0 and 1 pins in differential mode
          distance = (-0.0009353088486627 * adcRead + 27.36432542127); //calibrated displacement
          //------------Serial printout-----------------
          Serial.print(elapsedTime); //elapsed time since this part of the code is running
          Serial.print("\t"); //tab for separation
          Serial.print(adcRead, 0); // raw data, 0 decimals
          Serial.print("\t"); //tab for separation
          Serial.print(distance, 6); //calibrated data (displacement), 6 decimals
          Serial.print("\n"); //linebreak
          //-------------------------------------------

          delay(200); //delay 200 ms
        }
        break;
      //-------------------------------------------------------------------------------------------------
      //------------------------------------Single Readout to PC-----------------------------------------
      case 'r': //Read. Just a one shot reading.

        adcRead = ads.readADC_Differential_0_1();  //read the ADC 0 and 1 pins in differential mode
        distance = (-0.0009353088486627 * adcRead + 27.36432542127); //calibrated displacement
        //------------Serial printout-----------------
        Serial.print(adcRead, 0); // raw data, 0 decimals
        Serial.print("\t"); //tab for separation
        Serial.print(distance, 6); //calibrated data (displacement), 6 decimals
        Serial.print("\n"); //linebreak
        //-------------------------------------------
        delay(3000); //wait a bit more

        break;
      //-------------------------------------------------------------------------------------------------
      //------------------------------Using LCD----------------------------------------------------------
      case 'l': //LCD data
        // we read the sampling frequency from the serial. Lower number, higher sampling rate.
        // this number is independent from the SPS settings. This controls the frequency of Serial.println()
        samplingfreq = Serial.parseInt();

        while (Serial.read() != 'N') { //While we don't interrupt it by sending 'N' to the Arduino     
          
          double elapsedTime = millis() - startTime; //start another timer 
          adcRead = ads.readADC_Differential_0_1(); //read the ADC 0 and 1 pins in differential mode
          distance = (-0.0009353088486627 * adcRead + 27.36432542127); //calibrated displacement
          //------------Serial printout-----------------
          Serial.print(elapsedTime); //elapsed time since this part of the code is running
          Serial.print("\t"); //tab for separation
          Serial.print(adcRead, 0); // raw data, 0 decimals
          Serial.print("\t"); //tab for separation
          Serial.print(distance, 6); //calibrated data (displacement), 6 decimals
          Serial.print("\n"); //linebreak
          //-------------------------------------------
          //-------------LCD Printout------------------
          lcd.clear(); //clear LCD
          lcd.setCursor(0, 0); //Defining positon to write from first row,first column .
          lcd.print("Displacement");
          lcd.setCursor(0, 1); //Defining positon to write from second row,first column .
          lcd.print(distance, 6); //You can write 16 Characters per line
          //-------------------------------------------

          delay(samplingfreq); //we have to subtract the code's running time, to get the exact frequency.
        }

        break;
      //-------------------------------------------------------------------------------------------------
      default:

        break;

    }
  }



  //--------------------------------------------------------------------------------------------------------
}

void PGAifchecker(int cin1)
{
  //the commented parts are for testing, but I left them in the code
  cin1 = Serial.parseInt();
  //Serial.println(cin1);
  //Serial.println("first cin");
  delay(50);
  //Serial.println("after delay");

  if (cin1 < 1 )
  {
    ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default) //1
    //Serial.println("test");
    //Serial.println("PGA-0");
  }
  else if (cin1 < 2)
  {
    ads.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV // 1,5
    //Serial.println("PGA-1");
  }
  else if (cin1 < 3)
  {
    ads.setGain(GAIN_TWO);        // 2x gain   +/- 2.048V  1 bit = 1mV      0.0625mV // 3
    //Serial.println("PGA-2");
  }
  else if (cin1 < 4)
  {
    ads.setGain(GAIN_FOUR);       // 4x gain   +/- 1.024V  1 bit = 0.5mV    0.03125mV // 6
    //Serial.println("PGA-3");
  }
  else if (cin1 < 5)
  {
    ads.setGain(GAIN_EIGHT);      // 8x gain   +/- 0.512V  1 bit = 0.25mV   0.015625mV //12
    //Serial.println("PGA-4");
  }
  else if (cin1 < 6)
  {
    ads.setGain(GAIN_SIXTEEN);    // 16x gain  +/- 0.256V  1 bit = 0.125mV  0.0078125mV //24
    //Serial.println("PGA-5");
  }

  //Serial.println("The value of the PGA now is:");
  //Serial.println(cin1);

}

void SPSifchecker(int cin1)
{
  //the commented parts are for testing, but I left them in the code
  cin1 = Serial.parseInt();
  //Serial.println(cin1);
  //Serial.println("first cin");
  delay(50);
  //Serial.println("after delay");

  // try it with == 1, without ' ' or " "
  if (cin1 < 1)
  {
    ads.setDataRate(RATE_ADS1015_128SPS );        // 128 samples per second
    //Serial.println("128 SPS");
  }
  else if (cin1 < 2)
  {
    ads.setDataRate(RATE_ADS1015_250SPS );        // 250 samples per second
  }
  else if (cin1 < 3)
  {
    ads.setDataRate(RATE_ADS1015_490SPS );        /// 490 samples per second
  }
  else if (cin1 < 4)
  {
    ads.setDataRate(RATE_ADS1015_920SPS );       // 920 samples per second
  }
  else if (cin1 < 5)
  {
    ads.setDataRate(RATE_ADS1015_1600SPS );      // 1600 samples per second (default)
  }
  else if (cin1 < 6)
  {
    ads.setDataRate(RATE_ADS1015_2400SPS );    // 2400 samples per second
    //Serial.println("2400 SPS");
  }
  else if (cin1 < 7)
  {
    ads.setDataRate(RATE_ADS1015_3300SPS );    // 3300 samples per second
  }

  //Serial.println("The value of the PGA now is:");
  //Serial.println(cin1);
}

Previous
Previous

Homing with the AccelStepper library and a limit switch

Next
Next

Failure of a piece of steel under tensile loading