A library to control a standard inkjet printer carriage.
PrintHead.h
- Committer:
- mattegan
- Date:
- 2016-11-04
- Revision:
- 0:a2dfb2b5f1c9
File content as of revision 0:a2dfb2b5f1c9:
#include "mbed.h" /** PrintHead allows you to control a inkjet printer carriage. * This library expects the DC motor is controlled using three outputs, * one PWM output should set the speed, and the other two should turn the motor * on in a the left and right direction when brought high. The implementation * circuitry is an implementation detail of which the library has no concern. * * The library also expects two interrupt pins that are used as inputs from the * two photo interrupter outputs from the carriage. If the carriage is moving * to the right the "right encoder" input should rise while the "left encoder" * or fall while the "left encoder" is low. The opposite should be true for the * "left encoder". If in doubt, try one, output the count continuously to a * serial terminal. Positive numbers are to the right on the count. If it's * backwards, just flip the writing or the declaration of your instance. */ class PrintHead { public: // positive is to the right // negative is to the left int count; int goal; /** Constructor * * @param PinName left_motor_pin when this pin is high, the carriage should move left * @param PinName right_motor_pin when this pin is high, the carriage should move right * @param PinName motor_pwm_pin this should control the speed of the motor * @param PinName left_encoder_pin the encoder output on the left side of the carriage * @param PinName right_encoder_pin the encoder output on the right side of the carriage * * The initial goal and count position is 0. These are public so change * or read them at will. The class will attempt to servo at whatever goal * position is set. */ PrintHead(PinName left_motor_pin, PinName right_motor_pin, PinName motor_pwm_pin, PinName left_encoder_pin, PinName right_encoder_pin) : _left_motor(left_motor_pin), _right_motor(right_motor_pin), _motor_speed(motor_pwm_pin), _left_encoder(left_encoder_pin), _right_encoder(right_encoder_pin) { // change the motor pwm speed for smooth motor operation // if the pwm frequency is too low the motor jerks the // print head along the track as the PWM toggles on and off _motor_speed.period(0.0001); _motor_speed = 0.6; _left_encoder.rise(this, &PrintHead::left_encoder_rising); _left_encoder.fall(this, &PrintHead::left_encoder_falling); _right_encoder.rise(this, &PrintHead::right_encoder_rising); _right_encoder.fall(this, &PrintHead::right_encoder_falling); _update_motor_ticker.attach_us(this, &PrintHead::update_motor, 1000); count = 0; goal = 0; } void left_encoder_rising() { if(_right_encoder) count--; else count++; } void left_encoder_falling() { if(_right_encoder) count++; else count--; } void right_encoder_rising() { if(_left_encoder) count++; else count--; } void right_encoder_falling() { if(_left_encoder) count--; else count++; } void update_motor() { _left_motor = 0; _right_motor = 0; // gate between 0.4 and 1; // it should be 1 if we're more than 200 away from the goal // between 200 and 0 from the goal, that should be 1 -> 0.4 int dist = abs(goal - count); if(dist > 1000) _motor_speed = 1; else _motor_speed = (0.0006 * dist) + 0.4; if(dist > 20) { _left_motor = (count > goal); _right_motor = (count < goal); } } private: DigitalOut _left_motor; DigitalOut _right_motor; PwmOut _motor_speed; InterruptIn _left_encoder; InterruptIn _right_encoder; Ticker _update_motor_ticker; };