Monday, December 11, 2023

Arduino interfacing with ADS1115 for high resolution analog measurement

 


To interface with the ADS1115 ADC and print data on an LCD using Arduino, you will need to do the following:

  1. Connect the ADS1115 to the Arduino using the I2C protocol. Connect the SDA and SCL pins of the ADS1115 to the corresponding pins on the Arduino (A4 and A5, respectively).

  2. Connect the LCD to the Arduino using the appropriate pins. This can vary depending on the specific LCD you are using, but typically involves connecting the LCD's data pins (D4-D7) to digital pins on the Arduino and connecting the RS, E, and RW pins to other digital pins.

  3. Include the necessary libraries in your Arduino sketch. You will need the Wire library for I2C communication and the LiquidCrystal library for controlling the LCD.

  4. In your sketch, initialize the ADS1115 and the LCD. This will involve setting up the I2C communication and configuring the ADC and the LCD for your specific needs.

  5. Continuously read the data from the ADS1115 and display it on the LCD. You can use the ADS1115 library to read the data from the ADC, and the LiquidCrystal library to write the data to the LCD.

Here's some example code to get you started:

#include <Wire.h> #include <Adafruit_ADS1015.h> #include <LiquidCrystal.h> #define ADS1115_ADDRESS 0x48 Adafruit_ADS1115 ads(ADS1115_ADDRESS); #define LCD_RS 12 #define LCD_EN 11 #define LCD_D4 5 #define LCD_D5 4 #define LCD_D6 3 #define LCD_D7 2 LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7); void setup() { Wire.begin(); ads.begin(); lcd.begin(16, 2); } void loop() { int16_t adc0, adc1, adc2, adc3; adc0 = ads.readADC_SingleEnded(0); adc1 = ads.readADC_SingleEnded(1); adc2 = ads.readADC_SingleEnded(2); adc3 = ads.readADC_SingleEnded(3); lcd.clear(); lcd.setCursor(0, 0); lcd.print("ADC0: "); lcd.print(adc0); lcd.setCursor(0, 1); lcd.print("ADC1: "); lcd.print(adc1); delay(500); }

This code initializes the ADS1115 and the LCD in the setup() function, and continuously reads the data from the ADC and displays it on the LCD in the loop() function. The ADC data is read using the readADC_SingleEnded() function, and the data is written to the LCD using the print() function of the LiquidCrystal library. You can modify this code to suit your specific needs, such as changing the ADC channels that are read, or adding additional LCD displays.



#include <Wire.h> #include <Adafruit_ADS1015.h> #include <LiquidCrystal.h> #define ADS1115_ADDRESS 0x48 Adafruit_ADS1115 ads(ADS1115_ADDRESS); #define LCD_RS 12 #define LCD_EN 11 #define LCD_D4 5 #define LCD_D5 4 #define LCD_D6 3 #define LCD_D7 2 LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7); void setup() { Serial.begin(9600); Wire.begin(); ads.begin(); lcd.begin(16, 2); } void loop() { int16_t adc0, adc1, adc2, adc3; adc0 = ads.readADC_SingleEnded(0); adc1 = ads.readADC_SingleEnded(1); adc2 = ads.readADC_SingleEnded(2); adc3 = ads.readADC_SingleEnded(3); lcd.clear(); lcd.setCursor(0, 0); lcd.print("ADC0: "); lcd.print(adc0); lcd.setCursor(0, 1); lcd.print("ADC1: "); lcd.print(adc1); Serial.print("ADC0: "); Serial.println(adc0); Serial.print("ADC1: "); Serial.println(adc1); delay(500); }

This code adds the Serial.begin() function to initialize serial communication at a baud rate of 9600. In the loop() function, the ADC data is read and displayed on the LCD as before, but it is also sent over serial using the Serial.print() and Serial.println() functions. This allows you to monitor the ADC data in real-time using a serial monitor, such as the one built into the Arduino IDE. To view the serial output, open the serial monitor in the Arduino IDE and set the baud rate to 9600.

Saturday, February 25, 2023

Solution of a second order system using LabVIEW

 

The second-order system model is a set of mathematical equations used to describe the behavior of nonlinear systems. It consists of two nonlinear differential equations and a set of constants that define how those variables change over time. The system is defined by its state variables and the values for their respective operators at each instant in time.

Standard mathematical form of a second-order differential equation is as below:


Where A and B are constants.

For control system, the standard mathematical form of second order system with Unit step input is as below:


Where ξ is the damping factor and ωn is the natural frequency.

The system will be underdamped when 0 < ξ < 1. The particular solution,
yp(t) = 1 determines the steady state solution of the system. The homogeneous solution determines the transient solution which is


 

1.     Methods

This project report will be executed using LabVIEW. The first part of the report will be presenting Numeric block based code for analyzing the response of the system based on the following solution:

Where ξ is the damping factor and ωn is the natural frequency. If T is the total time for which response is analyzed, N is the number of points then time step is ∆t = T/N. At ith iteration, t= i*∆t = i*T/N.

