프로그래밍/하드웨어

[Arduino] 체중계 분해하여 체중계 만들기 - HX711과 아두이노를 이용하여 데이터를 받아보자

당근천국 2019. 11. 5. 15:30

전 글에서 앰프를 직접 만들어서 사용해 보았습니다.

이제 로드 셀(load cell)에 주로 사용하는 HX711 칩이 들어간 AD를 가지고 체중계를 써보겠습니다.

 

구매정보 : HX711 로드셀 측정 24비트 AD 컨버터 모듈

 

연관글 영역

 

 

 

1. 체중계 분해

전 편에서 체중계를 어떻게 분해하는지 자세하게 알아봤습니다.

참고 : [하드웨어] 체중계 분해하여 체중계 만들기 - 체중계 분해하여 로드셀(Loadcell) 사용하기

 

 

분해를 하면 보통 아래와 같이 배선되어 있을 겁니다.

 

기판에 글자가 안 쓰여있는 경우도 있는데 보통 양쪽 끝이 +V, -V입니다.

그리고 가운데가 +S, -S입니다.

 

따로 쓰여있는 내용이 없는 경우 거의 위에 사진과 같이 돼 있을 확률이 높습니다.

하지만 꼭 그런 건 아니므로 기판의 배선을 확인해야 합니다.

모르겠으면.....

 

그냥 기판에서 로드 셀 때고 배선 다시 합시다.

만약 메인보드에 일체형을 되어 있다면 선을 때서 직접 배선을 해야 합니다.

참고 : [하드웨어] 체중계 분해하여 체중계 만들기 - 3선 로드 셀(Load cell) 배선을 하자

 

 

2. HX711에 연결하기

원래 이 모듈의 전체 이름은 'HX711 로드 셀 측정 24비트 AD 컨버터 모듈(HX711 Sensor Weigh Transducer Module Dual-channel 24Bit AD Conversion Microcontroller Board Transducer)' 입니다만.... 귀찮으니 'HX711'로 부르겠습니다. ㅎㅎ

 

이전 글에서 보셨다면 'HX711'에 연결하는 방법까지 나와 있지만 다시 확인해 보겠습니다.

참고 : [하드웨어] 체중계 분해하여 체중계 만들기 - 3선 로드 셀(Load cell) 배선을 하자

 

이제 배선에서 E-,E+ 와 A-,A+를 찾아야 합니다.

이건 직접 결선하여 테스트해보는 수 밖에 없습니다.

 

결선할 때 플러스(+), 마이너스(-)가 한 세트이니 이걸 명심하여 값을 확인하면서 연결해야 합니다.

두 세트가 있으니 경우에 수는 두 개뿐입니다.

 

다른 방식은 아래와 같습니다.

 

하지만....아직 코드를 넣지 않았으니 어떤 값이 나올지 모릅니다.

일단은 그냥 감으로 대충 꼽고 다음으로 넘어갑시다.

 

HX711에서 나온 SCK(CLK)를 3번 핀에

DT(DOUT)를 2번 핀에

VCC를 전원에(여기선 5V)

GND를 GND에 연결합니다.

 

 

만약 배선이 잘 안된다면 이전 포스팅의 '2-2. 풀 브리지 2번'도 시도해 보세요.

참고 : [하드웨어] 체중계 분해하여 체중계 만들기 - 3선 로드 셀(Load cell) 배선을 하자

 

 

3. 테스트 코드 넣기

다행히도 'HX711' IC를 사용할 때 사용하는 아두이노 라이브러리가 있습니다.

참고 : Github - HX711

 

 

이 라이브러리를 받아 넣어 사용하면 됩니다.

라이브러리를 넣는 방법은 아래 링크에 '2-1. 라이브러리에 추가하기'를 참고해 주세요.

참고 : [Arduino] 라이브러리 작성하기

 

깃허브에 기본 예제(examples)가 있는 코드를 살짝 수정하여 넣습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include "HX711.h"
 
// HX711 circuit wiring
const int LOADCELL_DOUT_PIN = 2;
const int LOADCELL_SCK_PIN = 3;
 
HX711 scale;
 
void setup() 
{
  Serial.begin(9600);
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
}
 
