ทดลอง Calibrate Load Cell แล้ว Zero Factor ติดลบค่ะ

เนื่องจากได้ทำการทดลองคาลิเบรทโหลดเซล ต่อกับ esp32 ค่ะ
ค่า zero factor ออกมาติดลบ อยากสอบถามพี่ ๆ ว่ามันสามารถแก้ตรงไหนได้บ้างคะ (พอดีเพื่อนทดลองเหมือนกันแต่ค่าที่ออกมาไม่ติดลบค่ะ)

code :

#include "HX711.h"
#include <Wire.h> 

#define DOUT  27
#define CLK   26

#define DEC_POINT  2
#define STABLE  1

float offset=0;
float calibration_factor = 1;
float real_weight = 1.560;//kg

HX711 scale(DOUT, CLK);

unsigned char state=0;
long  FindZeroFactor();
float get_units_kg();
void  ReadWeight();
void  FindCalibrationFactor();

void setup()
{
  Serial.begin(115200);
  Serial.println();
  Serial.println("Auto Calibrate Program");
  Serial.println("Send 'a' to Find Zero Factor (Please Remove all weight from scale)");
  Serial.println("Send 'b' to Find Calibration Factor (Please insert know the weight on the scales)");
  Serial.println("Send 'c' Show weight on the scales");
}
void loop() 
{
  if(Serial.available())
  {
    char temp = Serial.read();
    if(temp=='a')
      state=1;
    if(temp=='b')
      state=2;   
    if(temp=='c')
      state=3;
  }

  switch(state)
  {
    case 0:
    break;
    case 1:
      FindZeroFactor();
   //   ReadWeight();
      state=0;
    break;
    case 2:
     FindCalibrationFactor();
     state=0;
    break;
    case 3:
      ReadWeight();
      delay(200);
    break;
    case 4:
     
    break;
    
  }
}

long FindZeroFactor()
{
     Serial.println("Find Zero Factor");
     Serial.println("Please wait .....");
     scale.set_scale();
     scale.tare(); 
     long zero_factor = scale.read_average(20); 
     Serial.print("Zero factor: ");
     Serial.println(zero_factor);
     return(zero_factor);
}

void FindCalibrationFactor()
{
  unsigned char flag_stable=0;
  unsigned int decpoint=1;
  for(unsigned char i=0;i<DEC_POINT+1;i++ )
    decpoint = decpoint*10;
  while(1)
  {
      scale.set_scale(calibration_factor); //Adjust to this calibration factor
      Serial.print("Reading: ");
      float read_weight = get_units_kg();
      String data = String(read_weight, DEC_POINT);
      Serial.print(data);
      Serial.print(" kg"); 
      Serial.print(" calibration_factor: ");
      Serial.print(calibration_factor);
      Serial.println();
      long r_weight      = (real_weight*decpoint);
      long int_read_weight = read_weight*decpoint;
      Serial.print(r_weight);
      Serial.print(" , ");
      Serial.println(int_read_weight);
      long x;
      if(r_weight == int_read_weight)
      {
        flag_stable++;
        if(flag_stable>=STABLE)
        {
          Serial.print("Calibration Factor is = ");
          Serial.println(calibration_factor);
          break;
         }
        }
       if(r_weight > int_read_weight)
          {
            x = r_weight - int_read_weight;
            if(x > 100)
              calibration_factor -= 1000; 
            else if(x > 100)
              calibration_factor -= 10;
            else
              calibration_factor -= 1;
            flag_stable=0;
          }
          if(r_weight < int_read_weight)
          {
            x =  int_read_weight-r_weight;
            if(x > 100)
              calibration_factor += 1000; 
            else if(x > 10)
              calibration_factor += 10;
            else
              calibration_factor += 1; 
            flag_stable=0; 
           }  
  }
}

float get_units_kg()
{
  return(scale.get_units()*0.453592);
}
void ReadWeight()
{
  scale.set_scale(calibration_factor); //Adjust to this calibration factor
  Serial.print("Reading: ");
  String data = String(get_units_kg()+offset, DEC_POINT);
  Serial.print(data);
  Serial.println(" kg");
}

ขอบคุณค่ะ :grinning:

1 Like
  1. เพื่อนทดลองได้ ค่าเท่าไหร่ครับ
  2. ปัจจัยการต่อทดสอบเหมือนกันทั้งเราและเพื่อนหรือไม่

ติดตั้ง Load Cell กลับทิศทาง ครับ ดูที่ลูกศร จะมีบอกอยู่ ว่าให้หันไปทางไหน
อีกสาเหตุ ต่อสายไฟผิดคู่

ทดลอง เอา Load Cell ของเพื่อนมาดูการต่อสาย ดูการวางรับแรงกด
และ Load Cell มีทั้งชนิดรับแรงกด กับรับแรงดึง จะใช้ด้วยกันไม่ได้ ลองเทียบกับเพื่อนดูครับ

