Skip to content

HX711 library (Queuetue) no longer talks to device with 1.6.7 #169

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
totalgee opened this issue Sep 30, 2016 · 21 comments
Closed

HX711 library (Queuetue) no longer talks to device with 1.6.7 #169

totalgee opened this issue Sep 30, 2016 · 21 comments
Milestone

Comments

@totalgee
Copy link

Hello there, I have a program that's talking to a HX711 (using the Queuetue library), and it worked fine with v1.6.6 of the SAMD tools (I'm using MKR1000). Today I updated to v1.6.7, and the same program, same hardware, no longer seems to talk to the HX711, it just always returns zero as the data measurement.

Any tips on what might have changed that could cause this? The HX711 is hooked up with data on A2 and clock on A3, and there is another device using SCL/SDA for I2C (that device is working with both versions of the MKR1000 driver and tools).

If I revert back to 1.6.6, everything works fine again. Thanks for any thoughts on how to solve this.

@sandeepmistry
Copy link
Contributor

Hi @totalgee,

I've tested shiftIn, digitalWrite and digitalRead with 1.6.7, things seem ok to me. I don't have a HX711 to test with unfortunately.

There have been some changes to pinMode and digitalWrite in #101, which disable the pullup in output mode. Not sure if that is the root cause of you issues.

Could you try replacing cores/arduino/wiring_digital.c with the version from 1.6.6? To see if that was the relevant change. Also, does the same thing happen if you change pins?

@totalgee
Copy link
Author

totalgee commented Oct 2, 2016

Hi, so I tried replacing the wiring_digital.c with the old version from 1.6.6, and it doesn't seem to fix the problem when I rebuild and upload my MKR1000 project.

