Coder Social home page Coder Social logo

Comments (24)

bogde avatar bogde commented on July 18, 2024 1

i think i have some nrf52832 too, and a (cheap) logic analyser, i'll try to look into this if time permits. thanks @electrokean for all your effort.

from hx711.

amotl avatar amotl commented on July 18, 2024 1

Hi Pooya,

[1] lists two items regarding support for SAMD, however those have not been tested. We will be happy to hear if the library works properly on a nRF52, so please get back to us.

The background on needing to implement specific support for ESP8266 and ESP32 is that those are considered to be FAST_CPUs, along with STM32 and SAMD, see also #123. That means that for those, we use the shiftInSlow() function in order to slow down the bitbanging needed to properly read out the HX711.

HX711/src/HX711.cpp

Lines 36 to 62 in 75dfed4

#if FAST_CPU
// Make shiftIn() be aware of clockspeed for
// faster CPUs like ESP32, Teensy 3.x and friends.
// See also:
// - https://github.com/bogde/HX711/issues/75
// - https://github.com/arduino/Arduino/issues/6561
// - https://community.hiveeyes.org/t/using-bogdans-canonical-hx711-library-on-the-esp32/539
uint8_t shiftInSlow(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) {
uint8_t value = 0;
uint8_t i;
for(i = 0; i < 8; ++i) {
digitalWrite(clockPin, HIGH);
delayMicroseconds(1);
if(bitOrder == LSBFIRST)
value |= digitalRead(dataPin) << i;
else
value |= digitalRead(dataPin) << (7 - i);
digitalWrite(clockPin, LOW);
delayMicroseconds(1);
}
return value;
}
#define SHIFTIN_WITH_SPEED_SUPPORT(data,clock,order) shiftInSlow(data,clock,order)
#else
#define SHIFTIN_WITH_SPEED_SUPPORT(data,clock,order) shiftIn(data,clock,order)
#endif

With kind regards,
Andreas.

[1] https://github.com/bogde/HX711#hal-support

from hx711.

electrokean avatar electrokean commented on July 18, 2024

What exactly are you trying to do with this operation?
retVal = retVal << (1 && j);
I'd guess you're trying to avoid shifting on the last bit. That would multiply your reading by 2, which is what appears to be happening.

Surely it is easier to have the loop do this (swap the order):

retVal = retVal << 1;
retVal |= readVal & 0x01;

The first shift does nothing as the retVal starts with 0.

from hx711.

mashhashkarma avatar mashhashkarma commented on July 18, 2024

retVal = retVal << (1 && j);
will reduce to
retVal = retVal << 0 ; when j becomes 0.
I didnt quite undersatand how this is result in multiplication by 2.

However,the suggestion you made to swap the statements is valid.

from hx711.

mashhashkarma avatar mashhashkarma commented on July 18, 2024

typo correction "...undersatand how this would result in ... "

from hx711.

electrokean avatar electrokean commented on July 18, 2024

Agreed, it seems like it "should" work, but it depends on how the compiler treats logical values. Pretty sure that isn't clearly defined.
A safe alternative might have been:
retVal = retVal << (j?1:0);

from hx711.

mashhashkarma avatar mashhashkarma commented on July 18, 2024

As per HX711 datasheet the range of values should be between 800000h (MIN) and 7FFFFFh (MAX). But as you can see i'm getting 8 digit values on the other board, though in Arduino it is 7 digit.
Note that the same code is running on both the MCU's (both are ARM COrtex M0).

from hx711.

mashhashkarma avatar mashhashkarma commented on July 18, 2024

I can try retVal = retVal << (j?1:0); But not convinced it will solve.
Is there any other cause you can think of that can result in this kind of behavior?

from hx711.

electrokean avatar electrokean commented on July 18, 2024

So you're running exactly the same code on both? Both via Arduino IDE? Same gcc version?
You say both are running Cortex M0, so which "Arduino" are you using? Same CPU speed?

The only thing that worried me in you original code I highlighted, as it could have led to incorrect shifting. I've seen various compiler bugs over the years, including problems with shifting by 0.