1 Like

1.เพื่อนทดลองแล้ว ได้ค่าzero factor = 8409851
ส่วน calibration factor = 51368.00 ค่ะ ส่วนของเจ้าของกระทู้ ได้ค่า calibration factor = 7513867.00
2.ปัจจัยการทดลอง ใช้โหลดเซลในการต่อแบบเดียวกันค่ะ อุณหภูมิห้องเดียวกันเนื่องจากทดลองที่เดียวกัน โหลดโปรแกรมมาใหม่เป็นเว่อชั่นเดียวกันแล้วค่ะ ก็ไม่ได้

จริงด้วยครับพี่ ค่า factor มันสัมพันธ์กับทิศทาง

อุปกรณ์ มีการขยับ เครื่องย้าย หรือต่อใหม่รึป่าวครับ ถ้ามีรูปการต่อจะดีมาก

1.รูปนี้เป็นการต่อของเจ้ากระทู้ค่ะ ตอนแรกคิดว่าเป็นเพราะตัวอ่านhx711 ลองซื้อมาเปลี่ยน3ตัวผลเหมือนกันหมดเลยค่ะ

2.รูปนี้เป็นการต่อของเพื่อนค่ะ


3.รูปนี้ลองสลับสายการต่อของโหลดเซล

ต่อแบบเดียวกันเลยค่ะ ลองเอาของเพื่อนมาต่อที่คอมตัวเองแล้วค่าที่ได้ก็ยังติดลบค่ะ :pensive:
ที่ต่างกันตอนนี้มีแค่ยี่ห้อของโน้ตบุคแล้วค่ะ

1 Like

** ลองสลับสายต่อ Load Cell ***
หมายถึง สลับคู่สายจาก Load Cell ที่ต่อเข้าวงจรขยายสัญญาณ หรือ ลองสลับคู่สาย ที่ออกจากวงจรขยาย มาเข้าที่ Node MCU ครับ
ที่ตัว Load Cell เครื่องหมายลูกษร บอกทิศทางบ้างไหม ลอง กลับ Load Cell หรือยัง
ลองเอา Load Cell ของเพื่อนมาต่อทดลอง Code หรือยังครับ

ลองสลับสายต่อ Load Cell

  • สลับคู่สายจาก Load Cell ที่ต่อเข้าวงจรขยายสัญญาณ ลองสลับแล้วค่ะ โดยสลับจาก สายสีแดงต่อ A+ สีดำ A- สีขาว E- และ สีเขียว E + ผลที่ได้ ติดลบค่ะ
  • สลับคู่สาย dout,sclk ติดลบเหมือนกันค่ะ
    ลอง กลับ Load Cell หรือยัง
  • ลองกลับแล้วค่ะ ติดลบ
    ลองเอา Load Cell ของเพื่อนมาต่อทดลอง Code หรือยัง
  • ลองแล้วค่ะ มีค่าติดลบเหมือนกันแต่ น้อยกว่าของตัวเองที่ทดลอง
    รวมถึงลองเอาLoad cell ของตัวเองไปต่อคอมเพื่อน ค่าที่ออกมาเป็นบวกค่ะ

เข้าที่

ภาพ

ค้นหาไฟล์ชื่อ HX711.cpp
ภาพ

ค้นหาโค้ตชุดนี้

ภาพ

วางโค้ตชุดนี้แทนที่ หรือแก้เป็น

for(i = 0; i < 8; ++i) {
        digitalWrite(clockPin, HIGH);     //remove comment from here
        if(bitOrder == LSBFIRST)
            value |= digitalRead(dataPin) << i;
        else
            value |= digitalRead(dataPin) << (7 - i);
        //digitalWrite(clockPin, HIGH);    //comment this line

        digitalWrite(clockPin, LOW);
    }

Save ทับแล้วปิด

ทดสอบดูว่าค่าเป็นอย่างไร

  1. ถ้ายังไม่ได้แก้เป็น
for(i = 0; i < 8; ++i) {
        
        if(bitOrder == LSBFIRST)
            value |= digitalRead(dataPin) << i;
        else
            value |= digitalRead(dataPin) << (7 - i);
       

        digitalWrite(clockPin, LOW);
    }

3.ถ้ายังไม่ได้ ให้ copy file library HX711 ของเครื่องเพื่อนที่มีค่าเป็นบวก มาทับเครื่องเราแทนครับ


#include <Arduino.h>
#include <HX711.h>

HX711::HX711(byte dout, byte pd_sck, byte gain) {
	PD_SCK 	= pd_sck;
	DOUT 	= dout;
	
	pinMode(PD_SCK, OUTPUT);
	pinMode(DOUT, INPUT);

	set_gain(gain);
}

HX711::~HX711() {

}

bool HX711::is_ready() {
	return digitalRead(DOUT) == LOW;
}