We will be using this equation for different parameters of ζ , ωn, T and N to analyze its response on graph.

In next part of the lab we will be using another method which is call formula node. In formula node we write the formula in script and then give input and output arguments to it.

Below code is written using Numeric blocks in LabvIEW.



We can simulate the same model using Formula script node also.










Wednesday, February 1, 2023

Current Sinking and Current sourcing configuration of a device

Current sinking refers to a configuration in electrical circuits where a device, such as an LED or transistor, is connected to a power source and "sinks" current into the ground. This means that current flows from the power source, through the device, and into the ground.

Current sourcing, on the other hand, is when a device "sources" current out of a power source and into a load. In this configuration, current flows from the power source, through the device, and into a load, such as a motor or a resistor.

In both cases, the device acts as a switch that controls the flow of current in the circuit. The choice of whether to use current sinking or sourcing depends on the specific requirements of the circuit and the characteristics of the device being used. sinking and sourcing terminology applies only to DC input and output circuits. Input and output points that are sinking or sourcing can conduct current in one direction only. 
The figure below depicts a sinking input. To properly connect the external supply, it must be connected so the input provides a path to supply common(-). So, start at the PLC input terminal, follow through the input sensing circuit, exit at the common terminal, and connect the supply (-) to the common terminal. By adding the switch between the supply (+) and the input, the circuit is completed. Current flows in the direction of the arrow when the switch is closed.



The four possible combinations of input/output sinking/sourcing circuits are shown below. The common terminal is the terminal that serves as the common return path for all I/O points in the bank.





Why 4-20 mA signal is used for transmission?

4 to 20 mA Current Transmission

In many process control applications, signals are transmitted in the form of current in the range of 4 to 20 mA. Current loops are used not only for receiving information from sensors and field instrumentation, they are also used for transmitting control signals to actuators or other devices to regulate a controlled action. For long distance signal transmission, current signal is preferred because of

(1) Compatibility: The 4-20 mA signal is widely used in industrial process control because it is a widely accepted standard. This means that a wide range of instrumentation and control equipment is available that can use this signal, making it easy to integrate into many different types of control systems.


(2) Noise immunity from EMI:  Industrial environments can be noisy places, with electrical interference from other equipment and power sources. The 4-20 mA signal is designed to be immuned to this type of noise, which helps to ensure that the signal remains accurate and reliable even in noisy environments.

(3) Unaffected by voltage drop along the line.

(4) No stray Thermocouples at joints, hence no error due to thermoelectric emf.

(5) Current signal can be transmitted over long distance till the compliance voltage requirement is met.

(6) Self monitoring ability. currents less than 4 mA and higher than 20 mA can indicate a fault in the circuit.

(7) Power Transmission: The 4-20 mA signal is self-powered, meaning that it can be transmitted over long distances without the need for an external power source.

4 mA lower limit known as "Live zero" provides ability to detect cable or connection fault. The current upto 3.6-3.8mA is used to power the loop instruments in loop-powered mode.


How current transmission provide noise immunity?

(1) Loop wiring: The 4-20 mA signal is typically transmitted in a loop configuration, where the signal is transmitted from the field device back to the control system. This creates a closed loop circuit that helps to reduce the impact of noise and interference on the signal.

(2) Low frequency: The 4-20 mA signal operates at a relatively low frequency, typically in the range of a few kilohertz. This low frequency reduces the impact of high-frequency noise and interference that can be present in industrial environments.

(3) Signal strength: The 4-20 mA signal is transmitted at a relatively high current level, typically between 4 and 20 milliamperes. This high current level helps to ensure that the signal remains strong and robust, even in the presence of noise and interference.

(4) Common mode rejection: Many industrial control systems are designed to reject common mode noise, which is a type of noise that affects both the positive and negative parts of the signal in a similar way. The 4-20 mA signal is typically transmitted in a differential configuration, which helps to reduce the impact of common mode noise.

Tuesday, January 31, 2023

Very fast Analog data logging using Arduino

For fast analog data acquisition on an Arduino UNO, you can utilize the analogRead() function, but to optimize it for speed, we can:

1. Use Direct Register Manipulation to bypass the overhead of the `analogRead()` function.
2. Disable ADC interrupts if you're not using them.
3. Set the ADC prescaler to a value that allows faster conversions.

Here’s a code example that shows how to configure the Arduino UNO to acquire analog data very fast:

Fast Analog Data Acquisition Code


const int analogPin = A0;  // Analog input pin
const int numSamples = 1000; // Number of samples to acquire

// Variables to hold ADC results
volatile uint16_t analogData[numSamples];
volatile unsigned long lastMicros = 0;
volatile int sampleIndex = 0;

