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