Problems interfacing the nRF9160 with load sensor and an HX711

Hi Good Day,

Please I am fairly new to the nRF framework and I am facing some problems with a project I am working on. I am trying to interface a load sensor with an nRF9160 using an HX711.

I have a hard time getting values from my load sensor using an HX711. I did some research and saw that there was a repo by nobody guy that gave some documentation on the installation, configuration and use of the HX711 library. So I followed the instructions and everything was installed and compiled successfully.

Problems arise when I connect my load sensors and HX711 with my microcontroller (nRF9160). I keep getting a zero value, even when weight is put on the load sensor. You can see this in the image below.

I am guessing my problems may be coming from my connections. But I don't really know exactly where to start checking. Also, I see that in this code, there are 3 data pins (SCK Dout and rate) and it confuses me a little, cause I am used to working with just 2 data pins when using the HX711 and load sensors.

Will this code affect me if I use a load sensor with just 2 data pins? How may I go about this?
And finally, just to be sure, when a pin is declared as "gpio0 26" for example, does it mean we are using the physical pin labelled as "P0.26" for connection on the nRF board?

Any help would be much appreciated.

Thanks.

  • Hello,

    Are you working with a custom board or the nRF9160 DK? I am asking because I wonder if the pins selected for the HX711 are available or if they are used for other board functions. P0.02 is for instance assigned to LED2 on the DK.  

    Problems arise when I connect my load sensors and HX711 with my microcontroller (nRF9160). I keep getting a zero value, even when weight is put on the load sensor. You can see this in the image below.

    Do you have an oscilloscope/logic analyzer to probe the data and clock line with? This would help troubleshoot the problem.

    I am guessing my problems may be coming from my connections. But I don't really know exactly where to start checking. Also, I see that in this code, there are 3 data pins (SCK Dout and rate) and it confuses me a little, cause I am used to working with just 2 data pins when using the HX711 and load sensors.

    The rate pin controls the sample rate. If pulled low, you will get 10 Hz, and 80 Hz if pulled high. This pin should be hardwired to ground or VDD if it is not routed to a GPIO on the MCU.

    And finally, just to be sure, when a pin is declared as "gpio0 26" for example, does it mean we are using the physical pin labelled as "P0.26" for connection on the nRF board?

    Yes, you have understood it correctly.

    Best regards,

    Vidar

  • Thanks for your reply  .

    1. Please I am working with an nRF9160 DK, and truly pin 2 is assigned by default to an LED. I was wondering if I should change pin 2 in the code, to an unused pin of the nRF9160DK board (pin 25) for example.   

    2. I currently don't have an oscilloscope/logic analyzer for data probing.

    3. Please what if I have an HX711 which just has just DT and SCK data pins, how do I go about using the "rate-gpios" pin?

    The above image is an example of the HX711 copy I have. It has no "VDD" pin. Or would it be better to use an HX711 which has a VDD pin? Like the one below.

  • Hi,

    The RATE pin is grounded on the Sparkfun board as you can see from the schematics here:

    And the board you have does not route the RATE input out on the pin header either. This means you need to remove the "rate-gpios" property from your overlay file so it will not be used by the driver. 

    Overlay without the optional RATE pin assignment:

    /{
    	hx711 {
    		compatible = "avia,hx711";
    		status = "okay";
    		label = "HX711";
    		dout-gpios = <&gpio0 26 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP) >;
    		sck-gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>;
    	};
    };

    Please try P0.10 and P0.13 for DOUT and CLK, these should be routed directly to be pin headers.

    Da-Vinci said:
    The above image is an example of the HX711 copy I have. It has no "VDD" pin. Or would it be better to use an HX711 which has a VDD pin? Like the one below.

    The sparkfun board allows you to use to seperate power rails, but this is not required.

  • Hi  ,

    Thanks for your support. With the insights you gave, and that of my colleagues, I could finally solve the problem.

    Seeing as it was a headache for me to solve this, I assume other newbies like me will have a hard time too, getting around this, so I will leave a well-documented approach to definitely solving this problem from scratch.

    Yes, I am aware that the repo from nobody guy already gives a lot of insight and library documentation. Nevertheless, it will be confusing for an nRF framework newbie. For example, where you have to add the code to the board.overlay file, I had a hard time knowing what it was and understanding how to use it.

    So firstly, to use the HX711, its library has to be installed. This library can be gotten from nobody guy by doing the following;

    1. Ensure your IDE is adequately installed because lacking components might cause problems. Nordic does a great job at explaining how to do this with their course.

    2. After installation, create a simple project from the project templates. The hello world project will do. You can also see what they have done in the course.



      NB: Make sure you are choosing the right locations for your project, SDK and Toolchain installation.

    3. After creating a new project, add a new build for the project.




      NB: Make sure you are choosing the right settings for your board. If you are using the nRF9160DK, you can just use the above settings.

    4. After adding the build configurations, build your project.


    5. After building your project, the next thing will be to install your libraries.

      Close your IDE and go to your installation folder, then open the SDK folder. For me, the path is something like "C:\ncs\v2.2.0\".

      In your installation folder open the ".west" folder.

      In your ".west" open the "config" file in a text editor. This will give you the location of your "west.yml" file.



      As you can see, my "west.yml" file, is found in the "nrf" folder inside my installation folder. So, just go there and open it. My own path to that file will be something like "C:\ncs\v2.2.0\nrf\west.yml".


      In the "west.yml" file, add the following specifications for the HX711 module;

      - name: HX711
            path: modules/HX711
            revision: refs/tags/zephyr-v3.2.0
            url: https://github.com/nobodyguy/HX711_zephyr_driver


      If you look under the "projects:" line, you will see a similar list of module specifications. You can just scroll till you reach the last module, indent from the margin to like the modules above and then add your specifications under them.

      After adding your HX711 module you should have something like the image below;



      After adding the module specifications, save your "west.yml" file and close it.

    6. Open your "command promptapp ("terminal" app for Linux and Mac).

      Navigate to your "west.yml" file location in your command line app.

      Since I am on windows, my location is something like "C:\ncs\v2.2.0\nrf" so I will just use the "cd" command to get into that location, as shown below.



      In your command line app, once you are in this location, update the west module file "west.yml" you earlier modifies and saved. This will verify the specifications you earlier added then download all necessary components for the HX711 module from nobody guy's repo.

      To update your "west.yml", make sure you are connected to the internet, then enter the command "west update" in your command line app. That will look something like the images below;



      Once done, you should see your module file start updating, as below;



      Then you should see that one of the modules updated is the HX711 module, as in the image below;



      If you see that, it means your module has been successfully installed.

      It happens sometimes that you get an error, as I did. That usually is because either "Python" or "West" is not installed on your PC.

      Make sure that your "Python" and "West" are installed and up to date, especially "Python", because "West" is just actually a "Python" module and depends on "Python" to work.

      Verify if "Python" is installed, by simply typing the "python --version" command, in your command line app. You should see your "Python" version, as shown below.



      If your command line environment doesn't recognize "Python", it's probably because you are lacking python on your PC. Go to the Python website, and get instructions on how to install python for your operating system.

      If python is installed, make sure you upgrade "PIP" to the latest version. you can use the "python -m pip install --upgrade pip" command, in your command line app.

      NB: you may have to run your command line app with administrator privileges.

      Verify if "West" is installed, by simply typing the "west --version" command, in your command line app. You should see your "West" version, as shown below.



      If your command line environment doesn't recognize "West" it's probably because you are lacking the west module for python. Install the west module by typing the command "pip install west" in your command line app. As shown below;



      If you earlier had trouble using the  "west update" command, after installing "Python" and "West", you can try the "west update" commandAs you can see for me, "West" is already installed.

    7. The next thing to do is to enable your sensor driver. To do that, open your IDE and launch your project. In your project file explorer, locate the "prj.conf" file and open it.



      Add the following lines in your "prj.conf" file;

      CONFIG_SENSOR=y
      CONFIG_HX711=y
      CONFIG_LOG=y




      Once your file is modified, save it. Your project will automatically build to update the changes.

    8. The next thing will be to define the HX711 and the pins it uses, in your overlay file. To do that, start by creating an overlay file, by clicking on "create" an overlay, which you most probably don't have by now.

      Create by clicking on the "No overlay files Click to create one" option



      Open the "overlay" file and add the following code as shown below;

      /{
      	hx711 {
      		compatible = "avia,hx711";
      		status = "okay";
      		label = "HX711";
      		dout-gpios = <&gpio0 2 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP) >;
      		sck-gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
      		// rate-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>;
      	};
      };




      So, if you have already checked the instructions on nobody guy's repo, you may see that my overlay code is slightly different.

      I changed the pins of "dout-gpios" and "sck-gpios" to 2 (P0.02) and 3 (P0.03) respectively, because those pins also coincide with the nRF9160 onboard LEDs 1 and 2 respectively. This is so that if the code and hardware work properly, you should see the LEDs corresponding to these pins flash their lights.

      I also commented the line for the "rate-gpios" pin, out, because as  , earlier said above, my HX711 doesn't provide room for that pin and it is not necessary in my case.

      If your HX711 does support that pin, you will have to connect the "rate-pin" of your HX711 to pin 25 (P0.25) of your nRF9160 DK, as that is the dedicated pin for clock connections on the nRF9160 DK. If you are not using the nRF9160 DK like me, then you will have to check for your dedicated clock pin by looking at the back of your board, or by checking your board specifications on nordic's website.



    9. The next thing will be to edit your "main.c" file;



      Add the following code to your "main.c" file;

      /*
       * Copyright (c) 2012-2014 Wind River Systems, Inc.
       *
       * SPDX-License-Identifier: Apache-2.0
       */
      
      #include <zephyr/kernel.h>
      #include <zephyr/device.h>
      #include <zephyr/devicetree.h>
      #include <zephyr/drivers/sensor.h>
      #include <zephyr/logging/log.h>
      #include <zephyr/sys/util.h>
      #include <zephyr/types.h>
      
      #include <sensor/hx711/hx711.h>
      #include <stddef.h>
      
      LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);
      
      const struct device *hx711_dev;
      
      // void set_rate(enum hx711_rate rate)
      // {
      // 	static struct sensor_value rate_val;
      
      // 	rate_val.val1 = rate;
      // 	sensor_attr_set(hx711_dev,
      // 			HX711_SENSOR_CHAN_WEIGHT,
      // 			SENSOR_ATTR_SAMPLING_FREQUENCY,
      // 			&rate_val);
      // }
      
      void measure(void)
      {
      	static struct sensor_value weight;
      	int ret;
      
      	ret = sensor_sample_fetch(hx711_dev);
      	if (ret != 0) {
      		LOG_ERR("Cannot take measurement: %d", ret);
      	} else {
      		sensor_channel_get(hx711_dev, HX711_SENSOR_CHAN_WEIGHT, &weight);
      		LOG_INF("Weight: %d.%06d grams", weight.val1, weight.val2);
      	}
      }
      
      void main(void) {
      	int calibration_weight = 1000; // grams
      	hx711_dev = DEVICE_DT_GET_ANY(avia_hx711);
      	__ASSERT(hx711_dev == NULL, "Failed to get device binding");
      
      	LOG_INF("Device is %p, name is %s", hx711_dev, hx711_dev->name);
      	LOG_INF("Calculating offset...");
      	avia_hx711_tare(hx711_dev, 5);
      
      	LOG_INF("Waiting for known weight of %d grams...", calibration_weight);
      
      	for (int i = 5; i >= 0; i--) {
      		LOG_INF(" %d..", i);
      		k_msleep(1000);
      	}
      
      	LOG_INF("Calculating slope...");
      	avia_hx711_calibrate(hx711_dev, calibration_weight, 5);
      
      	while (true) {
      		// k_msleep(1000);
      		// LOG_INF("== Test measure ==");
      		// LOG_INF("= Setting sampling rate to 10Hz.");
      		// set_rate(HX711_RATE_10HZ);
      		measure();
      
      		// k_msleep(1000);
      		// LOG_INF("= Setting sampling rate to 80Hz.");
      		// set_rate(HX711_RATE_80HZ);
      		// measure();
      		k_msleep(1000);
      	}
      }


      Again, I have slightly modified the code from nobody guy's repo. This is because in the earlier overlay file, I had commented out the  "rate-gpios" pin, given that I was not going to use it. So, I removed all the code that was related to, or referenced the "rate-gpios" pin in the overlay file.

      After adding the code, do a "Pristine Build" for your project, as shown below;



      When your build is done, one important thing you MUST do else your project will not work, is to enable your microcontroller board to read VDD (3V) signal. By default, Nordic sets their boards to not to VDD(3V), but for your case you will need it, because as  earlier said, VCC of the HX711 board is connected to VDD of the nRF9160 DK board.

      To enable VDD, locate the small switch button just beside your power switch button. If your board is new, you may see a dark-brownish thin plastic paper covering the VDD switch. remove the plastic then push the switch to VDD.



      NB: Make sure your switch button is on the side of 3V as in the image above ELSE YOUR BOARD WILL NOT READ YOUR SENSOR DATA.

      Once VDD is set, you can proceed with your connections. I did mine as follows;


      Load sensor red-wire to HX711 E+ pin
      Load sensor black-wire to HX711 E- pin
      Load sensor white-wire to HX711 A- pin
      Load sensor green-wire to HX711 A+ pin
      HX711 VCC pin to nRF9160 VDD pin
      HX711 SCK pin to nRF9160 P0.03 pin
      HX711 DT pin to nRF9160 P0.02 pin
      HX711 GND pin to nRF9160 GND pin

      Once that is done, flash your board with your code;



    10. Once your board is complete with flashing, connect to a COM PORT and check the nRF Terminal for readings;



      I had set my calibration value to 1KG, because I had a know weight of 1KG. But you can change it to suite your known weight. Make sure during calibration, you put your weight on the load sensor, when you see the count down in your nRF terminal.

      If you want to use the exact code I did, you can get my project from my repo. Since this is basically the code from no body guy's repo that I modified, I put the code in my repo under the same license (Apache-2.0 license) make sure you read the license before using the code.

      I also have a colleague that worked on the SAADC method of using load sensors with nRF9160 DK, may also want to clone the repo and check it out.

      HOPEFULLY THIS DEFINITELY SOLVES AND SEALS THIS PROBLEM.
Related