Waga elektroniczna do filamentów

W przypadku, gdy na szpuli filamentu zostało już niewiele i nie mamy pewności czy wystarczy materiału na dany wydruk warto mieć jakiś sposób aby móc oszacować ile konkretnie materiału zostało na szpuli. Najprościej i najszybciej jest do tego celu wykorzystać wagę. Co prawda należy uwzględnić również ciężar szpuli, ale wielu producentów filamentów podaje jaka jest waga pustych szpul, a nawet jeśli nie to możemy zważyć taką szpulę sami - inne egzemplarze szpul o takim samym wyglądzie będą zwykle identyczne wagowo. Oczywiście są gotowe wagi kuchenne do kupienia za kilkadziesiąt złotych, ale możemy również zrobić taką wagę sami.

 

Do wykonania takiej wagi wykorzystałem:

  1. Belka tensometryczna z czterema przewodami. Dostępne są różne warianty w zależności od maksymalnego obciążenia, ja uznałem że 5kg do tego zastosowania będzie w sam raz. Belki takie łatwo znaleźć w różnych sklepach dla elektroników czy modelarzy.
  2. Wzmacniacz do belki tensometrycznej oparty o układ HX711. Posiada on także wbudowany, 24bitowy przetwornik analogowo-cyfrowy.
  3. Wyświetlacz LCD 2x8 z kontrolerem HD44780 do prezentacji wyników.
  4. Koszyk baterii 3x AAA
  5. Włącznik

Oraz do wykonania płytki drukowanej (alternatywnie można wykorzystać Arduino):

  1. Mikrokontroler AVR - w moim przypadku Atmega8, którą miałem pod ręką. Może być także praktycznie dowolny inny o wystarczającej liczbie wyprowadzeń. W projekcie tym wykorzystuję jedynie podstawowe operacje na portach I/O oraz interfejs UART do przesyłania wyników do PC.
  2. Gniazdo programowania w standardzie Atmel-ISP6
  3. 2 sztuki microswitchy z dłuższą osią (minimum 10mm)
  4. Potencjometr 10k
  5. Rezystor 220
  6. Rezystor 10k
  7. 3 kondensatory 100n
  8. Kondensator 47u
  9. Dioda 1n4007
  10. Złącze do komunikacji z PC
  11. Goldpiny do przylutowania wyświetlacza i płytki z HX711

Mając już wszystkie potrzebne elementy można opracować schemat płytki drukowanej:

Schemat ten zawiera jedynie niezbędne minimum potrzebne do prawidłowej pracy urządzenia. Na podstawie schematu powstał wzór ścieżek. W przeciwieństwie do większości wykonywanych przeze mnie płytek zdecydowałem się na wykorzystanie jedynie elementów do montażu przewlekanego. W płytkach wykonywanych samodzielnie najbardziej nie lubię wiercenia, ale z racji wykorzystania większości elementów z demontażu innego, nieużywanego już urządzenia żal mi było je po prostu wyrzucić. Wzór ścieżek przedstawiam poniżej:

Wersję w odpowiedniej skali do wydrukowania załączam w pliku PDF. W celu wykonania płytki metodą termotransferową należy pamiętać o wybraniu skali rzeczywistej wydruku i możliwie najlepszej jakości wydruku.

Mając już gotową płytkę drukowaną zaprojektowałem obudowę, którą wydrukowałem później na drukarce 3d. Obudowa składa się z czterech części: Podstawy, dolnej części wagi (obciążnika), płyty na której umieszcza się ważone przedmioty oraz pokrywki wyświetlacza. Do przykręcenia belki tensometrycznej konieczne będą stożkowe śruby M4 i M5.

Belkę tensometryczną podłącza się do wzmacniacza następująco:

  • czerwony - E+
  • czarny - E-
  • biały - A-
  • zielony - A+

Po wydrukowaniu i polutowaniu złożone urządzenie prezentowało się następująco:

 

