Simplest possible way to read load cell on teensy

Status
Not open for further replies.

Storbeck

Active member
I need to read a load cell, trying to do it with the greatest simplicity possible for physically assembling things together.

Load cell puts out 2mV/V at full scale, so if I excite it with the 3.3volt supply from the teensy I will be reading a nominally 1.65volt signal with a +-6.6mV differential.

I want to know if I can use the ADC library with a differential measurement, internal 1.2volt reference and the PGA with a gain of 64 (so differential voltage will be +- (6.6mV * 64 = 422mV).

I would then also measure the 3.3volt supply with a ~10:1 voltage divider to another differential ADC channel with the 1.2volt internal reference so I can compensate for drift and inaccuracy between the two.



My questions:

1. This setup would mean I'd be reading a differential voltage of less than the 1.2volt reference, but the absolute level of both the positive and negative side of that differential would be higher than the 1.2volt reference (but less than 3.3)

Is that acceptable?


2. Are there any other obvious pitfalls to doing things this way?


For reference I'm trying to get about .1% resolution, and ~1% accuracy. This is for a datalogger that will be logging at ~100Hz so I can take many data points and average them together. I'd rather not average together the entire 10milliseconds between data points, but I think if I average however many ADC readings I can take in say 1 or 2 milliseconds that still leaves me with quite a few ADC readings (I'll have to test to see how many).

Bridge resistance is ~200ohms.
 
I seem to have answered number 1 myself. Set up the load cell and the teensy as described and it is working quite well. Haven't tried to do the voltage divider for measuring 3v3 yet but the PGA set to 64 measuring the differential signal is working nicely. So it is true differential, doesn't seem to matter what the absolute level of the two pins are as long as the differential is within 1.2/gain.

Sweet.

Now I have to see if I can figure out how to get the other ADC to measure the scaled down .33volts without using the PGA. Hopefully the PGA can be enabled on one ADC but not the other.
 
my experience with low-g load cells: Need a good PGA (gain stage) ahead of a good 12 bit ADC. Plus some averaging and threshold duration, etc.
High sampling rate of course if detecting transients/strikes.
 
I hear you, I'm aware that what I'm doing here is kind of "hackish", but my application is honestly not very demanding, simplicity is very high priority, so far it is looking like this is working.

I think I found an even easier way to account for any variation in the 3.3volt supply that is being used for excitation voltage of the bridge and the 1.2volt internal reference used to measure the bridge output. I'm using the second ADC to measure the internal 1.2volt using the default 3.3 reference. Kind of the backwards version of my original idea to use a voltage divider on the 3.3 to be read by the ADC with the 1.2volt internal ref. Can't do it simultaneous that way but I think that's okay because I'm averaging over ~20-50 (haven't decided yet) samples for each of the ADC's anyway, and it looks like the 1.2 stays pretty stable anyway. This might not even be worthwhile but it *should* (hopefully, right?) compensate for any drift due to changes in supply voltage or temperature.
 
Code:
#include <ADC.h>

ADC *adc = new ADC();

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
//analogReadRes(16);
//analogReadAveraging(32);

    pinMode(A10, INPUT); //Diff Channel 0 Positive
    pinMode(A11, INPUT); //Diff Channel 0 Negative
    
    adc->setAveraging(32, ADC_0); // set number of averages
    adc->setResolution(12, ADC_0); // set bits of resolution
    adc->setConversionSpeed(ADC_VERY_HIGH_SPEED, ADC_0); // change the conversion speed
    adc->setSamplingSpeed(ADC_VERY_HIGH_SPEED, ADC_0); // change the sampling speed
    adc->setReference(ADC_REF_1V2, ADC_0);
    adc->enablePGA(64,ADC_0);

    adc->setAveraging(32, ADC_1); // set number of averages
    adc->setResolution(12, ADC_1); // set bits of resolution
    adc->setConversionSpeed(ADC_VERY_HIGH_SPEED, ADC_1); // change the conversion speed
    adc->setSamplingSpeed(ADC_VERY_HIGH_SPEED, ADC_1); // change the sampling speed
    adc->setReference(ADC_REF_3V3, ADC_1);


    
delay(2000);
}
int value;
int internalvalue;
int averages;
int average;
unsigned long lastmillis;
int internalaverage;
void loop() {
  // put your main code here, to run repeatedly:
//int data1 = analogRead(A10);
//int data2 = analogRead(A11);
//int data = data1-data2;
value = adc->analogReadDifferential(A10, A11, ADC_0);
internalvalue = adc->analogRead(39);
averages++;
average = average + value;
internalaverage = internalaverage + internalvalue;
if (averages >= 50)
{
  
  float refvolt = ((float)internalaverage)*3.3/(4096*averages);
  float forceaverage = average;
  float force = forceaverage*.4766*refvolt/averages;

  
  int conversiontime = millis() - lastmillis;
  lastmillis = millis();
  int zero = 7;
  int forcezeroed = force + zero;
  Serial.println(forcezeroed);
  Serial.println(conversiontime);
  Serial.println(value);
  Serial.println(refvolt,6);
//  Serial.println(data);
  Serial.println(forceaverage);
  
  Serial.println(" ");
  averages = 0;
  average = 0;
  internalaverage = 0;
  delay(250);
}


}
 
That is it at the moment, it is a pretty ugly result of a convoluted trial and error process and I plan on tidying it up quite a bit, but currently it's working as is to simply measure force on the load cell and print force and some diagnostic items to the serial monitor.
 
You may want to consider using an instrumentation amplifier. I know you want to keep things as simple as possible, think of it as trading software complexity vs. hardware complexity.
Have a look at the LTC2053, low voltage, rail-to-rail, runs off of the 3.3V-Rail.
Ben
 
The suggestions are appreciated.

I did experiment with an INA125 amplifier but it adds a lot of complexity, (relative to the simplicity of a bare teensy) and since it looks like I can get the teensy alone to do what I want I'd prefer to avoid it. I will take a look at the LTC2053, but initial impression is it looks like only available as surface mount which is a no go for me.

About the HX711, I'm familiar with those and actually my experimenting with a teensy is for a potential replacement for my current setup which uses an arduino and an HX711. One issue though is that they can be set to sample at approximately 10Hz or approximately 80Hz by setting a pin high or low, and unfortunately the cheap ebay units are set to 10Hz, the only way to change it is to solder a jumper from one of the pins to Vcc, which can be done (I've done it) but not ideal. One can also buy the sparkfun breakout which is a little more expensive but has a trace that can be cut to set the chip to 80Hz. I have been fighting with random stray readings with the HX711 setup, which seem to happen about once every 10 hours, so hard to diagnose. Honestly not a deal breaker for my application, but annoying, and since the teensy looks like it can give acceptable performance with less cost and simpler assembly (and hopefully no random glitches, but we'll see), I'm going to give the Teensy a try.

The arduino HX711 unit is sending data to an lcd screen via a parallel connection and also sending serial data to an openlog to datalog. This is running for long lengths of time (3-4 days) uninterrupted, I'm guessing the random stray readings are coming from some interference between writing to the lcd, writing to serial, and the simple serial connection to the hx711. I'm a mechanical engineer stumbling through the world of electronics so maybe it's a simple problem to solve, and maybe if I simply replace the arduino with a teensy the problem will go away, but I'm really looking for as simple as possible here.

But, we'll see how the teensy does with the load cell once I start asking it to do other tasks at the same time. I might be back to the drawing board with an amp or an external ADC.
 
Another strange post from a first timer... Potential spammer

May be I should present me in the appropriate section but I am not a spammer ;)
I am currently use load cell with complex hardware for finally only toggle inputs not for precise measurement, that is why I am really curious of Storbeck's experience. Regards,
 
May be I should present me in the appropriate section but I am not a spammer ;)
I am currently use load cell with complex hardware for finally only toggle inputs not for precise measurement, that is why I am really curious of Storbeck's experience. Regards,