In reality you should be sign extending the values = i.e. 800000h => FF800000h to get a 32-bit signed.
That's what this code in the library is for (which you left out):

	// Replicate the most significant bit to pad out a 32-bit signed integer
	if (data[2] & 0x80) {
		filler = 0xFF;
	} else {
		filler = 0x00;
	}

	// Construct a 32-bit signed integer
	value = ( static_cast<unsigned long>(filler) << 24
			| static_cast<unsigned long>(data[2]) << 16
			| static_cast<unsigned long>(data[1]) << 8
                        | static_cast<unsigned long>(data[0]) );

Just picking two of your example readings:
8315440 is 7EE230h, and doesn't need sign extending - but seems awfully close to the max conversion range limit, so it doesn't seem valid.
16746303 is FF873Fh, and extended that is FFFF873Fh = -30913 decimal - which looks perfectly valid.

Something you're doing must be different for these to be read differently from the HX711 on the two platforms.

from hx711.

electrokean avatar electrokean commented on July 18, 2024

BTW retVal = retVal << (j?1:0); was just a suggested alternative to your original logic, because I believe (1 && j) is not guaranteed to return 0 or 1 (just 0 and non-zero). But that could still trip up a compiler or CPU that doesn't like shifting by zero. I'd stick with the shift prior to OR'ing the next LSB.

from hx711.

mashhashkarma avatar mashhashkarma commented on July 18, 2024

Hi, sorry for the delayed response, was sucked into something else.
Firstly i wish to correct myself and say i'm using Arduino UNO and NRF52832 (has Cortex M0).
I did an experiment of simply tabulating the values read from HX711 when using Arduino and when using NRF. I see some bizarre stuff happening and request all to help me understand and fix the matter. I have posed some questions below the table.

SETUP

The same Loadcell and HX711 is used. Once Loadcell is connected to HX711 it remains that way. HX711 connected to NRF first and readings taken.
Then the wire connection from HX711 changed to Arduino and readings taken.
The HX711_read() is minimized to just reading the bits from HX711 i.e the read value is not modified (not even XOR'ing with 0x8000). Have pasted the code at the end.

TABULATED READINGS

image

QUESTIONS

a) Why is the HX711 readings -ve when read via Arduino and +ve when read via NRF(CortexMO)
b) Why are the readings read via Arduino double that of readings read from NRF(Cortex MO)
c) When using NRF, the MAX value 0x7FFFFF(as per spec) is crossed when the 300gms replaced with 400 gms. Similarly the MIN value of 0x800000(as per spec) is crossed when using Arduino when the 300gms replaced with 400 gms.In both cases the values seem to restart from 0 after crossing. This is contradictory to specification which says it saturates at MIN and MAX value.

from hx711.

mashhashkarma avatar mashhashkarma commented on July 18, 2024

Forgot to paste the code. Here it is.
long HX711::read() {
byte readVal=0;
long retVal=0;

// wait for the chip to become ready
while (!is_ready())
	{}

Serial.println(F("Reading HX711... "));

for (int j = 23; j >= 0; j--) 
{
	digitalWrite(PD_SCK, HIGH);
	readVal=digitalRead(DOUT);
	digitalWrite(PD_SCK, LOW);
	
	retVal = retVal << 1;
	retVal |= readVal & 0x01;
				
}

// set the channel and the gain factor for the next reading using the clock pin
for (int i = 0; i < GAIN; i++) 
{
	digitalWrite(PD_SCK,HIGH);
	digitalWrite(PD_SCK,LOW);
}

Serial.print(F("HXvLOG:HX711Read():RetVal "));
Serial.print(retVal);
Serial.print(F(" Diff "));
Serial.println((retVal-OFFSET));
return retVal;

}

from hx711.

electrokean avatar electrokean commented on July 18, 2024

The values returned by the Arduino look completely normal. The values read from the HX711 need to be sign extended as I've explained above. So 0x800000 is actually 0xff800000 or -8388608 decimal, and 0x7fffff is 8388607, giving a full 24 bit range of 16777216. Of course, you don't typically get that full dynamic range.

