Help with silo level measurement using Vegabar + ADS1115 + ESP32 + Blynk

Hi everyone,

I’m working on an industrial project for milk silos and I’d like some help understanding a measurement issue with a 4–20mA pressure sensor (Vegabar) and also some advice about alternative sensors / approaches for silo level.


1. Hardware / Setup

  • Central device: Heltec WiFi LoRa 32 (V3) – ESP32 + SX1262 LoRa
  • Remote nodes (per silo):
    • ESP32 board
    • Vegabar 28 (4–20mA pressure transmitter, range 0–2.5 bar)
    • ADS1115 16-bit ADC
    • Shunt resistor: 150 Ω, 0.1%, 0.5 W (metal film) to convert 4–20mA → voltage
    • Extra resistors: 10 kΩ and 1 kΩ (pull-downs / dividers, etc.)
  • Power:
    • 24 V supply for the Vegabar (current loop)
    • 5 V / 3.3 V supply for ESP32 and ADS1115
  • Communication:
    • Each node reads the Vegabar via ADS1115, computes / sends:
      • Raw voltages (V0, V1)
      • Optional pre-computed P / h / L / T
    • Data is sent by LoRa to the Heltec central, which uploads everything to Blynk.Cloud.
  • Smartphone: Android 16
  • Blynk app: latest Blynk IoT app from Play Store
  • Blynk Library: latest version from GitHub / Library Manager
  • Server: Blynk.Cloud (I’m in Argentina, not sure which exact region)

2. What I’m doing with the Vegabar / ADS1115

On the remote node, the Vegabar 28 (4–20mA) current loop goes through a 150 Ω shunt resistor, so:

  • 4 mA → about 0.6 V on the shunt
  • 20 mA → about 3.0 V on the shunt

This voltage is measured by the ADS1115 and sent via LoRa as V0 (pressure channel) and V1 (temperature channel, with a second 4–20mA loop).

On the central (Heltec WiFi LoRa 32 V3) I receive this payload:

<ID>;P=...;h=...;L=...;T=...;V0=...;V1=...

And I recalculate the physical values using:

  • A per-silo zero in volts (blynkZeroV[slot]) coming from a Blynk numeric input (V130…V134, etc.)
  • A per-silo area in m² (blynkAreaM2[slot]) also from Blynk

The formula is:

// V0 = raw volts from ADS1115 (pressure channel)
// zV = "zero" volts (when silo is empty), configured from Blynk

float V0corr = v0_raw - zV;
if (V0corr < 0) V0corr = 0;

// Rshunt per slot (default 147 Ω, or measured value like 147.9 Ω, 149.9 Ω, etc.)
float I0_mA = 4.0f + mA_from_V_slot(V0corr, idx);  // ΔI + 4 mA base
I0_mA = clamp_mA(I0_mA);                            // 4..20 mA

// Pressure in bar
float Pbar = ((I0_mA - 4.0f) / 16.0f) * P_MAX_BAR;  // P_MAX_BAR = 2.5 bar

// Height in meters (using milk density + g)
float h_m  = (Pbar * 100000.0f) / (RHO_MILK * G_ACC);  // RHO_MILK = 1030 kg/m³

// Liters = h (m) * area (m²) * 1000
float L_L  = h_m * area * 1000.0f;

I also use individual Rshunt per silo (measured with a multimeter):

static const float RSHUNT_DEFAULT = 147.0f;   // ohms
float rshuntSlot[MAX_NODES];  // NaN => use default

static float mA_from_V_slot(float V, int slotIdx){
  float R = (!isnan(rshuntSlot[slotIdx]) && rshuntSlot[slotIdx] > 1.0f)
              ? rshuntSlot[slotIdx]
              : RSHUNT_DEFAULT;
  return (V / R) * 1000.0f;
}

And the zeros / areas are set from Blynk virtual pins, one per silo.


3. What works and what is the problem