Vincenet

I ended up doing some tweaking on the version of my device that used an arduino compatible and an hx711 and found it to be satisfactory, so I never followed through with the teensy experimentation. I haven't used the device in several months anyway.

The thing that I didn't like about the arduino and the hx711 is that I didn't know exactly when the sample was being taken, it would sample at a rate of approximately 80Hz, but you don't know that the actual sampling is happening at a steady rate, how much time passes between one sample and another. For my purposes it was okay, and I just lived with it, but with the Teensy you could be more sure.

Also there was less physical complexity with the Teensy using it's internal ADC and PGA.
 
My apologies Vincenet... We've had a rash of spam lately!
Welcome to the Forum.
 
Last edited:
Vincenet what are you using the load cell to do?

"...only toggle inputs not for precise measurement...."

This makes me think it's something like a weight sensor that is used to actuate something, I would think the built in hardware of the teensy should be able to handle that.
 
The company I work for has been using Teensy 3.2 for initial prototyping of a product that will eventually use an MK60 (quad differential ADC). Our first few tests of the part produced results that initially surprised us, and you may want to be aware of the underlying structure.

The PGA is a chopping amplifier, so if you enable the PGA and use no averaging, the results will appear at first glance to be VERY strange: Measurement results produced by the ADC will alternate between values that are too high and values that are too low to make sense.

