Comments (24)
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.
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_CPU
s, 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.
Lines 36 to 62 in 75dfed4
With kind regards,
Andreas.
[1] https://github.com/bogde/HX711#hal-support
from hx711.
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.
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.
typo correction "...undersatand how this would result in ... "
from hx711.
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.
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.
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.
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.
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.
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
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.
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.
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.
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.
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.
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.
i just checked and unfortunately i don't have the NRF52832 board. sorry.
from hx711.
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.
@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.
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.
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.
sure, no problem, i'll keep it open.
from hx711.
@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.
@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.
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.
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)
- Arduino 2 support
- Formula to find hx711 output of load cell voltage output HOT 1
- Arduino MKR 1010 Upload failure
- Arduino freezes after about 1 hour of continuous reading
- serial monitor freezes on arduino uno when data or clock from HX711 is connected to the arduino digital data pin
- Should function "scale.tare();" need a parameter? HOT 2
- add NRF to compatible boards list
- Verify my wiring (HX711 with four strain gauges) HOT 2
- Multiple HX711 with one clock HOT 1
- warning: this use of "defined" may not be portable [-Wexpansion-to-defined]
- Reason behind using D2 and D3 pins HOT 1
- HX711 only reads once on startup HOT 2
- How to check load cell is connected or not
- What are possible values for scale.set_scale(2280.f); HOT 2
- 71
- self-calibration of load cell
- HX711 not thread safe?
- HX711 high current consumption
- Error on `make build-all` HOT 1
- 2 (or more) mass calibration
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from hx711.