4

I have been porting the library for HX711 (Weighting sensor module amplifier) for Arduino to C# for Raspberry Pi Windows 10 Core. Source here on GitHub Arduino library

It does work, I am even using basically the very same calibration_factor I was using on Arduino, so it seems the code side of things is working as expected.

BUT, and that is the reason for my questions, I see some (seemingly random) readings that are way out of line. Meaning, with no weight on the scale, I normally read a value 1/2 gram around 0 (+ or -), but sometimes, I read values of ~500, or even around 1 million something! (Then it get immediately back to expected values)

I guess I could code around this to eliminate values + or - 10% around a sample of readings, but I wonder if there would not be some electronic way to regulate pins readings, instead of coding around.

I was having variations on the Arduino, but never of such magnitude.

  • I did not investigate how the sensor works but beware if it does not hold the signal low, and you have not used/configured a pull-down, the input value will float as if disconnected. This may be the case if the problem only occurs with the scale unloaded. – goldilocks Jan 19 '16 at 18:31
  • Thanks for your answer. I am not a specialist, so it may take me a little time to fully understand and use this idea, but I will do my best to try. – BernardG Jan 19 '16 at 18:37
  • I'm probably wrong, looking at that thing here. It would only make sense if when unloaded there is something that literally disconnects the input from anything including ground. By "floating" I mean a high-Z state; this is what a bare pin does. – goldilocks Jan 19 '16 at 18:47
  • Does the same thing happen when you place a weight on? Do you get random high values? – Piotr Kula Jan 19 '16 at 20:46
  • @goldilocks - Thanks for your interest and your answers. It does not happen only when the scale is unloaded, and from the way pins are initialized, I doubt one would be "bare". – BernardG Jan 20 '16 at 23:24
3

As I did not find another way, I coded around the difficulty. It's not perfect, but is better than nothing.

Instead of simply returning an average of readings, I eliminate the 2 higher, as it seems the problem is always with big values:

public float read_average(int times = 10)
    {
        float[] readings = new float[times];
        float sum = 0;
        for (byte i = 0; i < times; i++)
        {
            readings[i] = read();               
        }
        Array.Sort(readings);
        for (byte y = 0; y < (times - 2); y++) // eliminate the 2 larger values.....
        {
            sum += readings[y];
        }
        return sum / (times - 2);
    }

Array.Sort makes this easy. If anyone has a better way, I am listening...

EDIT

Based on your answers, here is the revised method, where I first take out extreme values, then filter based on average + and - a percentage:

    public float read_average(int times = 10)
            {

                float[] readings = new float[times];
                float sum = 0;
                float goodSum = 0;
                for (short i = 0; i < times; i++)
                {
                    readings[i] = read();               
                }
                Array.Sort(readings);
                for (short y = 1; y < (times - 2); y++) // eliminate extreme values.....
                {
                    sum += readings[y];
                }
                float avread = sum / (times - 3);
                float avreadPlustenpercent = avread * (float)(1.0 + SPREAD);
                float avreadMinustenpercent = avread * (float)(1.0 - SPREAD);

                List<float> goodReads = new List<float>();
                for(short w = 0; w < (times -2); w++)
                {
                    if (readings[w] < avreadPlustenpercent && readings[w] > avreadMinustenpercent)
                    {
                        goodReads.Add(readings[w]);
                    }
                }
                foreach (var item in goodReads)
                {
                    goodSum += item;
                }
                if (goodReads.Count > 0)
                {
                    return goodSum / goodReads.Count;
                }
                else
                    return 0;


            }
  • For now, maybe checking if the value if above a threshhold, dont know wha the max is on this? But set a upper limit maybe and discard any reading that is way above the limit. The issue may be a IoT Driver problem or an OS latency issue, but maybe a pull down is required on the pin to help solve this. Did you set your code to initialise the pin with pull down? On the Pi you can set if you want the PIN pulled up or down after init, unlike Arduino where you have to pull it down manually with a resistor – Piotr Kula Jan 19 '16 at 20:48
  • Also from a C# sematics point of view, you should not use byte as a counter as it is really reserved for byte arrays. I know its 255 and only takes up 8 bits in memory, but it is more readable to use short or int - Just from a professional point of view - as bytes cause conversion issues later if you tend to overuse them, and really the extra bits wont cause any serious problems with memory, leaving your code to be more future proof. One problem I see now if if somebody set times to 300, your loop will cause an exception when hitting 255+1, or overflow and never end. – Piotr Kula Jan 19 '16 at 21:00
  • Did you have a look at this source code? github.com/ggurov/hx711 - It is Raspberry Pi specific. The Pi may contain some specific GPIO settings that Arduino does not require. It seems like the problem is caused by OS not being realtime like Arduino. So you have to put in software safeguards against crazy values. – Piotr Kula Jan 19 '16 at 21:14
  • @ppumkin - Thanks for your help. I had been looking at the source code you linked to, and used his idea in my revamped read-average method. I filter twice, and its much better now. Maybe not perfect, but usable for the calculations I need to make based on those readings. – BernardG Jan 20 '16 at 23:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.