¿Como Utilizar un Sensor AS5048a con Arduino?
En la siguiente guía vamos a explicar como puedes utilizar con Arduino un Encoder AS5048a y leer los datos que se están recibiendo fácilmente en un LCD 16×2
Materiales Necesarios:
- Encoder AS5048a.
- Arduino Nano, Uno, Mega.
- Jumpers.
Pasos a Seguir:
- Realizaremos al siguiente conexión electrónica entre nuestro Arduino y Encoder AS5048a.
- Ahora procedemos a descargar y importar la librería que controla nuestra LCD, la encontraras en el siguiente link:https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-libraryTambién puedes descargarla desde nuestros servidores en el siguiente link:
- Ahora procedemos a cargar el siguiente código a nuestro Arduino:
#include <SPI.h> /*PINS Pines Arduino SPI MOSI = 11, MISO = 12, SCK = 13, CS = 10 Pines STM32 SPI MOSI = PA7, MISO = PA6, SCK = PA5, CS = PA4 */ //16x2 LCD #include <LiquidCrystal_I2C.h> /*PINS Pines Arduino i2C SDA = A4, SCL = A5 Pines STM32 i2C SDA = PB7, SCL = PB6 */ LiquidCrystal_I2C lcd(0x27, 16, 2); const byte CS_pin = 10; //Pin de selección de chip para conmutación manual uint16_t rawData = 0; //Pin de selección de chip para conmutación manual float degAngle = 0; //Ángulo en grados float startAngle = 0; //ángulo de inicio para referencia float correctedAngle = 0; //valor del ángulo tarado (degAngle-startAngle) float totalAngle = 0; //desplazamiento angular acumulado total float numberofTurns = 0; float rpmCounter = 0; //cuenta el número de turnos durante un período determinado float revsPerMin = 0; //RPM int quadrantNumber = 0; int previousquadrantNumber = 0; uint16_t command = 0b1111111111111111; //comando de lectura (0xFFF) float timer = 0; //temporizador para actualizar la pantalla LCD y enviar los datos a través del puerto serie float rpmTimer = 0; //temporizador para estimar las RPM void setup() { SPI.begin(); Serial.begin(9600); Serial.println("AS5048A - Codificador de posición magnetico"); pinMode(CS_pin, OUTPUT); //Pin CS - salida //------------------------------------------------------ lcd.begin(); //inicializar la pantalla lcd lcd.backlight(); //------------------------------------------------------ lcd.setCursor(0, 0); //Definición de posición para escribir desde la primera fila, primera columna. lcd.print("AS5048A Encoder"); lcd.setCursor(0, 1); //2da fila, 1er bloque lcd.print("SPI Demo"); delay(2000); //espera 2 seg printLCD(); //Imprimir Valores //------------------------------------------------------ //Comprobando el ángulo inicial readRegister(); startAngle = degAngle; } void loop() { readRegister(); //leer la posición del imán correctAngle(); //normalizar la lectura anterior checkQuadrant(); //comprobar el sentido de giro y calcular el desplazamiento final if (millis() - timer > 250) { Serial.print("Giros: "); Serial.println(numberofTurns); Serial.print("Angulo Total: "); Serial.println(totalAngle, 2); updateLCD(); //imprima el nuevo contenido en la pantalla LCD (solo los números) timer = millis(); } if (millis() - rpmTimer > 15000) //comprobar y calcular las RPM cada 15 segundos { revsPerMin = 4 * rpmCounter; //60000/15000 = 4 (asumimos la misma velocidad durante todo el minuto) rpmCounter = 0; //Reinicio rpmTimer = millis(); } } void readRegister() { SPI.beginTransaction(SPISettings(3000000, MSBFIRST, SPI_MODE1)); //--enviando el comando digitalWrite(CS_pin, LOW); SPI.transfer16(command); digitalWrite(CS_pin, HIGH); delay(10); //--recibiendo la lectura digitalWrite(CS_pin, LOW); rawData = SPI.transfer16(command); digitalWrite(CS_pin, HIGH); SPI.endTransaction(); rawData = rawData & 0b0011111111111111; //quitar los 2 bits superiores (PAR y EF) degAngle = (float)rawData / 16384.0 * 360.0; //16384 = 2^14, 360 = 360 grados //Serial.print("Gra: "); //Serial.println(degAngle); } void correctAngle() { //recalcular el ángulo correctedAngle = degAngle - startAngle; //esto tara la posición if (correctedAngle < 0) //si el ángulo calculado es negativo, necesitamos "normalizarlo" { correctedAngle = correctedAngle + 360; //corrección para números negativos (es decir, -15 se convierte en +345) } else { //hacer nada } //Serial.print("Ángulo corregido: "); //Serial.println(correctedAngle, 2); //imprimir el ángulo corregido / tarado } void checkQuadrant() { /* //Cuadrantes: 4 | 1 ---|--- 3 | 2 */ //cuadrante 1 if (correctedAngle >= 0 && correctedAngle <= 90) { quadrantNumber = 1; } //Cuadrante 2 if (correctedAngle > 90 && correctedAngle <= 180) { quadrantNumber = 2; } //Cuadrante 3 if (correctedAngle > 180 && correctedAngle <= 270) { quadrantNumber = 3; } //Cuadrante 4 if (correctedAngle > 270 && correctedAngle < 360) { quadrantNumber = 4; } //Serial.print("Cuadrante: "); //Serial.println(quadrantNumber); //imprime nuestra posición "en cuadrante" if (quadrantNumber != previousquadrantNumber) //si cambiamos de cuadrante { if (quadrantNumber == 1 && previousquadrantNumber == 4) { numberofTurns++; // 4 --> 1 transición: rotación CW rpmCounter++; } if (quadrantNumber == 4 && previousquadrantNumber == 1) { numberofTurns--; // 1 --> 4 transición: rotación CCW rpmCounter--; } //esto podría hacerse entre cada cuadrante para que se pueda contar cada 1/4 de transición previousquadrantNumber = quadrantNumber; //actualizar al cuadrante actual } //Serial.print("Vueltas: "); //Serial.println(numberofTurns); //número de vueltas en términos absolutos (puede ser negativo, lo que indica vueltas en sentido antihorario) //después de tener el ángulo corregido y los giros, podemos calcular la posición absoluta total totalAngle = (numberofTurns * 360) + correctedAngle; //número de vueltas (+/-) más el ángulo real dentro del rango 0-360 //Serial.print("Angulo total: "); //Serial.println(totalAngle, 2); //posición absoluta del motor expresada en ángulos de grado, 2 dígitos } void printLCD() { //imprimiendo las partes permanentes lcd.setCursor(0, 0); // primera linea lcd.print("RPM: "); lcd.setCursor(5, 0); lcd.print(" "); lcd.setCursor(5, 0); lcd.print(revsPerMin,0); lcd.setCursor(0, 1); // segunda linea lcd.print("Total: "); lcd.setCursor(7, 1); lcd.print(" "); lcd.setCursor(7, 1); lcd.print(totalAngle,1); } void updateLCD() { //imprimiendo las partes variables lcd.setCursor(5, 0); // primera linea lcd.print(" "); lcd.setCursor(5, 0); lcd.print(revsPerMin,0); lcd.setCursor(7, 1); // segunda linea lcd.print(" "); lcd.setCursor(7, 1); lcd.print(totalAngle,1); }
- Por ultimo procedemos a cargar el código y podremos verificar en nuestro Encoder que pasos estamos teniendo y el sentido de giro.
Debe estar conectado para enviar un comentario.