Things that work well:

  • LoRa communication ESP32 node → Heltec central is stable.
  • Blynk connection is stable (with watchdogs and timers).
  • The Blynk dashboard shows P, h, L, T, RSSI for each silo.
  • The web UI (local port 8080) shows all silos and a “wash mode” (where I temporarily force level to zero during cleaning).

The problem is with the Vegabar measurement vs. real silo level:

  • I’ve zeroed the silo when empty (using the raw V0 value, stored as zero in Blynk).
  • I’ve configured a precise silo area (for example: Silo 9 → 19.500 m²; Silo 8 → 16.400 m²).
  • I’ve measured the shunt resistors and set the exact value for each slot (rshuntSlot[1] = 147.9f; rshuntSlot[8] = 149.9f, etc.).

However, I still see a difference between:

  • What the Vegabar should be reporting according to its datasheet / pressure range, and
  • The actual liters in the silo (based on real usage / truck unloads, etc.).

Sometimes the error is small, but in some operating ranges the liters don’t match what we expect (especially near the top or in certain levels). I know some of this can be due to:

  • Silo geometry (not a perfect cylinder, conical bottoms, etc.)
  • Milk density variations with temperature
  • Possible non-linearity of the pressure transmitter or mounting height

But before I redesign the whole thing, I’d like to check with the community:

  1. Does the way I’m converting 4–20mA → pressure → height → liters look OK to you?
  • Would you do the math directly on the node instead of the central?
  • Any better way to handle zero / span in code?
  1. Has anyone used Vegabar (or similar 4–20mA pressure transmitters) for silo level with ESP32 + Blynk?
  • Any typical tricks (filtering, averaging, calibration steps) I’m missing?
  1. Would you recommend a different type of sensor for this use case (milk silos, several meters high), that plays well with ESP32/Blynk? For example:
  • Ultrasonic level sensors
  • Radar level sensors
  • Load cells at silo legs
  • Other digital (Modbus/RS-485) transmitters that you’ve successfully used with Blynk

4. Example serial output

Here is an example of the serial output from the central when receiving data (just as a reference):

[RAW] SILO-9     V0=0.57600 V  zero=0.56889 V  area=19.500 m2
[RX]  SILO-9     RSSI= -93 SNR= 10  P=0.175 bar  h=1.728 m  L=34221 L  T=4.5 C  (slot 8) [recalc]

[RAW] SILO-8     V0=0.57000 V  zero=0.56377 V  area=16.400 m2
[RX]  SILO-8     RSSI= -90 SNR=  9  P=0.160 bar  h=1.580 m  L=25912 L  T=4.3 C  (slot 1) [recalc]

(If needed I can post a longer log showing the discrepancy between expected vs. measured liters.)


As nobody has responded to your post, I’ll chip-in with a few observations.

I’m not familiar with the Vegabar 28 sensor, and haven’t found much info online other than the manufacturer’s slightly odd dataset etc.

I’m not clear how you’re powering this, and whether the output you get from the sensor is electrically tied to the supply rail or not. But, your comments like…

aren’t what I expected to see.

I’m also confused about why you’re using an external 16 bit ADC rather than the ESP32’s built-in 12 bit ADCs. From the figures you’ve quoted, I don’t see how the additional resolution will help your use case.

As with any analog system, wire lengths and shielding are extremely important, and the more sensitive your system, the more important these become. Do you have a physical setup that supports this approach?

If electrical noise is an issue and you’ve done everything you can to minimise it, then multiple sampling and averaging may help to minimise the inaccuracies.

As far as alternative types of sensors are concerned, I wouldn’t use ultrasonic sensors in the environment you describe. You’re likely to get echos off of the inner walls of the silos. I’d expect that laser distance measuring would be the most reliable approach.

You mention Modbus/RS-485 communication. Personally, I’d steer clear of this if your LoRa communication is working okay. RS-485 adds an additional level of complexity that could send you down addition rabbit holes without any appreciable gain.

Pete.

2 Likes