yogurt: Add part 1 block post (force push to use lfs to xcf).
This commit is contained in:
parent
19f2613d8c
commit
4120078834
45 changed files with 473 additions and 0 deletions
250
content/posts/smart-yogurt-maker-part-01/index.md
Normal file
250
content/posts/smart-yogurt-maker-part-01/index.md
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
---
|
||||
title: "Smart Yogurt Maker Part 1"
|
||||
date: "2022-01-25"
|
||||
author: "William Floyd"
|
||||
featured_image: "media/IMG_20220125_113949_cleaned.jpg"
|
||||
categories: [
|
||||
"Development",
|
||||
"Hardware",
|
||||
"Software"
|
||||
]
|
||||
tags: [
|
||||
"ESPHome",
|
||||
"Rice Cooker",
|
||||
"Home Assistant",
|
||||
"Smart Home",
|
||||
"Automation",
|
||||
"Yogurt"
|
||||
]
|
||||
---
|
||||
|
||||
A certain [Rice](/2018/smart-rice-cooker) [Cooker](/2018/dumb-rice-cooker) has been languishing in a box for the last several years - now it is time to revisit it.
|
||||
It is a tale of Solder, Software, and Streptococcus thermophilus.
|
||||
|
||||
***
|
||||
|
||||
# "Last time, on Rice Cooker Adventures"
|
||||
|
||||
This story picks up where I left off 3 years ago - the rice cooker has thermistors taped to the bottom of the pot with high temperature fiberglass tape. Specifically, I have 4 of the same thermistor in 2 parallel lines of 2 series resistors, like so.
|
||||
|
||||
![Thermistor Diagram][thermistors]
|
||||
|
||||
This serves to roughly average the resistances, to account for possible hotspots on the pot, while only taking a single ADC pin.
|
||||
|
||||
However, time has not been kind to my memory, and the specific parameters of these thermistors are unknown, so first, it's time to do some testing.
|
||||
|
||||
# Side Quest: Thermistor Calibration
|
||||
|
||||
I have a thermocouple that I can use to verify the temperature of the pot with, so here is the setup: log the resistance through the thermistor bank at close to room temperature, rolling boil, and a middle temperature (during cooldown). These three sample points may then be used to find the parameters of the thermistor exactly.
|
||||
|
||||
From hazy memory (and counting parts in inventory), my suspicion was that I had used a $100k\Omega$ thermistor.
|
||||
Brand is unknown, but representative datasheets online cite a $\beta$ value of 3950 - let's see how we compare.
|
||||
|
||||
## Wait, what does $\boldsymbol{\beta}$ mean?
|
||||
|
||||
For a more in depth read, look [here](https://www.qtisensing.com/wp-content/uploads/Beta-vs-Steinhart-Hart.pdf), but in summary early studies proposed that for NTC thermistors, the temperature $T$ could be determined given a measured resistance $R$, coefficient $\beta$ and reference resistance $R_0$ and temperature $T_0$, like so:
|
||||
|
||||
$$
|
||||
\frac {1}{T}=\frac{1}{T_{0}}+{\frac {1}{\beta}} \ln{\frac {R}{R_{0}}}
|
||||
$$
|
||||
|
||||
While this may work for small temperature ranges (approximately $20^\circ \text{C}$ or so), we require a larger range, and so we are instead going to look at the...
|
||||
|
||||
## Steinhart-Hart Equation
|
||||
|
||||
Briefly summarizing [Wikipedia](https://en.wikipedia.org/wiki/Steinhart%E2%80%93Hart_equation), the equation states:
|
||||
|
||||
$$\frac{1}{T}=A+B\cdot\ln\{\left(R\right)}+C(\ln \left(R\right))^{3}$$
|
||||
|
||||
Which, when using 3 sample points, results in:
|
||||
|
||||
$$
|
||||
\begin{bmatrix}
|
||||
1 & \ln R_1 & \ln^3 R_1 \\\\
|
||||
1 & \ln R_2 & \ln^3 R_2 \\\\
|
||||
1 & \ln R_3 & \ln^3 R_3
|
||||
\end{bmatrix}\begin{bmatrix}
|
||||
A \\
|
||||
B \\
|
||||
C
|
||||
\end{bmatrix} = \begin{bmatrix}
|
||||
\frac{1}{T_1} \\\\
|
||||
\frac{1}{T_2} \\\\
|
||||
\frac{1}{T_3}
|
||||
\end{bmatrix}
|
||||
$$
|
||||
|
||||
In my case, I found the points of reference using a setup like so:
|
||||
|
||||

|
||||
|
||||
Do note that in order to reach a full boil (and $100^\circ \text{C}$ on the thermocouple), the lid of the rice cooker was attached.
|
||||
|
||||
While I could show the calculations, and they wouldn't be difficult, I'll be honest: I used an [online calculator](https://www.thinksrs.com/downloads/programs/therm%20calc/ntccalibrator/ntccalculator.html).
|
||||
|
||||

|
||||
|
||||
Using the measurements:
|
||||
|
||||
$$
|
||||
\begin{array}{|l|l|}
|
||||
\hline \mathbf{R}(\boldsymbol{\Omega}) & \mathbf{T}\left({ }^{\circ} \mathbf{C}\right) \\\\
|
||||
\hline 81 \mathrm{k} & 33 \\\\
|
||||
\hline 21.3 \mathrm{k} & 66 \\\\
|
||||
\hline 6.4 \mathrm{k} & 100 \\\\
|
||||
\hline
|
||||
\end{array}
|
||||
$$
|
||||
|
||||
Yielded
|
||||
|
||||
$$
|
||||
\begin{aligned}
|
||||
A &= 1.032978070 \cdot 10^{-3}\\\\
|
||||
B &= 1.733021623 \cdot 10^{-4}\\\\
|
||||
C &= 1.902682261 \cdot 10^{-7}\\\\
|
||||
\hline
|
||||
R_{(25^\circ \text{C})} &= 117072.68 \Omega \\\\
|
||||
\beta_\text{calculated} &= 4202.76 \text{K}
|
||||
\end{aligned}
|
||||
$$
|
||||
|
||||
As we can see then, the actual $\beta$ value is larger than predicted ($3950\text{K}$ predicted vs. $4203\text{K}$ actual), as is the reference resistance ($100\text{k}\Omega$ predicted vs. $117\text{k}\Omega$ actual).
|
||||
In fact, neither of these are even in the commonly stated "$\pm 1 \\%$" range.
|
||||
Good thing we're calibrating, hey?
|
||||
|
||||
# "Back to our regularly scheduled programming"
|
||||
|
||||
How to use this data then?
|
||||
Being short on time, I opted to take the easy way out, and use the wonderful [ESPHome](https://esphome.io/), as I already use Home Assistant.
|
||||
As it turns out, they already have us covered, with a [NTC Sensor component](https://esphome.io/components/sensor/ntc.html) already built in.
|
||||
This, coupled with a [resistance](https://esphome.io/components/sensor/resistance.html) and [ADC](https://esphome.io/components/sensor/adc.html) sensor allow using a voltage divider to measure the resistance of the thermistor.
|
||||
|
||||
You know those calculations and equations we did above?
|
||||
Unnecessary, all of it.
|
||||
ESPHome supports doing Steinhart-Hart calculations itself, and only needs the three sample points.
|
||||
|
||||
In the meantime, a Wemos D1 Mini on a breadboard is ready to go (they're cheap and chearful).
|
||||
I wire it up with a $6.8\text{k}\Omega$ resistor (what I had handy), and away I went.
|
||||
The circuit looks something like this, where the two trailing wires connect to the thermistor bank:
|
||||
|
||||

|
||||
|
||||
To prevent confusion, here is my final working config, then I'll explain.
|
||||
|
||||
```yaml
|
||||
sensor:
|
||||
- platform: ntc
|
||||
sensor: resistance_sensor
|
||||
calibration:
|
||||
- 81.0kOhm -> 33°C
|
||||
- 21.3kOhm -> 66°C
|
||||
- 6.4kOhm -> 100°C
|
||||
name: Rice Cooker Temperature
|
||||
unit_of_measurement: °C
|
||||
|
||||
- platform: resistance
|
||||
id: resistance_sensor
|
||||
sensor: source_sensor
|
||||
configuration: DOWNSTREAM
|
||||
resistor: 6.96kOhm
|
||||
reference_voltage: 3.306V
|
||||
name: Resistance Sensor
|
||||
|
||||
- platform: adc
|
||||
id: source_sensor
|
||||
pin: A0
|
||||
name: Voltage Sensor
|
||||
filters:
|
||||
- multiply: 3.2
|
||||
update_interval: 1s
|
||||
```
|
||||
|
||||
# Calibrate all the things
|
||||
|
||||
## Series Resistor
|
||||
Easy, measuring mine I found it to be $6.96\text{k}\Omega$, certainly different from the $6.8\text{k}\Omega$ it's meant to be.
|
||||
Throw that in the config.
|
||||
|
||||
## Reference Voltage
|
||||
This is also easy enough, measure the $3.3\text{V}$ pin off the D1 mini.
|
||||
Mine came out to be $3.306\text{V}$, respectably close to rated!
|
||||
That goes in the config too.
|
||||
|
||||
## Multiply Filter
|
||||
As it turns out, the D1 mini has an internal voltage divider to convert the $3.3\text{V}$ of the input voltage down to the $1\text{V}$ the ADC is rated for.
|
||||
This is nice, as it protects the ADC, but it must be accounted for.
|
||||
But there's a catch - on my board this wasn't quite right - the voltage read was still slightly wrong.
|
||||
I could try manually tuning this, but there is an easier way.
|
||||
Instead, I measured the actual voltage ($3.306\text{V}$), and compared it to the voltage being read.
|
||||
|
||||
Say there was no error, then we would say $V_\text{actual}=V_\text{measured}$, and if there is an error of a multiple difference between the two, we can say $V_\text{actual}=m\cdot V_\text{measured}$. Thus, to find this multiplier, we say:
|
||||
|
||||
$$
|
||||
m = \frac{V_\text{actual}}{V_\text{measured}}
|
||||
$$
|
||||
|
||||
Using this method, I find my multiplier to be $3.2$, not $3.3$.
|
||||
|
||||
With that, the board is finally reading the correct voltage, the correct resistance, and the correct temperature.
|
||||
|
||||
# "You're so controlling!"
|
||||
|
||||
Given that I have Home Assistant, automating it becomes easy.
|
||||
|
||||
I'm currently using a [Tasmota](https://tasmota.github.io/docs/) flashed smart outlet to control the power to the heating element of the rice cooker (for reference, it pulls up to $400\text{W}$ at full load).
|
||||
In future, I would like to condense all functionality into a relay controlled directly by the ESP8266, to allow greater safety in case of network issues or even local PID tuning.
|
||||
|
||||
I am also using a [PID controller for Home Assistant](https://github.com/soloam/ha-pid-controller).
|
||||
It seems to work fine, I am just bad at PID tuning, so results may vary depending on hardware, amount of mass in the cooker, ambient temperatures, etc.
|
||||
That being said, a simple automation to turn the heater on when the PID response goes high and turn off when not high yields acceptable results.
|
||||
|
||||
From fiddling with the settings, I currently am using the following parameters:
|
||||
|
||||
$$
|
||||
\begin{aligned}
|
||||
P &= 60 \\\\
|
||||
I &= 5.6 \\\\
|
||||
D &= 6.7 \\\\
|
||||
\end{aligned}
|
||||
$$
|
||||
|
||||
Further tuning is required, but this held well overnight - mostly...
|
||||
|
||||

|
||||
|
||||
I did change the set point from $105^\circ\text{F}$ to $107^\circ\text{F}$ halfway through, as well as tweaked some of the PID tuning.
|
||||
The concerning spike at 9:00 is marked by a momentary loss of connection with the ESP board - my automation failed to account for a loss of connection and so allowed the heat to continue rising.
|
||||
Thankfully, this was a short-lived event, but it is concerning nonetheless, and will require testing of my automation to prove that power loss tends towards a "safer" outcome.
|
||||
Do note that "safer" means no dead yogurt culture - the safety features of the rice cooker remain unchanged and functional.
|
||||
|
||||
# The proof is in the... yogurt?
|
||||
|
||||
So how did it do?
|
||||
I am notoriously _not_ picky when it comes to food, but I think it turned out great!
|
||||
Filling the rice cooker about halfway with whole milk, I heated it to $180^\circ \text{F}$ for a few minutes (I read I ought to go for longer...), cooled to about $110^\circ \text{F}$, then added a liberal few spoonfuls (think 1/5 volume of milk) of plain Dannon yogurt.
|
||||
I let it proof in the rice cooker for 7.5 hours, with the lid sealed.
|
||||
|
||||

|
||||
|
||||
I put the whole rice cooker in the fridge to cool, with the lid sealed.
|
||||
Trying it later that same evening, I quite enjoyed it.
|
||||
I'll start my next batch from this one, and hopefully it'll be even better.
|
||||
|
||||

|
||||
|
||||
# "Next time, on Rice Cooker Adventures"
|
||||
|
||||
Now that I have a temperature controllable rice-cooker, and the ability to remotely start, stop, and modify set points, I may try other foods.
|
||||
For now, I need to:
|
||||
|
||||
* solder a perfboard version of the circuit
|
||||
* add a relay to control the cooker directly
|
||||
* ensure the outlet will turn off if the ESP8266 loses connection
|
||||
* PID tune the setup for the most common scenario (steady $107^\circ \text{F}$ with the lid shut)
|
||||
|
||||
First though, I'm gonna go eat some fresh yogurt...
|
||||
|
||||
[thermistors]: media/circuit.svg "Thermistor Diagram]"
|
||||
|
||||
{{< mathjax >}}
|
||||
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG-20220125-WA0001.jpeg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG-20220125-WA0001.jpeg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220124_174144.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220124_174144.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220124_180143.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220124_180143.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220125_105918.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220125_105918.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220125_105924.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220125_105924.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220125_113949.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220125_113949.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220125_113949_cleaned.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220125_113949_cleaned.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220125_114006.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220125_114006.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220125_114006_cleaned.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220125_114006_cleaned.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220125_175809.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220125_175809.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220125_180035.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/IMG_20220125_180035.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/posts/smart-yogurt-maker-part-01/media/calc.png
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/calc.png
(Stored with Git LFS)
Normal file
Binary file not shown.
98
content/posts/smart-yogurt-maker-part-01/media/circuit.svg
Normal file
98
content/posts/smart-yogurt-maker-part-01/media/circuit.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 9.8 KiB |
BIN
content/posts/smart-yogurt-maker-part-01/media/log.png
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/log.png
(Stored with Git LFS)
Normal file
Binary file not shown.
0
content/posts/smart-yogurt-maker-part-01/media/src/.env
Normal file
0
content/posts/smart-yogurt-maker-part-01/media/src/.env
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG-20220125-WA0001.jpeg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG-20220125-WA0001.jpeg
(Stored with Git LFS)
Normal file
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
350414652e48b1502c92d53cae3f8a8a
|
||||
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220124_174144.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220124_174144.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
3ffd8f056e06cb258bfc412cda49c453
|
||||
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220124_180143.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220124_180143.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
73535fefabedc24d7a9628a9832edc84
|
||||
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_105918.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_105918.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
d971cb31c8c70b313ef7777c2e18f180
|
||||
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_105924.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_105924.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
c01a86e33e628effde4cb073b2d4e788
|
||||
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_113949.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_113949.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
586e44b3168e8350d97d49a524187ee1
|
||||
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_113949_cleaned.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_113949_cleaned.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
871f28fb15205ad180e9050e8d56feb1
|
||||
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_113949_cleaned.xcf
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_113949_cleaned.xcf
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_114006.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_114006.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
9f353e96551de67df144c31d8fae0edf
|
||||
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_114006_cleaned.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_114006_cleaned.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
29f2466883105eb032f60bb9fdfbf077
|
||||
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_114006_cleaned.xcf
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_114006_cleaned.xcf
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_175809.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_175809.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
9ec9803782dbd1372555907b9e596198
|
||||
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_180035.jpg
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/src/IMG_20220125_180035.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
a617dc66c55fe5979218f3fe7df43599
|
||||
BIN
content/posts/smart-yogurt-maker-part-01/media/src/calc.png
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/src/calc.png
(Stored with Git LFS)
Normal file
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
944f12a1110fa607994bb5b84e64dbbd
|
||||
BIN
content/posts/smart-yogurt-maker-part-01/media/src/log.png
(Stored with Git LFS)
Normal file
BIN
content/posts/smart-yogurt-maker-part-01/media/src/log.png
(Stored with Git LFS)
Normal file
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
ed3ce82d285ceb1c021ff0d6f01ada81
|
||||
28
layouts/shortcodes/mathjax.html
Normal file
28
layouts/shortcodes/mathjax.html
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<script type="text/javascript" async
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
|
||||
MathJax.Hub.Config({
|
||||
tex2jax: {
|
||||
inlineMath: [['$','$'], ['\\(','\\)']],
|
||||
displayMath: [['$$','$$']],
|
||||
processEscapes: true,
|
||||
processEnvironments: true,
|
||||
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre'],
|
||||
TeX: { equationNumbers: { autoNumber: "AMS" },
|
||||
extensions: ["AMSmath.js", "AMSsymbols.js"] }
|
||||
}
|
||||
});
|
||||
MathJax.Hub.Queue(function() {
|
||||
// Fix <code> tags after MathJax finishes running. This is a
|
||||
// hack to overcome a shortcoming of Markdown. Discussion at
|
||||
// https://github.com/mojombo/jekyll/issues/199
|
||||
var all = MathJax.Hub.getAllJax(), i;
|
||||
for(i = 0; i < all.length; i += 1) {
|
||||
all[i].SourceElement().parentNode.className += ' has-jax';
|
||||
}
|
||||
});
|
||||
|
||||
MathJax.Hub.Config({
|
||||
// Autonumbering by mathjax
|
||||
TeX: { equationNumbers: { autoNumber: "AMS" } }
|
||||
});
|
||||
</script>
|
||||
Loading…
Add table
Reference in a new issue