#include "breakout_potentiometer.hpp" #include namespace pimoroni { bool BreakoutPotentiometer::init(bool skip_chip_id_check) { bool success = false; if(ioe.init(skip_chip_id_check)) { ioe.set_mode(POT_TERM_A, IOExpander::PIN_OUT); ioe.set_mode(POT_TERM_B, IOExpander::PIN_OUT); ioe.set_mode(POT_INPUT, IOExpander::PIN_ADC); if(direction_cw) { // Clockwise increasing ioe.output(POT_TERM_A, IOExpander::LOW); ioe.output(POT_TERM_B, IOExpander::HIGH); } else { // Counter clockwise increasing ioe.output(POT_TERM_A, IOExpander::HIGH); ioe.output(POT_TERM_B, IOExpander::LOW); } // Calculate a period large enough to get 0-255 steps at the desired brightness uint16_t period = (uint16_t)(255.0f / brightness); ioe.set_pwm_period(period); ioe.set_pwm_control(2); // PWM as fast as we can to avoid LED flicker ioe.set_mode(LED_R, IOExpander::PIN_PWM, false, INVERT_OUTPUT); ioe.set_mode(LED_G, IOExpander::PIN_PWM, false, INVERT_OUTPUT); ioe.set_mode(LED_B, IOExpander::PIN_PWM, false, INVERT_OUTPUT); success = true; } return success; } i2c_inst_t* BreakoutPotentiometer::get_i2c() const { return ioe.get_i2c(); } int BreakoutPotentiometer::get_sda() const { return ioe.get_sda(); } int BreakoutPotentiometer::get_scl() const { return ioe.get_scl(); } int BreakoutPotentiometer::get_int() const { return ioe.get_int(); } void BreakoutPotentiometer::set_addr(uint8_t i2c_addr) { ioe.set_addr(i2c_addr); } float BreakoutPotentiometer::get_adc_vref(void) { return ioe.get_adc_vref(); } void BreakoutPotentiometer::set_adc_vref(float vref) { ioe.set_adc_vref(vref); } bool BreakoutPotentiometer::get_direction(void) { return direction_cw; } void BreakoutPotentiometer::set_direction(bool clockwise) { if(clockwise) { // Clockwise increasing ioe.output(POT_TERM_A, IOExpander::LOW); ioe.output(POT_TERM_B, IOExpander::HIGH); } else { // Counter clockwise increasing ioe.output(POT_TERM_A, IOExpander::HIGH); ioe.output(POT_TERM_B, IOExpander::LOW); } direction_cw = clockwise; } void BreakoutPotentiometer::set_brightness(float brightness) { this->brightness = std::min(std::max(brightness, 0.01f), 1.0f); // Calculate a period large enough to get 0-255 steps at the desired brightness uint16_t period = (uint16_t)(255.0f / this->brightness); ioe.set_pwm_period(period); } void BreakoutPotentiometer::set_led(uint8_t r, uint8_t g, uint8_t b) { ioe.output(LED_R, r, false); // Hold off pwm load until the last ioe.output(LED_G, g, false); // Hold off pwm load until the last ioe.output(LED_B, b); // Loads all 3 pwms } int16_t BreakoutPotentiometer::read(uint32_t adc_timeout) { return ioe.input(POT_INPUT, adc_timeout); } float BreakoutPotentiometer::read_as_percent(uint32_t adc_timeout) { return (ioe.input_as_voltage(POT_INPUT, adc_timeout) / ioe.get_adc_vref()); } }