O sensor incluído é um "sensor inercial de 9 Eixos", vejamos o que é isso e como usá-lo.
O sensor utilizado é o LSM9D1 da ST (datasheet), que contém acelerômetro, giroscópio e bússola (magnetômetro), cada um deles capaz de medir nas três dimensões.
O acelerômetro fornece a força que está sendo aplicada no sensor (gravidade incluída). O giroscópio informa a velocidade com que o sensor está sendo rotacionado. O magnetômetro mede a intensidade do campo magnético.
O Getting Started do arduino.cc sugere usar a biblioteca oficial para acessar o LSM9D1, o gerenciador de bibliotecas nos oferece 5 opções.
Vejamos rapidamente o que estas opções fornecem:
- Arduino: é a oficial mas é extremamente simples, retornando os valores dos sensores e não permite mudar as sensibilidades.
- Adafruit: apesar da documentar dizer que foi projetada para o módulo LSM9D1 da Adafruit, deve funcionar com o Nano 33 BLE. É ligeiramente mais completa que a biblioteca oficial.
- Melopero: além da leitura dos valores dos sensores, tem suporte a interrupção. Infelizmente no Nano 33 BLE os pinos de interrupção do LSM9D1 estão desconectados.
- SmartEverything: mais ou menos equivalente à oficial.
- Sparkfun: é a mais completa, com métodos para mudar a sensibilidade e métodos para medir e compensar o offset dos sensores.
Vamos fazer um teste rápido, enviando pela serial os valores X e Y dos sensores lidos pela biblioteca oficial:
/*
* Teste simples do sensor inercial do Nano 33 BLE
* Envia leitura dos sensores pela serial
*
* Daniel Quadros
*/
#include <Arduino_LSM9DS1.h>
// Iniciação
void setup() {
Serial.begin(9600);
if (!IMU.begin()) {
Serial.println("Falha ao iniciar a IMU!");
while (1);
}
}
// Laço principal
void loop() {
float xAcc = 0.0, yAcc = 0.0, zAcc = 0.0;
float xMag = 0.0, yMag = 0.0, zMag = 0.0;
float xGir = 0.0, yGir = 0.0, zGir = 0.0;
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(xAcc, yAcc, zAcc);
}
if (IMU.magneticFieldAvailable()) {
IMU.readMagneticField(xMag, yMag, zMag);
}
if (IMU.gyroscopeAvailable()) {
IMU.readGyroscope(xGir, yGir, zGir);
}
Serial.print (xMag);
Serial.print (";");
Serial.print (yMag);
Serial.print (";");
Serial.print (xAcc);
Serial.print (";");
Serial.print (yAcc);
Serial.print (";");
Serial.print (xGir);
Serial.print (";");
Serial.print (yGir);
Serial.println ();
delay(200);
}
O programa python abaixo, para ser executado em um micro, lê os valores enviados pelo Nano 33 BLE e os apresenta de forma gráfica. O programa foi testado com Python 3.6 (era o que tinha instalado no micro) e requer a instalação do pySerial. Uma dificuldade foi descobrir a escala a usar para os sensores. Os valores máximos retornados são +/-2000 graus/segundo para o giroscópio, +/-4G para a aceleração e +/-400 microTesla para o magnetômetro. O programa usa valores máximos menores para ficar mais visível os valores típicos.import tkinter
import serial
import threading
from tkinter import Canvas
from tkinter import Label
top = tkinter.Tk()
canvBussola = Canvas(top, bg = "white", height = 300, width = 300)
canvAccel = Canvas(top, bg = "white", height = 300, width = 300)
canvGiro = Canvas(top, bg = "white", height = 300, width = 300)
lblBussola = Label(top, text="Bussola")
lblAccel = Label(top, text="Acelerometro")
lblGiro = Label(top, text="Giroscopio")
canvBussola.grid(row=0, column=0)
lblBussola.grid(row=1, column=0)
canvAccel.grid(row=0, column=1)
lblAccel.grid(row=1, column=1)
canvGiro.grid(row=0, column=2)
lblGiro.grid(row=1, column=2)
canvBussola.create_line(0, 150, 300, 150, fill="blue")
canvBussola.create_line(150, 0, 150, 300, fill="blue")
canvAccel.create_line(0, 150, 300, 150, fill="blue")
canvAccel.create_line(150, 0, 150, 300, fill="blue")
canvGiro.create_line(0, 150, 300, 150, fill="blue")
canvGiro.create_line(150, 0, 150, 300, fill="blue")
def read_from_port(ser):
global running
ptMag = None
ptAcc = None
ptGir = None
while running:
linha = ser.readline().decode()
partes = linha.split(";")
if len(partes) == 6:
xMag = (float(partes[0])+60.0)/120.0*300.0
yMag = 300.0 - (float(partes[1])+60.0)/120.0*300.0
xAcc = (float(partes[2])+4.0)/8.0*300.0
yAcc = 300.0 - (float(partes[3])+4.0)/8.0*300.0
xGir = (float(partes[4])+1000.0)/2000.0*300.0
yGir = 300.0 - (float(partes[5])+1000.0)/2000.0*300.0
try:
if not (ptMag is None):
canvBussola.delete(ptMag)
ptMag = canvBussola.create_oval(xMag+2, yMag+2, xMag-2, yMag-2, fill="red")
if not (ptAcc is None):
canvAccel.delete(ptAcc)
ptAcc = canvAccel.create_oval(xAcc+2, yAcc+2, xAcc-2, yAcc-2, fill="red")
if not (ptGir is None):
canvGiro.delete(ptGir)
ptGir = canvGiro.create_oval(xGir+2, yGir+2, xGir-2, yGir-2, fill="red")
except:
print ("Fim")
ser = serial.Serial('COM7', 9600)
thread = threading.Thread(target=read_from_port, args=(ser,))
running = True
thread.start()
top.mainloop()
running = False
Nos testes deu para observar um offset bem grande nos valores retornados pelo magnetômetro.



Nenhum comentário:
Postar um comentário