int16_t DAIPin::update() { uint16_t now = static_cast<uint16_t>(millis()); uint16_t delta = now - m_lastTime; m_lastTime = now; if (read()) { // move up if (m_duration == 0) { return writeInputValue(256); } m_time += delta; // clamp if (m_time > m_duration) { m_time = m_duration; } } else { // move down if (m_duration == 0) { return writeInputValue(-256); } // clamp if (m_time < delta) { m_time = 0; } else { m_time -= delta; } } return writeInputValue(rc::rangeToNormalized(m_time, m_duration)); }
int16_t AIPin::read() const { uint16_t raw = analogRead(m_pin); // reverse if needed if (m_reversed) raw = 1023 - raw; // apply trim raw += m_trim; // early abort if (raw <= m_min) return writeInputValue(-256); if (raw >= m_max) return writeInputValue( 256); // calculate distance from center and maximum distance from center uint16_t out = raw > m_center ? raw - m_center : m_center - raw; uint16_t max = raw > m_center ? m_max - m_center : m_center - m_min; // change the range from [0 - max] to [0 - 256] // first bring the value down to below 256, or we'll be getting overflows, we'll compensate later int bits = 0; while (out >= 256) { out >>= 1; ++bits; } out <<= 8; // multiply by 256 out /= max; // bring down to new range // bring the value back up if we did any truncating before while (bits > 0) { out <<= 1; --bits; } return writeInputValue((raw < m_center) ? -out : out); }
int16_t AnalogSwitch::update(SwitchState p_state) { uint16_t target = 0; switch (p_state) { case SwitchState_Up: target = m_duration; if (m_duration == 0 || m_time == 0xFFFF) { m_time = target; return writeInputValue(256); } break; case SwitchState_Center: target = m_duration / 2; if (m_duration == 0 || m_time == 0xFFFF) { m_time = target; return writeInputValue(0); } break; case SwitchState_Down: target = 0; if (m_duration == 0 || m_time == 0xFFFF) { m_time = target; return writeInputValue(-256); } break; default: case SwitchState_Disconnected: return writeInputValue(0); } uint16_t now = static_cast<uint16_t>(millis()); uint16_t delta = now - m_lastTime; m_lastTime = now; if (m_time < target) { // move up m_time += delta; // clamp if (m_time > target) { m_time = target; } } else { // move down // clamp if (m_time > target + delta) { m_time = target; } else { m_time -= delta; } } return writeInputValue(rc::rangeToNormalized(m_time, m_duration)); }