앞서 포스팅 된 글에서 바이트(byte)를 문자열, 문자열(string)을 정수(integer)로 변환하였다.

각 저울의 무게의 출력까지 진행했으니, 저울의 무게을 알맞게 조합하였다.

파이썬은 조합 모듈이 내장되어 있다. 

from itertools import combinations

조합을 사용하기 위해서는 리스트를 만들어야 하는데, 앞전에 포스팅 된 글에서 리스트를 이미 만들었다.

 

for문을 활용한 리스트 변환.

p_4 = [int(i) for i in p_3]

파이썬을 사용하는 사람들이라면 절대적으로 필요한 반복문이다.

저 문장을 글로 해석하자면, p_3안에 있는 원소 i를 정수화 int(i) 하여 리스트 '[ ]' 안에 p_4라는 변수로 정의하겠다. 라는 의미다.

고로 p_4라는 변수는 8개의 저울 무게가 포함된 리스트이다. 

본 프로젝트는 문제 정의는 다음과 같다.

1. 각 저울 무게로부터 하여금 알맞게 조합하여 타겟 무게를 확보하는 것. 

2. 타겟 무게는 사용자가 임의로 지정하여 타겟 무게보다 높아야하고, 제일 가까운 수여야 함.

3. 3개 조합, 4개 조합, 5개 조합, 6개 조합이 포함된 리스트 내에서 타겟에 가까워야 함.

4. 다시 말해서 3,4,5,6개 조합이 한 리스트에 저장된 후, 그 중에서 가장 가까운 조합을 선정해야 함.

조합을 하기 위해서 for문을 사용하는데, 다음과 같다. 

comb_3 = [a for a in itertools.combinations(p_4, 3)]

p_4안에 있는 원소들을 활용하여 3개씩 조합하는 문장이다.

이 문장을 글로 해석하자면 p_4의 원소들을 활용하여 3개씩 조합 itertools.combinatios(p_4, 3) 하여 a라는 원소로 comb_3 리스트에 담는다. 

이와 같이 4,5,6 조합 리스트를 구한다.

comb_4 = [b for b in itertools.combinations(p_4, 4)]
comb_5 = [c for c in itertools.combinations(p_4, 5)]
comb_6 = [d for d in itertools.combinations(p_4, 6)]

조합된 리스트의 원소들을 한 곳으로 모으기 위해서 len 을 활용했다.

comb_3[len(comb_3):len(comb_3)] = comb_4
comb_3[len(comb_3):len(comb_3)] = comb_5
comb_3[len(comb_3):len(comb_3)] = comb_6

comb_3라는 리스트에 3,4,5,6개의 조합된 원소들이 포함된다.

 

 

 

저울에서 측정한 데이터를 Serial 포트를 통해 쉽게 데이터 처리를 하기 위해 파이썬을 활용하였다.

우선적으로 파이썬을 통해 데이터를 처리하기 전 데이터를 수신하는 방법이다.

내가 사용하는 코드 편집기는 Microsoft Visual Studio를 사용한다. 비상업적 용도로 사용하기 때문에, 무료로 사용할 수 있다. 

처음 파이썬을 접했을때 아나콘다를 활용하여 편집을 진행했지만, 코드의 오류와 모듈의 설치 등 초보가 사용하기에 적합한 프로그램이라 판단했다.

사실 멋모르고 사용하기 시작했던 Visual Studio는 다른 편집기를 사용하려해도 낯설고 나에겐 어려워 본 편집기에 정착했다.

디버깅과 릴리즈를 사용하는 면에서는 훌륭하다고 생각된다.

Visual Studio의 모듈 추가는 다른 편집기와는 사뭇 다르다.

Visual Studio의 모듈 추가

Python 애플리케이션 템플릿을 새롭게 만들면, 우측에 패키지 선택 항목이 있다.

패키지를 선택하면, 원하는 모듈은 검색하고 설치할 수 있다.

Serial 모듈 설치

