Monitoring High-Current Pulses with AN3V & CC6921B Current Sensor Modules with Arduino
In that article we will explore 2 new current sensor modules from JSumo.
When dealing with high-current applications, such as robots, motor drivers precision and speed are everything. Better current sending gives us detailed feedback of system. This technical guide explores how to interface the AN3V 80A Current Sensor Module and CC6921B 100A Current Sensor Module Hall-effect sensors with an Arduino to capture peak current pulses using hardware interrupts.
The Hardware: Hall-Effect Current Sensors
Unlike traditional shunts, Hall-effect sensors provide galvanic isolation, meaning your microcontroller unit (such as Arduino, STM, ESP…) is electrically safe from the high-voltage/high-current line you are measuring. This big advantage is very important difference than shunt sensors.
Current Sensor Modules Comparison
Both JSumo current sensors have direct analog output for measuring currents with small differences:
The most important difference we see is the operating voltage.
Advanced Control Logic
This project isn’t just about reading a value; it’s about controlling a high-current load. We implement two advanced MCU features, these are:
1. Pin Change Interrupts (PCINT)
Instead of constantly “polling” a button in the main loop, we use PCINT. This allows the Arduino to react instantly to a button press, triggering the MOSFET without the delays caused by other code operations.
2. Hardware Timer1 (CTC Mode)
To ensure the MOSFET stays active for exactly 120ms, we utilize Timer1. By using the Clear Timer on Compare Match (CTC) mode, the hardware handles the timing. This is far more accurate than using delay(), as it allows the CPU to continue monitoring current while the pulse is active.
Code Walkthrough
The provided firmware is divided into three functional blocks:
- The Sampling Engine: It takes 100 samples every 20ms to filter out electrical noise, calculating the difference between and to determine the exact amperage.
- Peak Detection: Within a 200ms window, the code stores the highest recorded value. This is vital for capturing the “Inrush Current” that occurs at the very start of a pulse.
- The Safety Cutoff: Once the 120ms hardware timer expires, an Interrupt Service Routine (ISR) immediately shuts down the MOSFET, preventing over-heating or component failure.
Calibration and Accuracy
To get the most out of your sensor, consider these two factors:
- VCC Calibration: If your Arduino is powered by USB, your rail might actually be . Measuring this and updating SYSTEM_VCC in the code will significantly improve accuracy.
- Zero-Current Offset: Hall-effect sensors are sensitive to magnetic fields. If you see a small current reading when no load is connected, you can add a small software offset to “zero” the sensor.

