Sensor Fusion Library 0.6.1
Orientation sensing for Espressif (ESP32, ESP8266) processors
Loading...
Searching...
No Matches
control.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2017 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
18#include <Arduino.h>
19#include <HardwareSerial.h>
20#ifdef ESP8266
21 #include <ESP8266WiFi.h>
22#endif
23#ifdef ESP32
24 #include <WiFi.h>
25#endif
26#include "sensor_fusion.h" // Requires sensor_fusion.h to occur first in the #include stackup
27#include "build.h"
28#include "control.h"
29
30// global structures
31uint8_t sUARTOutputBuffer[MAX_LEN_SERIAL_OUTPUT_BUF];
32
33// Blocking function to write multiple bytes to specified output(s): a UART
34// or a TCP socket
35// On ESP32, hardware UART has internal FIFO of length 0x7f, and once the
36// bytes to be written are all in the FIFO, this routine returns. Actual
37// sending of the data may take a while longer...
38int8_t SendSerialBytesOut(SensorFusionGlobals *sfg)
39{
40 ControlSubsystem *pComm = sfg->pControlSubsystem;
41 // track number of bytes separately to run wired/wireless output in parallel
42 uint16_t bytes_left_wired = 0;
43 HardwareSerial *serial_port = (HardwareSerial *) (pComm->serial_port);
44 if (serial_port) {
45 bytes_left_wired = pComm->bytes_to_send;
46 }
47
48 uint16_t bytes_left_wireless = 0;
49 WiFiClient *tcp_client = NULL;
50 if (NULL != pComm->tcp_client) {
51 tcp_client = (WiFiClient *)(pComm->tcp_client);
52 // was WiFiClient *tcp_client = (WiFiClient *)(pComm->tcp_client);
53 bytes_left_wireless = pComm->bytes_to_send;
54 }
55
56 int bytes_to_write_wired;
57
58 while ((bytes_left_wired > 0) || (bytes_left_wireless > 0)) {
59 if (bytes_left_wired > 0) {
60 bytes_to_write_wired = serial_port->availableForWrite();
61 if( bytes_to_write_wired > bytes_left_wired ) {
62 bytes_to_write_wired = bytes_left_wired;
63 }
64 //write() won't return until all requested are sent, so only ask for what there's room for
65 serial_port->write(&(pComm->serial_out_buf[pComm->bytes_to_send - bytes_left_wired]), bytes_to_write_wired);
66 bytes_left_wired -= bytes_to_write_wired;
67 };
68 if (bytes_left_wireless > 0) {
69 if( tcp_client->connected() ) {
70 // send data to wifi TCP socket. write() returns actual # queued, which may be less than requested.
71 bytes_left_wireless -= tcp_client->write(&(pComm->serial_out_buf[pComm->bytes_to_send - bytes_left_wireless]), bytes_left_wireless);
72 }else {
73 tcp_client->stop();
74 bytes_left_wireless = 0; //don't bother trying to send any remaining bytes
75 }
76 }
77 }//end while() there are unsent bytes
78 pComm->bytes_to_send = 0;
79 return (0);
80}//end SendSerialBytesOut()
81
82// Check for incoming commands, which are sequences of ASCII text,
83// arriving on either hardware UART or TCP socket. Send them to
84// function for decoding, as defined in DecodeCommandBytes.c
85// Doesn't distinguish between which path the commands arrive by,
86// as it is unlikely one would have multiple simultaneous sources.
87int8_t ReceiveIncomingCommands(SensorFusionGlobals *sfg)
88{
89 uint8_t data;
90 WiFiClient *tcp_client = (WiFiClient *) sfg->pControlSubsystem->tcp_client;
91 HardwareSerial *serial_port = (HardwareSerial*) sfg->pControlSubsystem->serial_port;
92
93 // check for incoming bytes from serial UART
94 if( serial_port ) {
95 while (0 < Serial.available() )
96 { data = serial_port->read();
97 DecodeCommandBytes(sfg, &data, 1);
98 }
99 }
100 // check for incoming bytes from TCP socket
101 if (tcp_client) {
102 while (tcp_client->connected() && (0 < tcp_client->available())) {
103 tcp_client->read(&data, 1);
104 DecodeCommandBytes(sfg, &data, 1);
105 }
106 }
107
108 return 0;
109}//end ReceiveIncomingCommands()
110
113 ControlSubsystem *pComm,
114 const void *serial_port, const void *tcp_client )
115{
116 if (pComm)
117 { //commands (e.g. from Sensor Toolbox) can change some of these, such as
118 //which packets are enabled
119 pComm->DefaultQuaternionPacketType = Q3; // default to simplest algorithm
120 pComm->QuaternionPacketType = Q3; // default to simplest algorithm
121 pComm->AngularVelocityPacketOn = false; // transmit angular velocity packet
122 pComm->DebugPacketOn = false; // transmit debug packet
123 pComm->RPCPacketOn = true; // transmit roll, pitch, compass packet
124 pComm->AltPacketOn = false; // Altitude packet
125 pComm->AccelCalPacketOn = false;
126 pComm->serial_out_buf = sUARTOutputBuffer;
127 pComm->write = SendSerialBytesOut;
128 pComm->stream = CreateOutgoingPackets;
129 pComm->readCommands = ReceiveIncomingCommands;
130 pComm->injectCommand = DecodeCommandBytes;
131 pComm->serial_port = serial_port;
132 pComm->tcp_client = tcp_client;
133
134 return true;
135 }
136 else
137 {
138 return false;
139 }
140}//end initializeIOSubsystem()
141
142void UpdateTCPClient(ControlSubsystem *pComm,void *tcp_client) {
143 pComm->tcp_client = tcp_client;
144}//end UpdateTCPClient()
Build configuration file.
bool initializeIOSubsystem(ControlSubsystem *pComm, const void *serial_port, const void *tcp_client)
Initialize the control subsystem and all related hardware.
Definition control.cc:112
Defines control sub-system.
void CreateOutgoingPackets(SensorFusionGlobals *sfg)
void DecodeCommandBytes(SensorFusionGlobals *sfg, uint8_t input_buffer[], uint16_t nbytes)
The sensor_fusion.h file implements the top level programming interface.
@ Q3
Quaternion derived from 3-axis accel (tilt)
The ControlSubsystem encapsulates command and data streaming functions.
Definition control.h:51
The top level fusion structure.