해당 화면처럼 Serial 모듈을 검색하고 설치하면 모듈은 설치가 된다.

 

모듈을 추가한 다음, port와 baudrate를 알맞게 입력한다.

Arduino가 연결된 USB 포트에 맞는지 확인한다. (장치관리자)

통신속도는 아두이노 편집기에서 설정해놓은 값을 그대로 적용하면 된다. 

import Serial

ard = serial.Serial('COM4',9600)

시리얼 통신후  통신할 때 쓰레기 값을 제거

ard.flush

시리얼 데이터는 기본적으로 byte 형식으로 들어오기 때문에 알맞게 디코딩(decoding) 후,

각 저울에 맞는 무게를 분류하기 위해 변수를 생성해준다.

p = ard.readline() #시리얼 데이터 한줄씩 읽기
p_1 = p.decode() # 시리얼 데이터 디코딩
p_2 = str(p_1) # String 으로 변환
p_3 = re,findall("\d+", p_2)
p_4 = [int(i) for i in p_3]

a1 = int(p_3[0])
a2 = int(p_3[1])
a3 = int(p_3[2])
a4 = int(p_3[3])
a5 = int(p_3[4])
a6 = int(p_3[5])
a7 = int(p_3[6])
a8 = int(p_3[7])

 

1개의 로드셀을 연결하여 출력을 확인했으니 2개,3개를 거쳐 8개를 연결하여 코딩을 진행했다.

'8개의 로드셀(HX711)을 한번에 연결하여 무게를 출력하는 방법'

현재 보유하고 있는 아두이노 우노는 아날로그 input이 6개(A0~A5)가 최대.

8개를 연결하기 위해서는 최소 16개의 input이 요구된다. 

아두이노 우노(Arduino Uno)
아두이노 듀에(Arduino Due)

듀에(Due)를 사용하면서 새롭게 알게된 지식인데, Digital 이든 Analog든 상관없이 각 로드셀에 연결되는 핀번호에 해당하는 변수만 잘 지정한다면, 문제 없이 사용할 수 있다.

쉽게 말해서 Digital 혹은 Analog에 상관없이 연결하여 사용할 수 있다.




코딩은 로드셀 한개를 연결한 내용에서 추가만 해주면 된다.

 

HX711 모듈의 헤더파일을 추가한 후, 8개의 모듈을 연결한 핀에 정의를 해준다.

#include "HX711.h"

//define DOUT, CLK(Clock data)
#define DOUT1 A1
#define CLK1 A0

#define DOUT2 A3
#define CLK2 A2

#define DOUT3 A5
#define CLK3 A4

#define DOUT4 A7
#define CLK4 A6

#define DOUT5 A9
#define CLK5 A8

#define DOUT6 44
#define CLK6 45

#define DOUT7 46
#define CLK7 47

#define DOUT8 48
#define CLK8 49

#define DOUT9 50
#define CLK9 51

#define DOUT10 52
#define CLK10 53

다음은 8개의 로드셀에 대한 코딩을 진행해주면 아두이노 시리얼 데이터는 이로써 끝이 난다.

HX711 scale1;
HX711 scale2;
HX711 scale3;
HX711 scale4;
HX711 scale5;
HX711 scale6;
HX711 scale7;
HX711 scale8;
HX711 scale9;
HX711 scale10;
float val1, val2, val3, val4, val5, val6, val7, val8, val9, val10;

