diff --git a/analog_input.h b/analog_input.h index d05cefe..9f9aa57 100644 --- a/analog_input.h +++ b/analog_input.h @@ -12,7 +12,6 @@ #define ANALOG_INPUT_H const int MAX_INPUT = (1 << 10) - 1; // Max 10 bit analog read resolution. -const int CALIBRATION_OFFSET = 15; class AnalogInput { public: @@ -36,20 +35,29 @@ class AnalogInput { void Process() { old_read_ = read_; int raw = analogRead(pin_); - read_ = map(raw, CALIBRATION_OFFSET, MAX_INPUT, 0, MAX_INPUT); + read_ = map(raw, calibration_offset_, MAX_INPUT, calibration_low_, calibration_high_); } + // Set calibration values. + + void AdjustCalibrationLow(int val) { calibration_low_ += val; } + void AdjustCalibrationOffset(int val) { calibration_offset_ += val; } + void AdjustCalibrationHigh(int val) { calibration_high_ += val; } + /** - * @brief Get the current value of the analog input. + * @brief Get the current value of the analog input within a range of +/-512. * * @return InputState */ - inline uint16_t Read() { return read_; } + inline int16_t Read() { return read_; } private: uint8_t pin_; - uint16_t read_; + int16_t read_; uint16_t old_read_; + int calibration_offset_ = 0; + int calibration_low_ = -512; + int calibration_high_ = 512; }; #endif diff --git a/examples/calibrate_analog/calibrate_analog.ino b/examples/calibrate_analog/calibrate_analog.ino index 148c152..fa5115c 100644 --- a/examples/calibrate_analog/calibrate_analog.ino +++ b/examples/calibrate_analog/calibrate_analog.ino @@ -1,70 +1,99 @@ +/** + * Analog Input Calibration Script + * + * Provide each CV input with a constant voltage of -5v, 0v, and 5v. For + * each config point, provide the appropriate voltage value and then adjust + * the encoder until you have the correct calibration value set. + * + * With the arrow on the left side of the bar, provide a -5v signal and adjust + * the encoder until you read -512. + * + * With the arrow in the center of the bar, provide a 0v signal and adjust the + * encoder until you read 0. + * + * With the arrow on the right side of the bar, provide a 5v signal and adjust + * the encoder until you read 512. + * + * TODO: store the calibration value in EEPROM. + */ + #include "gravity.h" -byte idx = 0; -bool reversed = false; -bool freeze = false; byte selected_param = 0; // Initialize the gravity library and attach your handlers in the setup method. void setup() { // Initialize Gravity. gravity.Init(); - - // Attach handlers. - gravity.clock.AttachIntHandler(IntClock); + gravity.encoder.AttachRotateHandler(CalibrateCV); + gravity.encoder.AttachPressHandler(NextCalibrationPoint); } // The loop method must always call `gravity.Process()` to read any peripherial state changes. void loop() { gravity.Process(); - UpdateDisplay(); } -// The rest of the code is your apps logic! - -void IntClock(uint32_t tick) { - if (tick % 12 == 0 && ! freeze) { - gravity.outputs[idx].Low(); - if (reversed) { - idx = (idx == 0) ? OUTPUT_COUNT - 1 : idx - 1; - } else { - idx = (idx + 1) % OUTPUT_COUNT; - } - gravity.outputs[idx].High(); - } +void NextCalibrationPoint() { + selected_param = (selected_param + 1) % 6; } +void CalibrateCV(Direction dir, int val) { + AnalogInput* cv = (selected_param > 2) ? &gravity.cv2 : &gravity.cv1; + switch (selected_param % 3) { + case 0: + cv->AdjustCalibrationLow(val); + break; + case 1: + cv->AdjustCalibrationOffset(val); + break; + case 2: + cv->AdjustCalibrationHigh(val); + break; + } +} void UpdateDisplay() { gravity.display.clearDisplay(); int cv1 = gravity.cv1.Read(); int cv2 = gravity.cv2.Read(); - - gravity.display.setCursor(10, 10); + + // CV1 Value + gravity.display.setCursor(10, 2); gravity.display.print(F("CV1: ")); gravity.display.print(cv1); - gravity.display.drawRect(10, 22, 100, 10, 1); - if (cv1 >= 512) { - int x = (float(cv1 - 512) / 512.0) * 50; - gravity.display.fillRect(60, 22, x, 10, 1); + gravity.display.drawRect(10, 12, 100, 10, 1); + if (cv1 > 0) { + // 0 to 512 + int x = (float(cv1) / 512.0) * 50; + gravity.display.fillRect(60, 12, x, 10, 1); } else { - int x = (float(512 - cv1) / 512.0) * 50; - gravity.display.fillRect(60-x, 22, x, 10, 1); + // -512 to 0 + int x = (float(abs(cv1)) / 512.0) * 50; + gravity.display.fillRect(60 - x, 12, x, 10, 1); } - gravity.display.setCursor(10, 42); + // CV2 Value + gravity.display.setCursor(10, 32); gravity.display.print(F("CV2: ")); gravity.display.print(cv2); - if (cv2 >= 512) { - int x = (float(cv2 - 512) / 512.0) * 50; + + gravity.display.drawRect(10, 42, 100, 10, 1); + if (cv2 >= 0) { + int x = (float(cv2) / 512.0) * 50; gravity.display.fillRect(60, 42, x, 10, 1); } else { - int x = (float(512 - cv2) / 512.0) * 50; - gravity.display.fillRect(60-x, 42, x, 10, 1); + int x = (float(abs(cv2)) / 512.0) * 50; + gravity.display.fillRect(60 - x, 42, x, 10, 1); } + // Selected calibration point. + int left = 10 + (48 * (selected_param % 3)); + int top = 22 + (selected_param > 2 ? 32 : 0); + gravity.display.drawChar(left, top, 0x1E, 1, 0, 1); + gravity.display.display(); } \ No newline at end of file