Una cèl·lula de càrrega és un sensor que permet mesurar forces i, per tant, saber el pes dels objectes. Una cèl·lula de càrrega típica consisteix en una peça que es subjecta per un costat i se li aplica una força al costat contrari. Aquesta força provoca una flexió a la peça que depèn de la força aplicada.

Per mesurar la flexió de la peça, fem servir galques extensiomètriques. Una galga extensiomètrica té una resistència elèctrica que varia en ser estirada o comprimida. Les galgues que posem a la part superior de la barra s'estiraran i les de la part inferior es comprimiran. Si connectem quatre galgues formant un pont i alimentem a tensió constant per dos extrems oposats obtindrem una tensió de sortida als altres dos extrems que dependrà de la força aplicada. La tensió de sortida és molt petita i, per tant, caldrà algun sistema amplificador per poder-la llegir amb el microcontrolador.
Nosaltres farem servir una cèl·lula de càrrega de 10 kg que connectarem a un amplificador que es basa en el circuit integrat HX711. Aquest amplificador no dona un senyal analògic sinó que proporciona la lectura a partir d'una comunicació sèrie. El circuit serà el següent.

El circuit integrat HX711 ens donarà un valor de 24 bits que correspondrà a la lectura del sensor. El nostre programa guardarà el valor llegit a la variable Lectura.
Per llegir el valor, farem un bucle de 24 iteracions. A cada iteració activarem RC6 per demanar un nou bit i llegirem el valor a RC4. Tot seguit desactivarem RC6. El circuit integrat HX711 té tres modes de treball diferents que se seleccionen en funció del nombre de polsos que es fan en el procés de lectura. En el nostre cas ens interessa llegir el port A amb guany elevat, que correspon a 25 polsos. Per això, un cop llegits els 24 valors farem un pols més a RC6.
El següent programa de prova llegeix el valor del sensor (amb la funció LlegirHX), el guarda a la variable Lectura i mostra a la pantalla els tres bytes.
#pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF #pragma config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF #include <xc.h> // Carrega el fitxer de funcions necessari per al compilador XC8 #define _XTAL_FREQ 4000000 // La freqüència del rellotge és 4 MHz
unsigned short long Lectura; // Valor llegit del sensor char Port; // Bits del port C // RC0 a RC3 són els LED // RC4 és DAT (DOUT del sensor) // RC6 és CLK (PD_SCK del sensor) // RC5 és on hi ha el brunzidor
// Definició de les funcions que farem servir unsigned short long LlegirHX(void); // Lectura del sensor void Escriu(unsigned short long Valor); // Escriu un valor de 24 bits a la pantalla void EnviaL(char Caracter); // Envia un caràcter ASCII void Esborra(void); // Esborra la pantalla i posa el cursor a l'inici
void main (void) {
ANSEL = 0b00000101; // Configura AN0 i AN2 com entrada analògica
ANSELH = 0; // Desactiva les altres entrades analògiques
TRISC = 0b00010000; // Posa RC4 com a entrada, la resta és de sortida
TRISB = 0; // Tot el port B és de sortida
TRISA = 0b11111111; // Tot el port A és d'entrada
TXSTAbits.BRGH = 1; // Configuració de velocitat
BAUDCTLbits.BRG16 = 0; // Paràmetre de velocitat de 8 bits
SPBRG = 25; // Velocitat de 9600 baud
TXSTAbits.SYNC = 0; // Comunicació asíncrona
TXSTAbits.TX9 = 0; // Comunicació de 8 bits
RCSTAbits.SPEN = 1; // Activa comunicació sèrie
TXSTAbits.TXEN = 1; // Activa comunicació
PORTB = 0; // Desactiva tots els bits del port B
PORTC = 0; // Desactiva tots els bits del port C
Port = 0; // Desactiva tots els bits de Port
while (1) { // Inici del bucle de programa
Lectura = LlegirHX(); // Llegeix el valor del sensor HX711
Esborra(); // Esborra la pantalla
Escriu(Lectura); // Escriu la lectura a la pantalla
__delay_ms(1000); // Retard d'1 s
}
}
unsigned short long LlegirHX(void) {
unsigned short long Buffer; // Valor rebut
Port = Port & 0b10111111; // Desactiva PD_SCK
PORTC = Port;
for (signed char j = 1; j <= 24; j++){ // 24 bits
Port = Port | 0b01000000; // Activa PD_SCK
PORTC = Port;
Buffer = Buffer << 1; // Rodem els bits per situar el següent
// a la dreta hi quedarà un zero
if (RC4 == 1) { // Si DOUT està activat, posem un 1
Buffer = Buffer | 0b00000001;
}
Port = Port & 0b10111111; // Desactiva PD_SCK
PORTC = Port;
__delay_us(3); // Espera 3 us per fer els polsos de la mateixa amplada
}
Port = Port | 0b01000000; // Activa PD_SCK per dir-li el guany
PORTC = Port;
__delay_us(6); // Espera 6 us per fer els polsos de la mateixa amplada
Port = Port & 0b10111111; // Desactiva PD_SCK
PORTC = Port;
return Buffer; // Retorna el valor
}
void Escriu(unsigned short long Valor) {
char Digits[8]; // Aquí guardarem els 8 dígits
unsigned short long Result; // Variable de treball
Result = Valor % 10;
Digits[0] = (char) Result; // Unitats
Valor = Valor / 10;
Result = Valor % 10;
Digits[1] = (char) Result; // Desenes
Valor = Valor / 10;
Result = Valor % 10;
Digits[2] = (char) Result; // Centenes
Valor = Valor / 10;
Result = Valor % 10;
Digits[3] = (char) Result; // Milers
Valor = Valor / 10;
Result = Valor % 10;
Digits[4] = (char) Result; // Desenes de miler
Valor = Valor / 10;
Result = Valor % 10;
Digits[5] = (char) Result; // Centenes de miler
Valor = Valor / 10;
Result = Valor % 10;
Digits[6] = (char) Result; // Unitats de milió
Result = Valor / 10;
Digits[7] = (char) Result; // Centenes de milió
for (signed char j = 7; j >= 0; j--){ // 8 dígits
Digits[j] = Digits[j] + '0'; // Li sumem el codi ASCII de 0
if (j == 5 || j == 2) { // Posem espais per separar
EnviaL(' '); // Espai
}
EnviaL(Digits[j]); // Número
}
}
void EnviaL(char Caracter) {
TXREG = Caracter; // Agafa el caràcter i l'envia
__delay_ms(1); // Donem temps
while (PIR1bits.TXIF == 0) // Esperem que s'acabi d'enviar
; // No fem res
}
void Esborra(void) {
EnviaL(254); // Caràcter de control
EnviaL(1); // Esborra la pantalla i posa el cursor a l'inici
}
Cada cèl·lula de càrrega i cada amplificador poden ser una mica diferents. També cada usuari pot triar en quin rang de pesos vol treballar (sempre amb un màxim absolut de 10 kg) i amb quina resolució. Anem a veure un cas com a exemple. Hem suposat que el rang de mesura va de 0 a 8 kg. Hem fet una mesura sense pes (0 kg) i una altra amb un pes proper al límit del rang i hem obtingut els següents resultats:
| Pes aplicat | Lectura |
| 0 g | 160 910 |
| 8025 g | 1 859 457 |
Si restem els valors de la darrera columna, trobem que per passar de 0 a 8025 g el valor ha augmentat 1 698 547 unitats. Si ho dividim pels 8025 g obtenim que cada gram ens fa augmentar el valor en 212. Per tant, cada unitat són, aproximadament, 5 mg que és un valor massa sensible si no volem que la lectura ens estigui fluctuant constantment. Cada usuari haurà de triar quina resolució vol donar, tenint present que si tenim més resolució les lectures fluctuaran més.
El nostre programa haurà de llegir el sensor sense pes i guardar-ho com a tara. Després haurà de llegir el sensor amb el pès que volem mesurar i guardar-ho com a lectura. Si restem la tara de la lectura obtindrem el valor que correspon al pes. Si fem això amb un objecte de pes conegut podrem determinar el factor que ens permetrà obtenir el valor del pes en cada mesura.
Important: Ha de quedar clar que aquesta explicació correspon a una cèl·lula de càrrega concreta amb un amplificador determinat i, per tant, les dades llegides poden variar d'un cas a un altre. D'altra banda, cada usuari pot triar el rang de pes amb el que vol treballar (sense passar de 10 kg) i la resolució. En cada cas, doncs, els càlculs poden ser diferents.
En l'exemple explicat s'ha fet servir un pes d'aproximadament 8 kg per a les proves. Sempre és bo fer l'ajust amb el valor límit de l'escala desitjada per aconseguir la màxima precisió però no és imprescindible. Podíem haver fet l'ajust, per exemple, amb un pes al voltant de 3 kg i després haver treballat amb un rang més gran.
Observació: Existeix la possibilitat que les lectures corresponents a pesos petits siguin números negatius i que a l'arribar a un determinat pes es canviï el signe. A la pantalla, però, no veuríem números negatius (ja que el programa no ho contempla) sinó valors extraordinàriament grans. Per exemple, imaginem que a la pantalla llegim 16 661 354, que correspon a -115 862. Una possible solució és sumar un valor (significativament superior a 115 862) a totes les lectures, per exemple 250 000.
Si la cèl·lula estigués muntada amb els cables permutats també pot ser que els valors siguin majoritàriament negatius però aquest altre cas no el contemplarem perquè el raonable és muntar el circuit correctament.

Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.