Cristian Castro
/
08-Nucleo446_V2HX711
Lectura de una celda de Carga HX711.
Revision 1:392a3fb6d177, committed 2021-09-03
- Comitter:
- CCastrop1012
- Date:
- Fri Sep 03 04:51:59 2021 +0000
- Parent:
- 0:5d67331a6e7e
- Commit message:
- Lectura de una celda de Carga.
Changed in this revision
--- a/HX711.lib Fri May 05 20:16:31 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://developer.mbed.org/users/laskowsk/code/HX711/#716e1cbdac61
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Hx711.cpp Fri Sep 03 04:51:59 2021 +0000 @@ -0,0 +1,77 @@ +#include "mbed.h" +#include "Hx711.h" + +void Hx711::set_gain(uint8_t gain) { + switch (gain) { + case 128: // channel A, gain factor 128 + gain_ = 1; + break; + case 64: // channel A, gain factor 64 + gain_ = 3; + break; + case 32: // channel B, gain factor 32 + gain_ = 2; + break; + } + + sck_.write(LOW); + read(); +} + +uint32_t Hx711::readRaw() { + // wait for the chip to become ready + // TODO: this is not ideal; the programm will hang if the chip never + // becomes ready... + while (!is_ready()); + + uint32_t value = 0; + uint8_t data[3] = { 0 }; + uint8_t filler = 0x00; + + // pulse the clock pin 24 times to read the data + data[2] = shiftInMsbFirst(); + data[1] = shiftInMsbFirst(); + data[0] = shiftInMsbFirst(); + + // set the channel and the gain factor for the next reading using the clock pin + for (unsigned int i = 0; i < gain_; i++) { + sck_.write(HIGH); + sck_.write(LOW); + } + + // Datasheet indicates the value is returned as a two's complement value + // Flip all the bits + data[2] = ~data[2]; + data[1] = ~data[1]; + data[0] = ~data[0]; + + // Replicate the most significant bit to pad out a 32-bit signed integer + if ( data[2] & 0x80 ) { + filler = 0xFF; + } else if ((0x7F == data[2]) && (0xFF == data[1]) && (0xFF == data[0])) { + filler = 0xFF; + } else { + filler = 0x00; + } + + // Construct a 32-bit signed integer + value = ( static_cast<uint32_t>(filler) << 24 + | static_cast<uint32_t>(data[2]) << 16 + | static_cast<uint32_t>(data[1]) << 8 + | static_cast<uint32_t>(data[0]) ); + + // ... and add 1 + return static_cast<int>(++value); +} + + +uint8_t Hx711::shiftInMsbFirst() { + uint8_t value = 0; + + for (uint8_t i = 0; i < 8; ++i) { + sck_.write(HIGH); + value |= dt_.read() << (7 - i); + sck_.write(LOW); + } + return value; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Hx711.h Fri Sep 03 04:51:59 2021 +0000 @@ -0,0 +1,166 @@ +#ifndef _HX711_H_ +#define _HX711_H_ + +/** + * Class for communication with the HX711 24-Bit Analog-to-Digital + * Converter (ADC) for Weigh Scales by AVIA Semiconductor. + * This library is a port of the Arduino library at + * https://github.com/bogde/HX711 + * It works with the FRDM K22F. + */ +class Hx711 { + +public: + + /** + * Create an Hx711 ADC object + * @param pin_sck PinName of the clock pin (digital output) + * @param pin_dt PinName of the data pin (digital input) + * @param offset offset for sensor values + * @param scale scale factor to obtain real values + * @param gain channel selection is made by passing the appropriate gain: + * 128 or 64 for channel A, 32 for channel B + */ + Hx711(PinName pin_sck, PinName pin_dt, float offset, float scale, uint8_t gain = 128) : + sck_(pin_sck), + dt_(pin_dt) { + set_offset(offset); + set_scale(scale); + set_gain(gain); + } + + /** + * Create an Hx711 ADC object with zero offset and unit scaling + * @param pin_sck PinName of the clock pin (digital output) + * @param pin_dt PinName of the data pin (digital input) + * @param gain channel selection is made by passing the appropriate gain: + * 128 or 64 for channel A, 32 for channel B + * TODO: constructor overloading is not allowed? + */ + Hx711(PinName pin_sck, PinName pin_dt, uint8_t gain = 128) : + sck_(pin_sck), + dt_(pin_dt) { + set_offset(0); + set_scale(1.0f); + set_gain(gain); + } + + /** + * Check if the sensor is ready + * from the datasheet: When output data is not ready for retrieval, + * digital output pin DOUT is high. Serial clock input PD_SCK should be low. + * When DOUT goes to low, it indicates data is ready for retrieval. + * @return true if dt_.read() == LOW + * TODO: this is not ideal; the programm will hang if the chip never + * becomes ready... + */ + bool is_ready() { + return dt_.read() == LOW; + } + + /** + * Waits for the chip to be ready and returns a raw int reading + * @return int sensor output value + */ + uint32_t readRaw(); + + /** + * Obtain offset and scaled sensor output; i.e. a real value + * @return float + */ + float read() { + return convert_to_real(readRaw()); + } + + /** + * Convert integer value from chip to offset and scaled real value + * @param val integer value + * @return (val - get_offset()) * get_scale() + */ + float convert_to_real(int val) { + return ((float)(val - get_offset())) * get_scale(); + } + + /** + * Puts the chip into power down mode + */ + void power_down() { + sck_.write(LOW); + sck_.write(HIGH); + } + + /** + * Wakes up the chip after power down mode + */ + void power_up() { + sck_.write(LOW); + } + + /** + * Set the gain factor; takes effect only after a call to read() + * channel A can be set for a 128 or 64 gain; channel B has a fixed 32 gain + * depending on the parameter, the channel is also set to either A or B + * Ensures that gain_ = 128, 64 or 32 + * @param gain 128, 64 or 32 + */ + void set_gain(uint8_t gain = 128); + + /** + * Obtain current gain + * @return gain_ + */ + uint8_t get_gain() { + return gain_; + } + + /** + * Set the scale factor + * @param scale desired scale + */ + void set_scale(float scale = 1.0f) { + scale_ = scale; + }; + + /** + * Get sensor scale factor + * @return scale_ + */ + float get_scale() { + return scale_; + } + + /** + * Set the sensor offset + * @param offset the desired offset + */ + void set_offset(float offset = 0.0) { + offset_ = offset; + } + + /** + * Get current sensor offset + * @return offset_ + */ + float get_offset() { return offset_; } + + +private: + + static const uint8_t LOW = 0; // digital low + static const uint8_t HIGH = 1; // digital high + + DigitalOut sck_; // clock line + DigitalIn dt_; // data line + + uint8_t gain_; // amplification factor at chip + float offset_; // offset chip value + float scale_; // scale output after offset + + /** + * Port of the Arduino shiftIn function; shifts a byte one bit at a time + * @return incoming but + */ + uint8_t shiftInMsbFirst(); +}; + +#endif \ No newline at end of file
--- a/TextLCD.lib Fri May 05 20:16:31 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/simon/code/TextLCD/#308d188a2d3a
--- a/main.cpp Fri May 05 20:16:31 2017 +0000 +++ b/main.cpp Fri Sep 03 04:51:59 2021 +0000 @@ -1,30 +1,65 @@ #include "mbed.h" -#include "HX711.h" -#include "TextLCD.h" +#include "Hx711.h" + +#define n_muestras 10 -DigitalOut led(LED_BLUE); -HX711 scale(PTC9, PTC8); +DigitalOut led(LED1); + +Hx711 LoadCeld(A1, A0, 1, 1.0); Serial rs232(USBTX, USBRX); // USB Serial Terminal -TextLCD lcd(PTE20,PTE21,PTE22,PTE23,PTE29,PTE30, TextLCD::LCD16x2); // Rs, E, d4, d5, d6, d7 + + + + + +float escala = 0.0; +float offset; float calibration_factor = 1000; //Ajustar este valor para calibrar el peso exacto -int averageSamples = 100; +int averageSamples = 300; int main(void) { - scale.setScale(0); - scale.tare(); //Reset the scale to 0 + + for(int i = 0; i < n_muestras; i++ ) + { + while(!LoadCeld.is_ready()); + + offset = ( offset + LoadCeld.readRaw()); + + } - long zero_factor = scale.averageValue(averageSamples); // Saca promedio de varias lecturas para estabilizar la medida + offset = (offset / n_muestras); + LoadCeld.set_offset(offset); + LoadCeld.set_scale(1.0); + rs232.printf("Offset: %.2f \n", offset); + rs232.printf("Offset: %.2f \n", LoadCeld.get_offset()); + offset = 0.0; + + //scale.tare(); //Reset the scale to 0 + + //long zero_factor = scale.averageValue(averageSamples); // Saca promedio de varias lecturas para estabilizar la medida while (true) { - scale.setScale(calibration_factor); - float weight = scale.getGram(); - rs232.printf("Peso: %.2f\n", weight); - lcd.locate(0,0); - lcd.printf("Peso: %.2f Grms", weight); + + + for(int i = 0; i < n_muestras; i++ ) + { + while(!LoadCeld.is_ready()); + + escala = ( escala + LoadCeld.read()); + + } + escala = (escala / n_muestras); + rs232.printf("Peso: %.2f \n", escala); + escala = 0.0; + //scale.setScale(calibration_factor); + //float weight = scale.getGram(); + //rs232.printf("Peso: %.2f\n", weight); + //lcd.locate(0,0); + //lcd.printf("Peso: %.2f Grms", weight); led = !led; // toggle led wait(0.2f); }