To quickly describe our test setup: Our current sensors are soldered to load resistors via pads to withstand high currents. The Arduino Nano sends data to the computer via USB. This data is then used to read PLOT or raw data.
For the first simple test, we successfully read currents even at low currents of 1-3A using the LiPo battery. Later, for higher current tests, we added a MOSFET (IRFP064N) to the circuit, briefly switching the load line on and off via the MOSFET for better performance.
The clamp meter was set to its maximum position to compare the measured values with those of a commercially available clamp meter. Our circuits yielded better results than the clamp meter, especially at low currents and for fast, instantaneous measurements.
Conclusion
By combining isolated Hall-effect sensing with hardware-level timing, you can build a robust system capable of measuring and controlling significant power safely. Whether you are building a battery spot welder or testing motor loads, this framework provides the stability and precision required for professional results.
Arduino codes:
First code is for AN3V sensor it will send values with button interrupt and opens the mosfet for 120mS interval.
/*
* Sensor: Chipsense AN3V 80 PB50
* Nominal Current: 80A
* Sensitivity: 10 mV/A
* Function: Captures peak current within 200ms intervals and
* manages a 120ms MOSFET pulse via button interrupt.
*/
// — 1. GLOBAL CONFIGURATION —
// Pin Definitions
const int PIN_VOUT = A0; // Sensor Signal Output
const int PIN_VREF = A1; // Sensor Reference (Vcc/2)
const int PIN_BUTTON = 10; // Trigger Button (D10)
const int PIN_MOSFET_MAIN = 12; // Primary MOSFET Control
const int PIN_MOSFET_SEC = 3; // Secondary MOSFET/Indicator
const int PIN_LED_UNUSED_1 = 13; // Generic Output
const int PIN_LED_UNUSED_2 = 11; // Generic Output
// Sensor & System Constants
const float SENSITIVITY = 10.0; // 10 mV/A
const float SYSTEM_VCC = 5.0; // Arduino Supply Voltage
const int ADC_RESOLUTION = 1024; // 10-bit ADC
const int PLOTTER_MAX_A = 80; // Reference limit for Serial Plotter
// Timing Settings (ms)
const unsigned long DEBOUNCE_DELAY = 50;
const unsigned long READ_INTERVAL = 20; // Frequency of sensor sampling
const unsigned long PRINT_INTERVAL = 200; // Frequency of Serial output
// — 2. STATE VARIABLES —
volatile unsigned long lastDebounceTime = 0;
unsigned long lastReadTime = 0;
unsigned long lastPrintTime = 0;
float intervalPeakAmps = 0.0; // Stores highest current in the window
float intervalPeakMV = 0.0; // Stores highest mV in the window
void setup() {
Serial.begin(115200);
// MOSFET and Indicator Pin Setup
pinMode(PIN_MOSFET_MAIN, OUTPUT);
pinMode(PIN_MOSFET_SEC, OUTPUT);
pinMode(PIN_LED_UNUSED_1, OUTPUT);
pinMode(PIN_LED_UNUSED_2, OUTPUT);
// Initial State: MOSFETs OFF (Logic 1 in this circuit)
digitalWrite(PIN_MOSFET_MAIN, 1);
digitalWrite(PIN_MOSFET_SEC, 1);
pinMode(PIN_BUTTON, INPUT_PULLUP);
// — INTERRUPT SETUP —
// 1. PCINT (Pin Change Interrupt) for D10 (Button)
PCICR |= (1 << PCIE0); // Enable Port B interrupts
PCMSK0 |= (1 << PCINT2); // Enable specifically for D10 (PCINT2) // 2. Timer1 (120ms MOSFET auto-cutoff) noInterrupts(); TCCR1A = 0; TCCR1B = 0; // Timer remains off until button press triggers it interrupts(); Serial.println(“AN3V 80 PB50 Peak Current Monitor Started…”); Serial.println(“——————————————-“); } // — BUTTON INTERRUPT SERVICE ROUTINE (D10) — ISR(PCINT0_vect) { // If button is pressed (LOW) if (digitalRead(PIN_BUTTON) == LOW) { unsigned long currentMillis = millis(); // Software Debounce if (currentMillis – lastDebounceTime > DEBOUNCE_DELAY) {
lastDebounceTime = currentMillis;
// 1. Activate MOSFET immediately (Logic 0 = ON)
digitalWrite(PIN_MOSFET_MAIN, 0);
digitalWrite(PIN_MOSFET_SEC, 1);
// 2. Configure and start Timer1 for 120ms pulse
// 16MHz / 64 Prescaler = 250,000Hz. 120ms = 30,000 counts.
TCNT1 = 0;
OCR1A = 29999;
TCCR1B |= (1 << WGM12); // CTC Mode
TCCR1B |= (1 << CS11) | (1 << CS10); // Start Timer with 64 Prescaler
TIMSK1 |= (1 << OCIE1A); // Enable Compare Match Interrupt
}
}
}
// — TIMER1 INTERRUPT (Triggers exactly at 120ms) —
ISR(TIMER1_COMPA_vect) {
// 1. Pulse duration finished, Turn OFF MOSFET
digitalWrite(PIN_MOSFET_MAIN, 1);
digitalWrite(PIN_MOSFET_SEC, 1);
// 2. Disable Timer until next button press
TCCR1B = 0;
TIMSK1 &= ~(1 << OCIE1A); } void loop() { unsigned long currentMillis = millis(); // PART 1: SENSOR SAMPLING & PEAK RECORDING (Every 20ms) if (currentMillis – lastReadTime >= READ_INTERVAL) {
lastReadTime = currentMillis;
long voutSum = 0;
long vrefSum = 0;
const int sampleCount = 100;
for (int i = 0; i < sampleCount; i++) { voutSum += analogRead(PIN_VOUT); vrefSum += analogRead(PIN_VREF); delayMicroseconds(50); } float voutAvg = (float)voutSum / sampleCount; float vrefAvg = (float)vrefSum / sampleCount; float voutVolts = (voutAvg * SYSTEM_VCC) / ADC_RESOLUTION; float vrefVolts = (vrefAvg * SYSTEM_VCC) / ADC_RESOLUTION; float deltaMV = (voutVolts – vrefVolts) * 1000.0; float currentAmps = deltaMV / SENSITIVITY; // Peak detection: Update if current reading is higher than existing record if (currentAmps > intervalPeakAmps) {
intervalPeakAmps = currentAmps;
intervalPeakMV = deltaMV;
}
}
// PART 2: REGULAR DATA REPORTING (Every 200ms)
if (currentMillis – lastPrintTime >= PRINT_INTERVAL) {
lastPrintTime = currentMillis;
// Output the peak captured during the last 200ms window
Serial.print(“Difference(mV): “);
Serial.print(intervalPeakMV, 2);
Serial.print(” Current(A): “);
Serial.print(intervalPeakAmps, 3);
Serial.print(” Limit: “);
Serial.println(PLOTTER_MAX_A);
// Reset peaks for the next 200ms monitoring window
intervalPeakAmps = 0.0;
intervalPeakMV = 0.0;
}
}
And next arduino sketch is for CC6921B sensor, as nearly same codes but simpler and ratio values are (10mv/A vs 13.2mV/A, zero reference voltages 2.5v vs 1.65V) is different.
/*
* Sensor: CrossChip CC6921BSO ELC-100A
* Current Range: -100A to +100A
* Sensitivity: 13.2 mV/A
*/
// — CONFIGURATION PARAMETERS —
// Change these values to match your specific hardware setup
const int PIN_VOUT = A0; // Signal output from sensor
const int PIN_VREF = A1; // Reference voltage from sensor (Vcc/2)
const float SENSITIVITY = 13.2; // Sensitivity in mV/A (13.2 for 100A model)
const float SYSTEM_VCC = 3.3; // Arduino supply voltage
const int ADC_RES = 1024; // 10-bit ADC resolution for most Arduinos
const int SAMPLE_COUNT = 100; // Number of samples for averaging
const float OFFSET_CORRECT = 0.0; // Manual current offset correction in Amps
void setup() {
Serial.begin(115200);
Serial.println(“CC6921 100A Current Sensor Test Starting…”);
}
void loop() {
long voutSum = 0;
long vrefSum = 0;
// Sampling loop for a stable reading (noise reduction)
for (int i = 0; i < SAMPLE_COUNT; i++) {
voutSum += analogRead(PIN_VOUT);
vrefSum += analogRead(PIN_VREF);
delayMicroseconds(50);
}
// Calculate the average ADC values
float voutAvg = (float)voutSum / SAMPLE_COUNT;
float vrefAvg = (float)vrefSum / SAMPLE_COUNT;
// Convert ADC values to actual voltage (Volts)
float voutVolts = (voutAvg * SYSTEM_VCC) / ADC_RES;
float vrefVolts = (vrefAvg * SYSTEM_VCC) / ADC_RES;
// Calculate the difference in millivolts (Vout – Vref)
// The CC6921 uses Vref as the zero-current center point
float deltaMV = (voutVolts – vrefVolts) * 1000.0;
// Calculate Current: I = (Vout – Vref) / Sensitivity
float measuredCurrent = (deltaMV / SENSITIVITY) – OFFSET_CORRECT;
// Output results to Serial Monitor
Serial.print(“Diff (Vout-Vref): “);
Serial.print(deltaMV, 2);
Serial.print(” mV | Current: “);
Serial.print(measuredCurrent, 3);
Serial.println(” A”);
delay(50);
}
You can download sketch files below:
https://blog.jsumo.com/wp-content/uploads/2026/02/Current_Read_an3v_80_pb50_PLOTTER.zip
https://blog.jsumo.com/wp-content/uploads/2026/02/Curent_Read_CC6921BSO_ELC100A_SERIAL_FAST.zip
Note: For more details the datasheets can be reachable from this links:
AN3V Sensor Datasheet: https://www.chipsense.net/uploads/pdf/2025-04-22/DS-AN3V%20PB55%20EN-V1.pdf
AN3V Module: https://www.jsumo.com/an3v-80a-current-sensor-200a-absolute-10mv-hall-sensor
CC6921B Sensor Datasheet: https://blog.jsumo.com/wp-content/uploads/2026/02/CC6921B-current-sensor.pdf
CC6921B Module: https://www.jsumo.com/100a-current-sensor-module-cc6921bso-hall-sensor



In the next example, we connected two sensors in series and ensured that the same current passed through them, and we used an Omega Sumo Robot (capable of drawing a sufficiently high current with 2 Mabuchi 775 motors) to measure the current.
The video below briefly shows the currents drawn by the robot during its initial operation and in the forward and reverse modes of the motors that will draw maximum current.

