I am working on a project that weights out coffee beans. It will use a vibratory feeder to flow coffee into a drum sitting on scales.
I am currently programming the ESP8266 that will manage the scales and feeder. I am trying to put all of my scale interest into a custom library/Class (using PlatformIO).
The issue I am having is getting a reading from the HX711 library. Below is the code I have been playing with (cut down). I have tried initializing the HX711 library inside the Class (but I wasn't sure how to do that), and passing the initialized HX7111 as a pointer. But all I can get from scale.get_units(5); is inf. If I paste the same code into the setup() and loop() functions it works perfectly.
You declare hx711 inside of the setup() function, so it goes out of scope (is destroyed) when setup ends. You are then left with a pointer to where hx711 used to be.
@jfjlaros thank you so much for your time. I thought that HX711 hx711; on line 5 of the main.cpp was the declaration? I call begin() in the setup function which assigns the pins?
I am not sure how "pass by reference" works in Arduino, but just to be sure, you can try to pass the HX711 object into the constructor.
I am afraid that when passing the reference to a function, it uses a shadow address, which won't be valid after the the function executes. Therefore, when using the address inside the "loop" function, the address is no longer valid.
So, just to be sure that your HX711 address pointer remains valid through the entire life-cycle of your Scale instance, pass the reference to its constructor, instead of setup function, and save it there.
@Hutkikz legend thank you so much. I refactored my code using your approach and it worked. @robert_c thank you for taking the time to help also.
Seems there must be a difference between references and pointers. Well beyond my knowledge but once I changed it to a reference as demonstrated in @Hutkikz's code it worked. I think I need to spend some more time learning the difference (or even just try understand them haha). For anyone interested I found this post while doing research. c++ - How to pass Serial object by reference to my class in Arduino? - Stack Overflow
Probably, I just said I am not sure.
But can you explain why?
Why, holding a reference with a pointer inside a function works, but outside of it (more specifically, inside of the class instance), doesn't?
Here are 3 different ways to pass a Reference to an object into a class object and store it in the object as either a pointer or a Reference. They all work:
Thank you for explaining that @gfvalvo I am still learning how that works and been seeing different ways as I was researching. That was great to see them laid out. Is there a reason you use one method over another? I have read there is preferences but no-one has explained why you use a reference over a pointer for instance. I have created all of my custom libraries to use the first method you shared and they are all working now.
Also do you always need to initialises an instance and pass it in? Or in the case of my Scale example where it's the only place it's used could I have initialized it inside the custom class?
One advantage of using a pointer is that it can be changed later during program execution. Once a reference is bound to an object, it stays that way for it's entire lifetime. Your application will determine if that's important.
I'd probably make the entire HX711 instance private:
@gfvalvo Thank you so much for taking the time to explain that. Your time is precious and I am grateful for you taking the time to help me learn.
Ok cool, I think my projects are pretty straight forward for now so I don't imagine I would see them changing. I am slowly starting to understand how these work.
In the class above you never "initialized" the HX711 instance? Like I would do say at the start of my file with HX711 scale; before I use scale.begin(...) in my setup(). Is this what happens in the above line anyway? That looks so much cleaner.
Curretly initialize HX711 then pass it into my Scales constructor like so
HX711 hx711;
Scales scale(hx711);
Thank you for your time. Greatly appreciated.
[EDIT] Yes, it really is that simple. I just tried it out. Thank you so much @gfvalvo
Because the HX711 class has a default constructor (see HX711.h / HX711.cpp), the private HX711 instance will be constructed before the Scales class instance. So, all you need to do is call scale.begin() in setup().