Teraz pozostało już tylko napisać program odczytujący naprężenia z belki tensometrycznej i przeliczający odczytane wartości na wagę. Na temat obsługi wyświetlacza LCD i transmisji UART nie będę się wypowiadał w tym artykule, może napiszę kiedyś osobny na ten temat. Zainteresowanych odsyłam do książek i internetu - jest z czego wybierać. Najbardziej interesująca w tym momencie jest funkcja void hx711_odczytaj(uint32_t *wynik), która bezpośrednio odczytuje wynik ze wzmacniacza HX711. Jako argument zadawany jest wskaźnik 32bitowej zmiennej, do której trafi zmierzona wartość. Sama operacja odczytu wrzucona jest w blok atomowy, aby w trakcie odczytu nie były obsługiwane przerwania (związane np. z komunikacją z PC). Następnie odczytywane jest 24 bitów z przetwornika. Po pomiarze ustawiany jest parametr wzmocnienia, który determinuje jednocześnie kanał, z którego wykonywany jest pomiar. Ważna jest także stała WSP_KALIBRACJI. To ona determinuje jaka wartość odczytana z przetwornika odpowiada jakiej wadze. Na początek można ustawić ją na 1.

/*
 * WagaCyfrowa.c
 *
 * Created: 29.12.2020 21:12:56
 * Author : Mateusz
 */ 

#include <avr/io.h>;
#include <util/atomic.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdlib.h>
#include "lcd.h"
#include "uart.h"

#define CLOCK_PIN (1 << PC0) //Arduino Uno 23
#define CLOCK_PIN_DDR DDRC
#define CLOCK_PIN_PORT PORTC
#define CLOCK_PIN_PIN PINC

#define DATA_PIN (1 << PC1) //Arduino Uno 24
#define DATA_PIN_DDR DDRC
#define DATA_PIN_PORT PORTC
#define DATA_PIN_PIN PINC

#define PRZYC1 (1 << PB1)
#define PRZYC1_DDR DDRB
#define PRZYC1_PORT PORTB
#define PRZYC1_PIN PINB

#define PRZYC2 (1 << PD3)
#define PRZYC2_DDR DDRD
#define PRZYC2_PORT PORTD
#define PRZYC2_PIN PIND

#define WZMOCNIENIE 1 //1: Kanał A, wzmocnienie 128, 3: Kanał A wzmocnienie 64, 2: Kanał B wzmocnienie 32
#define WSP_KALIBRACJI 455
uint32_t offset;

uint8_t hx711_czyGotowa()
{
	//Jeśli DATA PIN = 0 to prawda
	if (! (DATA_PIN_PIN & DATA_PIN))
	return 1;
	else
	return 0;
}

void hx711_odczytaj(uint32_t *wynik)
{
	while (!hx711_czyGotowa());
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
	{
		//Odczyt danych (24Bit)
		*wynik =0;
		
		for(uint8_t i = 0; i < 24; ++i)
		{
			CLOCK_PIN_PORT |= CLOCK_PIN;
			*wynik <<= 1;
			if (DATA_PIN_PIN & DATA_PIN)
			*wynik |= 1;
			CLOCK_PIN_PORT &= ~CLOCK_PIN;
		}
		
		//Ustawienie wzmocnienia dla kolejnego pomiaru
		for (uint8_t i = 0; i < WZMOCNIENIE; i++)
		{
			CLOCK_PIN_PORT |= CLOCK_PIN; //Stan wysoki na wyjściu CLK
			CLOCK_PIN_PORT &= ~CLOCK_PIN; //Stan niski na wyjściu CLK
		}
	}
	
}


void hx711_odczytajSrednia(uint8_t n, uint32_t *wynik)
{
	//Wykonuje n pomiarów i wyznacza średnią
	uint32_t suma =0;
	for (uint8_t i = 0; i < n; i++)
	{
		hx711_odczytaj(wynik);
		suma += *wynik;
	}
 	*wynik = suma /n;
}