void loop() 
{
 
  if (scale.is_ready()) 
  {
    long reading = scale.read();
    Serial.print("HX711 reading: ");
    Serial.println(reading);
  } 
  else 
  {
    Serial.println("HX711 not found.");
  }
 
  delay(1000);
  
}
cs

 

 

이제 아두이노를 PC에 연결하고 시리얼 모니터를 열어 테스트해봅시다.

 

 

 

센서에 올라가 보면 값이 변하는 것을 알 수 있습니다.

여기서 중요한 건 체중계에 올라갔을 때 값이 변하고 내려오면 다시 값이 복원되는 것만 확인되면 됩니다.

 

만약 배선이 정확한데 값이 안 나온다면 E-,E+ 와 A-,A+를 바꿔서 연결해봅시다.

마이너스 값으로 값이 증가한다면 E-와 E+를 반대로 꼽아 봅시다.

아니면 A-와 A+를 반대로 꼽아봅시다

 

그래도 안 나오면 보통 배선이 문제일 확률이 높습니다.

 

 

 

4. kg 맞추기

무게를 맞추려면 캘리브레이션(Calibration, 교정) 작업을 해서 0kg에서 시작할 수 있도록 조정해야 합니다.

이 작업은 같은 곳에서 만든 센서여도 연결하면 다를 수 있기 때문에 매번 조정해줘야 합니다.

 

'sparkfun'에서 제공하는 코드를 활용하면 됩니다.

참고 : github - HX711-Load-Cell-Amplifier/firmware/SparkFun_HX711_Calibration/

 

 

이 코드를 그대로 써도 되는데.....

그냥 쓰면 엄청 불편해서 쓰기 편하게 살짝 바꾸겠습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
 Example using the SparkFun HX711 breakout board with a scale
 By: Nathan Seidle
 SparkFun Electronics
 Date: November 19th, 2014
 License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).
 
 This is the calibration sketch. Use it to determine the calibration_factor that the main example uses. It also
 outputs the zero_factor useful for projects that have a permanent mass on the scale in between power cycles.
 
 Setup your scale and start the sketch WITHOUT a weight on the scale
 Once readings are displayed place the weight on the scale
 Press +/- or a/z to adjust the calibration_factor until the output readings match the known weight
 Use this calibration_factor on the example sketch
 
 This example assumes pounds (lbs). If you prefer kilograms, change the Serial.print(" lbs"); line to kg. The
 calibration factor will be significantly different but it will be linearly related to lbs (1 lbs = 0.453592 kg).
 
 Your calibration factor may be very positive or very negative. It all depends on the setup of your scale system
 and the direction the sensors deflect from zero state
 This example code uses bogde's excellent library: https://github.com/bogde/HX711
 bogde's library is released under a GNU GENERAL PUBLIC LICENSE
 Arduino pin 2 -> HX711 CLK
 3 -> DOUT
 5V -> VCC
 GND -> GND
 
 Most any pin on the Arduino Uno will be compatible with DOUT/CLK.
 
 The HX711 board can be powered from 2.7V to 5V so the Arduino 5V power should be fine.
 
*/
 
//This library can be obtained here http://librarymanager/All#Avia_HX711
#include "HX711.h" 
 
#define LOADCELL_DOUT_PIN 2
#define LOADCELL_SCK_PIN 3
 
HX711 scale;
 
//-7050 worked for my 440lb max scale setup
float calibration_factor = -200000;
 
void setup() 
{
  Serial.begin(9600);
  Serial.println("HX711 calibration sketch");
  Serial.println("Remove all weight from scale");
  Serial.println("After readings begin, place known weight on scale");
  Serial.println("Press + or a to increase calibration factor");
  Serial.println("Press - or z to decrease calibration factor");
 
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  scale.set_scale();
  //Reset the scale to 0
  scale.tare();
 
  //Get a baseline reading
  long zero_factor = scale.read_average(); 
  //This can be used to remove the need to tare the scale. Useful in permanent scale projects.
  Serial.print("Zero factor: ");
  Serial.println(zero_factor);
}
 
