Commit Graph

87 Commits

Author SHA1 Message Date
Wurstnase b52a1217a9 temp.c: refactor MCP3008 to similar structure. 2016-06-23 22:32:51 +02:00
Phil Hord 05565a0aec temp.c: use free-running readings in EMWA mode.
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).
2016-06-23 22:32:51 +02:00
Phil Hord 6cf845ecda temp.c: remove write-only "temp_flags". 2016-06-23 22:32:51 +02:00
Phil Hord 9d53c13ebd temp.c: assemble cooperative state machine.
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.
2016-06-23 22:32:51 +02:00
Phil Hord 335437022c temp.c: refactor temperature reads into functions.
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.
2016-06-23 22:32:51 +02:00
Phil Hord afb81f21be temp.c: cleanup temp_sensor_tick() and next_read_time sanity.
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.
2016-06-23 22:32:51 +02:00
Robert Konklewski 86c3d97315 temp.c: integrate next_start_adc_time clock into next_read_time.
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().
2016-06-23 22:32:51 +02:00
Robert Konklewski 1aa8698f62 temp.c: improved condition checks for next_read_time timers.
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.
2016-06-23 22:32:51 +02:00
Robert Konklewski 678184b037 Temp: request ADC reads only when necessary.
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.
2016-06-23 22:32:51 +02:00
Robert Konklewski 1236a352c9 Temp: fix a one-off error in sensor read counter check condition. 2016-06-23 22:32:51 +02:00
Robert Konklewski b5cbba7ed8 Temp: read ADC on-demand, instead of constantly running.
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().
2016-06-23 22:32:51 +02:00
Robert Konklewski 03c8d71a56 Temp: have residency updates on 1s clock.
Temperature residency time / temperature achieved check is in
the order of seconds, while updates for residency time were being
called every 10ms - unnecessarily often.
2016-06-23 22:32:51 +02:00
Robert Konklewski 8e977d50ce Temp: have heater update on 250ms intervals.
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
2016-06-23 22:32:51 +02:00
Phil Hord 537b93ae89 Properly handle temp sensor initialization
The existing code eschews "break" apparently thinking that it will
exit the loop prematurely.  In fact this will only exit the switch
correctly.  The loop will run as normal.

Maybe it's not a big deal, though, since the sensors get re-inited
each time the type of sensor is encountered in the loop.  Presumably
it's ok for each of these sensors to get inited multiple times. If
that's always the case, maybe there's no problem here. But with the
current code sensor types might be initialized even when there is no
sensor defined for that type if the TEMP_* boolean is #defined.

For example, if I have this in my config:

    #define TEMP_MAX6675
    #define TEMP_MCP3008
    //#define TEMP_INTERCOM

    DEFINE_TEMP_SENSOR(extruder, TT_MAX6675, AIO5,  0)
    DEFINE_TEMP_SENSOR(bed,      TT_MAX6675, AIO7,  0)

Then the MAX6675 initialization code will be run twice and the MCP3008
code will, too, even though no temp sensor is defined for that type.

This change does not address the "init runs twice" problem.  It only
addresses the "initialization of unused types" problem.
2016-04-20 10:33:12 -04:00
Phil Hord fbe1832467 Optimize ADC temperature search
Use a binary search to find our target temperate in fewer
comparisons.  The search algorithm is ostensibly slower because
it involves a division, but it's a div-by-two so should be
optimized into a simple bit-shift.  Fewer comparisons involves
fewer pgm_read_words and should be faster overall, but the gain
is arguably tiny.

Note by Traumflug:

According to @Wurstnase's performance measurements, gain is
actually pretty huge. Temp conversions 0..1024 before this
and the previous few commits:

  minimum: 1011.84 clock cycles.
  maximum: 1993.92 clock cycles.
  average: 1768.85 clock cycles.

Now:

  minimum: 437.72 clock cycles.
  maximum: 494.76 clock cycles.
  average: 470.278 clock cycles.

