motor_control: operate on units of half micro seconds

This commit is contained in:
Peter Cai 2021-06-11 12:54:27 +08:00
parent 2a4670009b
commit e3517d6fa3
4 changed files with 20 additions and 17 deletions

View File

@ -28,10 +28,11 @@ print("#pragma once")
print("")
print("constexpr unsigned int midi_pitch_offset = " + str(start_pitch) + ";")
print("constexpr unsigned int midi_pitch_max = " + str(end_pitch) + ";")
print("// period is in units of 0.5 us, instead of 1 us")
print("constexpr unsigned long midi_pitch_period[" + str(end_pitch - start_pitch) + "] = {")
for i in range(start_pitch, end_pitch):
period = int(pitch_to_period_micros(i))
period = int(2.0 * pitch_to_period_micros(i))
name = pitch_to_name(i)
if name == "D3" or name == "D#3" or name == "E3":
period = int(period / 2)

View File

@ -78,11 +78,13 @@ int main() {
MIDI.setHandleNoteOff(midi_note_off);
unsigned long cur_micros;
unsigned long cur_half_micros;
unsigned long last_read_micros = 0;
while (true) {
cur_micros = timer2.get_count() / 2ul; // The unit of get_count is 0.5us
handle_tick(cur_micros);
cur_half_micros = timer2.get_count(); // The unit of get_count is 0.5us
cur_micros = cur_half_micros / 2ul;
handle_tick(cur_half_micros);
if (cur_micros - last_read_micros >= MIDI_CMD_INTERVAL_MIN) {
last_read_micros = cur_micros;

View File

@ -4,7 +4,7 @@
MotorControl::MotorControl(int pin_dir, int pin_step) :
pin_dir(pin_dir), pin_step(pin_step),
last_tick_micros(0), tick_period_micros(0)
last_tick_half_micros(0), tick_period_half_micros(0)
{
// No actual constructor logic -- initialization is in Init()
}
@ -17,10 +17,10 @@ void MotorControl::Init() {
digitalWrite(pin_step, LOW);
}
void MotorControl::TickOn(unsigned long period_micros) {
tick_period_micros = period_micros;
void MotorControl::TickOn(unsigned long period_half_micros) {
tick_period_half_micros = period_half_micros;
// Force the next tick to happen
last_tick_micros = 0;
last_tick_half_micros = 0;
}
void MotorControl::TickAtPitch(unsigned int midi_pitch) {
@ -33,21 +33,21 @@ void MotorControl::TickAtPitch(unsigned int midi_pitch) {
}
void MotorControl::TickOff() {
tick_period_micros = 0;
tick_period_half_micros = 0;
}
void MotorControl::Tick(unsigned long cur_micros) {
if (cur_micros == 0) {
void MotorControl::Tick(unsigned long cur_half_micros) {
if (cur_half_micros == 0) {
return;
}
if (tick_period_micros == 0) {
if (tick_period_half_micros == 0) {
return;
}
if (last_tick_micros == 0 || (cur_micros - last_tick_micros) >= tick_period_micros) {
if (last_tick_half_micros == 0 || (cur_half_micros - last_tick_half_micros) >= tick_period_half_micros) {
DoTick();
last_tick_micros = cur_micros;
last_tick_half_micros = cur_half_micros;
}
}

View File

@ -5,9 +5,9 @@ class MotorControl {
// Control pins of the stepper motor
int pin_dir, pin_step;
// Timestamp of the last motor tick
unsigned long last_tick_micros;
unsigned long last_tick_half_micros;
// Interval of motor ticking; 0 to disable the motor
unsigned long tick_period_micros;
unsigned long tick_period_half_micros;
void DoTick();
public:
@ -16,12 +16,12 @@ class MotorControl {
// Must be called before using any other functionality (but after enabling the controllers)
void Init();
// Set the motor to tick at a given interval (inverse of frequency)
void TickOn(unsigned long period_micros);
void TickOn(unsigned long period_half_micros);
// Set the motor to tick with a given MIDI pitch
void TickAtPitch(unsigned int midi_pitch);
// Turn off the motor
void TickOff();
// Perform a tick if necessary
// This should be called from the main event loop
void Tick(unsigned long cur_micros);
void Tick(unsigned long cur_half_micros);
};