NXP, și Freescale înainte de achiziție, au oferit de-a lungul ultimilor 2 ani o bibliotecă open source pentru dezvoltarea de aplicații bazate pe fuziune de senzori. Versiunea 4.22 a început această acțiune. Un an mai târziu, a urmat versiunea 5.00 care dispunea de îmbunătățiri semnificative. Versiunea 6.00 nu a fost publicată niciodată. Aceasta a adăugat suport pentru precizia accelerometrelor și memorarea parametrilor acestora în NVM. Pe de altă parte, în acea perioadă, CodeWarrior și instrumentele Expert Procesor destinate microcontrolerelor Kinetis, începeau să nu mai fie utilizate. Venise timpul pentru unelte noi. Acesta este momentul în care versiunea 7.00 intră în joc, versiune care se bazează pe fundamentele versiunii 6.00, dar cu O MULȚIME de modificări:
1. Este retras suportul pentru unealta de dezvoltare software – CodeWarrior
2. Suportul pentru software-ul Processor Expert este, de asemenea, retras
3. Suportul pentru MQX RTOS este retras
4. A fost adăugat suport pentru FreeRTOS
5. A fost adăugat suport pentru proiecte bazate pe software-ul BareMetal. Acest lucru a dus la reducerea semnificativă a cantității de memorie flash
de care era nevoie pentru memorarea aplicației.
6. Deoarece aceasta face parte din ecosistemul KEX, acum primiți suport pentru:
• Kinetis Design Studio IDE v3.2
• IAR Embedded Workbench pentru ARM, versiunea 7.50.1
• MDK-ARM Microcontroller Development Kit (Keil)® 5.17
• Suport Makefiles cu GCC revizia 4.9-2015-q3-update de la ARM Embedded
• Atollic® TrueSTUDIO® 5.4.0
7. Parametri de poziție pentru accelerometre
8. Stocarea tuturor valorilor senzorilor pe memorie flash non-volatilă (prin intermediul aplicației Sensor Fusion Toolbox pentru Windows)
9. Abilitatea de întrerupere a alimentării senzorilor selectați (în special a giroscoapelor) în timpul perioadelor de inactivitate
10. Funcțiile de top au fost repartiționate pentru ca să puteți integra în codul vostru capabilități de fuziune de senzori într-un mod incredibil de ușor
11. Funcționalitățile hardware cu care se confruntă au fost simplificate pentru o portare facilă la platformele care nu dispun de microcontrolere Kinetis.
Schema bloc de mai sus arată modul în care biblioteca de fuziune de senzori se potrivește în aplicația voastră. Numărul de funcții de nivel superior pe care trebuie să vi-l amintiți este extrem de mic. Sunt disponibile drivere de senzori pentru senzorii NXP, dar este, de asemenea, ușor să vă scrieți propriile voastre drivere în cazul în care vreți să activați alte dispozitive. În această soluție, vom folosi magnetometrul și accelerometrul pe 6 axe FXOS8700, giroscopul pe 3 axe FXAS21002 și senzorii de presiune barometrici MPL3115.
Haideți să aruncăm o privire la o linie bare metal main().
Primul bloc de cod “trage” header-ele specifice hardware-ului vostru:
// KSDK and ISSDK Headers
#include “fsl_debug_console.h” // KSDK header file for the debug interface
#include “board.h” // KSDK header file to define board configuration
#include “pin_mux.h” // KSDK header file for pin mux initialization functions
#include “clock_config.h” // KSDK header file for clock configuration
#include “fsl_port.h” // KSDK header file for Port I/O control
#include “fsl_i2c.h” // KSDK header file for I2C interfaces
#include “fsl_pit.h” // KSDK header file for Periodic Interval Timer
#include “Driver_I2C.h” // CMSIS I2C Driver
#include “Driver_I2C_SDK2.h” // ISSDK CMSIS I2C Driver
#include “fxas21002.h” // Gyroscope register and bit-field definitions
#include “mpl3115.h” // Pressure sensor register and bit-field definitions
#include “fxos8700.h” // 6-axis accel/mag register and bit-field definitions
#include “fsl_smc.h”
În continuare vom include un număr de antete de fuziune de senzori:
#include “sensor_fusion.h” // Top level magCal and sensor fusion interfaces
#include “control.h” // Command/Streaming interface – application specific
#include “status.h” // Status indicator interface – application specific
#include “drivers.h” // NXP sensor drivers OR customer-supplied drivers
#include “driver_pit.h” // PIT is used to control main() timing loop
Va trebui să definiți un set de structuri de date globale:
SensorFusionGlobals sfg; ///< This is the primary sensor fusion data structure
ControlSubsystem controlSubsystem; ///< Used for serial communications
StatusSubsystem statusSubsystem; ///< Provides visual (usually LED) status indicator
PhysicalSensor sensors[3]; ///< This implementation uses up to 3 sensors
Acum, să aruncăm o privire la main (). Începem prin a face o configurație hardware generală:
int main(void) // This is a bare-metal implementation of the NXP sensor fusion demo build.
{
uint16_t i=0; // general counter variable
BOARD_InitPins(); // defined in pin_mux.c, initializes pkg pins
BOARD_BootClockRUN(); // defined in clock_config.c, initializes clocks
BOARD_InitDebugConsole(); // defined in board.c, initializes the OpenSDA port
Apoi, inițializăm magistrala I2C utilizată pentru comunicația senzorilor:
ARM_DRIVER_I2C* I2Cdrv = &I2C_S_DRIVER_BLOCKING; // Defined by ISSDK
I2Cdrv->Initialize(NULL); // Initialize the I2C KSDK driver
I2Cdrv->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST); // Configure the I2C bus speed
Acum inițializăm diferite subsisteme asociate cu fuziunea de senzori:
initializeControlPort(&controlSubsystem); // configure pins and ports for the control sub-system
initializeStatusSubsystem(&statusSubsystem); // configure pins and ports for the status sub-system
// Initialize sensor fusion structures
initSensorFusionGlobals(&sfg, &statusSubsystem, &controlSubsystem);
Senzorii sunt instalați în momentul rulării:
sfg.installSensor(&sfg, &sensors[0], FXOS8700_I2C_ADDR, 1, (void*) I2Cdrv, FXOS8700_Init, FXOS8700_Read);
sfg.installSensor(&sfg, &sensors[1], FXAS21002_I2C_ADDR, 1, (void*) I2Cdrv, FXAS21002_Init, FXAS21002_Read);
sfg.installSensor(&sfg, &sensors[2], MPL3115_I2C_ADDR, 1, (void*) I2Cdrv, MPL3115_Init, MPL3115_Read);
Punerea în funcțiune a motorului de fuziune, timer-ului hardware și starea inițială:
sfg.initializeFusionEngine(&sfg); // This will initialize sensors and magnetic calibration
pit_init(1000000/FUSION_HZ); // pitIsrFlag will be set true at FUSION_HZ periodic intervals
sfg.setStatus(&sfg, NORMAL); // If we got this far, let’s set status state to NORMAL
Acum avem bucla noastră principală care este temporizată prin intermediul unui temporizator de interval periodic:
while (true)
{
if (true == pitIsrFlag) { // Check whether occur interupt and toggle LED
sfg.readSensors(&sfg, 1); // Reads sensors, applies HAL and does averaging
sfg.conditionSensorReadings(&sfg); // MagCal is run as part of this
sfg.runFusion(&sfg); // Run the actual fusion algorithms
sfg.loopcounter++; // Used to “serialize” mag cal operations
i=i+1;
if (i>=4) { // Some status codes include a “blink” feature. This loop
i=0; // should cycle at least 4X for that to operate correctly.
sfg.updateStatus(&sfg); // This is where pending status updates are made visible
}
sfg.queueStatus(&sfg, NORMAL); // assume NORMAL status for next pass through the loop
// Send stream data to the Sensor Fusion Toolbox
sfg.pControlSubsystem->stream(&sfg, sUARTOutputBuffer);
pitIsrFlag = false; // Reset the flag for the next cycle
}
}
}
Chiar dacă am scris în “C” standard, am folosit un stil de codificare orientată-obiect pentru interfața de nivel superior. Funcțiile care operează pe o structură sunt instalate efectiv, ca făcând parte din această structură, la fel ca și în C ++. Starea și controlul subsistemelor sunt instalate în timpul rulării. Acest lucru vă permite să instalați propriile versiuni, mai degrabă decât să utilizați valorile NXP implicite. Senzorii care urmează să fie utilizați în aplicație sunt, de asemenea, instalați în mod explicit. Apoi vom porni, pur și simplu, subsistemul de fuziune și un temporizator de sistem și le vom plasa într-o buclă principală. Cred că sunteți de acord că această versiune face mai ușoară înțelegerea structurii generale a aplicației decât așa cum era cu bibliotecile anterioare. Pentru mai multe informații, accesați nxp.com/sensorfusion și kex.nxp.com pentru a descărca această versiune și nxp.com/freedom pentru a comanda plăci de dezvoltare.
de Mike Stanley
Systems Engineer
NXP Semiconductors
Despre autor:
Mike Stanley dezvoltă algoritmi avansați și aplicații cu microcontrolere și senzori, inclusiv fuziune de senzori și analiză de date pentru senzori.
Este membru fondator al comunității “MEMS Industry Group’s Accelerated Innovation” și contribuie la definirea parametrilor de performanță ai senzorilor pentru standardul IEEE 2700-2014. Este co-autor al unui capitol privind senzorii inteligenți din manualul “Measurement, Instrumentation, and Sensors Handbook” (volumul doi) și ține conferințe pe teme de senzori. Atunci când temperatura din Arizona scade sub 37°C, îl veți puteți vedea pe Mike zburând la bordul quadcopterului său – F450.
NXP Semiconductors | www.nxp.com