void setup() {
  Serial.begin(115200);  // Initialize Serial for output
  // Configure the ADC for fast conversion
  ADMUX = (1 << MUX0);    // Select A0 pin (MUX0 = 1)
  ADCSRA |= (1 << ADEN);  // Enable ADC
  ADCSRA &= ~(1 << ADIF); // Clear ADC interrupt flag
  ADCSRA |= (1 << ADATE); // Enable Auto Trigger
  ADCSRA |= (1 << ADPS2) | (1 << ADPS1);  // Set prescaler to 64 (fastest)
  ADCSRA |= (1 << ADSC);  // Start the conversion
  ADCSRA |= (1 << ADIE);  // Enable ADC interrupt

  // Configure the ADC to be in free-running mode
  ADCSRA |= (1 << ADATE); // Enable auto-triggering mode (free running)
  ADCSRB = 0;             // Free running mode

  sei();  // Enable global interrupts
}

void loop() {
  // We acquire data until numSamples is filled
  if (sampleIndex >= numSamples) {
    // Send the data to Serial when done
    for (int i = 0; i < numSamples; i++) {
      Serial.println(analogData[i]);
    }
    sampleIndex = 0;  // Reset for the next acquisition
  }
}

// ADC Conversion Complete ISR
ISR(ADC_vect) {
  if (sampleIndex < numSamples) {
    analogData[sampleIndex++] = ADC;  // Store the ADC result
  }
}


Key Optimizations:

1. Direct Register Manipulation:
   - Instead of using `analogRead()`, this code reads directly from the ADC register (`ADC`).
   - It sets the ADC prescaler to 64 for faster conversion, and uses `ADCSRA` for controlling ADC features.

2. Auto-trigger (Free Running Mode):
   - The ADC is set to continuous conversion mode, so it automatically triggers a new conversion after each one. This eliminates the need for manual triggering.

3. Interrupts for Fast Acquisition:
   - The `ADC_vect` interrupt is triggered every time an analog-to-digital conversion is complete, enabling fast acquisition without delay.

Prescaler Settings for ADC Clock:
The ADC clock in an Arduino UNO can be controlled using the prescaler, which divides the 16 MHz system clock to give the ADC a lower clock frequency. The prescaler is set in the `ADCSRA` register:

- Prescaler of 16 (default): 1 MHz
- Prescaler of 64: 250 kHz (faster, but higher noise)
- Prescaler of 128: 125 kHz (useful for higher precision but slower)

In the example, we used a prescaler of 64, which provides a balance between speed and accuracy.

Data Output:
- The `analogData` array will store all the ADC readings, and once the acquisition of the desired number of samples (`numSamples`) is complete, it sends the data over serial to the PC for analysis.

Notes:
- The code is designed for fast analog data acquisition. You can adjust the `numSamples` for longer or shorter acquisition.
- The resolution of the analog readings will be 10 bits (0-1023) as provided by the standard ADC in Arduino UNO.
- If you need higher speeds, consider moving to a more advanced board, such as Arduino Due or Teensy, which support faster ADCs.


Sunday, May 22, 2022

Synchronous pulse train generation using Arduino

Using arduino, i have generated synchronized pulses with a fixed delay between them. The parameters can be remotely adjusted using serial port.

The pulse 2 (Blue) goes high after some user settable delay of Pulse 1(Yellow) rising edge.


 If we set td=tm, we can get consecutive pulses as below:



Monday, March 14, 2022

Analog signal isolation using HCNR200/201 optocoupler

 

The HCNR200/201 is a high-linearity analog optocoupler which can be used to isolate analog signals. It offers good stability, linearity, bandwidth, simple design and low cost. With choice of suitable application circuit it can also incorporate amplification, attenuation, offset, inversion among others to the input signal. 

 Details of the IC along with datasheet can be found in the link below.

https://www.broadcom.com/products/optocouplers/industrial-plastic/specific-function/high-linearity-analog/hcnr200

 

 At first glance, understanding the application circuit is difficult for a new user. 

To get complete isolation, make sure that grounds as well as bias supplies of input and output stage are isolated. Note the label used in above circuit for input stage are GND, VCC, VEE and that of output stage are GND2, VCC2 and VEE2. I generally use two isolated DC to DC converters each powering one stage at a time.

Now coming back to working of the circuit. Lets us analyze the input stage first.

The input side op-amp always tries to force same input voltages at its two input terminals in close loop connection. Thus, the input side  photodiode PD1 (terminal 3,4 of HCNR200) will have zero voltage across it. A positive voltage at inverting terminal of U1 will swing the output to negative rail causing current flow through LED (terminal 1,2 of HCNR200). Also the positive voltage will cause a current through R1 which will eventually flow through photodiode PD1.

IPD1 = Vin/ R1

Current is linearly related to input voltage. 

Since photodiode PD1 and PD2 are identical to each other, IPD2 should be equal to IPD1 ideally. Practically the relation is

 IPD2 = K x IPD1

where K is gain coefficient.

Output voltage can be given as Vout =  R2 x IPD2


Convert presurre and temperature in different units

  Unit Converter Pressure and Temperature Unit Converter Pressure Converter Temperature Converter ...