// TEENSYDUINO has a port of Dean Camera's ATOMIC_BLOCK macros for AVR to ARM Cortex M3. #define HAS_ATOMIC_BLOCK (defined(ARDUINO_ARCH_AVR) || defined(TEENSYDUINO))
// Whether we are running on either the ESP8266 or the ESP32. #define ARCH_ESPRESSIF (defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32))
// Whether we are actually running on FreeRTOS. #define IS_FREE_RTOS defined(ARDUINO_ARCH_ESP32)
// Define macro designating whether we're running on a reasonable // fast CPU and so should slow down sampling from GPIO. #define FAST_CPU \ ( \ ARCH_ESPRESSIF || \ defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) || \ defined(ARDUINO_ARCH_STM32) || defined(TEENSYDUINO) \ )
voidHX711::set_gain(byte gain) { switch (gain) { case128: // channel A, gain factor 128 GAIN = 1; break; case64: // channel A, gain factor 64 GAIN = 3; break; case32: // channel B, gain factor 32 GAIN = 2; break; }
}
longHX711::read() {
// Wait for the chip to become ready. wait_ready();
// Define structures for reading data into. unsignedlong value = 0; uint8_t data[3] = { 0 }; uint8_t filler = 0x00;
// Protect the read sequence from system interrupts. If an interrupt occurs during // the time the PD_SCK signal is high it will stretch the length of the clock pulse. // If the total pulse time exceeds 60 uSec this will cause the HX711 to enter // power down mode during the middle of the read sequence. While the device will // wake up when PD_SCK goes low again, the reset starts a new conversion cycle which // forces DOUT high until that cycle is completed. // // The result is that all subsequent bits read by shiftIn() will read back as 1, // corrupting the value returned by read(). The ATOMIC_BLOCK macro disables // interrupts during the sequence and then restores the interrupt mask to its previous // state after the sequence completes, insuring that the entire read-and-gain-set // sequence is not interrupted. The macro has a few minor advantages over bracketing // the sequence between `noInterrupts()` and `interrupts()` calls. #if HAS_ATOMIC_BLOCK ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
#elif IS_FREE_RTOS // Begin of critical section. // Critical sections are used as a valid protection method // against simultaneous access in vanilla FreeRTOS. // Disable the scheduler and call portDISABLE_INTERRUPTS. This prevents // context switches and servicing of ISRs during a critical section. portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; portENTER_CRITICAL(&mux);
// Pulse the clock pin 24 times to read the data. data[2] = SHIFTIN_WITH_SPEED_SUPPORT(DOUT, PD_SCK, MSBFIRST); data[1] = SHIFTIN_WITH_SPEED_SUPPORT(DOUT, PD_SCK, MSBFIRST); data[0] = SHIFTIN_WITH_SPEED_SUPPORT(DOUT, PD_SCK, MSBFIRST);
// Set the channel and the gain factor for the next reading using the clock pin. for (unsignedint i = 0; i < GAIN; i++) { digitalWrite(PD_SCK, HIGH); #if ARCH_ESPRESSIF delayMicroseconds(1); #endif digitalWrite(PD_SCK, LOW); #if ARCH_ESPRESSIF delayMicroseconds(1); #endif }
#if IS_FREE_RTOS // End of critical section. portEXIT_CRITICAL(&mux);
// 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<unsignedlong>(filler) << 24 | static_cast<unsignedlong>(data[2]) << 16 | static_cast<unsignedlong>(data[1]) << 8 | static_cast<unsignedlong>(data[0]) );
return static_cast<long>(value); }
voidHX711::wait_ready(unsignedlong delay_ms) { // Wait for the chip to become ready. // This is a blocking implementation and will // halt the sketch until a load cell is connected. while (!is_ready()) { // Probably will do no harm on AVR but will feed the Watchdog Timer (WDT) on ESP. // https://github.com/bogde/HX711/issues/73 delay(delay_ms); } }
boolHX711::wait_ready_retry(int retries, unsignedlong delay_ms) { // Wait for the chip to become ready by // retrying for a specified amount of attempts. // https://github.com/bogde/HX711/issues/76 int count = 0; while (count < retries) { if (is_ready()) { returntrue; } delay(delay_ms); count++; } returnfalse; }
boolHX711::wait_ready_timeout(unsignedlong timeout, unsignedlong delay_ms) { // Wait for the chip to become ready until timeout. // https://github.com/bogde/HX711/pull/96 unsignedlong millisStarted = millis(); while (millis() - millisStarted < timeout) { if (is_ready()) { returntrue; } delay(delay_ms); } returnfalse; }
longHX711::read_average(byte times) { long sum = 0; for (byte i = 0; i < times; i++) { sum += read(); // Probably will do no harm on AVR but will feed the Watchdog Timer (WDT) on ESP. // https://github.com/bogde/HX711/issues/73 delay(0); } return sum / times; }
classHX711 { private: byte PD_SCK; // Power Down and Serial Clock Input Pin byte DOUT; // Serial Data Output Pin byte GAIN; // amplification factor long OFFSET = 0; // used for tare weight float SCALE = 1; // used to return weight in grams, kg, ounces, whatever
public:
HX711();
virtual ~HX711();
// Initialize library with data output pin, clock input pin and gain factor. // Channel selection is made by passing the appropriate gain: // - With a gain factor of 64 or 128, channel A is selected // - With a gain factor of 32, channel B is selected // The library default is "128" (Channel A). voidbegin(byte dout, byte pd_sck, byte gain = 128);
// Check if HX711 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. boolis_ready();
// Wait for the HX711 to become ready voidwait_ready(unsignedlong delay_ms = 0); boolwait_ready_retry(int retries = 3, unsignedlong delay_ms = 0); boolwait_ready_timeout(unsignedlong timeout = 1000, unsignedlong delay_ms = 0);
// 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 voidset_gain(byte gain = 128);
// waits for the chip to be ready and returns a reading longread();
// returns an average reading; times = how many times to read longread_average(byte times = 10);
// returns (read_average() - OFFSET), that is the current value without the tare weight; times = how many readings to do doubleget_value(byte times = 1);
// returns get_value() divided by SCALE, that is the raw value divided by a value obtained via calibration // times = how many readings to do floatget_units(byte times = 1);
// set the OFFSET value for tare weight; times = how many times to read the tare value voidtare(byte times = 10);
// set the SCALE value; this value is used to convert the raw data to "human readable" data (measure units) voidset_scale(float scale = 1.f);
// get the current SCALE floatget_scale();
// set OFFSET, the value that's subtracted from the actual reading (tare weight) voidset_offset(long offset = 0);
// get the current OFFSET longget_offset();
// puts the chip into power down mode voidpower_down();
// wakes up the chip after power down mode voidpower_up(); };
The domain name of this website has been changed to triority.cc(Using CDN via cloudflare, recommended) / www.triority.cc(Connecting directly, works better in Chinese mainland). Please contact me if you have any questions.