Creating a Force Sensor with the ADS1120 Module Using Arduino IDE (Part 2)
The previous article introduced how to use the Arduino IDE to program the ESP32 to drive the ADS1120 and read the values from the force sensor.

In the end, we successfully read the force value and displayed it on phyphox:
However, upon closer inspection of the collected points, we find that the sampling rate is relatively low, only 20 samples per second. This is because we did not set the sampling frequency for the ADS1120, which defaults to 20 sps.
In this article, we will cover this content. In the ADS1120 library function example, there is a program called ADS1220_WE_all_settings:
This program includes some function descriptions for using the ADS1220:
Find the following segment, which is about setting the sampling rate:
ads.setDataRate(ADS1220_DR_LVL_2);
This line is used to set the sampling rate. If we want to measure 100 times per second (more than that and phyphox won’t be able to keep up!), we can choose LVL_3, which corresponds to a sampling rate of 175 sps. Each time we read a data point, it takes about 6 milliseconds, and then we wait 4 milliseconds in the main loop to output data every 10 milliseconds. The final program is as follows:
#include <ADS1220_WE.h>#include <SPI.h>#include <phyphoxBle.h>
#define ADS1220_CS_PIN 5#define ADS1220_DRDY_PIN 27
float result0=0; // Variable for zeroing
ADS1220_WE ads = ADS1220_WE(ADS1220_CS_PIN, ADS1220_DRDY_PIN);
void setup(){ Serial.begin(115200); PhyphoxBLE::start("ads1120 Force Sensor"); ads.init(); ads.setDataRate(ADS1220_DR_LVL_3); // Set sampling frequency ads.setGain(ADS1220_GAIN_128); // Set gain of 128 ads.setCompareChannels(ADS1220_MUX_0_1); // Differential voltage between A0 and A1 result0 = ads.getVoltage_muV(); // Read voltage in microvolts for zeroing delay(100);}
void loop(){ float result = ads.getVoltage_muV()-result0; // Read voltage in microvolts, subtract zeroing variable int tm=millis(); // Get the time just after sampling float force = result/541; // Calculate the corresponding force value Serial.print("force:[N]:"); Serial.println(force,4); Serial.println(millis()); // Output time to illustrate sampling rate float tmn=tm*0.001; PhyphoxBLE::write(force,tmn); // Send force value and time value to phyphox delay(4);}
From the output below, we can see that data is output every 10 milliseconds, which means the sampling rate is exactly 100 sps.
Then, we opened phyphox on the phone to check the data read:
Clicking on the points will show the specific data points. I took a snapshot for one second; the sampling rate is already very high. If you’re interested, you can count to see if there are exactly 100 points in one second.
Of course, besides setting the sampling rate, there are many more controls. Let’s take a look at the functions it provides to see what other settings are available:
1、ads.setCompareChannels(ADS1220_MUX_0_3);
First is the input port setting, modifying the content in the parentheses will set the corresponding input/output ports. The above setting is for the positive input to be AIN0 and the negative input to be AIN3 for differential voltage measurement. In the force sensor example, we used AIN0 and AIN1, so the corresponding setting statement is:
ads.setCompareChannels(ADS1220_MUX_0_1);
2、ads.setGain(ADS1220_GAIN_1);
This line is used to set the gain. If you want to use gain, you must enable the PGA, which is enabled by default, so no additional settings are needed.
The content inside the parentheses can be ADS1220_GAIN_1 to ADS1220_GAIN_128, which is described as follows:
ADS1220_GAIN_X: X can equal 1,2,4,8,16,32,64, or 128
3、ads.setDataRate(ADS1220_DR_LVL_2);
This line has been introduced earlier. It is used to set the sampling frequency. The default sampling rate is 20 sps, and in Normal mode, the maximum is 1000 sps. You can also set it to Turbo mode, which can reach a maximum of 2000 sps.
4、ads.setOperatingMode(ADS1220_DUTY_CYCLE_MODE);
This line is used to set the mode, which defaults to Normal mode. Usually, you can just use the default.
5、 ads.setConversionMode(ADS1220_CONTINUOUS);
This is used to set the ADS1220 sampling mode, which can be either single sampling or continuous sampling mode, with single sampling being the default. We usually just use the default.
6、ads.setVRefSource(ADS1220_VREF_REFP0_REFN0);
This line is used to set the external reference voltage source. Since my ADS1120 module has a built-in 3V reference voltage source, this voltage source is applied to REFP0 and REFN0. If you do not want to use the built-in voltage source, you can set it to use an external voltage source by adding the following two lines in the setup() initialization program.
ads.setVRefSource(ADS1220_VREF_REFP0_REFN0);
ads.setVRefValue_V(3.00);
Of course, there are other settings as well; you can check the English documentation below.
7、ads.setIdacCurrent(ADS1220_IDAC_50_MU_A);
This is the most powerful feature of the ADS1120, which can act as a constant current source! The output current is relatively small, with a maximum of 1.5mA, which is perfect for capacitor charging and discharging experiments! This line sets the current size.
8、ads.setIdac1Routing(ADS1220_IDAC_AIN0_REFP1);
The ADS1120 also has two constant current sources that can output. Once the command ads.setIdac1Routing(ADS1220_IDAC_AIN0_REFP1) is executed, AIN0 will output current. Of course, to have current, there must be a circuit, and it must return to the GND (negative terminal) of the ADS1120! Stopping the output is also simple; you can run ads.setIdacCurrent( ADS1220_IDAC_OFF);
Alright, there are actually some other functions; you can check the examples for more details. The ADS1120 is a highly versatile ADC that can handle experiments in the electrical and mechanical parts of high school physics, and it can even serve as a constant current source. However, this ADC is also quite fragile, so please do not exceed its range, especially when using high gain modes—be careful, be careful!!!