void setup() {
  Serial.begin(9600);

  Serial.println(scale1.read());      // print a raw reading from the ADC
  Serial.println(scale2.read());      // print a raw reading from the ADC
  Serial.println(scale3.read());      // print a raw reading from the ADC
  Serial.println(scale4.read());      // print a raw reading from the ADC
  Serial.println(scale5.read());      // print a raw reading from the ADC
  Serial.println(scale6.read());      // print a raw reading from the ADC
  Serial.println(scale7.read());      // print a raw reading from the ADC
  Serial.println(scale8.read());      // print a raw reading from the ADC
  
  scale1.set_scale(484.88);                   
  scale1.tare(5);
  
  scale2.set_scale(484.88);
  scale2.tare(5);
  
  scale3.set_scale(484.88);
  scale3.tare(5);
  
  scale4.set_scale(484.88);
  scale4.tare(5);
  
  scale5.set_scale(484.88);
  scale5.tare(5);

  
  scale6.set_scale(484.88);
  scale6.tare(5);

  scale7.set_scale(484.88);
  scale7.tare(5);
 
  scale8.set_scale(484.88);
  scale8.tare(5);

void loop() {  
  val1 = scale1.get_units();
  val2 = scale2.get_units();
  val3 = scale3.get_units();
  val4 = scale4.get_units();
  val5 = scale5.get_units();
  val6 = scale6.get_units();
  val7 = scale7.get_units();
  val8 = scale8.get_units();

  Serial.print(val1, 1);
  Serial.print(" ");
  Serial.print(val2, 1);
  Serial.print(" ");
  Serial.print(val3, 1);
  Serial.print(" ");
  Serial.print(val4, 1);
  Serial.print(" ");
  Serial.print(val5, 1);
  Serial.print(" ");
  Serial.print(val6, 1);
  Serial.print(" ");
  Serial.print(val7, 1);
  Serial.print(" ");
  Serial.print(val8, 1);

  delay(1000);
}

 

로드셀의 눈금조절(Calibration)은 간단하다.

1-1 에서 다루었던 해당 라인의 출력은 다음과 같다. 

Serial.println(scale1.read())

Output > 

무게에 따라 스케일 값이 변하기 때문에 간단한 함수로 나타내어 기울기 값을 구하면되는데,

기울기 값이 로드셀의 눈금(Calibration)이 되는 것이다. 

저울에 올라간 무게(g)와 스케일 값

무게에 따라 스케일 값을 엑셀에 입력한 후, 그래프(곡선이 있는 분산형)로 나타낸다.

해당 그래프를 우클릭하여 추세선 서식을 클릭한 후,

다른 옵션은 놔두고 수식을 차트에 표시하면, 

그래프의 기울기가 나타나고 이 값을 다시 아두이노 코딩에 입력해줘야 눈금이 맞춰진다.

  scale1.set_scale(484.88);

 

동일한 방법으로 다른 저울들도 연결한 후 눈금을 맞춰주도록 하자.

 

1. 서론 

무게를 측정하기 위해 저울이 필요하여, 로드셀과 HX711 모듈을 사용한 저울을 제작하였다.

 

HX711 모듈은 AD컨버터 모듈로써, 무게에 대한 데이터를 아두이노에서 읽어 들이기 위해 필요한 모듈이다.

 

 

AD(Analog to Digital) 컨버터란?

 

쉽게 말해서 아날로그 신호를 디지털 신호로 변환해주는 것

 

앞으로도 수없이 센서를 다루기 위해서는 이부분에 대해서 별도로 알아보도록 해야겠다.

 

 

2-1. 본론(모듈 라이브러리 추가)

본격적으로 아두이노 코딩을 진행하기 앞서, 모듈을 사용하기 위한 헤더 파일을 아두이노 라이브러리에 추가한다.

HX711.zip
0.00MB
ㅇ
HX711 모듈 라이브러리 추가

아두이노를 활용하여 저울을 사용하는데 많은 시간이 소요되었다. 

 

성격급한 나는 구글링해서 HX711 모듈을 사용한 다양한 사례들을 복붙하여 이렇게도 해보고 저렇게도 해봤다.

 

다양한 방법을 사용해본 이유는 최종적으로 내가 개발하기 위한 프로젝트에 적용할 가장 적합한 것을 찾기 위해서다.

 

하지만, 이런 주먹구구 형식의 방법은 시간이 많이 소요되고, 또한 현명한 방법이 아니기 때문에 

 

지금부터라도 하나하나 요목조목 따져가며 한줄, 한줄 해석하는 능력을 갖춰야겠다.

 

어쨌든, 라이브러리에 알맞게 추가하고 선연결을 진행했다. 

 

 

2-2. 본론(아두이노 선 연결)

아두이노 우노를 활용한 로드셀(HX711) 배선도

 

1개의 로드셀을 연결하는 선 연결은 간단했다. 

 

추후 8개의 로드셀을 사용하여 연결할때는 이것보다 복잡하지만, 2개,3개씩 차례대로 연결하다보니 어렵지 않았다.

 

일단, 1개의 로드셀로 코딩이 어떻게 진행되는지 정확하게 파악하기 위한 작업을 진행했다.

 

2-3. 본론(아두이노 코딩)

 

우선 라이브러리에 추가된 헤더 파일을 넣어주고,

#include "HX711.h"

그 다음, 선연결 정보를 정의한다.

#define DOUT1 A0
#define SCK1 A1

baudrate와 로드셀 고유의 캘리브레이션 값을 찾아서 입력하고 1초(1000ms)마다 저울의 무게를 나타내었다. 

float val1;

void setup() {
  Serial.begin(9600);

  scale1.begin(DOUT1, SCK1);

  Serial.println(scale1.read());     

  scale1.set_scale(484.88);                   
  scale1.tare(5); 

void loop() {

  val1 = scale1.get_units();

  Serial.print(val1);

  delay(1000);
}

로드셀의 캘리브레이션의 값을 찾는 것은 구글에 검색하면 여러가지 방법이 있겠지만,

나는 직접 저 값을 찾는 방법을 구현하였다.

 

 

 

 

 

마트에서 파는 과일의 대부분은 상자 박스 안에 담겨있고, 2kg, 5kg..등과 같이 중량별로 유통되고 있다.

 

사람이 직접 전자저울에 무게를 올려놓고 목표 중량에 맞춰 과일 상자안에 담겨 패키징되는데, 

 

그 과정에 소요되는 시간을 단축시키고 정확한 중량 선별을 진행하려고 한다. 

 

 

중량 선별기 제작 프로젝트(Weight Checker Project)  과정

 

크게 3가지 과정을 통해 프로젝트를 진행

 

1. HX711 센서를 활용한 아두이노 선 연결 & 코딩

 

          [1-1] HX711 하나를 이용하여 무게 측정 및 캘리브레이션(Calibration)

          [1-2] HX711 다중 연결(8개)을 통한 측정 안정성 확인 

 

 

2. 파이썬을 활용한 아두이노 시리얼 데이터 처리 

 

          [2-1] Python 내장 모듈(Serial)을 활용한 아두이노 시리얼 데이터 수신 

          [2-2] 시리얼 데이터의 변환(bytes → integer)

          [2-3] 각 저울의 무게로 조합(Combination) 모듈을 사용하여 목표 무게에 가까운 값 찾기

          [2-4] 목표 무게를 저울에 부여된 번호로 반환하기 

 

 

3.  파이썬 Tkinter 모듈을 활용한 GUI 제작

 

          [3-1] Tkinter 라벨을 활용한 표현 방법 1(라벨의 내용 입력)

          [3-2] Tkinter 라벨을 활용한 표현 방법 2(실시간 무게 얻기)

          [3-3] Tkinter 입력값(entry) 적용 방법

 

 

 

과정은 위와 같으며, 제작까지 오랜 시간이 걸렸다. 대략 10개월 정도...

 

코딩의 기본도 아직 모른다. 인터넷 검색과 관련 서적 등 모든걸 동원하여 시간이 남을 때 마다 들여보고, 수정하고, 

 

반복의 반복을 거듭하여 만든 제작의 전반적인 내용을 담았다.

 

처음으로 블로그를 통해 일기처럼 내 개발일지를 기록하여 남겨두려 한다. 

 

 

 

 

 

 

 

 

 

 

+ Recent posts