That's a speedup by factor 3.7 on average!
2016-04-17 14:31:54 +02:00
Markus Hitter 65857b17dc temp.c: get rid of TEMPTABLE_FORMAT.
Detecting tables by data size works fine, the optimiser removes
unneeded code successfully. Binary size stays the same.
2016-04-17 14:31:52 +02:00
Phil Hord 2291642456 Expand thermistortable to include precomputed slope
Save a division at runtime by pre-calculating the slope between each
pair of adjacent thermistortable values.  Since we use the larger value
each time, save the slope between two values A and B in the table
with the B data.  Therefore the slope is that between each value and
its predecessor in the list.

Store this new value in the third element of the now 3-integers-wide
array which makes up the table. Use fixed-point 6.10 format to store
the slope.  This is almost too narrow for some slopes and maybe it
should be changed to 8.8 fixed-point. In practice this presents a
loss in accuracy, but it is still significantly better than the
previous fixed-sample-size table production method. In particular no
provision is made to handle values which scale over 65535, and it
seems we should at least warn about this if not simply fail before
letting the user go off compiling his code.

Add a new flag TEMPTABLE_FORMAT and define it as 1 to tell the code
that we are using this new and incompatible format.  This lets us
tolerate old hand-crafted thermistor tables by keeping the slower
algorithm in case one is still used.  New thermistor tables should be
defined with this new format and with the FORMAT define set accordingly.

With the default 25 samples this adds 100 bytes to the flash image for
the thermistortable storage for two different thermistors.  But the
code is simplified and saves me 134 bytes in the bargain for a net
decrease in flash size of 34 bytes.
2016-04-17 14:31:12 +02:00
Witold Sowa fdf6dbe849 Added support for MCP3008 and MCP3004 ADC for temperature read 2016-04-12 22:37:50 +02:00
Markus Hitter fb317fef08 ARM: get spi.c, pff.c and pff_diskio.c (SD card handling) in.
Neither is ported for now, but also not essential for printing,
so it's just made sure it's always disabled on ARM.
2015-08-13 17:12:13 +02:00
Markus Hitter d753e2ca7f ARM: enable temperature control.
Postponed until now to allow better testing of heaters earlier.

Also made pid_init() to handle all heaters at once.
2015-08-13 17:12:12 +02:00
Markus Hitter 8f24fbaad4 ARM: get temp.c in.
No code changes, but quite a few removals of __ARMEL_NOTYET__
guards. 20 such guards left.

Test: M105 should work and report plausible temperatures.

Current code size:

    SIZES          ARM...     lpc1114
    FLASH  :  9460 bytes          29%
    RAM    :  1258 bytes          31%
    EEPROM :     0 bytes           0%
2015-08-12 14:26:37 +02:00
Markus Hitter 370bb9f93c Move pin I/O macros from arduino.h to pinio.h.
arduino.h is now free of function definitions.
2015-08-12 14:26:34 +02:00
Markus Hitter 36c2e09788 temp.c: remove a number of obsolete #includes. 2015-08-07 16:16:05 +02:00
Markus Hitter 9c194b42f6 Messages: more newlines needed.
The recent switch to send 'ok' postponed requires also sending a
newline in a few places, because this 'ok' is no longer at the
start of the line. Now it appears in its own line.

Some whitespace at line end was removed in heater.c.

Costs 14 bytes binary size on AVR.
2015-08-07 16:15:17 +02:00
Phil Hord 22b640697b Replace SIMULATOR with __AVR__ in several places.
Previously some features were excluded based on whether SIMULATOR
was defined. But in fact these should have been included when __AVR__
was defined. These used to be the same thing, but now with ARM coming
into the picture, they are not. Fix the situation so AVR includes are
truly only used when __AVR__ is defined.

The _crc16_update function appears to be specific to AVR; I've kept the
alternate implementation limited to AVR in that case in crc.c. I think
this is the right thing to do, but I am not sure. Maybe ARM has some
equivalent function in their libraries.
2015-07-29 21:05:38 +02:00
Markus Hitter 1fb3ece31e SD card: establish spi.c/.h and sd.c/.h and get SPI running.
For now this is just a nice demonstration on how to send bytes
over SPI. Add SD_CARD_SELECT_PIN to your configuration board
file manually to see data signals on MOSI dancing on the scope.

The TODO's about SS in arduino*.h were wrong, SS does have a
chip-specific special meaning (used in SPI multi-master or SPI
slave mode). Still, a #define MAX6675_SELECT_PIN is missing.

