Similar to M221 which sets a variable flow rate percentage, add
support for M220 which sets a percentage modifier for the
feedrate, F.
It seems a little disturbing that the flow rate modifies the next
G1 command and does not touch the buffered commands, but this
seems like the only reasonable thing to do since the M221 setting
could be embedded in the source gcode for some use cases. Perhaps
an "immediate" setting using P1 could be considered later if
needed.
`target` is an input to dda_create, but we don't modify it. We
copy it into dda->endpoint and modify that instead, if needed.
Make `target` const so this treatment is explicit.
Rely on dda->endpoint to hold our "target" data so any decisions
we make leading up to using it will be correctly reflected in our
math.
In a test, the system worked fine even for a change in config.h,
which is #included by a variable (config_wrapper.h, line 20).
This should speed up repeated regression test, e.g. when doing a
'git regtest', substantially.
Disable it only when appropriate, of course.
The move of this code makes Teacup compiling with both,
ACCELERATION_REPRAP and LOOKAHEAD enabled. Such a configuration
makes no sense, but can happen anyways.
The flow rate is given as a percentage which is kept as
100 = 100% internally. But this means we must divide by 100 for
every movement which can be expensive. Convert the value to
256 = 100% so the compiler can optimize the division to a
byte-shift.
Also, avoid the math altogether in the normal case where the
flow rate is already 100% and no change is required.
Note: This also requires an increase in the size of e_multiplier
to 16 bits so values >= 100% can be stored. Previously flow
rates only up to 255% (2.5x) were supported which may have
surprised some users. Now the flow rate can be as high as
10000% (100x), at least internally.
Now it is possible to control the extruders flow.
M221 S100 = 100% of the extruders steps
M221 S90 = 90% of the extruders steps
M221 is also used in other firmwares for this. Also a lot of
hosts, like Octoprint and Pronterface using this M-Code for
this behaviour.
Note a performance improvement opportunity.
Review note by Traumflug: the original commit didn't add a
comment, but replaced the existing code with what's in the
comment now.
According to the comment in issue #223:
Pre-unroll:
LED on time minimum: 3138.44 clock cycles.
LED on time maximum: 5108.8 clock cycles.
LED on time average: 4590.58 clock cycles.
Unrolled:
LED on time minimum: 3016.92 clock cycles.
LED on time maximum: 4987.28 clock cycles.
LED on time average: 4469.06 clock cycles.
Thermistors and AD595 can be faster in that mode.
The new stategy is:
1. read the value
2. start the adc
3. return the result
- next cycle
instead of:
1. start the adc
- wait 10ms
2. read the value
3. return the result
- next cycle
Review changes by Traumflug: fixed the warnings appearing in some
configurations (case NEEDS_START_ADC undefined and case
NEEDS_START_ADC defined, but TEMP_READ_CONTINUOUS == 0)
This allows to use EWMA_ALPHA in an #if clause, which is needed
for the next commit.
Review changes by Traumflug: made changes to comments more
complete, added rounding ("+ 500") and also adjusted Configtool
for the change.
After firmware startup it's always in a valid range, even in the
unlikely case analog_init() is called twice.
This saves 4 bytes binary size without drawback.
If we have EMWA mode turned on, then the user wants to average
several samples from the temp sensors over time. But now we read
temp sensors only 4 times per second making this averaging take
much longer.
Read the temperatures continuously -- as fast as supported by the
probe type -- if we are using weight averaging (TEMP_EMWA < 1.0).
Heater PID loops must be called every 250ms, and temperature
probes do not need to be called any more often than that. Some
probes require some asynchronous operations to complete before
they're ready. Handle these in a state machine that first begins
the conversion and finally completes it on some future tick.
Signal it is complete by setting the new state variable to IDLE.
Kick off the heater PID loop by simply beginning the temperature
conversion on all the temperature probes. When each completes,
it will finish the process by calling its PID routine.
Remove the "next_read_time" concept altogether and just run each
temp conversion at fixed 250ms intervals.
Every type of temp sensor has its own special way to be read
and the once-simple loop has grown complex. Restore some sanity
by isolating the code for each sensor into its own inline
function.
In the process I noticed temp_flags is only ever set (never read)
and is used only in MAX6675. I don't understand what it was used
for, so for now, let's comment it out and revisit this later in
this series.
Integrate the next_read_time countdown into the loop as is common.
Check for start_adc() in the same loop -- before decrementing the
timer -- and call it when needed on the tick before we need the
results.
One concern I have still is that start_adc() may be called twice
within a few microseconds if two probes need to be read. I expect
it should only be called once, but I am not readily familiar with
the AVR ADC conversion protocol.
Extra clock next_start_adc_time was unnecessary. As @phord
observed, it was more understandable to explicitly call start_adc()
1 cycle ahead during temp_sensor_tick(), for sensors which use
analog_read().
As @phord observed, the conditions and the meaning of
next_read_time was not very intuitive. Changed that so that now
it represents the number of 10ms clock ticks before next sensor
reading, i.e. 1 is for 10ms, 2 for 20ms, etc.
Issues ADC reads (via start_adc()) only when actually needed.
When EWMA is enabled, then reads are performed at every
temp_sensor_tick() call, i.e. every 10ms. That's to ensure EWMA
gets updated frequently enough.
When EWMA is disabled, then the only other use for analog reads
is heater control, i.e. heater_tick(). It's run on a 250ms clock,
so that's how often analog reads need to be performed in that
case.
Additionally, ADC conversions are being started 10ms in advance,
so that they can finish before their results are read.
On AVRs analog conversions were running in essentially
free-running mode, i.e. next conversion was being started
immediately after the previous one ended. This caused many
unnecessary interrupts.
Now, conversions are initiated manually by start_adc(). This
causes a single read on each of the registered channels. Once
all channels are read, conversions stop until the next call of
start_adc().
Temperature residency time / temperature achieved check is in
the order of seconds, while updates for residency time were being
called every 10ms - unnecessarily often.
Thermal managers (PID, bang-bang, etc.) assume they're being
ticked on 250ms intervals. In reality, they were being updated on
each temperature reading, which was between 10ms and 250ms. This
caused thermal management to malfunction.
https://github.com/Traumflug/Teacup_Firmware/issues/211
REPRAP style acceleration broke quite a while ago, but no one noticed.
Maybe it's not being used, and therefore also not tested. But it should
at least compile while it remains an option.
The compiler complains that dda->n is not defined and that current_id is
never used. The first bug goes back to f0b9daeea0 in late 2013.
In the interest of supporting exploratory accelerations, fix this to
build when ACCELERATION_REPRAP is chosen.
As far as I (Traumflug) can see, this was an attempt to ease PID
tuning by setting PID parameters according to a model easier
understandable by humans.
This was moved to the attic because because automatic PID tuning
is around the corner, so users (hopefully) no longer have to mess
with PID parameters at all before too long.
simulator.h is already included in config.h/arduino.h, so it doesn't
need to be included again most of the time. In some cases it was
included twice on purpose to undo some intervening include file, but
these intervening includes were unnecessary. Remove some related
include file redundancy by re-ordering the include files and relocating
some nested includes up to the parent .c file.
Because these two pins have no presence in Configtool's GUI, they
got dropped when writing a board config file. These pins are
needed for Gen3 Extruder Board support.
This should solve issue #179.