Stepdance Software Library
Loading...
Searching...
No Matches
analog_in.hpp
1#include "arm_math.h"
2#include <sys/_stdint.h>
3#include <Arduino.h>
4#include "core.hpp"
5
6/*
7Analog Input Module of the StepDance Control System
8
9This module is responsible for reading analog input values in the background, and setting target parameters.
10
11[More Details to be Added]
12
13A part of the Mixing Metaphors Project
14(c) 2025 Ilan Moyer, Jennifer Jacobs, Devon Frost
15
16*/
17
18#ifndef analog_in_h // prevent importing twice
19#define analog_in_h
20
21#define ADC_MODULE_1 0
22#define ADC_MODULE_2 1
23
24#define ADC_NONE 255 // used to flag modules and channels when pin does not map to an ADC
25
26#define NUM_ADC_MODULES 2
27#define MAX_NUM_ADC_INPUTS 16 // per module
28
29// ---ADC SETTINGS---
30
31// AVERAGING
32#define ANALOG_AVERAGING_1 -1 // AVGE = 0
33#define ANALOG_AVERAGING_4 0 // AVGE = 1, corresponds to settings of AVGS
34#define ANALOG_AVERAGING_8 1
35#define ANALOG_AVERAGING_16 2
36#define ANALOG_AVERAGING_32 3
37
38// SAMPLE RESOLUTION
39#define ANALOG_RESOLUTION_8_BIT 0
40#define ANALOG_RESOLUTION_10_BIT 1
41#define ANALOG_RESOLUTION_12_BIT 2
42
43// CLOCK SPEED
44#define ANALOG_CLOCK_75MHZ_DIV_4 1
45#define ANALOG_CLOCK_75MHZ_DIV_8 2
46#define ANALOG_CLOCK_75MHZ_DIV_16 3
47
48// ENABLED
49#define ANALOG_INPUT_DISABLED 0
50#define ANALOG_INPUT_ENABLED 1
51
52// REFERENCE VOLTAGE
53#define VREF_3V3 3.3
54
55// DEADBAND STARTUP DELAY
56#define ANALOG_DEADBAND_STARTUP_DELAY_MS 20
57
62struct analog_pin_info_struct
63{ // hardware_specific
64 // Physical IO
65 uint8_t TEENSY_PIN; // TEENSY Pin #s
66 uint8_t ADC_MODULE; // Which ADC module to use with this pin (some pins only support a single module)
67 uint8_t ADC_INPUT_CHANNEL; // input number on the module
68};
79
80class AnalogInput : public Plugin
81{
82public:
94 void begin(uint8_t pin_reference);
99 void map(ControlParameter *target_parameter);
106 void set_callback(void (*callback_function)());
107
112 void set_floor(ControlParameter output_at_floor); // sets the scaled output value at the floor
118 void set_floor(ControlParameter output_at_floor, uint16_t adc_lower_limit); // allows the lower limit to be adjusted. ADC values below this will output at the floor
123 void set_ceiling(ControlParameter output_at_ceiling);
129 void set_ceiling(ControlParameter output_at_ceiling, uint16_t adc_upper_limit);
133 void invert(); // inverts the output
138 ControlParameter read(); // returns the last read value, based on the internal conversion factor
143 ControlParameter read_raw(); // returns the last read raw value.
144
149 void map(DecimalPosition *target_parameter);
150 void calibrate();
151 void set_averaging(int8_t averaging);
152 void set_resolution(int8_t resolution);
153 void set_clock(int8_t clock);
154 volatile uint16_t last_value_raw = 0;
155 void (*callback_function)() = nullptr;
156 ControlParameter *target_control_param = nullptr;
157 DecimalPosition *target_decimal_pos = nullptr;
158 static AnalogInput *adc1_inputs[MAX_NUM_ADC_INPUTS]; // keeps pointers to all instantiated analog inputs on the ADC1 module
159 static AnalogInput *adc2_inputs[MAX_NUM_ADC_INPUTS];
160 static uint8_t module_num_inputs[NUM_ADC_MODULES]; // tracks the number of instantiated analog inputs on the ADC module; indexed by ADC module
161 static volatile uint8_t module_current_input_index[NUM_ADC_MODULES]; // current analog input
162 void configure_adc(); // changes the ADC configuration to support this AnalogInput
163 void begin_conversion(); // begins a conversion on the ADC module
164 void set_deadband_here(ControlParameter output_at_deadband = 0, uint16_t adc_deadband_width = 4); // sets the deadband to the current value.
165 void set_deadband(ControlParameter output_at_deadband, uint16_t adc_deadband_center, uint16_t adc_deadband_width = 4);
166 float32_t full_scale_volts = VREF_3V3; // we'll default to this for now, until we support changing the reference voltage.
167
168 float32_t conversion_slope_1 = 1;
169 float32_t conversion_intercept_1 = 0;
170 float32_t conversion_slope_2 = 1;
171 float32_t conversion_intercept_2 = 0;
172 uint16_t adc_deadband_location = 0;
173 uint16_t adc_deadband_width = 0;
174 uint16_t adc_deadband_lower = 0;
175 uint16_t adc_deadband_upper = 0;
176
177 void enroll(RPC *rpc, const String &instance_name);
179
180private:
181 // Static Parameters and Methods
182 static const uint16_t max_adc_values[3]; // 8, 10, 12 bit
183 static const struct analog_pin_info_struct analog_pin_info[]; // stores setup information for all analog inputs
184 static volatile uint8_t module_calibrating[NUM_ADC_MODULES]; // flag to indicate that ADC is currently calibrating
185 static void adc1_on_interrupt();
186 static void adc2_on_interrupt();
187 void set_slope_intercept(); // utility to set the slope and intercept values.
188
189 // Instance Parameters and Methods
190 void initialize_adc(); // initializes ADC modules
191 // Default Values
192 // SFCAdder = 3, AverageNum = 32, BCT = 21, LST = 21 --> Total ADCLK per input = 1347
193 // At CLK/16, this gives a total sample rate of 3480 Hz, which would be the interrupt rate.
194 // Spread across four analog inputs, this is ~ 870Hz. We'll turn off the VREF inputs when not actively reading them
195 int8_t averaging = ANALOG_AVERAGING_32;
196 int8_t resolution = ANALOG_RESOLUTION_10_BIT;
197 int8_t clock = ANALOG_CLOCK_75MHZ_DIV_16;
198 int8_t input_enabled = ANALOG_INPUT_ENABLED;
199 uint8_t adc_module;
200 uint8_t adc_input_channel;
201 uint8_t teensy_pin;
202 ControlParameter output_at_floor = 0;
203 ControlParameter output_at_deadband = 512;
204 ControlParameter output_at_ceiling = 1023;
205 uint16_t adc_lower_limit = 0;
206 uint16_t adc_upper_limit = 1023; // 10 bit
207 bool deadband_enabled = false;
208
209 int8_t inversion_multiplier = 1; // 1 for straight thru, -1 for inverted
210};
211
212#endif
void set_ceiling(ControlParameter output_at_ceiling, uint16_t adc_upper_limit)
Sets the scaled output value of the Analog Input at the ceiling (upper limit). This defines the mappi...
void map(ControlParameter *target_parameter)
Maps the AnalogInput to a ControlParameter, which will be updated each time a new analog value is rea...
void begin(uint8_t pin_reference)
Initialize the AnalogInput with a pin reference corresponding to the target physical analog input pin...
void set_ceiling(ControlParameter output_at_ceiling)
Sets the scaled output value of the Analog Input at the ceiling (upper limit). This defines the mappi...
void set_callback(void(*callback_function)())
Sets a callback function that will be called each time a new analog value is read.
void set_floor(ControlParameter output_at_floor)
Sets the scaled output value of the Analog Input at the floor (lower limit).
ControlParameter read_raw()
Reads the last raw ADC value from the Analog Input.
void set_floor(ControlParameter output_at_floor, uint16_t adc_lower_limit)
Sets the scaled output value of the Analog Input at the floor (lower limit). This defines the mapping...
ControlParameter read()
Reads the last converted and scaled value from the Analog Input.
AnalogInput()
Default constructor for AnalogInput. Initializes an AnalogInput instance with default,...
void invert()
Inverts the output of the Analog Input, such that higher raw ADC values correspond to lower ControlPa...
RPC class for handling remote procedure calls over serial streams.
Definition rpc.hpp:35