tag:blogger.com,1999:blog-45421765496924041942024-03-12T21:19:35.873-05:00Projects from TechA blog following my endeavors as I explore the world of Arduinos, robots, and magic smoke.Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.comBlogger82125tag:blogger.com,1999:blog-4542176549692404194.post-18246864640272672252017-11-07T23:00:00.000-06:002017-11-07T23:00:05.726-06:00Installing TensorFlow 1.4 on Windows 10 with AnacondaI had a few problems during my install, so this will serve to document the procedure I used to get it to work correctly. The general install instructions are on <a href="https://www.tensorflow.org/install/install_windows" target="_blank">tensorflow.org</a>. These instructions may work on other versions of Windows, but they have not been tested. In this case I am installing the GPU enabled version, and I am assuming you have already verified that your <a href="https://developer.nvidia.com/cuda-gpus" target="_blank">graphics card is supported</a>.<br />
<br />
<h2>
1) Install CUDA Toolkit 8.0</h2>
Do not install CUDA 9.0 unless you know what you are doing. 9.0 will be supported in TensorFlow 1.5 according to <a href="https://github.com/tensorflow/tensorflow/issues/14244" target="_blank">THIS</a> post. For now you will have to download 8.0 from the <a href="https://developer.nvidia.com/cuda-toolkit-archive" target="_blank">CUDA archive</a>. It kept bugging me to install Visual Studio, and I finally did. I don't think that is actually a requirement though if you plan to use something else.<br />
<br />
<h2>
2) Install cuDNN 6.0</h2>
<div>
I could not find an install for version 6.1, but this seemed to work just fine. You can find the different versions <a href="https://developer.nvidia.com/cudnn" target="_blank">HERE</a>. Just unzip them somewhere convenient and add the cuda/bin directory to the system %PATH% environment variable.</div>
<div>
<br /></div>
<h2>
3) Create/Activate Anaconda Environment</h2>
<div>
If you have not already installed Anaconda, install it with Python version 3.6 (the instructions say 3.5, but I used an environment I already had set up with 3.6). Create the conda environment by opening the Anaconda prompt and typing:</div>
<div>
<br /></div>
<div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">conda create <span style="color: #333333;">--</span>name myEnvName python<span style="color: #333333;">=</span><span style="color: #6600ee; font-weight: bold;">3.6</span>
</pre>
</div>
<br />
Activate the environment by then typing:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">activate myEnvName</pre>
</div>
<br />
<h2>
4) Install TensorFlow Using pip</h2>
This step is where you need to pay attention. Do <u>not</u> follow the instructions on the TensorFlow website. When I did what they say I got the error described in <a href="https://stackoverflow.com/questions/46356732/anaconda-prompt-corrupts-after-installation" target="_blank">THIS</a> post. My conda environment would no longer activate. There was probably an easy fix, but I ended up having to reinstall Anaconda. If you find another solution, let me know in the comments. Instead, use this command (in your virtual environment):<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">pip install tensorflow<span style="color: #333333;">-</span>gpu
</pre>
</div>
<br />
While it looks like there is a <a href="https://anaconda.org/conda-forge/tensorflow" target="_blank">conda-forge package</a> you could install. The latest version of it at the time of this writing is 1.3.0. Granted TensorFlow 1.4 is only 5 days old, so they may release version 1.4 tomorrow on conda. If so, that would be an attractive option.<br />
<h2>
5) Validate your Install</h2>
You can now validate your install using the short program specified on the TensorFlow website.<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">python
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">tensorflow</span> <span style="color: #008800; font-weight: bold;">as</span> <span style="color: #0e84b5; font-weight: bold;">tf</span>
hello <span style="color: #333333;">=</span> tf<span style="color: #333333;">.</span>constant(<span style="background-color: #fff0f0;">'Hello, TensorFlow!'</span>)
sess <span style="color: #333333;">=</span> tf<span style="color: #333333;">.</span>Session()
<span style="color: #008800; font-weight: bold;">print</span>(sess<span style="color: #333333;">.</span>run(hello))
</pre>
</div>
<br />
<br />
This is how I got my install to work. If you have any errors, feel free to post them below, but you're better off Googling them or posting on StackOverflow.<br />
<br />
Matthew</div>
Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-79377031041799215992017-11-04T08:00:00.000-05:002017-11-04T08:00:09.957-05:00Querying SQLite database using sqlite3 in JavaScript<h2>
Motivation</h2>
I've never regretted studying mechanical engineering instead of electrical engineering or computer science, but sometimes by lack of formal programming knowledge does bite me. This happened a few days ago when I wanted to see if I could apply some machine learning techniques to some data in a SQLite database. Having no experience with SQL and minimal experience with javascript, I Googled how to get the data. The answers that I found seemed overly complicated. As such, this post will be a practical example of querying the data from an SQLite database. It is as much for my memory as anything. I was using JavaScript (via Node) and sqlite3. I did this on a Virtual Machine running Ubuntu, but I believe all of the tools I use can be used in Windows as well.<br />
<br />
<h2>
Data Visualization using SQLiteStudio</h2>
<div>
Here is a visualization of the data. It is some historical trade data from the cryptocurrency exchange, Poloniex. Having never used SQL before, I downloaded <a href="https://sqlitestudio.pl/index.rvt" target="_blank">SQLiteStudio</a> to see what the data actually looked like. As you can see, the database contains two tables - in this case one for each of the two trading pairs for which I had data. Inside those tables, there are labeled columns. Each row has a unique id. </div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-tgbLXqZUCmQ/WfZDzzdscgI/AAAAAAAABEo/-KO_YPgCuNk0EVc1TKDlcnL0My958U0oQCLcBGAs/s1600/SQL%2BVisualization.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="657" data-original-width="1211" height="345" src="https://1.bp.blogspot.com/-tgbLXqZUCmQ/WfZDzzdscgI/AAAAAAAABEo/-KO_YPgCuNk0EVc1TKDlcnL0My958U0oQCLcBGAs/s640/SQL%2BVisualization.PNG" width="640" /></a></div>
<br />
<h2>
Querying the Database using sqlite3</h2>
<div>
I found a tutorial (<a href="http://www.sqlitetutorial.net/sqlite-nodejs/query/" target="_blank">THIS ONE</a>) and tried to follow it, but I found that it took a frustratingly long amount of time to figure out what all of the values meant. Anyway, here is my javascript code to query a single line from the database. If you understand this, the above tutorial should be easy to adapt to pulling multiple lines. Of course, you need to already have sqlite3 installed. </div>
<div>
<br /></div>
<div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #888888;">//Import sqlite to read database</span>
<span style="color: #008800; font-weight: bold;">const</span> sqlite3 <span style="color: #333333;">=</span> require(<span style="background-color: #fff0f0;">'sqlite3'</span>).verbose();
<span style="color: #888888;">//Connect to database</span>
<span style="color: #008800; font-weight: bold;">let</span> db <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> sqlite3.Database(<span style="background-color: #fff0f0;">'./history/poloniex_0.1.db'</span>, (err) <span style="color: #333333;">=></span> {
<span style="color: #008800; font-weight: bold;">if</span> (err) {
console.error(err.message);
}
console.log(<span style="background-color: #fff0f0;">'Connected to the database.'</span>);
});
<span style="color: #888888;">// get columns start and label it as startval, open-> openval, etc from the appropriate table</span>
<span style="color: #888888;">// when the id = what we define it as below</span>
<span style="color: #008800; font-weight: bold;">let</span> sql <span style="color: #333333;">=</span> <span style="background-color: #ffaaaa; color: red;">`</span>SELECT start startval,
open openval,
high highval
FROM candles_USDT_ETH
WHERE id <span style="color: #333333;">=</span> <span style="color: #333333;">?</span><span style="background-color: #ffaaaa; color: red;">`</span>;
<span style="color: #008800; font-weight: bold;">let</span> id <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">2</span>;
<span style="color: #888888;">// Get only [id] row (in this case 2nd row)</span>
db.get(sql, [id], (err, row) <span style="color: #333333;">=></span> {
<span style="color: #008800; font-weight: bold;">if</span> (err) {
<span style="color: #008800; font-weight: bold;">return</span> console.error(err.message);
}
<span style="color: #008800; font-weight: bold;">return</span> row
<span style="color: #333333;">?</span> console.log(row.startval, row.openval, row.highval)
<span style="color: #333333;">:</span> console.log(<span style="background-color: #ffaaaa; color: red;">`</span>No values found <span style="color: #008800; font-weight: bold;">with</span> the id ${id}<span style="background-color: #ffaaaa; color: red;">`</span>);
});
<span style="color: #888888;">// Close the database</span>
db.close((err) <span style="color: #333333;">=></span> {
<span style="color: #008800; font-weight: bold;">if</span> (err) {
console.error(err.message);
}
console.log(<span style="background-color: #fff0f0;">'Close the database connection.'</span>);
});
</pre>
</div>
<br /></div>
<div>
<br /></div>
<div>
<h2>
Converting the Table to CSV</h2>
</div>
<div>
Another useful thing I stumbled upon was how to convert a database from SQL to CSV in order to import it into some other program (in my case MATLAB). For my MATLAB example, I did not have the database toolbox, so this allowed me to play with this data without it. I copied <a href="http://www.sqlitetutorial.net/sqlite-export-csv/" target="_blank">THIS</a> tutorial. It is more thorough, but here is the highlight. To save the start, open, and high columns from the candles_USDT_ETH table, use the following code.</div>
<div>
<br /></div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">sqlite3 .<span style="color: #333333;">/</span>history<span style="color: #333333;">/</span>poloniex_0.<span style="color: #0000dd; font-weight: bold;">1</span>.db
.headers on
.mode csv
.output data.csv
SELECT start,
open,
high
FROM candles_USDT_ETH;
.quit
</pre>
</div>
<br />
<br />
That's all I have for now. As I mentioned above, like many of my posts this is as much for my memory as anything, but I hope it helps someone.<br />
-Matthew<br />
<br />
<br />Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-40352987425010228452017-10-06T18:00:00.000-05:002018-01-08T13:13:19.655-06:00Visual Object Recognition in ROS Using Keras with TensorFlowI've recently gotten interested in machine learning and all of the tools that come along with that. This post will document a method of doing object recognition in ROS using Keras. I don't want to turn this post into a "what is machine learning and how does it work" piece, so I am going to assume you are familiar with machine learning in general and the robotic operating system (ROS). Instead I'm going to present a specific set of instructions on how to get a specific (but very useful) machine learning algorithm working on a ROS platform.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://2.bp.blogspot.com/-0Wrl4tY8Ex0/WcgTRJ3d44I/AAAAAAAABD0/47DmwryAw0U6WgUgQYUCItfFIY79Q_TjQCLcBGAs/s1600/CoffeeMug.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="448" data-original-width="729" height="196" src="https://2.bp.blogspot.com/-0Wrl4tY8Ex0/WcgTRJ3d44I/AAAAAAAABD0/47DmwryAw0U6WgUgQYUCItfFIY79Q_TjQCLcBGAs/s320/CoffeeMug.PNG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The end result. Object recognition in ROS on a live webcam (~2Hz)</td></tr>
</tbody></table>
<br />
When I was looking around the ROS wiki I was a bit surprised that there was no object recognition package readily available. I decided I wanted one; that is I wanted a package that would take a raw camera image and tell me what was in the picture. While I have no doubt that there are many obscure ways of doing this, the most common these days (to my knowledge) is machine learning - specifically using convolutional neural networks (CNNs). In fact, it is often used as an example of what machine learning is all about. This is where this project picks up.<br />
<br />
There are many tutorials on getting CNNs working on various platforms, but I am going to use Keras with the TensorFlow backend. The idea is this, there are plenty of tutorials on getting object recognition working with this package. Pick one (I used <a href="https://deeplearningsandbox.com/how-to-build-an-image-recognition-system-using-keras-and-tensorflow-for-a-1000-everyday-object-559856e04699" target="_blank">THIS</a> one, but more general would be the <a href="https://keras.io/applications/" target="_blank">Keras documentation</a>). This code is simply Python code. ROS accepts Python code via rospy. Let's put this code into a ROS package. I will be the first to admit that I am not an expert in ROS or machine learning, so use these instructions at your own risk. However, this did work for me.<br />
<br />
<h2>
Step 1: Install TensorFlow</h2>
<div>
I am installing TensorFlow on my virtualized Ubuntu 16.04 install as created in <a href="http://projectsfromtech.blogspot.com/2017/09/installing-ros-on-virtual-machine-for.html" target="_blank">this post</a>. I will tell you that this works surprisingly well, but I am giving it 12 GB of RAM and 3 cores of an i7. The point is, if you have Windows this will work for you too!</div>
<div>
<br /></div>
<div>
Install TensorFlow using the <a href="https://www.tensorflow.org/install/install_linux" target="_blank">Linux install instructions</a>. I used the CPU support only ones for virtualenv. This is probably not the best way to do this as I imagine there is a way in ROS to handle external dependencies. Feel free to comment below what that is. I figured worst case I could activate the virtualenv in my launch file. This will work for prototyping. When you decide which version of Python to use, I used 2.7 as this is the version recommended for ROS Kinetic. Be sure to <a href="https://www.tensorflow.org/install/install_linux#ValidateYourInstallation" target="_blank">validate the install</a> before proceeding.</div>
<div>
<br /></div>
<div>
<br /></div>
<h2>
Step 2: Install Keras</h2>
<div>
Next you want to <a href="https://keras.io/#installation" target="_blank">in<span style="font-family: inherit;">stall Keras</span></a><span style="font-family: inherit;">. The important note here is that you want to install this in the same virtualenv environment as TensorFlow. Do this by activating the environment before you install like you did in the TensorFlow directions (<b style="box-sizing: inherit; color: #37474f;">source ~/tensorflow/bin/activate</b>). The TensorFlow backend is the default, so you are ok there. However you will need <a href="http://docs.h5py.org/en/latest/build.html" target="_blank">h5py</a>. Install this with <pip install h5py>.</span></div>
<div>
<br /></div>
<h2>
Step 3: Build your ROS package</h2>
<div>
First, we need to create a package. Call it what you want, but note the dependencies.</div>
<div>
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">catkin_create_pkg object_recognition rospy std_msgs cv_bridge sensor_msgs
</pre>
</div>
<br />
Next, create a new file called classify.py, and make sure it is an enabled as an executable. Copy the code below into the file.<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #888888;">#!/usr/bin/env python</span>
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">rospy</span>
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">cv2</span>
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">roslib</span>
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">numpy</span> <span style="color: #008800; font-weight: bold;">as</span> <span style="color: #0e84b5; font-weight: bold;">np</span>
<span style="color: #008800; font-weight: bold;">from</span> <span style="color: #0e84b5; font-weight: bold;">std_msgs.msg</span> <span style="color: #008800; font-weight: bold;">import</span> String
<span style="color: #008800; font-weight: bold;">from</span> <span style="color: #0e84b5; font-weight: bold;">std_msgs.msg</span> <span style="color: #008800; font-weight: bold;">import</span> Float32
<span style="color: #008800; font-weight: bold;">from</span> <span style="color: #0e84b5; font-weight: bold;">sensor_msgs.msg</span> <span style="color: #008800; font-weight: bold;">import</span> Image
<span style="color: #008800; font-weight: bold;">from</span> <span style="color: #0e84b5; font-weight: bold;">cv_bridge</span> <span style="color: #008800; font-weight: bold;">import</span> CvBridge, CvBridgeError
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">tensorflow</span> <span style="color: #008800; font-weight: bold;">as</span> <span style="color: #0e84b5; font-weight: bold;">tf</span>
<span style="color: #008800; font-weight: bold;">from</span> <span style="color: #0e84b5; font-weight: bold;">keras.preprocessing</span> <span style="color: #008800; font-weight: bold;">import</span> image
<span style="color: #008800; font-weight: bold;">from</span> <span style="color: #0e84b5; font-weight: bold;">keras.applications.resnet50</span> <span style="color: #008800; font-weight: bold;">import</span> ResNet50, preprocess_input, decode_predictions
<span style="color: #888888;"># import model and implement fix found here.</span>
<span style="color: #888888;"># https://github.com/fchollet/keras/issues/2397</span>
model <span style="color: #333333;">=</span> ResNet50(weights<span style="color: #333333;">=</span><span style="background-color: #fff0f0;">'imagenet'</span>)
model<span style="color: #333333;">.</span>_make_predict_function()
graph <span style="color: #333333;">=</span> tf<span style="color: #333333;">.</span>get_default_graph()
target_size <span style="color: #333333;">=</span> (<span style="color: #0000dd; font-weight: bold;">224</span>, <span style="color: #0000dd; font-weight: bold;">224</span>)
rospy<span style="color: #333333;">.</span>init_node(<span style="background-color: #fff0f0;">'classify'</span>, anonymous<span style="color: #333333;">=</span><span style="color: #007020;">True</span>)
<span style="color: #888888;">#These should be combined into a single message</span>
pub <span style="color: #333333;">=</span> rospy<span style="color: #333333;">.</span>Publisher(<span style="background-color: #fff0f0;">'object_detected'</span>, String, queue_size <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">1</span>)
pub1 <span style="color: #333333;">=</span> rospy<span style="color: #333333;">.</span>Publisher(<span style="background-color: #fff0f0;">'object_detected_probability'</span>, Float32, queue_size <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">1</span>)
bridge <span style="color: #333333;">=</span> CvBridge()
msg_string <span style="color: #333333;">=</span> String()
msg_float <span style="color: #333333;">=</span> Float32()
<span style="color: #008800; font-weight: bold;">def</span> <span style="color: #0066bb; font-weight: bold;">callback</span>(image_msg):
<span style="color: #888888;">#First convert the image to OpenCV image </span>
cv_image <span style="color: #333333;">=</span> bridge<span style="color: #333333;">.</span>imgmsg_to_cv2(image_msg, desired_encoding<span style="color: #333333;">=</span><span style="background-color: #fff0f0;">"passthrough"</span>)
cv_image <span style="color: #333333;">=</span> cv2<span style="color: #333333;">.</span>resize(cv_image, target_size) <span style="color: #888888;"># resize image</span>
np_image <span style="color: #333333;">=</span> np<span style="color: #333333;">.</span>asarray(cv_image) <span style="color: #888888;"># read as np array</span>
np_image <span style="color: #333333;">=</span> np<span style="color: #333333;">.</span>expand_dims(np_image, axis<span style="color: #333333;">=</span><span style="color: #0000dd; font-weight: bold;">0</span>) <span style="color: #888888;"># Add another dimension for tensorflow</span>
np_image <span style="color: #333333;">=</span> np_image<span style="color: #333333;">.</span>astype(<span style="color: #007020;">float</span>) <span style="color: #888888;"># preprocess needs float64 and img is uint8</span>
np_image <span style="color: #333333;">=</span> preprocess_input(np_image) <span style="color: #888888;"># Regularize the data</span>
<span style="color: #008800; font-weight: bold;">global</span> graph <span style="color: #888888;"># This is a workaround for asynchronous execution</span>
<span style="color: #008800; font-weight: bold;">with</span> graph<span style="color: #333333;">.</span>as_default():
preds <span style="color: #333333;">=</span> model<span style="color: #333333;">.</span>predict(np_image) <span style="color: #888888;"># Classify the image</span>
<span style="color: #888888;"># decode returns a list of tuples [(class,description,probability),(class, descrip ...</span>
pred_string <span style="color: #333333;">=</span> decode_predictions(preds, top<span style="color: #333333;">=</span><span style="color: #0000dd; font-weight: bold;">1</span>)[<span style="color: #0000dd; font-weight: bold;">0</span>] <span style="color: #888888;"># Decode top 1 predictions</span>
msg_string<span style="color: #333333;">.</span>data <span style="color: #333333;">=</span> pred_string[<span style="color: #0000dd; font-weight: bold;">0</span>][<span style="color: #0000dd; font-weight: bold;">1</span>]
msg_float<span style="color: #333333;">.</span>data <span style="color: #333333;">=</span> <span style="color: #007020;">float</span>(pred_string[<span style="color: #0000dd; font-weight: bold;">0</span>][<span style="color: #0000dd; font-weight: bold;">2</span>])
pub<span style="color: #333333;">.</span>publish(msg_string)
pub1<span style="color: #333333;">.</span>publish(msg_float)
rospy<span style="color: #333333;">.</span>Subscriber(<span style="background-color: #fff0f0;">"camera/image_raw"</span>, Image, callback, queue_size <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">1</span>, buff_size <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">16777216</span>)
<span style="color: #008800; font-weight: bold;">while</span> <span style="color: black; font-weight: bold;">not</span> rospy<span style="color: #333333;">.</span>is_shutdown():
rospy<span style="color: #333333;">.</span>spin()
</pre>
</div>
<br />
At this point you can obviously go straight to running the code if you wish, but I'll step through each chunk and explain it.<br />
<br />
<h3>
Load Dependencies</h3>
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #888888;">#!/usr/bin/env python</span>
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">rospy</span>
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">cv2</span>
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">roslib</span>
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">numpy</span> <span style="color: #008800; font-weight: bold;">as</span> <span style="color: #0e84b5; font-weight: bold;">np</span>
<span style="color: #008800; font-weight: bold;">from</span> <span style="color: #0e84b5; font-weight: bold;">std_msgs.msg</span> <span style="color: #008800; font-weight: bold;">import</span> String
<span style="color: #008800; font-weight: bold;">from</span> <span style="color: #0e84b5; font-weight: bold;">std_msgs.msg</span> <span style="color: #008800; font-weight: bold;">import</span> Float32
<span style="color: #008800; font-weight: bold;">from</span> <span style="color: #0e84b5; font-weight: bold;">sensor_msgs.msg</span> <span style="color: #008800; font-weight: bold;">import</span> Image
<span style="color: #008800; font-weight: bold;">from</span> <span style="color: #0e84b5; font-weight: bold;">cv_bridge</span> <span style="color: #008800; font-weight: bold;">import</span> CvBridge, CvBridgeError
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">tensorflow</span> <span style="color: #008800; font-weight: bold;">as</span> <span style="color: #0e84b5; font-weight: bold;">tf</span>
<span style="color: #008800; font-weight: bold;">from</span> <span style="color: #0e84b5; font-weight: bold;">keras.preprocessing</span> <span style="color: #008800; font-weight: bold;">import</span> image
<span style="color: #008800; font-weight: bold;">from</span> <span style="color: #0e84b5; font-weight: bold;">keras.applications.resnet50</span> <span style="color: #008800; font-weight: bold;">import</span> ResNet50, preprocess_input, decode_predictions
</pre>
</div>
<br />
This section just imports the dependencies. You can see we have some from Python, some from ROS, and some from Keras. If you are not too familiar with rospy, the comment on the first line always has to be there. Don't put anything else on the first line or else ROS won't know this is a Python script.<br />
<br />
<h3>
Load Keras Model</h3>
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #888888;"># import model and implement fix found here.</span>
<span style="color: #888888;"># https://github.com/fchollet/keras/issues/2397</span>
model <span style="color: #333333;">=</span> ResNet50(weights<span style="color: #333333;">=</span><span style="background-color: #fff0f0;">'imagenet'</span>)
model<span style="color: #333333;">.</span>_make_predict_function()
graph <span style="color: #333333;">=</span> tf<span style="color: #333333;">.</span>get_default_graph()
target_size <span style="color: #333333;">=</span> (<span style="color: #0000dd; font-weight: bold;">224</span>, <span style="color: #0000dd; font-weight: bold;">224</span>)
</pre>
</div>
<br />
This section is where we import our machine learning model. I am using the ResNet50 model frankly because that is what the tutorial linked above used, but there are many others included if you look <a href="https://keras.io/applications/" target="_blank">HERE</a>. You can see that this ResNet model was trained using ImageNet, but you could also obviously insert your own model or weights here as well. Also note <a href="https://github.com/fchollet/keras/issues/2397" target="_blank">the fix</a> that his been implemented as noted in the comment.<br />
<br />
<h3>
Start ROS Node</h3>
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">rospy<span style="color: #333333;">.</span>init_node(<span style="background-color: #fff0f0;">'classify'</span>, anonymous<span style="color: #333333;">=</span><span style="color: #007020;">True</span>)
<span style="color: #888888;">#These should be combined into a single message</span>
pub <span style="color: #333333;">=</span> rospy<span style="color: #333333;">.</span>Publisher(<span style="background-color: #fff0f0;">'object_detected'</span>, String, queue_size <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">1</span>)
pub1 <span style="color: #333333;">=</span> rospy<span style="color: #333333;">.</span>Publisher(<span style="background-color: #fff0f0;">'object_detected_probability'</span>, Float32, queue_size <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">1</span>)
bridge <span style="color: #333333;">=</span> CvBridge()
msg_string <span style="color: #333333;">=</span> String()
msg_float <span style="color: #333333;">=</span> Float32()
</pre>
</div>
<br />
This starts all of the ROS stuff. We initialize the node and start two publishers. Now, I am aware that this is bad practice. I should really create a ROS message to house this data. However, at the moment I don't have a specific application for this, so I will leave that to the user. I am just publishing two different messages - one for the name of the most likely object name and one for the corresponding probability.<br />
<br />
<br />
<h3>
Run Model Inside callback</h3>
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">def</span> <span style="color: #0066bb; font-weight: bold;">callback</span>(image_msg):
<span style="color: #888888;">#First convert the image to OpenCV image </span>
cv_image <span style="color: #333333;">=</span> bridge<span style="color: #333333;">.</span>imgmsg_to_cv2(image_msg, desired_encoding<span style="color: #333333;">=</span><span style="background-color: #fff0f0;">"passthrough"</span>)
cv_image <span style="color: #333333;">=</span> cv2<span style="color: #333333;">.</span>resize(cv_image, target_size) <span style="color: #888888;"># resize image</span>
np_image <span style="color: #333333;">=</span> np<span style="color: #333333;">.</span>asarray(cv_image) <span style="color: #888888;"># read as np array</span>
np_image <span style="color: #333333;">=</span> np<span style="color: #333333;">.</span>expand_dims(np_image, axis<span style="color: #333333;">=</span><span style="color: #0000dd; font-weight: bold;">0</span>) <span style="color: #888888;"># Add another dimension for tensorflow</span>
np_image <span style="color: #333333;">=</span> np_image<span style="color: #333333;">.</span>astype(<span style="color: #007020;">float</span>) <span style="color: #888888;"># preprocess needs float64 and img is uint8</span>
np_image <span style="color: #333333;">=</span> preprocess_input(np_image) <span style="color: #888888;"># Normalize the data</span>
<span style="color: #008800; font-weight: bold;">global</span> graph <span style="color: #888888;"># This is a workaround for asynchronous execution</span>
<span style="color: #008800; font-weight: bold;">with</span> graph<span style="color: #333333;">.</span>as_default():
preds <span style="color: #333333;">=</span> model<span style="color: #333333;">.</span>predict(np_image) <span style="color: #888888;"># Classify the image</span>
<span style="color: #888888;"># decode returns a list of tuples [(class,description,probability),(class, descrip ...</span>
pred_string <span style="color: #333333;">=</span> decode_predictions(preds, top<span style="color: #333333;">=</span><span style="color: #0000dd; font-weight: bold;">1</span>)[<span style="color: #0000dd; font-weight: bold;">0</span>] <span style="color: #888888;"># Decode top 1 predictions</span>
msg_string<span style="color: #333333;">.</span>data <span style="color: #333333;">=</span> pred_string[<span style="color: #0000dd; font-weight: bold;">0</span>][<span style="color: #0000dd; font-weight: bold;">1</span>]
msg_float<span style="color: #333333;">.</span>data <span style="color: #333333;">=</span> <span style="color: #007020;">float</span>(pred_string[<span style="color: #0000dd; font-weight: bold;">0</span>][<span style="color: #0000dd; font-weight: bold;">2</span>])
pub<span style="color: #333333;">.</span>publish(msg_string)
pub1<span style="color: #333333;">.</span>publish(msg_float)
rospy<span style="color: #333333;">.</span>Subscriber(<span style="background-color: #fff0f0;">"camera/image_raw"</span>, Image, callback, queue_size <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">1</span>, buff_size <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">16777216</span>)
<span style="color: #008800; font-weight: bold;">while</span> <span style="color: black; font-weight: bold;">not</span> rospy<span style="color: #333333;">.</span>is_shutdown():
rospy<span style="color: #333333;">.</span>spin()
</pre>
</div>
<br />
Here is the heart of the code. I tried to comment it pretty well, but here is the workflow.<br />
<br />
<ol>
<li>The callback function fires when a new image is available. </li>
<li>Use cv_bridge to convert the image from a ROS image type to an OpenCV image type.</li>
<li>Resize the image to the shape required by ResNet50, 224 x 224. </li>
<li>Read the OpenCV image in as a NumPy array.</li>
<li>Expand the array into the size needed for TensorFlow.</li>
<li>Convert the data from uint8 to float64.</li>
<li>Normalize the data.</li>
<li>Run the model and classify the image.</li>
<li>Decode the prediction and convert them to appropriate data types.</li>
<li>Publish the prediction.</li>
</ol>
<div>
It's also worth noting the large buffer size on the subscriber. This was done per the recommendation <a href="https://github.com/ros/ros_comm/issues/536" target="_blank">HERE</a>.</div>
<div>
<br /></div>
<h2>
Step 4: Run the Code!</h2>
<div>
Now the fun part. Start your webcam via your favorite method. We just need the camera/image_raw topic which is pretty standard. If you need help with that, see <a href="https://projectsfromtech.blogspot.com/2017/09/tracking-ar-tags-with-ros-monocular.html" target="_blank">my other post</a> on AR Tags for instructions.</div>
<div>
<br /></div>
<div>
Now we need to launch our node. It's important that we do that in our virtualenv, so source the environment again if you haven't al<span style="font-family: inherit;">ready (<b style="box-sizing: inherit;">source ~/tensorflow/bin/activate</b><span style="box-sizing: inherit;">).</span><span style="box-sizing: inherit; color: #37474f;"> </span><span style="box-sizing: inherit;">Then just rosrun your node.</span></span></div>
<div>
<br /></div>
<div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">rosrun object_recognition classify.py
</pre>
</div>
<br />
Now you should be able to rostopic echo /object_detected and /object_detected_probability to see what your webcam is seeing. On my virtual machine this runs at about 2 Hz, but I imagine that could be increased if you're on a typical Ubuntu install. Here are some examples! It does ok. It didn't recognize a pack of playing cards, so I am guessing that is not in the ImageNet training set. I am still fairly impressed with it.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-GE3OMfsRLQw/WcgTf6NaN6I/AAAAAAAABEA/XFcanIdxBgwlj8kVnXcCHYhRLn7u57eKgCLcBGAs/s1600/Padlock.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="454" data-original-width="735" height="197" src="https://3.bp.blogspot.com/-GE3OMfsRLQw/WcgTf6NaN6I/AAAAAAAABEA/XFcanIdxBgwlj8kVnXcCHYhRLn7u57eKgCLcBGAs/s320/Padlock.PNG" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-HwER80wXERA/WcgTf54D99I/AAAAAAAABD4/Zufa1RKKRcwUGF7MqXvw7vzaQtz4doWTACLcBGAs/s1600/cards.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="461" data-original-width="716" height="206" src="https://2.bp.blogspot.com/-HwER80wXERA/WcgTf54D99I/AAAAAAAABD4/Zufa1RKKRcwUGF7MqXvw7vzaQtz4doWTACLcBGAs/s320/cards.PNG" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-4OB-lX7yaOE/WcgTf-aJYnI/AAAAAAAABD8/M6xwJDXulBQ5PHfa58gB0ElBEWfeH9u5gCLcBGAs/s1600/laptop.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="461" data-original-width="730" height="202" src="https://2.bp.blogspot.com/-4OB-lX7yaOE/WcgTf-aJYnI/AAAAAAAABD8/M6xwJDXulBQ5PHfa58gB0ElBEWfeH9u5gCLcBGAs/s320/laptop.PNG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
So that's it; you can now implement an object recognition package in ROS! Comment below if you use this in a project. I'd be particularly interested if someone uses their own model or does some transfer learning with this one to suit their specific application. If you have any other questions or comments, feel free to post those as well.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
-Matthew</div>
</div>
</div>
Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-73987166630402545012017-09-27T18:00:00.000-05:002017-09-27T18:00:06.170-05:00Tracking AR Tags with ROS: Monocular VisionIf you've found this I am going to assume that you are familiar with ROS. What you might not be so familiar with is AR tags (Augmented Reality Tags). I am not going to go into how AR tags work, because frankly I am not an expert in them. What I can say is that I have used them, and it is very easy using ROS. They allow anyone with a cheap webcam to get a full 6 DOF position from a single reference, an AR tag. They can be printed on any home printer and are fully scalable. Below is a picture of what a simple implementation looks like. Search YouTube for some videos. People are doing some cool things with them, but enough talk. Lets get a demo working.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://1.bp.blogspot.com/-IOAAUq7osfo/WcRBQhH7kMI/AAAAAAAABC8/F5CJ83dVenogag-UMwQmp46DGnLc6n8ewCLcBGAs/s1600/Capture3.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="752" data-original-width="748" height="400" src="https://1.bp.blogspot.com/-IOAAUq7osfo/WcRBQhH7kMI/AAAAAAAABC8/F5CJ83dVenogag-UMwQmp46DGnLc6n8ewCLcBGAs/s400/Capture3.PNG" width="397" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Tracking 3 AR tags with a Standard Monocular Webcam, a Logitech C615</td></tr>
</tbody></table>
<br />
<br />
This post is the documentation for how I got it working on my machine. It should be mostly complete, but I will admit that I have probably left out some things that I thought were self explanatory. If you have problems or suggest changes, please post those in the comments.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://2.bp.blogspot.com/-7Jgg8A6yOTs/WcRBDblkyjI/AAAAAAAABC4/GFKhsBkWiigWbqlQIYj3AidLXwFvxgdiQCLcBGAs/s1600/artag.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="529" data-original-width="535" height="197" src="https://2.bp.blogspot.com/-7Jgg8A6yOTs/WcRBDblkyjI/AAAAAAAABC4/GFKhsBkWiigWbqlQIYj3AidLXwFvxgdiQCLcBGAs/s200/artag.PNG" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">AR tag</td></tr>
</tbody></table>
<h2>
Prerequisites</h2>
1) Installed ROS Kinetic. I am using a virtual machine as detailed <a href="http://projectsfromtech.blogspot.com/2017/09/installing-ros-on-virtual-machine-for.html" target="_blank">HERE</a>.<br />
2) Setup Catkin Workspace (I'll assume it's called catkin_ws).<br />
3) Know some basic ROS. If you don't you can likely Google your questions.<br />
<div>
<h2>
Setup</h2>
</div>
<h3>
Install package ar_track_alvar</h3>
1) Open a terminal in catkin_ws/src<br />
2) In the terminal type:<br />
<div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">git clone -b kinetic-devel https://github.com/ros-perception/ar_track_alvar.git
<span style="color: #007020;">cd</span> ..
catkin_make</pre>
</div>
</div>
<div>
</div>
<h3>
<span style="background-color: white; color: #333333;"><span style="font-family: inherit;"><br /></span></span></h3>
<h3>
<span style="background-color: white; color: #333333;"><span style="font-family: inherit;">Install package video_stream_opencv</span></span></h3>
<div>
<span style="color: #333333;"><span style="background-color: white;">1) Open a terminal</span></span></div>
<div>
<span style="color: #333333;"><span style="background-color: white;">2) In the terminal type:</span></span></div>
<div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">sudo apt-get install ros-kinetic-video-stream-opencv
sudo apt-get update</pre>
</div>
</div>
<h3>
<span style="color: #333333;"><span style="background-color: white;"><br /></span></span></h3>
<h3>
<span style="color: #333333;"><span style="background-color: white;">Create our custom package</span></span></h3>
<div>
<span style="color: #333333;"><span style="background-color: white;">1) Open a terminal in catkin_ws/src</span></span></div>
<div>
<span style="color: #333333;"><span style="background-color: white;">2) In the terminal type:</span></span></div>
<div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">catkin_create_pkg ar_tag_demo std_msgs rospy</pre>
</div>
<h3>
<span style="color: #333333;"><span style="background-color: white;"><br /></span></span></h3>
<h3>
<span style="color: #333333;"><span style="background-color: white;">Install package image_pipeline</span></span></h3>
<div>
<span style="color: #333333;"><span style="background-color: white;">This is likely already installed. You can check with <rospack list>. If it is not simply enter into a terminal:</span></span></div>
<div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">sudo apt-get install ros-kinetic-image-pipeline</pre>
</div>
<span style="color: #333333;"><span style="background-color: white;"><br /></span></span>
<span style="color: #333333;"><span style="background-color: white;">Then run another catkin_make.</span></span><br />
<h2>
<span style="color: #333333;"><span style="background-color: white;">Write Launch Files</span></span></h2>
<div>
<h3>
<span style="color: #333333;"><span style="background-color: white;">Camera.launch</span></span></h3>
<span style="color: #333333;"><span style="background-color: white;">In your custom package "ar_tag_demo", create a new folder called "launch". Inside, create a file called camera.launch. Copy the code below into it. It is a modified version of the camera.launch file from video_stream_opencv. Note that video_stream_provider may have to be changed to 1 if you are using an external camera. If you are using a virtual machine like I am, you will need to enable the webcam under Devices>Webcam in the Virtual Box menu. If you have issues with this, install the Virtual Box extension pack as discussed in <a href="http://projectsfromtech.blogspot.com/2017/09/installing-ros-on-virtual-machine-for.html" target="_blank">my previous post</a>.</span></span><br />
<br /></div>
<div>
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #007700;"><launch></span>
<span style="color: #007700;"><arg</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"camera_name"</span> <span style="color: #0000cc;">default=</span><span style="background-color: #fff0f0;">"camera"</span> <span style="color: #007700;">/></span>
<span style="color: #888888;"><!-- video_stream_provider can be a number as a video device or a url of a video stream --></span>
<span style="color: #007700;"><arg</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"video_stream_provider"</span> <span style="color: #0000cc;">default=</span><span style="background-color: #fff0f0;">"0"</span> <span style="color: #007700;">/></span>
<span style="color: #888888;"><!-- frames per second to query the camera for --></span>
<span style="color: #007700;"><arg</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"fps"</span> <span style="color: #0000cc;">default=</span><span style="background-color: #fff0f0;">"10"</span> <span style="color: #007700;">/></span>
<span style="color: #888888;"><!-- frame_id for the camera --></span>
<span style="color: #007700;"><arg</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"frame_id"</span> <span style="color: #0000cc;">default=</span><span style="background-color: #fff0f0;">"camera_link"</span> <span style="color: #007700;">/></span>
<span style="color: #888888;"><!-- By default, calibrations are stored to file://${ROS_HOME}/camera_info/${NAME}.yaml</span>
<span style="color: #888888;"> To use your own fill this arg with the corresponding url, e.g.:</span>
<span style="color: #888888;"> "file:///$(find your_camera_package)/config/your_camera.yaml" --></span>
<span style="color: #007700;"><arg</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"camera_info_url"</span> <span style="color: #0000cc;">default=</span><span style="background-color: #fff0f0;">""</span> <span style="color: #007700;">/></span>
<span style="color: #888888;"><!-- flip the image horizontally (mirror it) --></span>
<span style="color: #007700;"><arg</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"flip_horizontal"</span> <span style="color: #0000cc;">default=</span><span style="background-color: #fff0f0;">"false"</span> <span style="color: #007700;">/></span>
<span style="color: #888888;"><!-- flip the image vertically --></span>
<span style="color: #007700;"><arg</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"flip_vertical"</span> <span style="color: #0000cc;">default=</span><span style="background-color: #fff0f0;">"false"</span> <span style="color: #007700;">/></span>
<span style="color: #888888;"><!-- force width and height, 0 means no forcing --></span>
<span style="color: #007700;"><arg</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"width"</span> <span style="color: #0000cc;">default=</span><span style="background-color: #fff0f0;">"0"</span><span style="color: #007700;">/></span>
<span style="color: #007700;"><arg</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"height"</span> <span style="color: #0000cc;">default=</span><span style="background-color: #fff0f0;">"0"</span><span style="color: #007700;">/></span>
<span style="color: #888888;"><!-- if show a image_view window subscribed to the generated stream --></span>
<span style="color: #007700;"><arg</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"visualize"</span> <span style="color: #0000cc;">default=</span><span style="background-color: #fff0f0;">"true"</span><span style="color: #007700;">/></span>
<span style="color: #888888;"><!-- images will be published at /camera_name/image with the image transports plugins (e.g.: compressed) installed --></span>
<span style="color: #007700;"><group</span> <span style="color: #0000cc;">ns=</span><span style="background-color: #fff0f0;">"$(arg camera_name)"</span><span style="color: #007700;">></span>
<span style="color: #007700;"><node</span> <span style="color: #0000cc;">pkg=</span><span style="background-color: #fff0f0;">"video_stream_opencv"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"video_stream"</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"$(arg camera_name)_stream"</span> <span style="color: #0000cc;">output=</span><span style="background-color: #fff0f0;">"screen"</span><span style="color: #007700;">></span>
<span style="color: #007700;"><remap</span> <span style="color: #0000cc;">from=</span><span style="background-color: #fff0f0;">"camera"</span> <span style="color: #0000cc;">to=</span><span style="background-color: #fff0f0;">"image_raw"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><param</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"camera_name"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"string"</span> <span style="color: #0000cc;">value=</span><span style="background-color: #fff0f0;">"$(arg camera_name)"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><param</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"video_stream_provider"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"string"</span> <span style="color: #0000cc;">value=</span><span style="background-color: #fff0f0;">"$(arg video_stream_provider)"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><param</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"fps"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"int"</span> <span style="color: #0000cc;">value=</span><span style="background-color: #fff0f0;">"$(arg fps)"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><param</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"frame_id"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"string"</span> <span style="color: #0000cc;">value=</span><span style="background-color: #fff0f0;">"$(arg frame_id)"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><param</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"camera_info_url"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"string"</span> <span style="color: #0000cc;">value=</span><span style="background-color: #fff0f0;">"$(arg camera_info_url)"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><param</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"flip_horizontal"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"bool"</span> <span style="color: #0000cc;">value=</span><span style="background-color: #fff0f0;">"$(arg flip_horizontal)"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><param</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"flip_vertical"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"bool"</span> <span style="color: #0000cc;">value=</span><span style="background-color: #fff0f0;">"$(arg flip_vertical)"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><param</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"width"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"int"</span> <span style="color: #0000cc;">value=</span><span style="background-color: #fff0f0;">"$(arg width)"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><param</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"height"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"int"</span> <span style="color: #0000cc;">value=</span><span style="background-color: #fff0f0;">"$(arg height)"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"></node></span>
<span style="color: #007700;"><node</span> <span style="color: #0000cc;">if=</span><span style="background-color: #fff0f0;">"$(arg visualize)"</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"$(arg camera_name)_image_view"</span> <span style="color: #0000cc;">pkg=</span><span style="background-color: #fff0f0;">"image_view"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"image_view"</span><span style="color: #007700;">></span>
<span style="color: #007700;"><remap</span> <span style="color: #0000cc;">from=</span><span style="background-color: #fff0f0;">"image"</span> <span style="color: #0000cc;">to=</span><span style="background-color: #fff0f0;">"image_raw"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"></node></span>
<span style="color: #007700;"></group></span>
<span style="color: #007700;"></launch></span></pre>
</div>
</div>
<div>
<h3>
<span style="color: #333333;"><span style="background-color: white;"><br /></span></span></h3>
<h3>
<span style="color: #333333;"><span style="background-color: white;">Track.launch</span></span></h3>
</div>
<div>
<span style="color: #333333;"><span style="background-color: white;">Next we create the launch file that does the tracking. Again, this is a modified launch file from the ar_track_alvar package. Create a file called track.launch in your launch file folder and copy the following code inside it. Note that you will need to set the marker size. This is the length in centimeters of one side of the black part of an AR Tag.</span></span><br />
<span style="color: #333333;"><span style="background-color: white;"><br /></span></span></div>
<div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #007700;"><launch></span>
<span style="color: #007700;"><arg</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"marker_size"</span> <span style="color: #0000cc;">default=</span><span style="background-color: #fff0f0;">"6.9"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><arg</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"max_new_marker_error"</span> <span style="color: #0000cc;">default=</span><span style="background-color: #fff0f0;">"0.08"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><arg</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"max_track_error"</span> <span style="color: #0000cc;">default=</span><span style="background-color: #fff0f0;">"0.2"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><arg</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"cam_image_topic"</span> <span style="color: #0000cc;">default=</span><span style="background-color: #fff0f0;">"/camera/image_raw"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><arg</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"cam_info_topic"</span> <span style="color: #0000cc;">default=</span><span style="background-color: #fff0f0;">"/camera/camera_info"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><arg</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"output_frame"</span> <span style="color: #0000cc;">default=</span><span style="background-color: #fff0f0;">"/camera_link"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><node</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"ar_track_alvar"</span> <span style="color: #0000cc;">pkg=</span><span style="background-color: #fff0f0;">"ar_track_alvar"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"individualMarkersNoKinect"</span> <span style="color: #0000cc;">respawn=</span><span style="background-color: #fff0f0;">"false"</span> <span style="color: #0000cc;">output=</span><span style="background-color: #fff0f0;">"screen"</span><span style="color: #007700;">></span>
<span style="color: #007700;"><param</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"marker_size"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"double"</span> <span style="color: #0000cc;">value=</span><span style="background-color: #fff0f0;">"$(arg marker_size)"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><param</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"max_new_marker_error"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"double"</span> <span style="color: #0000cc;">value=</span><span style="background-color: #fff0f0;">"$(arg max_new_marker_error)"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><param</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"max_track_error"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"double"</span> <span style="color: #0000cc;">value=</span><span style="background-color: #fff0f0;">"$(arg max_track_error)"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><param</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"output_frame"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"string"</span> <span style="color: #0000cc;">value=</span><span style="background-color: #fff0f0;">"$(arg output_frame)"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><remap</span> <span style="color: #0000cc;">from=</span><span style="background-color: #fff0f0;">"camera_image"</span> <span style="color: #0000cc;">to=</span><span style="background-color: #fff0f0;">"$(arg cam_image_topic)"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><remap</span> <span style="color: #0000cc;">from=</span><span style="background-color: #fff0f0;">"camera_info"</span> <span style="color: #0000cc;">to=</span><span style="background-color: #fff0f0;">"$(arg cam_info_topic)"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"></node></span>
<span style="color: #007700;"></launch></span></pre>
</div>
</div>
<div>
<h3>
<span style="color: #333333;"><span style="background-color: white;"><br /></span></span></h3>
<h3>
<span style="color: #333333;"><span style="background-color: white;">main.launch</span></span></h3>
</div>
<div>
<span style="color: #333333;"><span style="background-color: white;">Because this is a demo, you might only want to have to launch one file. This launch file simply calls the other two.</span></span></div>
<div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #007700;"><launch></span>
<span style="color: #007700;"><include</span> <span style="color: #0000cc;">file=</span><span style="background-color: #fff0f0;">"$(find ar_tag_demo)/launch/camera.launch"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><include</span> <span style="color: #0000cc;">file=</span><span style="background-color: #fff0f0;">"$(find ar_tag_demo)/launch/track.launch"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"></launch></span></pre>
</div>
</div>
<div>
<h2>
<span style="color: #333333;"><span style="background-color: white;"><br /></span></span></h2>
<h2>
<span style="color: #333333;"><span style="background-color: white;">Running the files</span></span></h2>
</div>
<h3>
<span style="color: #333333;"><span style="background-color: white;">Camera Calibration</span></span></h3>
<div>
<span style="color: #333333;"><span style="background-color: white;">You will want to calibrate the camera using the camera_calibrate node (part of the image_pipeline package). You can follow the instructions found on the wiki for monocular camera calibration: <a href="http://wiki.ros.org/camera_calibration/Tutorials/MonocularCalibration">http://wiki.ros.org/camera_calibration/Tutorials/MonocularCalibration</a></span></span><br />
<div>
<span style="color: #333333;"><span style="background-color: white;"><br /></span></span>
<span style="color: #333333;"><span style="background-color: white;">Here are the pertinent parts: </span></span></div>
<span style="color: #333333;"></span><br />
<div>
<span style="color: #333333;"><span style="background-color: white;">1) Print the <a href="http://wiki.ros.org/camera_calibration/Tutorials/MonocularCalibration?action=AttachFile&do=view&target=check-108.pdf" target="_blank">checkerboard pdf</a>.</span></span><br />
<span style="color: #333333;"><span style="background-color: white;">2) Open a terminal and type:</span></span></div>
</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">rosdep install camera_calibration
rosrun ar_tag_demo camera.launch
rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.0245 image:<span style="color: #333333;">=</span>/camera/image_raw camera:<span style="color: #333333;">=</span>/camera
</pre>
</div>
<div>
<span style="color: #333333;"><span style="background-color: white;"><br /></span></span></div>
<div>
Note that that the grid size (8x6) and square size (.0245) is for the above as printed on my printer. You may have to adjust it. The square size is in meters.<br />
<br />
3) Complete the calibration by moving the checkerboard around the camera's field of view and rotating it in all directions.<br />
4) When you are done, click commit to automatically save the camera calibration data. The camera node will now automatically pull that calibration file when you launch it.</div>
<div>
5) ctrl + c in all terminal windows to stop camera and calibration nodes<br />
<h3>
Run the demo</h3>
</div>
<div>
In a terminal type the following command. </div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">roslaunch ar_tag_demo main.launch
</pre>
</div>
<div>
<span style="color: #333333;"><span style="background-color: white;"><br /></span></span>
<span style="color: #333333;"><span style="background-color: white;">T</span></span>his should bring up the camera and the tracking node. Feel free to rostopic echo ar_pose_marker to see the raw data, but RVIZ is probably more impressive. Launch RVIZ (type rviz into a terminal), and add TF to the data visualized on the left. Show the camera a marker, then set fixed frame to "camera_frame". You should now see something like this!<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-Y-XiRDrAxn4/WcQ8v-IE0DI/AAAAAAAABCo/Ycmu0kNsa9sBTXNfCA9A1uWOoWieG2jTQCLcBGAs/s1600/Capture1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="687" data-original-width="1118" height="392" src="https://1.bp.blogspot.com/-Y-XiRDrAxn4/WcQ8v-IE0DI/AAAAAAAABCo/Ycmu0kNsa9sBTXNfCA9A1uWOoWieG2jTQCLcBGAs/s640/Capture1.PNG" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Show off your AR tag demo with pride! Don't tell anyone that Scott Neikum (the code maintainer) did all the hard work for you.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
I hope this was helpful to someone. If it was, comment below and let me know. If you run into any problems or see anything that should be changed, comment below for that as well. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Until next time,</div>
<div class="separator" style="clear: both; text-align: left;">
Matthew</div>
</div>
</div>
</div>
Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-68055040953643416312017-09-21T18:05:00.001-05:002017-09-21T18:05:40.158-05:00Installing ROS on a Virtual Machine for WindowsThis is a quick set of instructions for installing ROS Kinetic on a Virtual Machine. This allows you to run ROS on Windows.<br />
<br />
1) Install Virtual Box from this <a href="https://www.virtualbox.org/wiki/Downloads" target="_blank">link</a>.<br />
2) Install the Virtual Box Extension Pack for your version of Virtual Box (also at this <a href="https://www.virtualbox.org/wiki/Downloads" target="_blank">link</a>). This allows you to use the USB ports on your computer within the virtual machine.<br />
3) Download the Ubuntu 16.04 LTS .iso from this <a href="https://www.ubuntu.com/download/desktop" target="_blank">link</a>.<br />
4) Run Virtual Box and create a virtual machine with the .iso you downloaded.<br />
5) In the virtual machine go to Devices > Insert Guest Additions CD image and install guest additions. This adds additional functionality, most notably the shared clipboard. Enable this under Devices > Shared Clipboad > Bidirectional.<br />
6) Follow the instructions on the ROS Wiki to install ROS Kinetic (<a href="http://wiki.ros.org/kinetic/Installation/Ubuntu" target="_blank">link</a>).<br />
7) Follow the instructions on the ROS Wiki to setup your Catkin workspace (<a href="http://wiki.ros.org/ROS/Tutorials/InstallingandConfiguringROSEnvironment" target="_blank">link</a>).<br />
8) Make a snapshot of your new clean ROS install by going to Machine > Take Snapshot. This allows you to roll back to a fresh install if you tank it at some point.<br />
9) Proceed to other projects! Here are some of mine to get you started (<a href="http://projectsfromtech.blogspot.com/search/label/ROS" target="_blank">link</a>)<br />
<br />
MatthewMatthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-57432335335036814012017-05-28T18:00:00.000-05:002017-05-29T17:05:20.469-05:00Arduino 101 - An Introduction to the Intel Curie Module Development BoardThis post is about the Arduino/Genuino Board 101 - the Intel Curie Module development board. It is a not an introduction to Arduino, AKA Arduino 101.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-jrJCDydqnAE/WSybDKXQrfI/AAAAAAAABCM/LtyxOfhKOUIVsxJj2VfmmJnTs4zhTt7GwCLcB/s1600/IMG_20170509_164350536.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1118" data-original-width="1600" height="223" src="https://3.bp.blogspot.com/-jrJCDydqnAE/WSybDKXQrfI/AAAAAAAABCM/LtyxOfhKOUIVsxJj2VfmmJnTs4zhTt7GwCLcB/s320/IMG_20170509_164350536.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-o-Gv6HcWfQ8/WSya54oNxzI/AAAAAAAABCI/0Okhx7PeRjoHIRF4QLR7vpWHNEaxVvr4gCLcB/s1600/IMG_20170509_164401165.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1192" data-original-width="1600" height="238" src="https://1.bp.blogspot.com/-o-Gv6HcWfQ8/WSya54oNxzI/AAAAAAAABCI/0Okhx7PeRjoHIRF4QLR7vpWHNEaxVvr4gCLcB/s320/IMG_20170509_164401165.jpg" width="320" /></a> </div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<h3>
Introduction</h3>
<div>
This post is just a quick introduction to the Arduino 101. I plan to do a couple of projects in the future involving it, and I want to document a few of the questions I had when initially considering whether or not this board will work for me. I will likely update this post with any other issues I run into. </div>
<div>
<br /></div>
<div>
The Arduino 101 is very different from the classic Atmel AVR based chips the world has come to know and love. The old AVR based Arduinos (easily spotted by the plethera of low cost generics available on sites like eBay) are traditional microcontroller development boards. They are basically just microcontrollers packaged conveniently and paired with the all important Arduino IDE. While I honestly have had very little exposure to most of the vast array of new boards covering the Arduino universe these days, I can say the Arduino 101 is not your slightly-younger-self's AVR. It instead is based on the very capable Intel Curie Module and wraps it in a software architecture to give you a board that looks and feels like an Arduino Uno but performs like something else entirely. Bluetooth Low Energy (BLE) support and a built in IMU make this a very capable little board for $30. While it is being marketed as an internet of things board, I say why has no one made this into a drone yet?</div>
<div>
<br /></div>
<div>
<div>
</div>
Overall the Arduino 101 looks like a very powerful board for anyone with the willingness to dig into the datasheets. As it is further developed, I have no doubt it will become a hallmark of the new multi-core (non-AVR) Arduino family. </div>
<div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br /></div>
<h2>
Questions Answered</h2>
<h3>
What IMU is in the Arduino 101?</h3>
<div>
The <a href="https://www.bosch-sensortec.com/bst/products/all_products/bmi160">Bosch BMI160</a></div>
<div>
<br /></div>
<h3>
Is there an included IMU sensor fusion algorithm?</h3>
<div>
It does not appear that there is any sort of sensor fusion capability exposed at the Arduino level at the time of this writing. However, the 32 MHz processor is more than capable of running the Madgwick algorithm, and there is a library <a href="https://github.com/arduino-libraries/MadgwickAHRS">ready to go</a> out of the box. I imagine it is only a matter of time before it or some Kalman filter variant is included in the Curie download or sensor fusion is implemented at a lower level. See the <a href="https://www.arduino.cc/en/Tutorial/Genuino101CurieIMUOrientationVisualiser">visualization tutorial</a>.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<h2>
Resources</h2>
<div>
<ul>
<li><a href="https://drive.google.com/file/d/0B6s_UhmkBLQfcnV5ak1vQW43T2c/view?usp=sharing">Intel Curie Module Datasheet</a></li>
<li><a href="https://drive.google.com/file/d/0B6s_UhmkBLQfci1NTDdWSEw4TVk/view?usp=sharing">Bosch BMI160 Datasheet</a></li>
<li><a href="https://www.arduino.cc/en/Main/ArduinoBoard101">Arduino 101 Hardware</a></li>
<li><a href="https://www.arduino.cc/en/Reference/CurieIMU">Curie IMU Library Reference</a></li>
<li><a href="https://www.arduino.cc/en/Guide/Arduino101">Arduino 101 Getting Started</a></li>
<li><a href="https://software.intel.com/en-us/articles/getting-to-know-the-arduino-101-platform">Intel - Getting to Know the Arduino 101</a> </li>
</ul>
</div>
</div>
<br />
<h2>
Troubleshooting</h2>
<h3>
Uploading Script Problem</h3>
When I first tried to use the Arduino 101 I got the "ERROR: Timed out waiting for Arduino 101 on COM##" error. No amount of pressing the Master Reset would fix it. I was running Curie Core 2.0.2 on Windows 7, so I tried reverting to 1.0.7. Then I tried running as an administrator. Eventually I tried changing USB ports. My computer has a 2.0 port as well as a 3.0. When I changed to the USB 2.0 it worked. This could very well mean that I simply have a flaky USB port. I've certainly triggered the fuse on it a few times. However, I mention it here simply in case someone else has this problem. In my case, switching to my USB 2.0 port fixed it.<br />
<br />
Matthew<br />
<br />
<br />
<br />
<br />Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-31964988323211922272016-11-26T08:00:00.000-06:002016-11-26T08:00:30.551-06:00Arduino Interrupt Stepper Driver - CTC Mode<h3>
Introduction to the Problem</h3>
This tutorial will show how to drive a Pololu style stepper (A4988) driver using a timer interrupt. This method is non blocking, efficient, and as far as I know is pretty much what most 3D printer firmwares use.<br />
<br />
The idea is this. A pololu style stepper driver (the kind that plugs into the RAMPS board) only requires two inputs from the Arduino. One is a direction pin. The other is a pulse train. One rising edge equals one step (or micro step, depending on how the set pins are wired). Most people when they first get going with steppers probably do one of two things. 1) They use some library that does all this for them (I don't know if one exists, but maybe it does) or 2) They just throw a digitalWrite in the loop() and pulse it that way. The problem with that is that it is dependent on the speed with which the loop runs. Enter Timer Interrupts<br />
<br />
<h3>
Interrupts - Conceptually</h3>
The timer interrupt is a low level feature of the ATmega family. It is not something that is provided by Arduino, and in fact functions such as millis() and delay() are based on them. I have always been a bit surprised that Arduino does not break timer interrupts out a little. They are really pretty easy to use but are very powerful. I am not going to go into great detail on the specifics of timer interrupts because there are other sources out there. The best of which is the ATmega datasheet.<br />
<br />
The idea is this - the ATmega CPU is sitting there executing your code, pulling commands off of the stack. It does this in the same order each time. On another part of the chip there is this thing called a timer. It is counting up from 0 to some value over and over again incrementing at a set frequency. When it reaches the target value it sets a flag and goes back to 0. When that flag is set, the ATmega chip sees it and says, "it is time to execute a special piece of code. Drop everything and do it." What ever it was doing before goes back on the stack and what you put in the "interrupt service routine (ISR)" gets executed. Then it goes back to its normal business. We want to put our "pulse stepper driver" code in the ISR.<br />
<br />
There are a couple of dangers with this, but I will just leave you with this. Keep the ISR short. Don't do any serial prints or heavy computations (floating point math) in there. Calculate those ahead of time and pull them in as compile time constants ideally.<br />
<br />
<h3>
Solving the Problem</h3>
Now I actually came up with 3 ways of solving this problem<br />
<ol>
<li>Using a fixed rate Timer Interrupt and only pulsing on some of the ISRs</li>
<li>Using CTC mode and pulsing inside the ISR</li>
<li>Using a special PWM mode </li>
</ol>
<div>
This tutorial covers method 2. It uses Timer5 in Clear Timer on Compare (CTC) Mode. This allows you to call an interrupt at whatever frequency you want. If you're familiar with timer interrupts the picture below might help. Again, I will not take the time to go into that much detail on that in this post. For now, I will point you to the ATMega datasheet which covers all of this stuff and <a href="http://maxembedded.com/2011/07/avr-timers-ctc-mode/">THIS</a> post by maxembedded.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://2.bp.blogspot.com/-D4JFGJi0YhY/WCn_cdbZm7I/AAAAAAAABBE/h049l7p54Dk7HHF2teG8cBlrF0TJW6N5gCLcB/s1600/AVR%2BCTC%2BMode.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="119" src="https://2.bp.blogspot.com/-D4JFGJi0YhY/WCn_cdbZm7I/AAAAAAAABBE/h049l7p54Dk7HHF2teG8cBlrF0TJW6N5gCLcB/s320/AVR%2BCTC%2BMode.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">CTC Mode - From ATMega Datasheet</td></tr>
</tbody></table>
<br />
Another important point is that I use direct port manipulation in the interrupt. I will not cover that here, but there are numerous examples online of how that works in addition to the ATMega datasheet. <a href="http://tronixstuff.com/2011/10/22/tutorial-arduino-port-manipulation/">HERE</a> is one example. I use direct port manipulation because it is much faster. As stated above, the ISR should execute as quickly as possible.</div>
<div>
<br />
<h3>
The Practical Stuff</h3>
</div>
<div>
Copy the code below. Wire it according to pins set in the code. Change the pulses per second calculation based on your setup (change it in the ISR Location calculation too). Set targSpeed in mm/s. Then set the <span style="background-color: white; color: #3b3b3b;">Z_DIR_PIN and DirFlag based on the direction you want to drive. Test your code.</span></div>
<div>
<br /></div>
<div>
I hope this is helpful to someone. If it is, please let me know in the comments. If anyone that reads this has any insight into libraries available or other methods, comment those too. Good luck!</div>
<div>
<br /></div>
-Matthew<br />
<u><br /></u>
<br />
<pre style="background: #fff; color: #3b3b3b;"></pre>
<pre style="background: #fff; color: #3b3b3b;"><span style="color: #af82d4;">/*
* Drives stepper using a pololu stepper driver and timer interrupts
*
* This example uses pinouts associated with RAMPS 1.4 z-axis
*
* Last edited by Matthew 11/14/2016 Arduino 1.6.7
* projectsfromtech.blogspot.com
* TRCCR1A/B
* COM1A = 0b00 - disconnect OCR
* WGM1 = 0b0100 - Fast PWM with the top value at compare match
* CS1 = 0b001 - no prescaling
* ICNC1 = ICES = 0b0 - doesn't apply
*
* */</span>
<span style="color: #ff5600;">const</span> byte Z_STEP_PIN = <span style="color: #a8017e;">46</span>;
<span style="color: #ff5600;">const</span> byte Z_DIR_PIN = <span style="color: #a8017e;">48</span>;
<span style="color: #ff5600;">const</span> byte Z_ENABLE_PIN = <span style="color: #a8017e;">62</span>; <span style="color: #af82d4;">//62</span>
<span style="color: #af82d4;">//Interrupt Variables</span>
<span style="color: #ff5600;">volatile</span> <span style="color: #a535ae;">uint16_t</span> PulseOnISRNum = <span style="color: #a8017e;">0</span>;
<span style="color: #ff5600;">volatile</span> <span style="color: #a535ae;">uint16_t</span> isrSincePulse = <span style="color: #a8017e;">0</span>;
<span style="color: #af82d4;">//============================================================================</span>
<span style="color: #ff5600;">void</span> <span style="color: #21439c;">setup</span>() {
Serial.<span style="color: #45ae34; font-weight: 700;">begin</span>(115200);
pinMode(Z_STEP_PIN, OUTPUT);
pinMode(Z_ENABLE_PIN,OUTPUT);
pinMode(Z_DIR_PIN, OUTPUT);
//setup Timer1
TCCR5A = 0b00000000;
TCCR5B = 0b00001001;
TIMSK5 |= 0b00000010; //set for output compare interrupt
sei(); //enables interrups. Use <span style="color: #0053ff; font-weight: 700;">cli</span>() to turn them off
}
<span style="color: #ff5600;">float</span> targSpeed = <span style="color: #a8017e;">2.5</span>; <span style="color: #af82d4;">// mm/s</span>
<span style="color: #ff5600;">float</span> PPS = <span style="color: #a8017e;">0</span>; <span style="color: #af82d4;">// Pulses Per Second</span>
<span style="color: #a535ae;">int8_t</span> DirFlag = <span style="color: #a8017e;">1</span>; <span style="color: #af82d4;">// Direction flag. Set this to keep track of location</span>
<span style="color: #a535ae;">int32_t</span> Location = <span style="color: #a8017e;">0</span>; <span style="color: #af82d4;">// nanometers (m*10^-9) scaled by 10^-6 to avoid floating point math in interrupt</span>
<span style="color: #ff5600;">long</span> clk = micros();
<span style="color: #af82d4;">//============================================================================</span>
<span style="color: #ff5600;">void</span> <span style="color: #21439c;">loop</span>() {
//Set Direction
digitalWrite(Z_DIR_PIN, LOW); // Low is <span style="color: #0053ff; font-weight: 700;">forward</span> (based on setup)
DirFlag = 1;
// digitalWrite(Z_DIR_PIN,HIGH); // High is <span style="color: #0053ff; font-weight: 700;">backward</span> (based on setup)
// DirFlag = -1;
digitalWrite(Z_ENABLE_PIN , LOW); // Active Low
// Set Speed - these calculation are based on your harware setup
// - Mine are for 1/16 microstepping and an m5 threaded rod driving the stage
//------------------------
for(float ind = 0 ; ind <3.0 ; ind = ind+0.0005)
{
targSpeed = ind; // mm/s
PPS = targSpeed * 4000; //Pulses/s
OCR5A = 16000000/PPS - 1; //equation from pg 146 in datasheet- removed factor of 2 b/c I am manually pulsing in an interrupt every time
Serial.<span style="color: #45ae34; font-weight: 700;">print</span>("<span style="color: #45ae34; font-weight: 700;">Speed</span> (mm/s): ");
Serial.<span style="color: #45ae34; font-weight: 700;">print</span>(targSpeed);
Serial.<span style="color: #45ae34; font-weight: 700;">print</span>(" Loop <span style="color: #0053ff; font-weight: 700;">Time</span> (ms): ");
Serial.<span style="color: #45ae34; font-weight: 700;">print</span>(<span style="color: #45ae34; font-weight: 700;">micros</span>()-clk);
Serial.<span style="color: #45ae34; font-weight: 700;">print</span>(" Location (mm): ");
Serial.<span style="color: #45ae34; font-weight: 700;">println</span>(Location/1000000.);
clk=<span style="color: #45ae34; font-weight: 700;">micros</span>();
// Input other code here! Stepper driver will run even if this code is blocking!
}}
<span style="color: #af82d4;">//================================================================================</span>
<span style="color: #21439c;">ISR</span>(TIMER5_COMPA_vect) {
// digitalWrite(46, HIGH); // Driver only looks for rising edge
// digitalWrite(46, LOW); // DigitalWrite executes in 16 us
//Generate Rising Edge
PORTL = PORTL |= 0b00001000; //Direct Port manipulation executes in 450 ns => 16x faster!
PORTL = PORTL &= 0b11110111;
Location = Location + 250 * DirFlag ; //Updates <span style="color: #0053ff; font-weight: 700;">Location</span> (based on 4000 Pulses/mm)
}
</pre>
Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com1tag:blogger.com,1999:blog-4542176549692404194.post-91116084625600353502016-11-19T08:00:00.001-06:002016-11-19T08:00:06.897-06:00Raspian ROS on Raspberry PI B+ with Downloadable ImageI wanted to share my image of ROS Indigo for a Raspberry Pi B+. When I tried a couple of images I found online, none of them seemed to work, so I had to make my own. I will warn you that it is pretty slow, but ROS is installed. I was originally going to use this onboard a turtlebot, but I decided against it after seeing how slow it was. As far as I know it would work, but the extent of my testing was launching roscore. Here is the process I went through to create the image.<br />
<br />
<ol>
<li><a href="https://www.raspberrypi.org/documentation/installation/installing-images/README.md">Install Raspian </a>Jessie with Pixel version September 2016</li>
<li><a href="http://wiki.ros.org/ROSberryPi/Installing%20ROS%20Indigo%20on%20Raspberry%20Pi">Follow instructions </a>on the ROS wiki for the ROS-Comm version on Indigo</li>
<li><a href="https://www.raspberrypi.org/documentation/installation/installing-images/">Pull Image</a> using Win32DiskImager</li>
</ol>
<br />
Download the image here: <a href="https://drive.google.com/file/d/0B6s_UhmkBLQfS25ublhJYUFab3M/view?usp=sharing">Raspian_PiBPlus_ROS_Indigo_11_17_2016.7z</a><br />
<br />
<br />
Notes:<br />
<br />
<ul>
<li>It would probably be better to use the minimal version of Raspian. Like I commented above, it is pretty slow</li>
<li>I had issues building the catkin workspace. I think it was RAM related as the wiki suggests. I ended up closing everything that was open and running with the default -j4 option, and it worked.</li>
<li>Contrary to seemingly popular belief, ROS can be installed on an original Raspberry Pi. It is just painful. My install took several hours.</li>
<li>The image is 2.287 Gb compressed and 31.260 Gb uncompressed. </li>
</ul>
<div>
I hope this is useful to someone.</div>
<div>
-Matthew</div>
Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-79145271262615537302016-11-12T15:42:00.000-06:002016-11-12T15:42:24.922-06:00Replacing a Burnt Out MOSFET in an AR6400This is a quick post about changing the MOSFET in an AR6400. This appears to be a a fairly common problem people have with RC airplanes such as the Hobbyzone Champ or the Parkzone P51 Mustang. Symptoms include elevator or other control surface only moving in one direction, elevator or other control surface not moving at all, or a distinct electronics burning smell emanating from the control board. This appears to be usually caused by plugging in the battery backwards.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://1.bp.blogspot.com/-ljc7kPcaAow/WCc2CgQd2_I/AAAAAAAABAs/-9-lxfSmaq4ahIr2TsSrhZOJUd1t_Dj_wCLcB/s1600/AR6400.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="180" src="https://1.bp.blogspot.com/-ljc7kPcaAow/WCc2CgQd2_I/AAAAAAAABAs/-9-lxfSmaq4ahIr2TsSrhZOJUd1t_Dj_wCLcB/s320/AR6400.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">My AR6400L with MOSFET Desoldered</td></tr>
</tbody></table>
<br />
I don't really have a whole lot in the way of new information on the subject. I am just going to compile some of the necessary resources here for reference.<br />
<br />
The replacement part is the<b> FDG6322C.</b> When I considered shipping, the cheapest place I could find in a short search was DigiKey. I would buy extras. They are extremely tiny. Here is the datasheet.<br />
<a href="https://www.fairchildsemi.com/datasheets/FD/FDG6322C.pdf">https://www.fairchildsemi.com/datasheets/FD/FDG6322C.pdf</a><br />
<br />
One useful piece of information is that the two sides are wired the same, so if one is still intact you can use that side as reference. Here is a schematic taken from an rcgroups forum post that I found helpful.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://1.bp.blogspot.com/-CJtF6WulAOQ/WCT_6hkwdsI/AAAAAAAABAE/eus2WKZBub4Zjj_vvrssVPG3MO_EtzJ9ACLcB/s1600/HPIM1878.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://1.bp.blogspot.com/-CJtF6WulAOQ/WCT_6hkwdsI/AAAAAAAABAE/eus2WKZBub4Zjj_vvrssVPG3MO_EtzJ9ACLcB/s320/HPIM1878.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Photo Credit: RCgroups.com member greghol</td></tr>
</tbody></table>
<br />
Here are the forum posts I used for reference. Really, the only pieces of information I would say you will need is the schematic and part number above.<br />
<br />
<a href="https://www.rcgroups.com/forums/showthread.php?t=960011&page=3">https://www.rcgroups.com/forums/showthread.php?t=960011&page=3</a><br />
<br />
<a href="https://www.rcgroups.com/forums/showthread.php?t=1221866#post14761707">https://www.rcgroups.com/forums/showthread.php?t=1221866#post14761707</a><br />
<br />
<a href="https://www.rcgroups.com/forums/showthread.php?t=1837318">https://www.rcgroups.com/forums/showthread.php?t=1837318</a><br />
<br />
One last word of encouragement. I was able to do this with a pretty standard Weller SPG40 soldering iron. My burnt out MOSFET actually disentegrated while I was trying to remove it, but after replacing it the board works fine. It will fly again.<br />
<br />
Notes:<br />
At the time of this writing, these are some prices if you can't fix it.<br />
<br />
<ul>
<li> AR6400L - $60 (Ebay)</li>
<li>Hobbyzone Champ - $89.99 (Your local hobby shop)</li>
<li>HobbyKing SuperMicro control board - $22.68 (<a href="https://hobbyking.com/en_us/2-4ghz-supermicro-systems-dsm2-compatible-receiver-w-brushed-esc-linear-servos.html">HobbyKing</a>)</li>
</ul>
<br />
-Matthew<br />
<br />Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-82560050515850828722016-09-28T22:07:00.001-05:002016-09-28T22:07:37.931-05:00Combining and Trimming Videos Without Re-encoding Using FMPEG<br />
Recently I was tasked with trimming and combining some videos for work. We had filmed 16 hours of lectures and needed to make them ready to be published. Unfortunately the cameras we used split the video into 19 minute segments that then had to be recombined into one long video. I got to work.<br />
<br />
It was recommended to me that I just use Windows Movie Maker. I was skeptical, but I decided to give it a try. I copied the first 3 videos into the Windows Movie Maker workspace and waited. After waiting several minutes for the files to import and seeing the progress bar barely move, I decided there had to be a better way. I had used FFMPEG in the past in the form of SUPER media encoder. However, this time I decided to go directly to the source and use FFMPEG from the command line. Since Windows 7 (64 bit) is my primary operating system, I would use that. Likewise, my videos are mp4 files, so these instructions are written for those.<br />
<br />
Disclaimer: I am not an FFMPEG expert. This is just what I found that worked for me. No guarantees that it is the most efficient way or that it will even work for you.<br />
<br />
<h3>
1) Download FFMPEG - <a href="https://www.ffmpeg.org/download.html">https://www.ffmpeg.org/download.html</a></h3>
FFMEG can be found at the link above. Select your operating system and put it in a convenient folder (I used a Windows static version). Unzip it, and it is ready to use.<br />
<br />
<h3>
2) Separate Files into Directories</h3>
<div>
The first thing you are going to want to do is separate each set of files that you want to join into directories (ie. folders). One thing to make your life easier, make the name short and leave out any spaces. For example, "JohnsBirthday" instead of "Johns Birthday May 22 1934"</div>
<div>
<br />
<h3>
3) Run Batch File and Navigate to Directory</h3>
</div>
<div>
Run the batch file in the folder where you unzipped FFMPEG. It should be called "ff-prompt.bat". This will launch FFMPEG in a command prompt in the directory where it is located. </div>
<div>
<br /></div>
<div>
Now you need to navigate in the command prompt to the directory (the folder) where you put the videos. If you know how to do this, use your favorite method. If you don't, here are some basic instructions. "cd" is the command to <b>c</b>hange <b>d</b>irectory. The usage is below.</div>
<div>
<ul>
<li>Use "cd .." to go up one level</li>
<li>Use "cd folderName" to navigate to a folder in your current directory</li>
</ul>
<div>
If you get lost, you could always put the videos you are working on in the folder with the batch file. Then you would not have to navigate anywhere.</div>
</div>
<div>
<br /></div>
<h3>
4) Combine Videos Using FFMPEG</h3>
<div>
<br /></div>
<div>
To combine a video we are going to "concatenate" them. If you are familiar with programming, it is the same concept as concatenating a string. You are taking one and sticking on the end of the other. <a href="https://trac.ffmpeg.org/wiki/Concatenate">HERE</a> is the link to the ffmpeg wiki page with the documentation, but I will copy the steps below that I used.</div>
<div>
<br /></div>
<div>
<b>1)</b> Copy the command below into the command line you have open. Replace "mp4" with the file type of your videos (.wav, .mov, etc.). Then run the command. It should execute very quickly.</div>
<div>
<pre class="wiki" style="background: rgb(247, 247, 247); border-radius: 0.3em; border: 1px solid rgb(215, 215, 215); box-shadow: rgb(238, 238, 238) 0px 0px 1em; font-size: 13px; margin: 1em 1.75em; overflow: auto; padding: 0.25em;">(for %i in (*.mp4) do @echo file '%i') > mylist.txt</pre>
</div>
<div>
This creates a list of the files to be concatenated. Alternatively, you can create the file by hand. One note on this, I am not sure how it determines the order. It seems to be by the name. Also, spaces in the name cause problems, so make sure no file names have spaces. </div>
<div>
<br /></div>
<div>
<b>2) </b>Now copy this into the command line you have open. Note that the ".mp4" was added by me to get it to work. The wiki implies you shouldn't need it.</div>
<div>
<pre class="wiki" style="background: rgb(247, 247, 247); border-radius: 0.3em; border: 1px solid rgb(215, 215, 215); box-shadow: rgb(238, 238, 238) 0px 0px 1em; font-size: 13px; margin: 1em 1.75em; overflow: auto; padding: 0.25em;">ffmpeg -f concat -i mylist.txt -c copy output.mp4</pre>
</div>
<div>
This will take some time to execute, but it will still be much faster than re-encoding the video. I was combining about 1.5Gb of video and it took 3 minutes.</div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://2.bp.blogspot.com/-F77t0krJ4xw/V-Pr13UzjXI/AAAAAAAAA_g/kukK4hdF_wsiOnwkPVP4q7c2GNrMTAfqwCLcB/s1600/Done%2BConcatonating%2Bcmd.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="208" src="https://2.bp.blogspot.com/-F77t0krJ4xw/V-Pr13UzjXI/AAAAAAAAA_g/kukK4hdF_wsiOnwkPVP4q7c2GNrMTAfqwCLcB/s320/Done%2BConcatonating%2Bcmd.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Command Line at the End of Successful Execution</td></tr>
</tbody></table>
<div>
<br /></div>
<div>
<b>3)</b> Verify video. I went through and double checked at the points were it transitioned to make sure everything worked out. This step is obviously optional</div>
<div>
<br /></div>
<div>
<h3>
5) Trim Videos Using FFMPEG</h3>
<div>
Trimming is a bit more complicated. "Why does my audio get desynced when trimming with FMPEG?" This is because of something called "key frames" that mp4 files use. I did not take the time to research those all that much, but the long and short seems to be that you have to trim at a key frame if you want to be able to trim a video without re-encoding or desyncing the audio. This is the command line instruction.</div>
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: "Times New Roman"; font-size: medium; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
<div style="margin: 0px;">
<span style="font-family: monospace; font-size: 13px; white-space: pre;"></span></div>
<pre class="wiki" style="background: rgb(247, 247, 247); border-radius: 0.3em; border: 1px solid rgb(215, 215, 215); box-shadow: rgb(238, 238, 238) 0px 0px 1em; font-size: 13px; margin: 1em 1.75em; overflow: auto; padding: 0.25em;">ffmpeg -ss 00:03:35 -i output.mp4 -t 00:57:04 -c copy outputtrimmed.mp4</pre>
</div>
</div>
As best I understand it, here is what is happening - the -ss "searches" for the closest key frame to the time 00:03:35. This will happen at the speed of re-encoding (slow). It will then pull in the file "output.mp4" starting at that key frame and will copy from that frame until time 00:57:04 into the file "outputtrimmed.mp4". This part will happen without re-encoding and will be fairly fast. This does not allow to trim at exact points, but it allows you to do it quickly and without losing audio sync (both important in my book).<br />
<br />
<h3>
6) Repeat</h3>
<div>
Do this for all of your videos.<br />
<br />
<h3>
Conclusion</h3>
<div>
So that is how I combined and trimmed a bunch of 19 minute segments into hour long blocks totaling about 16 hours quickly and without re-encoding the video. No guarantees it will work for you. I just had a hard time finding detailed instructions on this, so I thought I would post. One note, I imagine trimming before you combine would speed up the process a bit. For me it just made sense to do it after so I would not have to juggle so many files. The process isn't that long anyway.</div>
<div>
<br /></div>
<div>
That's it! If you have any questions or comments post those in the comments below. If you have any other methods to try or ways to make this better, post those too!</div>
</div>
<div>
<br /></div>
<div>
Until later,</div>
<div>
-Matthew</div>
<div>
<br /></div>
<div>
<br /></div>
Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-90615939367638528872015-12-25T14:54:00.000-06:002015-12-25T14:54:27.666-06:00Fixing Login on Xiaomi Mi Band 2This will be a fairly short post. I just wanted to get this out there in case others are working on this over Christmas. I may update this later as things progress. This all occurred yesterday 12/24/2015.<br />
<br />
My mother received a mi band 2 for Christmas this year, and I was tasked with setting it up. I downloaded the latest version of mifit (version 1.8.111) and followed the setup procedure. I created an account using an email address and logged into google when prompted.<br />
<br />
I tried multiple times, but it always gave an error - either "error 96103" or "invalid email address".<br />
<h3>
<br /></h3>
<h3>
<br />What worked for me...</h3>
<div>
1) Uninstall the most recent app.</div>
<div>
2) Download an older version of the app. I used version 1.3.412 found <a href="http://www.apkmirror.com/apk/xiaomi-technology/mi-fit/mi-fit-1-3-412-android-apk-download/">HERE</a>, but I cannot vouch for its safety apart from not receiving any obvious damage.</div>
<div>
3) Transfer this file to the phone (or download it on the phone) and click on it. I used ES Filer Explorer for this.</div>
<div>
4) Run this file. On ES File Explorer just navigate to the file, tap it, and select install. Here you may be required to turn off a security setting or two. Do this at your own risk. I would recommend turning it back on when you're done.</div>
5) Follow the setup procedure and create an account. You will be required to put in a phone number and an email address.<br />
6) Uninstall the old version.<br />
7) Reinstall the current version and log in with the account you created.<br />
8) Enjoy your mi band and comment on this page how the process went.<br />
<br />
<h3>
What I suspect will also work...</h3>
Just create an account using a phone number. The older version of the app requires a phone number to create the account. This leads me to believe just using the most recent app and selecting "create account with phone number" (or something like that) might also work.<br />
<br />
If this works please comment on this post, so others will know. If you know of any other fixes please mention them there as well.<br />
<br />
<h3>
What didn't work - but could be tried again...</h3>
<div>
I tried using this link on a laptop. This did not work. It gave me the page below.</div>
<div>
<a href="https://account.xiaomi.com/pass/register">https://account.xiaomi.com/pass/register</a></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-8f0sAL-1PRc/Vn2qsR38NdI/AAAAAAAAA_M/8K1mFqJK4Hc/s1600/email%2Baddress%2Bincorrect.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="220" src="http://1.bp.blogspot.com/-8f0sAL-1PRc/Vn2qsR38NdI/AAAAAAAAA_M/8K1mFqJK4Hc/s320/email%2Baddress%2Bincorrect.PNG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
I hope this helps. Merry Christmas!</div>
<div>
-Matthew </div>
Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-90797826091139010672015-12-06T21:02:00.000-06:002015-12-29T11:07:34.394-06:003D Printed Disc Golf Disc<h4>
Disclaimer</h4>
I will begin by saying, if you are thinking about printed a disc golf disc to get into disc golf, don't. Go buy a nice 165g dx shark online for $10 and know exactly how its going to fly when you take it out of the plastic. With that said, this was an interesting proof of concept that might be fun for others to attempt. If you had better filament materials, I believe it could be possible to print a fairly useful disc.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-GrleKJtZDYc/Vlk70J5qVWI/AAAAAAAAA-0/xGwTSXr87yg/s1600/IMG_2442.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://4.bp.blogspot.com/-GrleKJtZDYc/Vlk70J5qVWI/AAAAAAAAA-0/xGwTSXr87yg/s320/IMG_2442.JPG" width="240" /></a></div>
<br />
<h4>
Intro</h4>
I originally used my X-out KC Pro Roc as a pattern for what my disc should look like. Taking measurements off of the disc directly as well as using dimensions from the PDGA list of approved discs I was able to get a model of something that looked pretty close to the Roc. From the dimensions of my<a href="http://projectsfromtech.blogspot.com/2015/03/replikeo-prusa-i3-rework-build-part-4.html"> Prusa i3</a> print bed I decided that I would split the rim into thirds and then a single piece central domed flightplate.<br />
<br />
<a href="http://2.bp.blogspot.com/-y9fxOnYG_zA/Vlk6ujAIGiI/AAAAAAAAA-U/_COXSIL9Pp0/s1600/IMG_20151028_095126119.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="111" src="http://2.bp.blogspot.com/-y9fxOnYG_zA/Vlk6ujAIGiI/AAAAAAAAA-U/_COXSIL9Pp0/s200/IMG_20151028_095126119.jpg" width="200" /></a><i>This first disc I designed was quite naturally perfect; it was a work of art, flawless, sublime. A triumph equaled only by its monumental failure. The inevitability of its doom is as apparent to me now as a consequence of the imperfection inherent in every FDM 3D printer.Thus I redesigned it based on my printer's capabilities to more accurately reflect the varying grotesqueries of a 3D printed object. However, I was again frustrated by failure. I have since come to understand that the answer eluded me because it required a less typical design, or perhaps a design less bound by the parameters of perfection..</i><br />
<br />
But seriously, when I did some initial prints of the profile based off the KC Roc, it didn't go very well. My printer did not handle the overhangs very well, and I did not want to go with support material as I didn't want to mess up the surface finish. I then started editing the profile until I got something that would both fit on my printer and print with fairly clean overhangs. The main thing that suffers from this is the dome top. In order to have a flat surface to print the rims on and have a flight plate still fit on my build plate, there is about an inch section where the disc is flat on top before the dome of the flight plate begins. I imagine this decreases the lift it creates. My final design I deemed the TTU Roc.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-UklrdWyW5tw/Vlk5ta7SGhI/AAAAAAAAA-M/Q-209YaYbCQ/s1600/IMG_2446.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://2.bp.blogspot.com/-UklrdWyW5tw/Vlk5ta7SGhI/AAAAAAAAA-M/Q-209YaYbCQ/s320/IMG_2446.JPG" width="320" /></a></div>
<br />
<h4>
Construction</h4>
<div>
The final design can be downloaded from Thingiverse <a href="http://www.thingiverse.com/thing:1160108">HERE</a>. Construction is as follows.</div>
<div>
<br /></div>
<div>
Print 3 of the file TTURocRim_120C.stl . I used settings:<br />
<br />
Layer Height: 0.1mm<br />
Perimeters: 4<br />
Infill: 25%<br />
Combine Infill every: 2 layers<br />
Support: Off</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-JYjEZeZqrE0/Vlk5cHCnqPI/AAAAAAAAA98/5lobNIQE0m0/s1600/IMG_20151029_103914597.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://2.bp.blogspot.com/-JYjEZeZqrE0/Vlk5cHCnqPI/AAAAAAAAA98/5lobNIQE0m0/s320/IMG_20151029_103914597.jpg" width="320" /></a></div>
<div>
<br /></div>
<div>
Print 1 of the file FlightPlateC.stl. I used settings:<br />
<br />
Layer Height: 0.2mm<br />
Perimeters: 4<br />
Infill: 30%<br />
Combine Infill every: 1 layers<br />
Support: On</div>
<div>
<br /></div>
<div>
Next you will need to drill out the holes for the filament splints. These are the holes in the ends of the rim pieces that splint the 3 pieces together. I used plain 1.75mm filament to do this. Just drill them out so that they are an easy fit.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-2s1iS-SNcWM/Vlk5ln9-28I/AAAAAAAAA-E/Tf0FJCQ-1wo/s1600/IMG_20151030_114309447.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://4.bp.blogspot.com/-2s1iS-SNcWM/Vlk5ln9-28I/AAAAAAAAA-E/Tf0FJCQ-1wo/s320/IMG_20151030_114309447.jpg" width="320" /></a></div>
<div>
<br /></div>
<div>
Now it is time to glue the disc together. I used super glue, and it is what I would recommend. This took me an hour or so of gluing in stages. If you know how to friction weld you might try that here. Really, join them however you want.</div>
<div>
<br /></div>
<div>
Next I applied some DIY plastic rivets. Drill 1.75mm holes through the bottom of the rim into the flight plate. Then glue in the filament, snip it off, and and sand it down to level. This was just something else I did to try to strengthen the joints between the flight plate and the rim. Use as many of them as you see fit. I imagine you could also use friction based rivets if you are comfortable with that.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-DdwgGsKzqY4/Vlk4ri4fAWI/AAAAAAAAA9s/o1tKGwsGPPk/s1600/IMG_20151101_214222155.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="http://2.bp.blogspot.com/-DdwgGsKzqY4/Vlk4ri4fAWI/AAAAAAAAA9s/o1tKGwsGPPk/s320/IMG_20151101_214222155.jpg" width="320" /></a></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-9EiVs0aGhUI/Vlk494bdtoI/AAAAAAAAA90/UPcyGjGwBmA/s1600/IMG_2444.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://1.bp.blogspot.com/-9EiVs0aGhUI/Vlk494bdtoI/AAAAAAAAA90/UPcyGjGwBmA/s320/IMG_2444.JPG" width="320" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div>
Finally, sand the disc smooth and finish it however you want. I sanded it fairly smooth and then did a light coat of acetone to smooth it out some. Use whatever finishing techniques you have.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-prBuDRE_R2Q/Vlk7BpUq96I/AAAAAAAAA-c/_d_Mkwk7Dsg/s1600/IMG_2447.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://4.bp.blogspot.com/-prBuDRE_R2Q/Vlk7BpUq96I/AAAAAAAAA-c/_d_Mkwk7Dsg/s320/IMG_2447.JPG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-dEmLNqCTLls/Vlk7ISElpXI/AAAAAAAAA-k/Z_sDGPrVoY4/s1600/IMG_2443.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://1.bp.blogspot.com/-dEmLNqCTLls/Vlk7ISElpXI/AAAAAAAAA-k/Z_sDGPrVoY4/s320/IMG_2443.JPG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-O9M6rq10sKI/Vlk7QKPIaAI/AAAAAAAAA-s/WgtBY-P4lK0/s1600/IMG_2448.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://3.bp.blogspot.com/-O9M6rq10sKI/Vlk7QKPIaAI/AAAAAAAAA-s/WgtBY-P4lK0/s320/IMG_2448.JPG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<h4>
Performance</h4>
<div>
My final disc weight came out to 156 grams. I consider that an acceptable weight. Overall, the disc flew surprisingly well. To my amateur eye, it flies similar to a Roc. It appears to be a little slower and have less glide. Honestly, I haven't thrown it that many times for fear it will rip apart in my hand. I also doubt it will "beat in" very well. As ABS is pretty hard I imagine it would just break if it hit a tree. It also is not terribly comfortable in my hand. It is too hard and scratchy. In conclusion I made this chart to compare 3d printed disc golf discs of today to traditional discs.</div>
<div>
<br /></div>
<div>
<b>3D Printed Disc Golf Discs:</b></div>
<div>
<b>Pro:</b></div>
<div>
<ul>
<li>Infinitely customizable</li>
<li>Expose new players to the game </li>
<li>Fun!</li>
</ul>
</div>
<div>
<b>Con:</b></div>
<div>
<ul>
<li>Lack consistency</li>
<li>Brittle materials</li>
<li>Poor surface finish</li>
<li>Made of joined parts </li>
</ul>
<div>
-Matthew</div>
</div>
<div>
<br /></div>
<div>
Again, download CAD files <a href="http://www.thingiverse.com/thing:1160108">HERE</a>.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-53485141868231926192015-05-16T20:30:00.000-05:002015-05-16T20:30:00.774-05:00Reprap 3D Printing ToolkitI wanted to take a few minutes to compile a list of a few useful tools for RepRap 3D printing. I do this because I have been fortunate enough to learn a lot about the tools of the trade from people at school and various other sources, but others may not be that fortunate. I know that there are many other lists of this sort out there, but I will trust the magic of Google to take you to those posts if they are more relevant than mine.<br />
<h3>
Tools</h3>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/--TmNYl8a8hI/VVeyXc4eyQI/AAAAAAAAA9M/Y8qWJZz9l5U/s1600/IMG_20150516_160247628.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="http://3.bp.blogspot.com/--TmNYl8a8hI/VVeyXc4eyQI/AAAAAAAAA9M/Y8qWJZz9l5U/s400/IMG_20150516_160247628.jpg" width="400" /></a></div>
<div>
<br /></div>
<b>
Hairspray</b><br />
A friend at school that is very experienced with 3D printing recommended Garnier Fructis Style Natural Hairspray. Strength of 4 or 5 works well. I haven't had too many issues with ABS not sticking when using this. Purple Elmer's Glue stick is also a popular bed treatment, but I have not tried that yet.<br />
<div>
<br />
<b>Giftcard</b><br />
This is my trusty iTunes giftcard that I use to pry parts off of the build plate and scrape the plate clean. Any credit card will work, or you could spring for an epoxy spreader.</div>
<br />
<b>Screwdrivers</b><br />
I use a small philips screwdriver to adjust my bed level and change filament. It is one of the few real tools I need unless I am doing serious modifications or repair.<br />
<div>
<br />
<b>Mini Needle Nose Pliers</b><br />
I use these to clean off the nozzle just before a part prints. I basically use them to grab anything near something hot.</div>
<div>
<br />
<b>Acetone</b><br />
This is a must for printing with ABS. ABS dissolves with acetone. I brush it on to polish parts (too lazy for vapor polishing) and use it to clean the nozzle and seperate fingers glued together. Note that some nail polish remover contains acetone, but I use a bottle from the paint department.</div>
<div>
<br />
<b>Super Glue (CA)</b><br />
Plastic glues very well. Printing primarily in ABS, I find that cracks happen. Usually they can be repaired with at drop of CA. While I know from my RC airplane days that there are different thicknesses and even glue with an external hardener, those are more expensive. I use the cheapest stuff walmart sells and it works fine.</div>
<div>
<br />
<b>Kapton Tape</b><br />
High temperature electrical tape. This stuff is pretty pricey, but you will likely need some for something. The small roll in the picture came with my Replikeo printer kit. </div>
<div>
<br />
<b>Calipers</b><br />
An all around must have for any aspiring engineer (in my opinion). I use it to calibrate extruder steps, measure parts when drawing them in CAD, verify printed part dimensions, and basically every other linear measurement less than 6 inches. These are fairly cheap ones from Harbor Freight. They work, but I doubt you will regret buying a decent pair from somewhere else.<br />
<br /></div>
<h3>
Test Prints</h3>
<div>
<div style="text-align: center;">
<b>General Tests</b></div>
<div style="text-align: center;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-vtHENHawSl4/VPzdJdW4g7I/AAAAAAAAA50/Tg21CZ14Y-E/s1600/3FPD-Levelling_Pattern-2X_preview_featured.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="150" src="http://1.bp.blogspot.com/-vtHENHawSl4/VPzdJdW4g7I/AAAAAAAAA50/Tg21CZ14Y-E/s1600/3FPD-Levelling_Pattern-2X_preview_featured.jpg" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="http://www.thingiverse.com/thing:111720">Bed Leveling Pattern</a></td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-5_1p9Lntybc/VPzeT_2E4VI/AAAAAAAAA6E/A7AX-cY6bfE/s1600/IMG_20141216_151929725.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="112" src="http://2.bp.blogspot.com/-5_1p9Lntybc/VPzeT_2E4VI/AAAAAAAAA6E/A7AX-cY6bfE/s1600/IMG_20141216_151929725.jpg" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="http://www.thingiverse.com/thing:38108">Test Cube</a></td></tr>
</tbody></table>
<b></b><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-Afnr8nTaSPY/VPzcE4-3wOI/AAAAAAAAA5k/Bri-wcn8fhw/s1600/IMG_20141216_181108254.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="112" src="http://2.bp.blogspot.com/-Afnr8nTaSPY/VPzcE4-3wOI/AAAAAAAAA5k/Bri-wcn8fhw/s1600/IMG_20141216_181108254.jpg" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="http://www.thingiverse.com/thing:10650">Yoda</a></td></tr>
</tbody></table>
<b></b><br />
<b></b>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-5JCp8BVvwhg/VPzdrHOYWMI/AAAAAAAAA58/9ZSPZJb60lQ/s1600/OwlReDo1_fixed_sc_preview_featured.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="150" src="http://2.bp.blogspot.com/-5JCp8BVvwhg/VPzdrHOYWMI/AAAAAAAAA58/9ZSPZJb60lQ/s1600/OwlReDo1_fixed_sc_preview_featured.jpg" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="http://www.thingiverse.com/thing:18218">Owl Statue</a></td></tr>
</tbody></table>
<b></b><br />
<b></b><br />
<div style="text-align: center;">
<b>Retraction Tests</b></div>
<div style="text-align: center;">
<b><br /></b></div>
<b></b><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-XvF-qeqkpgg/VPzbHwLwoWI/AAAAAAAAA5c/NySrc60IaqI/s1600/pyramid_photo_preview_featured.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="150" src="http://1.bp.blogspot.com/-XvF-qeqkpgg/VPzbHwLwoWI/AAAAAAAAA5c/NySrc60IaqI/s1600/pyramid_photo_preview_featured.jpg" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="http://www.thingiverse.com/thing:29429">Hollow(er) Calibration Pyramid</a></td></tr>
</tbody></table>
</div>
<div>
<br />
<div style="text-align: center;">
<b>Overhang Tests</b></div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-6SYndY72zoc/VPzcs67XYsI/AAAAAAAAA5s/-Sq4wjXAaus/s1600/IMG_20141216_165338110.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="112" src="http://2.bp.blogspot.com/-6SYndY72zoc/VPzcs67XYsI/AAAAAAAAA5s/-Sq4wjXAaus/s1600/IMG_20141216_165338110.jpg" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="http://www.thingiverse.com/thing:58218">Overhang Test print</a></td></tr>
</tbody></table>
<br /></div>
<div>
<h3>
Websites</h3>
</div>
<div>
<ul>
<li><a href="http://reprap.org/">RepRap Wiki</a> - The official wiki of the RepRap Project</li>
<li><a href="http://www.thingiverse.com/">Thingiverse</a> - Run by Makerbot. An archive of CAD models for 3D printing. If you want to make something, search here first to see if someone has already made it.</li>
<li><a href="https://www.youmagine.com/">Youmagine</a> - A thingiverse competitor that has sprung up. Some people don't use thingiverse for a variety of reasons. This is another good resource.</li>
<li><a href="http://richrap.blogspot.com/">RichRap Blog</a> - This is a blog that I have personally found useful. He has covered many useful topics over the years.</li>
<li><a href="http://projectsfromtech.blogspot.com/">Projects From Tech</a> - A nice blog of generally useful information</li>
<li><a href="https://www.google.com/">Google</a> - If at first you don't succeed, Google the problem and find out why.</li>
</ul>
<div>
<br />
There are always more tools and test prints out there, but this post is long enough. If you know of any other must have items feel free to comment. I will be interested to see them.<br />
<br />
-Matthew</div>
</div>
Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-32697192252639411622015-03-14T13:28:00.000-05:002015-05-16T20:24:43.272-05:00Replikeo Prusa i3 Rework Build - Part 4: Initial Prints and ModificationsThis is Part 4 of my Replikeo Prusa i3 build account. This post will cover the initial modifications I made to the printer, how they effected print quality, issues I had with those modifications, and work for the future. It will also feature pictures of first prints and tests because I think those are obligatory when writing about a RepRap 3D printer. If you are interested in my other posts on this topic:<br />
<br />
<ul>
<li>Part 1: <a href="http://projectsfromtech.blogspot.com/2015/01/replikeo-prusa-i3-rework-build-part-1.html">Unboxing</a></li>
<li>Part 2: <a href="http://projectsfromtech.blogspot.com/2015/01/replikeo-prusa-i3-rework-build-part-2.html">Assembly</a></li>
<li>Part 3: <a href="http://projectsfromtech.blogspot.com/2015/02/replikeo-prusa-i3-rework-build-part-3.html">Wiring and Software Setup</a></li>
<li>Part 4: Initial Prints and Modifications</li>
<li><a href="http://projectsfromtech.blogspot.com/2015/03/reprap-3d-printing-toolkit.html">RepRap 3D Printing Toolkit</a></li>
</ul>
<h2>
Printer Modifications</h2>
<div>
<b>Board Mount</b></div>
<div>
In my mind, the single most important upgrade I made to my printer was to mount it to a plywood board. This allows me move the printer easier without getting it out of alignment or level. It gave me a place to mount the PSU and several of the other upgrades I will discuss.</div>
<div>
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-79epncxPeYk/VQNtyf07qOI/AAAAAAAAA68/hgJUvVvv-IM/s1600/IMG_20150220_121926196.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://3.bp.blogspot.com/-79epncxPeYk/VQNtyf07qOI/AAAAAAAAA68/hgJUvVvv-IM/s1600/IMG_20150220_121926196.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
The board is 3/4" oak plywood, but any sort of plywood would likely work (just make sure it is flat). The board is 20.25" x 22.5" . I mounted it with 1/2" pipe mounting clamps from Home Depot as shown in the picture. I used 8 of them, and it is rock solid. The corners never get loose, and I don't worry about it shifting when I put it in my car or rotate it on my work table. On the bottom I used some no skid rubber feet also from Home Depot. It keeps the vibration down and makes it feel very steady.<br />
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-6bVjQQ8LYdk/VQNt0NzS9pI/AAAAAAAAA7E/T9UfE_T-gB8/s1600/IMG_20150220_121951898.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://2.bp.blogspot.com/-6bVjQQ8LYdk/VQNt0NzS9pI/AAAAAAAAA7E/T9UfE_T-gB8/s1600/IMG_20150220_121951898.jpg" width="320" /></a></div>
<br />
<br /></div>
<div>
<b>Filament Spool Holder</b><br />
This was actually the first modification I made to the printer. I quickly got tired of having to manually unwind printer filament. It is a combination of parts almost identical to <a href="http://clickglide.com/?p=1068">THIS</a> blog post.<br />
<br />
<ul>
<li><a href="http://www.thingiverse.com/thing:381286">Prusa i3 Spool Mount for 3mm Frame</a> </li>
<li><a href="http://community.shapedo.com/wildseyed/osfa_filament_spool_holder">OSFA Filament Spool Holder</a></li>
<li><a href="http://www.thingiverse.com/thing:4676">Printable 608 Ball Bearing</a></li>
</ul>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-0J0KuR87ePk/VQNuIKepTII/AAAAAAAAA7M/X4YfAHHMAsQ/s1600/IMG_20150220_121837187.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://3.bp.blogspot.com/-0J0KuR87ePk/VQNuIKepTII/AAAAAAAAA7M/X4YfAHHMAsQ/s1600/IMG_20150220_121837187.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
This spool holder actually did work pretty well. It would probably work better if you used real 608 bearings. I eventually abandoned the OSFA spool holder and just hung it on the rod. That actually works better for me. Another note, the spool mount limits the z-height on the printer as the stepper hits the mount. It needs to be a little thinner. At some point I will get around to fixing it. It is also worth noting that without the z-axis support (next mod), this spool holder causes the z axis to bend over slightly. This causes the nozzle to raise off the build plate. This means when you put a heavier spool on the holder the nozzle gets pulled off the plate more. Not ideal. Overall I would recommend this setup, but if you have something better, go for it.</div>
<br />
<b>Z Axis Support</b><br />
Downloadable <a href="http://www.thingiverse.com/thing:723748">HERE</a> this modification supports the z axis so that it doesn't rock during the print. It bolts right on to the back of the z axis rod supports at top of the frame and screws into the plywood board. It requires 2 each of the printed parts and one 5/16" x 36" threaded rod cut in half. It works great. I highly recommend an upgrade like this.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-w5g-px64Uww/VQNuZ-9bZMI/AAAAAAAAA7U/j2HUmRl1IZ8/s1600/IMG_20150220_121900289.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://1.bp.blogspot.com/-w5g-px64Uww/VQNuZ-9bZMI/AAAAAAAAA7U/j2HUmRl1IZ8/s1600/IMG_20150220_121900289.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-dZ29tUrOpxA/VQNuaTM7-QI/AAAAAAAAA7c/M7mA2tabswQ/s1600/IMG_20150220_121905894.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://3.bp.blogspot.com/-dZ29tUrOpxA/VQNuaTM7-QI/AAAAAAAAA7c/M7mA2tabswQ/s1600/IMG_20150220_121905894.jpg" width="320" /></a></div>
<br />
<b>PSU Mount</b><br />
This is not so much about performance as it is convenience. I drew up a PSU mount in CAD for the PSU that comes with the Replikeo kit. A couple screws and some zipties and the PSU is firmly mounted to the plywood board. Now the printer is one unit that can be carried or put in a car without worry. Get the printed parts <a href="http://www.thingiverse.com/thing:691314">HERE</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-KjK4BD_vXBA/VQNutO9YkeI/AAAAAAAAA7k/D8SmIbIdKjk/s1600/IMG_20150220_121750597_HDR.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://4.bp.blogspot.com/-KjK4BD_vXBA/VQNutO9YkeI/AAAAAAAAA7k/D8SmIbIdKjk/s1600/IMG_20150220_121750597_HDR.jpg" width="320" /></a></div>
<br />
<b>Power Switch</b><br />
I was going to wire up a fancy power switch on my printer, so I would not have to unplug it all the time. Then I realized I could just get a cheap surge protector and use that instead. I think I got a 2-pack for $6. Worth it in my mind.<br />
<br />
<b>X Axis Belt Tensioner</b><br />
There are a couple of these drop in replacement x idlers that add tensioners. I liked <a href="http://www.thingiverse.com/thing:247992">THIS</a> one the best. It went on with no problems. Now I can tweak the x axis tension however I want. This probably isn't a high priority upgrade, but it is something that I changed.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-OPRK8ObWDTA/VQNu11VncNI/AAAAAAAAA7s/fzY38-BObHs/s1600/IMG_20150220_121814770_HDR.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://4.bp.blogspot.com/-OPRK8ObWDTA/VQNu11VncNI/AAAAAAAAA7s/fzY38-BObHs/s1600/IMG_20150220_121814770_HDR.jpg" width="320" /></a></div>
<br />
<b>Z Axis Adjustable Endstop</b><br />
<a href="http://www.thingiverse.com/thing:542892">THIS</a> upgrade has been very helpful in tuning the printer. It allows me to change the endstop location with the turn of a screwdriver. It is a little flaky having the screw hit the limit switch arm. Someday I plan to put a larger pad on the end of the screw so that it hits more uniformly, but it works for now. I printed the tall version and snapped off the bits I didn't need with some wire cutters.<br />
<b><br /></b>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-8MdbJJwfaG0/VQNvE8qhHnI/AAAAAAAAA70/FSgBWYOEzRY/s1600/IMG_20150220_122052939.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://1.bp.blogspot.com/-8MdbJJwfaG0/VQNvE8qhHnI/AAAAAAAAA70/FSgBWYOEzRY/s1600/IMG_20150220_122052939.jpg" width="320" /></a></div>
<b><br /></b>
<b>Print Cooling Fan</b><br />
I use <a href="http://www.thingiverse.com/thing:582256">THIS</a> cooling fan setup and it works great. I highly recommend that you shell out the extra $2 and get a centripetal fan. This fan setup blows more air than I need.It blows air right across the nozzle, so I had to wrap a little insulation around the extruder block to keep the temperature from fluctuating too much when the fan comes on. Possibly against common practice, I use it both on PLA and sometimes ABS depending on what I am printing and what other settings I am using. See the next mod as well.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-0eJkb3l0OqI/VQNvONfJ2FI/AAAAAAAAA78/bdLUN5gyYO0/s1600/IMG_20150220_122027573.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://2.bp.blogspot.com/-0eJkb3l0OqI/VQNvONfJ2FI/AAAAAAAAA78/bdLUN5gyYO0/s1600/IMG_20150220_122027573.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-Orsp-Eerwfs/VQNvOlU3SHI/AAAAAAAAA8A/c1aOorg6W8o/s1600/IMG_20150220_122042456.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://1.bp.blogspot.com/-Orsp-Eerwfs/VQNvOlU3SHI/AAAAAAAAA8A/c1aOorg6W8o/s1600/IMG_20150220_122042456.jpg" width="320" /></a></div>
<br />
<b>Dual Fan Mount</b><br />
<a href="http://www.thingiverse.com/thing:693770">THIS</a> clips onto the Wade's extruder body that comes in the Replikeo kit where the fan would go and allows you to mount two fans. That means you can keep your current extruder cooling fan and also use a print cooling fan like above. If you are going to add a fan, it works great for me.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/--r82iR2eBmI/VQNvWhlGKUI/AAAAAAAAA8M/mRtmS7offnY/s1600/IMG_20150220_122005658.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://3.bp.blogspot.com/--r82iR2eBmI/VQNvWhlGKUI/AAAAAAAAA8M/mRtmS7offnY/s1600/IMG_20150220_122005658.jpg" width="320" /></a></div>
<br />
<br />
That is all of the modifications I have made to my Replikeo Prusa i3 printer thus far. To me, I would consider the first 5 "must have" improvements. They just improve the performance or convenience of the printer so much that they are definitely worth your consideration. If you have any other improvements you recommend, let us know in the comments. Now the obligatory first prints I promised.<br />
<br />
<h2>
First Prints</h2>
<div>
These are some of my first prints. The green is Hatchbox PLA. The white is the ABS that came with the kit. They are printed at various temperatures and layer heights using hairspray as the bed adhesive.</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-ouX3zDO3X6g/VQRw6BHPgQI/AAAAAAAAA8o/MdI_WygRaMY/s1600/IMG_20150313_182800380.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="180" src="http://2.bp.blogspot.com/-ouX3zDO3X6g/VQRw6BHPgQI/AAAAAAAAA8o/MdI_WygRaMY/s1600/IMG_20150313_182800380.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">First ever prints. Learned the importance of bed prep right off the bat</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-hn8rapcQxi8/VQRw5zKP8bI/AAAAAAAAA8k/vbonsCDGo9Q/s1600/IMG_20150313_182825679.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="180" src="http://3.bp.blogspot.com/-hn8rapcQxi8/VQRw5zKP8bI/AAAAAAAAA8k/vbonsCDGo9Q/s1600/IMG_20150313_182825679.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Switched to the included ABS</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-uIJTdKGrSP8/VQRw6Lu31aI/AAAAAAAAA8g/DwUnPD-YCj4/s1600/IMG_20150313_182901683.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="180" src="http://1.bp.blogspot.com/-uIJTdKGrSP8/VQRw6Lu31aI/AAAAAAAAA8g/DwUnPD-YCj4/s1600/IMG_20150313_182901683.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Printed a few replacement parts</td></tr>
</tbody></table>
<br />
While I could post plenty more pictures I'd say this post is about long enough. If you want to see more, check out some of my other posts under the 3D printing tag to the right. If you have any questions or comments feel free to post below.</div>
<div>
<br /></div>
<div>
-Matthew</div>
<div>
<br />
<br />
<b><br /></b></div>
Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-6819646738196846282015-03-10T17:05:00.000-05:002015-03-10T18:01:11.955-05:00Fixing Autoscroll in GNU Octave for Windows<b>Introduction</b><br />
A quick and dirty post documenting an Octave "fix" for a problem I was having. Running GNU Octave version 3.8.2-5 from MXE installer found <a href="http://mxeoctave.osuv.de/">HERE</a> on a Windows 7 64 bit PC on 3/10/2015.<br />
<h2>
The Problem</h2>
<div>
The output of GNU Octave as installed above has a feature that while I am sure is useful to some, is quite irritating to me. Outputs that are too long to fit on the screen of the terminal are paginated. It will display the values that will fit on the screen and then wait for you to press "f" to see the next page worth's of data. See below. It displays "-- less -- (f)oward, (b)ack, (q)uit" at the end of each page.</div>
<div>
<br /></div>
<div>
While this may be great if you want to see every single value, if you are running long programs where the output is mostly for debugging purposes or similar, this can be irritating. I finally decided to figure out how to change this. Here it is.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-yLdMXN7qvsg/VP9k_8dyHcI/AAAAAAAAA6c/Gaut_d9_lD4/s1600/Octave%2Bpager%2Boutput%2Bless.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-yLdMXN7qvsg/VP9k_8dyHcI/AAAAAAAAA6c/Gaut_d9_lD4/s1600/Octave%2Bpager%2Boutput%2Bless.JPG" height="640" width="529" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<h2 style="clear: both; text-align: left;">
A Solution</h2>
<div>
While I don't claim to understand exactly what is going on above, it is clear that the "pager" being used on my install is "less". I wanted to change it to "more".</div>
<div>
<br /></div>
<div>
<b>1) </b>Check what pager you are using - Type "PAGER()". My guess is it will probably be "less". </div>
<div>
<br /></div>
<div>
<b>2)</b> View help file on PAGER() - Type "help PAGER". A couple useful websites: Documentation from a <a href="http://www.chemie.fu-berlin.de/chemnet/use/info/octave/octave_22.html">German university</a> and Documentation on the <a href="https://www.gnu.org/software/octave/doc/interpreter/Paging-Screen-Output.html">Octave Wiki</a>.</div>
<div>
<br /></div>
<div>
<b>3)</b> Change pager to "more" - Type "PAGER("more")</div>
<div>
<br /></div>
<div>
This should make the output look like the picture below. As you can see it scrolled through my entire output just fine. I will note that "PAGER()" now returns "more". Honestly, I don't really know what I changed under the hood, but it worked. Also note that it will reset when you reopen Octave.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-hbCQwsZ3WGQ/VP9nbcf-1YI/AAAAAAAAA6o/bl1C4B-es40/s1600/Pager%2Boutput%2Bmore.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-hbCQwsZ3WGQ/VP9nbcf-1YI/AAAAAAAAA6o/bl1C4B-es40/s1600/Pager%2Boutput%2Bmore.JPG" height="640" width="532" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
That is all I have on this. If anyone has a more detailed explanation of how this works or other ways to fix this "problem" feel free to post in the comments.</div>
<div>
-Matthew</div>
<div>
<br /></div>
Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-53058759211907139572015-03-05T16:00:00.000-06:002015-03-10T18:15:19.276-05:00Serial Port Communication with GNU Octave in WindowsThis is not so much a finished post as it is a place to record progress. Use any information found on this page at your own risk.<br />
<br />
<h2>
Introduction</h2>
<div>
I have been using <a href="https://www.gnu.org/software/octave/">GNU Octave</a> in place of MATLAB on my laptop for a while now. It is free and serves my purposes well. One place MATLAB does have it beat though is in its ability to communicate with outside hardware through a serial port. I recently needed this functionality for Octave. This is how I made it work. My configuration:</div>
<div>
<ul>
<li>Windows 7 - 64 bit</li>
<li>GNU Octave 3.8.2-5 using <a href="http://mxeoctave.osuv.de/">MXE installer</a></li>
<li>Instrument Control Package 0.2.1</li>
</ul>
</div>
<div>
<br /></div>
<h2>
Walkthrough</h2>
<h3>
Install Octave</h3>
<div>
If you found this post I will assume you are probably running Windows. There is a convenient unoffical installer for Windows <a href="http://mxeoctave.osuv.de/">HERE</a>. At the time of this writing I am running 3.8.2-5. Anything greater than 3.8.0 has the nice MATLAB style GUI.</div>
<div>
<br /></div>
<h3>
Install Instrument Control Package</h3>
<div>
The equivalent of MATLAB toolboxes are packages in Octave. You need the instrument-control package to access the serial ports. There are two ways to install it.</div>
<div>
<br /></div>
<div>
1) Install it from Octave forge. Assuming you have an internet connection, open Octave and type in the command window "pkg install -forge instrument-control-0.2.1.tar.gz" Replace the 0.2.1 with the newest version of the package.</div>
<div>
<br /></div>
<div>
2) Download it from <a href="http://octave.sourceforge.net/instrument-control/">HERE</a>. Assuming you did a standard install, move it to the folder "C:/Octave/Octave-3.8.2/src". There you will find all the other packages that were included with the installer. Now open Octave and make that folder your directory. Type in the command window "pkg install instrument-control-0.2.1.tar.gz". Obviously you may need to change the name of the package if you download a newer version.</div>
<div>
<br /></div>
<div>
Both options will take a while. One of my first mistakes was thinking I had crashed my computer. I wasn't sure if it would work on Windows, so when it just sat there for a minute I thought it was hung. Just give it some time. Mine took a couple minutes. </div>
<div>
<br /></div>
<h3>
Load Instrument Control Package</h3>
<div>
You only have to install the package once, but you need to load it every time you open Octave (you can also set it to auto load. Google it.)</div>
<div>
<br /></div>
<div>
Type "pkg list" to see all your installed packages. If you don't see instrument-control then you need to go back to the last step. Any package with an * by it is loaded.</div>
<div>
<br /></div>
<div>
To load the package type "pkg load instrument-control". Now load the list of packages again to see if it worked.</div>
<div>
<br /></div>
<h3>
Use the Package</h3>
<div>
Now the part you have been waiting for. It is important to note that at the time of this writing the instrument control package is not a drop in replacement for the serial capabilities of MATLAB. Here are some helpful links to illustrate this. It is fairly obvious that the function names are different or missing for Octave.</div>
<div>
<ul>
<li><a href="http://octave.sourceforge.net/instrument-control/overview.html">Octave Package Function Reference</a></li>
<li><a href="http://www.mathworks.com/help/matlab/serial-port-devices.html">MATLAB Serial Function Reference</a></li>
<li><a href="http://wiki.octave.org/Instrument_control_package">Octave Wiki demonstrating use</a></li>
</ul>
<b>Set COM Port</b></div>
<div>
For my initial test I used an Arduino with a jumper between Rx and Tx. This essentially mirrored anything I sent back to me. To simplify things, go to the device manager and change the serial port number to COM1 through COM8. Over that and additional work is needed. Device Manager > your port > Port Settings > Advanced > COM Port Number.</div>
<div>
<br /></div>
<b>My Additions</b><br />
<div>
To better serve my needs I added a few files to make the package more MATLAB compatible. Just make sure they are in your path somewhere if you want to use them.</div>
<div>
<br /></div>
<div>
<b>srl_fwrite: </b>Download <a href="https://drive.google.com/file/d/0B6s_UhmkBLQfMm9YY29Zb0RRZVE/view?usp=sharing">HERE</a>. Similar to the MATLAB fwrite. The regular srl_write only accepts char and uint8s. I made this function to simplify sending other variable types. Accepts three inputs </div>
<div>
<ul>
<li>Serial Object</li>
<li>Data to be sent</li>
<li>Data Type - int8, uint8, int16, uint16, int32, uint32, int64, or uint64</li>
</ul>
<div>
<b>srl_fread:</b> Download <a href="https://drive.google.com/file/d/0B6s_UhmkBLQfS2VhUlE4X0Y1Vkk/view?usp=sharing">HERE</a>. Similar to MATLAB fread. Reads serial port and returns data type specified. Takes three inputs.</div>
<div>
<ul>
<li>Serial Object</li>
<li>Number of values to be returned. (eg for 3 uint64s, enter 3 not 24)</li>
<li>Data Type - int8, uint8, int16, uint16, int32, uint32, int64, or uint64</li>
</ul>
</div>
<div>
<b><br /></b></div>
<b>Test Script</b></div>
<div>
<a href="https://drive.google.com/file/d/0B6s_UhmkBLQfNG1YZWJ6OWMzeG8/view?usp=sharing">Test Script</a>: This script was taken and modified from the wiki linked above. It opens a serial port, sends a couple values and then attempts to read them when the serial device mirrors them back. A "correct" output should look something like this.</div>
<div>
<br /></div>
<div>
<div>
Serial: Supported</div>
<div>
s1 = 0x444</div>
<div>
int8 = 200</div>
<div>
intdata =</div>
<div>
<br /></div>
<div>
0 142 1 44</div>
<div>
<br /></div>
</div>
<div>
<br /></div>
<div>
That is all I have at the moment. I hope this tutorial was useful to someone out there. I plan to do another post on the way I am actually using this capability in the future as a more in depth example. </div>
<div>
<br /></div>
<div>
-Matthew</div>
Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-20273015042309978452015-02-22T23:00:00.000-06:002015-03-15T21:58:02.828-05:00Replikeo Prusa i3 Rework Build - Part 3: Wiring and Software SetupPart 3 will cover my wiring of the Replikeo Prusa i3 Rework (mostly following <a href="http://reprap.org/wiki/Prusa_i3_Rework_Electronics_and_wiring">the wiki page</a>). Then I will cover my setup of the Repetier Firmware. I'll save first prints for Part 4. If you are interested in the unboxing and assembly see <a href="http://projectsfromtech.blogspot.com/2015/01/replikeo-prusa-i3-rework-build-part-1.html">Part 1</a> and <a href="http://projectsfromtech.blogspot.com/2014/12/replikeo-prusa-i3-rework-build-part-2.html">Part 2</a> respectively.<br />
<br />
<h4>
Wiring</h4>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-N4BbelDhBM0/VOqrqfC0WUI/AAAAAAAAA48/fb3-6hYtVGs/s1600/IMG_20150102_095131045.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-N4BbelDhBM0/VOqrqfC0WUI/AAAAAAAAA48/fb3-6hYtVGs/s1600/IMG_20150102_095131045.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">"Completed" Wiring</td></tr>
</tbody></table>
<span id="goog_462280222"></span><span id="goog_462280223"></span><br />
As the wiki page already has a very complete set of instructions on wiring, I will refrain from giving a step-by-step description of the procedure. I will instead clarify a few points that caused me a bit of confusion or could cause confusion.<br />
<br />
1) The Arduino does indeed mount in the holes shown on the wiki page. The USB port points down. I initially could not manage to get the holes lined up, but they eventually cooperated.<br />
<br />
2) The endstops as wired in the picture are connected to the min endstop pin. That doesn't really matter right now, but you will need to know that when you go to setup the firmware.<br />
<br />
3) On the power supply L=Line, N=Neutral, and G= Ground. I used a multimeter to find out which wire goes to which pin. If you live in Tennessee you should have about 120 VAC across the line and neutral. Be sure you change the switch on the power supply to 110V mode.<br />
<br />
4) When wiring the motors you can plug both Z motors into the ramps board. There are (quite conveniently) two headers there. You don't have to have an external combining pcb as shown in the picture on the wiki.<br />
<br />
5) I used the fan that came with the Replikeo kit as an extruder cooling fan, not a "Print Fan". As such, I did not connect it to D9. This required that I crimp on an old servo connector I had to attach it to the extruder fan pins. These are just a 12V breakout. Whenever you plug your printer in, it is going to come on.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://reprap.org/mediawiki/images/archive/c/ca/20131210184132!Arduinomega1-4connectors.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://reprap.org/mediawiki/images/archive/c/ca/20131210184132!Arduinomega1-4connectors.png" height="285" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Ramps 1.4 Pinout</td></tr>
</tbody></table>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<h4>
Software</h4>
<div>
I am using the <a href="http://www.repetier.com/">Repetier</a> Firmware with Repetier Host and Slic3r. Repetier has a very convenient web setup tool. It really wasn't all that difficult and was pretty helpful in figuring out how things worked, but if you are having problems and want to try the firmware I am using download mine <a href="https://drive.google.com/file/d/0B6s_UhmkBLQfVnJheUhzS29FMGc/view?usp=sharing">HERE</a>. Just upload the configuration.h file and see what's going on. One thing to remember, some of the settings may be getting set in EEPROM. This means you will need to update them from Repetier Host. It's under the Config tab. </div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
In Repetier Host, be sure to input all the correct Printer Settings. For instance I have a max x endstop and the other two are mins. And my bed is actually 190x170. If you follow the installation instructions on Repetier's website you should be fine.<br />
<br />
In Slic3r for the ABS that was included with the kit a lot of the default settings work fairly well. For the filament settings my diameter measured to be about 1.73mm and I print at 230 for the first layer and 215 for the rest. Bed is at 100. I also had some success starting the bed at 100 then dropping it to 85. I have not been able to calibrate the thermistor yet, so I can't be verify that those are the actual temperatures. But those settings work for me.<br />
<br />
Now the fun part begins, You get to go play and test things. I doubt very many people will read this and use it as a guide to assembling their printers. However, if you are trying to decide if this is the printer for you, I can confirm that the wiring and software is equally simple. A few hours and I had it working.<br />
<br />
That's all for part 3. In <a href="http://projectsfromtech.blogspot.com/2015/03/replikeo-prusa-i3-rework-build-part-4.html">part 4</a> I will show some pictures of my "completed" printer and the modifications I made. Some of them are good. Some of them still require work.<br />
<br />
-MatthewMatthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-31241385617154801382015-01-02T18:00:00.000-06:002015-02-22T22:31:06.318-06:00Replikeo Prusa i3 Rework Build - Part 2: AssemblyPart 2 will describe the process of building my Replikeo Prusa i3 Rework. Having already taken inventory in <a href="http://projectsfromtech.blogspot.com/2015/01/replikeo-prusa-i3-rework-build-part-1.html">part 1</a>, I will continue following the wiki instructions with <a href="http://reprap.org/wiki/Prusa_i3_Rework_Y_axis_assembly">Y-axis assembly</a>. Below are the pictures from the build.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-G9uvgOKRXLw/VJ-IvRdKpfI/AAAAAAAAA1Y/59DxNVJ-Bgo/s1600/IMG_20141213_151703131_HDR.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://4.bp.blogspot.com/-G9uvgOKRXLw/VJ-IvRdKpfI/AAAAAAAAA1Y/59DxNVJ-Bgo/s1600/IMG_20141213_151703131_HDR.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Y axis assembly</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-xR9l-mHzyzg/VJ-JCEagxRI/AAAAAAAAA1g/P7qFUtkzWGg/s1600/IMG_20141213_152841688_HDR.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://2.bp.blogspot.com/-xR9l-mHzyzg/VJ-JCEagxRI/AAAAAAAAA1g/P7qFUtkzWGg/s1600/IMG_20141213_152841688_HDR.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Y axis assembly with carriage</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-qC7Zle1zKWc/VJ-JmgluLUI/AAAAAAAAA1o/WbNGQCL1lb8/s1600/IMG_20141213_173331292.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://2.bp.blogspot.com/-qC7Zle1zKWc/VJ-JmgluLUI/AAAAAAAAA1o/WbNGQCL1lb8/s1600/IMG_20141213_173331292.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">X and Y axis assemblies</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-dNQvKGNs5FE/VJ-KIvKl1lI/AAAAAAAAA1w/sp5LdL8ReSs/s1600/IMG_20141213_180828863.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://4.bp.blogspot.com/-dNQvKGNs5FE/VJ-KIvKl1lI/AAAAAAAAA1w/sp5LdL8ReSs/s1600/IMG_20141213_180828863.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">X, Y, and Z axis assemblies</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-6oSjQ8Vzi9E/VJ-LSN9_i6I/AAAAAAAAA18/RWoUS7yXm6s/s1600/IMG_20141213_183651499_HDR.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://3.bp.blogspot.com/-6oSjQ8Vzi9E/VJ-LSN9_i6I/AAAAAAAAA18/RWoUS7yXm6s/s1600/IMG_20141213_183651499_HDR.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Z Steppers added</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-vWawpiKCvH0/VJ-Lk2Rt0AI/AAAAAAAAA2E/E4jBTUXn6Cw/s1600/IMG_20141214_195823066_HDR.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://3.bp.blogspot.com/-vWawpiKCvH0/VJ-Lk2Rt0AI/AAAAAAAAA2E/E4jBTUXn6Cw/s1600/IMG_20141214_195823066_HDR.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Attach uprights to base and add X,Y steppers</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
I don't remember having any serious problems with this portion of the build. I was able to put what you see above together in a few hours. Some screws were too long as I had seen documented elsewhere. I just put some extra washers underneath them. On the z-axis threaded rods, the nuts did not fit snuggly into their housings, so I added a drop of hot glue to each. Other than that, I pretty much followed the instructions. Next was the <a href="http://reprap.org/wiki/Prusa_i3_Rework_Extruder_assembly">extruder assembly</a>.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The extruder assembly required a little teasing. It is worth noting that this is the only printed part that is included in the kit. As such, some trimming of support material was required. I was not overly impressed by the print quality. I plan to print a replacement at some point and expect mine to come out much better. The biggest problem was that the hole for the j-head was not round. Luckily the j-head is almost exactly the same diameter as the drum sander attachment on a dremel tool. A bit of sanding and it was good to go. Below are some pictures.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-JSt1gKbcfOg/VJ-TZUQKkTI/AAAAAAAAA2U/p7rFK76oxfI/s1600/IMG_20141215_095536761_HDR.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-JSt1gKbcfOg/VJ-TZUQKkTI/AAAAAAAAA2U/p7rFK76oxfI/s1600/IMG_20141215_095536761_HDR.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Assembly before stepper</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-TMDUVZxEx_0/VJ-Vlec2NTI/AAAAAAAAA2g/ucVDynIK7aw/s1600/IMG_20141215_095614314_TOP.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-TMDUVZxEx_0/VJ-Vlec2NTI/AAAAAAAAA2g/ucVDynIK7aw/s1600/IMG_20141215_095614314_TOP.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">J-head hole enlarged</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-ikpVgg5VOX0/VKSxRXRvRyI/AAAAAAAAA3M/S1dQJbMiqy0/s1600/IMG_20141215_101947944.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://3.bp.blogspot.com/-ikpVgg5VOX0/VKSxRXRvRyI/AAAAAAAAA3M/S1dQJbMiqy0/s1600/IMG_20141215_101947944.jpg" height="400" width="225" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Hot glue added to keep bearing in place</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-2fGYE6Hpbbs/VKSxWaNODzI/AAAAAAAAA3U/eFZDzV9cz5I/s1600/IMG_20141215_112532222.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-2fGYE6Hpbbs/VKSxWaNODzI/AAAAAAAAA3U/eFZDzV9cz5I/s1600/IMG_20141215_112532222.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Fully assembled extruder before stepper</td></tr>
</tbody></table>
<br />
<div class="separator" style="clear: both; text-align: left;">
At this point the only things left to do were add the heated bed and wire everything up. Wiring will be in part 3, but I will put the heated bed pictures here. I debated for a while how to best attach the thermistor. Eventually I ended up using silicone sealant and some kapton tape I had. The wide kapton was not included in the kit, but many smaller pieces of the stuff included in the kit could be used if that is all you have. In the end, the silicone did nothing. I would just leave that off.</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-OPeX4svfc7M/VKSyvxwFglI/AAAAAAAAA3g/UoLnVHUvXQ0/s1600/IMG_20141215_123741306.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://4.bp.blogspot.com/-OPeX4svfc7M/VKSyvxwFglI/AAAAAAAAA3g/UoLnVHUvXQ0/s1600/IMG_20141215_123741306.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Thermistor included in the kit. Wires are presoldered and heatshrinked</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-WyS9kEaSi4c/VKSy2zGgDkI/AAAAAAAAA3o/yXccSQWvyWA/s1600/IMG_20141215_130724161.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-WyS9kEaSi4c/VKSy2zGgDkI/AAAAAAAAA3o/yXccSQWvyWA/s1600/IMG_20141215_130724161.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Thermistor taped to heatbed</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-XV-YMenmYKM/VKSy_3AWFHI/AAAAAAAAA3w/whHKPwAGG3Q/s1600/IMG_20141215_135219437.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-XV-YMenmYKM/VKSy_3AWFHI/AAAAAAAAA3w/whHKPwAGG3Q/s1600/IMG_20141215_135219437.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Printer ready to be wired</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: left;">
Its worth noting that I used springs to support the heated bed instead of washers like in the wiki instructions. I think it's fairly obvious how to do this; the springs are included in the kit.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
At this point the only wiki page left is Electronics and Wiring. <a href="http://projectsfromtech.blogspot.com/2015/02/replikeo-prusa-i3-rework-build-part-3.html">Part 3</a> will address wiring and initial software setup.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
-Matthew</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<br />
<br />Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-5451284020867538802015-01-01T00:00:00.000-06:002015-01-01T22:32:42.229-06:00Replikeo Prusa i3 Rework Build - Part 1: Unboxing<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
About a month ago I decided to build a 3D printer. This only left me with the task of deciding what kind of printer to build. While I had dealt with the Makerbot we have at school, I did not want to shell out that kind of money for a prebuilt, so I decided to go the RepRap route. After consulting with a friend that has a RepRap and searching around online, I came up with a few options to decide between. <br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Eventually those options narrowed to two. I would either build an <a href="http://www.thingiverse.com/thing:41967">OB1.4 printer</a>. Or I would buy a full Prusa i3 rework kit. With Christmas break fast approaching and not wanting to forget a screw and have to wait until next semester I decided to go with the <a href="http://www.replikeo.com/en/KIT001">full kit from Replikeo</a>. At the time I couldn't find too many reviews on it, so I decided now that I have it up and running I would post a few things about how it went. I would encourage others that buy the printer to do the same.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<h3 style="text-align: left;">
Long Story - Short </h3>
<div style="text-align: left;">
I would recommend this kit to anyone with a little electronics and mechanical knowledge (the basic knowledge needed to build any RepRap). I got it up and running in about 4 days. Maybe 25ish hours. While I have some improvements planned, it had everything I needed to get it going. I really like the injection molded parts. The electronics look genuine. I am glad I purchased the kit instead of sourcing my own.</div>
<div style="text-align: left;">
<br /></div>
<h3 style="text-align: left;">
Long Story - Long</h3>
<div style="text-align: left;">
I ordered the "iron" 1.75mm Replikeo kit for $350. Shipping from wherever to my house in Southern Tennessee (USA) was $90. Addtionally I ordered $23 of Hatchbox PLA filament from Amazon and a Full Graphic Smart Controller from Ebay for $25. Everything came for less than $500. </div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Shipping took exactly how long they said it would. 3-5 days via DHL. I think I got mine in 5 days including a weekend. Mine was not beaten up like<a href="http://forums.reprap.org/read.php?151,344338"> another post</a> I saw. I was irritated that there was no parts list but <a href="http://reprap.org/wiki/Prusa_i3_Rework_Introduction">HERE</a> is the wiki page. Now here are some unboxing pictures.</div>
<div style="text-align: left;">
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-q3u5s3wOK3k/VJ8m6xyfmOI/AAAAAAAAAz4/EVIfPY1caNI/s1600/IMG_20141213_100407803.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://2.bp.blogspot.com/-q3u5s3wOK3k/VJ8m6xyfmOI/AAAAAAAAAz4/EVIfPY1caNI/s1600/IMG_20141213_100407803.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">All my purchases together. Replikeo box is one the right.</td></tr>
</tbody></table>
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-geEh-za4ezg/VJ8nGSign7I/AAAAAAAAA0A/G50WZxVKybk/s1600/IMG_20141213_101414555.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-geEh-za4ezg/VJ8nGSign7I/AAAAAAAAA0A/G50WZxVKybk/s1600/IMG_20141213_101414555.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Removed from the cardboard</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-MlrjveQCFYQ/VJ8nGuibz8I/AAAAAAAAA0E/lKOV9fblJ0A/s1600/IMG_20141213_101420731.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://3.bp.blogspot.com/-MlrjveQCFYQ/VJ8nGuibz8I/AAAAAAAAA0E/lKOV9fblJ0A/s1600/IMG_20141213_101420731.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Top removed exposing the frame</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-goGpalSYDac/VJ8nRVghB3I/AAAAAAAAA0o/tA3pYJ_nfik/s1600/IMG_20141213_102225426.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://2.bp.blogspot.com/-goGpalSYDac/VJ8nRVghB3I/AAAAAAAAA0o/tA3pYJ_nfik/s1600/IMG_20141213_102225426.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Steppers and Power Supply</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-hjY4jd7-nEs/VJ8nPI8HI4I/AAAAAAAAA0Q/HvQ48E6Q6xk/s1600/IMG_20141213_101725144.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-hjY4jd7-nEs/VJ8nPI8HI4I/AAAAAAAAA0Q/HvQ48E6Q6xk/s1600/IMG_20141213_101725144.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">ABS filament, electronics (in cardboard box), and rods protected below.</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-gspNEgLAtNc/VJ8nPb4gbcI/AAAAAAAAA0Y/RTj58T0l8IQ/s1600/IMG_20141213_102012429.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-gspNEgLAtNc/VJ8nPb4gbcI/AAAAAAAAA0Y/RTj58T0l8IQ/s1600/IMG_20141213_102012429.jpg" height="400" width="225" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Threaded rods and smooth rods protected in packaging</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-TiasAVbACCA/VJ8nPd38xEI/AAAAAAAAA0U/0rT4k8uDefs/s1600/IMG_20141213_102152876.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-TiasAVbACCA/VJ8nPd38xEI/AAAAAAAAA0U/0rT4k8uDefs/s1600/IMG_20141213_102152876.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">I thought this was interesting. Apparently this kit was made just for me (that is my name).</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-9tbUxnxFVf4/VJ8tSk4cy2I/AAAAAAAAA04/5PBqsReAsfY/s1600/IMG_20141213_102836301.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://2.bp.blogspot.com/-9tbUxnxFVf4/VJ8tSk4cy2I/AAAAAAAAA04/5PBqsReAsfY/s1600/IMG_20141213_102836301.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Hardware and Electronics removed.</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-9Q_eycHwni8/VJ8thqFW10I/AAAAAAAAA1A/U4vf2OP8ZuQ/s1600/IMG_20141213_121218419_TOP.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-9Q_eycHwni8/VJ8thqFW10I/AAAAAAAAA1A/U4vf2OP8ZuQ/s1600/IMG_20141213_121218419_TOP.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Electronics in anti-static packaging</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-HktMz9uSObc/VJ8tp6gBtkI/AAAAAAAAA1I/q9BlANu6sR0/s1600/IMG_20141213_140137323_TOP.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-HktMz9uSObc/VJ8tp6gBtkI/AAAAAAAAA1I/q9BlANu6sR0/s1600/IMG_20141213_140137323_TOP.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">All small parts laid out.</td></tr>
</tbody></table>
<br />
After getting it unboxed I took inventory of all the parts. While I did not bother to count all the small screws I estimated that I had enough of each. All the electronics were included. The one thing I would recommend is getting a longer USB A-> B Cable. The one included is tiny and inconvenient. I had one sitting around from my Arduino projects. The Arduino appears to be a "real" Arduino (or else a pretty good clone).<br />
<div>
<br /></div>
<div>
The <a href="http://www.replikeo.com/en/3d-printer/moulded-parts-prusa-i3-rework">injection molded parts</a> are really nice. I don't see any of them breaking anytime soon, and it makes assembly very easy. While I would probably have used higher gauge wire on some components I am more or less pleased with it. The heated bed works well and the carbon fiber build plate is working well so far.<br />
<br />
That is all I have for the unboxing section. Look for the next part (<a href="http://projectsfromtech.blogspot.com/2015/01/replikeo-prusa-i3-rework-build-part-2.html">HERE</a>) soon when I post pictures of the build.<br />
<br />
-Matthew<br />
<div>
<br /></div>
</div>
Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com2tag:blogger.com,1999:blog-4542176549692404194.post-28539702084771365972014-12-27T18:00:00.000-06:002014-12-27T16:46:13.515-06:00Linearizing the Sharp IR Ranger (2YOA21) with an ArduinoToday I will be linearizing a <a href="https://www.sparkfun.com/products/242">Sharp IR Ranger</a>. More specifically, I will be using the Sharp 2YOA21 F 04.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://cdn.sparkfun.com//assets/parts/1/8/4/00242-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://cdn.sparkfun.com//assets/parts/1/8/4/00242-1.jpg" width="200" /></a></div>
<br />
<br />
First, a quick word on why we would want to do this. The Sharp ir rangers are a very effective means of measuring distance. While ultrasonic sensors (for more about those see the Sensors label) can be fooled by textures and echos, ir sensors are more susceptible to interference from outside light sources and changes in material reflectivity. Therefore, if a cheap measurement system is required in a varying environment (eg, a mobile robot) a combination of ultrasonic rangers and ir rangers can be quite effective.<br />
<br />
If you have found this page, you probably already know this, but I will state it anyway. Sharp ir sensors have an analog output. However, the analog value does not have a linear relationship to distance. In this exercise we will find the function that does relate the two and use that to take an analog value and convert it to a distance.<br />
<br />
<h3>
Wiring</h3>
<div>
As stated above, the sensor has an analog output. Connect the red lead to +5V, black lead to GND, and yellow lead to A0.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-aBFkYscpNpA/VDBeZ9j8H-I/AAAAAAAAAzA/nU8EscbHPpk/s1600/IMG_2309.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-aBFkYscpNpA/VDBeZ9j8H-I/AAAAAAAAAzA/nU8EscbHPpk/s1600/IMG_2309.JPG" height="320" width="240" /></a></div>
<div>
<br /></div>
<h3>
Aquire Data</h3>
<div>
<br /></div>
<div>
I used a simple sketch that took the average of 5 values and printed it to the screen. I then manually copied it into an excel spreadsheet along with the measured distance value. </div>
<div>
<ul>
<li>My <a href="https://drive.google.com/folderview?id=0B6s_UhmkBLQfTnJRYzFkVXRoc0k&usp=sharing">sketch</a></li>
<li>My <a href="https://drive.google.com/file/d/0B6s_UhmkBLQfU2tkblpWRVFHc28/view?usp=sharing">spreadsheet</a></li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-Ht37WmjHYBI/VDBeoCkO4KI/AAAAAAAAAzI/ffcV-Mikl6Y/s1600/IMG_2307.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-Ht37WmjHYBI/VDBeoCkO4KI/AAAAAAAAAzI/ffcV-Mikl6Y/s1600/IMG_2307.JPG" height="300" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-Xj1z_Mc47_I/VDBeCts0UII/AAAAAAAAAyw/9YUIkTOpjDQ/s1600/All%2Bdata.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-Xj1z_Mc47_I/VDBeCts0UII/AAAAAAAAAyw/9YUIkTOpjDQ/s1600/All%2Bdata.JPG" height="253" width="400" /></a></div>
<div>
<br /></div>
<h3>
Fit Data</h3>
</div>
<div>
Once you have acquired the data, plot it. Some points will most likely fall outside of the trend. Exclude those points and fit the rest. My fit was <span style="font-family: inherit;">Value</span><span style="font-size: 14pt; vertical-align: baseline;"><span style="font-family: inherit;"> = 1893.9*Distance^-0.92.</span> </span></div>
<div>
<span style="font-size: 14pt; vertical-align: baseline;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-VxRTZjjrIFQ/VDBeFryMg4I/AAAAAAAAAy4/IzeqtvCpLhM/s1600/fit%2BData.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-VxRTZjjrIFQ/VDBeFryMg4I/AAAAAAAAAy4/IzeqtvCpLhM/s1600/fit%2BData.JPG" height="250" width="400" /></a></div>
<div>
<span style="font-size: 14pt; vertical-align: baseline;"><br /></span></div>
<div>
<span style="font-size: 14pt; vertical-align: baseline;"><br /></span></div>
<h3>
<span style="font-size: 14pt; vertical-align: baseline;">Use Equation</span></h3>
<div>
<span style="font-family: inherit;">Solving the equation I got above for Distance gets me this, Distance = (1893.9*Value) ^-1.087.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">This is something we can plug into Arduino code. At this point it is only right to note that the method I am using will involve floating point math. There are methods that avoid that. If processing power is at a premium, you might want to check those out.</span></div>
<div>
<br /></div>
<div>
The important piece of code looks like this:</div>
<div>
<br /></div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #333399; font-weight: bold;">float</span> Distance <span style="color: #333333;">=</span> pow((sensorValue <span style="color: #333333;">/</span> <span style="color: #6600ee; font-weight: bold;">1893.9</span>), <span style="color: #333333;">-</span><span style="color: #6600ee; font-weight: bold;">1.087</span>);
</pre>
</div>
<div>
<br /></div>
<div>
If you want the whole thing, you can download my code <a href="https://drive.google.com/folderview?id=0B6s_UhmkBLQfbTBXaFp2bHZvd0U&usp=sharing">HERE</a>.</div>
<div>
<br /></div>
<div>
That's all I have. I hope it was useful.<br />
<br />
-Matthew</div>
<div>
<br /></div>
<div>
<br /></div>
Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-4102299845661883862014-05-03T12:00:00.000-05:002014-05-03T12:00:05.539-05:00Delaying Startup Programs Until Idle on Windows 7The other day I was starting up my computer in a rush before class. As I waited for all the "necessary" startup programs to start up, it hit me. Wouldn't it be great to be able to a prioritize the way my computer starts up? More than that though, I want to be able to tell some programs to not launch until my computer isn't being used. They can load up after I leave for class. If I need them I can just launch them manually.<br />
<br />
A few Google searches yielded a few programs (some free some not), but I am always hesitant to hand over important things like startup procedures to an unknown program from the abyss. Then I found my answer.<br />
<br />
Enter Window Task Scheduler. I had encountered Windows Task Scheduler before on Windows 8 but hadn't ever directly used it on Windows 7. It does exactly what I wanted! Using the task scheduler it is pretty trivial to create a task to start a program after startup and whenever the computer is idle. However, I thought I could make it easier.<br />
<br />
I decided to create a batch file to launch my secondary programs (KeePass, iTunes updater, etc.). Then all I have to do is create one scheduled event in the task scheduler to launch the batch file. Even better, I can put the batch file somewhere convenient (the desktop, documents, etc), so it is easy to change. If you're reading this, I will assume you know how to find the startup programs you have on your computer. Make sure you don't get delay an important one.<br />
<br />
Anyway, here is the batch file code. The best way to see what is going on is to just open a command window and type HELP START. This will give you all the commands you need. Note that if you are using a location that has spaces you will need to put it in quotes with a /D preceding it.<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">@ECHO OFF</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">START /B /D C:\Users\Matthew\AppData\Local\Google\Update\GoogleUpdate.exe</span><br />
<span style="font-family: Courier New, Courier, monospace;">START "Startup Batch Window" /B /D "C:\ProgramFiles(x86)\Seagate\SeagateDashboard2.0\DBAgent.exe"</span><br />
<span style="font-family: Courier New, Courier, monospace;">START "Startup Batch Window" /B /D "C:\ProgramFiles(x86)\KeePassPasswordSafe2\KeePass.exe" </span><br />
<div>
<br /></div>
<br />
<br />
And here are some screenshots of me making my scheduled event.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-CCnewKuywc4/U2UVF6Jg9lI/AAAAAAAAAx4/WucRpRoaIOI/s1600/Create+Task-+Censored.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-CCnewKuywc4/U2UVF6Jg9lI/AAAAAAAAAx4/WucRpRoaIOI/s1600/Create+Task-+Censored.jpg" height="183" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Create New Task</td></tr>
</tbody></table>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-bL4tj7Ym_vc/U2US2gX1DGI/AAAAAAAAAxU/Dnlu269pD9Q/s1600/Trigger.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-bL4tj7Ym_vc/U2US2gX1DGI/AAAAAAAAAxU/Dnlu269pD9Q/s1600/Trigger.JPG" height="367" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Adding a Trigger</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><br />
<a href="http://4.bp.blogspot.com/-3vZcDJTCI-o/U2US4eUAWxI/AAAAAAAAAxc/EzFNCvfk-Ek/s1600/trigger+2.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://4.bp.blogspot.com/-3vZcDJTCI-o/U2US4eUAWxI/AAAAAAAAAxc/EzFNCvfk-Ek/s1600/trigger+2.JPG" height="348" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Triggers for My Event</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-9AKFrAie9iA/U2UTIWnS1pI/AAAAAAAAAxs/deVh-CgTakc/s1600/Action.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://2.bp.blogspot.com/-9AKFrAie9iA/U2UTIWnS1pI/AAAAAAAAAxs/deVh-CgTakc/s1600/Action.JPG" height="348" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Adding Action to be Triggered - Launch Batch File</td></tr>
</tbody></table>
<br />
<br />
Hopefully this is useful to someone. As my Calculus II professor always said, "What is that American expression? There is more than one way to skin the cat?" If I missed a much easier, more effecient, or more logical one feel free to comment. This just seems to work for me.<br />
<br />
-MatthewMatthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com1tag:blogger.com,1999:blog-4542176549692404194.post-55587263924692521052014-04-14T11:43:00.000-05:002014-04-14T11:43:09.723-05:00Cheap Drill Batteries! Making a Corded Cordless DrillThis was a quick afternoon project that I worked on a few weeks ago. The beginnings were pretty simple. I was digging through the basement and found an old 12v cordless drill whose batteries had died. Being me, I decided that it would be cool and pretty easy to connect a cord to it and plug it into a lab power supply or other 12V source.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-dnsXtpc1jwE/U0wO_yQhm7I/AAAAAAAAAw0/X5a6pk4tJFc/s1600/2014-03-15+16.18.17.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-dnsXtpc1jwE/U0wO_yQhm7I/AAAAAAAAAw0/X5a6pk4tJFc/s1600/2014-03-15+16.18.17.jpg" height="320" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
As this project is pretty dependent on the type of drill you have, I will try to include what pictures I took. Also, it is worth noting that as I type this Walmart has plenty of decent corded and even cordless drills for less than $40.<br />
<br />
<b>Step 1)</b><br />
Take apart the battery. Determine the positive and negative leads. On mine white = negative, black = positive (similar to wiring a house).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-0hL-ACbW1Tk/U0wOqqUt8RI/AAAAAAAAAwk/Wbkiu6jH5yI/s1600/2014-03-15+15.08.28.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-0hL-ACbW1Tk/U0wOqqUt8RI/AAAAAAAAAwk/Wbkiu6jH5yI/s1600/2014-03-15+15.08.28.jpg" height="320" width="240" /></a></div>
<br />
<b>Step 2)</b><br />
Aquire a cord. The wire I scavenged is suspected to have come off of an old vacuum. I would recommend scavenging for this project to keep costs down. I also found some banana plugs to make it easier to connect to a power supply. I considered using some old test lead alligators.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://media.digikey.com/photos/Emerson%20Network%20Photos/108-0302-001_sml.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://media.digikey.com/photos/Emerson%20Network%20Photos/108-0302-001_sml.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The kind of Banana Jack I used</td></tr>
</tbody></table>
<br />
<b>Step 3)</b><br />
Remove the batteries and wire together. I actually left some of the batteries in the casing to add some counterbalance. I then soldered on the wire, punched a hole in the case to let the wire out, and hot glued everything together.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-sXeuOR_uppI/U0wOjH2VCRI/AAAAAAAAAwc/rY341kCh07I/s1600/2014-03-15+15.08.18.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-sXeuOR_uppI/U0wOjH2VCRI/AAAAAAAAAwc/rY341kCh07I/s1600/2014-03-15+15.08.18.jpg" height="320" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-Oaw2EjlOiJo/U0wOzzzBI5I/AAAAAAAAAws/eWFUMXjbOXk/s1600/2014-03-15+15.34.30.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-Oaw2EjlOiJo/U0wOzzzBI5I/AAAAAAAAAws/eWFUMXjbOXk/s1600/2014-03-15+15.34.30.jpg" height="320" width="240" /></a></div>
<b>Step 4)</b><br />
Test. My next step was to hook it up to a car battery and test it. It worked! for a few seconds. Then the burnt smell.<br />
<br />
The drill did not like being run on a car battery. There is a large diode inside the drill that I burnt out. Luckily, I found a replacement in a box of old hairdryers that we happened to have on hand.<br />
<br />
With the replacement diode in, I took it over to a lab and tried it out. It worked fine. There was still a slight burning smell, but I suspect that may just be dust in the motor from years of non use. Overall it seemed to work ok. The video below will give you a peak at the power supply readout during testing.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/OrYTLkZkm2M?feature=player_embedded' frameborder='0'></iframe></div>
<br />
<br />
Some might call this a wasted Saturday afternoon, and they are probably right. However, if you enjoy tinkering with things, making a corded cordless drill might be right up your alley.<br />
<br />
-MatthewMatthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com3tag:blogger.com,1999:blog-4542176549692404194.post-21663678948223077442014-03-01T11:53:00.000-06:002014-03-01T11:53:52.440-06:00Arduino Shift Register Stepper Motor ControllerThis is my first "reader requested" post. A reader sent me an email asking me to do a post about controlling a stepper motor using a shift register, and here it is. In this post I will specifically discuss controlling a 28BYJ-48 stepper motor with a 74HC595 shift register, ULN2003, and Arduino.<br />
<br />
<a href="http://bildr.org/blog/wp-content/uploads/2011/02/574px-SN74HC595-pinout.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="http://bildr.org/blog/wp-content/uploads/2011/02/574px-SN74HC595-pinout.png" height="200" width="190" /></a>First of all, I need to explain what a shift register is. Rather than doing that however, I will differ you to <a href="http://bildr.org/2011/02/74hc595/">THIS</a> page. It does an excellent job of introducing shift registers and provides some really easy to use sample Arduino code. My code is based off of the functions on that page. I will be using a <a href="https://www.sparkfun.com/products/733">74HC595 shift register</a>. I chose it because it is pretty common. I got mine off of eBay, but you can buy them at various vendors.<br />
<br />
<a href="http://2.bp.blogspot.com/-SOfPFIY246U/T6yGH_zAkTI/AAAAAAAAAlk/y_daXFqbg_E/s1600/ULN2003.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="http://2.bp.blogspot.com/-SOfPFIY246U/T6yGH_zAkTI/AAAAAAAAAlk/y_daXFqbg_E/s1600/ULN2003.jpg" height="200" width="168" /></a>Second, I should point you to some information on the stepper motor I will be using. It is a <a href="http://www.hobbyking.com/hobbyking/store/uh_viewitem.asp?idproduct=26925&aff=272191">28BYJ-48 stepper motor</a>. It is the same one I used in the two posts(<a href="http://projectsfromtech.blogspot.com/2013/05/stepper-motors-and-arduino-28byj-48.html">Arduino Control</a> and <a href="http://projectsfromtech.blogspot.com/2014/01/stepper-motors-and-attiny-28byj-48.html">ATtiny Control</a>). If you need it, those two pages have links to some good reference material.<br />
<br />
Third, like in the other cases, I will be using a ULN2003 to drive the stepper. This is pretty common with this board. However, this time I just wired it up on my breadboard rather than using the control board that came with my stepper. I did this because I intended to solder together a whole control board. In the end, I decided I didn't have a need for it at the moment and just left it breadboarded. I can always solder it later.<br />
<br />
<br />
Now, wiring this project has a few more wires than some of my others, so I threw out all the stops and made a Fritzing schematic. When you look at it, wiring is not terribly complicated; the wires just get crossed easily.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-vcfzWBMX3xQ/Uwp4yjLOy5I/AAAAAAAAAvQ/bZV1hOWVa8U/s1600/Shift+Register+Stepper_bb2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-vcfzWBMX3xQ/Uwp4yjLOy5I/AAAAAAAAAvQ/bZV1hOWVa8U/s1600/Shift+Register+Stepper_bb2.jpg" height="297" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
So here is what is going on. The Arduino is controlling the shift register like described in the link I provided above. The shift register outputs are fed into the ULN2003. The ULN2003 acts as a switch and allows the stepper to draw the current that it needs to operate.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
One thing you may wish to change, in this diagram I have the stepper being driven by the 5V from the Arduino. It may be wise to drive it from an external 5V source if you are doing more than one. Also, the colors on the stepper (or even the order of the wires) can vary from vendor to vendor. Basically, if the stepper just sits there and grinds against itself, switch the wires.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="" style="clear: both; text-align: left;">
Another thing that confused me for a little while, the ULN2003 sinks current (as opposed to sourcing current). That is, it allows the output to be a path to ground if the input is HIGH. If you wire the stepper like shown above it should work. The trouble comes when people like me want to test it with an LED before connecting the stepper. I connected the positive end to the ULN2003 and the negative to ground. Eventually, I realized my mistake and switched it. Long story short, to test with an LED, put the "negative" end on the ULN2003 output and the "positive" on 5V.</div>
<div class="" style="clear: both; text-align: left;">
<br /></div>
<div class="" style="clear: both; text-align: left;">
Here is my setup for this project. The sketch I used is an adaption of one of the sketches from my previous posts. Basically, where there was a digitalWrite I put a setRegisterPin. A potentiometer controls the speed. Get my code <a href="https://drive.google.com/folderview?id=0B6s_UhmkBLQfZEhlazNFMVFrc3c&usp=sharing">HERE</a>. </div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-1D2BLt3c-ts/UxIRck-wHkI/AAAAAAAAAvk/yeneUGmSyuY/s1600/IMG_1584.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-1D2BLt3c-ts/UxIRck-wHkI/AAAAAAAAAvk/yeneUGmSyuY/s1600/IMG_1584.JPG" height="240" width="320" /></a></div>
<div class="" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The motor did not turn very quickly (around 10 seconds a revolution), I suppose I shouldn't have expected much more considering all the delays the shift register puts into the system, but if you ever needed to control a large number of stepper motors on only a few pins maybe this would be an option. If you do plan on that, you might note that the ULN2003 only has 7 inputs/outputs, so be sure to get the right number of parts.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div style="text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/NOoo5rl7DpY?feature=player_embedded' frameborder='0'></iframe></div>
<br />
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Also, it appears that this sketch could very easily be wrapped into a library. Perhaps the stepper library could be edited to utilize a shift register. Regardless, that is beyond the scope of this post. I leave that to the reader (though feel free to tell us about it in comments).</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Hopefully this is useful to someone. If anyone else has suggestions for posts, let me know. The reader requested label is looking pretty lonely.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
-Matthew</div>
<br />
<br />
<br />Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com7tag:blogger.com,1999:blog-4542176549692404194.post-37508489091546945962014-02-08T18:00:00.000-06:002014-02-08T18:10:52.746-06:00DHT11 on ATtiny85Recently I got my DHT11 temperature and humidity sensor working with my Arduino Mega2560. If you are interested in that, check it out <a href="http://projectsfromtech.blogspot.com/2014/02/dht11-with-adafruit-library-and-arduino.html">HERE.</a> However, while that was all well and good, I found it a bit impractical. While I may someday decide to create some sort of weather logger using the DHT11, it is unlikely that I would dedicate an entire Arduino to the task. Enter ATtiny85.<br />
<br />
The ATtiny85 is great because it is cheap, but the real question is, "Does it work with the DHT11?" Yes it does.<br />
<br />
Now in my last post I used the DHT library from Adafruit. While that library served its purpose, it does not work with the ATtiny. Don't ask me why; I did not explore it. <a href="http://forum.arduino.cc/index.php?topic=124457.0">HERE</a> is another report of it not working and a description of what will happen if you try it. It reads out all zeros.<br />
<br />
What does work is the <a href="http://playground.arduino.cc/Main/DHT11Lib">DHT11</a> library. To get it working you will need to modify the example code. Basically, you need to change everything that says "Serial" to the Software Serial equivalent. This will allow us to get the sensor readings back from the ATtiny. If you want more information on serial communication on an ATtiny, check out <a href="http://projectsfromtech.blogspot.com/2013/06/serial-communication-on-attiny85-with.html">THIS</a> post. Alternatively, you could just download my code (<a href="https://drive.google.com/file/d/0B6s_UhmkBLQfQ05nZ0MxZkJ1bDQ/edit?usp=sharing">HERE</a>), wire everything the way I say, and see if it works.<br />
<br />
Now when you go to compile my example, there is a good chance you will run into a problem. As it turns out, there is an issue with the <a href="https://code.google.com/p/arduino-tiny/">tiny core</a> when trying to compile sketches close to the maximum sketch size. Luckily there is a quick and easy fix. I won't go into the details, but follow the instructions <a href="http://forum.arduino.cc/index.php?topic=156641.0">HERE</a>.<br />
<br />
When that was straightened out I was able to upload my sketch successfully. I used my USBtinyISP and my <a href="http://projectsfromtech.blogspot.com/2013/04/attiy85-programming-adapter.html">ATtiny85/45 programming adapter</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-QAeiWv5W5Do/Us7cdjI4gqI/AAAAAAAAAtM/SVaI6kFvjA0/s1600/ATTiny85+Datasheet+Pinout.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-QAeiWv5W5Do/Us7cdjI4gqI/AAAAAAAAAtM/SVaI6kFvjA0/s1600/ATTiny85+Datasheet+Pinout.JPG" height="96" width="320" /></a></div>
<br />
The only thing left to do is wire it up and see the output. Basic wiring of the DHT11 is the same as in my last post.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-2srlqA2BGEA/UunQFsUBZ_I/AAAAAAAAAuU/MJsx0_Ig4zc/s1600/IMG_1533.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="http://3.bp.blogspot.com/-2srlqA2BGEA/UunQFsUBZ_I/AAAAAAAAAuU/MJsx0_Ig4zc/s1600/IMG_1533.JPG" height="240" width="320" /></a></div>
<br />
<b style="background-color: white; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.200000762939453px;">Correct Wiring:</b><br />
<b style="background-color: white; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.200000762939453px;">Pin 1</b><span style="background-color: white; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.200000762939453px;">: +5V</span><br />
<b style="background-color: white; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.200000762939453px;">Pin 2</b><span style="background-color: white; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.200000762939453px;">: Signal. Connect to digital IO with a 5k ohm pull-up resistor</span><br />
<b style="background-color: white; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.200000762939453px;">Pin 3</b><span style="background-color: white; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.200000762939453px;">: Nothing. Some people suggest grounding it if you run into trouble</span><br />
<b style="background-color: white; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.200000762939453px;">Pin 4</b><span style="background-color: white; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.200000762939453px;">: GND</span><br />
<span style="background-color: white; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.200000762939453px;"><br /></span>
On the ATtiny side, PB3 is the software serial Rx and PB4 is the software serial Tx. Connect those to an FTDI (or some other serial receiving device). Connect 5V and ground.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-al2PQQXzCYU/UvZUPfmSgfI/AAAAAAAAAus/RwDm-XWcM9E/s1600/IMG_1539.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-al2PQQXzCYU/UvZUPfmSgfI/AAAAAAAAAus/RwDm-XWcM9E/s1600/IMG_1539.JPG" height="240" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Power it up and watch the show!<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-Ym-v3ZRP1c4/UvZUUieqvEI/AAAAAAAAAu0/7W2-O4p7xhs/s1600/DHT11+output.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-Ym-v3ZRP1c4/UvZUUieqvEI/AAAAAAAAAu0/7W2-O4p7xhs/s1600/DHT11+output.JPG" height="212" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
This of course could be modified to do other things with the temperature data. It could, for instance, transmit them via I2C. Maybe it could log them on an SD card. Those projects I leave to you (for now anyway). If you are interested in more ATtiny projects of mine, check out my <a href="http://projectsfromtech.blogspot.com/search/label/ATtiny">ATtiny label</a>. Let me know if this works or doesn't work for you. As always, I'm happy to help.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
-Matthew</div>
<br />Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0tag:blogger.com,1999:blog-4542176549692404194.post-50917437950661832912014-02-03T22:00:00.000-06:002014-02-03T22:00:00.690-06:00DHT11 with Adafruit Library and Arduino Mega 2560In this post I will be playing with the DHT11 Temperature and Humidity Sensor with my <a href="http://www.hobbyking.com/hobbyking/store/uh_viewitem.asp?idproduct=42817&aff=272191">Arduino Mega 2560</a>. While a DHT22 could also be used, I used a DHT11 mostly because it and it was cheap. I think I got mine for around a dollar. They can also be found it premade <a href="http://www.hobbyking.com/hobbyking/store/uh_viewitem.asp?idproduct=26939&aff=272191">breakouts</a>, but there really isn't much to them. As you can tell from the picture in the link, the breakout merely removes the extra pin and adds the pull-up resistor and a decoupling capacitor.<br />
<br />
Once you decide on which sensor to buy, you will be faced with yet another choice. What library should I use? There are approximately a lot of them out there. I chose the Adafruit DHT library found <a href="https://github.com/adafruit/DHT-sensor-library">HERE</a>. It worked for me (and supports multiple sensors), so I saw little reason to pursue any of the other libraries.<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="http://www.hobbyist.co.nz/sites/default/files/Arduino_Sensor_interface.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="http://www.hobbyist.co.nz/sites/default/files/Arduino_Sensor_interface.png" height="170" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">This does <b><u>NOT</u> </b>work</td></tr>
</tbody></table>
<br />
Now when I bought my DHT11 from Ebay, a picture like this was on the listing. Quite frankly, I don't understand what this is getting at. It doesn't work. While I can't vouch for the rest of the world, my sensor is not analog. It is digital. You can even look at the <a href="http://www.micro4you.com/files/sensor/DHT11.pdf">datasheet</a>.<br />
<br />
<b>Correct Wiring:</b><br />
<b>Pin 1</b>: +5V<br />
<b>Pin 2</b>: Signal. Connect to digital IO with a 5k ohm pull-up resistor<br />
<b>Pin 3</b>: Nothing. Some people suggest grounding it if you run into trouble<br />
<b>Pin 4</b>: GND<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-2srlqA2BGEA/UunQFsUBZ_I/AAAAAAAAAuQ/4iTQKYMq3Vk/s1600/IMG_1533.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-2srlqA2BGEA/UunQFsUBZ_I/AAAAAAAAAuQ/4iTQKYMq3Vk/s1600/IMG_1533.JPG" height="240" width="320" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-YUCWddM4P4g/UunQXijehGI/AAAAAAAAAuY/T718fFjp91k/s1600/IMG_1532.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-YUCWddM4P4g/UunQXijehGI/AAAAAAAAAuY/T718fFjp91k/s1600/IMG_1532.JPG" height="240" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Once everything is wired up, open the example sketch. It does about everything I would want it to do, so there is not much to say. Uncomment the correct sensor and upload. Open the serial monitor and get testing. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
There isn't much to say about this sensor. It is slow and probably not too accurate, but with the hard work of making the library already done, this sensor is incredibly easy to use. If you don't like my description of this sensor, there are many others out there at your disposal. If you do like it, I'm glad I could be of help.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
-Matthew</div>
Matthewhttp://www.blogger.com/profile/07493487402447428879noreply@blogger.com0