Squashed in this commit from the SPI development topic branch to
get this first step working:

Author: jbernardis <jeff.bernardis@gmail.com>
2015-02-04 22:35:07
mendel.c: disable SPI in power management only when not needed.

If we want to talk to a SD card connected to SPI, we need SPI
powered, of course.

From Traumflug: nice catch, Jeff!
2015-07-05 23:32:46 +02:00
Markus Hitter d9fb7cab96 temp.c: print the right temperature.
Order of heater and temperature sensor can differ, so they can get
different numbers. When printing extruder temperatur, we want to
print the temperature of the sensor matching the extruder heater,
not that of the temp sensor with the same number as the extruder
heater. Same for the bed respectively.

This should partially solve issue #96.
2015-05-23 20:36:40 +02:00
Markus Hitter f734b225eb Rename ThermistorTable.h to thermistortable.h.
This is purely cosmetics to match naming conventions of other
files. No functional change.
2015-05-04 20:08:39 +02:00
jbernardis bb29d50f31 temp.c: also report target temperatures.
It's handy and some hosts actually expect this.
2015-04-21 02:11:01 +02:00
Markus Hitter f6115688c5 Move Intercom temp sensor initialisation from mendel.c to temp.c. 2014-12-26 19:41:38 +01:00
Markus Hitter a9f1d00865 Move MAX6675 initialisation from mendel.c to temp.c.
Also note a misplaced and misnamed pin.
2014-12-26 19:41:38 +01:00
Markus Hitter 6dbc7a7797 temp.c: fix typo. 2014-04-13 11:24:47 +02:00
Markus Hitter da8ccf7535 temp_achieved(): check only sensors/heaters turned on.
Problem spotted, described in a helpful manner and over-fixed
by @zungmann. This fix picks up his basic idea and implements it
with already existing state properties.
2014-03-04 19:58:19 +01:00
Phil Hord 21e5343552 Add config.h wrapper to simplify test automation
Test code which wants to customize config.h can do so without
touching config.h itself by wrapping config.h in a macro variable
which is passed in to the compiler.  It defaults to "config.h" if
no override is provided.

This change would break makefile dependency checking since the selection
of a different header file on the command line is not noticed by make
as a build-trigger.  To solve this, we add a layer to the BUILDDIR path
so build products are now specific to the USER_CONFIG choice if it is
not "config.h".
2014-03-04 19:56:23 +01:00
Phil Hord 452e2e5cd9 Restore simulation build target.
This code was accidentally removed long ago in a botched merge. This
patch recovers it and makes it build again. I've done minimal testing
and some necessary cleanup. It compiles and runs, but it probably still
has a few dust bunnies here and there.

I added registers and pin definitions to simulator.h and
simulator/simulator.c which I needed to match my Gen7-based config.
Other configs or non-AVR ports will need to define more or different
registers. Some registers are 16-bits, some are 8-bit, and some are just
constant values (enums). A more clever solution would read in the
chip-specific header and produce saner definitions which covered all
GPIOs. But this commit just takes the quick and easy path to support my
own hardware.

Most of this code originated in these commits:

	commit cbf41dd4ad
	Author: Stephan Walter <stephan@walter.name>
	Date:   Mon Oct 18 20:28:08 2010 +0200

	    document simulation

	commit 3028b297f3
	Author: Stephan Walter <stephan@walter.name>
	Date:   Mon Oct 18 20:15:59 2010 +0200

	    Add simulation code: use "make sim"

Additional tweaks:

Revert va_args processing for AVR, but keep 'int' generalization
for simulation. gcc wasn't lying. The sim really aborts without this.

Remove delay(us) from simulator (obsolete).

Improve the README.sim to demonstrate working pronterface connection
to sim. Also fix the build instructions.

Appease all stock configs.

Stub out intercom and shush usb_serial when building simulator.

Pretend to be all chip-types for config appeasement.

Replace sim_timer with AVR-simulator timer:

The original sim_timer and sim_clock provided direct replacements
for timer/clock.c in the main code. But when the main code changed,
simcode did not. The main clock.c was dropped and merged into timer.c.
Also, the timer.c now has movement calculation code in it in some
cases (ACCELERATION_TEMPORAL) and it would be wrong to teach the
simulator to do the same thing. Instead, teach the simulator to
emulate the AVR Timer1 functionality, reacting to values written to
OCR1A and OCR1B timer comparison registers.

