Data sampling of load cell to determine the impact force

Hi guy's
I'm very new to Arduino, but I really need help with my project!
I want to use a load cell to measure the impact force that is acting on the load cell. Since I want to map out as much as possible data of the force that is acting on the Load cell ( minimum & maximum force and time duration of that force). I thought if I use the ADC free-running mode connected to the Load cell this will give me almost 500k sample ratings per second, but I really don't know how to do that?
Did someone already do such a project before?
Or does anyone knows how to solve this problem?

As a professional I have a genuine experience from things like this. The sails people wanted an "impact sensor" and we tried to design that. In the final end, the sensor did not detect the kind of impacts that the customers wanted.
Suppose You collide with a one ton bail of cotton, or a one ton block of steel...... I assure You the experiences will differ more than a lot.

The cotton collision will give shock waves during "some time" but the collision with the block of steel will give much higher values at a much higher frequency during a lot shorter time.

What kind of collisions do You intend to monitor?
Facing that question during several years I say, reconsider, or drop the project.

The body is going to collide with load cell is made from hard plastic. Basically, I have an arm designed like a hammer that will hit the load cell every now and then.
I want to study the force that is acting on the load cell.

Okey. Using known surfaces colliding You are getting closer.
Do You know the theory about the energy in collisions? Do You know about the ( I think ) Q factor? Steel against steel has a high Q factor and a soft ball against another soft ball has a very low Q factor?
I don't remember the frequency of the steel to steel collision, or steel versus concrete...

Be prepared for using high frequency sampling, the harder materials, the higher the frequency. I think You need to use certain collision surfaces and the sensor attached to one of them. Then the question is how long the load cell will survive.

What is the real purpose of the project? What is that "body" You want to use?

Where and how do You intend to store that amount of data? It's difficult!

The real purpose of this project is to determine the exact velocity of the collision. Since F average = - mass * Velocity. If I know the average force during the time interval and the mass of the plunger, I can easily determine the velocity of the hammer that is hitting the load cell. The biggest challenge is that the distance that the hammer is covering before hitting the load cell is Just 5 cm.
So the process is going like this. The hammer is going up for 5 cm and then free fall and collide with the load cel.

I did the same thing but used an oscilloscope to capture the event. And, because it was a DSO I could trigger at a point that wasn't particularly low. Its been way too long to recall the time scale.

I suggest you setup an Arduino to run the A/D as fast as you can collect the data. Plot it out and see what you get. If the plot suggests you are missing critical data then consider how to make the sampling faster.

I can easily determine the velocity of the hammer that is hitting the load cell

I don't think it will be that easy. You would have to know the material and shape details of the exact materials you are using.

For velocity I would suggest either an encoder on your swing arm pivot, or even a lowly potentiometer.

That is wrong! F = m * g, mass times gravity. Analyzing the variables mass is given in Kg, LBS and gravity in distance/ second in square. In SI variables it ends up in Kg * m /s /s.

You use F = M * v, force is mass times velocity. Totally wrong!
In SI variables it ends up in Kg * m /s. Completely wrong dimension.

There is a factor, don't know in English, movement torgue. A lot different.

Check the formulas in Your physics handbook!

weight = m * g

more generally, force = m * a

The OP may find it helpful to focus on the impulse and momentum equations and how they pertain to collisions.

Sorry my mistake I meant momentum dp = mv2-mv1

Oops. Wrong. Weight is mass, not force! Weight measures in kg or LBS. Force measures in Newton or whatever in Imperial units.

Corrected: force = m * a..... That's perfectly correct.
Thanks! Impulse and momentum sounds like proper words in English.

@ fahooodi
momentum dp = mv2-mv1.... What is v2 and v1? Speed before impact and speed after impact? Then You would need to measure speed near the collision zone. How will You know dp?

I've got more than one lesson at the university to check the units of the variables used. That verifies the formula used.
Sometimes members want to convert analog readings to God knows what. It just doesn't work....

Re reading the goal, is it correct that you are trying to calculate the velocity of a mass in a freefall from 5cm? Then why the need for the load cell?

BTW KE = 1/2 mv^2


S = 1/2 at^2
V = at

1 Like

How long do you expect the impact collision to last? A few mS? A few tens of mS? You can sample very quickly but you need to put that 10-bit data somewhere and the easiest and quickest place is SRAM.

On an AVR like a Mega2560, you have 8K of SRAM; if you use 16-bits of storage per sample then you have a theoretical maximum of 4096 samples you can save. Since the program itself needs memory, you'd be down from that of course.

This example for a Mega2560 is "armed" by a low-going input on pin 2. The logging is triggered when the ADC result is > 300 and 3500 continuous samples are taken. It takes 3500 samples at 125,000 samples per second giving a sample window of 28mS.

Is that enough to capture your impact data? If you need more or faster sampling, you can probably adapt this to another processor like, say, the Due.

const uint16_t k_TriggerCnt     = 300u;         //#     counts  ADC count threshold to start logging when armed
const uint16_t k_uBuffSize      = 3500u;        //#     bytes   number of samples to take