void HX711::set_gain(byte 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;
	}

	digitalWrite(PD_SCK, LOW);
	read();
}

long HX711::read() {
	// wait for the chip to become ready
	while (!is_ready());

	byte data[3];

	// pulse the clock pin 24 times to read the data
	for (byte j = 3; j--;) {
		for (char i = 8; i--;) {
			digitalWrite(PD_SCK, HIGH);
			bitWrite(data[j], i, digitalRead(DOUT));
			digitalWrite(PD_SCK, LOW);
		}
	}

	// 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);
	}

	data[2] ^= 0x80;

	return ((uint32_t) data[2] << 16) | ((uint32_t) data[1] << 8) | (uint32_t) data[0];
}

long HX711::read_average(byte times) {
	long sum = 0;
	for (byte i = 0; i < times; i++) {
		sum += read();
	}
	return sum / times;
}

double HX711::get_value(byte times) {
	return read_average(times) - OFFSET;
}

float HX711::get_units(byte times) {
	return get_value(times) / SCALE;
}

void HX711::tare(byte times) {
	double sum = read_average(times);
	set_offset(sum);
}

void HX711::set_scale(float scale) {
	SCALE = scale;
}

void HX711::set_offset(long offset) {
	OFFSET = offset;
}

void HX711::power_down() {
	digitalWrite(PD_SCK, LOW);
	digitalWrite(PD_SCK, HIGH);	
}

void HX711::power_up() {
	digitalWrite(PD_SCK, LOW);	
}

ไม่เจอโค้ดชุดนี้เลยค่ะ เดี๋ยวจะลองเปลี่ยนแทนgainดูนะคะ

เข้า ที่ Documents เครื่องครับ เป็น ไฟล์ Library ไม่ใช่โค้ตหลัก

โฟล์เดอ HX711-master

ไลบราลี่ทุกตัวไม่มีไฟล์.cppค่ะ ลองหากลายเป็นว่าWindowsบังคับเปิดไฟล์ c++

แก้ในไฟล์นี้ครับ เปิดมาแล้วหาดูว่าเจอไหม

ภาพ

#include <Arduino.h>
#include <HX711.h>

HX711::HX711(byte dout, byte pd_sck, byte gain) {
	PD_SCK 	= pd_sck;
	DOUT 	= dout;
	
	pinMode(PD_SCK, OUTPUT);
	pinMode(DOUT, INPUT);

	set_gain(gain);
}

HX711::~HX711() {

}

bool HX711::is_ready() {
	return digitalRead(DOUT) == LOW;
}

void HX711::set_gain(byte 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;
	}

	digitalWrite(PD_SCK, LOW);
	read();
}

long HX711::read() {
	// wait for the chip to become ready
	while (!is_ready());

	byte data[3];

	// pulse the clock pin 24 times to read the data
	for (byte j = 3; j--;) {
		for (char i = 8; i--;) {
			digitalWrite(PD_SCK, HIGH);
			bitWrite(data[j], i, digitalRead(DOUT));
			digitalWrite(PD_SCK, LOW);
		}
	}

	// 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);
	}

	data[2] ^= 0x80;

	return ((uint32_t) data[2] << 16) | ((uint32_t) data[1] << 8) | (uint32_t) data[0];
}

long HX711::read_average(byte times) {
	long sum = 0;
	for (byte i = 0; i < times; i++) {
		sum += read();
	}
	return sum / times;
}

double HX711::get_value(byte times) {
	return read_average(times) - OFFSET;
}

float HX711::get_units(byte times) {
	return get_value(times) / SCALE;
}

void HX711::tare(byte times) {
	double sum = read_average(times);
	set_offset(sum);
}

void HX711::set_scale(float scale) {
	SCALE = scale;
}

void HX711::set_offset(long offset) {
	OFFSET = offset;
}

void HX711::power_down() {
	digitalWrite(PD_SCK, LOW);
	digitalWrite(PD_SCK, HIGH);	
}

void HX711::power_up() {
	digitalWrite(PD_SCK, LOW);	
}

เป็นโค้ดชุดนี้แทนค่ะ

อยากเห็น โฟเดอร์ของเครื่องเพื่อนบ้างครับว่ามีไฟล์ หน้าตาเป็นแบบไหน

ตอนนี้เพื่อนน่าจะหลับแล้วค่ะ :sweat_smile: ถ้ายังไงเดี๋ยวมาแจ้งในตอบกลับอีกทีนะคะ
ส่วนการแก้calibrate load cell กำลังเปลี่ยนไปใช้ source codeและตัวอย่างอื่นๆค่ะ

ขอบคุณมากเลยนะคะ :pray:

โอเค ยังไงได้ขอมูลเอามาอัพเดทกันอีกที ผมยังไม่อยากเปลี่ยนเป็นโค้ตชุดอื่น กระทู้นี้มีหลายประเด็น แยกประเด็นแล้วอัพเดทปัญหาต่อไปครับ