Thus, your values in the table above starting with FF when sign extended to 32 bit will be smaller negative values. At 0g you have 0xfffedc77 which is -74633. That is your zero offset (tare), and a small negative offset is nothing to worry about.

At 700g you have 94294 - -74633 or a total of 168927, which means approx 241 counts per gram.

Why your code on the Cortex M0 isn't working I can't exactly explain, nor have the time to try reproduce, but it clearly is only half the expected value. The only thought I have other than a hard to spot bug, is that the Cortex M0 is pulsing the clock and reading the result too fast for the HX711. Actually, you could try moving the digitalRead() to after the falling pulse on PD_SCK and see if that helps.

for (int j = 23; j >= 0; j--) 
{
	digitalWrite(PD_SCK, HIGH);
	digitalWrite(PD_SCK, LOW);
	readVal=digitalRead(DOUT);

	retVal = retVal << 1;
	retVal |= readVal & 0x01;			
}

Any reason you aren't using the code from the library (which is known to work, and does sign extension), rather than writing your own read function?
If you're asking for support on this library, but are actually using your own code, the least you could do is test if the actual library read function give the expected results?

from hx711.

mashhashkarma avatar mashhashkarma commented on July 18, 2024

hi there,
In my earlier experiment, i was trying to analyse and compare the 24 bits read from HX711 in case of Arduino and NRF, hence did not use the library code.
This time i used the library code with only change that instead of ShiftIn() i have read bits into data[ ].
I Have done this so that same code i can run on both Arduino and NRF. The code is later on below.
Well, on Arduino everything works well, as you can see in the table below i.e readings are fine, weight measurements are coming out well.
However, on using same code on NRF, the readings are not good, as you can see in the table below.
By the way i did take in your suggestion of moving the digitalRead() to after the falling pulse on PD_SCK.

Any other suggestions you may have ? If you would like to run some experiments, please tell me , i can do it.

image

Below is the code of HX711::read().
long HX711::read() {
uint8_t readVal=0;
unsigned long value = 0;
uint8_t data[3] = { 0 };
uint8_t filler = 0x00;

// wait for the chip to become ready
while (!is_ready());

// pulse the clock pin 24 times to read the data
// read MSB
for (int j = 0; j <8; j++) 
{
	digitalWrite(PD_SCK, HIGH);
	readVal=digitalRead(DOUT);
	digitalWrite(PD_SCK, LOW);
        data[i] = data[i]<< 1;
	data[i] |= readVal & 0x01;
}
//read second byte
for (int j = 0; j <8; j++) 
{
	digitalWrite(PD_SCK, HIGH);
	readVal=digitalRead(DOUT);
	digitalWrite(PD_SCK, LOW);
	data[1] = data[1]<< 1;
	data[1] |= readVal & 0x01;
}
//read third byte
for (int j = 0; j <8; j++) 
{
	digitalWrite(PD_SCK, HIGH);
	readVal=digitalRead(DOUT);
	digitalWrite(PD_SCK, LOW);
	data[0] = data[0]<< 1;
	data[0] |= readVal & 0x01;
}
// set the channel and the gain factor for the next reading using the clock pin
for (int i = 0; i < GAIN; i++) {
	digitalWrite(PD_SCK, HIGH);
	digitalWrite(PD_SCK, LOW);
}

// Replicate the most significant bit to pad out a 32-bit signed integer
if (data[2] & 0x80) {
	filler = 0xFF;
} else {
	filler = 0x00;
}

// Construct a 32-bit signed integer
value = ( static_cast<unsigned long>(filler) << 24
		| static_cast<unsigned long>(data[2]) << 16
		| static_cast<unsigned long>(data[1]) << 8
		| static_cast<unsigned long>(data[0]) );

 return (static_cast<long>(value));

}

from hx711.

electrokean avatar electrokean commented on July 18, 2024