Just to confirm, do I need to do anything special to build it? I found the file in ~/Library/Arduino15/packages/arduino/hardware/samd/1.6.7/cores/arduino (I'm on OS X) and replaced it with the older file. When I build my project, how do I confirm it's actually compiled and using the modified file? Are there any other steps to perform to test this properly? Thanks.

@totalgee
Copy link
Author

totalgee commented Oct 2, 2016

If it helps, the hx711.readyToSend() function never returns true any more. The code in the library for this function is:

bool Q2HX711::readyToSend() {
  return digitalRead(OUT_PIN) == LOW;
}

(the confusingly-named OUT_PIN is the data pin (in my case, A2), actually an input to the Arduino (output from the HX711 chip))

Maybe that gives you a hint of what might have changed? Some default relating to digital pins?

@sandeepmistry
Copy link
Contributor

Hi @totalgee,

Just to confirm, do I need to do anything special to build it? I found the file in ~/Library/Arduino15/packages/arduino/hardware/samd/1.6.7/cores/arduino (I'm on OS X) and replaced it with the older file.

That's all you need to do, you can add a #error statement to the file and make sure the build fails to see if it is the right file.

Ok, so it doesn't sound like #101 is the root cause them. A few things to try out:

  • The Button.ino example using A2 as the button pin.
  • Try using some other pins as data and clock instead of A2 and A3

@totalgee
Copy link
Author

totalgee commented Oct 7, 2016

Okay, I tried those:

  • The Button.ino example works fine for me with 1.6.7, using A2 as the button pin.
  • Using (for example) A4 and A5 rather than A2 and A3 doesn't work. (both cases work fine with 1.6.6).

Let me know if there's anything else I can do to help track this down.

@totalgee
Copy link
Author

totalgee commented Oct 9, 2016

Hi Sandeep, I tried again, this time with v1.6.6, and only putting in the changes to wiring_digital.c from #101 . So, it does seem related to this after all. I tried using other pins, and the same result...it seems to work well (with whichever pins) when using wiring_digital.c from 1.6.6, and not with the one from 1.6.7. Is there something I can do in my own code to enable the pullup in output mode, when using 1.6.7 (if you think that's related to the problem)? Thanks.

@totalgee
Copy link
Author

totalgee commented Oct 9, 2016

More info: in digitalWrite(), using the 1.6.7 version:

If I add one of the following lines (I suppose they're equivalent) at the end of the function -- i.e. always enabling the pull-up resistor -- then it seems to work fine.

    // Enable pull-up resistor (do one of the following two)
    PORT->Group[port].PINCFG[pin].reg=(uint8_t)(PORT_PINCFG_PULLEN) ;
    PORT->Group[port].PINCFG[pin].bit.PULLEN = 1;

I don't know why it works, but it seems to.

Does this mean the solution is for me to add a hardware pull-up (resistor to Vcc) on that output pin? Or is there a way I can use the existing 1.6.7 code, but force the pull-up in software?

Thanks,
Glen.

@cmaglie
Copy link
Member

cmaglie commented Oct 10, 2016

Does this mean the solution is for me to add a hardware pull-up (resistor to Vcc) on that output pin? Or is there a way I can use the existing 1.6.7 code, but force the pull-up in software?

to enable pull-up you can configure the pin as INPUT_PULLUP:

pinMode(pin, INPUT_PULLUP);

another way that is allowed in the API is to do a digitalWrite(pin, HIGH) while the pin is configured as INPUT:

pinMode(pin, INPUT);
digitalWrite(pin, HIGH); // Enable pull-up but keeps the pin as INPUT

@totalgee
Copy link
Author

Thanks, yes, but this is an output pin, it would need something like OUTPUT_PULLUP (which doesn't exist), wouldn't it? I tried setting it as INPUT_PULLUP anyhow, but this doesn't seem to work. Do I have to call pinMode() again after each digitalWrite()?

@cmaglie
Copy link
Member

cmaglie commented Oct 10, 2016

it would need something like OUTPUT_PULLUP

not sure what you mean here, maybe you want something similar to an open-drain output but with pull-up (so OUTPUT LOW for "0", and INPUT PULLUP for "1")?

I also see that "OUT_PIN" is set as a plain INPUT:

https://github.com/queuetue/Q2-HX711-Arduino-Library/blob/master/src/Q2HX711.cpp#L9

so I don't understand why you need it as OUTPUT (or even open-drain).

Can you please also send a complete sketch that reproduces the problem?
This will help to understand your setup.

@totalgee
Copy link
Author

It's CLOCK_PIN that's the output (from Arduino) and that's causing problems.

I've attached a sketch that shows the problem (it's essentially just the simple_scale example included with the Queuetue HX711 Library). The minimal requirements are an MKR1000 and a HX711 (I have the "green one", not the red one from Sparkfun); you don't need a load cell connected to the HX711 to repro the problem.

Hx711_SAMD_bug169.txt <-- rename to be .ino extension

Alt Green HX711

@cmaglie
Copy link
Member

cmaglie commented Oct 10, 2016

Aaah ok, now I see, thanks for the clarification.

I'm wondering if pinMode(INPUT_PULLUP) is working as expected. May you try to replace:

pinMode(pin, INPUT_PULLUP);

with:

pinMode(pin, INPUT);
digitalWrite(pin, HIGH); // Enable pull-up but keeps the pin as INPUT

?

@totalgee
Copy link
Author

Again...do you mean OUTPUT? The line that seems to be causing trouble is the output (clock). Are you suggesting that I change (in Q2HX711.cpp) the OUTPUT to be an INPUT, then call digitalWrite() to set it HIGH (to enable pull-up)? I've tried various combinations like this (setting the clock output to be INPUT_PULLUP or INPUT followed by set HIGH), with no luck so far.

@cmaglie
Copy link
Member

cmaglie commented Oct 10, 2016

Again...do you mean OUTPUT?

No I really mean INPUT -> INPUT_PULLUP:

Q2HX711::Q2HX711(byte output_pin, byte clock_pin) {
  CLOCK_PIN  = clock_pin;
  OUT_PIN  = output_pin;
  GAIN = 1;
  pinMode(CLOCK_PIN, OUTPUT);
  pinMode(OUT_PIN, INPUT_PULLUP); // <----- add PULLUP here
}

@totalgee
Copy link
Author

Nope, I tried but this does not help the problem. As I mentioned, it's the CLOCK_PIN (OUTPUT) that seems to need to be pulled up, not the OUT_PIN (INPUT).

@cmaglie
Copy link
Member

cmaglie commented Oct 11, 2016

Uhm ok, I'm still missing how you determined that is the CLOCK_PIN that needs a pull-up?
you said that you added a line taken from samd core 1.6.6 here that made it work again, I thought that you added the pull-up to the input but maybe it was the output? may you post the full function?

I'm asking because this is totally counter-intuitive, CLOCK_PIN is an OUTPUT and it should not need a pull-up at all or, put in another way, the OUTPUT pin is (or at least should) be a very strong source, so a weak pull-up should not influence it in any way!

@totalgee
Copy link
Author

Aargh, I think I've got it... It seems that the pins are maybe not set into the right mode after all. The example code for the Q2HX711 library uses a global variable to hold the hx711 object, and in its constructor it does set the pinMode() for both pins. But it seems this happens "too soon"(?). I tried putting the initialization at the start of setup(), and now it seems to work fine. Modified version:

// Same as the attached file above, except added these two lines to setup()

void setup() {
  pinMode(hx711_clock_pin, OUTPUT); // <-- added; same is done earlier,  in Q2HX711 constructor
  pinMode(hx711_data_pin, INPUT); // <-- added; same is done earlier,  in Q2HX711 constructor

  Serial.begin(115200);

  delay(3000);
  Serial.println("Starting up...");
}

These pinMode() calls have already been called in the constructor, but it seems maybe that was "too soon"...

I tried another version, where I create (new) the HX711 object in setup() instead of as a global object, and that also works... Grrr! Sorry for the confusion, it seems we were looking in the wrong place!

@totalgee
Copy link
Author

totalgee commented Oct 11, 2016

As you see, I've added a PR to fix this problem in the Q2HX711 Library. Thanks to Sandeep and Cristian for the help debugging this; it seems there is no bug in the SAMD library.

@cmaglie
Copy link
Member

cmaglie commented Oct 11, 2016

Grrr! Sorry for the confusion, it seems we were looking in the wrong place!

no worries!

Ok that explains it, global constructors on SAMD are called before hardware initialization, even before setup(). I see your PR, looks good, even if, in general, we recommend to add a begin() method that should be called in setup() (like Serial.begin(), Wire.begin(), etc...)

BTW this issue reveals a different behaviour of the SAMD core compared to SAM or AVR, where global constructors are called after hardware is initialized.

This should be fixed IMHO by moving this line from here:
https://github.com/arduino/ArduinoCore-samd/blob/master/cores/arduino/cortex_handlers.c#L160

to here:
https://github.com/arduino/ArduinoCore-samd/blob/master/cores/arduino/main.cpp#L41
just before setup()

This should solve the problem even with the unpatched library. I'll prepare a PR in a moment so we can check this out.

@totalgee
Copy link
Author

Brilliant, thanks, finally something is making sense... (-; Do you want me to open this so you have something so "solve" with your PR, or no?

cmaglie added a commit to cmaglie/ArduinoCore-samd that referenced this issue Oct 11, 2016
This sometimes helps libraries that setups hardware in class
constructor to work properly (in other words allows C++ global
constructors to run after hardware initialization).

See also arduino#169
cmaglie added a commit to cmaglie/ArduinoCore-samd that referenced this issue Oct 11, 2016
This pachs allows C++ global constructors to run after hardware
initialization. This helps some libraries that setups hardware
in class constructor to work properly.

See also arduino#169
@cmaglie
Copy link
Member

cmaglie commented Oct 11, 2016

...just posted: #174 :-)

@sandeepmistry sandeepmistry added this to the Release 1.6.8 milestone Nov 28, 2016
boseji pushed a commit to go-ut/combined-ArduinoCore-samd that referenced this issue May 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants