Commit | Line | Data |
---|---|---|
4cff3ded AW |
1 | #include "mbed.h" |
2 | #include "libs/Module.h" | |
3 | #include "libs/Kernel.h" | |
4 | #include "modules/robot/Block.h" | |
5 | #include "modules/tools/extruder/Extruder.h" | |
6 | ||
7 | ||
8 | ||
9 | Extruder* extruder_for_irq; // We need this global because ISRs can't be attached to an object | |
10 | extern "C" void TIMER1_IRQHandler (void){ | |
11 | if((LPC_TIM1->IR >> 1) & 1){ | |
12 | LPC_TIM1->IR |= 1 << 1; | |
13 | extruder_for_irq->step_pin = 0; | |
14 | } | |
15 | if((LPC_TIM1->IR >> 0) & 1){ | |
16 | LPC_TIM1->IR |= 1 << 0; | |
17 | extruder_for_irq->stepping_tick(); | |
18 | } | |
19 | } | |
20 | ||
436a2cd1 AW |
21 | Extruder::Extruder(PinName stppin) : step_pin(stppin){ |
22 | this->absolute_mode = true; | |
23 | } | |
4cff3ded AW |
24 | |
25 | void Extruder::on_module_loaded() { | |
f5598f5b | 26 | |
436a2cd1 | 27 | if( this->kernel->config->value( extruder_module_enable_checksum )->by_default(false)->as_bool() == false ){ return; } |
f5598f5b | 28 | |
4cff3ded AW |
29 | extruder_for_irq = this; |
30 | ||
31 | // Settings | |
da24d6ae | 32 | this->on_config_reload(this); |
4cff3ded AW |
33 | |
34 | // We work on the same Block as Stepper, so we need to know when it gets a new one and drops one | |
35 | this->register_for_event(ON_BLOCK_BEGIN); | |
36 | this->register_for_event(ON_BLOCK_END); | |
436a2cd1 | 37 | this->register_for_event(ON_GCODE_EXECUTE); |
4cff3ded AW |
38 | |
39 | // Configuration | |
40 | this->acceleration_ticker.attach_us(this, &Extruder::acceleration_tick, 1000000/this->kernel->stepper->acceleration_ticks_per_second); | |
41 | ||
42 | this->start_position = 0; | |
43 | this->target_position = 0; | |
44 | this->current_position = 0; | |
45 | this->current_block = NULL; | |
46 | ||
47 | // Start Timer1 | |
48 | LPC_TIM1->MR0 = 10000; | |
49 | LPC_TIM1->MR1 = 500; | |
50 | LPC_TIM1->MCR = 11; // For MR0 and MR1, with no reset at MR1 | |
51 | NVIC_EnableIRQ(TIMER1_IRQn); | |
52 | LPC_TIM1->TCR = 1; | |
53 | } | |
54 | ||
da24d6ae | 55 | void Extruder::on_config_reload(void* argument){ |
436a2cd1 AW |
56 | this->microseconds_per_step_pulse = 5; //this->kernel->config->value(microseconds_per_step_pulse_ckeckusm)->by_default(5)->as_number(); |
57 | } | |
58 | ||
59 | // Computer extrusion speed based on parameters and gcode distance of travel | |
60 | void Extruder::on_gcode_execute(void* argument){ | |
61 | Gcode* gcode = static_cast<Gcode*>(argument); | |
62 | ||
63 | // Absolute/relative mode | |
64 | if( gcode->has_letter('M')){ | |
65 | int code = gcode->get_value('M'); | |
66 | if( code == 82 ){ this->absolute_mode == true; } | |
67 | if( code == 83 ){ this->absolute_mode == false; } | |
68 | } | |
69 | ||
70 | // Extrusion length | |
71 | if( gcode->has_letter('E' )){ | |
72 | double extrusion_distance = gcode->get_value('E'); | |
73 | //this->kernel->serial->printf("extrusion_distance: %f, millimeters_of_travel: %f\r\n", extrusion_distance, gcode->millimeters_of_travel); | |
74 | if( gcode->millimeters_of_travel == 0.0 ){ | |
75 | this->solo_mode = true; | |
76 | this->travel_distance = extrusion_distance; | |
77 | //this->kernel->serial->printf("solo mode distance: %f\r\n", this->travel_distance ); | |
78 | }else{ | |
79 | this->solo_mode = false; | |
80 | this->travel_ratio = extrusion_distance / gcode->millimeters_of_travel; | |
81 | //this->kernel->serial->printf("follow mode ratio: %f\r\n", this->travel_ratio); | |
82 | } | |
83 | }else{ | |
84 | this->travel_ratio = 0; | |
85 | } | |
da24d6ae AW |
86 | } |
87 | ||
436a2cd1 AW |
88 | |
89 | ||
4cff3ded AW |
90 | void Extruder::on_block_begin(void* argument){ |
91 | Block* block = static_cast<Block*>(argument); | |
92 | this->current_block = block; | |
436a2cd1 | 93 | //this->kernel->serial->printf("block: solomode: %d, travel_distance: %f, travel_ratio: %f \r\n", this->solo_mode, this->travel_distance, this->travel_ratio); |
4cff3ded | 94 | this->start_position = this->current_position; |
436a2cd1 AW |
95 | this->target_position = this->start_position + ( this->current_block->millimeters * this->travel_ratio * 159 ); //TODO : Get from config ( extruder_steps_per_mm ) |
96 | this->acceleration_tick(); | |
4cff3ded AW |
97 | } |
98 | ||
99 | void Extruder::on_block_end(void* argument){ | |
100 | Block* block = static_cast<Block*>(argument); | |
101 | this->current_block = NULL; | |
102 | } | |
103 | ||
104 | void Extruder::acceleration_tick(){ | |
105 | // If we are currently taking care of a block | |
106 | if( this->current_block ){ | |
107 | double steps_by_acceleration_tick = this->kernel->stepper->trapezoid_adjusted_rate / 60 / this->kernel->stepper->acceleration_ticks_per_second; | |
108 | // Get position along the block at next tick | |
436a2cd1 AW |
109 | double current_position_ratio = double( (this->kernel->stepper->step_events_completed>>16) ) / double(this->kernel->stepper->current_block->steps_event_count); |
110 | double next_position_ratio = ( (this->kernel->stepper->step_events_completed>>16) + steps_by_acceleration_tick ) / this->kernel->stepper->current_block->steps_event_count; | |
4cff3ded AW |
111 | // Get wanted next position |
112 | double next_absolute_position = ( this->target_position - this->start_position ) * next_position_ratio; | |
113 | // Get desired speed in steps per minute to get to the next position by the next acceleration tick | |
436a2cd1 AW |
114 | double desired_speed = ( ( next_absolute_position + this->start_position ) - this->current_position ) * double(this->kernel->stepper->acceleration_ticks_per_second); //TODO : Replace with the actual current_position |
115 | ||
116 | //this->kernel->serial->printf("stp->sec: %d, stp->cb->secnt: %u, sbat: %.4f, npr: %.4f, ds: %f --> tap: %u, nap: %f, sp: %u, cp: %u, (tp-sp): %d, cpr: %f\r\n", this->kernel->stepper->step_events_completed>>16, this->kernel->stepper->current_block->steps_event_count, steps_by_acceleration_tick, next_position_ratio, desired_speed,this->target_position, next_absolute_position, this->start_position, this->current_position, int(this->target_position-this->start_position), current_position_ratio ); | |
117 | ||
118 | if( desired_speed <= 0 ){ return; } | |
4cff3ded AW |
119 | |
120 | // Set timer | |
436a2cd1 | 121 | LPC_TIM1->MR0 = ((SystemCoreClock/4))/int(floor(desired_speed)); |
4cff3ded AW |
122 | |
123 | // In case we are trying to set the timer to a limit it has already past by | |
124 | if( LPC_TIM1->TC >= LPC_TIM1->MR0 ){ | |
125 | LPC_TIM1->TCR = 3; | |
126 | LPC_TIM1->TCR = 1; | |
127 | } | |
128 | ||
129 | // Update Timer1 | |
130 | LPC_TIM1->MR1 = (( SystemCoreClock/4 ) / 1000000 ) * this->microseconds_per_step_pulse; | |
131 | } | |
132 | } | |
133 | ||
134 | inline void Extruder::stepping_tick(){ | |
135 | if( this->current_position < this->target_position ){ | |
136 | this->current_position++; | |
137 | this->step_pin = 1; | |
138 | }else{ | |
139 | if( this->current_block == NULL ){ | |
140 | //this->stepping_ticker.detach(); | |
141 | } | |
142 | } | |
143 | } | |
144 | ||
145 | ||
146 |