Skip to content

# Quick Start

## Motor Tester Example

This example demonstrates a motor tester with:

- Motor control with kick-start and S-curve for realistic driving feel

- Joystick throttle input

- Buttons to adjust curve behavior on the fly

- Non-blocking timer for consistent updates

    #include <evaTac.h>
    #include <evaRepeatTimer.h>
    #include <evaJoystick.h>
    #include <evaSwitch.h>

    #include <evamTA6586Driver.h>
    #include <evamDirectionalMotor.h>
    #include <evamCurveDecor.h>
    #include <evamKickDecor.h>

    using namespace eva;
    using namespace evam;

    // Build the motor stack from bottom up:
    // Driver (TA6586) -> DirectionalMotor -> KickDecor -> CurveDecor
    // 25ms kick pulse at 90% power to overcome static friction
    // Negative bend (-6) creates sharper initial response

    using BaseMotor = DirectionalMotor<TA6586Driver<9, 10>, -1000, -200, 200, 1000>;
    using KickMotor = KickDecor<BaseMotor, 25, 900>;
    using PreciseMotor = CurveDecor<KickMotor, -6>;

    class Vehicle {
    private:
      PreciseMotor mMotor;

      // Joystick on A0, outputs 1000-2000, mapped to -1000..1000
      PinSymmetricJoystick<A0, INPUT, 100, 600> mThrottle;

      // Timer updates motor every 100ms
      RepeatTimer mTimer{ 100, new Handler<Vehicle>(this, &Vehicle::onTimerTick) };

      // Button on pin 7 increases bend (softer low-speed control)
      PullupSwitch<7> mIncreaseButton{ new Handler<Vehicle>(this, &Vehicle::onIncreaseButtonPress), ON_PRESS };

      // Button on pin 8 decreases bend (sharper response)
      PullupSwitch<8> mDecreaseButton{ new Handler<Vehicle>(this, &Vehicle::onDecreaseButtonPress), ON_PRESS };

      void onIncreaseButtonPress(void* sender, CallbackInfo cbInfo) {
        // Softer low-speed response, stronger high-end
        mMotor.SetBend(5);
      }

      void onDecreaseButtonPress(void* sender, CallbackInfo cbInfo) {
        // Sharper initial response
        mMotor.SetBend(-5);
      }

      void onTimerTick(void* sender, CallbackInfo cbInfo) {
        // Map joystick value (1000-2000) to motor range (-1000..1000)
        int speed = map(mThrottle.getValue(), 1000, 2000, -1000, 1000);
        mMotor.Go(speed);
      }
    };

    void setup() {
      // Static ensures object persists after setup() exits
      static Vehicle vehicle;
    }

    void loop() {
      // Single call drives timers, switches, and motor decorators
      eva::tac();
    }

## Key Concepts Explained

### Motor Stack Composition

The motor is built by stacking components from the bottom up:

    CurveDecor        ← Adds S-curve transformation
        ↑
    KickDecor         ← Adds kick-start pulse
        ↑
    DirectionalMotor  ← Converts -1000..1000 to driver format
        ↑
    TA6586Driver      ← Interfaces with hardware (pins 9, 10)

### EVA Integration

- `eva::tac()` drives all time-based components (timer, decorators)

- `RepeatTimer` provides non-blocking periodic updates

- `Handler` binds events to methods without polling

- `PullupSwitch` handles button behaviour

For more information please visit eva-core-sk documentation

### Customizing Behavior

Parameter | Effect
--- | ---
`KickDecor<..., 25, 900>` | 25ms pulse at 90% power to overcome static friction
`CurveDecor<..., -6>` | Negative bend = sharper initial response
`SetBend(5)` | Softer low-speed control, stronger high-end response