<?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>Keith&#039;s Electronics Blog &#187; Arduino</title>
	<atom:link href="http://www.neufeld.newton.ks.us/electronics/?cat=9&#038;feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.neufeld.newton.ks.us/electronics</link>
	<description></description>
	<lastBuildDate>Fri, 18 Apr 2025 00:10:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>ESP-WROOM-32 with ST7789 LCD (Wiring, Adafruit_GFX and Adafruit_ST77* Libraries, and Arduino Code)</title>
		<link>http://www.neufeld.newton.ks.us/electronics/?p=2400</link>
		<comments>http://www.neufeld.newton.ks.us/electronics/?p=2400#comments</comments>
		<pubDate>Fri, 18 Apr 2025 00:10:55 +0000</pubDate>
		<dc:creator>Keith Neufeld</dc:creator>
				<category><![CDATA[Arduino]]></category>

		<guid isPermaLink="false">http://www.neufeld.newton.ks.us/electronics/?p=2400</guid>
		<description><![CDATA[I&#8217;m wanting to play with a medium-resolution LCD screen attached to something that I can program from the Arduino IDE and I happen to have some &#8220;AITRIP&#8221;-branded ESP-WROOM-32 modules on hand. Connecting an ST7789-driven LCD to one of them involved filling in a number of gaps in the documentation I was able to find, so [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m wanting to play with a medium-resolution LCD screen attached to something that I can program from the Arduino IDE and I happen to have some &#8220;AITRIP&#8221;-branded ESP-WROOM-32 modules on hand.  Connecting an ST7789-driven LCD to one of them involved filling in a number of gaps in the documentation I was able to find, so let me write it all down in one place in case it&#8217;s useful to someone else, including Future Keith.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/17/IMG_20250417_184837_0648.jpg"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/17/IMG_20250417_184837_0648_mid.jpg" alt="ESP-WROOM-32 driving Waveshare 2.0-inch LCD" /></a></p>
<p>The LCD I bought is a <a href="https://www.waveshare.com/wiki/2inch_LCD_Module">Waveshare 2.0&#8243; LCD</a> using an ST7789V driver chip, a variant of a popular (<em>the</em> popular?) LCD driver.</p>
<p><span id="more-2400"></span></p>
<h3>Wiring</h3>
<p>The first puzzle was how to wire the LCD to the ESP32.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/17/AITRIP_ESP-WROOM-32_pinouts.jpg"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/17/AITRIP_ESP-WROOM-32_pinouts.jpg" alt="AITRIP ESP-WROOM-32 module pinouts" /></a></p>
<p>Different ESP32 module manufacturers provide different module pin counts and I suspect (though haven&#8217;t verified) different pinouts for the same pin counts; so I&#8217;m specifically referencing the pinouts for the module I&#8217;m using.</p>
<p>I found a couple of forum posts &#8212; unfortunately didn&#8217;t save the links &#8212; indicating that the LCD can run on 5V or 3.3V power and that it gets grumpy if the data lines are at a different voltage than its power.  This is easily handled &#8212; power the LCD from the ESP32&#8242;s 3.3V regulator.  So first wire the power connections:</p>
<table border=1 cellspacing=0 cellpadding=5>
<tr>
<th>LCD Pin</th>
<th>ESP32 Pin</th>
<th>Signal</th>
</tr>
<tr>
<td>VCC</td>
<td>VDD 3V3</td>
<td>3.3V regulated power</td>
</tr>
<tr>
<td>GND</td>
<td>GND</td>
<td>ground</td>
</tr>
</table>
<p>Next, the LCD uses SPI, so wire the data and clock lines.  The ESP32 has labeled pins for these so I used them; though I saw a forum post that the ESP32&#8242;s hardware SPI can be matrixed to any digital I/O pin, so it&#8217;s possible that these could be reassigned elsewhere.</p>
<table border=1 cellspacing=0 cellpadding=5>
<tr>
<th>LCD Pin</th>
<th>ESP32 Pin</th>
<th>Signal</th>
</tr>
<tr>
<td>DIN</td>
<td>VSPI MOSI aka GPIO 23</td>
<td>SPI master out / slave in aka <br/> PICO (peripheral in / controller out)</td>
</tr>
<tr>
<td>CLK</td>
<td>VSPI SCK aka GPIO 18</td>
<td>SPI clock</td>
</tr>
</table>
<p>Then three LCD pins can be wired to any available I/O, so I picked pins near the others I was already using:</p>
<table border=1 cellspacing=0 cellpadding=5>
<tr>
<th>LCD Pin</th>
<th>ESP32 Pin</th>
<th>Signal</th>
</tr>
<tr>
<td>CS</td>
<td>GPIO 1</td>
<td>SPI chip select</td>
</tr>
<tr>
<td>DC</td>
<td>GPIO 3</td>
<td>LCD data / command select</td>
</tr>
<tr>
<td>RST</td>
<td>GPIO 21</td>
<td>LCD module reset</td>
</tr>
</table>
<p>And finally the backlight enable pin, which <a href="https://files.waveshare.com/upload/e/ee/2inch_LCD_Module_SchDoc.pdf">the schematic</a> shows is pulled high / active so is superfluous unless you want to blank or PWM the backlight:</p>
<table border=1 cellspacing=0 cellpadding=5>
<tr>
<th>LCD Pin</th>
<th>ESP32 Pin</th>
<th>Signal</th>
</tr>
<tr>
<td>BL</td>
<td>GPIO 17</td>
<td>backlight control (active high)</td>
</tr>
</table>
<h3>Arduino Libraries</h3>
<p>Waveshare provides their own ST7789 and LCD graphics libraries but I overlooked those, so for what seemed like expedience I loaded the <a href="https://github.com/adafruit/Adafruit-ST7735-Library">Adafruit ST77* library</a> and <a href="https://github.com/adafruit/Adafruit-GFX-Library">Adafruit GFX library</a>.</p>
<p>I could not find, in <a href="https://cdn-learn.adafruit.com/downloads/pdf/adafruit-gfx-graphics-library.pdf">the documentation</a> or <a href="https://learn.adafruit.com/adafruit-1-44-color-tft-with-micro-sd-socket/wiring-and-test">tutorials</a>, the syntax for some fundamentals &#8212; to wit, I didn&#8217;t find documentation stating the syntax to instantiate a display object, nor documentation of (the correct) syntax to initialize the display object.  (I ran across what in retrospect incidentally sort of demonstrated these; but I would like documentation to expressly tell me how to use what I&#8217;m trying to use.)</p>
<p>The libraries come with example code and by examining <code>Examples from Custom Libraries</code> / <code>Adafruit ST7735 and ST7789 Library</code> / <code>graphicstest_st7789</code>, and with the help of <a href="https://forum.arduino.cc/t/esp32-wroom-32d-with-ic-st7789-tft/1343907/5">a forum post</a>, I was able first to get the graphics demo to run on my display and second to write my own code.</p>
<p>The library needs to know where things got wired up:</p>
<p><code>#define TFT_CS (1)    //  yellow wire<br />
#define TFT_RST (21)  //  brown wire<br />
#define TFT_DC (3)    //  blue wire<br />
</code></p>
<p>Then to be initialized with the right dimensions for this LCD:</p>
<p> <code>  // OR use this initializer (uncomment) if using a 2.0" 320x240 TFT:<br />
  tft.init(240, 320);           // Init ST7789 320x240<br />
</code></p>
<p>And then the demo works.</p>
<h3>My Demo</h3>
<p>Putting it all together into my own test:</p>
<p><code>#include &lt;Adafruit_GFX.h&gt;<br />
#include &lt;Adafruit_ST7789.h&gt;</p>
<p>#define TFT_CS (1)    //  yellow wire<br />
#define TFT_RST (21)  //  brown wire<br />
#define TFT_DC (3)    //  blue wire</p>
<p>#define PIN_BACKLIGHT (17)  //  grey wire</p>
<p>Adafruit_ST7789 mylcd = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);</p>
<p>void setup() {<br />
  pinMode(PIN_BACKLIGHT, OUTPUT);<br />
  digitalWrite(PIN_BACKLIGHT, HIGH);</p>
<p>  mylcd.init(240, 320);<br />
  mylcd.setRotation(1);<br />
  mylcd.fillScreen(ST77XX_BLACK);</p>
<p>  //mylcd.drawLine(0, 0, 25, 25, 65535);</p>
<p>  mylcd.setCursor(0, 0);<br />
  mylcd.setTextColor(65535);<br />
  mylcd.setTextSize(3);<br />
  mylcd.print("hello, world");<br />
}</p>
<p>void loop() {<br />
}<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.neufeld.newton.ks.us/electronics/?feed=rss2&#038;p=2400</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ESP32 Modules in Breadboards</title>
		<link>http://www.neufeld.newton.ks.us/electronics/?p=2394</link>
		<comments>http://www.neufeld.newton.ks.us/electronics/?p=2394#comments</comments>
		<pubDate>Mon, 14 Apr 2025 22:56:08 +0000</pubDate>
		<dc:creator>Keith Neufeld</dc:creator>
				<category><![CDATA[Arduino]]></category>

		<guid isPermaLink="false">http://www.neufeld.newton.ks.us/electronics/?p=2394</guid>
		<description><![CDATA[A frequently-heard refrain is that ESP32 modules are so inconvenient because with their 1.0&#8243; spacing between header rows, in the standard installation, their footprint covers all but one horizontal row of holes on a breadboard; and kids these days like using fly-wire-style breadboard jumpers rather than trace-style breadboard jumpers (which would work underneath it). This [...]]]></description>
			<content:encoded><![CDATA[<p>A frequently-heard refrain is that ESP32 modules are so inconvenient because with their 1.0&#8243; spacing between header rows, in the standard installation, their footprint covers all but one horizontal row of holes on a breadboard; and kids these days like using fly-wire-style breadboard jumpers rather than trace-style breadboard jumpers (which would work underneath it).</p>
<p>This should be regarded as irritating rather than intractable.  I present here two workarounds and leave the discovery of more as an exercise for the reader.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/14/IMG_20250414_173039_0627_crop.jpg"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/14/IMG_20250414_173039_0627_crop_mid.jpg" alt="ESP32 module installed on modular breadboard system" /></a></p>
<p>Option 1, remove one power-strip row from a modular breadboard and dovetail-pin that breadboard onto another.  Install the ESP module over the new &#8220;power gutter&#8221; and revel in the luxury of plenty of rows for connecting jumpers.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/14/IMG_20250414_173931_0636_crop.jpg"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/14/IMG_20250414_173931_0636_crop_mid.jpg" alt="ESP32 module installed on modified breadboard system" /></a></p>
<p>Option 2, SAW THROUGH THAT and revel in the luxury of plenty of rows for connecting jumpers.</p>
<p>Footnote:  Use a hacksaw.  Its finer teeth cut without snagging like a wood-cutting saw&#8217;s teeth would do; I don&#8217;t want to contemplate the kind of workholding it would take for me to feel safe using a tablesaw or circular saw on this; and you would be so startled the moment a wood-cutting bandsaw&#8217;s teeth first engage in the edge of the plastic and the blade leaps toward you.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.neufeld.newton.ks.us/electronics/?feed=rss2&#038;p=2394</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ESP32-WROOM-32 in Arduino IDE</title>
		<link>http://www.neufeld.newton.ks.us/electronics/?p=2380</link>
		<comments>http://www.neufeld.newton.ks.us/electronics/?p=2380#comments</comments>
		<pubDate>Mon, 14 Apr 2025 20:13:11 +0000</pubDate>
		<dc:creator>Keith Neufeld</dc:creator>
				<category><![CDATA[Arduino]]></category>

		<guid isPermaLink="false">http://www.neufeld.newton.ks.us/electronics/?p=2380</guid>
		<description><![CDATA[Back in 2021 I documented the process of installing and selecting support for a particular ESP8266 into the Arduino IDE, in case it would help anyone else and as a reference for the next time I needed to do it myself. Well, here I am back again doing the same to bootstrap myself on the [...]]]></description>
			<content:encoded><![CDATA[<p>Back in 2021 I <a href="/?p=1919">documented the process of installing and selecting support for a particular ESP8266 into the Arduino IDE</a>, in case it would help anyone else and as a reference for the next time I needed to do it myself.  Well, here I am back again doing the same to bootstrap myself on the ESP-WROOM-32 aka ESP32-WROOM-32.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/14/IMG_20250414_171256_0612_crop.jpg"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/14/IMG_20250414_171256_0612_crop_mid.jpg" alt="ESP-WROOM-32 board" /></a></p>
<p>My refresher on the basics came from <a href="https://samueladesola.medium.com/how-to-set-up-esp32-wroom-32-b2100060470c">https://samueladesola.medium.com/how-to-set-up-esp32-wroom-32-b2100060470c</a>, although he had to go through some steps I didn&#8217;t and vice-versa.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/14/Arduino-board-manager-Espressif-URL.png"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/14/Arduino-board-manager-Espressif-URL.png" alt="Adding Espressif URL to Arduino IDE board manager list" /></a></p>
<p>First, go to <code>File</code> / <code>Preferences</code> / <code>Additional boards manager URLs</code> and add<br />
<code>https://dl.espressif.com/dl/package_esp32_index.json</code> to indicate another repository to search for board definitions.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/14/Arduino-board-manager-add-boards.png"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/14/Arduino-board-manager-add-boards.png" alt="Arduino IDE board manager" /></a></p>
<p>Then <code>Tools</code> / <code>Board</code> / <code>Boards Manager...</code> to pick an available board bundle, start typing <code>esp32</code>, and click to install <code>esp32 by Espressif Systems</code> .</p>
<p>I&#8217;m installing this on my Linux workstation so I had to give myself permission to access the USB port, which was:</p>
<p><code>sudo usermod -aG dialout neufeld</code></p>
<p>To make that group change take effect, I was only supposed to need to logout; but doing so added me to the entry in <code>/etc/group</code> but didn&#8217;t activate the group membership when I ran <code>id</code> or tried to access the device file.  I had an OS update to apply anyway so I rebooted and all was well.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/14/Arduino-ESP32-board-selection.png"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/14/Arduino-ESP32-board-selection.png" alt="Picking ESP32 Dev Module from Arduino IDE board selection list" /></a></p>
<p>Back in the Arduino IDE, <code>Select Other Board and Port</code>, start typing <code>esp32 dev</code> into the board search, and pick <code>ESP32 Dev Module</code> when it popped up.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/14/Arduino-board-selection-not-found.png"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/14/Arduino-board-selection-not-found.png" alt="Arduino IDE board selection list with nothing picked" /></a></p>
<p>Weirdly, even with the USB serial port selected (and accessible), it complains that no boards were found &#8212; but it works.</p>
<p>Finally, <code>File</code> / <code>Examples</code> / <code>01.Basics</code> / <code>Blink</code> to make sure I can compile and upload code to the correct board.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/14/Arduino-blink-define-LEDBUILTIN.png"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2025/04/14/Arduino-blink-define-LEDBUILTIN.png" alt="Defining LED_BUILTIN for Arduino Blink sketch on board that doesn't define it" /></a></p>
<p>Blink relies on an LED_BUILTIN macro that&#8217;s not defined in this Espressif board spec.  <a href="https://forum.arduino.cc/t/esp-32-wroom-32-pin-allocation/1228704">This forum post</a> suggested pin 2 for the built-in LED on this board and adding</p>
<p><code>#define LED_BUILTIN (2)</code></p>
<p>did the trick.  Compile, upload, and I have a blinking blue LED next to the red power LED.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.neufeld.newton.ks.us/electronics/?feed=rss2&#038;p=2380</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting Started with D-duino-Clone ESP8266 and SSD1306 0.96&#8243; OLED Module</title>
		<link>http://www.neufeld.newton.ks.us/electronics/?p=1919</link>
		<comments>http://www.neufeld.newton.ks.us/electronics/?p=1919#comments</comments>
		<pubDate>Fri, 06 Aug 2021 15:49:11 +0000</pubDate>
		<dc:creator>Keith Neufeld</dc:creator>
				<category><![CDATA[Arduino]]></category>

		<guid isPermaLink="false">http://www.neufeld.newton.ks.us/electronics/?p=1919</guid>
		<description><![CDATA[I&#8217;ve been interested in the ESP8266 for a long time; and way back in 2017 when I first learned that support had been added to program them with the Arduino IDE, I ordered this totes adorbs little guy, who&#8217;s been patiently waiting for me until today. In the process of figuring out how to program [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2021/08/06/IMG_20210806_095628_DSC01415.jpg"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2021/08/06/IMG_20210806_095628_DSC01415_mid.jpg" alt="D-duino clone ESP8266 and SSD1306 OLED module" /></a></p>
<p>I&#8217;ve been interested in the ESP8266 for a long time; and way back in 2017 when <em>I</em> first learned that support had been added to program them with the Arduino IDE, I ordered this totes adorbs little guy, who&#8217;s been patiently waiting for me until today.  In the process of figuring out how to program it, I learned that it&#8217;s a clone of the <a href="https://www.tindie.com/products/lspoplove/d-duino-v2arduinonodemcuesp8266096oled/">D-duino</a>.</p>
<p>I find the ESP8266 market space very confusing, with lots of boards and lots of assumptions that you already know what you&#8217;re doing.  It took me a fair bit of searching and fiddling to get this working.  In case you&#8217;re in the same boat I was until yesterday and want to try this yourself, here is <a href="https://www.amazon.com/dp/B08RS1CX1B/">one currently-available product</a> [no affiliation] that I expect will be identical to mine.  You may find others; and/or you may not even need this walkthrough, both of which are perfectly fine.</p>
<p><span id="more-1919"></span></p>
<p>The first step in programming it was figuring out what board the Arduino IDE needed to identify it as.  Sparing the missteps along the way, my board has no useful identification but the current Amazon listing (which I found only for your benefit, Dear Reader, because the listing from which I made my purchase has long since expired) shows the names &#8220;WeMos&#8221; and &#8220;D-duino&#8221; on the back side of the board.  That combination took me to this <a href="http://www.esp8266learning.com/d-duino-wemos-actually-neither.php">ESP8266 Learning page</a> discussing a cloned board like mine that they had bought.</p>
<p>It didn&#8217;t tell me much about the D-duino; but seeing that the name was a Real Thing led me to the creator&#8217;s <a href="https://www.tindie.com/products/lspoplove/d-duino-v2arduinonodemcuesp8266096oled/">Tindie page announcing the D-duino</a> and subsequent <a href="https://hackaday.io/project/19922-how-to-start-with-d-duinod-duino-bx-8266">Hackaday article on how to use it</a>.  That latter is pure gold, providing the OLED-related steps below.  For completeness, here also is the <a href="https://github.com/lspoplove/D-duino">project&#8217;s/product&#8217;s GitHub page</a>.</p>
<p>First, tell the Arduino IDE about ESP8266es in general.  Per the  <a href="https://github.com/esp8266/Arduino/blob/master/README.md">ESP8266 Arduino support page</a>, &#8220;enter <code>https://arduino.esp8266.com/stable/package_esp8266com_index.json</code> into the File>Preferences>Additional Boards Manager URLs field of the Arduino IDE,&#8221; then go into Tools / Board: / Boards Manager&#8230; and search for and install the esp8266 boards bundle.  Now use Tools / Board: / ESP8266 Boards > to select the <code>NodeMCU 1.0 (ESP-12E Module)</code>.</p>
<p>At this point, I was able to upload the File / Examples > / 01.Basics > / Blink sketch and get the Comforting Blue LED of Reassurance.</p>
<p>Next, install the OLED driver.  Per the Hackaday article, go to the <a href="https://github.com/ThingPulse/esp8266-oled-ssd1306">GitHub esp8266-oled-ssd1306 page</a>, use the Code button to download the ZIP file, find your Sketchbook location from your Arduino preferences, and unzip the SSD1306 OLED library in the Library folder under your Sketchbook location.</p>
<p>Exit and restart your Arduino environment to pick up the library changes if necessary and you should now find D-duino example code under File / Examples > / Examples from Custom Libraries / ESP8266 and ESP32 OLED driver for SSD1306 displays.</p>
<p>I started with SSD1306SimpleDemo and &#8230; got nothing on the display.  After trying several of the code variations mentioned in the Hackaday article, I found that this one works on my module:</p>
<p><code>SSD1306Wire display(0x3c, D1, D2);<br />
</code></p>
<p>That is, the I2C SDA and SCL pins don&#8217;t appear to be correctly autopopulated for this board, so they need to be set manually to D1 and D2.</p>
<p>And voila!  I had a working attract-mode program again, the same as when I received the module and before I started trying to program it.</p>
<p>Skinnying that program down to the basics for displaying text yields the following code (that WordPress does not wish to indent) and the photograph at the top.  This lays a great foundation for doing something useful with the device!</p>
<p><code><br />
// Include the correct display library</p>
<p>// For a connection via I2C using the Arduino Wire include:<br />
#include &lt;Wire.h&gt;               // Only needed for Arduino 1.6.5 and earlier<br />
#include "SSD1306Wire.h"        // legacy: #include "SSD1306.h"</p>
<p>// Initialize the OLED display using Arduino Wire:<br />
SSD1306Wire display(0x3c, D1, D2);   // ADDRESS, SDA, SCL</p>
<p>void setup() {<br />
  // Initialising the UI will init the display too.<br />
  display.init();</p>
<p>  display.flipScreenVertically();<br />
}</p>
<p>void loop() {<br />
  // clear the display<br />
  display.clear();</p>
<p>  display.setTextAlignment(TEXT_ALIGN_LEFT);<br />
  display.setFont(ArialMT_Plain_16);<br />
  display.drawString(0, 0, "hello, pliers");</p>
<p>  // write the buffer to the display<br />
  display.display();</p>
<p>  delay(1000);<br />
}<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.neufeld.newton.ks.us/electronics/?feed=rss2&#038;p=1919</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AMPduino [from 2011 Draft]</title>
		<link>http://www.neufeld.newton.ks.us/electronics/?p=1425</link>
		<comments>http://www.neufeld.newton.ks.us/electronics/?p=1425#comments</comments>
		<pubDate>Fri, 22 Jun 2018 19:23:01 +0000</pubDate>
		<dc:creator>Keith Neufeld</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[Salvage]]></category>

		<guid isPermaLink="false">http://www.neufeld.newton.ks.us/electronics/?p=1425</guid>
		<description><![CDATA[Another unpublished post dredged out of the distant past &#8212; this one apparently complete. Soon after I got my friend Cort hooked on the Arduino, he said he wished he could easily carry it to the office to play with over lunch, to the tire shop to work on while he waited, etc. I offered [...]]]></description>
			<content:encoded><![CDATA[<p><em>Another unpublished post dredged out of the distant past &#8212; this one apparently complete.</em></p>
<p>Soon after I got my friend Cort hooked on the Arduino, he said he wished he could easily carry it to the office to play with over lunch, to the tire shop to work on while he waited, etc.  I offered him <a href="?p=245">three-ring binders and boxed cases</a>, but that wasn&#8217;t quite what he was looking for.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2011/06/21/IMG956959.jpg"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2011/06/21/IMG956959_mid.jpg" alt="AMPduino case" /></a></p>
<p>After some discussion, we settled on an empty plastic case from a videocassette.  I visited our Media Resources department, had their video director help me scrounge up a suitably large case (Cort says &#8220;U-Matic 3/4&#8243; helical scan&#8221;), and updated the labeling.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2011/06/21/IMG959414.jpg"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2011/06/21/IMG959414_mid.jpg" alt="AMPduino case, inside" /></a></p>
<p>Cort cut out the spindle posts and then stickied down the Arduino, a couple of breadboards, and some other things useful for prototyping and now does all of his development with the AMPduino.  Handy for the workbench, the kitchen table, and the tire shop.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.neufeld.newton.ks.us/electronics/?feed=rss2&#038;p=1425</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>If All You Have Is a Logic Analyzer, Everything Looks Like a Timing Problem</title>
		<link>http://www.neufeld.newton.ks.us/electronics/?p=1519</link>
		<comments>http://www.neufeld.newton.ks.us/electronics/?p=1519#comments</comments>
		<pubDate>Thu, 28 Jun 2012 02:44:29 +0000</pubDate>
		<dc:creator>Keith Neufeld</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Equipment]]></category>

		<guid isPermaLink="false">http://www.neufeld.newton.ks.us/electronics/?p=1519</guid>
		<description><![CDATA[I just rewrote the Arduino Playground Nokia LCD screen code to use hardware SPI instead of ShiftOut(). (More work to do before releasing the code back to the community. And I know, not everyone will want to use the hardware SPI, but it should be an option.) It looked like a trivial change, but after [...]]]></description>
			<content:encoded><![CDATA[<p>I just rewrote the <a href="http://www.arduino.cc/playground/Code/PCD8544">Arduino Playground Nokia LCD screen code</a> to use hardware SPI instead of <code>ShiftOut()</code>.  (More work to do before releasing the code back to the community.  And I know, not everyone will want to use the hardware SPI, but it should be an option.)</p>
<p>It looked like a trivial change, but after making it, the display&#8217;s screen remained blank.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/27/spi-bad-ss.png"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/27/spi-bad-ss_mid.png" alt="Logic analyzer capture of bad SPI communication" /></a></p>
<p>But &hellip; but &hellip; but &hellip; the slave-select line is supposed to be held low during each byte of transmission.  I know the ATmega&#8217;s SPI hardware doesn&#8217;t manage it for you, but surely the Arduino&#8217;s <code>SPI.transfer()</code> function does, right???</p>
<h3>Working Arduino SPI Transfer</h3>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/27/spi-manual-ss.png"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/27/spi-manual-ss_mid.png" alt="Logic analyzer capture of working SPI communication" /></a></p>
<p>No.  You have to manage it manually.</p>
<p><code>void LcdWrite(byte dc, byte data) {<br />
  digitalWrite(PIN_SS, LOW);<br />
  digitalWrite(PIN_DC, dc);<br />
  SPI.transfer(data);<br />
  digitalWrite(PIN_SS, HIGH);<br />
}</code></p>
<p>SPI support is a <em>perfect</em> candidate to be a real object-oriented class rather than a functional library in OO clothing.  Instantiate objects that know which slave-select pin is theirs, which may have different bit orders and clock rates and clock modes, and provide a <code>transfer()</code> method that sets all the registers, twiddles SS for you, and transfers your byte.</p>
<p>Sigh.</p>
<h3>Faster Arduino SPI Transfer</h3>
<p>BTW, notice on the second capture that manually bouncing SS using two <code>digitalWrite()</code>s <em>takes longer than transferring eight bits of data using the hardware SPI</em>.  Start to understand why I want to transfer data using hardware instead of bit-banging?</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/27/spi-faster-ss.png"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/27/spi-faster-ss_mid.png" alt="Logic analyzer capture of working SPI communication with fast SS manipulation" /></a></p>
<p>Manipulating the SS bit in the port register directly is <em>much</em> faster &hellip; at the cost of being much less clear what&#8217;s going on to non-native speakers of C.</p>
<p><code>void LcdWrite(byte dc, byte data) {<br />
  PORTB &#038;= ~ (1 << 2);<br />
  digitalWrite(PIN_DC, dc);<br />
  SPI.transfer(data);<br />
  PORTB |= (1 << 2);<br />
}</code></p>
<h3>ATmega I/O Pin Hardware Toggling for Fastest Arduino SPI Transfer (That Isn't Any Faster)</h3>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/27/atmega-port-toggle.png"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/27/atmega-port-toggle_mid.png" alt="ATmega I/O pin hardware toggle diagram" /></a></p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/27/spi-fastest-ss.png"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/27/spi-fastest-ss_mid.png" alt="Logic analyzer capture of working SPI communication with fast SS manipulation" /></a></p>
<p>The C-based bit manipulation code above is already fast enough that the timing constraint has moved back to the programmer-selected SPI clocking speed and the ultimate solution -- <a href="http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1282100129">using the ATmega's hardware-based pin toggle feature</a> -- doesn't save any noticeable time, <strike>but the code sure looks cool</strike> <strike>but it's the right thing to do</strike> and it's a risky game to play to assume you always know correctly the logic level of the pin when you enter the function.</p>
<p><code>void LcdWrite(byte dc, byte data) {<br />
  PINB = _BV(PINB2);<br />
  digitalWrite(PIN_DC, dc);<br />
  SPI.transfer(data);<br />
  PINB = _BV(PINB2);<br />
}</code></p>
<p>(BTW, I had a dream recently -- which I did not know was not real -- in which the latest Arduino release added <code>digitalWrite(pin, TOGGLE)</code> to do the above.  Imagine my disappointment tonight to learn it was only a dream.  And no, I'm not the first to suggest that feature, by a long shot.  Just, maybe, the first to think it had actually happened.)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.neufeld.newton.ks.us/electronics/?feed=rss2&#038;p=1519</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Arduino-Compatible &#8220;Practice&#8221;</title>
		<link>http://www.neufeld.newton.ks.us/electronics/?p=1513</link>
		<comments>http://www.neufeld.newton.ks.us/electronics/?p=1513#comments</comments>
		<pubDate>Sun, 24 Jun 2012 21:50:27 +0000</pubDate>
		<dc:creator>Keith Neufeld</dc:creator>
				<category><![CDATA[Arduino]]></category>

		<guid isPermaLink="false">http://www.neufeld.newton.ks.us/electronics/?p=1513</guid>
		<description><![CDATA[I&#8217;m trying to get my LED calculator out the door this summer, and that requires embedding an Arduino-compatible &#8220;core&#8221; into my own system. Yes, yes, I could use a microcontroller without the Arduino environment; but if I actually get this thing ready to sell, I want my customers to be able to reprogram it (apply [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m trying to get my <a href="?p=1145">LED calculator</a> out the door this summer, and that requires embedding an Arduino-compatible &#8220;core&#8221; into my own system.  Yes, yes, I could use a microcontroller without the Arduino environment; but if I actually get this thing ready to sell, I want my customers to be able to reprogram it (apply firmware upgrades <em>or</em> enhance the feature set) in a comfortable environment.  Hence an Arduino-compatible core.</p>
<p>I haven&#8217;t made an Arduino-compatible before, and the only two things I found daunting were the crystal, which I understand has to be exactly matched to its supporting capacitors or the circuit won&#8217;t resonate, so it was important to find the same one used in the Arduino; and the resettable polyfuse on the USB power lines, which doesn&#8217;t (in the Arduino circuit) specify whether 500&nbsp;mA is the hold current or the trip current.</p>
<p>I found an <a href="http://www.arduino.cc/en/Main/StandalonePartList">Arduino playground post by Tom Igoe</a> giving Digi-Key part numbers for a bare-bones breadboard Arduino-compatible and chased the out-of-stock crystal to the equivalent <a href="http://www.digikey.com/product-detail/en/9B-16.000MAAJ-B/887-1019-ND/2118703">Digi-Key catalog number 887-1019-ND</a>.  I searched far and wide for information on the polyfuse and gave up, settling on 500 mA hold current, since that&#8217;s permitted (after negotiation) by the USB spec and surely we wouldn&#8217;t want to trip at the maximum permitted current.</p>
<p>With that data in hand, I still had a healthy dose of uncertainty about my likelihood of building a working Arduino-compatible.  I prefer to develop and test modularly, so I wanted to assemble a working proof-of-concept Arduino-compatible before diving into the LED calculator project.  And as it happens, I had a perfect project waiting in the wings &#8212; an Arduino-compatible board with ground and power headers surrounding the normal I/O headers (like servo connectors), to make it easy to connect external sensors without going all-out and buying a <a href="http://arduino-info.wikispaces.com/SensorShield">sensor shield</a> (which actually has the I/O pin at the end of each connector rather than in the middle, whatever).  I want to build my own version of my friend Trevor&#8217;s <a href="http://progressiveodyssey.blogspot.com/2012/03/updated-home-temperature-system.html">household temperature-monitoring system</a>, and such an Arduino-compatible would be a great platform for terminating the three-wire temperature sensors.</p>
<p>To speed the process, I started with the EAGLE schematic of the <a href="http://www.freeduino.org/freeduino_open_designs.html">Freeduino through-hole design</a>, ripping up the board and laying it out mostly from scratch to make room for my extra header rows.  I had the board produced by BatchPCB, I received it last week, and I have now assembled it into a working Arduino-compatible.</p>
<p>But not &#8212; this is going to sound <em>soooo</em> familiar &#8212; without some snags along the way.</p>
<h3>Testing the FTDI USB-Serial</h3>
<p>The one component not available in a through-hole package was the FTDI USB-serial chip; and I planned on hand-soldering it; and that&#8217;s way easier to do without other components looming over it and getting in the way of the iron; so I attached it first.  And that led me to test it first as well, since I test as I go.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/20/DSCN8895.jpg"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/20/DSCN8895_mid.jpg" alt="Arduino-compatible with USB-serial components installed" /></a></p>
<p><span id="more-1513"></span></p>
<p>This is about the minimal set of components to test the entire operation of the FTDI chip.  Power jumper and lots of bypass capacitors, polyfuse, power LED and current-limiting resistor, transmit and receive LEDs and resistors, and &hellip; yeah, the Arduino&#8217;s digital pin 13 LED is completely unnecessary.</p>
<p>And it worked!  I powered it up first connected only to a powered external USB hub so that if anything was horribly wrong, there was no way it could smoke my computer.  The power LED came on and the transmit and receive LEDs came on and stayed on.  With only the slightest twinge of hesitation, I plugged it into my laptop.  The transmit and receive LEDs went out, ZTerm recognized a new serial port, and I could type into the receive LED to my heart&#8217;s content.</p>
<h3>ATmega and ISP Header</h3>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/24/DSCN8913.JPG"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/24/DSCN8913_mid.jpg" alt="Arduino-compatible with ATmega and USB-serial ICs installed" /></a></p>
<p>The next step was to install the microcontroller and try to in-system program it.  The minimum additions were the ATmega and socket, the crystal and its capacitors, the reset button and pull-up resistor, and the ISP programming header.</p>
<p>I connected my <a href="http://www.ladyada.net/make/usbtinyisp/">USBtinyISP</a>, fired up the Arduino IDE, and tried to burn the bootloader &#8212; and it didn&#8217;t work.  The USBtinyISP thought it had no chip connected.</p>
<p>It was late Wednesday evening and I had to put the board away with the problem unsolved.  I didn&#8217;t yet know whether the problem was with the microcontroller not even running, with the programming port, or somewhere else in the design.</p>
<h3>Troubleshooting In-System Programming</h3>
<p>Thursday night I had a rehearsal so didn&#8217;t get to devote much time to the problem, but I did move the ATmega from a working Arduino into this board and it worked, running the Blink sketch.  I put the ATmega from this board into the working Arduino board and in-system programmed it, and it worked, both there and when I put it back into this board.  That was a relief &#8212; it meant the fundamental design was okay and I had a problem with the programming port.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/03/Freeduino-ISP.png"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/03/Freeduino-ISP_mid.png" alt="Freeduino in-system programming port" /></a></p>
<p>Which is so dead simple, how can it have a problem???  It&#8217;s just traces!</p>
<p>But one of the traces is both the ISP clock line (SCK) and the Arduino-compatible&#8217;s digital pin 13, which has an LED on it, which loads down the ISP clock line &hellip;  I lifted one leg of the current-limiting resistor, but that didn&#8217;t fix it.</p>
<p>I spent Friday evening with friends making (and consuming!) pizza and ice cream, so it was Saturday before I got back to this.  By then I had examined the schematic and board layout over and over again, comparing them to multiple other references for the ISP pinout, not finding any problems; and I knew I had to get more serious.  It was time to learn to use my <a href="http://www.saleae.com/logic">Saleae logic analyzer</a>.</p>
<p>I love the product.  I find the manual not well organized and I got no response to my polite email months ago detailing many, <em>many</em> ways they could make it more clear for me &#8212; such as listing what voltage range is considered logic high.  I love the look of the user interface.  I find manipulating the view and the data clumsy.  I hate learning to use new products and systems when I&#8217;m in the middle of something hard I wish I didn&#8217;t have to do, and I learned anyway.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/23/logic-capture-factory.png"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/23/logic-capture-factory_mid.png" alt="Timing diagram of successful ATmega in-system programming" /></a></p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/23/logic-capture-homemade.png"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/23/logic-capture-homemade_mid.png" alt="Timing diagram of unsuccessful ATmega in-system programming" /></a></p>
<p>I connected the logic analyzer to every pin of the ISP port &#8212; including the 5V power pin, mainly for completeness but partly out of paranoia &#8212; of the working, real Arduino and set the analyzer to trigger on a negative-going edge of the RESET line (or assertion of /RESET, if you wanna be that way).  I captured the beginning of an ISP cycle, then moved the analyzer to the homemade Arduino-compatible and repeated the capture.  You may safely ignore the transitions on SCK before the trigger event (time 0.0) &#8212; the boards are running the Blink code until they get reset to start the programming (attempt), and that&#8217;s the LED pin.</p>
<p>I saw enough differences between these captures that I wasn&#8217;t sure where to begin, so I decided to go to the source:  Atmel&#8217;s application note <a href="www.atmel.com/Images/doc0943.pdf">AVR910P In-System Programming</a>.  I verified the ISP port pinout yet again.  I read about the functions of each pin.  And on page 4, I found this gem:</p>
<blockquote><p>When Reset is applied to the target AVR microcontroller, the MISO pin is set up to be an input with no pull up. Only after the “Programming Enable” command has been correctly transmitted to the target will the target AVR microcontroller set its MISO pin to become an output. During this first time, the In-System programmer will apply its pull up to keep the MISO line stable until it is driven by the target microcontroller.
</p></blockquote>
<p><em>Hang on</em>.  MISO is set to be an input and the ISP will apply a pull-up?  Then why, on my board, is it low the entire time?  It must be shorted to ground.</p>
<p>I grabbed the meter.  MISO was shorted to ground.</p>
<p>AWESOME!  I just have to find the solder splash &hellip; which is unlikely on a commercially-produced board with solder mask &hellip; and there&#8217;s no solder splash.</p>
<p>Okay, I just have to find the design error connecting MISO to ground.  Yeahno, EAGLE absolutely has MISO and GND as separate signals.  And BatchPCB sent me a spare copy of the board, which I checked with a meter, and which did not have MISO shorted to ground.</p>
<p>Okay, I just have to find the manufacturing error shorting MISO to ground.  Many, many minutes with a magnifying glass and I found nothing.</p>
<p>The whole time I&#8217;m thinking about how glad I am it&#8217;s a two-layer board so I don&#8217;t have to be paranoid about a short on an interior layer where I can&#8217;t see it.</p>
<p>Yesterday ended and I went to bed knowing I had a signal shorted to ground and being completely unable to find it.</p>
<p>Today I knew I had to get yet more serious.  Out came the <a href="http://midwestdevices.com/">Capacitor Wizard</a>.</p>
<p>Scoff all you want.  It has saved me countless hours testing capacitors in-circuit, but its utility doesn&#8217;t end there.  It is an exquisitely sensitive ohmmeter and can easily detect the difference in resistance between 1&#8243; and 2&#8243; of copper trace.</p>
<p>I put one probe on the ground plane and tested every point along the MISO path with the other probe.  The short to ground was quite clearly nearest the header at the top of the board.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/24/DSCN8899.jpg"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/24/DSCN8899_mid.jpg" alt="Copper splash across PCB isolation" /></a></p>
<p>Back to the magnifying glass, and knowing where to look, I found this.  (As always, click to see full resolution.)  It looked like a booger in the varnish, but it extended across the isolation between the ground plane and MISO, and it was in the segment of the MISO trace where the Capacitor Wizard said it should be.</p>
<p>I took the board to Ron&#8217;s to use his big magnifying glass to get the pic, and he was convinced the booger wasn&#8217;t in the copper layer and didn&#8217;t want to scratch up my pretty new board finding out, especially after knocking down the surface of the booger with a plastic scratching stick and not getting down to copper.  He even desoldered the microcontroller socket to get a closer look at its pads and the vias under the socket &hellip; finding nothing, of course.</p>
<p>So when he stepped out of the shop for a bit, I cut the MISO trace near the microcontroller to isolate which end of the trace had the short to ground &#8212; and it was the upper end.  Armed with that information, Ron couldn&#8217;t help but capitulate.  I allowed him the honor of scraping away the &#8220;hair&#8221; for me, which quickly revealed itself as copper, and he quickly revealed a few words he knew.  And the short was gone.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/24/DSCN8909.jpg"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/24/DSCN8909_mid.jpg" alt="Arduino-compatible with USBtinyISP" /></a></p>
<p>Ron did a gorgeous, almost invisible job of jumpering over the trace I had cut.  MISO was still not shorted.  I brought the board home and resoldered the socket and MISO was still not shorted.  I tested the ISP.  It now works fine with the digital pin 13 LED out of circuit and it doesn&#8217;t like the load with the LED in circuit.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/24/DSCN8919.jpg"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/24/DSCN8919_mid.jpg" alt="Socketed LED" /></a></p>
<p>No problem.  For my prototype board, I socketed the ancient, power-sucking LED so I can remove it if ever I want to in-system program the board again.  Inside my LED calculator, I probably won&#8217;t put a &#8220;Blink&#8221; LED.  If I want to make a board that does have an LED on digital pin 13, I&#8217;ll buy a modern, high-efficiency LED that I can run with a much higher series resistance, just like the real Arduino does, and not load down the SCK pin so much.</p>
<h3>Sweet, Sweet Success at Last</h3>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/24/DSCN8922.JPG"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2012/06/24/DSCN8922_mid.jpg" alt="Arduino-compatible" /></a></p>
<p>A little more soldering to install the headers and the rest of the components, and that&#8217;s the rest of the story.</p>
<p>Well, almost.</p>
<p>To quote <a href="http://www.sparkfun.com/products/10909">SparkFun forum user FlorinC</a>, talking about an entirely different board,</p>
<blockquote><p>The capacitors look taller than the headers. This will be a problem when a shield is plugged in.</p></blockquote>
<p>&lt;scratches head&gt; Yup.  Ya got me there.  Good thing I built this one specifically to avoid using a shield.</p>
<p>But well noted.  I&#8217;ll use leetle capacitors should I decide to make an Arduino-compatible into which I intend to plug a shield.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.neufeld.newton.ks.us/electronics/?feed=rss2&#038;p=1513</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Monitoring Battery Voltage</title>
		<link>http://www.neufeld.newton.ks.us/electronics/?p=1235</link>
		<comments>http://www.neufeld.newton.ks.us/electronics/?p=1235#comments</comments>
		<pubDate>Sat, 12 Feb 2011 16:16:41 +0000</pubDate>
		<dc:creator>Keith Neufeld</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Circuits]]></category>

		<guid isPermaLink="false">http://www.neufeld.newton.ks.us/electronics/?p=1235</guid>
		<description><![CDATA[Hey, real EE types out there, is there any reason I can&#8217;t monitor 12V battery voltage using a simple voltage divider into an A/D input of a microcontroller that&#8217;s powered by a voltage regulator on that same battery? This seems straightforward, but I ask because there seem to be a lot of fancy circuits and [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2011/02/12/power-circuit.png"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2011/02/12/power-circuit_mid.png" alt="Battery and voltage regulator schematic" /></a></p>
<p>Hey, real EE types out there, is there any reason I can&#8217;t monitor 12V battery voltage using a simple voltage divider into an A/D input of a microcontroller that&#8217;s powered by a voltage regulator on that same battery?</p>
<p>This seems straightforward, but I ask because there seem to be a lot of fancy circuits and devices out there for monitoring supply voltage.  It seems to me they all revolve around monitoring the device&#8217;s own V<sub>CC</sub> and where to get a reliable A<sub>REF</sub> when you don&#8217;t trust your own supply.</p>
<p>In the case of monitoring a battery voltage that will always be much higher than the dropout of the voltage regulator powering the microcontroller which generates its own A<sub>REF</sub>, I can&#8217;t think of any reason to get fancier than this.</p>
<p>I would Just Do It but I don&#8217;t have a good test setup for this and I&#8217;m getting ready to commit it to a board layout.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.neufeld.newton.ks.us/electronics/?feed=rss2&#038;p=1235</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Transistor-Based Variable Current Drive for LED Calculator</title>
		<link>http://www.neufeld.newton.ks.us/electronics/?p=1145</link>
		<comments>http://www.neufeld.newton.ks.us/electronics/?p=1145#comments</comments>
		<pubDate>Mon, 06 Sep 2010 22:20:53 +0000</pubDate>
		<dc:creator>Keith Neufeld</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Circuits]]></category>
		<category><![CDATA[LEDs]]></category>
		<category><![CDATA[Products]]></category>

		<guid isPermaLink="false">http://www.neufeld.newton.ks.us/electronics/?p=1145</guid>
		<description><![CDATA[I&#8217;ve put off working on my LED calculator project for far too long, at first trying to find the right handheld case to put it in and then later hoping to be able to manufacture a case myself. I&#8217;m not having any luck with that right now and if I keep waiting I&#8217;ll wait forever; [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve put off working on my <a href="?p=248">LED calculator project</a> for far too long, at first trying to find the right handheld case to put it in and then later hoping to be able to manufacture a case myself.  I&#8217;m not having any luck with that right now and if I keep waiting I&#8217;ll wait forever; so I&#8217;m resurrecting the project with the intention of selling it as a kit sans case.</p>
<p>The idea is to expand on a simple LED tester by allowing the user to plug in an LED, dial in the LED brightness, and then read information on an LCD showing the LED voltage drop, the current current, and the value of current-limiting resistor to use in a target circuit.</p>
<p>A microcontroller determines this information by <a href="?p=218">measuring the voltage drop across a series current-sense resistor</a> to calculate the current and <a href="?p=218">measuring the voltage drop across the LED</a> to calculate how much voltage will drop across the current-limiting resistor in the target circuit and what that resistor value should be.</p>
<h3>Variable Resistor Drive</h3>
<p><a href="http://www2.neufeld.newton.ks.us/files/electronics/led-calculator/breadboard-noduino.png"><img src="http://www2.neufeld.newton.ks.us/files/electronics/led-calculator/breadboard-noduino.png" alt="LED calculator drive circuit" /></a></p>
<p>Until now, all of my prototyping has used a variable resistor in series with the LED to set the current.  After subtracting the LED&#8217;s forward voltage drop from the supply voltage, the variable resistor dominates the resistance of the remaining series chain (which includes the current-sense resistor), thereby setting the series current.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2010/09/05/DSCN7407.jpg"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2010/09/05/DSCN7407_mid.jpg" alt="LED calculator prototype with direct potentiometer drive" /></a></p>
<p>This does give control over the LED current and brightness, but the problems with this method are:</p>
<ul>
<li>A small-valued potentiometer doesn&#8217;t provide enough resistance to dial down to low enough LED currents.  For example, a 1K pot with the circuit running on 9V won&#8217;t deliver less than 6mA, depending on the LED color (and voltage drop); and modern, high-efficiency LEDs are surprisingly bright at 6mA.</li>
<li>A large-valued potentiometer has an extremely non-linear current response, with all the &#8220;action&#8221; at the very end of its rotation.</li>
</ul>
<p>Here&#8217;s the response of two different LEDs with a 10K potentiometer:</p>
<table align=center border=1 cellspacing=0 cellpadding=5>
<tr>
<th>Position</th>
<th>Green LED Current</th>
<th>Blue LED Current</th>
</tr>
<tr>
<td>0</td>
<td>1mA</td>
<td>1mA</td>
</tr>
<tr>
<td>1</td>
<td>1mA</td>
<td>1mA</td>
</tr>
<tr>
<td>2</td>
<td>1mA</td>
<td>1mA</td>
</tr>
<tr>
<td>3</td>
<td>1mA</td>
<td>1mA</td>
</tr>
<tr>
<td>4</td>
<td>1mA</td>
<td>1mA</td>
</tr>
<tr>
<td>5</td>
<td>2mA</td>
<td>2mA</td>
</tr>
<tr>
<td>6</td>
<td>3mA</td>
<td>2mA</td>
</tr>
<tr>
<td>7</td>
<td>4mA</td>
<td>3mA</td>
</tr>
<tr>
<td>8</td>
<td>5mA</td>
<td>6mA</td>
</tr>
<tr>
<td>9</td>
<td>34mA</td>
<td>21mA</td>
</tr>
<tr>
<td>10</td>
<td>100mA</td>
<td>89mA</td>
</tr>
</table>
<p>Very slow response until near the end of the potentiometer&#8217;s rotation, at which point the response is so rapid that it&#8217;s very difficult to control<br />
And of course this makes sense, as it&#8217;s the hyperbolic curve of I = V/R.</p>
<h3>Transistor Drive</h3>
<p>Last week I started looking at improving the range and linearity of the LED current.  I&#8217;m <em>not</em> looking for a perfectly flat response curve nor for a true constant-current drive; I just want a somewhat better response.  What came to mind was this simple PNP transistor circuit &#8212; actually an even simpler version without R1 and R3, but I&#8217;ll explain their purposes in a bit.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2010/09/06/drive-circuit.png"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2010/09/06/drive-circuit.png" alt="Transistor LED current control circuit" /></a></p>
<p>The theory is that R2 (or R1 + R2 + R3) acts as a voltage divider across the power supply, linearly setting a drive voltage.  R4 (nearly) linearly turns this voltage into a current sink across the PNP transistor&#8217;s emitter-base junction; and because R4 >> R2, R2 presents a &#8220;stiff&#8221; voltage source to R4, meaning we can largely ignore R4&#8242;s effects on the voltage division.</p>
<p>Thus R2 provides (nearly) linear control of the emitter-base current.  In the common-emitter configuration, the PNP transistor amplifies the current by the transistor&#8217;s &beta; (about 150-200 for a small, general-purpose PNP like the 3906) for a correspondingly higher emitter-collector current</p>
<blockquote><p>
I<sub>EC</sub> = &beta; I<sub>EB</sub>
</p></blockquote>
<p>which goes through the LED and the sense resistor, providing (nearly) linear control of the LED brightness by turning R2.</p>
<p>Well, that&#8217;s the theory, anyway.  This weekend I dug out the prototype and built up the transistor control to test it in practice.</p>
<p><a href="http://www2.neufeld.newton.ks.us/images/electronics/2010/09/05/DSCN7412.jpg"><img src="http://www2.neufeld.newton.ks.us/images/electronics/2010/09/05/DSCN7412_mid.jpg" alt="LED calculator prototype with transistor current drive" /></a></p>
<p>(70s decor courtesy Radio Shack.)</p>
<p>The first thing I noticed was a section at the CCW end of R2&#8242;s travel in which nothing happened, because R2 wasn&#8217;t providing more than the transistor&#8217;s cut-in voltage &#8212; that is, although V<sub>B</sub> was less than V<sub>E</sub>, it wasn&#8217;t enough less to overcome to emitter-base forward voltage drop and bias the transistor down into the active region.</p>
<p>I tried installing a small-signal diode &#8220;above&#8221; the potentiometer so that V<sub>B</sub> would always be at least .6V below V<sub>E</sub> and eliminate R2&#8242;s dead region, but the diode&#8217;s forward voltage drop was a little too high (it did <em>too</em> good a job) and the resulting minimum LED current was a little higher than I liked.  I settled on adding R3 in that position, selecting 68&Omega; as a value that worked well with both traditional and high-power / high-efficiency LEDs and with both 9V and 7.2V supplies.</p>
<p>With a 9V supply and R3 = 68&Omega;, I tried three different values of the base resistor R4.</p>
<table align=center border=1 cellspacing=0 cellpadding=5>
<tr>
<th rowspan=2>R2 Position</th>
<th colspan=2>R4 = 10k&Omega;</th>
<th colspan=2>R4 = 22k&Omega;</th>
<th colspan=2>R4 = 47k&Omega;</th>
</tr>
<tr>
<th>Green</th>
<th>Blue</th>
<th>Green</th>
<th>Blue</th>
<th>Green</th>
<th>Blue</th>
</tr>
<tr>
<td>7:00</td>
<td>0mA</td>
<td>0mA</td>
<td>0mA</td>
<td>0mA</td>
<td>0mA</td>
<td>0mA</td>
</tr>
<tr>
<td>8:00</td>
<td>0mA</td>
<td>0mA</td>
<td>0mA</td>
<td>0mA</td>
<td>0mA</td>
<td>0mA</td>
</tr>
<tr>
<td>9:00</td>
<td>8mA</td>
<td>7mA</td>
<td>3mA</td>
<td>2mA</td>
<td>1mA</td>
<td>1mA</td>
</tr>
<tr>
<td>10:00</td>
<td>30mA</td>
<td>30mA</td>
<td>15mA</td>
<td>13mA</td>
<td>7mA</td>
<td>6mA</td>
</tr>
<tr>
<td>11:00</td>
<td>46mA</td>
<td>42mA</td>
<td>24mA</td>
<td>22mA</td>
<td>13mA</td>
<td>11mA</td>
</tr>
<tr>
<td>12:00</td>
<td>56mA</td>
<td>47mA</td>
<td>34mA</td>
<td>32mA</td>
<td>17mA</td>
<td>17mA</td>
</tr>
<tr>
<td>1:00</td>
<td>60mA</td>
<td>48mA</td>
<td>42mA</td>
<td>40mA</td>
<td>24mA</td>
<td>22mA</td>
</tr>
<tr>
<td>2:00</td>
<td>62mA</td>
<td>49mA</td>
<td>49mA</td>
<td>44mA</td>
<td>29mA</td>
<td>26mA</td>
</tr>
<tr>
<td>3:00</td>
<td>62mA</td>
<td>49mA</td>
<td>53mA</td>
<td>46mA</td>
<td>32mA</td>
<td>30mA</td>
</tr>
<tr>
<td>4:00</td>
<td>63mA</td>
<td>49mA</td>
<td>55mA</td>
<td>47mA</td>
<td>34mA</td>
<td>31mA</td>
</tr>
<tr>
<td>5:00</td>
<td>63mA</td>
<td>49mA</td>
<td>55mA</td>
<td>47mA</td>
<td>34mA</td>
<td>32mA</td>
</tr>
</table>
<p>The table shows a similar effect at the other end of R2&#8242;s travel in which the LED current was pretty well maxed out and not increasing any further.  I think I was hitting the knee between the transistor&#8217;s linear region and saturation, meaning increasing I<sub>EB</sub> was no longer increasing I<sub>EC</sub>.  Experimentation gave me R1 of 200&Omega; keeps the transistor pretty well out of saturation and gives a satisfyingly more-linear response than what I measured here.</p>
<p>The 0mA readings at the beginning of the table, by the way, are a bit deceptive &#8212; some of my test LEDs are actually lit in that region.  I&#8217;ve updated the Arduino code to show tenths of a milliamp when the reading is below 10mA, and I can see LEDs glowing with as little as .1mA.  Probably not a value of interest for most people, but it could be effective for making flickering gas lamps for model railroads.</p>
<h3>Choosing Values</h3>
<p>R4 = 22k&Omega; looks like a pretty good compromise between providing a near-linear response and covering the range of LED currents I expect most people would be interested in testing, so I&#8217;ve tentatively settled on it.</p>
<p>I&#8217;m still fiddling with values to give good performance at both 9V (alkaline battery) and 7.2V (NiMH), because I use rechargeables almost exclusively and want to make this work well on rechargeables to encourage other people to do the same.  The problem is,</p>
<blockquote><p>V<sub>supply</sub> = 7.2V<br />
V<sub>EC</sub> &asymp; .8V<br />
V<sub>blue LED</sub> &asymp; 3.5V</p>
<p>V<sub>R5</sub> = V<sub>supply</sub> &#8211; V<sub>EC</sub> &#8211; V<sub>LED</sub> = 7.2V &#8211; .8V &#8211; 3.5V = 2.9V</p>
<p>I<sub>LED</sub> = I<sub>R5</sub> = V<sub>R5</sub> / R5 = 2.9V / 100&Omega; = 29mA</p></blockquote>
<p>In other words, running on a 7.2V battery, with the transistor saturated, a blue LED with a 3.5V forward drop maxes out at 29mA; and it gets worse with a battery that&#8217;s not straight out of the charger and some white LEDs with a higher forward voltage drop.  I&#8217;d like to enable people to test up to 50mA, to cover high-brightness LEDs, so I&#8217;d like to push this maximum current a little higher.</p>
<p>R5 = 68&Omega; gives I<sub>LED</sub> up to about 42mA, which isn&#8217;t as high as I like; but the tradeoff is that a smaller R5 gives me a smaller voltage range to sample in the A/D converter, hence lower resolution for the display.  68&Omega; seems like a good compromise.  And I&#8217;m already thinking about a DPDT switch to change the resistor and alert the microcontroller about battery chemistry.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.neufeld.newton.ks.us/electronics/?feed=rss2&#038;p=1145</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Rutgers Student&#8217;s CupCaked Robot Chassis</title>
		<link>http://www.neufeld.newton.ks.us/electronics/?p=726</link>
		<comments>http://www.neufeld.newton.ks.us/electronics/?p=726#comments</comments>
		<pubDate>Mon, 23 Nov 2009 14:51:00 +0000</pubDate>
		<dc:creator>Keith Neufeld</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[MakerBot CupCake]]></category>
		<category><![CDATA[Robotics]]></category>

		<guid isPermaLink="false">http://www.neufeld.newton.ks.us/electronics/?p=726</guid>
		<description><![CDATA[Being able to do things like this is why I bought a CupCake. via Make]]></description>
			<content:encoded><![CDATA[<p><a href="http://sites.google.com/site/reprapgeneration/reprapbot/reprapbot-mrk2"><img src="http://www2.neufeld.newton.ks.us/images/electronics/links/reprapbot_mid.jpg" alt="Rutgers student's RepRapBot Mrk II" /></a></p>
<p><a href="http://sites.google.com/site/reprapgeneration/reprapbot/reprapbot-mrk2">Being able to do things like this</a> is why I bought a CupCake.  <a href="http://blog.makezine.com/archive/2009/11/line-following_chassis_from_reprap.html">via Make</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.neufeld.newton.ks.us/electronics/?feed=rss2&#038;p=726</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