void loop() 
{
  //Adjust to this calibration factor
  scale.set_scale(calibration_factor);
 
  Serial.print("Reading: ");
  Serial.print(scale.get_units(), 1);
  //Change this to kg and re-adjust the calibration factor if you follow SI units like a sane person
  //기존 예제가 파운드(lbs) 기준이지만 우리는 킬로그램(kg)을 쓸것이므로 'kg'로 바꿉시다.
  Serial.print(" kg"); 
  Serial.print(" calibration_factor: ");
  Serial.print(calibration_factor);
  Serial.println();
 
  if(Serial.available())
  {
    char temp = Serial.read();
 
    //변경 : 보정값 범위 설정 가능하도록 변경
    switch(temp)
    {
      case '1':
        calibration_factor += 10;
        break;
      case '2':
        calibration_factor += 50;
        break;
      case '3':
        calibration_factor += 100;
        break;
      case '4':
        calibration_factor += 1000;
        break;
 
      case 'a':
        calibration_factor -= 10;
        break;
      case 's':
        calibration_factor -= 50;
        break;
      case 'd':
        calibration_factor -= 100;
        break;
      case 'f':
        calibration_factor -= 1000;
        break;
    }
  }
  
}
cs

 

 

값을 늘리고 싶으면 1(10), 2(50), 3(100), 4(1000)를 입력하면 됩니다.

값을 줄이고 싶으면 a(10), s(50), d(100), f(1000)를 입력하면 됩니다.

 

입력은 여기에!

 

 

 

수치를 보정하려면 다음과 같은 단계로 하시면 됩니다.

 

1) 먼저 아무것도 없을 때 -0.0 ~ 0.0 값이 나오도록 조절합니다.

2) '1kg'짜리 물건을 올립니다.

1kg는 상온에서 물 1리터입니다.

집에 생수병이 있으면 그거 올려놓고 측정을 합시다.

3) '1kg'가 되었으면 자신이 올라가서 자기 몸무게가 나오는지 확인합니다.

안 나온다면 조절을 한 후 다시 '2)'와 '3)'을 반복합니다.

 

 

여기서 정확한 값이 안 나올 수도 있습니다.

HX711 라이브러리가 내부적으로 평활 해서 준다고 알고 있었는데.....

막상 해보면 평활이 안 된것 처럼 보입니다.

 

나중에 보정하면 되니까 일정 시간 동안 근사치가 나오는지 확인되면 조정이 끝난 겁니다.

조정이 끝난 'calibration_factor'값을 적어 둡시다.

 

여기까지 왔으면 일단 체중계는 완성 된 겁니다!

 

 

5. 조정된 값을 넣기

이제 위에서 보정된 캐리브레이션 값을 고정값으로 넣어 코드를 정리합니다.

 

참고 : github - HX711-Load-Cell-Amplifier/firmware/SparkFun_HX711_Example/SparkFun_HX711_Example

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/*
 Example using the SparkFun HX711 breakout board with a scale
 By: Nathan Seidle
 SparkFun Electronics
 Date: November 19th, 2014
 License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).
 
 This example demonstrates basic scale output. See the calibration sketch to get the calibration_factor for your
 specific load cell setup.
 
 This example code uses bogde's excellent library: https://github.com/bogde/HX711
 bogde's library is released under a GNU GENERAL PUBLIC LICENSE
 
 The HX711 does one thing well: read load cells. The breakout board is compatible with any wheat-stone bridge
 based load cell which should allow a user to measure everything from a few grams to tens of tons.
 Arduino pin 2 -> HX711 CLK
 3 -> DAT
 5V -> VCC
 GND -> GND
 
 The HX711 board can be powered from 2.7V to 5V so the Arduino 5V power should be fine.
 
*/
 
//This library can be obtained here http://librarymanager/All#Avia_HX711
#include "HX711.h"
 
//This value is obtained using the SparkFun_HX711_Calibration sketch
#define calibration_factor -18910.0
 
#define LOADCELL_DOUT_PIN 2
#define LOADCELL_SCK_PIN 3
 
HX711 scale;
 
void setup() 
{
  Serial.begin(9600);
  Serial.println("HX711 scale demo");
 
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  //This value is obtained by using the SparkFun_HX711_Calibration sketch
  scale.set_scale(calibration_factor);
  //Assuming there is no weight on the scale at start up, reset the scale to 0
  scale.tare();
 
  Serial.println("Readings:");
}
 