const uint8_t pinArm    = 2;            //arm input (high-to-low arms logging)
const uint8_t pinDbg    = 7;            //debug output (duration of logging)
const uint8_t pinLED    = LED_BUILTIN;  //armed indicator (ON when armed, OFF when logging complete)

typedef enum
    ST_IDLE     = 0,

volatile bool
    bArmed = false;
void setup( void )
    //ADC setup
    ADMUX = _BV(REFS0);
    DIDR0 = _BV(ADC0D);    

    pinMode( pinArm, INPUT_PULLUP );
    armLast = digitalRead( pinArm );
    pinMode( pinLED, OUTPUT );
    pinMode( pinDbg, OUTPUT );

    //using Serial Plotter so can use high speed
    //make sure serial plotter or monitor is set to same rate
    Serial.begin( 2000000 );

void loop( void )
    static uint32_t
        timeRead = 0ul;    
    static uint8_t
        stateLoop = ST_IDLE;
        timeNow = millis();
    switch( stateLoop )
        //waiting for arm signal
        case    ST_IDLE:
            //read arm input once every 50mS
            if( (timeNow - timeRead) >= 50ul )
                //look for falling edge
                timeRead = timeNow;
                uint8_t armNow = digitalRead( pinArm );
                if( armNow != armLast )
                    armLast = armNow;
                    if( armNow == LOW )
                        //armed; set LED on and flag to ISR
                        digitalWrite( pinLED, HIGH );
                        bArmed = true;                
                        //move to logging state
                        stateLoop = ST_LOGGING;


        //logging is armed
        case    ST_LOGGING:
            //ISR sets bArmed false when logging complete
            if( bArmed == false )
                //when done turn off the LED and print the contents of the buffer
                //plot on serial plotter (e.g.)
                digitalWrite( pinLED, LOW );                
                for( uint16_t idx=0; idx<k_uBuffSize; idx++ )
                    Serial.println( adcBuff[idx] );

                //and go back to waiting for another arm
                stateLoop = ST_IDLE;


ISR( ADC_vect )
    static uint8_t
        stateADC = ST_IDLE;
    static uint16_t
    //grab this result
    uint16_t cnts = ADC;
    switch( stateADC )
        //ADC freewheeling
        case    ST_IDLE:
            //ADC is free-running but results not being used yet
            //are we armed?
            if( bArmed == true )                
                stateADC = ST_ARMED;    //move to armed state if so

        //waiting for ADC result to meet or exceed logging-start threshold
        case    ST_ARMED:
            //if result is at or above threshold...
            if( cnts >= k_TriggerCnt )
                //indicate start of logging
                digitalWrite( pinDbg, HIGH );
                //reset buffer index and store this result
                hPtr = 0;
                adcBuff[hPtr++] = cnts;
                //and move to logging state in ISR
                stateADC = ST_LOGGING;

        case    ST_LOGGING:
            //place result in next buffer location
            adcBuff[hPtr++] = cnts;
            //if buffer is full...
            if( hPtr == k_uBuffSize )
                //indicate logging stopped
                digitalWrite( pinDbg, LOW );
                //setting bArmed low signals loop() logic that logging is done
                bArmed = false;           
                //and return to IDLE state     
                stateADC = ST_IDLE;
}//ADC interrupt

I'm using Arduino Due to store the data and then I want to plot this data in a chart using so I can analyze it and then measure the impact velocity of the force.

  • Can your load cell handle the high frequency of the impact?
  • Does the load cell measuring electronics have the bandwidth to pass the signal through?
  • What measurement resolution do you need?
  • How many samples do you need to store?
  • How will you trigger the sampling start?

Even if the arduino meets your resolution & accuracy specs, be aware that you'll have to directly manipulate the ADC registers. analogRead() is not nearly fast enough for this.

F = (M(V^2))/2

Force = (Mass x (Velocity x Velocity))/2.
Momentum = Mass x Velocity.
Acceleration is the first derivative of Velocity.
So, therefore, Force = Mass x Acceleration.

That being said - if you really want to understand what your sensor is logging, without having to adjust for coefficient of restitution, why not just baseline it against some known good reading? Any sensor as unsophisticated as this, is going to have to be single threaded. (calibrated against one, and only one, use case at at time)

I understand that, however I know in freefall, the hammer will accelerate to a velocity in 5cm and is 100% calculatable. This is especially true because the velocity will be low enough air resistance will negligible.

Consider your target in two cases:

  1. A piece of steel. Deceleration will have a high peak and a short duration. Not all energy will be absorbed and the hammer will bounce.

  2. A slab of clay. Deceleration will have a much lower peak, a longer duration and all or most of the energy will be absorbed in the clay.

However I recommend you perform your test. Not worry about if the Arduino is as fast as you need. Then look at the data to decide if the data is adequate or not. One can postulate all day, but in my experience going ahead and performing a test is much faster and more fruitful than analyzing it to death.

Not an easy problem to solve …. Additionally you have bounce , the mass of the target , response times, shock waves , how rigidly it is mounted , contact areas, surface deformation and so on …

I guess my question is why do you want to do this ? There may be a different way

Not in this universe.