The Kinetis hardware averaging function selects between None, 4, 8, 16 or 32 samples per delivered result. When using the PGA, it is a very good idea to use averaging, at least of 4 samples. Otherwise it's something that your program should do with its attendant cost of complexity and performance.

FYI, we are doing strain gauge measurements so our use-case is at least peripherally related to your situation.
 
Thanks all for your feedback.

Storbeck, I use load cell to trig notes for (musical) instruments on the floor.
 
So you're just sensing if there is over or under some amount of force?

Do you have any details about your load cell? Exciting with the 3.3 volt supply from the teensy? What sort of mv/v at how much force, etc...

For what reason are you using a load cell sensing force and not just a simple switch?

This sounds like something that the teensy's internal hardware should be able to easily handle.
 
For what reason are you using a load cell sensing force and not just a simple switch?
The load cell is more reliable for our installation.
details about your load cell?
capacity of 200kg with threshold at 2 or 3kg
1.5mV/V
four wires kind (excitation+ excitation- signal+ signal-).
I think I can link the signal- to the ADC_REF_EXT.
Any idea to protect supply against short circuit ?
 
Last edited:
I am not really an expert on this so others can feel free to correct me if I go wrong, but I'll do my best, this is my take on it.

You do not want to connect the signal- to the ADC REF EXT

First let's take a look at if this is even possible.

You said 1.5 mV/V and full scale of 200kg, I assume you mean that the 1.5mV/V is AT the full scale

so, if you excite with the Teensy's 3.3v power supply, you have 3.3*1.5 = 4.95mV/200Kg or .025mV/Kg

if you use the 1.2 volt internal voltage reference (1200mV), with a 13bit resolution ADC (Teensy's ADC has 13 bit resolution in differential mode) you have 8192 steps. You are going to have to use a differential measurement, so really you are measuring +1200mV to -1200mv, so full scale is a total of 2400 mV, so the resolution of your ADC is 2400/8196 = .29mV

This means the smallest change in signal voltage you can measure in this way is .29mV, which would come out to .29/.025 = 11.6Kg. You are looking for something in the neighborhood of 1-2Kg resolution, so this isn't good enough.

BUT...we havn't used the PGA yet.

with a gain of 64, your full scale goes to 3.3*1.5*64 =~317mV/200Kg or 1.59mV/Kg Using the .29mV adc resolution, this means .29/1.59 = .18Kg resolution of your measurement....that's more than sufficient for your needs, so you should be all set.

In reality there is going to be noise and imperfections so the actual resolution might be a bit lower, but for your purposes you have plenty of time to do a lot of averaging, which oddly can effectively improve resolution (it's a hard thing to understand maybe, but you really can effectively increase resolution by averaging a lot of samples). So at least with our basic calculations we can tell we should be in the ballpark, this should be possible.


Okay, it can be done, now how to do it?

I would recommend you study up on the ADC library:

https://forum.pjrc.com/threads/25532-ADC-library-update-now-with-support-for-Teensy-3-1

From this image (linked from the first page of the ADC library thread) you can see that the only easily accessible pins (with through holes) that work with the pga are A10 and A11

https://forum.pjrc.com/attachment.php?attachmentid=1793&d=1396800490



So you'll be connecting your signal+ and signal- wires to A10 and A11. You'll be connecting excitation- and exitation+ to ground and 3.3v power.

For your programming, you should be able to use the ADC library and the example "analogReadDifferential" should get you a pretty good start, or use part of the example that I posted.

You are using the internal 1.2 volt reference voltage, pga gain set to 64, adc resolution 13 (I had it set to 12 in my example for some reason, I think that was a mistake), I would use a high number of averages (I think max is 32) if I were you I'd use fairly low conversion speed and fairly high sampling speed, but I'm really not sure, once you get that far it will take a little experimentation.


For your purposes, I don't think you need to do any of the fooling around with measuring the internal reference voltage, I only did that to deal with any drift of the internal reference or the power supply relative to each other, and I don't think you need to be that worried about accuracy, but you certainly could do it if you like.

If any of that isn't clear, feel free to ask away.

Like I said I'm really not an expert, and I did this a while ago so it's a little fuzzy in my memory, so others may correct me on some things.
 
Status
Not open for further replies.
Back
Top