Whenever OCR1A/B are changed, the sim_setTimer function needs to be
called. It is called automatically after a timer event, so changes
within the timer ISRs do not need to bother with this.

A C++ class could make this requirement go away by noticing the
assignment. On the other hand, a chip-agnostic timer.c would help
make the main code more portable. The latter cleanup is probably
better for us in the long run.
2013-12-06 19:24:58 +01:00
David Forrest 6ac79b288d temp.c: DEBUG_USER code for raw temp readings. 2013-07-11 22:03:21 +02:00
Markus Hitter 2ebfd44530 Clean up some unused delay related stuff. 2013-03-24 16:19:21 +01:00
Markus Hitter 042d9ddfc2 Move temp_all_zero() to heaters_all_zero().
We need the power supply for the heaters, after all, not for
the temperature sensors. Some heaters (e.g. fans) don't even have
a temp sensor.
2013-01-03 15:34:47 +01:00
Markus Hitter 6f2ec09837 Make temperature sensor type TT_NONE obsolete.
The requirement was simply neither obvious nor intuitive. Drawback
is, the indices of temperature sensors can now differ from these
of the heaters. That's easier to recognize for newbies, though.
2013-01-03 15:34:41 +01:00
Markus Hitter a2185a4154 temp.c: explicitely cast the EMWA algorithm result.
Contribution by DaveX, see:
http://forums.reprap.org/read.php?147,33082,160633#msg-160633
2012-11-08 16:25:35 +01:00
Markus Hitter 8e27595a5f temp.c: allow smoothing temperature readings.
This is done by an Exponentially Weighted Moving Average (EWMA)
formula. Contribution by DaveX, see
http://forums.reprap.org/read.php?147,33082,157978#msg-157978

Thanks a lot, Dave.
2012-11-08 16:22:31 +01:00
Markus Hitter 8b05e77d49 temp.c: try to deal with flakey temperature sensors. 2012-11-08 16:22:16 +01:00
Markus Hitter a054d4c6cd Remove all remaining evidence of M109.
M109 went away a few commits ago in favour of only M116.
2012-10-14 22:57:22 +02:00
Markus Hitter 97a663a00c analog.c: trim down analog values storage.
Saves 10 bytes RAM and 16 bytes binary size on an 1284P (8 ADC
channels) running two sensors. Should also be a bit faster, as one
loop runs fewer iterations.

Also, checking for NUM_TEMP_SENSORS was a mistake, as temp sensors
_not_ using an analog pin exist. Extreme case is, temp sensors
exist, but zero ADC channels are used.
2012-09-29 23:00:11 +02:00
Mikko Sivulainen bfe5e6f2fc Fixed ADC channel handling.
ADC pin is not the same as ADC channel in atmega1280/2560.
2012-09-29 22:57:55 +02:00
Markus Hitter 37933c8a85 Fix temperature printing.
Remove the assumption there's always an extruder temperature
sensor and make reading on single sensors (e.g. M105 P2) more usable.

Apparently works very well, but *sigh* yet another 100 bytes of binary size.
2012-08-04 22:08:17 +02:00
Markus Hitter 24561919bf temp.c: remove a redundant variable.
This doesn't save a single byte in binary size, as the optimizer
catches this anyways.
2012-08-04 22:08:09 +02:00
Markus Hitter 886bacdbe4 temp.c: remove the delay for the MAX6675.
Suggestion by JTrantow, see also
https://github.com/triffid/Teacup_Firmware/issues/22
2012-05-21 21:00:17 +02:00
Markus Hitter f9a4495aa1 Introduce TEMP_NONE, a "sensor" just storing the target temperature.
This is useful when operation a milling spindle. In this case,
set the spindle speed with M104 Sxxx, where xxx is 1..255.
M104 S0 turns the spindle off.
2011-09-01 19:03:33 +02:00
Markus Hitter 58f4678253 Catch by RobertFach: compatibility option for RepRap Host 20110509. 2011-08-30 12:01:48 +02:00