Sensor Fusion Library 0.6.1
Orientation sensing for Espressif (ESP32, ESP8266) processors
Loading...
Searching...
No Matches
example_main.cc
1
15#include <Arduino.h>
16#include <sstream>
17#include <string>
18
19#ifdef ESP8266
20 #include <ESP8266WiFi.h>
21 #include <ESP8266WiFiAP.h>
22#endif
23#ifdef ESP32
24 #include <WiFi.h>
25 #include <WiFiAP.h>
26#endif
27#include <WiFiClient.h>
28
29// Sensor Fusion Headers
30#include "sensor_fusion_class.h"
31#include "board.h" // hardware-specific settings. Edit as needed for board & sensors.
32#include "build.h" // sensor fusion configuration options. Edit as needed.
33
34// UART details for data streaming and debug messages. */
35#ifndef BOARD_DEBUG_UART_BAUDRATE
36#define BOARD_DEBUG_UART_BAUDRATE 115200
37#endif
38
39// I2C details - indicate which pins the sensor is connected to
40//Pin numbers are specified using the GPIO## scheme, not the Arduino D## scheme.
41#ifdef ESP8266
42 #define PIN_I2C_SDA (12) //Adjust to your board. A value of -1
43 #define PIN_I2C_SCL (14) // will use default Arduino pins.
44#endif
45#ifdef ESP32
46 #define PIN_I2C_SDA (-1) //Adjust to your board. A value of -1
47 #define PIN_I2C_SCL (-1) // will use default Arduino pins.
48#endif
49// sensor hardware details
50#define BOARD_ACCEL_MAG_I2C_ADDR (0x1F) //I2C address on Adafruit breakout board
51#define BOARD_GYRO_I2C_ADDR (0x21) //I2C address on Adafruit breakout board
52
53//pin that can be twiddled for debugging
54#ifdef ESP8266
55 //ESP8266 has different nomenclature for its GPIO pins and directions
56 #define DEBUG_OUTPUT_PIN 15
57 #define GPIO_MODE_OUTPUT OUTPUT
58#endif
59#ifdef ESP32
60 //was GPIO_NUM_22 for esp_wrover and esp32dev boards, but not avail on nano.
61 #define DEBUG_OUTPUT_PIN GPIO_NUM_14
62#endif
63
69#if F_USE_WIRELESS_UART
70 const char *ssid = "compass";
71 const char *password = "northsouth";
72 #define WIFI_STREAMING_PORT 23
73 WiFiServer server(WIFI_STREAMING_PORT); // use wifi server port 23 (telnet)
74 WiFiClient tcp_client;
75#endif
76
77// Pointer to the Sensor Fusion object, created in setup() and used in loop()
78SensorFusion *sensor_fusion;
79
80// Variables used for timing the fusion calls and outputting data
81unsigned long last_loop_time;
82unsigned long last_print_time;
83
84// Buffer for holding general text output
85#define MAX_LEN_OUT_BUF 180
86char output_str[MAX_LEN_OUT_BUF];
87
88// Loop counter, used for toggling the debugging GPIO pin
89int i;
90
91void setup() {
92 // put your setup code here, to run once:
93
94 pinMode(DEBUG_OUTPUT_PIN, GPIO_MODE_OUTPUT);
95
96 Serial.begin(BOARD_DEBUG_UART_BAUDRATE); // initialize serial UART
97 // delay not necessary - gives time to open a serial monitor
98 delay(1000);
99 Serial.println("Serial port configured.");
100
101 // wifi config - using ESP as Access Point (AP)
102#if F_USE_WIRELESS_UART
103 // init WiFi connection
104 WiFi.softAP(ssid, password);
105 IPAddress myIP = WiFi.softAPIP();
106 Serial.print("My AP IP address: ");
107 Serial.println(myIP);
108 server.begin(23);
109 Serial.print("TCP server started. Connect to ");
110 Serial.print(myIP);
111 Serial.println(" on port 23.");
112#endif
113
114 //create our fusion engine instance
115 sensor_fusion = new SensorFusion();
116
135#if F_USE_WIRELESS_UART && F_USE_WIRED_UART
136 // setup IO subsystem to use both Serial and WiFi
137 if (!(sensor_fusion->InitializeInputOutputSubsystem(&Serial, &tcp_client))) {
138 Serial.println("trouble initting Output and Control system");
139 }
140#elif F_USE_WIRED_UART
141 // setup IO subsystem to use only Serial port
142 if (!(sensor_fusion->InitializeInputOutputSubsystem(&Serial, NULL))) {
143 Serial.println("trouble initting Output and Control system");
144 }
145#elif F_USE_WIRELESS_UART
146 // setup IO subsystem to use only WiFi
147 if (!(sensor_fusion->InitializeInputOutputSubsystem(NULL, &tcp_client))) {
148 Serial.println("trouble initting Output and Control system");
149 }
150#else
151 // setup IO subsystem for no output
152 if (!(sensor_fusion->InitializeInputOutputSubsystem(NULL, NULL))) {
153 Serial.println("trouble initting Output and Control system");
154 }
155#endif
156
157 // connect to the sensors. Accelerometer and magnetometer are in same IC.
158 if(! sensor_fusion->InstallSensor(BOARD_ACCEL_MAG_I2C_ADDR,
159 SensorType::kMagnetometer) ) {
160 Serial.println("trouble installing Magnetometer");
161 }
162 if(! sensor_fusion->InstallSensor(BOARD_ACCEL_MAG_I2C_ADDR,
163 SensorType::kAccelerometer) ) {
164 Serial.println("trouble installing Accelerometer");
165 }
166 if(! sensor_fusion->InstallSensor(BOARD_ACCEL_MAG_I2C_ADDR,
167 SensorType::kThermometer) ) {
168 Serial.println("trouble installing Thermometer");
169 }
170 if(! sensor_fusion->InstallSensor(BOARD_GYRO_I2C_ADDR,
171 SensorType::kGyroscope) ) {
172 Serial.println("trouble installing Gyroscope");
173 }
174 Serial.println("Sensors connected");
175
176 sensor_fusion->Begin(PIN_I2C_SDA, PIN_I2C_SCL);
177 if(sensor_fusion->GetSystemStatus() == NORMAL)
178 { Serial.println("Fusion Engine Ready");
179 }else
180 { Serial.printf("Fusion status: %d\n",(int)sensor_fusion->GetSystemStatus());
181 //may not see this if Begin() hangs, which it does when non-I2C pins chosen.
182 //If pins are I2C-capable, but no physical sensor attached, then will see this error.
183 }
184 last_loop_time = millis(); //these will be used in loop()
185 last_print_time = millis();
186
187} // end setup()
188
189
190void loop() {
191 // put your main code here, to run repeatedly:
192
201 const unsigned long kLoopIntervalMs = 1000 / LOOP_RATE_HZ;
202 const unsigned long kPrintIntervalMs = 1000;
203
204#if F_USE_WIRELESS_UART
205 if (!tcp_client) {
206 tcp_client = server.available(); // check for incoming TCP clients
207 if (tcp_client) {
208 sensor_fusion->UpdateWiFiStream(&tcp_client);
209 }
210 }
211#endif
212 if ((millis() - last_loop_time) > kLoopIntervalMs) {
213 last_loop_time += kLoopIntervalMs; //set up for next time through loop
214
215 //read the Sensors whose turn it is, according to the loops_per_fuse_counter_
216 sensor_fusion->ReadSensors();
217
218 // run fusion routine according to loops_per_fuse_counter_
219 sensor_fusion->RunFusion();
220
221 //create and send Toolbox format packet if fusion has produced new data
222 //This call is optional - if you don't want Toolbox packets, omit it
223// sensor_fusion->ProduceToolboxOutput();
224
225 //Process any incoming commands arriving over serial or TCP port.
226 //See control_input.c for list of available commands.
227 //This call is optional - if you don't need external control, omit it
228// sensor_fusion->ProcessCommands();
229
230// sfg.applyPerturbation(
231// &sfg); // apply debug perturbation (if testing mode enabled)
232 // Serial.println("applied perturbation");
233
234 digitalWrite(DEBUG_OUTPUT_PIN, i % 2); // toggle pin for debugging
235 i++;
236
237 } // end of if() that reads sensors and runs fusion as needed
238
239 // Send example output to Serial port
240 // A few example parameters are chosen - see sensor_fusion_class.h for
241 // a complete list of Get___() methods.
242 if ((millis() - last_print_time) > kPrintIntervalMs) {
243 last_print_time += kPrintIntervalMs;
244 snprintf(output_str, MAX_LEN_OUT_BUF,
245 "%lu: Heading %03.0f, Pitch %+4.0f, Roll %+4.0f, Temp %3.0fC, TurnRate %+5.0f, B %3.0f uT, Inc %3.0f deg, Status %d",
246 millis(),
247 sensor_fusion->GetHeadingDegrees(),
248 sensor_fusion->GetPitchDegrees(),
249 sensor_fusion->GetRollDegrees(),
250 sensor_fusion->GetTemperatureC(),
251 sensor_fusion->GetTurnRateDegPerS(),
252 sensor_fusion->GetMagneticBMag(),
253 sensor_fusion->GetMagneticInclinationDeg(),
254 sensor_fusion->GetSystemStatus()
255 );
256
257 Serial.println( output_str ); //simplest way to see library output
258
271// if (!sensor_fusion->SendArbitraryData(output_str, strlen(output_str))) {
272// Serial.println("couldn't send output");
273// }
274
275 } // end timed if() that prints data as text
276} // end loop()
Board configuration file.
Build configuration file.
float GetRollDegrees(void)
bool InstallSensor(uint8_t sensor_i2c_addr, SensorType sensor_type)
Install Sensor in linked list The max length of the list is checked, and if there is room,...
float GetPitchDegrees(void)
float GetMagneticInclinationDeg(void)
void UpdateWiFiStream(void *tcp_client)
Update the TCP client pointer. Call when a new TCP connection is made, as reported by WiFiServer::ava...
float GetTurnRateDegPerS(void)
void ReadSensors(void)
Reads all sensors. Applies HAL remapping, removes invalid values, and stores data for later processin...
void Begin(int pin_i2c_sda=-1, int pin_i2c_scl=-1)
float GetTemperatureC(void)
bool InitializeInputOutputSubsystem(const Stream *serial_port=NULL, const void *tcp_client=NULL)
void RunFusion(void)
Apply fusion algorithm to sensor raw data. Sensor readings contained in global struct are calibrated ...
float GetMagneticBMag(void)
float GetHeadingDegrees(void)
@ NORMAL
Operation is Nominal.