void hx711_zeruj()
{
	//Tarowanie wagi
	hx711_odczytajSrednia(20, &offset);
}

void hx711_odczytWagi(int32_t *waga)
{
	//Zapisuje wynik pomiaru w gramach
	uint32_t uwaga = 0;
	hx711_odczytajSrednia(10, &uwaga);
	*waga = (int32_t)uwaga - (int32_t)offset;
	*waga *= 10;
	*waga /= WSP_KALIBRACJI;
}

int main(void)
{
	DATA_PIN_DDR &= ~DATA_PIN;
	DATA_PIN_PORT |= DATA_PIN;
	CLOCK_PIN_DDR |= CLOCK_PIN;
	
	PRZYC1_PORT |= PRZYC1;
	PRZYC2_PORT |= PRZYC2;
	
	offset = 0;
	lcdInicjalizacja();
	lcdTekst_P(PSTR("CZEKAJ.."));
	uartInicjalizuj(__UBRR);
	sei();
	lcdDom();
	hx711_zeruj();//Tarowanie
	/* Replace with your application code */
	while (1)
	{
		static uint8_t czyTrzyma = 0;
		//Obsługa przycisku tarowania
		if (! (PRZYC1_PIN & PRZYC1))
		{
			lcdDom();
			lcdTekst_P(PSTR("CZEKAJ..."));
			hx711_zeruj();
		}
		//Obsługa przycisku przytrzymania wyniku
		if (!(PRZYC2_PIN & PRZYC2))
		{
			
			if (!czyTrzyma)
			{
				lcdXY(0,1);
				lcdTekst_P(PSTR("TRZYMAM"));
				czyTrzyma = 1;
				_delay_ms(500);
			}
			else
			{
				czyTrzyma = 0;
			}
		}
		
		
		if (!czyTrzyma)//Jeśli nie włączono funkcji przytrzymania wyniku
		{
			//Wyświetlanie i wysyłanie wyników
			int32_t wynik; //Zmienna przechowująca wynik
			hx711_odczytWagi(&wynik);
			lcdCzysc();
			if (wynik < 0)
			{
				lcdTekst("-");
				uartZapiszZnak('-');
				wynik = -wynik;
			}
			int32_t tmp = wynik/10;
			//Konwersja liczby na łańcuch znaków
			char bufor[6];
			ltoa(tmp, bufor, 10);
			lcdTekst(bufor);
			lcdTekst(",");
			uartZapiszTekst(bufor);
			uartZapiszZnak(',');
			//Część dziesiętna
			tmp = wynik %10;
			ltoa(tmp, bufor, 10);
			lcdTekst(bufor);
			lcdTekst("g");
			uartZapiszTekst(bufor);
			uartZapiszTekst("g\n");
		}
	}
}


Po wgraniu programu na mikrokontroler można przystąpić do kalibracji. Do tego celu potrzebujemy przedmiotu o znanej masie, zmierzonej na przykład za pomocą innej wagi. Jeśli taką nie dysponujemy to możemy wykorzystać na przykład swojego smarfona. Wagę praktycznie każdego modelu można znaleźć w internecie. Ważne tylko, aby wyjąć telefon z etui. Po uruchomieniu wagi i wyzerowaniu kładziemy przedmiot na wagę i zapisujemy wskazaną wartość. Przykładowo, jeśli przedmiot waży 1000 gram, a odczyt wynosi 154532, to współczynnik kalibracji obliczamy z proporcji w następujący sposób:

wsp_kalibracji = odczyt / waga przedmiotu, czyli zgodnie z przykładowymi danymi: 154532/1000 = 155

Współczynnik kalibracji może przyjmować jedynie wartości całkowite.

Załączniki:

Pobierz pliki STL obudowy

Pobierz projekt płytki w formacie KiCAD

Pobierz kod źródłowy