<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>chillibasket</title>
	<atom:link href="https://wired.chillibasket.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://wired.chillibasket.com</link>
	<description>A Robotics and Technology Blog</description>
	<lastBuildDate>Tue, 18 Oct 2022 19:44:31 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://wired.chillibasket.com/wp-content/uploads/2015/03/4e9d6895b4e9e70456edbdb2b46312aa1-550c5afcv1_site_icon-32x32.png</url>
	<title>chillibasket</title>
	<link>https://wired.chillibasket.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Modular Synth &#8211; Common Op. Amp Circuits</title>
		<link>https://wired.chillibasket.com/2022/06/modular-synth-common-op-amp-circuits/</link>
					<comments>https://wired.chillibasket.com/2022/06/modular-synth-common-op-amp-circuits/#respond</comments>
		
		<dc:creator><![CDATA[Simon Bluett]]></dc:creator>
		<pubDate>Sun, 26 Jun 2022 17:55:04 +0000</pubDate>
				<category><![CDATA[Modular Synth]]></category>
		<category><![CDATA[Op. Amp]]></category>
		<category><![CDATA[Operational Amplifier]]></category>
		<category><![CDATA[Synth]]></category>
		<category><![CDATA[Synthesiser]]></category>
		<guid isPermaLink="false">https://wired.chillibasket.com/?p=1514</guid>

					<description><![CDATA[Amplifiers are devices which take in an input electrical signal and increase the amplitude (voltage) of that waveform. In music systems, these signals are usually audio and amplifying them increases the volume of the signal. However, Operational Amplifiers (op. amps) are a special type of amplifier which take in two inputs rather than one, and [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Amplifiers are devices which take in an input electrical signal and increase the amplitude (voltage) of that waveform. In music systems, these signals are usually audio and amplifying them increases the volume of the signal. However, <em>Operational Amplifiers</em> (op. amps) are a special type of amplifier which take in two inputs rather than one, and amplify the difference between both signals. By using some simple circuit designs, it is possible to apply these amplifiers to perform many additional tasks, such as inverting the signal, adding up multiple signals, and isolating signals from the rest of the circuit. This wide range of applications is why operational amplifiers are so commonly used in modular synthesisers designs. In this tutorial, I briefly cover how op. amps works and discuss the most common op. amp circuits used in modular synths.</p>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-group has-very-light-gray-background-color has-background"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Tutorial Contents</h4>



<ol class="wp-block-list"><li><a href="#how-they-work">How do Operational Amplifiers Work?</a></li><li><a href="#voltage-comparator">Voltage Comparator</a></li><li><a href="#signal-buffer">Unity Gain Amplifier (Signal Buffer)</a></li><li><a href="#simple-amplifier">Simple Amplifier (Signal Boost)</a></li><li><a href="#summing-amplifier">Summing Amplifier (Signal Mixer)</a></li><li><a href="#unused-opamps">Dealing with unused Op. Amps</a></li></ol>
</div></div>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading" id="how-they-work">1. How do Operational Amplifiers Work?</h2>



<p>Operational amplifiers are a type of integrated circuit designed to amplify the difference in voltage between the two input signals. Mathematically, the output signal (V<sub>o</sub>) of an op. amp is proportional to the difference between the voltages being supplied to the positive (V<sub>+</sub>) input terminal and the negative (V<sub>&#8211;</sub>) input terminal:</p>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>V_o =A_{vo}(V_+-V_-)</pre></div>



<p>The open loop gain (A<sub>vo</sub>) refers to the amount of amplification applied to the difference between the two inputs. One characteristic that makes op. amps so useful is that the open loop gain/amplification value is very large (often around x100,000); this allows the output voltage to be regulated down to any desired value using some simple external components. The table below lists the main characteristics of operational amplifiers, and compares the ideal versus the actual characteristics seen in practice:</p>



<figure class="wp-block-table"><table><thead><tr><th>Ideal</th><th>Actual</th></tr></thead><tbody><tr><td>The amplifier has an infinitely large open loop gain</td><td>The gain is large but finite (typically 100&#8217;s dB)</td></tr><tr><td>The input impedance is infinitely large (no current flows through the inputs)</td><td>The input impedance is high but finite (typically 100&#8217;s MΩ); a small current flows into the inputs</td></tr><tr><td>There is zero output impedance</td><td>The output impedance is low, but not zero (typically 10&#8217;s Ω)</td></tr><tr><td>The gain is not dependent on the frequency of the input signals</td><td>The signal bandwidth is not infinite and at higher frequencies the gain tends to reduce</td></tr><tr><td>The amplifier can switch the output voltage instantaneously to changes in the inputs</td><td>The speed at which the output voltage can change is limited and is defined by the &#8220;slew rate&#8221;</td></tr><tr><td>The output voltage can increase up to the voltages supplied to the power rails of the amplifier</td><td>There is a voltage drop introduced, meaning the output cannot increase up to the rails (usually 2-3 V drop)</td></tr></tbody></table></figure>



<p>In practice, while op. amps don&#8217;t exactly follow the ideal assumptions, they are close enough so that these mathematical simplifications can usually be used when designing modular synthesiser circuits and figuring out suitable component values. Some of the situations when you need to watch out for non-ideal properties of op. amps are:</p>



<ul class="wp-block-list"><li>The resistance of the input signals is very high</li><li>The output load from the circuit is very low</li><li>High frequency operation is required</li><li>The output voltage needs to be able to swing right up to the supply voltages </li></ul>



<p>In applications such as these, there are many specialised types of operational amplifiers which can fulfil these needs (but often are more expensive or make a compromise with other properties of the amplifier).</p>



<div class="wp-block-group has-very-light-gray-background-color has-background"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Operational Amplifiers: Further Reading</h4>



<ul class="wp-block-list"><li><em>Great video explaining how op. amps work:</em> <a rel="noreferrer noopener" href="https://www.youtube.com/watch?v=7FYHt5XviKc" target="_blank">EEV Blog &#8211; OpAmps Tutorial</a></li></ul>
</div></div>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading" id="voltage-comparator">2. Voltage Comparator (Threshold Detection)</h2>



<p>A comparator is a type of circuit which compares the voltages of two inputs, outputting a high voltage value when input 1 is larger than input 2, and a low value when input 1 is smaller than input 2. If the voltage of the second input remains fixed, a comparator circuit can be used to determine if the first input signal has exceeded the voltage threshold of the second signal.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="underline-heading wp-block-heading">(a) Simple Comparator</h3>



<p>An op. amp can be used as a simple comparator circuit by connecting the two signals you want to compare to the inverting (V<sub>2</sub>) and non-inverting (V<sub>1</sub>) input terminals. If the voltage at the non-inverting input is greater than the one at the inverting input, then the output voltage will be positive; otherwise the output will be negative.</p>



<p>Due to the high gain of the amplifier, the output will saturate almost immediately to the maximum voltage which the op. amp can supply &#8212; this is dictated by the supply voltage rails. As a result, the output appears to be almost digital, switching between a fixed low and high voltage value.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<h4 class="wp-block-heading">Mathematical <strong>Derivation</strong></h4>



<ul class="wp-block-list"><li>Starting with the op. amp formula:</li></ul>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>V_{out} = A_{vo}(V_1 - V_2)</pre></div>



<ul class="wp-block-list"><li>If the gain is very large (approaching infinity), this means the output should also approach positive or negative infinity; however, the maximum output voltage is limited by the supply voltages connected to the amplifier:</li></ul>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\textbf{If: } \; A_{vo} \to \infin \quad \textbf{ Then:}</pre></div>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>V_{out}=\begin{cases}
V_{s+} -V_{d} &amp; V_1 &gt; V_2 \\
V_{s-} +V_{d} &amp; V_1 &lt; V_2  \\
\text{Unstable} &amp; V_1 = V_2
\end{cases}</pre></div>



<p>Depending on whether the difference between the two input terminals is positive or negative, the output will jump to equal the positive or negative supply rails. When both inputs are equal, the output is unstable and can quickly jump between both rails. Note that the voltage of the output is reduced by the term <strong>V<sub>d</sub></strong> since most op. amps (unless advertised) introduce a voltage drop of up to 2 to 3 volts with respect to the rails. </p>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<h4 class="wp-block-heading"><strong>Circuit Diagram</strong></h4>


<div class="wp-block-image">
<figure class="aligncenter size-large"><a href="https://wired.chillibasket.com/wp-content/uploads/2021/07/differential_amplifier.jpg"><img fetchpriority="high" decoding="async" width="501" height="361" src="https://wired.chillibasket.com/wp-content/uploads/2021/07/differential_amplifier.jpg" alt="" class="wp-image-2054" srcset="https://wired.chillibasket.com/wp-content/uploads/2021/07/differential_amplifier.jpg 501w, https://wired.chillibasket.com/wp-content/uploads/2021/07/differential_amplifier-300x216.jpg 300w" sizes="(max-width: 501px) 100vw, 501px" /></a><figcaption><strong>Schematic 1:</strong> <em>Open-loop differential op. amp used as a voltage comparator.</em></figcaption></figure>
</div>


<p></p>
</div>
</div>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="underline-heading wp-block-heading">(b) Inverting Comparator with Hysteresis</h3>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>In the above simple comparator circuit, when both input voltages are equal the output voltage can jump rapidly between both input rails. This can be an issue when the input signal itself is noisy; in that case the output jumps back and forth multiple times as the input voltage approaches the reference voltage instead of just giving a single clean transition. The most common method of dealing with this issue is to use positive feedback to offset the reference voltage after a transition has occurred. As a result, the reference voltage as the signal is increasing is different than that when the signal is decreasing (this is known as <strong>hysteresis</strong>). </p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<h4 class="wp-block-heading">Mathematical Formula</h4>



<p>The voltage at the non-inverting terminal changes depending on whether the output voltage is currently at the high or the low voltage level. This means that the voltage threshold changes depending on whether the input signal is rising or falling.</p>



<p>For rising input voltages we can calculate the voltage at the non-inverting input (the threshold voltage) using superposition:</p>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>V_{+rising} = \frac{V_{ref}(R_1)}{(R_1+R_2)}+\frac{V_{outLOW}(R_2)}{(R_1+R_2)}</pre></div>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\therefore V_{+rising} = \frac{(V_{ref}R_1+V_{outLOW}R_2)}{R_1+R_2}</pre></div>



<p>Similarly, for falling input voltages the threshold can be calculated:</p>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\therefore V_{+falling} = \frac{(V_{ref}R_1+V_{outHIGH}R_2)}{R_1+R_2}</pre></div>



<p>So the total hysteresis voltage swing can be calculated by subtracting these two thresholds:</p>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>V_{hysteresis} = V_{-rising}-V_{+falling}</pre></div>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\therefore V_{hysteresis} = (V_{outHIGH}-V_{outLOW})\frac{R_2}{R_1+R_2}</pre></div>



<p></p>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<h4 class="wp-block-heading"><strong>Circuit Diagram</strong></h4>


<div class="wp-block-image">
<figure class="aligncenter size-large"><a href="https://wired.chillibasket.com/wp-content/uploads/2021/07/comparator-with-hysteresis.jpg"><img decoding="async" width="570" height="294" src="https://wired.chillibasket.com/wp-content/uploads/2021/07/comparator-with-hysteresis.jpg" alt="" class="wp-image-2055" srcset="https://wired.chillibasket.com/wp-content/uploads/2021/07/comparator-with-hysteresis.jpg 570w, https://wired.chillibasket.com/wp-content/uploads/2021/07/comparator-with-hysteresis-300x155.jpg 300w" sizes="(max-width: 570px) 100vw, 570px" /></a><figcaption><strong>Schematic 2:</strong> <em>Inverting op. amp comparator circuit with hysteresis</em></figcaption></figure>
</div>


<p>In this circuit configuration, the output voltage is high if the input voltage is below the lower &#8220;falling&#8221; threshold, and it switches to a low output voltage when the input voltage exceeds the upper &#8220;rising&#8221; threshold. When the input voltage is in-between those two thresholds, it stays at whatever level it was at before:</p>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>V_{out}=\begin{cases}
V_{s+} -V_{d} &amp; V_{in} &lt; V_{+falling} \\
V_{s-} +V_{d} &amp; V_{in} &gt; V_{+rising} \\
\text{Unchanged} &amp; V_{+rising} \le V_{in} \le V_{+falling}
\end{cases}</pre></div>
</div>
</div>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading" id="signal-buffer">3. Unity Gain Amplifier (Signal Buffer)</h2>



<p>In a <em>unity gain amplifier</em> (also known as a <em>signal buffer</em> or a <em>voltage follower</em>), the output of the op. amp is connected back into the inverting input terminal. Using this feedback, the amplifier actively tries to reduce the difference between the input and output voltages, making them the same. This circuit is very common, as it can be used to electrically isolate (buffer) two parts of a circuit. The output of the op. amp acts as an ideal voltage source, meaning the load connected to the output won&#8217;t affect the signal at the input of the op. amp and vice versa.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<h4 class="wp-block-heading">Mathematical <strong>Derivation</strong></h4>



<ul class="wp-block-list"><li>Starting with the op. amp formula:</li></ul>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>V_{out}=A_{vo}(V_{in}-V_{out})</pre></div>



<ul class="wp-block-list"><li>Rearranging:</li></ul>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>(A_{vo}+1)V_{out}=A_{vo}V_{in}</pre></div>



<ul class="wp-block-list"><li>Due to the large open-loop gain of the amplifier (which is much larger than one), the left side of the equation can be simplified to remove the &#8220;+ 1&#8221; term.</li></ul>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\textbf{If: } \; A_{vo} \gg 1  \quad \textbf{ Then: } \; A_{vo}+1 \approx A_{vo}</pre></div>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\therefore \; V_{out} = V_{in}</pre></div>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<h4 class="wp-block-heading"><strong>Circuit Diagram</strong></h4>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img decoding="async" width="465" height="287" src="https://wired.chillibasket.com/wp-content/uploads/2020/06/unity_gain_amplifier.jpg" alt="" class="wp-image-1589" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/06/unity_gain_amplifier.jpg 465w, https://wired.chillibasket.com/wp-content/uploads/2020/06/unity_gain_amplifier-300x185.jpg 300w" sizes="(max-width: 465px) 100vw, 465px" /><figcaption><strong>Schematic 2:</strong> <em>A unity gain amplifier, often known as a &#8220;voltage buffer&#8221;.</em></figcaption></figure>
</div></div>
</div>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading" id="simple-amplifier">4. Simple Amplifier (Signal Boost)</h2>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="underline-heading wp-block-heading">(a) Inverting Amplifier</h3>



<p>An amplifier circuit is a system which takes an input signal and increases the magnitude (amplitude) of that signal. For example in modular synthesisers, this would increase the volume of the audio waveform. An inverting amplifier configuration applies this increase and inverts the signal, meaning that the positive sections of the signal become negative and the negative sections become positive.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<h4 class="wp-block-heading">Mathematical <strong>Derivation</strong></h4>



<ul class="wp-block-list"><li>To start off, we will substitute in zero for the non-inverting input terminal which is connected to ground:</li></ul>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>V_{out}=A_{vo}(V_+-V_-)</pre></div>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\textbf{Since: } \; V_+=0 \quad \Rightarrow \; V_{out} =  A_{vo}(-V_-)</pre></div>



<ul class="wp-block-list"><li>Due to the high open-loop gain, the amplifier changes its output to try to keep the voltages of the inverting and non-inverting input terminals the same. This creates a &#8220;virtual ground&#8221; at the negative input.</li></ul>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\textbf{If: } \; A_{vo} \to \infin \quad \textbf{ Then: } \; V_- \to 0</pre></div>



<ul class="wp-block-list"><li>Using superposition we can derive another formula for the voltage at the inverting input (see explanation in box below):</li></ul>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>V_-=  \frac{V_{in}R_2}{R_1+R_2}+\frac{V_{out}R_1}{R_1+R_2} = 0</pre></div>



<ul class="wp-block-list"><li>This can be rearranged and simplified to give us the relationship between the input and output voltages:</li></ul>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>V_{in}R_2+V_{out}R_1 = 0</pre></div>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\therefore \: V_{out}=-V_{in}\frac{R_2}{R_1}</pre></div>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<h4 class="wp-block-heading"><strong>Circuit Diagram</strong></h4>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="587" height="326" src="https://wired.chillibasket.com/wp-content/uploads/2020/06/inverting_amplifier.jpg" alt="" class="wp-image-1583" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/06/inverting_amplifier.jpg 587w, https://wired.chillibasket.com/wp-content/uploads/2020/06/inverting_amplifier-300x167.jpg 300w" sizes="auto, (max-width: 587px) 100vw, 587px" /><figcaption><strong>Schematic 3: </strong><em>Inverting amplifier used to increase the magnitude of the input signal.</em></figcaption></figure>
</div></div>
</div>



<div class="wp-block-group has-background" style="background-color:#f0f0f0"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<h4 class="wp-block-heading">Superposition</h4>



<p>When trying to calculate the voltage at a junction between multiple branches of a circuit, a useful trick is to look at the voltage contribution of each branch of the circuit separately before adding all the contributions together. When calculating each branch, all of the voltages at the other branches are set to zero. This process is known as &#8220;superposition&#8221; and is used extensively in circuit analysis.</p>
</div></div>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="underline-heading wp-block-heading">(b) Non-inverting Amplifier</h3>



<p>The non-inverting amplifier configuration is almost identical to the inverting amplifier above, except that the ground and input voltages are swapped. By adjusting the ratios of the two feedback resistors R<sub>1</sub> and R<sub>2</sub> the amount of gain/amplification of the circuit can be controlled.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<h4 class="wp-block-heading">Mathematical <strong>Derivation</strong></h4>



<ul class="wp-block-list"><li>If the open loop gain is infinitely large, then the voltages at the inverting and non-inverting inputs needs to be equal:</li></ul>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>V_{out}=A_{vo}(V_{in}-V_-)</pre></div>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\textbf{If: } \; A_{vo} \to \infin \quad \textbf{ Then: } \; V_{in} - V_- \to 0</pre></div>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\therefore V_{in} = V_-</pre></div>



<ul class="wp-block-list"><li>Using the formula for a potential divider, the voltage at the inverting input terminal can be related to the output voltage:</li></ul>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>V_- = \frac{V_{out}R_2}{R_1+R_2}</pre></div>



<ul class="wp-block-list"><li>Rearranging to isolate the output voltage:</li></ul>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\therefore V_{out}=V_{in}\left( \frac{R_1}{R_2} + 1 \right)</pre></div>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<h4 class="wp-block-heading"><strong>Circuit Diagram</strong></h4>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="570" height="294" src="https://wired.chillibasket.com/wp-content/uploads/2020/06/non-inverting_amplifier.jpg" alt="" class="wp-image-1585" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/06/non-inverting_amplifier.jpg 570w, https://wired.chillibasket.com/wp-content/uploads/2020/06/non-inverting_amplifier-300x155.jpg 300w" sizes="auto, (max-width: 570px) 100vw, 570px" /><figcaption><strong>Schematic 4:</strong> <em>Non-inverting amplifier used to increase the magnitude of the input signal.</em></figcaption></figure>
</div></div>
</div>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading" id="summing-amplifier">5. Summing Amplifier (Signal Mixer)</h2>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="underline-heading wp-block-heading">(a) Inverting Summing Amplifier</h3>



<p>In modular synths you often want to add multiple signals together to create a variety of effects and harmonies. This can be done very simply by adding additional inputs to the normal inverting amplifier I described in Section 3(a). The contribution of each input signal to the output is dependent on the ratio of the input and feedback resistors.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<h4 class="wp-block-heading">Mathematical <strong>Derivation</strong></h4>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>V_{out}=A_{vo}(V_+-V_-) = A_{vo}(-V_-)</pre></div>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\textbf{If: } \; A_{vo} \to \infin \quad \textbf{ Then: } \; V_- = 0</pre></div>



<ul class="wp-block-list"><li>Since almost no current flows into the inverting op. amp input, the sum of all the current coming into the inputs needs to flow through the feedback resistor (R). Note that as the conventional current flows from the 0V point at the inverting input across the feedback resistor, this can only be true if the output is at a lower voltage (meaning it is negative).</li></ul>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>I_R=\sum_{i=1}^N\frac{V_i}{R_i} \quad  \textbf{ and } \quad V_{out}=-I_RR</pre></div>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>V_{out}=-\left(V_1\frac{R}{R_1}+V_2\frac{R}{R_2}+...+V_N\frac{R}{R_N}\right)</pre></div>



<ul class="wp-block-list"><li>If all the resistors are equal, then all the resistor terms in the equation cancel each other out and the op. amp simply sums all the input voltages together and inverts it:</li></ul>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\textbf{If: } \; \{R_i = R \text{ }| \text{ } i = 1,...,N\}</pre></div>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\therefore V_{out} = -(V_1 + V_2 + ... + V_N)</pre></div>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<h4 class="wp-block-heading"><strong>Circuit Diagram</strong></h4>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="634" height="484" src="https://wired.chillibasket.com/wp-content/uploads/2020/06/inverting_mixer.jpg" alt="" class="wp-image-1584" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/06/inverting_mixer.jpg 634w, https://wired.chillibasket.com/wp-content/uploads/2020/06/inverting_mixer-300x229.jpg 300w" sizes="auto, (max-width: 634px) 100vw, 634px" /><figcaption><strong>Schematic 5:</strong> <em>Inverting signal mixer, used to combine multiple analogue signals.</em></figcaption></figure>
</div></div>
</div>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="underline-heading wp-block-heading">(b) Non-inverting Summing Amplifier</h3>



<p>It is also possible to create a non-inverting signal mixer, where the output is the positive sum of the inputs. However, this circuit is not as common in synthesisers since it is not as easy to add additional inputs. If more than two inputs are added, the ratio of the two resistors connected to the inverting input of the op. amp needs to be changed to ensure the output gain factor remains the same.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<h4 class="wp-block-heading">Mathematical <strong>Derivation</strong></h4>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>V_{out}=A_{vo}(V_+-V_-)</pre></div>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\textbf{If: } \; A_{vo} \to \infin \quad \textbf{ Then: } \; V_+ = V_-</pre></div>



<ul class="wp-block-list"><li>Same as the non-inverting amplifier circuit (4b), the voltage of the inverting input can be calculated using the potential divider formula. </li></ul>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>V_-=\frac{V_{out}R}{R+R}=\frac{V_{out}}{2}</pre></div>



<ul class="wp-block-list"><li>The voltage at the non-inverting input can be calculated using superposition: </li></ul>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>V_+=\frac{V_1R}{R+R}+\frac{V_2R}{R+R}=\frac{V_1+V_2}{2}</pre></div>



<ul class="wp-block-list"><li>Since the voltage at the inverting and non-inverting inputs needs to be equal, the output voltage therefore is the sum of the two inputs:</li></ul>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\therefore V_{out}=V_1+V_2</pre></div>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<h4 class="wp-block-heading"><strong>Circuit Diagram</strong></h4>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="635" height="363" src="https://wired.chillibasket.com/wp-content/uploads/2020/06/non-inverting_mixer.jpg" alt="" class="wp-image-1586" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/06/non-inverting_mixer.jpg 635w, https://wired.chillibasket.com/wp-content/uploads/2020/06/non-inverting_mixer-300x171.jpg 300w" sizes="auto, (max-width: 635px) 100vw, 635px" /><figcaption><strong>Schematic 6:</strong> <em>Non-inverting signal mixer, used to combine two analogue signals.</em></figcaption></figure>
</div></div>
</div>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading" id="unused-opamps">6. Dealing with Unused Op. Amps</h2>



<p>When working with operational amplifiers on a breadboard or in a circuit, each IC chip usually contains multiple op. amps. Commonly chips contains either 2 or 4 amplifiers; however, your circuit may not need to use all of these amplifiers meaning that one or two of them will remain disconnected. In this situation it is good practice to connect the pins of the unused amplifiers to a known input and output so that they won&#8217;t be changing randomly. If these pins are left floating, the unused op. amps may introduce noise and interference which negatively impacts the performance of the op. amps that are being used. To prevent this, the amplifiers should be wired up in a &#8220;Unity Gain&#8221; configuration (see Section 3), with the non-inverting input connected to a voltage which is halfway between the positive and negative rails:</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-vertically-aligned-bottom is-layout-flow wp-block-column-is-layout-flow"><div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" src="https://wired.chillibasket.com/wp-content/uploads/2020/06/unconnected_amplifier_1.jpg" alt="" class="wp-image-1587" width="289" height="399" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/06/unconnected_amplifier_1.jpg 385w, https://wired.chillibasket.com/wp-content/uploads/2020/06/unconnected_amplifier_1-217x300.jpg 217w" sizes="auto, (max-width: 289px) 100vw, 289px" /><figcaption><strong>Schematic 8:</strong> <em>This circuit keeps an unused op. amp within a stable configuration.</em></figcaption></figure>
</div></div>



<div class="wp-block-column is-vertically-aligned-bottom is-layout-flow wp-block-column-is-layout-flow"><div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" src="https://wired.chillibasket.com/wp-content/uploads/2020/06/unconnected_amplifier_2.jpg" alt="" class="wp-image-1588" width="304" height="248" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/06/unconnected_amplifier_2.jpg 405w, https://wired.chillibasket.com/wp-content/uploads/2020/06/unconnected_amplifier_2-300x245.jpg 300w" sizes="auto, (max-width: 304px) 100vw, 304px" /><figcaption><strong>Schematic 9:</strong><em> If the V+ and V- voltage inputs to the op. amp are equal and opposite (eg. +12V and -12V), then the non-inverting input can be connected to ground.</em></figcaption></figure>
</div></div>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://wired.chillibasket.com/2022/06/modular-synth-common-op-amp-circuits/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Modular Synth &#8211; Dual 12V Power Supply</title>
		<link>https://wired.chillibasket.com/2020/06/dual-power-supply/</link>
					<comments>https://wired.chillibasket.com/2020/06/dual-power-supply/#comments</comments>
		
		<dc:creator><![CDATA[Simon Bluett]]></dc:creator>
		<pubDate>Sun, 14 Jun 2020 18:23:06 +0000</pubDate>
				<category><![CDATA[Modular Synth]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Modular]]></category>
		<category><![CDATA[Power Supply]]></category>
		<category><![CDATA[Synth]]></category>
		<category><![CDATA[Synthesiser]]></category>
		<guid isPermaLink="false">https://wired.chillibasket.com/?p=1125</guid>

					<description><![CDATA[The very first thing which needs to be addressed when building a DIY synthesiser is how will it all be powered? Traditionally, synthesisers require both positive and negative voltages, which makes putting together a suitable power supply slightly trickier than it may at first seem. By convention, audio signals generated by an oscillator should have [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>The very first thing which needs to be addressed when building a DIY synthesiser is how will it all be powered? Traditionally, synthesisers require both positive and negative voltages, which makes putting together a suitable power supply slightly trickier than it may at first seem. By convention, audio signals generated by an oscillator should have an amplitude of around 10V centred on ground (-5V at the lowest point, +5V at the highest). Therefore, the power supply needs to deliver voltages that are above ±5V. The most common supply voltages are ±9V (for battery operated systems), ±12V (for Eurorack modules) and ±15V. In this tutorial, I&#8217;ll discuss the three most common circuit designs used to provide power for modular synthesisers.</p>



<div class="wp-block-group has-very-light-gray-background-color has-background"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Tutorial Contents</h4>



<ol class="wp-block-list"><li><a href="#series-battery">Series Battery Method</a></li><li><a href="#dual-rectification">Dual AC to DC Rectification</a><ul><li><a href="#half-wave-rectifier">Half-wave Rectifier Circuit</a></li><li><a href="#full-wave-rectifier">Full-wave Rectifier Circuit</a></li></ul></li><li><a href="#charge-pump">DC to DC Inverting Charge Pump</a></li></ol>
</div></div>



<div class="wp-block-group has-background" style="background-color:#ffe8e1"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>Note: </strong>Some of the circuits described in this post use mains power, and can be dangerous if built incorrectly. Since all other circuits in the synthesiser depend on a stable source of power, making a mistake in the power supply can cause a variety of issues to any connected modules. If you don&#8217;t have the experience or equipment to build your own power supply from scratch, I would encourage you to get a pre-assembled one or a circuit board kit instead!</p>
</div></div>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="763" src="https://wired.chillibasket.com/wp-content/uploads/2020/06/oscillator_test_circuit-1024x763.jpg" alt="" class="wp-image-1561" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/06/oscillator_test_circuit-1024x763.jpg 1024w, https://wired.chillibasket.com/wp-content/uploads/2020/06/oscillator_test_circuit-300x224.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2020/06/oscillator_test_circuit-768x573.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2020/06/oscillator_test_circuit.jpg 1100w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption><em>Image showing my DIY dual power supply used to power a basic oscillator module.</em></figcaption></figure>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading" id="series-battery">1. Series Battery Method</h2>



<p>One of the simplest ways to create a dual power supply is by using two sets of batteries. The batteries are connected in series, so that the positive terminal of one battery is attached to the negative terminal of the second battery. When this middle connection is used as the ground reference for the circuit, you will be able to get a positive and negative voltage from the batteries, as shown in the circuit diagram below. For small and portable synthesisers, this is often done using two 9V batteries as I&#8217;ve demonstrated on a breadboard in the image below. Since the voltage of both batteries will drop as the power is drained, we also need to include voltage regulators which ensure a stable voltage is supplied to the synthesiser. In the image below, you can see that the batteries I am using are almost empty as the voltage measured by my multimeter is only -7.11V. </p>



<p>This method only works when one or both voltage sources are said to be &#8220;floating&#8221;. This means that the power source is not connected to any absolute reference voltage, such as a connection to Earth. All batteries are floating power sources, however wired power supplies often aren&#8217;t. For example, if the negative terminal of both voltage sources is connected to ground, <span style="text-decoration: underline;"></span>then attaching the positive and negative terminals of both sources together will simply create a short-circuit; this is something I would encourage you to avoid!</p>



<ul class="wp-block-list"><li>Benefits:<ul><li>Very easy to implement and troubleshoot.</li><li>Relatively Portable.</li><li>Voltage can be increased by adding more batteries in series.</li><li>The battery life and maximum output current can be increased by adding more batteries in parallel.</li></ul></li><li>Disadvantages:<ul><li>Batteries constantly need to be replaced!</li><li>The voltage of the batteries will drop as they run out (as seen in the image), so an additional power regulator IC will still be required.</li></ul></li></ul>



<div class="wp-block-dgwt-justified-gallery">
<a href='https://wired.chillibasket.com/2020/06/dual-power-supply/dual-battery-supply/'><img loading="lazy" decoding="async" width="300" height="186" src="https://wired.chillibasket.com/wp-content/uploads/2020/04/dual-battery-supply-300x186.png" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/04/dual-battery-supply-300x186.png 300w, https://wired.chillibasket.com/wp-content/uploads/2020/04/dual-battery-supply.png 486w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>
<a href='https://wired.chillibasket.com/2020/06/dual-power-supply/dual-battery-test/'><img loading="lazy" decoding="async" width="300" height="175" src="https://wired.chillibasket.com/wp-content/uploads/2020/04/dual-battery-test-300x175.jpg" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/04/dual-battery-test-300x175.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2020/04/dual-battery-test-768x448.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2020/04/dual-battery-test.jpg 1000w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>
</div>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading" id="dual-rectification">2. Dual AC to DC Rectification</h2>



<p>The electricity being supplied in the mains socket alternates from a positive to a negative voltage many times a second (230V 50Hz in Europe, 120V 60Hz in the US). What we want to do is reduce this voltage down to a lower and more manageable voltage, taking the positive half of the AC signal to supply the positive output and the negative half for the negative output. This process requires the following steps:</p>



<ul class="wp-block-list"><li>Step down the high voltage being supplied by the mains to a lower voltage using a transformer.</li><li>Rectify the AC signal into a positive and negative signal using diodes.</li><li>Smooth out the voltage using capacitors.</li><li>Generate a stable output voltage using power regulators.</li></ul>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="underline-heading wp-block-heading" id="half-wave-rectifier">a. Half-wave Rectifier Circuit</h3>



<p>This is the power supply design I used in my synthesiser, and it is probably the most common design used by DIY synth builders. This design is often preferred to the <em>Full-wave Rectifier</em> as you can use a commercial wall plug transformer to convert the mains power down to 12V AC, which is used by the power supply. This means that your circuit does not directly come into contact with the mains power, making it a little bit safer to work with (but you still need to be careful!). </p>



<p><strong><span style="text-decoration: underline;">Important:</span> </strong>You need to make sure that the wall plug transformer you use outputs 12V <strong><em>alternating current</em></strong>, and not 12V direct current. The 12V DC plugs are a lot more common, so it may take some searching to find the correct type of 12V AC plug. Also make sure that the plug you get is rated for a current of at least 1000mA or above, and that the mains voltage input rating is correct for the country you are in.</p>



<p>An example of a half-wave rectifier circuit is shown in <strong><em>Schematic 2</em></strong> below. The circuit takes in a 12V AC signal from the wall plug, and converts it into a stable positive and negative 12V output. I have seen many variations of this circuit, using a wide variety of different capacitor values. </p>



<div class="wp-block-image"><figure class="aligncenter size-large"><a href="https://wired.chillibasket.com/wp-content/uploads/2020/06/half-wave-rectification.jpg"><img loading="lazy" decoding="async" width="1000" height="572" src="https://wired.chillibasket.com/wp-content/uploads/2020/06/half-wave-rectification.jpg" alt="" class="wp-image-1473" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/06/half-wave-rectification.jpg 1000w, https://wired.chillibasket.com/wp-content/uploads/2020/06/half-wave-rectification-300x172.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2020/06/half-wave-rectification-768x439.jpg 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></a><figcaption><strong>Schematic 2:</strong> <em>Half-wave Rectification Circuit</em></figcaption></figure></div>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">How does it work?</h4>



<ol class="wp-block-list"><li>The circuit takes in a 12V alternating current signal from the wall plug transformer. 12V AC refers to the root mean square (RMS) value of the signal. This signal has a peak voltage of <em>±</em>17V, as shown in the waveform diagram below.</li><li>The diode <strong>D1</strong> only allows the positive half of the AC signal to pass through, while <strong>D2</strong> lets negative voltages through. This process is known as <em>half-wave</em> or <em>half-bridge</em> rectification, since only half of the AC waveform is used to power each of the voltage outputs. As a result, each output can theoretically only output half of the power (and consequently current) delivered by the wall plug transformer. The peak voltage of the rectified signals is <em>±</em>16.3V, since the diodes introduce a 0.7V drop into the circuit.</li><li>The capacitors smooth out the waveform, ensuring that a more continuous voltage is being supplied to the voltage regulators. The reasoning behind selecting this specific capacitance value is discussed in the next section.</li><li>The LM7812 and LM7912 voltage regulators ensure that the outputs of the power supply stay at a stable +12V and -12V respectively. If you want to get +15V and -15V outputs instead, you can use a 15V AC power plug and replace these with the LM7815 and LM7915 regulators. If you are putting together your own circuit, watch out as the input, output and ground pins are in a different order on the positive and negative voltage regulators.</li><li>Capacitors <strong>C3</strong> and <strong>C4</strong> are mainly included to improve the transient response of the power supply; the capacitor can provide brief bursts of high current when there are sudden changes in load being applied to the power supply. According to the data-sheet for the negative voltage regulator LM7912, for stability the capacitor <strong>C4</strong> should be at least 1μF (using a tantalum capacitor) or 10μF (using an electrolytic capacitor). The higher value of 100μF was chosen to give an additional factor of safety over this minimum value.</li><li>The two LEDs are there to indicate that there is power at the outputs. Some negative power regulators also require a minimum load to be applied at the output before they start up, so the LEDs help to provide that load.</li><li>According to the data-sheet for LM7912, the diode <strong>D4</strong> is required when large capacitors such as <strong>C10</strong> are used at the input. The diode prevents momentary input short circuits, which can occur when the circuit is powered up or down. The LM7812 does not necessarily need this, but I put <strong>D6</strong> in for good measure.</li><li>The data sheet for both LM7812 and LM7912 specify that <strong>D5</strong> and <strong>D3</strong> should be present to prevent <em>latch-up</em> problems. These components act as clamping diodes, helping to protect the regulators from reversed polarity on the outputs. If one regulator starts up before the other one, devices such as operational amplifiers (op amps) can latch up and cause a short circuit between both power rails. This can prevent the second regulator from starting up. The diodes (preferably Schottkey) prevent the positive output from going below -0.3V and the negative output going above 0.3V, allowing both regulators to start up and the latch up condition to stop.</li></ol>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-large"><a href="https://wired.chillibasket.com/wp-content/uploads/2020/06/half-wave-diagram.png"><img loading="lazy" decoding="async" width="1000" height="288" src="https://wired.chillibasket.com/wp-content/uploads/2020/06/half-wave-diagram.png" alt="" class="wp-image-1504" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/06/half-wave-diagram.png 1000w, https://wired.chillibasket.com/wp-content/uploads/2020/06/half-wave-diagram-300x86.png 300w, https://wired.chillibasket.com/wp-content/uploads/2020/06/half-wave-diagram-768x221.png 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></a><figcaption><em>Diagram showing the main steps of the half-wave rectification process</em></figcaption></figure>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">How to choose the capacitor values?</h4>



<p>Why are there two capacitors at the input of each power rail (C1 &amp; C7, C2 &amp; C10)? How were the values of these capacitors chosen? I&#8217;ve looked at several schematics for half-wave rectifiers and there seems to be a lot of variance in what the capacitance value should be.</p>



<p>Generally there is one small non-electrolytic capacitor close to the input of each power regulator, which helps to stabilise, filter and smooth the input (C1 and C2). Usually this is between 100nF to 1μF. Small capacitors (ceramic, polyester, tantalum etc.) tend to be better than larger electrolytic film capacitor at filtering out high-frequency noise from the signal.</p>



<p>Then there is a bank of large electrolytic capacitors connected in parallel (C7 and C10; more capacitors can be connected if required), ensuring that there is a relatively constant reservoir of power even when the AC input signal is in the opposite half of the wave and no new power is being supplied. These capacitors are good at removing low frequency noise and stabilising variances in the DC voltage. The total capacitance of this reservoir depends on the amount of load you expect to put on the power supply. Here is how to calculate how much capacitance you may need:</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<p>According to the datasheet, the 12V regulators need a minimum input voltage of 14.5V to be able to provide a stable 12V output. Since 16.3V is the maximum voltage provided by our transformer and rectification circuit, under full load we are aiming for an average DC input voltage (V<sub>DC</sub>) of 15.4V and maximum voltage ripple (p<sub>%</sub>) of 5.8%.</p>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>V_{DC}=\frac{16.3+14.5}{2}=15.4V</pre></div>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\rho_\%=\frac{15.4-14.5}{15.4}\times100=5.8\%</pre></div>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<p>Next we need to calculate the effective resistance of the load. Since the regulator can output a maximum current (I<sub>DC</sub>) of around 1A, this means that the equivalent load resistance (R<sub>L</sub>) is 15.4 ohms. The power dissipated (P<sub>D</sub>) across the regulator (in the form of heat) is 3.4W. The regulator can only dissipate ~1W on its own, so we definitely need to attach a heatsink to it to remove the excess heat.</p>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>R_L=\frac{V_{DC}}{I_{DC}}=\frac{15.4}{1}=15.4\Omega</pre></div>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>P_D = (V_{DC}-V_O )(I_{DC})\newline=(15.4-12)(1)=3.4W</pre></div>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<p>We can then calculate a minimum capacitance value (C<sub>s</sub>) which can provide the desired voltage ripple. <em>The formula I am using assumes that the capacitor discharge is approximately linear and that the AC frequency is 50Hz.</em> The value turns out to be around 11,000µF! We theoretically would need to connect 3 of the large 4700µF capacitors together in parallel so that the power regulator could reach its maximum output current of 1A. With only one 4700µF capacitor the maximum output current is probably around 0.4A per rail.</p>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>C_s=\frac{1}{\rho _\%R_L}=\frac{1}{5.8\times 15.4}=0.011F</pre></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>\text{If } \quad C_s=0.0047F \quad \text{then:}</pre></div>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>R_L=\frac{1}{5.8\times 0.0047}=36.7\Omega</pre></div>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>I_{DC}=\frac{15.4}{36.7}=0.42A</pre></div>



<p></p>
</div>
</div>



<p>So to summarise&#8230; if we want to get a full 1A of output current from our power supply, the combined capacitance value at the input of the regulator needs to be at least 11,000µF.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-group has-very-light-gray-background-color has-background"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Half-bridge Rectifier: Further Reading</h4>



<ul class="wp-block-list"><li><em>Music from Outer Space:</em> <a rel="noreferrer noopener" href="http://musicfromouterspace.com/analogsynth_new/WALLWARTSUPPLY/WALLWARTSUPPLY.php" target="_blank">Wall-wart Power Supply</a></li><li><em>Circuits Today:</em> <a rel="noreferrer noopener" href="http://www.circuitstoday.com/half-wave-rectifiers" target="_blank">Half-wave Rectifier Circuit Theory</a></li></ul>
</div></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-large"><a href="https://wired.chillibasket.com/wp-content/uploads/2020/04/bread-board_power-supply_2.jpg"><img loading="lazy" decoding="async" width="910" height="568" src="https://wired.chillibasket.com/wp-content/uploads/2020/04/bread-board_power-supply_2.jpg" alt="" class="wp-image-1161" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/04/bread-board_power-supply_2.jpg 910w, https://wired.chillibasket.com/wp-content/uploads/2020/04/bread-board_power-supply_2-300x187.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2020/04/bread-board_power-supply_2-768x479.jpg 768w" sizes="auto, (max-width: 910px) 100vw, 910px" /></a><figcaption><em>Testing the half-bridge rectifier out on a breadboard.</em></figcaption></figure>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="underline-heading wp-block-heading" id="full-wave-rectifier">b. Full-wave Rectifier Circuit</h3>



<p>In a &#8220;full-bridge&#8221; or &#8220;full-wave&#8221; rectification circuit, both the positive and negative sections of the alternating waveform are used to power both outputs. This means that the circuit can theoretically drive twice the load compared to a half-bridge rectifier. As can be seen in <em><strong>Schematic 3</strong></em>, most of the circuit is identical to the half-bridge rectifier. The only differences are that two additional rectification diodes have been added, and a transformer with three outputs (called a &#8220;Center Tapped Transformer&#8221;) is used.  The central output of the transformer is used as the ground reference, while the other two connections output an identical 12V AC signal, but out of phase by 180°. This means that when one of the outputs is in the positive section of the alternating waveform, the other is in the negative section and vice versa. </p>



<p>This type of circuit is often used in professional equipment, but is not used as much by DIY synthesiser builders. Center-tapped transformers are not available as a pre-packaged wall-plug, so you would need to wire your own. Since one end of the transformer is connected to mains power, building this circuit involves a bit more risk and should only be attempted if you have the right equipment and know what you are doing! When buying a transformer, make sure that the mains voltage input rating is correct for the country you are in. </p>



<figure class="wp-block-image size-large"><a href="https://wired.chillibasket.com/wp-content/uploads/2020/06/full-wave-rectification.jpg"><img loading="lazy" decoding="async" width="1000" height="520" src="https://wired.chillibasket.com/wp-content/uploads/2020/06/full-wave-rectification.jpg" alt="" class="wp-image-1475" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/06/full-wave-rectification.jpg 1000w, https://wired.chillibasket.com/wp-content/uploads/2020/06/full-wave-rectification-300x156.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2020/06/full-wave-rectification-768x399.jpg 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></a><figcaption><strong>Schematic 3:</strong> <em>Full-wave Rectification Circuit</em></figcaption></figure>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">How does it work?</h4>



<ol class="wp-block-list"><li>The transformer takes the mains alternating signal and reduces the voltage, outputing two 12V alternating current signals which are out of phase by 180°.</li><li>The four diodes are used to separate the positive and negative sections of the alternating signal, directing the positive halves to the +12V regulator and the negative halves to the -12V regulator. Since both AC signals are out of phase, this results in a continuous supply of power for both polarities.</li><li>The rest of the circuit is identical to the &#8220;half-bridge rectifier&#8221;, so you can refer to my description above to see how it works and what each component is doing. </li></ol>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-large"><a href="https://wired.chillibasket.com/wp-content/uploads/2020/06/full-wave-diagram.png"><img loading="lazy" decoding="async" width="985" height="332" src="https://wired.chillibasket.com/wp-content/uploads/2020/06/full-wave-diagram.png" alt="" class="wp-image-1503" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/06/full-wave-diagram.png 985w, https://wired.chillibasket.com/wp-content/uploads/2020/06/full-wave-diagram-300x101.png 300w, https://wired.chillibasket.com/wp-content/uploads/2020/06/full-wave-diagram-768x259.png 768w" sizes="auto, (max-width: 985px) 100vw, 985px" /></a><figcaption><em>Diagram showing the mains steps of the full-wave rectification process</em></figcaption></figure>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-group has-very-light-gray-background-color has-background"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Full-bridge Rectifier: Further Reading</h4>



<ul class="wp-block-list"><li><em>Circuit Digest:</em> <a rel="noreferrer noopener" href="https://circuitdigest.com/electronic-circuits/12v-dual-power-supply-circuit" target="_blank">+-12V Dual Power Supply</a></li><li><em>Circuits Today:</em> <a href="http://www.circuitstoday.com/full-wave-bridge-rectifier" target="_blank" rel="noreferrer noopener">Full Wave Rectifier-bridge Theory</a></li><li><em>All About Circuits:</em> <a rel="noreferrer noopener" href="https://www.allaboutcircuits.com/textbook/semiconductors/chpt-3/rectifier-circuits/" target="_blank">Rectifier Circuits</a></li></ul>
</div></div>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading" id="charge-pump">3. DC to DC Inverting Charge Pump</h2>



<p>It is also possible to generate a dual 12V power supply from only one +12V DC power plug. This is useful since DC power plugs are a lot more common and therefore cheaper to buy. It is also easier to find 12V DC plugs which have a high current rating, allowing more synthesiser modules to be powered from the same supply. This type of power supply design is often seen in portable modular synthesiser kits, and small Eurorack-compatible power modules. Since the transformer and rectification circuitry (large capacitors) are all contained within the external plug, the footprint of the electronics used in this design can be made a lot smaller than in the <em>Dual AC-DC rectification</em> circuits.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="underline-heading wp-block-heading">a. How does it work?</h3>



<p>In its most simple form, an inverting charge pump uses a &#8220;floating&#8221; capacitor to carry charge over from the +12V side to the -12V side of the circuit. The capacitor is charged up from the +12V input being provided by the wall plug. Once full, the capacitor is disconnected from +12V input and the positive lead is instead connected to ground. Since the charge (and therefore voltage drop) across the capacitor remains the same, this means the negative terminal of the capacitor is now at a voltage of -12V. The capacitor then begins to discharge and this is used to power the negative rail. In our power supply, this process of charging and discharging is repeated many times a second. <em><strong>Schematic 4</strong></em> shows an equivalent circuit, demonstrating how this system works. In a real circuit, the switching of the capacitor is done using an IC chip.</p>



<div class="wp-block-image"><figure class="aligncenter size-full is-resized"><a href="https://wired.chillibasket.com/wp-content/uploads/2020/04/charge-pump.gif"><img loading="lazy" decoding="async" src="https://wired.chillibasket.com/wp-content/uploads/2020/04/charge-pump.gif" alt="" class="wp-image-1137" width="563" height="365"/></a><figcaption><strong>Schematic 4: </strong><em>GIF showing how the charge pump functions; schematic based on the tutorial by <a rel="noreferrer noopener" href="https://www.maximintegrated.com/en/design/technical-documents/tutorials/7/725.html" target="_blank">Maxim Integrated</a>.</em></figcaption></figure></div>



<ol class="wp-block-list"><li>Initially, switches <strong>S1</strong> and <strong>S3</strong> are closed while switches <strong>S2</strong> and <strong>S4</strong> are open. Capacitor <strong>C1</strong> is connected to <strong>Vin</strong> and <strong>ground</strong>, causing the charge in the capacitor to increase.</li><li>After a certain interval, the switches <strong>S1</strong> and <strong>S3</strong> are opened up again while <strong>S2</strong> and <strong>S4</strong> are closed. The top leg of the capacitor is now connected to <strong>ground</strong> instead of <strong>Vin</strong>. Since the charge in the capacitor hasn&#8217;t changed, there is still the same voltage drop across the capacitor. As a result, a voltage of <strong>-Vin</strong> is present on the bottom leg of the capacitor.</li><li>This switching mechanism is continuously repeated, charging the capacitor <strong>C1</strong> with the positive input voltage and de-charging it again on the inverted output. The capacitor is essentially pumping the charge from the positive input to the inverted output.</li><li>Capacitor <strong>C2</strong> acts as a power buffer/storage, smoothing the voltage on the output and ensuring that a continuous supply is available at the inverted output.</li></ol>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="underline-heading wp-block-heading">b. Implementing it in practice</h3>



<figure class="wp-block-image size-large"><a href="https://wired.chillibasket.com/wp-content/uploads/2020/06/charge-pump-simulation.jpg"><img loading="lazy" decoding="async" width="1013" height="569" src="https://wired.chillibasket.com/wp-content/uploads/2020/06/charge-pump-simulation.jpg" alt="" class="wp-image-1496" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/06/charge-pump-simulation.jpg 1013w, https://wired.chillibasket.com/wp-content/uploads/2020/06/charge-pump-simulation-300x169.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2020/06/charge-pump-simulation-768x431.jpg 768w" sizes="auto, (max-width: 1013px) 100vw, 1013px" /></a><figcaption><strong>Schematic 5:</strong> <em>LTspice Test circuit for the inverting charge pump using the LTC1144 IC</em></figcaption></figure>



<p>In the example circuit show in <strong><em>Schematic 5</em></strong>, we are using the LTC1144 chip made by Analog Devices to do the switching for out inverting charge pump. The capacitor <strong>C6</strong> is used to invert the charge, while <strong>C5</strong> acts as reservoir so that the negative output has a more stable output. The graphs show how the circuit reacts when it is started up. The current through the capacitor <strong>C6</strong> alternates from positive to negative at regular intervals as it charges from the positive supply and de-charges into the negative output. The voltage of the negative output quickly decreases as the reservoir capacitor <strong>C5</strong> is charged up, levelling out at -12V over time. </p>



<p>In the LTC1144 chip, the frequency of the switching signal can be increased or decreased by changing the value of the capacitor connected to the OSC input pin. Charge pumps can operate at a wide range of switching frequencies, usually ranging from 1kHz to as high as 200kHz. </p>



<p><em><span style="text-decoration: underline;">Note:</span> I haven&#8217;t had the chance to try this circuit out in practice, so the capacitor values in <strong>Schematic 5 </strong>will probably need to be altered to make it suitable for use as a synthesiser power supply. The circuit simulations were done in the free program &#8220;LTspice&#8221; made by Analog Devices.</em></p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-group has-very-light-gray-background-color has-background"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Charge Pumps: Further Reading</h4>



<ul class="wp-block-list"><li><em>All About Circuits:</em> <a rel="noreferrer noopener" href="https://www.allaboutcircuits.com/technical-articles/boosting-and-inverting-without-inductors-charge-pump-power-supplies/" target="_blank">Boosting and Inverting using a charge pump</a></li><li><em>Maxim Integrated: </em><a rel="noreferrer noopener" href="https://www.maximintegrated.com/en/design/technical-documents/tutorials/7/725.html" target="_blank">In-depth tutorial of charge pumps</a></li><li><em>EDN:</em> <a rel="noreferrer noopener" href="https://www.edn.com/the-ins-and-outs-of-charge-pump-converter-ics/" target="_blank">The ins and outs of charge-pump-converter ICs</a></li></ul>
</div></div>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-group has-vivid-cyan-blue-background-color has-text-color has-background" style="color:#ffffff"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>If you have any questions or suggestions, please feel free to leave a comment below!</p>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://wired.chillibasket.com/2020/06/dual-power-supply/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title>Modular Synth &#8211; An Introduction</title>
		<link>https://wired.chillibasket.com/2020/06/synth-introduction/</link>
					<comments>https://wired.chillibasket.com/2020/06/synth-introduction/#comments</comments>
		
		<dc:creator><![CDATA[Simon Bluett]]></dc:creator>
		<pubDate>Tue, 09 Jun 2020 20:28:27 +0000</pubDate>
				<category><![CDATA[Modular Synth]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Modular]]></category>
		<category><![CDATA[Music]]></category>
		<category><![CDATA[Synth]]></category>
		<category><![CDATA[Synthesiser]]></category>
		<guid isPermaLink="false">https://wired.chillibasket.com/?p=1119</guid>

					<description><![CDATA[As an electronic engineer and amateur musician, I&#8217;ve become fascinated with electronic music. More specifically, at how analogue electronic circuits can produce, filter and shape a variety of different signals to create sounds and music. This inspired me to begin building my own synthesiser from scratch, assembling together the circuits and controls used to generate [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>As an electronic engineer and amateur musician, I&#8217;ve become fascinated with electronic music. More specifically, at how analogue electronic circuits can produce, filter and shape a variety of different signals to create sounds and music. This inspired me to begin building my own synthesiser from scratch, assembling together the circuits and controls used to generate my own electronic music. I have included some pictures of my progress below!</p>



<p>Building a synthesiser rather than buying a pre-assembled one has several  benefits; first of all, it is significantly cheaper! For example, a simple voltage-controlled oscillator (VCO) Eurorack module usually costs at least €100, while the components for a DIY version can often be sourced for less than €20. But more importantly, building a DIY synth helps you to understand exactly how each circuit works and how it influences the overall sound. Once you become familiar with how a circuit works, you can also begin adding your own extra features and quirks! There is quite a large DIY synth community where people show off and share their own designs. For me at least, I find that building my own synth is just as much fun as trying to make music with it once it is complete.</p>



<div class="wp-block-dgwt-justified-gallery">
<a href='https://wired.chillibasket.com/2020/06/synth-introduction/modular_synth_3/'><img loading="lazy" decoding="async" width="300" height="200" src="https://wired.chillibasket.com/wp-content/uploads/2020/06/modular_synth_3-300x200.jpg" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/06/modular_synth_3-300x200.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2020/06/modular_synth_3-768x511.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2020/06/modular_synth_3.jpg 1000w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>
<a href='https://wired.chillibasket.com/2020/06/synth-introduction/modular_synth_2/'><img loading="lazy" decoding="async" width="300" height="160" src="https://wired.chillibasket.com/wp-content/uploads/2020/06/modular_synth_2-300x160.jpg" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/06/modular_synth_2-300x160.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2020/06/modular_synth_2-1024x544.jpg 1024w, https://wired.chillibasket.com/wp-content/uploads/2020/06/modular_synth_2-768x408.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2020/06/modular_synth_2.jpg 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>
<a href='https://wired.chillibasket.com/2020/06/synth-introduction/modular_synth_1/'><img loading="lazy" decoding="async" width="300" height="200" src="https://wired.chillibasket.com/wp-content/uploads/2020/06/modular_synth_1-300x200.jpg" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/06/modular_synth_1-300x200.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2020/06/modular_synth_1-1024x683.jpg 1024w, https://wired.chillibasket.com/wp-content/uploads/2020/06/modular_synth_1-768x512.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2020/06/modular_synth_1.jpg 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>
</div>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading">What is a Modular Synth?</h2>



<p>Synthesisers are devices which can create sounds and music from electronic circuits. A sound can be created very simply by generating an oscillating electrical signal, which is varying at a frequency which we can hear (usually between 20 to 20,000Hz). By changing the rate at which this signal oscillates we control the pitch of the tone, while the volume can be controlled by adjusting the peak-to-peak voltage of the signal. <em><strong>Diagram 1</strong></em> shows what changing the volume and pitch of an sinusoidal signal looks like. However, generating a basic signal is only the starting point when using a synth! By combining multiple signals and filtering them in weird and wonderful ways, it is possible to create some truly unique sounds and music. </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="900" height="219" src="https://wired.chillibasket.com/wp-content/uploads/2020/06/wave_parameter.png" alt="" class="wp-image-1519" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/06/wave_parameter.png 900w, https://wired.chillibasket.com/wp-content/uploads/2020/06/wave_parameter-300x73.png 300w, https://wired.chillibasket.com/wp-content/uploads/2020/06/wave_parameter-768x187.png 768w" sizes="auto, (max-width: 900px) 100vw, 900px" /><figcaption><strong>Diagram 1: </strong><em>Illustrating the characteristics of a synthesised audio waveform.</em></figcaption></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Basic synthesisers have multiple functions hardwired together to give you a specific type of instrument and tone. Modular synths are special, because each unique musical operation is broken out into a separate device/module. For example, you could have one module to generate an initial waveform (oscillator), then one to change the tone of the sound (filter), followed by a module to control the volume (amplifier). Each module has an audio jack for every input, output and control signal, allowing you to automate and change the way in which the module operates. This allows you to hook up the modules in a large number of different ways! <em><strong>Diagram 2</strong></em> shows one way in which 4 common modules can be linked together to produce music.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="900" height="244" src="https://wired.chillibasket.com/wp-content/uploads/2020/06/modular_synth_diagrams.png" alt="" class="wp-image-1517" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/06/modular_synth_diagrams.png 900w, https://wired.chillibasket.com/wp-content/uploads/2020/06/modular_synth_diagrams-300x81.png 300w, https://wired.chillibasket.com/wp-content/uploads/2020/06/modular_synth_diagrams-768x208.png 768w" sizes="auto, (max-width: 900px) 100vw, 900px" /><figcaption><strong>Diagram 2: </strong><em>A diagram of one possible modular synth patch.</em></figcaption></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>So what does the result sound like? I&#8217;ve attached an early video of my DIY modular synth below, showing a demo tune I put together to see if all of the modules were working. I have since added some extra modules to my synthesiser, which I will talk about in a later post. At the top of the box is an 8-step sequencer which is used to control the pitch and duration of each of the notes. On the left (blue) is a single oscillator which can produce three different types of waveforms (sinusoid, triangle, square), as demonstrated at the start of the video. Finally, next to this is an amplifier (grey) which can control the volume of each of these waveforms. It is interesting to hear all the different types of tones which this basic synthesiser can produce, without needing to introduce any filtering.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-embed-youtube wp-block-embed is-type-rich is-provider-embed-handler wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper"><iframe loading="lazy" src="https://www.youtube-nocookie.com/embed/vjTBHjhgklc?feature=oembed&amp;modestbranding=1&amp;showinfo=0&amp;rel=0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" width="560" height="315" frameborder="0"></iframe></div></figure>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading">Up next in this Tutorial Series&#8230;</h2>



<p>As I continue building and improving my own DIY synth, I hope to post several tutorials describing various electronic circuits commonly used to create music. Using a variety of diagrams and practical demonstrations, I will try to show how each synth module affects the audio signal. I will also try and model parts of the circuit mathematically, to illustrate the process and consideration made by the designers when developing the designs. Here is a list of the modules I have already built, and may discuss in my future tutorials:</p>



<ul class="wp-block-list"><li><a href="https://wired.chillibasket.com/2020/06/dual-power-supply/">Dual +-12V Power Supply</a></li><li>Voltage Controlled Oscillator (VCO)</li><li>Voltage Controlled Amplifier (VCA)</li><li>8-step Sequencer</li><li>Attack, Decay, Sustain and Release module (ADSR)</li><li>Voltage Controlled Filter &#8211; Low Pass and High Pass (VCF)</li></ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-buttons aligncenter is-layout-flex wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-outline is-style-outline--1"><a class="wp-block-button__link no-border-radius" href="https://wired.chillibasket.com/2020/06/dual-power-supply/"><em>Part 2: </em>Dual 12V Power Supplies</a></div>
</div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-group has-very-light-gray-background-color has-background"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">DIY Synth Circuit Designs</h4>



<p>Most of the synth modules I have built so far are based on circuit designs made by several other DIY synth enthusiasts; here is a list of some of my sources:</p>



<ul class="wp-block-list"><li><em>Birth of a Synth</em> &#8211;<a rel="noreferrer noopener" href="http://www.birthofasynth.com/Thomas_Henry/TH_main.html" target="_blank"> Thomas Henry Modular Synth Designs</a></li><li><em>Kristian Blåsol</em> &#8211; <a rel="noreferrer noopener" href="https://www.youtube.com/playlist?list=PLyE56WXw0_5Q5QGMEXWmskuhojKyRdA3T" target="_blank">Modular in a Week (YouTube Series)</a></li><li><em>Look Mum No Computer</em> &#8211; <a href="https://www.youtube.com/playlist?list=PLluPQLh1xzlIzqgTBwTo_a5k_O63JxwjQ" target="_blank" rel="noreferrer noopener">YouTube How-To Tutorials</a></li></ul>
</div></div>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-group has-vivid-cyan-blue-background-color has-text-color has-background" style="color:#ffffff"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>If you have any questions or suggestions, please feel free to leave a comment below!</p>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://wired.chillibasket.com/2020/06/synth-introduction/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Servo Trajectory Controller for Arduino</title>
		<link>https://wired.chillibasket.com/2020/05/servo-trajectory/</link>
					<comments>https://wired.chillibasket.com/2020/05/servo-trajectory/#comments</comments>
		
		<dc:creator><![CDATA[Simon Bluett]]></dc:creator>
		<pubDate>Tue, 19 May 2020 17:06:17 +0000</pubDate>
				<category><![CDATA[Robotics]]></category>
		<category><![CDATA[Techniques]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Dynamics]]></category>
		<category><![CDATA[Servo]]></category>
		<category><![CDATA[Velocity]]></category>
		<guid isPermaLink="false">https://wired.chillibasket.com/?p=1188</guid>

					<description><![CDATA[Servo motors are used in almost all hobby robotics projects, as they allow you to control the position of joints without too much effort. Using the core &#8220;Servo&#8221; library which comes with Arduino, it is easy to command the motor to move to a specific position/angle. However, controlling the speed and acceleration of the movement [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Servo motors are used in almost all hobby robotics projects, as they allow you to control the position of joints without too much effort. Using the core &#8220;Servo&#8221; library which comes with Arduino, it is easy to command the motor to move to a specific position/angle. However, controlling the speed and acceleration of the movement is a bit more difficult. In this post, I describe how servo motors work, and different ways in which they can be controlled. To make it easier to precisely control the motion of servo motors, I have created a &#8220;Trajectory&#8221; library which can be used in conjunction with the &#8220;Servo&#8221; library to control the motion of servo motors. A full description of how to use this controller is included in this post, along with an example sketch to show how it can be used in practice. The full library and example sketch can be downloaded from <a href="https://github.com/chillibasket/arduino-classes/tree/master/servo-trajectory">my GitHub page</a>.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>Contents:</strong></p>



<ol class="wp-block-list"><li><a href="#servos-work">How do Servo Motors Work?</a></li><li><a href="#controlling-servos">Controlling Hobby Servo Motors</a></li><li><a href="#using-controller">Using my Trajectory Controller</a></li><li><a href="#example-sketch">Example Sketch</a></li><li><a href="#timing">Timing</a></li></ol>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="624" src="https://wired.chillibasket.com/wp-content/uploads/2020/05/servo-motors-1024x624.jpg" alt="" class="wp-image-1202" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/05/servo-motors-1024x624.jpg 1024w, https://wired.chillibasket.com/wp-content/uploads/2020/05/servo-motors-300x183.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2020/05/servo-motors-768x468.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2020/05/servo-motors.jpg 1200w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading" id="servos-work">1. How do Servo Motors Work?</h2>



<p>A servo motor is any type of actuator which uses sensor feedback to control the position, velocity or acceleration of the output. This type of system is commonly used in industrial automation, and there are a wide variety of different sensors, motors and control algorithms to choose from. However, in hobby electronics the term &#8220;<em>servo motor</em>&#8221; usually refers to a specific type of motor commonly used in small robots and radio-controlled vehicles. The image above shows what these types of motor look like; a regular servo motor and a <em>micro</em> servo motor are shown.</p>



<p>Hobby servo motors usually consist of a small DC motor, a gearbox, a controller chip and a potentiometer (rotary variable resistor) connected directly to the output shaft. As the output shaft turns, the resistance of the potentiometer changes which allows the controller to determine how far the motor has moved. When you send a new position command to the servo motor (usually in the form of a PWM signal), the controller moves the motor until the error between the target position and the current position is zero. </p>



<p>Most servo motors can only turn up to 180°. This limitation is caused by the potentiometer within the servo, which cannot rotate much more than this without breaking. It is possible to buy &#8220;continuous rotation&#8221; servo motors, but these aren&#8217;t quite the same; the name is actually a bit misleading. In continuous rotation servo motors, the potentiometer is removed so that the output shaft can rotate more than 180°. However, this also removes the motor&#8217;s ability to figure out how far it has turned. It therefore acts more like a normal DC motor with a speed controller (h-bridge), and shouldn&#8217;t actually be called &#8220;servo&#8221; since it isn&#8217;t using any sensor feedback to control its position.</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://wired.chillibasket.com/wp-content/uploads/2020/05/micro-servo_components.jpg"><img loading="lazy" decoding="async" src="https://wired.chillibasket.com/wp-content/uploads/2020/05/micro-servo_components-1024x619.jpg" alt="" class="wp-image-1203" width="512" height="310" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/05/micro-servo_components-1024x619.jpg 1024w, https://wired.chillibasket.com/wp-content/uploads/2020/05/micro-servo_components-300x181.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2020/05/micro-servo_components-768x464.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2020/05/micro-servo_components.jpg 1200w" sizes="auto, (max-width: 512px) 100vw, 512px" /></a></figure></div>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading" id="controlling-servos">2. Controlling Hobby Servo Motors</h2>



<p>When you send a new position command to the servo motor, it quickly jumps to the target position at maximum speed (see <strong>Example 1</strong>). While this is very simple to program, it is only useful in a small number of applications where the speed of the motion doesn&#8217;t matter. For example, if you are trying to control a humanoid robot, you want to joints to move slowly and smoothly, rather than creating a robot which wildly flails its arms around! To get around this limitation, most programs split the movement down into small steps, which get sent to the servo motor individually over time. This is how the standard &#8220;Sweep&#8221; servo example sketch works (see <strong>Example 2</strong>). The code splits the movement into smaller but equal steps, making the servo move at a constant slower speed.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>Example 1:</strong> Raw servo commands</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<pre class="wp-block-code language-arduino"><code>// Include servo library
#include &lt;Servo.h&gt;
Servo myservo;

void setup() {
    myservo.attach(9);
}

void loop() {
    // Move to 180°
    myservo.write(180);  
    delay(2700);

    // Move back to 0°
    myservo.write(0);
    delay(2700);
}</code></pre>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="500" height="475" src="https://wired.chillibasket.com/wp-content/uploads/2020/05/servo_example_1.gif" alt="" class="wp-image-1233"/></figure>
</div>
</div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>Example 2:</strong> Sweep servo commands</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<pre class="wp-block-code language-arduino"><code>#include &lt;Servo.h&gt;
Servo myservo;
int pos = 0; 

void setup() {
    myservo.attach(9);
}

void loop() {
    // Move to 180° in steps of 1°
    for (pos = 0; pos &lt;= 180; pos += 1) {
        myservo.write(pos);
        delay(15);
    }
    // Move back to 0° in steps of 1°
    for (pos = 180; pos &gt;= 0; pos -= 1) {
        myservo.write(pos);
        delay(15);
    }
}</code></pre>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="500" height="475" src="https://wired.chillibasket.com/wp-content/uploads/2020/05/servo_example_2.gif" alt="" class="wp-image-1234"/></figure>
</div>
</div>



<p>However, when I was building my <a href="https://wired.chillibasket.com/3d-printed-wall-e/">Wall-E robot</a>, this was not quite good enough. Joints don&#8217;t usually move by just jumping suddenly to a certain velocity, and then stopping dead when the target is reached. There should be a gradual acceleration as the movement starts, and a slow deceleration as the joint approaches its target position. This motivated me to write my own Arduino class, which makes performing these types of movements simple!</p>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading" id="using-controller">3. Using my Trajectory Controller</h2>



<p>In this section, all of the different functions of the class are described individually. If you are impatient and want to see how to use it all together in practice, you can jump straight to the &#8220;<a href="#example-sketch">Example Sketch</a>&#8221; section! To download the full trajectory controller library, please visit <a href="https://github.com/chillibasket/arduino-classes/tree/master/servo-trajectory">my GitHub repository</a>.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="underline-heading wp-block-heading">a. Instantiating the Class</h3>



<p>First of all, make sure that the file &#8220;trajectory.h&#8221; is contained within the same folder as the Arduino sketch you want to use the controller in. To tell the sketch that you want to use the class, you need to include it at the top of the code:</p>



<pre class="wp-block-code language-arduino"><code>#include &quot;trajectory.h&quot;</code></pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Next, the class needs to be instantiated. In this step, there are several parameters which you can provide, which determine how the controller will function. If you are happy with using some of the default values, you can omit parameters from the right side of the instantiation statement&#8230; An example of how it works is shown below. &#8220;Units&#8221; refers to the unit type used to measure the position of the system. For servo motors, this would usually be measured in degrees, but the class can actually work in any units (meters, radians, feet etc.). The &#8220;Threshold&#8221; is the difference between the current position and target position at which the controller turns off. </p>



<pre class="wp-block-code language-arduino"><code>/**
 * FORMAT: Trajectory(float maxVelocity, float acceleration, float deceleration, float threshold)
 * @param Maximum Velocity (units/second) - default = 100
 * @param Acceleration (units/second^2) - default = 50
 * @param Deceleration (units/second^2) - default = same as acceleration
 * @param Threshold (units) - default = 0.1
 */
// For example:
Trajectory servoTrajectory(20, 15, 12.5, 0.01);

// If the default threshold of 0.1 doesn&#039;t need to be changed:
Trajectory servoTrajectory(20, 15, 12.5);

// If you want the acceleration and deceleration to be the same:
Trajectory servoTrajectory(20, 15);</code></pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="underline-heading wp-block-heading">b. Setting a new Target</h3>



<p>The class has three main ways in which it can be controlled:</p>



<p><strong>i. Position</strong> &#8211; when a new position target is provided, the system accelerates at a constant rate until a maximum velocity is reached. Then once it approaches the target, it decelerates and comes to a stop just on the target position: </p>



<pre class="wp-block-code language-arduino"><code>// FORMAT: void setTargetPos(float newPosition)
// For example, move to the 180° position:
servoTrajectory.setTargetPos(180);</code></pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>ii. Position and Time </strong>&#8211; it is also possible to provide a target position and the amount of time the system should take to reach that position. While the acceleration and deceleration stay the same, the maximum velocity is reduced so that the system takes just the right amount of time to reach the target (it took me a while to figure out the formula for that! If you are interested to see how it works, check out this <a rel="noreferrer noopener" href="https://www.desmos.com/calculator/lljhxgiwkv" target="_blank">interactive graph I made</a>). Depending on the maximum acceleration and velocity, it may not be possible for the system to reach the target position within the specified time. In these cases, the function notifies this by returning &#8220;False&#8221; rather than &#8220;True&#8221;, and it reverts to the normal position-only control.</p>



<pre class="wp-block-code language-arduino"><code>// FORMAT: bool setTargetPos(float newPosition, float timeSeconds)
// For example, move to 180° over 2 seconds:
bool status = servoTrajectory.setTargetPos(180, 2));
if (status) Serial.println(&quot;Command Successful&quot;);
else Serial.println(&quot;Unable to reach target within specified time&quot;);</code></pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>iii. Velocity</strong> &#8211; Finally, it is also possible to control just the velocity of the system. This is not applicable to normal hobby servo motors which can only rotate 180°, but it can be used for continuous-rotation motors with encoders. When a new velocity value is provided, the system accelerates/decelerates at a constant rate from the initial velocity until the target speed is reached. </p>



<pre class="wp-block-code language-arduino"><code>// FORMAT: void setTargetVel(float newVelocity)
// For example, set velocity to 50°/s:
servoTrajectory.setTargetVel(50);</code></pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="underline-heading wp-block-heading">c. Using the Output from the Controller</h3>



<p>To use the controller to control the position and velocity of a servo motor, the &#8220;update&#8221; function needs to be called at regular intervals in order to recalculate all the values. This new position value then can be sent to the servo motor. The control system inside most hobby analogue servo motors updates at a frequency of 60Hz, so updating the velocity controller class at a frequency equal to or slightly higher than this will give the best results. An example of how to use the &#8220;update&#8221; function is shown below. In the example, the variable &#8220;nextTime&#8221; is used to ensure that the update function is only run once every 1/60th of a second, to achieve a frequency of 60Hz. The new angle value is obtained directly from the update function, and is then rounded to the nearest integer before being sent to the servo motor:</p>



<pre class="wp-block-code language-arduino"><code>#define TIMER_FREQ 60
unsigned long nextTime = millis();

void loop() {

	// Run this code once every 16ms (~60Hz)
	if (nextTime &lt;= millis()) {
		nextTime = millis() + (1000 / TIMER_FREQ);

		// Update the controller and get the new position value
		float newAngle = servoTrajectory.update();
 
		// Send the new value to the servo motor
		myservo.write(round(newAngle));
	}
}</code></pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="underline-heading wp-block-heading">d. Other Functions</h3>



<p><strong>i. Current Position/Velocity: </strong>The current position and velocity of the controller can be read, along with the value of the current target. There is also a function with which the current position of the system can be changed:</p>



<pre class="wp-block-code language-arduino"><code>// Get the current position and velocity
float currentPosition = servoTrajectory.getPos();
float currentVelocity = servoTrajectory.getVel();

// To change the current position to 22.5°
servoTrajectory.setPos(22.5);

// To reset the position back to 0°, the input can be left empty
servoTrajectory.setPos();

// To read the current target position/velocity value
float currentTarget = servoTrajectory.getTarget();</code></pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>ii. Update class settings: </strong>The class provides some functions with which you can read and update the current velocity, acceleration and deceleration settings of the controller:</p>



<pre class="wp-block-code language-arduino"><code>// For example, setting the maximum velocity to 40.5°/s,
// acceleration to 10.6°/s^2 and deceleration to 23°/s^2
servoTrajectory.setMaxVel(40.5);
servoTrajectory.setAcc(10.6);
servoTrajectory.setDec(23);

// To read the current settings for velocity, acceleration and deceleration
float maxVelocity = servoTrajectory.getMaxVel();
float acceleration = servoTrajectory.getAcc();
float deceleration = servoTrajectory.getDec();</code></pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>iii. Reset controller:</strong> The controller uses an integrated timer which calculates the time difference since the &#8220;update&#8221; function was last called. If the controller is turned on again after the &#8220;update&#8221; function has not been used for a while, the timer needs to be reset. The reset function should be called once at the end of the &#8220;setup&#8221; function. The current position of the controller gets set back to 0 by default, but this can be changed by providing the desired position to the function:</p>



<pre class="wp-block-code language-arduino"><code>// To reset the controller, resetting the current position to 0°
servoTrajectory.reset();

// To reset the controller and change the position to 22.5°
servoTrajectory.reset(22.5);

// To reset the controller, but keep the position the same as it was
servoTrajectory.reset(servoTrajectory.getPos());</code></pre>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading" id="example-sketch">4. Example Sketch</h2>



<p>I have written a small example sketch for my library, which shows how the class can be used in practice. In the example, the aim is to smoothly move a servo motor back and forth between the 20° and 180° position. The maximum velocity is set to 60°/second, the acceleration to 40°/s<sup>2</sup> and the deceleration to 34°/s<sup>2</sup>. The first two moves use the basic &#8220;setTargetPos&#8221; function to rotate the servo to the target position as quickly as possible. The last two move specify both the target position and time to the class, causing the servo to move at a slower speed. The servo position is recalculated and updated at a rate of 100Hz (once every 10 milliseconds):</p>



<pre class="wp-block-code language-arduino code-600 line-numbers"><code>/* * * * * * * * * * * * * * * * * * * * * * *
 * EXAMPLE SKETCH FOR THE SERVO TRAJECTORY CONTROLLER CLASS
 *
 * Code by: Simon Bluett
 * Version: 1.2
 * Copyright (C) 2020, MIT License
 * * * * * * * * * * * * * * * * * * * * * * */


// --- Include the library ---
// Make sure that the file &quot;trajectory.h&quot; is included in 
// the same folder as the Arduino sketch
#include &quot;trajectory.h&quot;
#include &lt;Servo.h&gt;


// --- Instantiate the class ---
/**
 * If you want the acceleration and deceleration to be the same
 * FORMAT: Trajectory(max velocity, acceleration)
 */
//Trajectory servoTrajectory(60, 40);

/**
 * If the acceleration and deceleration are different
 * FORMAT: Trajectory(max velocity, acceleration, deceleration)
 */
Trajectory servoTrajectory(60, 40, 34);

/**
 * By default the dynamics controller turns off when it is within 0.1 units
 * of the target position. This threshold value can be changed in the declaration
 * FORMAT: Dynamics(max velocity, acceleration, deceleration, threshold)
 */
//Trajectory servoTrajectory(60, 40, 34, 0.05);

Servo myservo;


// --- Define global variables ---
// The controller will be updated at a rate of 100Hz
#define UPDATE_FREQUENCY 100
#define UPDATE_TIME (1000 / UPDATE_FREQUENCY)
unsigned long updateTimer = 0;
int moveNumber = 0;


/* * * * * * * * * * * * * * * * * * * * * * *
 * SETUP
 * * * * * * * * * * * * * * * * * * * * * * */
void setup() {

	Serial.begin(115200);
	Serial.println(&quot;Starting program&quot;);

	// Attaches the servo on pin 9 to the servo object
	myservo.attach(9);

	// We want the servo to start at an angle of 20°
	myservo.write(20);

	// By default the controller starts at 0, so we need to
	// set the starting angle as well
	servoTrajectory.reset(20);

	/**
	 * If we suddenly decide we want to change the maximum velocity to 30°/s,
	 * the acceleration to 15°/s^2 and deceleration to 5.3°/s^2
	 */
	//servoTrajectory.setMaxVel(30);
	//servoTrajectory.setAcc(15);
	//servoTrajectory.setDec(5.3);

	/**
	 * To read what the current velocity and acceleration settings are
	 */
	//float maxVelocity = servoTrajectory.getMaxVel();
	//float acceleration = servoTrajectory.getAcc();
	//float deceleration = servoTrajectory.getDec();
}


/* * * * * * * * * * * * * * * * * * * * * * *
 * NEW MOVEMENT COMMANDS
 * * * * * * * * * * * * * * * * * * * * * * */
void nextMove() {
	switch (moveNumber) {
		case 0:
			// First we move to the 180° position as fast as possible
			servoTrajectory.setTargetPos(180);
			break;

		case 1:
			// Then move back to 20° as fast as possible
			servoTrajectory.setTargetPos(20);
			break;

		case 2:
			// Next move to 180°, but over the course of 5 seconds
			servoTrajectory.setTargetPos(180, 5);
			break;

		case 3:
			// Finally back to 20°, taking 8.5 seconds
			servoTrajectory.setTargetPos(20, 8.5);
			break;

		default:
			// If all other moves have completed, stop the program
			Serial.println(&quot;All moves completed&quot;);
			while(1) {}
	}

	moveNumber++;
}


/* * * * * * * * * * * * * * * * * * * * * * *
 * LOOP
 * * * * * * * * * * * * * * * * * * * * * * */
void loop() {

	// Update the servo position at regular intervals
	if (updateTimer &lt;= millis()) {
		if (updateTimer &lt;= millis() - UPDATE_TIME) updateTimer = millis() + UPDATE_TIME;
		else updateTimer += UPDATE_TIME;

		// Update the controller
		float currentAngle = servoTrajectory.update();

		// Set the new servo position; the function only takes integer numbers
		myservo.write(round(currentAngle));

		/**
		 * For more precise servo control, you could use writeMicroseconds.
		 * The min and max PWM pulse widths which correspond to the 0° and 180°
		 * positions needs to be inserted for MIN_PWM and MAX_PWM.
		 */
		//myservo.writeMicroseconds(map(currentAngle, 0, 180, MIN_PWM, MAX_PWM));

		// Output the target position, along with the current position and velocity
		Serial.print(&quot;Target: &quot;);
		Serial.print(servoTrajectory.getTarget());
		Serial.print(&quot;, Angle: &quot;);
		Serial.print(servoTrajectory.getPos());
		Serial.print(&quot;, Velocity: &quot;);
		Serial.println(servoTrajectory.getVel());

		// Only once the servo has reached the desired position, complete the next move
		if (servoTrajectory.ready()) {
			nextMove();
		}
	}
}
</code></pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>The output position, velocity and acceleration of the system for each of the four moves is shown in the diagram below. As you can see, the position stops and starts smoothly. This type of motion is called a &#8220;trapezoidal velocity&#8221; trajectory, which comes from the shape seen in the &#8220;Velocity&#8221; graph. You may notice the there is sudden drop in the velocity just as the system reaches the target position. This is caused by the position &#8220;threshold&#8221; defined in the class, which turns off the controller when the system comes within a certain distance of the target position (by default this is set to 0.1). </p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://wired.chillibasket.com/wp-content/uploads/2020/05/example-dynamics.jpg"><img loading="lazy" decoding="async" src="https://wired.chillibasket.com/wp-content/uploads/2020/05/example-dynamics.jpg" alt="" class="wp-image-1237" width="541" height="616" srcset="https://wired.chillibasket.com/wp-content/uploads/2020/05/example-dynamics.jpg 721w, https://wired.chillibasket.com/wp-content/uploads/2020/05/example-dynamics-263x300.jpg 263w" sizes="auto, (max-width: 541px) 100vw, 541px" /></a></figure></div>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading" id="timing">5. Timing</h2>



<p>The class is relatively fast, making it useful for controlling systems which need a high refresh rate. The table below records the approximate times taken by a variety of micro-controllers to run the main functions of the class. The results show that using an Arduino Uno at an update rate of 100Hz, the class should be able to control up to 30 servo motors before slowing down. The Arduino Uno and Pro Mini both use the same ATmega 328P micro-processor, which explains why their speed is identical:</p>



<figure class="wp-block-table aligncenter is-style-regular"><table class="has-fixed-layout"><thead><tr><th><strong>Function</strong></th><th><strong>Arduino Uno</strong></th><th><strong>Arduino 101</strong></th><th><strong>Pro Mini</strong></th></tr></thead><tbody><tr><td>update()</td><td>0.164 ms</td><td>0.014 ms</td><td>0.164 ms</td></tr><tr><td>targetPos(x)</td><td>0.008 ms</td><td>0.002 ms</td><td>0.008 ms</td></tr><tr><td>targetPos(x,t)</td><td>0.28 ms</td><td>0.40 ms</td><td>0.28 ms</td></tr><tr><td>targetVel(v)</td><td>0.01 ms</td><td>0.005 ms</td><td>0.01 ms</td></tr></tbody></table></figure>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="background:#13aff0; color:white; padding: 20px;">If you have any questions or comments, please leave a reply below:</div>
]]></content:encoded>
					
					<wfw:commentRss>https://wired.chillibasket.com/2020/05/servo-trajectory/feed/</wfw:commentRss>
			<slash:comments>14</slash:comments>
		
		
			</item>
		<item>
		<title>3D printed Wall-E</title>
		<link>https://wired.chillibasket.com/2018/09/wall-e/</link>
					<comments>https://wired.chillibasket.com/2018/09/wall-e/#comments</comments>
		
		<dc:creator><![CDATA[Simon Bluett]]></dc:creator>
		<pubDate>Tue, 25 Sep 2018 20:56:47 +0000</pubDate>
				<category><![CDATA[3D Printing]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Robotics]]></category>
		<category><![CDATA[3D Printer]]></category>
		<category><![CDATA[Robot]]></category>
		<category><![CDATA[Wall-E]]></category>
		<guid isPermaLink="false">http://wired.chillibasket.com/?p=735</guid>

					<description><![CDATA[Ever since I first assembled my 3d-printer four years ago, I have wanted to build something substantial and impressive with it. I&#8217;ve printed numerous small and useful things with it over the years (replacements for broken shower parts, cases for electronic boards etc.), but I hadn&#8217;t really manufactured anything artistic which could stand up on [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-rich is-provider-embed-handler wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper"><iframe loading="lazy" src="https://www.youtube-nocookie.com/embed/QidMAtTzF88?feature=oembed&amp;modestbranding=1&amp;showinfo=0&amp;rel=0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" width="560" height="315" frameborder="0"></iframe></div></figure>



<p>Ever since I first assembled my 3d-printer four years ago, I have wanted to build something substantial and impressive with it. I&#8217;ve printed numerous small and useful things with it over the years (replacements for broken shower parts, cases for electronic boards etc.), but I hadn&#8217;t really manufactured anything artistic which could stand up on its own. I just finished my Electronic Engineering Undergraduate course in May, so I had three months free to work on my own project before I began my Masters in September.</p>



<p>Since I&#8217;m just starting a Masters in Robotics, I decided that whatever I make, it should be some kind of robot. That is how I began designing and manufacturing my own version of Wall-E, from the 2008 Pixar film! There are few robots that are better known and loved than Wall-E, and I also chose him for a number of other reasons. The project is scaleable, as apart from the building process a lot of interesting work could be done adding emotions and interactions to the robot. I planned to add several servo motors to the eyes and neck to allow him to be very expressive. As I did my Bachelor project on the area of voice and face recognition, I also wanted to include a camera in one of the eyes so that he could recognise his friends!</p>



<p>As always tends to happen on replica projects like these, I got a little bit too ambitious&#8230; but all in all I am really happy with the result! The robot is battery powered, and the motors are controlled using an Arduino Uno. The cable attached in the video is only used to send serial commands to the Arduino so that I can control his movements.</p>



<p>The robots is comprised of a mind-numbing total of 309 printed parts! 210 of those parts make up the tank/caterpillar treads, as each of the 70 small plates is held together by two even smaller plastic pins. The arms and hands are fully articulated, and can be manually posed into a variety of positions.</p>



<p>The final goal is to include a Raspberry Pi within Wall-E (connected to the Arduino) to allow him to be controlled wirelessly, and to add sounds and a live camera feed. Unfortunately I ran out of time during the summer, and only just managed to complete all of the 3d-printing, painting and assembly. I wrote a small program to test each of the motors, as well as drive the robot around with some simple controls. When testing the servo motors, I noticed that some parts of the robot are too heavy for the small motors to lift. For example the two joints in the neck don&#8217;t really work as the head is too heavy. I&#8217;ll need to have a look at how I can solve this issue once I have a little more time again.</p>



<p><strong>Update:</strong> (28th July 2019) I have now released all the 3d CAD files, assembly instructions and code for the robot so that you can make your own! I&#8217;ve described the robot in greater detail on a separate page:</p>



<div class="wp-block-buttons aligncenter is-layout-flex wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-outline is-style-outline--2"><a class="wp-block-button__link no-border-radius" href="https://wired.chillibasket.com/3d-printed-wall-e/">Click here for the full robot description!</a></div>
</div>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Here is a collection of pictures of the assembled robot:</p>



<div class="wp-block-dgwt-justified-gallery">
<a href='https://wired.chillibasket.com/2018/09/wall-e/wall-e7/'><img loading="lazy" decoding="async" width="300" height="281" src="https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e7-300x281.jpg" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e7-300x281.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e7-768x720.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e7-1024x961.jpg 1024w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e7.jpg 1050w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>
<a href='https://wired.chillibasket.com/2018/09/wall-e/wall-e5/'><img loading="lazy" decoding="async" width="224" height="300" src="https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e5-224x300.jpg" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e5-224x300.jpg 224w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e5-768x1027.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e5-765x1024.jpg 765w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e5.jpg 897w" sizes="auto, (max-width: 224px) 100vw, 224px" /></a>
<a href='https://wired.chillibasket.com/2018/09/wall-e/wall-e3/'><img loading="lazy" decoding="async" width="300" height="227" src="https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e3-300x227.jpg" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e3-300x227.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e3-768x582.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e3-1024x776.jpg 1024w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e3.jpg 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>
<a href='https://wired.chillibasket.com/2018/09/wall-e/wall-e2/'><img loading="lazy" decoding="async" width="222" height="300" src="https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e2-222x300.jpg" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e2-222x300.jpg 222w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e2-768x1039.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e2-757x1024.jpg 757w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e2.jpg 887w" sizes="auto, (max-width: 222px) 100vw, 222px" /></a>
<a href='https://wired.chillibasket.com/2018/09/wall-e/wall-e1/'><img loading="lazy" decoding="async" width="300" height="300" src="https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e1-300x300.jpg" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e1-300x300.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e1-150x150.jpg 150w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e1-768x769.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e1-1024x1024.jpg 1024w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e1.jpg 1100w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>
<a href='https://wired.chillibasket.com/2018/09/wall-e/wall-e4/'><img loading="lazy" decoding="async" width="300" height="228" src="https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e4-300x228.jpg" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e4-300x228.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e4-768x584.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e4-1024x779.jpg 1024w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e4.jpg 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>
<a href='https://wired.chillibasket.com/2018/09/wall-e/wall-e6/'><img loading="lazy" decoding="async" width="240" height="300" src="https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e6-240x300.jpg" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e6-240x300.jpg 240w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e6-768x959.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e6-820x1024.jpg 820w, https://wired.chillibasket.com/wp-content/uploads/2018/09/Wall-e6.jpg 881w" sizes="auto, (max-width: 240px) 100vw, 240px" /></a>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://wired.chillibasket.com/2018/09/wall-e/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Miniature Quadcopter</title>
		<link>https://wired.chillibasket.com/2017/07/miniature-quadcopter-1/</link>
					<comments>https://wired.chillibasket.com/2017/07/miniature-quadcopter-1/#respond</comments>
		
		<dc:creator><![CDATA[Simon Bluett]]></dc:creator>
		<pubDate>Sun, 23 Jul 2017 20:49:03 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://wired.chillibasket.com/?p=571</guid>

					<description><![CDATA[Consumer quadcopters and drones are really popular at the moment, and I&#8217;ve always wanted to fly one of my own. Unfortunately I live in the city centre, so there isn&#8217;t really much room to fly a drone anywhere without annoying a lot of people. Besides, most quadcopters are relatively expensive. As a result, I decided [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Consumer quadcopters and drones are really popular at the moment, and I&#8217;ve always wanted to fly one of my own. Unfortunately I live in the city centre, so there isn&#8217;t really much room to fly a drone anywhere without annoying a lot of people. Besides, most quadcopters are relatively expensive. As a result, I decided to set myself a challenge for the summer: to build my own miniature quadcopter! It should be small enough that I can fly it indoors, but also use as many recycled parts as possible in order to reduce cost.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading">Scavenging Parts</h2>



<p>When I was younger, I used to fly remote control aeroplanes. They worked really well for about a week or two, and then something would break. I think I went through about five or six planes over the course of three years. Some of the old broken RC planes were still lying around in my house, so I decided to dissect them to see if I could find any useful parts. In the end, I found six small motors which I could use, along with a couple of small controller boards. There was also one LiPo battery that looked as if it might still work, but there weren&#8217;t any markings on the case which said what voltage and capacity it worked at. I decided to start off the project by looking at the motors.</p>



<div class="wp-block-image"><figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="607" src="https://wired.chillibasket.com/wp-content/uploads/2017/07/ScavengingParts-1024x607.jpg" alt="" class="wp-image-630" srcset="https://wired.chillibasket.com/wp-content/uploads/2017/07/ScavengingParts-1024x607.jpg 1024w, https://wired.chillibasket.com/wp-content/uploads/2017/07/ScavengingParts-300x178.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2017/07/ScavengingParts-768x455.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2017/07/ScavengingParts.jpg 1071w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading">Testing the Motors</h2>



<p>Before I could continue designing and building the quadcopter, I needed to make sure that the motors were strong enough to actually lift some weight. They were intended for an aeroplane after all, which requires significantly less power to keep flying than a helicopter. To conduct the test I 3D printed a stand to mount the motor on, and than connected the motor to my variable power supply. To measure the amount of force exerted by the propellers, I turned the blades upside down so that it would push the air upwards instead of downwards. Finally, the motor and stand could be places on a weighing scales to measure this increase in downward force.</p>



<div class="wp-block-image"><figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="687" src="https://wired.chillibasket.com/wp-content/uploads/2017/07/TestingMotor1-1024x687.jpg" alt="" class="wp-image-623" srcset="https://wired.chillibasket.com/wp-content/uploads/2017/07/TestingMotor1-1024x687.jpg 1024w, https://wired.chillibasket.com/wp-content/uploads/2017/07/TestingMotor1-300x201.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2017/07/TestingMotor1-768x515.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2017/07/TestingMotor1.jpg 1200w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>The graph below shows the results I got. The light-blue line is the increase in mass of the contraption (which can be multiplied by 9.81 to get the force), while the dark-blue, orange, grey and yellow lines are the voltage, current, resistance and power (respectively) being supplied to the motor. I used a current meter attached to an Arduino to record these values. The accuracy of the weighing scales was ±1gram, so that&#8217;s why the line is very jagged.</p>



<div class="wp-block-image"><figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="753" src="https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_MotorPerformance-1024x753.png" alt="" class="wp-image-577" srcset="https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_MotorPerformance-1024x753.png 1024w, https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_MotorPerformance-300x221.png 300w, https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_MotorPerformance-768x564.png 768w, https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_MotorPerformance.png 1200w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>



<div class="wp-block-dgwt-justified-gallery">
<a href='https://wired.chillibasket.com/graph_voltagevscurrent/'><img loading="lazy" decoding="async" width="300" height="189" src="https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_VoltagevsCurrent-300x189.png" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_VoltagevsCurrent-300x189.png 300w, https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_VoltagevsCurrent-768x483.png 768w, https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_VoltagevsCurrent-1024x644.png 1024w, https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_VoltagevsCurrent.png 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>
<a href='https://wired.chillibasket.com/2017/07/miniature-quadcopter-1/graph_forcevsvoltage/'><img loading="lazy" decoding="async" width="300" height="198" src="https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_ForcevsVoltage-300x198.png" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_ForcevsVoltage-300x198.png 300w, https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_ForcevsVoltage-768x506.png 768w, https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_ForcevsVoltage-1024x675.png 1024w, https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_ForcevsVoltage.png 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>
<a href='https://wired.chillibasket.com/2017/07/miniature-quadcopter-1/graph_forcevscurrent/'><img loading="lazy" decoding="async" width="300" height="197" src="https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_ForcevsCurrent-300x197.png" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_ForcevsCurrent-300x197.png 300w, https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_ForcevsCurrent-768x505.png 768w, https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_ForcevsCurrent-1024x673.png 1024w, https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_ForcevsCurrent.png 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>
<a href='https://wired.chillibasket.com/graph_forcevspower/'><img loading="lazy" decoding="async" width="300" height="203" src="https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_ForcevsPower-300x203.png" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_ForcevsPower-300x203.png 300w, https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_ForcevsPower-768x520.png 768w, https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_ForcevsPower-1024x693.png 1024w, https://wired.chillibasket.com/wp-content/uploads/2017/07/Graph_ForcevsPower.png 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>
</div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>As you can see, the results are actually quite interesting. There is a clear correlation between the force created by the propeller and the voltage applied to the motor. This can be seen even more clearly when we just plot these two attributes on their own, in the third picture. The best-fit line has a very good correlation coefficient of about 0.98.</p>



<p>The blue dots relate to the readings taken while the voltage was increased, and the green ones relate to the readings taken when the voltage was decreased. The slight offset in the x-axis between the two plots is probably due to a delay in the response of the weighing scales (it is designed to take one reading, and not a continuously changing reading after all).</p>



<p>The resistance of the motor was found to be about 2.75 ohms, while the peak current draw at a voltage of 3.3V was 1.13 amps.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading">Power Management</h2>



<p>Most motor controllers introduce a voltage drop, reducing the maximum voltage which can be supplied to the motors. Let&#8217;s assume that the battery can provide 3.7V and that there is an average voltage drop of 0.4V, meaning that the maximum voltage which can be supplied is about 3.3V. With fours motors running at this maximum voltage, the battery needs to be able to supply 4.52 amps of current and 14.9 watts of power. A small single cell Lithium Ion (LiPo) battery usually has around 300mAh. We can calculate an approximate flight time as follows:</p>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true">\frac{300 \times 60}{1000 \times 4.5} = 4 \text{ minutes}</div>



<p>The controller board will also consume some power, but it is in the order of about 20-30mA, so it won&#8217;t affect the calculations much. As the motor drivers and battery aren&#8217;t 100% efficient, I&#8217;d estimate a flight time of about 3.5 minutes. This is very similar to the flight time advertised by other miniature quadcopters which are on the market at the moment.</p>



<p>The LiPo I looked at had a C-rating of 25C. That means that the entire capacity of the battery can be discharged in 1/25 of an hour, allowing the maximum current draw that it can handle to be calculated as shown below. The combined current draw of the motors is well under this rating, so we are all good.</p>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true">\text{Max Current Draw } = \text{ Capacity } \times \text{ C-Rating } = 0.3 \times 25 = 7.5 \text{ amps}</div>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading">Lift</h2>



<p>Do the motors and propellers provide enough lift in order to keep the quadcopter in the air? I put together a quick mass balance to figure this out:</p>



<table class="wp-block-table is-style-regular"><tbody><tr style="background-color:#c4ecff;"><th><strong>Item</strong></th><th><strong>Mass (grams)</strong></th><th><strong>Force (N)</strong></th></tr><tr><td>Max Lift (with four motors):</td><td>52</td><td>0.5101</td></tr><tr><td>Motors &amp; Propellors</td><td>22</td><td>0.2168</td></tr><tr><td>Battery</td><td>10</td><td>0.0981</td></tr><tr><td>Controller Circuitry</td><td>6</td><td>0.0589</td></tr><tr><td>Frame</td><td>10</td><td>0.0981</td></tr><tr><td><strong>Overall Lift</strong></td><td><strong>4</strong></td><td><strong>0.0392</strong></td></tr></tbody></table>



<p>Giving the quadcopter a reasonable upward acceleration of:</p>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true">\text{Force } \div \text{ Mass } = 0.0392 \div 0.048 = 0.82 m/s^{2}</div>



<p>Of course the realistic acceleration will be slightly less due to losses, but this table proves that it is possible for the quadcopter to fly! It will definitely be difficult to do, but I do like a good challenge! I will probably have to redesign the frame a couple of times to make sure that the whole device is light enough that it still has enough manoeuvrability.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p><em><strong>Next Steps</strong></em></p>



<ul class="wp-block-list"><li>Designing and 3D printing a light-weight frame</li><li>Deciding on a suitable controller board</li><li>Designing the motor controllers and power circuity</li></ul>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-text-color has-cyan-bluish-gray-color"><em>Updated: 25th May 2019 &#8211; Reformatted post</em></p>
]]></content:encoded>
					
					<wfw:commentRss>https://wired.chillibasket.com/2017/07/miniature-quadcopter-1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Arduino 101 &#8211; An Introduction</title>
		<link>https://wired.chillibasket.com/2016/10/arduino-101-an-introduction/</link>
					<comments>https://wired.chillibasket.com/2016/10/arduino-101-an-introduction/#comments</comments>
		
		<dc:creator><![CDATA[Simon Bluett]]></dc:creator>
		<pubDate>Mon, 24 Oct 2016 20:20:55 +0000</pubDate>
				<category><![CDATA[Arduino 101]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Curie]]></category>
		<category><![CDATA[Intel]]></category>
		<category><![CDATA[Module]]></category>
		<guid isPermaLink="false">http://wired.chillibasket.com/?p=472</guid>

					<description><![CDATA[There are a multitude of micro-controllers available today, many of them advertised to be &#8216;Arduino Compatible&#8217;. Are these devices really worth considering, or should you just stick with genuine Arduinos? For the past few years I&#8217;ve had a chance to work with a good few of these devices, and I&#8217;ve discovered many advantages and disadvantages [&#8230;]]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image"><figure class="aligncenter"><img loading="lazy" decoding="async" width="1200" height="450" src="http://wired.chillibasket.com/wp-content/uploads/2016/10/BannerPart1.jpg" alt="Arduino 101 - Introduction" class="wp-image-507" srcset="https://wired.chillibasket.com/wp-content/uploads/2016/10/BannerPart1.jpg 1200w, https://wired.chillibasket.com/wp-content/uploads/2016/10/BannerPart1-300x113.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2016/10/BannerPart1-768x288.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2016/10/BannerPart1-1024x384.jpg 1024w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure></div>



<p>There are a multitude of micro-controllers available today, many of them advertised to be &#8216;Arduino Compatible&#8217;. Are these devices really worth considering, or should you just stick with genuine Arduinos? For the past few years I&#8217;ve had a chance to work with a good few of these devices, and I&#8217;ve discovered many advantages and disadvantages with each of them. Over the summer I got my hands on the Arduino 101; a relatively new Uno compatible micro-controller using Intel&#8217;s Curie module. Over the next couple of weeks I&#8217;ll be writing a number of tutorials about how to use some&nbsp;of Arduino 101&#8217;s features, but in this post I&#8217;ll look simply look at what it&#8217;s all about!</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<hr class="wp-block-separator"/>



<h2 class="wp-block-heading">What makes Arduino 101 special?</h2>



<p>What makes the Arduino 101 different than any of the other micro-controllers? Let&#8217;s look at a quick comparison between the Uno and the 101:</p>



<table class="wp-block-table is-style-stripes"><tbody><tr><td><strong>Device</strong></td><td><strong>Arduino Uno R3</strong></td><td><strong>Arduino 101</strong></td></tr><tr><td><strong>Microcontroller</strong></td><td>ATmega328P</td><td>Intel Curie</td></tr><tr><td><strong>Operating Voltage</strong></td><td>5V</td><td>3.3V (5V tolerant I/O)</td></tr><tr><td><strong>Input Voltage (recommended)</strong></td><td>7-12V</td><td>7-12V</td></tr><tr><td><strong>Input Voltage (limit)</strong></td><td>6-20V</td><td>7-20V</td></tr><tr><td><strong>Digital I/O Pins</strong></td><td>14</td><td>14</td></tr><tr><td><strong>PWM Digital I/O Pins</strong></td><td>6</td><td>4</td></tr><tr><td><strong>Analog Input Pins</strong></td><td>6</td><td>6</td></tr><tr><td><strong>External Interrupt Pins</strong></td><td>2</td><td>All pins</td></tr><tr><td><strong>DC Current per I/O Pin</strong></td><td>20 mA</td><td>20 mA</td></tr><tr><td><strong>Flash Memory</strong></td><td>32KB</td><td>196 KB</td></tr><tr><td><strong>SRAM</strong></td><td>2 KB</td><td>24 KB</td></tr><tr><td><strong>EEPROM</strong></td><td>1 KB</td><td>None (Can be emulated)</td></tr><tr><td><strong>Clock Speed</strong></td><td>16MHz</td><td>32MHz</td></tr><tr><td><strong>LED_BUILTIN</strong></td><td>13</td><td>13</td></tr><tr><td><strong>Features</strong></td><td>&#8211;</td><td>Bluetooth LE, 6-axis accelerometer/gyro</td></tr><tr><td><strong>Length</strong></td><td>68.6 mm</td><td>68.6 mm</td></tr><tr><td><strong>Width</strong></td><td>53.4 mm</td><td>53.4 mm</td></tr><tr><td><strong>Weight</strong></td><td>25 gr.</td><td>34 gr.</td></tr><tr><td><strong>Price</strong></td><td>$24.95</td><td>$30.00</td></tr></tbody></table>



<p><em>(Source &#8211; <a href="http://www.arduino.cc" target="_blank" rel="noreferrer noopener">www.arduino.cc</a>, Prices on 22nd Oct 2016 &#8211; <a href="http://www.sparkfun.com" target="_blank" rel="noreferrer noopener">www.sparkfun.com</a>)</em></p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><em>Overview</em></h3>



<p>The two devices are physically identical; they both are the same size and have the same renowned &#8216;Uno&#8217; header layout. The Arduino 101 definitely wins out in terms of features; it has more flash memory and better interrupt support. The only place where the 101 is lacking is the number of PWM pins.</p>



<div class="wp-block-image"><figure class="aligncenter"><a href="http://wired.chillibasket.com/wp-content/uploads/2016/10/Arduino101Labels.jpg" rel="noopener"><img loading="lazy" decoding="async" width="1500" height="1000" src="http://wired.chillibasket.com/wp-content/uploads/2016/10/Arduino101Labels.jpg" alt="Labelling all components of the Arduino 101..." class="wp-image-511" srcset="https://wired.chillibasket.com/wp-content/uploads/2016/10/Arduino101Labels.jpg 1500w, https://wired.chillibasket.com/wp-content/uploads/2016/10/Arduino101Labels-300x200.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2016/10/Arduino101Labels-768x512.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2016/10/Arduino101Labels-1024x683.jpg 1024w" sizes="auto, (max-width: 1500px) 100vw, 1500px" /></a><figcaption>All main components and connections on the Arduino 101.</figcaption></figure></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><em>Input/Output Pins &amp; Interrupts</em></h3>



<p>The Arduino 101 has the same number of Digital and Analog I/O pins as the Uno. While it has less PWM pins than the Uno, it more than makes up for it in terms of interrupt pins. Many people who are new to micro-controllers don&#8217;t know the importance of interrupts, but they are extremely useful. For example if you have three buttons connected to the controller (with each of them attached to an interrupt), you know that the program definitely will notice the button being pressed, no matter what it is doing.</p>



<p>A cool feature with the Arduino 101 is that it also supports a software timing interrupt. If you&nbsp;<strong>#include &#8220;CurieTimerOne.h&#8221;&nbsp;</strong>library, you can set up an interrupt which runs repeatedly at a set time interval. This is really useful if you want to process sensor data at a regular rate, without having to write your own time-keeping function.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><em>Accelerometer, Gyroscope, and BLE</em></h3>



<p>The best feature of the Arduino 101 is that it has integrated Gyroscope, Accelerometer, and Bluetooth Low Energy (BLE) modules! If you were to buy these features separately as breakouts for the Arduino Uno, it would definitely add another $30 to the total cost. Therefore if you have a project in mind which uses any of these features, I&#8217;d encourage you to get the 101!</p>



<p>The accelerometer and gyroscope sensors are not the most accurate or sensitive ones I have ever used, but with some&nbsp;calibration and data processing, they should be good enough to cover most electronics projects.</p>



<p>I&#8217;ve used the BLE to connect the Curie to an Android phone. It can be quite awkward to get the BLE to work properly (especially on the Android side), but it definitely is possible. BLE is good for low-power communication at short ranges and low transfer rates, but it is not suitable for transmitting a large amount of real-time data (trust me, I&#8217;ve tried!). The Arduino sketch supports a number of interrupts for each of the main BLE events, such as connecting/disconnecting to a host and receiving new data.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><em><strong>Neural Network</strong></em></h3>



<p>The Intel Curie module&nbsp;also has a Neural Network Pattern Matching Engine, which can be used on the Arduino 101. I&#8217;ve looked around online, and there is very little documentation about what it is and how to use it. I happen to be one of the few people who has used it, so I will definitely be writing a tutorial about it soon&#8230;</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><em><strong>Advanced Features</strong></em></h3>



<p>The software support for the Curie module is still an ongoing process, and not all of the features have yet been catered for. The Intel Curie module itself is actually quite interesting. It has two processor cores; one of them is an Intel Quark processor core that hosts the USB and other system level duties, while the other is an ARC core that runs the user sketches. Advanced users can compile their own firmware for the Curie (based on Zephyr) which provides access to all of its features, low power states, and cores. The Open Developer Kit (ODK) is available on Intel&#8217;s <a href="https://software.intel.com/en-us/node/674972">software download page</a>.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<hr class="wp-block-separator"/>



<h2 class="wp-block-heading">Getting Started with the Arduino 101</h2>



<div class="wp-block-image wp-image-509 size-full"><figure class="aligncenter"><img loading="lazy" decoding="async" width="800" height="491" src="http://wired.chillibasket.com/wp-content/uploads/2016/10/Screen-Shot-2016-10-24-at-20.27.12.png" alt="Installing Arduino 101 Firmware using the boards manager." class="wp-image-509" srcset="https://wired.chillibasket.com/wp-content/uploads/2016/10/Screen-Shot-2016-10-24-at-20.27.12.png 800w, https://wired.chillibasket.com/wp-content/uploads/2016/10/Screen-Shot-2016-10-24-at-20.27.12-300x184.png 300w, https://wired.chillibasket.com/wp-content/uploads/2016/10/Screen-Shot-2016-10-24-at-20.27.12-768x471.png 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /><figcaption>Installing Arduino 101 Firmware using the boards manager.</figcaption></figure></div>



<p>The Arduino 101 is fully compatible with the Arduino IDE, so that makes creating sketches and uploading them to the device very simple. To get started, simply follow these steps:</p>



<ol class="wp-block-list"><li>Download the Arduino IDE: <a href="https://www.arduino.cc/en/Main/Software" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">https://www.arduino.cc/en/Main/Software</a></li><li>Unzip the application, and install it on your computer.</li><li>Once the IDE is open, you need to install the drivers for the 101. To do this navigate to: <strong>Tools->Board->Boards Manager</strong></li><li>Scroll down in the window that appears until you find &#8220;<strong>Intel Curie Boards </strong>by <strong>Intel</strong>&#8220;. Click on it and install the latest version.</li><li>You should now be good to go; I&#8217;d recommend you try out the &#8220;Blink&#8221; example sketch to make sure that everything is working.</li><li>Some common issues are that you do not have the right board selected in the menu <strong>Tools->Boards</strong>, or that you don&#8217;t have the right comms port selected in <strong>Tools->Port</strong>.</li></ol>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-text-color has-cyan-bluish-gray-color"> <em>Updated: 24th May 2019 &#8211; Reformatted post</em></p>
]]></content:encoded>
					
					<wfw:commentRss>https://wired.chillibasket.com/2016/10/arduino-101-an-introduction/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Assembling a 3D Printer</title>
		<link>https://wired.chillibasket.com/2016/06/my-3d-printer/</link>
					<comments>https://wired.chillibasket.com/2016/06/my-3d-printer/#respond</comments>
		
		<dc:creator><![CDATA[Simon Bluett]]></dc:creator>
		<pubDate>Sun, 19 Jun 2016 17:12:04 +0000</pubDate>
				<category><![CDATA[3D Printing]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Robotics]]></category>
		<category><![CDATA[3D Printer]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Assembly]]></category>
		<category><![CDATA[Printing]]></category>
		<category><![CDATA[Review]]></category>
		<guid isPermaLink="false">http://wired.chillibasket.com/?p=280</guid>

					<description><![CDATA[Over the past few years I have had the opportunity to use&#160;a number of 3D printers to print some of the parts I had designed. I really like the idea of being able to quickly design a part and then print it into a physical object, within only a few hours. As a result, I [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Over the past few years I have had the opportunity to use&nbsp;a number of 3D printers to print some of the parts I had designed. I really like the idea of being able to quickly design a part and then print it into a physical object, within only a few hours. As a result, I decided that I wanted to build my own printer!</p>



<p>At first I wanted to build the whole printer from scratch, using some parts that I had lying around at home along with some parts bought online. But after I did some research, I realised that buying&nbsp;a whole 3D printer kit online that was almost cheaper than buying the individual components! The HIC Prusa i3 kit was about $340 at the time (Summer 2015), and I also bought some PLA printer filament on Amazon. The best part of the deal was that the whole kit was sent for free by courier to Ireland; all the way from Hong Kong! The whole thing almost seemed too good to be true&#8230;</p>



<p>&#8230; and it was too good to be true! I had forgotten about import duties and taxes on packages from outside the EU, so that cost me another €50. All the same, the delivery took a mere 4 days (from Hong Kong to Ireland) and the parts arrived well packaged and undamaged.</p>



<div class="wp-block-image wp-image-450 size-full"><figure class="aligncenter"><img loading="lazy" decoding="async" width="1200" height="800" src="http://wired.chillibasket.com/wp-content/uploads/2016/05/3D-Printer-Unboxing.jpg" alt="3D Printer Unboxing" class="wp-image-450" srcset="https://wired.chillibasket.com/wp-content/uploads/2016/05/3D-Printer-Unboxing.jpg 1200w, https://wired.chillibasket.com/wp-content/uploads/2016/05/3D-Printer-Unboxing-300x200.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2016/05/3D-Printer-Unboxing-768x512.jpg 768w, https://wired.chillibasket.com/wp-content/uploads/2016/05/3D-Printer-Unboxing-1024x683.jpg 1024w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /><figcaption>Unboxing the 3D printer kit.</figcaption></figure></div>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Assembly </h2>



<p>Although the instructions provided with the printer kit weren&#8217;t great, the assembly of the 3D printed was relatively straight-forward. The main issue I came across during the assembly was that the Z-axis stepper motor cable included with the kit was too short, so I had to cut it in half and solder on some wires to make it longer. The linear bearings on which the X and Y-axis carriages were tricky to get aligned properly, so they required an hour or two to calibrate properly so that they would move smoothly.</p>



<p>The instructions didn&#8217;t say much about cable management &#8211; apart from one rough diagram &#8211; so I relied on my intuition as an engineer in order to position them properly. All the same, it wasn&#8217;t a hard build and there weren&#8217;t any unexpected surprises. I was prepared for a little bit of guess work and tinkering, so the whole assembly was completed in just a few hours (spread across 3-4 evenings).</p>



<div class="wp-block-image wp-image-449 size-full"><figure class="aligncenter"><img loading="lazy" decoding="async" width="927" height="1023" src="http://wired.chillibasket.com/wp-content/uploads/2016/05/3D-Printer-Assembly-e1464456862795.jpg" alt="3D Printer Assembly" class="wp-image-449" srcset="https://wired.chillibasket.com/wp-content/uploads/2016/05/3D-Printer-Assembly-e1464456862795.jpg 927w, https://wired.chillibasket.com/wp-content/uploads/2016/05/3D-Printer-Assembly-e1464456862795-272x300.jpg 272w, https://wired.chillibasket.com/wp-content/uploads/2016/05/3D-Printer-Assembly-e1464456862795-768x848.jpg 768w" sizes="auto, (max-width: 927px) 100vw, 927px" /><figcaption>Putting together the acrylic frame.</figcaption></figure></div>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Software</h2>



<p>Surprisingly enough, getting the firmware to work was the most difficult part of the whole build. Although the controller board came with some firmware already installed, I decided to compile my own version so that I would have more control of the whole system. I downloaded the latest version of <a href="http://reprap.org/wiki/Marlin">Marlin</a>, and started editing&nbsp;the configurations to suit those of my printer. There are plenty of videos/blog posts available describing how to configure the firmware properly, but it took me almost 2 weeks and numerous test prints to get most of the settings right. Since then, I&#8217;ve made minor changes to the firmware every month or two.</p>



<div class="wp-block-image wp-image-451 size-full"><figure class="aligncenter"><img loading="lazy" decoding="async" width="1000" height="944" src="http://wired.chillibasket.com/wp-content/uploads/2016/05/Dalek-3D-Print.jpg" alt="Dalek 3D Print" class="wp-image-451" srcset="https://wired.chillibasket.com/wp-content/uploads/2016/05/Dalek-3D-Print.jpg 1000w, https://wired.chillibasket.com/wp-content/uploads/2016/05/Dalek-3D-Print-300x283.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2016/05/Dalek-3D-Print-768x725.jpg 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /><figcaption>My fully assembled 3D printer, with a recent print of a &#8216;Dalek&#8217; from Doctor Who.</figcaption></figure></div>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-text-color has-cyan-bluish-gray-color"><em>Updated: 24th May 2019 &#8211; Reformatted post</em></p>
]]></content:encoded>
					
					<wfw:commentRss>https://wired.chillibasket.com/2016/06/my-3d-printer/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Putting it all together!</title>
		<link>https://wired.chillibasket.com/2015/10/putting-it-all-together/</link>
					<comments>https://wired.chillibasket.com/2015/10/putting-it-all-together/#comments</comments>
		
		<dc:creator><![CDATA[Simon Bluett]]></dc:creator>
		<pubDate>Thu, 08 Oct 2015 00:11:37 +0000</pubDate>
				<category><![CDATA[Self-balancing]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Accelerometer]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Balancing]]></category>
		<category><![CDATA[MPU6050]]></category>
		<category><![CDATA[Stabilisation]]></category>
		<guid isPermaLink="false">http://wired.chillibasket.com/?p=299</guid>

					<description><![CDATA[Up until now we have looked at all of the individual&#160;topics behind self-balancing robots. In this final part of the tutorial, I&#8217;ll bring it all together and&#160;give you some guidelines to designing and assembling your own robot! Designing the&#160;Robot Weight Distribution: Self-balancing robots work on the principle of an inverted pendulum. This means that the [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="384" src="https://wired.chillibasket.com/wp-content/uploads/2015/10/Self-balancing-Part-5-1024x384.jpg" alt="" class="wp-image-345" srcset="https://wired.chillibasket.com/wp-content/uploads/2015/10/Self-balancing-Part-5-1024x384.jpg 1024w, https://wired.chillibasket.com/wp-content/uploads/2015/10/Self-balancing-Part-5-300x113.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2015/10/Self-balancing-Part-5.jpg 1200w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Up until now we have looked at all of the individual&nbsp;topics behind self-balancing robots. In this final part of the tutorial, I&#8217;ll bring it all together and&nbsp;give you some guidelines to designing and assembling your own robot!</p>



<hr class="wp-block-separator"/>



<h2 class="wp-block-heading">Designing the&nbsp;Robot</h2>



<p><em><strong>Weight Distribution:</strong></em> Self-balancing robots work on the principle of an inverted pendulum. This means that the system is most stable when all of the mass is positioned as high as possible. This seems to go against common sense; usually systems are more stable when they have a low centre of gravity. In this case keeping the mass on top increases the inertia of the system, meaning that the robot has more time to&nbsp;respond to changes in balance. Therefore my first recommendation is to place the heaviest objects, such as the battery, at the top of the robot.</p>



<p><em><strong>Sensor Positioning:&nbsp;</strong></em>The positioning of the accelerometer/gyroscope module is also important. When I was demonstrating&nbsp;my balancing robot at the Dublin Maker Faire this year, I asked a number of people where they think the sensor should be positioned. Most guessed that it should be on top, as this is where it would record&nbsp;the largest amount of&nbsp;movement!</p>



<p>We actually want to avoid as much of this translational movement as possible, as we are only interested in the rotation of the robot.&nbsp;Therefore the sensor should be placed exactly on the axis of rotation, between both wheels. Placing the sensor&nbsp;further up on the frame introduces noise and jitter into the readings, and may cause a feedback loop (similar to the squeaking noise made when a microphone is too close to its own speaker).</p>



<p><em><strong>Frame Design:&nbsp;</strong></em>For the rest of the frame, it is up to your own imagination what you want to do with it. I&#8217;ve included&nbsp;a couple of pictures and sketches below to help you come up with your own designs. Although I 3D printed two of my frames, I made my first&nbsp;prototype out of lollipop sticks (and it worked really well)!</p>



<div class="wp-block-dgwt-justified-gallery">
<a href='https://wired.chillibasket.com/2015/10/putting-it-all-together/lollipop-balancer/'><img loading="lazy" decoding="async" width="210" height="300" src="https://wired.chillibasket.com/wp-content/uploads/2015/10/Lollipop-Balancer-210x300.jpg" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2015/10/Lollipop-Balancer-210x300.jpg 210w, https://wired.chillibasket.com/wp-content/uploads/2015/10/Lollipop-Balancer.jpg 699w" sizes="auto, (max-width: 210px) 100vw, 210px" /></a>
<a href='https://wired.chillibasket.com/2015/10/putting-it-all-together/gen1-balancer/'><img loading="lazy" decoding="async" width="183" height="300" src="https://wired.chillibasket.com/wp-content/uploads/2015/10/Gen1-Balancer-183x300.jpg" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2015/10/Gen1-Balancer-183x300.jpg 183w, https://wired.chillibasket.com/wp-content/uploads/2015/10/Gen1-Balancer.jpg 610w" sizes="auto, (max-width: 183px) 100vw, 183px" /></a>
<a href='https://wired.chillibasket.com/2015/10/putting-it-all-together/gen2-balancer/'><img loading="lazy" decoding="async" width="222" height="300" src="https://wired.chillibasket.com/wp-content/uploads/2015/10/Gen2-Balancer-222x300.jpg" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2015/10/Gen2-Balancer-222x300.jpg 222w, https://wired.chillibasket.com/wp-content/uploads/2015/10/Gen2-Balancer.jpg 667w" sizes="auto, (max-width: 222px) 100vw, 222px" /></a>
<a href='https://wired.chillibasket.com/2015/10/putting-it-all-together/balancerdiagram1/'><img loading="lazy" decoding="async" width="300" height="177" src="https://wired.chillibasket.com/wp-content/uploads/2015/10/BalancerDiagram1-300x177.jpg" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2015/10/BalancerDiagram1-300x177.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2015/10/BalancerDiagram1.jpg 700w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>
</div>



<div style="height:60px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Assembling the Frame</h2>



<p>Putting together the frame and&nbsp;electronics is actually the easiest part of the project! Once you have your frame designed and ready to go, all you have to do is stick/screw all of the components together. Here is a schematic I made to help you with the wiring of the robot:</p>



<div class="wp-block-dgwt-justified-gallery">
<a href='https://wired.chillibasket.com/2015/10/putting-it-all-together/overal-assembly-diagram/'><img loading="lazy" decoding="async" width="279" height="300" src="https://wired.chillibasket.com/wp-content/uploads/2015/09/overal-assembly-diagram-279x300.jpg" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2015/09/overal-assembly-diagram-279x300.jpg 279w, https://wired.chillibasket.com/wp-content/uploads/2015/09/overal-assembly-diagram.jpg 744w" sizes="auto, (max-width: 279px) 100vw, 279px" /></a>
<a href='https://wired.chillibasket.com/2015/10/putting-it-all-together/balancing-schematic-1/'><img loading="lazy" decoding="async" width="300" height="199" src="https://wired.chillibasket.com/wp-content/uploads/2015/10/balancing-schematic-1-300x199.jpg" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2015/10/balancing-schematic-1-300x199.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2015/10/balancing-schematic-1-1024x681.jpg 1024w, https://wired.chillibasket.com/wp-content/uploads/2015/10/balancing-schematic-1.jpg 1250w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>
<a href='https://wired.chillibasket.com/2015/10/putting-it-all-together/balancing-schematic-2/'><img loading="lazy" decoding="async" width="300" height="258" src="https://wired.chillibasket.com/wp-content/uploads/2015/10/balancing-schematic-2-300x258.jpg" class="attachment-medium size-medium" alt="" srcset="https://wired.chillibasket.com/wp-content/uploads/2015/10/balancing-schematic-2-300x258.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2015/10/balancing-schematic-2.jpg 1000w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>
</div>



<div style="height:60px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Combined Program</h2>



<p>In the previous parts of the tutorial I included snippets of code to show you how each part of the self-balancing robot should work. Here I have compiled all of the parts together into one code that you can use and modify for your own robot. I included a horrendous amount of comments, so that the program is as easy to follow as possible!</p>



<p><em>Note: This code is programmed for the specific components I was using, such as an Arduino motor shield, and the MPU6050 Accel-Gyro module.</em></p>



<pre class="wp-block-code language-cpp code-700 line-numbers"><code>/* * * * * * * * * * * * * * * * * * * * * *
 * SELF-BALANCING ROBOT
 * =========================================
 *
 * Code by: Simon Bluett
 * Email: hello@chillibasket.com
 * Website: wired.chillibasket.com
 *
 * 7/10/15, Version 2.0
 *
 * Here are some hints when you try to use this code:
 *
 *  &gt; Ensure pin-mapping is correct for your robot (line 54)
 *  &gt; Ensure calibration values are correct for your sensor (line 181)
 *  &gt; Uncomment (line 700) in order to see if your sensor is working
 *  &gt; Play with your PID values on (line 93)
 *  &gt; Ensure that your left &amp; right motors aren&#039;t inverted (line 355)
 *  &gt; Confirm whether you want the Pitch ypr&#091;1] or Roll ypr&#091;2] sensor readings!
 * * * * * * * * * * * * * * * * * * * * * */


/* * * * * * * * * * * * * * * * * * * * * *
 *  This Demo makes use of the I2Cdev and MPU6050 libraries, and the demonstration
 *  sketch written by (Jeff Rowberg &lt;jeff@rowberg.net&gt;), modified to work
 *  with the Intel Galileo Development Board:
 *  -- -- -- -- -- -- -- -- -- -- -- -- -- --
 *  I2Cdev device library code is placed under the MIT license
 *  Copyright (c) 2012 Jeff Rowberg
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the &quot;Software&quot;), to deal
 *  in the Software without restriction, including without limitation the rights
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 * * * * * * * * * * * * * * * * * * * * * */



// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
// for both classes must be in the include path of your project
#include &lt;I2Cdev.h&gt;
#include &lt;MPU6050_6Axis_MotionApps20.h&gt;
#include &lt;Wire.h&gt;

// Specific I2C addresses may be passed as a parameter here
MPU6050 mpu;        			// Default: AD0 low = 0x68


// Define the pin-mapping
// -- -- -- -- -- -- -- -- -- -- -- -- -- --
#define DIR_A 12                // Direction Pin, Motor A
#define DIR_B 13                // Direction Pin, Motor B
#define PWM_A 3                 // PWM, Motor A (Left Motor)
#define PWM_B 11                // PWM, Motor B (Right Motor)
#define BRK_A 9                 // Brake, Motor A
#define BRK_B 8                 // Brake, Motor B

#define BTN_1 10                 // On/Off Button
#define BTN_2 7                 // Set Centre of Gravity Button

#define LED_1 5                 // Low-battery Warning LED
#define LED_2 4                // Current mode LED


// Max PWM parameters
#define MAX_TURN 30


// MPU Control/Status
// -- -- -- -- -- -- -- -- -- -- -- -- -- --
bool dmpReady = false;         	// Set true if DMP init was successful
uint8_t devStatus;              // Return status after device operation (0 = success, !0 = error)
uint8_t mpuIntStatus;           // Holds actual interrupt status byte from MPU
uint16_t packetSize;            // Expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;             // Count of all bytes currently in FIFO
uint8_t fifoBuffer&#091;64];         // FIFO storage buffer


// Orientation/Motion
// -- -- -- -- -- -- -- -- -- -- -- -- -- --
Quaternion q;                   // &#091;w, x, y, z]       Quaternion Container
VectorFloat gravity;           	// &#091;x, y, z]            Gravity Vector
int16_t gyro&#091;3];               	// &#091;x, y, z]            Gyro Vector
float ypr&#091;3];                   // &#091;yaw, pitch, roll]   Yaw/Pitch/Roll &amp; gravity vector
float averagepitch&#091;50];        	// Used for averaging pitch value


// For PID Controller
// -- -- -- -- -- -- -- -- -- -- -- -- -- --
float Kp = 8;                   // (P)roportional Tuning Parameter
float Ki = 2;					// (I)ntegral Tuning Parameter        
float Kd = 5;					// (D)erivative Tuning Parameter       
float lastpitch;                // Keeps track of error over time
float iTerm;              		// Used to accumulate error (integral)
float targetAngle = 2.1;       	// Can be adjusted according to centre of gravity 

// You can Turn off YAW control, by setting
// the Tp and Td constants below to 0.
float Tp = 0.6;        			// Yaw Proportional Tuning Parameter
float Td = 0.1;					// Yaw Derivative Tuning Parameter
float targetYaw = 0;            // Used to maintain the robot&#039;s yaw
float lastYawError = 0;

float PIDGain = 0;				// Used for soft start (prevent jerking at initiation)


// Motor Control
// -- -- -- -- -- -- -- -- -- -- -- -- -- --
int direction_A = 0;            // 0 - Forwards, 1 - Backwards
int direction_B = 0;            //
int brake_A = 1;                // 1 - On, 0 - Off
int brake_B = 1;                //


// Runtime variables
// -- -- -- -- -- -- -- -- -- -- -- -- -- --
int modeSelect = 1;             // System Mode (0 = off, 1 = normal, 2 = guided)
bool initialised = true;        // Is the balancing system on?

char inchar = 0;                // Hold any incoming characters
float angular_rate = 0;         // Used to make sure rate is ~0 when balance mode is initiated

bool newCalibration = false;	// If set TRUE, the target angles are recalibrated


// Variables used for timing control
// Aim is 10ms per cycle (100Hz)
// -- -- -- -- -- -- -- -- -- -- -- -- -- --
#define STD_LOOP_TIME 9

unsigned long loopStartTime = 0;
unsigned long lastTime;             // Time since PID was called last (should be ~10ms)

// 0 = Off, 1 = On
int modes = 0;



// ------------------------------------------------------------------
// 					      INITIAL SETUP
// ------------------------------------------------------------------

void setup() {

    Wire.begin();

    // Initialize serial communication for debugging
    Serial.begin(115200);
	
	 // Configure LED for output
    pinMode(LED_1, OUTPUT);
    pinMode(LED_2, OUTPUT);

    digitalWrite(LED_1, LOW);
    digitalWrite(LED_2, LOW);

    // Set as input, internal pullup for buttons
    pinMode(BTN_1, INPUT_PULLUP);
    pinMode(BTN_2, INPUT_PULLUP);

    // Configure Motor I/O
    pinMode(DIR_A, OUTPUT);     // Left Motor Direction
    pinMode(DIR_B, OUTPUT);     // Right Motor Direction
    pinMode(BRK_A, OUTPUT);     // Left Motor Brake
    pinMode(BRK_B, OUTPUT);     // Right Motor Brake

    // Initialize MPU6050
    mpu.initialize();
    Serial.println(&quot;Testing MPU connection:&quot;);

    Serial.println(mpu.testConnection() ? &quot;&gt; MPU6050 connection successful&quot; : &quot;&gt; MPU6050 connection failed&quot;);
    Serial.println(&quot;Initialising DMP&quot;);
    devStatus = mpu.dmpInitialize();

    /* * * * * * * * * * * * * * * * * * * *
     * IMPORTANT!
     * Supply your own MPU6050 offsets here
     * Otherwise robot will not balance properly.
     * * * * * * * * * * * * * * * * * * * */
    mpu.setXGyroOffset(93);
    mpu.setYGyroOffset(-15);
    mpu.setZGyroOffset(30);
    mpu.setXAccelOffset(-2500);
    mpu.setYAccelOffset(1783);
    mpu.setZAccelOffset(877);

    // Make sure it worked (returns 0 if so)
    if (devStatus == 0) {
        Serial.println(&quot;Enabling DMP&quot;);
        mpu.setDMPEnabled(true);
        mpuIntStatus = mpu.getIntStatus();

        // Set our DMP Ready flag so the main loop() function knows it&#039;s okay to use it
        Serial.println(&quot;DMP Ready! Let&#039;s Proceed.&quot;);
        Serial.println(&quot;Robot is now ready to balance. Hold the robot steady&quot;);
        Serial.println(&quot;in a vertical position, and the motors should start.&quot;);
        dmpReady = true;
        packetSize = mpu.dmpGetFIFOPacketSize();

    } else {
		// In case of an error with the DMP
        if(devStatus == 1) Serial.println(&quot;&gt; Initial Memory Load Failed&quot;);
        else if (devStatus == 2) Serial.println(&quot;&gt; DMP Configuration Updates Failed&quot;);
    }

}



// -------------------------------------------------------------------
// 			 PID CONTROLLER
// -------------------------------------------------------------------

int PID(float pitch) {            

    // Calculate time since last time PID was called (~10ms)
    // -- -- -- -- -- -- -- -- -- -- -- -- -- --
    unsigned long thisTime = millis();
    float timeChange = float(thisTime - lastTime);

    // Calculate Error
    float error = targetAngle - pitch;


    // Calculate our PID terms
    // PID values are multiplied/divided by 10 in order to allow the
    // constants to be numbers between 0-10.
    // -- -- -- -- -- -- -- -- -- -- -- -- -- --
    float pTerm = Kp * error * 10;
    iTerm += Ki * error * timeChange / 10;  
    float dTerm = Kd * (pitch - lastpitch) / timeChange * 100; 
	
	if (Ki == 0) iTerm = 0;
    lastpitch = pitch;
    lastTime = thisTime;


    // Obtain PID output value
    // -- -- -- -- -- -- -- -- -- -- -- -- -- --
    float PIDValue = pTerm + iTerm - dTerm;

    // Set a minimum speed (motors will not move below this - can help to reduce latency)
    //if(PIDValue &gt; 0) PIDValue = PIDValue + 10;
    //if(PIDValue &lt; 0) PIDValue = PIDValue - 10;

	// Limit PID value to maximum PWM values
    if (PIDValue &gt; 255) PIDValue = 255;
    else if (PIDValue &lt; -255) PIDValue = -255; 

    return int(PIDValue);

}



// -------------------------------------------------------------------
// 			 YAW CONTROLLER
// -------------------------------------------------------------------

int yawPD(int yawError) {            


    // Calculate our PD terms
    // -- -- -- -- -- -- -- -- -- -- -- -- -- --
    float pTerm = Tp * yawError;
    float dTerm = Td * (yawError - lastYawError) / 10; 
	
    lastYawError = yawError;

    // Obtain PD output value
    // -- -- -- -- -- -- -- -- -- -- -- -- -- --
    int yawPDvalue = int(-pTerm + dTerm);

	// Limit PD value to maximum
    if (yawPDvalue &gt; MAX_TURN) yawPDvalue = MAX_TURN;
    else if (yawPDvalue &lt; -MAX_TURN) yawPDvalue = -MAX_TURN; 

    //Serial.print(&quot;Error: &quot;);
    //Serial.print(yawError);
    //Serial.print(&quot; - PD: &quot;);
    //Serial.println(yawPDvalue);
    return yawPDvalue;

}



// -------------------------------------------------------------------
// 			 	MOVEMENT CONTROLLER
// -------------------------------------------------------------------
// This function calculate the PWM output required to keep the robot 
// balanced, to move it back and forth, and to control the yaw.

void MoveControl(int pidValue, float yaw){
	
    // Set both motors to this speed
    int left_PWM = pidValue;
    int right_PWM = pidValue;


    /* YAW CONTROLLER */

    // Check if turning left or right is faster
    // -- -- -- -- -- -- -- -- -- -- -- -- -- --
    int leftTurn, rightTurn;

    float newYaw = targetYaw;

    if((yaw &gt; 0) &amp;&amp; (newYaw &lt; 0)){
        rightTurn = yaw + abs(newYaw);
        leftTurn = (180 - yaw) + (180 - abs(newYaw));

    } else if ((yaw &lt; 0) &amp;&amp; (newYaw &gt; 0)){
        rightTurn = (180 - abs(yaw)) + (180 - newYaw);
        leftTurn = abs(yaw) + newYaw;

    } else if (((yaw &gt; 0) &amp;&amp; (newYaw &gt; 0)) || ((yaw &lt; 0) &amp;&amp; (newYaw &lt; 0))){
        rightTurn = newYaw - yaw;

        if (rightTurn &gt; 0){
            leftTurn = rightTurn;
            rightTurn = 360 - leftTurn;
        } else if (rightTurn &lt; 0){
            rightTurn = abs(rightTurn);
            leftTurn = 360 - abs(rightTurn);
        } else if (rightTurn == 0){
            rightTurn = leftTurn = 0;
        }
    }

    // Apply yaw PD controller to motor output
    // -- -- -- -- -- -- -- -- -- -- -- -- -- --
    if ((leftTurn == 0) &amp;&amp; (rightTurn == 0)){
        // Do nothing
    } else if (leftTurn &lt;= rightTurn){
    	leftTurn = yawPD(leftTurn);
        left_PWM = left_PWM - leftTurn;
        right_PWM = right_PWM + leftTurn;

    } else if (rightTurn &lt; leftTurn){
        rightTurn = yawPD(rightTurn);
        left_PWM = left_PWM + rightTurn;
        right_PWM = right_PWM - rightTurn;
        
    }


    // Limits PID to max motor speed
    // -- -- -- -- -- -- -- -- -- -- -- -- -- --
    if (left_PWM &gt; 255) left_PWM = 255;
    else if (left_PWM &lt; -255) left_PWM = -255; 
    if (right_PWM &gt; 255) right_PWM = 255;
    else if (right_PWM &lt; -255) right_PWM = -255; 

    // Send command to left motor
    if (left_PWM &gt;= 0) Move(0, 0, int(left_PWM));   	// &#039;0&#039; = Left-motor, &#039;1&#039; = Right-motor
    else Move(0, 1, (int(left_PWM) * -1));
	// Send command to right motor
    if (right_PWM &gt;= 0) Move(1, 1, int(right_PWM)); 	// &#039;0&#039; = Forward, &#039;1&#039; = Backward
    else Move(1, 0, (int(right_PWM) * -1));    

}



// -------------------------------------------------------------------
// 			 MOTOR CONTROLLER
// -------------------------------------------------------------------

void Move(int motor, int direction, int speed) {            

	// Left Motor
	// -- -- -- -- -- -- -- -- -- -- -- -- -- --
	if (motor == 0){
	
		// Set motor direction (only if it is currently not that direction)
		if (direction == 0){
            if (direction_A == 1) digitalWrite(DIR_A, HIGH);		// Forwards
			direction_A = 0;
		} else {
			if (direction_A == 0)  digitalWrite(DIR_A, LOW);		// Backwards
			direction_A = 1;
		}
        
		// Release brake (only if brake is active)
		if (brake_A == 1){
			digitalWrite(BRK_A, LOW);
			brake_A = 0;
		}
		
		// Send PWM data to motor A
		analogWrite(PWM_A, speed);


    // Right Motor
	// -- -- -- -- -- -- -- -- -- -- -- -- -- --
    } else if (motor == 1){
	
		// Set motor direction (only if it is currently not that direction)
		if (direction == 0){
			if (direction_B == 1) digitalWrite(DIR_B, HIGH);		// Forwards
			direction_B = 0;
		} else {
			if (direction_B == 0)  digitalWrite(DIR_B, LOW);		// Backwards
			direction_B = 1;
		}
        
		// Release brake (only if brake is active)
		if (brake_B == 1){
			digitalWrite(BRK_B, LOW);
			brake_B = 0;
		}
		
		// Send PWM data to motor A
		analogWrite(PWM_B, speed);


    // Stop both motors
	// -- -- -- -- -- -- -- -- -- -- -- -- -- --
    } else if (motor = 3){  

        analogWrite(PWM_A, 0);
        analogWrite(PWM_B, 0);
        digitalWrite(BRK_A, HIGH);
        digitalWrite(BRK_B, HIGH);
        brake_A = 1;
        brake_B = 1;

    }
}



// -------------------------------------------------------------------
// 			 READ INPUT FROM SERIAL
// -------------------------------------------------------------------

void readSerial() {

    // Initiate all of the variables
    // -- -- -- -- -- -- -- -- -- -- -- -- -- --
	int changestate = 0;		// Which action needs to be taken?
	int no_before = 0;			// Numbers before decimal point
	int no_after = 0;			// Numbers after decimal point
	bool minus = false;			// See if number is negative
	inchar = Serial.read();		// Read incoming data

    if (inchar == &#039;P&#039;) changestate = 1;
    else if (inchar == &#039;I&#039;) changestate = 2;
    else if (inchar == &#039;D&#039;) changestate = 3;

    // Tell robot to calibrate the Centre of Gravity
    else if (inchar == &#039;G&#039;) calibrateTargets();


    // Records all of the incoming data (format: 00.000)
    // And converts the chars into a float number
    if (changestate &gt; 0){
        if (Serial.available() &gt; 0){

            // Is the number negative?
            inchar = Serial.read();
            if(inchar == &#039;-&#039;){
                minus = true;
                inchar = Serial.read();
            }
            no_before = inchar - &#039;0&#039;;

            if (Serial.available() &gt; 0){
                inchar = Serial.read();

                if (inchar != &#039;.&#039;){
                    no_before = (no_before * 10) + (inchar - &#039;0&#039;);

                    if (Serial.available() &gt; 0){
                        inchar = Serial.read();
                    }
                }

                if (inchar == &#039;.&#039;){
                    inchar = Serial.read();
                    if (inchar != &#039;0&#039;){
                        no_after = (inchar - &#039;0&#039;) * 100;
                    }

                    if (Serial.available() &gt; 0){
                        inchar = Serial.read();
                        if (inchar != &#039;0&#039;){
                            no_after = no_after + ((inchar - &#039;0&#039;) * 10);
                        }

                        if (Serial.available() &gt; 0){
                            inchar = Serial.read();
                            if (inchar != &#039;0&#039;){
                                no_after = no_after + (inchar - &#039;0&#039;);
                            }
                        }
                    }
                }
            }

            // Combine the chars into a single float
            float answer = float(no_after) / 1000;
            answer = answer + no_before;
            if (minus) answer = answer * -1;

            // Update the PID constants
            if (changestate == 1){
                Kp = answer;
                Serial.print(&quot;P - &quot;);
            } else if (changestate == 2){
                Ki = answer;
                Serial.print(&quot;I - &quot;);
            } else if (changestate == 3){ 
                Kd = answer;
                Serial.print(&quot;D - &quot;);
            }
            Serial.print(&quot;Constant Set: &quot;);
            Serial.println(answer, 3);

        } else {
            changestate = 0;
        }
    }
}



// -------------------------------------------------------------------
// 			 RECALIBRATE TARGET VALUES
// -------------------------------------------------------------------
// Takes a number of readings and gets new values for the target angles.
// Robot must be held upright while this process is being completed.

void calibrateTargets(){

	targetAngle = 0;
	targetYaw = 0;
	
    for(int calibrator = 0; calibrator &lt; 50; calibrator++){
	
		accelgyroData();
		targetAngle += pitch();
		targetYaw += yaw();
		delay(10);
	}
	
	// Set our new value for Pitch and Yaw
	targetAngle = targetAngle / 50;
	targetYaw = targetYaw / 50;
	Serial.print(&quot;Target Pitch: &quot;);
	Serial.print(targetAngle, 3);
	Serial.print(&quot;, Target Yaw: &quot;);
	Serial.print(targetYaw, 3);

	newCalibration = false;
}



// -------------------------------------------------------------------
// 			 GET PITCH AND YAW VALUES
// -------------------------------------------------------------------
// This simply converts the values from the accel-gyro arrays into degrees.

float pitch(){
	return (ypr&#091;1] * 180/M_PI);
}

float yaw(){
	return (ypr&#091;0] * 180/M_PI);
}

float angRate(){
	return -((float)gyro&#091;1]/131.0);
}



// -------------------------------------------------------------------
// 			 GET ACCEL_GYRO DATA
// -------------------------------------------------------------------

void accelgyroData(){

    // Reset interrupt flag and get INT_STATUS byte
    mpuIntStatus = mpu.getIntStatus();

    // Get current FIFO count
    fifoCount = mpu.getFIFOCount();

    // Check for overflow (this should never happen unless our code is too inefficient)
    if ((mpuIntStatus &amp; 0x10) || fifoCount == 1024) {
        // Reset so we can continue cleanly
        mpu.resetFIFO();
        Serial.println(&quot;Warning - FIFO Overflowing!&quot;);

    // otherwise, check for DMP data ready interrupt (this should happen exactly once per loop: 100Hz)
    } else if (mpuIntStatus &amp; 0x02) {
        // Wait for correct available data length, should be less than 1-2ms, if any!
        while (fifoCount &lt; packetSize) fifoCount = mpu.getFIFOCount();


        // read a packet from FIFO
        mpu.getFIFOBytes(fifoBuffer, packetSize);
        
        // track FIFO count here in case there is &gt; 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount -= packetSize;

        // Get sensor data
        mpu.dmpGetQuaternion(&amp;q, fifoBuffer);
        mpu.dmpGetGyro(gyro, fifoBuffer);
        mpu.dmpGetGravity(&amp;gravity, &amp;q);
        mpu.dmpGetYawPitchRoll(ypr, &amp;q, &amp;gravity);
        mpu.resetFIFO();

        //Serial.print(ypr&#091;1]);
        //Serial.print(&quot; - &quot;);
        //Serial.println(ypr&#091;0]);
    }
}



// -------------------------------------------------------------------
// 			 MAIN PROGRAM LOOP
// -------------------------------------------------------------------

void loop() {

	// If the &quot;SET&quot; button is pressed
	// -- -- -- -- -- -- -- -- -- -- -- -- -- --
	if (digitalRead(BTN_2) == LOW){

		digitalWrite(LED_1, HIGH);
	    calibrateTargets();

	    lastpitch = 0;
	    iTerm = 0;

	    Serial.println(&quot;&gt; Setting new centre of gravity &lt;&quot;);

		delay(250);
	    mpu.resetFIFO();
	    digitalWrite(LED_1, LOW);
	}


	// If the &quot;POWER&quot; button is pressed
	// -- -- -- -- -- -- -- -- -- -- -- -- -- --
	if (digitalRead(BTN_1) == LOW){
	    if (modeSelect == 1){
	        Serial.println(&quot;&gt; Turning off balancing system &lt;&quot;);
	        initialised = false;
	        modeSelect = 0;
	        Move(3,0,0);        // Stop both motors from moving
	        digitalWrite(LED_2, LOW);
	    } else if (modeSelect == 0){
	        Serial.println(&quot;&gt; Turning on balancing system &lt;&quot;);
	        initialised = false;
	        modeSelect = 1;
	        digitalWrite(LED_2, HIGH);
	    }
	    delay(500);
	    mpu.resetFIFO();
	}
		
	// Gather data from MPU6050
	accelgyroData();
		
	// If the Balance System is turned on:
	if (modeSelect == 1){
				
		if (!initialised){

	        // Wait until robot is vertical and angular rate is almost zero:
	        if ((pitch() &lt; targetAngle+0.1) &amp;&amp; (pitch() &gt; targetAngle-0.1) &amp;&amp; (abs(angRate()) &lt; 0.3)){
	            Serial.println(&quot;&gt;&gt;&gt;&gt; Balancing System Active &lt;&lt;&lt;&lt;&quot;);
	            initialised = true;
	            lastpitch = pitch();
	            iTerm = 0;
	        }
	
	    // Otherwise, run the PID controller
		} else {

			// Stop the system if it has fallen over:
			if ((pitch() &lt; -45) || (pitch() &gt; 45)){
					
				// Stop the motors
				Move(3, 0, 0);
				// Reset runtime variables
				lastpitch = 0;
				iTerm = 0;
				initialised = false;
				Serial.println(&quot;&gt;&gt;&gt;&gt; Balancing System Stopped &lt;&lt;&lt;&lt;&quot;);

			} else {
				// A bit of function-ception happening here:
				//Serial.println(pitch());
				MoveControl(PID(pitch()), yaw());
			}
		}
	}

    if (Serial.available() &gt; 0){    // If new PID values are being sent by the interface
        readSerial();               // Run the read serial method
    }

    // Call the timing function
    // Very important to keep the response time consistent!
    timekeeper();
}



// -------------------------------------------------------------------
// 			 	TIME KEEPER
// -------------------------------------------------------------------

void timekeeper() {

    // Calculate time since loop began
    float timeChange = millis() - loopStartTime;

    // If the required loop time has not been reached, please wait!

    if (timeChange &lt; STD_LOOP_TIME) {
        delay(STD_LOOP_TIME - timeChange);
    } 


    // Update loop timer variables
    loopStartTime = millis();   
}</code></pre>



<p>Here is a breakdown of how to use this code with your robot:</p>



<ol class="wp-block-list"><li>Before starting the program, connect the board via USB to your computer, and open a terminal window in the Arduino software (baud rate: 115200).</li><li><strong>Wait until robot is ready:</strong> At the start the robot automatically initialises the MPU6050 module. Once this is done, the following message should appear:<br><code>DMP Ready! Let&#039;s Proceed.</code></li><li><strong>Set Centre of Gravity:</strong> You should set the centre of gravity of the robot, so that the robot knows which way is up! Do this by steadily holding the robot upright, with the wheels off the floor, and pressing the button connected to GPIO-4. The LED on GPIO-2 will flash, and the following message should appear: <br><code>&gt; Setting new centre of gravity &lt;</code></li><li><strong>Automatic On/Off:</strong> The motors of the robot automatically turn off if the robot has fallen over, or is lying on its side. To turn them back on, hold the robot steadily in an upright position. The motors should start and the following message appear:<br><code>&gt;&gt;&gt;&gt; Balancing System Active &lt;&lt;&lt;&lt;</code><br>If the robot has fallen over and motors are off, this message appears:<br><code>&gt;&gt;&gt;&gt; Balancing System Stopped&nbsp;&lt;&lt;&lt;&lt;</code></li><li><strong>Manual On/Off:</strong> To manually turn the balancing system on/off, press the button connected to GPIO-7. The LED on GPIO-10 will be bright, if the balancing system is turned on. One of the following messages will appear to let you know which state the robot is in:<br><code>&gt; Turning off balancing system &lt;</code><br><code>&gt; Turning on balancing system &lt;</code></li><li><strong>Sending new PID values:</strong>&nbsp;Please read my guide <a href="https://wired.chillibasket.com/2015/03/pid-controller/">The PID Controller</a>, to see how to calibrate your robot. You can send new PID values via the console&nbsp;window, by typing the letter of the constant (P, I or D) you want to set, followed by the number you want to set it at. Then press the enter/return&nbsp;key to send. The code accepts any numbers between&nbsp;0.01 &#8211; 99.99. For example:<br><code>P8.2&nbsp;I1.51 D15</code><br>This sets the [P]roportional Constant to 8.2, the [I]ntegral Constant to 1.51, and the [D]erivative Constant to 15.</li></ol>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Dealing with Common Errors</h2>



<p>I have found that most of the common errors can be dealt with by checking the following:</p>



<ol class="wp-block-list"><li><strong>Check the Pin Mapping:</strong> Make sure that the GPIO number on (lines 54-65) match up with the ones you are using on your robot.</li><li><strong>Update the MPU-6050 Offsets:</strong>&nbsp;Each sensor has unique offset values, which have to be inputted on (lines 183-188). I explain how to find these offsets in my &#8220;<a href="https://wired.chillibasket.com/2015/01/calibrating-mpu6050/">Calibrating &amp; Optimising the MPU6050</a>&#8221; part of this tutorial.</li><li><strong>Ensure sensor is working properly:</strong> Check that the MPU-6050 is working, by uncommenting (line 704) of my code. While running, the robot should display the current angle on the console. When held upright, the angle should be 0. When pitching forwards/backwards, the number should be positive/negative in degrees.</li><li><strong>Both motors should spin in same direction:</strong> Set the turning constants on (lines 102-103) to zero. Now both motors should spin in same direction. If not, then one of the motors is wired backwards.</li><li><strong>Motors balance in wrong direction:</strong> Instead of stopping the robot from falling, the motors speed up the fall. This means that both motors are wired in backwards!</li></ol>



<hr class="wp-block-separator"/>



<p>This finally concludes my tutorial about self-balancing robots! If you have any questions or suggestions, please leave a comment below.</p>



<p class="has-text-color has-cyan-bluish-gray-color"><em>Updated: 23rd May 2019 &#8211; Reformatted post</em></p>
]]></content:encoded>
					
					<wfw:commentRss>https://wired.chillibasket.com/2015/10/putting-it-all-together/feed/</wfw:commentRss>
			<slash:comments>65</slash:comments>
		
		
			</item>
		<item>
		<title>The PID Controller</title>
		<link>https://wired.chillibasket.com/2015/03/pid-controller/</link>
					<comments>https://wired.chillibasket.com/2015/03/pid-controller/#comments</comments>
		
		<dc:creator><![CDATA[Simon Bluett]]></dc:creator>
		<pubDate>Mon, 16 Mar 2015 13:51:50 +0000</pubDate>
				<category><![CDATA[Self-balancing]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Accelerometer]]></category>
		<category><![CDATA[Galileo]]></category>
		<category><![CDATA[Gen2]]></category>
		<category><![CDATA[Gyroscope]]></category>
		<category><![CDATA[MPU6050]]></category>
		<category><![CDATA[Stabilisation]]></category>
		<guid isPermaLink="false">http://wired.chillibasket.com/?p=254</guid>

					<description><![CDATA[The most important element of any robot is the controller. The control algorithm determines how the robot should react to different sensor inputs, allowing it to intelligently adapt to and interact with its environment. Especially for a self-balancing robot, the control program is vital as it interprets the motion sensor data and decides how much [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="384" src="https://wired.chillibasket.com/wp-content/uploads/2015/03/Self-balancing-Part-4-1024x384.jpg" alt="" class="wp-image-267" srcset="https://wired.chillibasket.com/wp-content/uploads/2015/03/Self-balancing-Part-4-1024x384.jpg 1024w, https://wired.chillibasket.com/wp-content/uploads/2015/03/Self-balancing-Part-4-300x113.jpg 300w, https://wired.chillibasket.com/wp-content/uploads/2015/03/Self-balancing-Part-4.jpg 1200w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>The most important element of any robot is the controller. The control algorithm determines how the robot should react to different sensor inputs, allowing it to intelligently adapt to and interact with its environment. Especially for a self-balancing robot, the control program is vital as it interprets the motion sensor data and decides how much the motors need to be moved in order for the robot to remain stable and upright. The most common controller used for stabilisation systems is the PID controller. So let&#8217;s look at how it works&#8230;</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading">The PID Controller</h2>



<p>PID stands for <strong>P</strong>roportional, <strong>I</strong>ntegral and <strong>D</strong>erivative, referring to the mathematical equations used to calculate the output of the controller. This is perhaps the most common type of controller used in industry, as it is able to control relatively complex systems even though the calculations are actually quite straightforward (making it easy to program and fast to compute). Mathematically, the PID controller can be described by the following formula:</p>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>u(t)=K_pe(t) + K_i\int_{0}^{t}e(t)dt +K_d\frac{de(t)}{dt}</pre></div>



<p>In this formula, the output of the controller <em>u(t)</em> is determined by the sum of three different elements, each dependent on the error <em>e(t)</em>. The error simply is the difference between the target value and the current value (measured by the sensor). Now let&#8217;s quickly look at what each of the terms in the equation is doing for our robot&#8230;</p>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>K_pe(t)</pre></div>



<p>This is the proportional component, which takes the current error value and multiplies it by a constant number (<em>Kp</em>). For our self-balancing robot, this simply takes in the current angle of the robot and makes the motors move in the same direction as the robot is falling. The further the robot falls off target, the faster the motors move. If the P-component is used on its own, the robot might stabilise for a while, but the system will tend to overshoot, oscillate and ultimately fall over.</p>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>K_i\int_0^te(t)dt</pre></div>



<p>The integral component is used to accumulate any errors over time, and multiplies this accumulated value by a constant number (<em>Ki</em>). For example if the robot tends to fall over to one side, it knows that it needs to move in the opposite direction in order to keep on target and to prevent&nbsp;drifting left or right.</p>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>K_d\frac{de(t)}{dt}</pre></div>



<p>Finally, the derivative component is responsible for dampening any oscillations and ensures that the robot does not overshoot the target value. Each time the controller is called, this term calculates the change in the error value and multiplies it by a constant number (<em>Kd</em>). Often this is simplified to calculate only the change in the current sensor value, rather than the change in error. If the target position remains constant, this gives the same result. This simplification helps to prevent sudden jumps in the output value which happen when the target position it changed.</p>



<p>Summing all three of these terms together then gives us an output value which we can send to the motor of the self-balancing robot. However, before the controller can successfully balance the robot, the three constants (<em>Kp</em>), (<em>Ki</em>) and (<em>Kd</em>) need to be tuned to suit our specific application. By increasing or decreasing the values of these constants, we control how much each of the three components of the controller contributes to the output of the system. </p>



<p>The formula I used above is called the &#8220;Independent&#8221; PID equation. If you read up on the PID controller online, you may also see the formula for the algorithm expressed in a different format (known as the &#8220;Dependent&#8221; PID equation):</p>



<div class="wp-block-katex-display-block katex-eq" data-katex-display="true"><pre>u(t) = K_ce(t)+\frac{K_c}{T_i}\int_0^te(t)dt + K_cT_d\frac{de(t)}{dt}</pre></div>



<p>The term (<em>Kc</em>) is known as controller gain, (<em>Ti</em>) the integral time and (<em>Td</em>) the derivative time. This format can be useful when using some automated tuning techniques, however the final result is the same.</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="900" height="432" src="https://wired.chillibasket.com/wp-content/uploads/2015/03/pid-diagram-e1443473603418.jpg" alt="" class="wp-image-312"/><figcaption>Diagram of PID controller being used on a self-balancing robot.</figcaption></figure>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="striped-heading wp-block-heading">Implementing the Controller</h2>



<p>Now that we know the basic theory, we can start to write this in code. The basic layout of the function is shown below. The controller can be used by calling the &#8220;pid&#8221; function at regular intervals, providing the target position and the current position (as recorded by the sensor) as parameters of the function. The function then outputs the calculated result of the controller. Tuning of the controller can be done by changing the values of the (<em>Kp</em>), (<em>Ki</em>) and (<em>Kd</em>) variables at the top of the code.</p>



<pre class="wp-block-code line-numbers language-cpp"><code>// Declare variables
float Kp = 7;          // (P)roportional Tuning Parameter
float Ki = 6;          // (I)ntegral Tuning Parameter        
float Kd = 3;          // (D)erivative Tuning Parameter       
float iTerm = 0;       // Used to accumulate error (integral)
float lastTime = 0;    // Records the time the function was last called
float maxPID = 255;    // The maximum value that can be output
float oldValue = 0;    // The last sensor value

/**
 * PID Controller
 * @param  (target)  The target position/value we are aiming for
 * @param  (current) The current value, as recorded by the sensor
 * @return The output of the controller
 */
float pid(float target, float current) {
	// Calculate the time since function was last called
	float thisTime = millis();
	float dT = thisTime - lastTime;
	lastTime = thisTime;

	// Calculate error between target and current values
	float error = target - current;

	// Calculate the integral term
	iTerm += error * dT; 

	// Calculate the derivative term (using the simplification)
	float dTerm = (oldValue - current) / dT;

	// Set old variable to equal new ones
	oldValue = current;

	// Multiply each term by its constant, and add it all up
	float result = (error * Kp) + (iTerm * Ki) + (dTerm * Kd);

	// Limit PID value to maximum values
	if (result &gt; maxPID) result = maxPID;
	else if (result &lt; -maxPID) result = -maxPID;

	return result;
}</code></pre>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="underline-heading wp-block-heading">What does this program do?</h4>



<p>First of all, the algorithm calculates the time since the last loop was called, using the &#8220;millis()&#8221; function. The error is then calculated; this is the difference between the current value (the angle recorded by the sensor), and the target value (the angle of  0 degrees we are aiming to reach).</p>



<p>The PID values are then calculated and summed up to give an output for the motors. The output is then constrained to ±255 as this is the maximum PWM value that can be output to the motors of the self-balancing robot.</p>



<p>Although this program is almost complete, I found that my robot only worked well once I included a timing function. This is a system that ensures the PID controller function is called at regular intervals. In my self-balancing robot, I set the loop time to be 10ms (meaning the function is run 100 times per second). Here is the timer code and a sample loop function:</p>



<pre class="wp-block-code line-numbers language-cpp"><code>// Any variables for the PID controller go here!
float targetValue = 0;

// Variables for Time Keeper function:
#define LOOP_TIME 10          // Time in ms (10ms = 100Hz)
unsigned long timerValue = 0;

/******** SETUP ************/
void setup() {
	// Put all of your setup code here
	timerValue = millis();
}

/******* MAIN LOOP *********/
void loop() {
	// Only run the controller once the time interval has passed
	if (millis() - timerValue &gt; LOOP_TIME) {
		timerValue = millis();

		// Replace getAngle() with your sensor data reading
		float currentValue = getAngle();

		// Run the PID controller
		float motorOutput = pid(targetValue, currentValue);

		// Replace moveMotors() with your desired output
		moveMotors(motorOutput);
	}
}

/****** PID CONTROLLER *****/
float pid(float target, float current) {          

	// PID code from above goes in here!
	return result;
}</code></pre>



<p>Unfortunately this is not the end of the story! Although the PID controller code is complete, suitable&nbsp;PID constants still need to be found to tune the controller for your specific robot. These constants depend on things such as weight, motor speed and the shape of the robot, and therefore they can vary significantly from robot to robot. Here is a quick explanation of how you should go about calibrating your PID values:</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="underline-heading wp-block-heading">Calibrating your PID Controller</h4>



<ol class="wp-block-list"><li>Create some way in which you can change the PID constant of your robot while it is running.&nbsp;One option is to&nbsp;use a potentiometer or some other analogue input to be able to increase or decrease the PID constant. I personally used the USB connection and the serial monitor to send new PID values. This is important as you can then see straight away how well the new PID values are working, and you won&#8217;t have to re-upload the code hundreds of times!</li><li><strong>Set all PID constants to zero.</strong> This is as good a place to start as any&#8230;</li><li><strong>Slowly increase the P-constant value.</strong> While you are doing this, hold the robot to make sure it doesn&#8217;t fall over and smash into a million pieces! You should increase the P-constant until the robot responds quickly to any tilting, and then <em>just</em> makes the robot overshoot in the other direction.</li><li><strong>Now increase the I-constant.</strong> This component is a bit tricky to get right. You should keep this relatively low, as it can accumulate errors very quickly. In theory, the robot should be able to stabilise with only the P and I constants set, but will oscillate a lot and ultimately fall over.</li><li><strong>Raise&nbsp;the D-constant. A lot.&nbsp;</strong>The derivative components works against any motion, so it helps to dampen any oscillations and reduce overshooting. I found that this constant has to be set significantly higher than the other two (x10 to x100 more) in order to have any effect. All the same, don&#8217;t set it too high, as it will reduce the robot&#8217;s ability to react to external forces (aka. being pushed around).</li><li><strong>Spend many fruitless hours slightly modifying the PID values.</strong> This is probably the longest part of the procedure, as there isn&#8217;t much of a method to it. You just have to increase and decrease the values until you reach that perfect sweet-spot for your robot!</li></ol>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<hr>



<p>Please leave a comment below if you have any questions or suggestions. </p>



<div class="wp-block-buttons aligncenter is-layout-flex wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-outline is-style-outline--3"><a class="wp-block-button__link no-border-radius" href="https://wired.chillibasket.com/2015/10/putting-it-all-together/"><em>Part 5:</em> Putting it all together</a></div>
</div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-cyan-bluish-gray-color has-text-color"><em><strong>Updated: </strong>23rd May 2019 &#8211; Reformatted post and improved the code snippets. </em></p>



<p class="has-cyan-bluish-gray-color has-text-color"><em><strong>Updated: </strong>1st June 2020 &#8211; Add PID equations and improved the descriptions.</em></p>
]]></content:encoded>
					
					<wfw:commentRss>https://wired.chillibasket.com/2015/03/pid-controller/feed/</wfw:commentRss>
			<slash:comments>14</slash:comments>
		
		
			</item>
	</channel>
</rss>