void loop() 
{
  Serial.print("Reading: ");
  //scale.get_units() returns a float
  Serial.print(scale.get_units(), 1);
  //You can change this to kg but you'll need to refactor the calibration_factor
  Serial.print(" kg");
  Serial.println();
}
cs

 

 

조정된 값이 바로 깔끔하게 나온다면 다음 챕터는 필요 없는 내용이 되겠지만......

이런류의 센서는 값이 안 튀는 경우가 별로 없습니다.

 

 

 

6. 값 보정하기

보통 이런 센서는 아두이노에서 값을 보정하지 않고 PC나 별도의 프로세서에 보내서 처리하는 게 좋습니다.

하지만.......

이것은 아두이노 강좌이니 아두이노에서 보정해 봅시다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//This library can be obtained here http://librarymanager/All#Avia_HX711
#include "HX711.h"
 
//찾은 캘리브레이션값을 넣어 줍니다.
#define calibration_factor -18550.0
 
//DT(DOUT)로 사용하는 핀
#define LOADCELL_DOUT_PIN 2
//SCK(CLK)로 사용하는 핀
#define LOADCELL_SCK_PIN 3
 
HX711 scale;
 
//최신값을 몇개 저장해 두는지 개수.
int nValueCount = 10;
//최신값을 저장해 두는 배열. 위의 변수 값과 같은 크기를 설정한다.
float fValue[10];
 
 
void setup() 
{
  Serial.begin(9600);
 
  Serial.println("HX711 kg demo");
 
  //HX711 객체를 초기화 한다.
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  //설정된 캘리브레이션 값을 설정 한다.
  scale.set_scale(calibration_factor);
  //영점 잡기. 현재 값을 0으로 둔다.
  scale.tare();
 
  Serial.println("Readings:");
}
 
void loop() 
{
  Serial.print("Reading: ");
 
  //값 임시 저장
  float fValueTemp = 0.0;
  //값 합산
  float fValueSum = 0.0;
 
  
  //scale.get_units() returns a float
  fValueTemp = scale.get_units();
  //읽은 값을 합산값에 넣어 준다.
  fValueSum = fValueTemp;
  
  int i;
  for(i = 0; i < nValueCount; i = i + 1)
  {
    if(i > 0)
    {//0보다 클때만 계산
      //앞번호일수록 오래된 데이터이다.
      
      //기존에 저장된 데이터 합산
      fValueSum = fValueSum + fValue[i];
 
      //값을 앞으로 한칸씩 민다.
      fValue[i - 1= fValue[i];
    }
  }
 
  //맨 마지막에 최신값을 넣어 준다.
  fValue[nValueCount - 1= fValueTemp;
 
  //합산값을 평균을 낸다.
  Serial.print((fValueSum / nValueCount), 1);
  
  //You can change this to kg but you'll need to refactor the calibration_factor
  Serial.print(" kg");
  Serial.println();
}
cs

 

 

HX711개체에서 넘어오는 값이 심하게 튀지 않기 때문에 5개 정도 쌓아서 평균만 구해도 충분할 듯 합니다.

근데 막상 해보니.......5개는 너무 모자른 거 같아서 변수만 바꾸면 리스트 개수를 바꿀 수 있도록 수정하였습니다. ㅎㅎㅎ

나온 값을 확인해보고 값이 너무 흔들린다면 더 많은 개수를 넣으면 비교적 덜 흔들리는 값이 나옵니다.

 

 

 

마무리

 

이렇게 3편에 걸쳐서 체중계를 분해하여 체중계를 다시 만드는 짓을 해보았습니다 ㅎㅎㅎㅎ

물론 이렇게 추출한 값을 다른 곳에서 사용하려고 하는 짓이라 삽질이 아니죠 ㅎㅎㅎㅎ

 

첫 포스팅을 할때까지만 해도 이렇게 시리즈로 만들 생각도 없었고 지금이랑 상황이 많이 달랐는데...

이제는 저렴하게 로드셀도 구할 수 있고 부품도 구할 수 있으니 정말로 체중계를 만들어 쓸 수 있습니다. ㅎㅎㅎ

 

참고 : Arduino Bathroom Scale With 50 Kg Load Cells and HX711 Amplifier