It just doesn't appear to be reading all 24 bits.
Do you have access to a logic analyser to capture the signals and timing?
I probably have some nrf52832 around somewhere, but no time to search for them or set up a development environment to try this.
Afraid I have no more suggestions right now. Maybe someone else here has an idea.

from hx711.

bogde avatar bogde commented on July 18, 2024

i just checked and unfortunately i don't have the NRF52832 board. sorry.

from hx711.

mashhashkarma avatar mashhashkarma commented on July 18, 2024

hi Electrokean adn Bogde ,
Thanks a lot for your efforts/help.
I dont have a logic analyser. I thought i'll buy this one http://www.ebay.in/itm/302150017754?aff_source=Sok-Goog . DOes this help ?
Please tell me what experiment i can do with the logic analyser. Since you dont have the nrf52832, i can do the experiment and post you data.

from hx711.

electrokean avatar electrokean commented on July 18, 2024

@mashhashkarma yes, that will help.
Buying a real Saleae instead of a clone would be better of course.
You can then capture the signals on the clock and data pins in both setups and post images or make the capture files available for download and review. You may even spot the issue yourself.

from hx711.

bogde avatar bogde commented on July 18, 2024

hi @mashhashkarma , did you solve the issue? did you get the logic analyzer? do you still need any help with this?

fyi, i only have this: http://dangerousprototypes.com/blog/open-logic-sniffer/ (i'm not sure if it's better or worse than the one you found)

from hx711.

mashhashkarma avatar mashhashkarma commented on July 18, 2024

hi Bogde, havent got the chance to try out the logic analzer yet .... been sucked into some other urgent matters.
I would need help after running the anlayser...but it will take time.
Can this thread be open for longer ? or if its a problem, its there a way i can open it again later instead of creating a new issue ?

from hx711.

bogde avatar bogde commented on July 18, 2024

sure, no problem, i'll keep it open.

from hx711.

pvonmoradi avatar pvonmoradi commented on July 18, 2024

@bogde Is your library supported on nRF52? I'm using this core: https://github.com/sandeepmistry/arduino-nRF5 . To my understanding, as long as they have implemented Arduino HAL, all libraries should work on target. Isn't it right? If so why is there a https://github.com/bogde/HX711#hal-support in the readme?

from hx711.

pvonmoradi avatar pvonmoradi commented on July 18, 2024

@amotl
Hi Andreas, thanks for your quick reply :)
I have tested a HX711 with a custom board designed around nRF52832 using (https://github.com/sandeepmistry/arduino-nRF5) core.
Previously, there was an error in which the communication between MCU and ADC was faulty. I can't replicate that now and the library seem to be working fine.
This MCU is running @64mhz (similar to a bluepill) so I guess special consideration should be made to lower the transactions speeds?
Here is a snippet I'm using to read the value of a two load cell bridge setup.

void printHX711() {
    // TODO check if available here instead of true
    if (true) {
        Serial.print("Reading: ");
        r_weight = scale.get_units(1);
        /* if (units < 0) { */
        /*     units = 0.00; */
        /* } */
        Serial.print(r_weight);
        Serial.print(" grams");
        Serial.print(" calibration_factor: ");
        Serial.println(calibration_factor);
    } else {
        Serial.println("HX711 not found.");
    }
}

Here are the snapshots from my logic analyzer in four zoom levels.
D0: SCK
D1: DT

The jumps in D0 appear to be in sync with the 1000ms delay in sampling in main loop.
image
image
image
image

If I need to perform other experiments or if there is a "stress-test script" that should be tested, don't hesitate to ask me.
Thanks

from hx711.

amotl avatar amotl commented on July 18, 2024

Hi Pooya,

sorry that I am probably not able to contribute something significant here because I am not an electronic engineer at all.

However, from a software perspective, have you been able to confirm that the code running on your MCU actually uses the shiftInSlow() method for reading the signal?

If so, you might want to fiddle with the delayMicroseconds() procedure. Maybe this will be able to get you some better readings when adjusting that delay to match your MCU speed.

With kind regards,
Andreas.

from hx711.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.