tag:blogger.com,1999:blog-16229832758356216552024-03-28T22:30:12.829-05:00Embedded ProgrammerJorge Aparicio's blog on Electronics, Robotics and more...Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.comBlogger35125tag:blogger.com,1999:blog-1622983275835621655.post-84247520580780819542013-02-01T21:37:00.000-05:002013-02-01T21:37:14.319-05:00Graduating from Ubuntu and moving to Arch Linux<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="text-align: center;">
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggVquQ2GY9FQGOBAibVEaolZBNhjnZCgaD6BUcYOhRRgZ3KEjyV3JfZr8xf6SKNpoHapjVInoxodoRhmn1XCnrGCKCi-K5QxVWoyEhJjR2wAgEYgq7yW3Wg8I75EVLU8b_SfTWnwVVIRM/s1600/archey.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="223" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggVquQ2GY9FQGOBAibVEaolZBNhjnZCgaD6BUcYOhRRgZ3KEjyV3JfZr8xf6SKNpoHapjVInoxodoRhmn1XCnrGCKCi-K5QxVWoyEhJjR2wAgEYgq7yW3Wg8I75EVLU8b_SfTWnwVVIRM/s400/archey.png" width="400" /></a><br />
Arch Linux, a rolling release and highly customizable GNU/Linux distribution</div>
<br />
<div style="text-align: justify;">
I've recently left Ubuntu and migrated to a new GNU/Linux distribution: <a href="https://www.archlinux.org/">Arch Linux</a>. The process wasn't easy, as the learning curve of Arch Linux is steeper than the Ubuntu learning curve, but it has been immensely gratifying. This metamorphosis has taught me more about Linux that what I could have learned from staying in Ubuntu.</div>
<br />
<div style="text-align: justify;">
Not only have I learned new things but I have built a fully customized Operating System that fits my needs and boosts my productivity. This is the main difference between Arch Linux and Ubuntu, the former comes with the bare minimum to run, whereas the latter comes with batteries included. This implies the Arch user must choose his/her Desktop Environment, his/her Development Tools, his/her Media Player, his/her Web Browser, etc.</div>
<br />
<div style="text-align: justify;">
This plethora of choices may be overwhelming for the newcomer but this ultimate freedom is Arch Linux strongest feature. I believe that thanks to being forced to choose, the user will ultimately find what best fulfills his/her needs instead of sticking to the default, which may not be the optimum. This search for the best apps may be time consuming, but I think it eventually pays off in terms of productivity and conform.</div>
<br />
<div style="text-align: justify;">
Now, without further ado, I'll share my findings, what works the best for me, and I hope this insight will help you in building your ultimate Operating System.</div>
<br />
<h3>
Standing on the shoulder of giants</h3>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifyigetZxBC8yz9_XOcS5hSGH9zuhWHi_WO-pfJPmt0-kle8di84kzEDAaeecTA8CwENbzHxuuQSvR7i91TXhf5A2U9QZRFov_ke4C8KAkJ1ehMjUmxKkI0pwKFgMJ-SziMODLo05DnoA/s1600/arch_wiki.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifyigetZxBC8yz9_XOcS5hSGH9zuhWHi_WO-pfJPmt0-kle8di84kzEDAaeecTA8CwENbzHxuuQSvR7i91TXhf5A2U9QZRFov_ke4C8KAkJ1ehMjUmxKkI0pwKFgMJ-SziMODLo05DnoA/s320/arch_wiki.png" width="320" /></a></div>
<div style="text-align: center;">
The Arch Linux philosophy (The Arch Way): The user has complete control and responsibility over ther system</div>
<br />
<div style="text-align: justify;">
It's important to mention that a I've received a lot of help into building and tweaking my system from the <a href="https://wiki.archlinux.org/">Arch Wiki</a>. The information contained there has taught me a lot about how Linux works, has saved me lot of time troubleshooting problems and has provided helpful insight on selecting and setting up software.</div>
<br />
<h3>
On the cutting edge, with great power, comes great responsibility</h3>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9PfDn9vOQUfQHMZYK8I76n6ZJELRtw4FdsZUuolJzI7PYyrxge9hz2710ZjracUvuYJCRzx2mYGQCO4cCaCRusw4JCYrOqOrT1e5F2qnMs7uGWHoW-JZ9gtMpkm3XsMYDe1M_UD4Cepk/s1600/kernels.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9PfDn9vOQUfQHMZYK8I76n6ZJELRtw4FdsZUuolJzI7PYyrxge9hz2710ZjracUvuYJCRzx2mYGQCO4cCaCRusw4JCYrOqOrT1e5F2qnMs7uGWHoW-JZ9gtMpkm3XsMYDe1M_UD4Cepk/s320/kernels.png" width="320" /></a></div>
<div style="text-align: center;">
And Ubuntu 12.10 uses the version 3.5 of the kernel</div>
<br />
<div style="text-align: justify;">
Arch Linux is a rolling release distribution, this means you won't see a new version of Arch Linux coming out every 6 months, like Ubuntu does. Instead you get access to new software as soon as it has been tested to be relatively stable.</div>
<br />
<div style="text-align: justify;">
This means you'll live at the cutting edge and have access to the latest features implemented in your favorite software, but also means you should be ready to tackle the bugs that may come with the latest software.</div>
<br />
<h3>
The User Repository: Build It Yourself!</h3>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIhzMVDfL-cIrH2h8M9zEy5TRtv-KrAUItOfw1s2vKCcyo0QYs0EY9-O93-QnkW_jqwUyM4AFCUDjaNFOUryxlfI4yDRFpkBHplzLwhgpeU6RAt-lD_-aICl1xYSb1MjNMaG4c9Qswhlk/s1600/aur.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIhzMVDfL-cIrH2h8M9zEy5TRtv-KrAUItOfw1s2vKCcyo0QYs0EY9-O93-QnkW_jqwUyM4AFCUDjaNFOUryxlfI4yDRFpkBHplzLwhgpeU6RAt-lD_-aICl1xYSb1MjNMaG4c9Qswhlk/s320/aur.png" width="320" /></a></div>
<div style="text-align: center;">
The most voted user packages in Arch Linux</div>
<br />
<div style="text-align: justify;">
As with other GNU/Linux distributions, you can easily install software from the packages available in the official repository using pacman, the Arch Linux package manager. But there are times when you need a software that isn't available in the official repository. On many distributions this either means that you are on your own and will need to compile the software from source, or you depend on someone who might have built a binary compatible with your distribution/version.</div>
<br />
<div style="text-align: justify;">
On Arch Linux, you have the AUR (Arch User Repository), where the build instructions (PKGBUILD) are uploaded. This means that you'll build yourself a binary that does work with your system. And for the exciting part, AUR has system for commenting, voting and flagging outdated packages. This means that the community will be alert and vigilant about the correctness of the build instructions.</div>
<br />
<h3>
The Desktop Environment: From Unity to Gnome 3</h3>
<br />
<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGvw11qQmkurTLGj8ky8d_bRzPHTdBOW1y_vgqrGPTwP_E4hsWtsyaSMMcAtJmh-11Llw1rY_N0PkpaVjBAqXzrpO-fUVTiS9AHfvetp6R8FwLc5luErtPMAyv8SGPgzccorolAISgDDE/s1600/unity.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="88" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGvw11qQmkurTLGj8ky8d_bRzPHTdBOW1y_vgqrGPTwP_E4hsWtsyaSMMcAtJmh-11Llw1rY_N0PkpaVjBAqXzrpO-fUVTiS9AHfvetp6R8FwLc5luErtPMAyv8SGPgzccorolAISgDDE/s200/unity.png" width="200" /></a></div>
</td><td><div class="separator" style="clear: both; text-align: center;">
<a href="http://www.gnome.org/wp-content/uploads/2012/09/gnome-3-6-940x400.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="85" src="http://www.gnome.org/wp-content/uploads/2012/09/gnome-3-6-940x400.png" width="200" /></a></div>
</td>
</tr>
</tbody></table>
<div style="text-align: center;">
IMO, out of the box Gnome 3 looks better than out of the box Unity<br />
(Images from <a href="http://www.ubuntu.com/tour">ubuntu.com</a> and <a href="http://www.gnome.org/gnome-3/">gnome.org</a>)</div>
<br />
<div style="text-align: justify;">
My first Linux distro was Ubuntu 11.04, Natty Narwhal, and I arrived just in time to test Unity, which became the default GUI in that release. Coming from the "W" OS, the change was abrupt, and for me it was a total redefinition of the desktop experience.</div>
<br />
<div style="text-align: justify;">
I quickly became attached to the feature of workspaces, which are common in Linux Desktop Environments, and even established the policy of having <a href="http://embeddedprogrammer.blogspot.com/2012/07/ubuntu-tip-03-using-workspaces-like.html">one application per workspace</a> for faster switching, instead of alt-tabbing through many apps.</div>
<br />
<div style="text-align: justify;">
I loved the concept of adding extensions to the top panel for extra information and features, but to the date I still don't understand why some people use the <a href="https://extensions.gnome.org/extension/6/applications-menu/">application extension</a>, that just reminds me of the start menu from the "W" OS (ewww), I guess some habits die hard.</div>
<br />
<div style="text-align: justify;">
I also liked the Unity Lens, a desktop search mechanism, until Canonical decided to add the opt-out Amazon search...</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.gnome.org/wp-content/uploads/2012/09/overview-420x263.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://www.gnome.org/wp-content/uploads/2012/09/overview-420x263.png" width="320" /></a></div>
<div style="text-align: center;">
Out Unity, enter Gnome 3!</div>
<div style="text-align: center;">
(Image from <a href="http://www.gnome.org/gnome-3/">www.gnome.org</a>)</div>
<br />
<div style="text-align: justify;">
But enough of reminiscing, and fast forwarding to my migration to Arch Linux. Just after I installed the base system and had to select a Desktop Environment, I found out that Unity was not in the official repositories and I didn't know at that time about AUR. In need of a new DE, I choose the most similar to Unity: Gnome 3.</div>
<br />
And Gnome 3 just rocked my world:<br />
<ul>
<li style="text-align: justify;">It just looks better than Unity!</li>
<li style="text-align: justify;">Do you like workspaces? We have dynamic workspaces</li>
<li style="text-align: justify;">Do you like the top panel? You can install and manage your extensions from <a href="https://extensions.gnome.org/">the web</a></li>
<li style="text-align: justify;">On Unity, the Super key only let's you search/launch apps, on Gnome it launches the Activities Overview, where you can do the same but also switch apps/workspaces and close apps in the current workspace</li>
<li style="text-align: justify;">I love the hot corner, it launches the Activities Overview using the mouse, and I use it to switch applications/workspaces when my hand is already on the mouse</li>
<li style="text-align: justify;">Notifications! (not available in Unity), they are just awesome, many apps can report useful information in an unobtrusive way with these notifications</li>
</ul>
<br />
<h3>
On the way of Vim</h3>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNpT8txHpdlH1tP4tjWMWhwQ-FfNbFa8zRRIxAshynCLjyKfw4HTZOgD562lprWgar977SEcqsPcRnDaOguL73DUjG4osTltrrDuHcEanfs5uCe1vojl4Hehny57wGfH2_nvs2A8kWjLI/s1600/vim.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNpT8txHpdlH1tP4tjWMWhwQ-FfNbFa8zRRIxAshynCLjyKfw4HTZOgD562lprWgar977SEcqsPcRnDaOguL73DUjG4osTltrrDuHcEanfs5uCe1vojl4Hehny57wGfH2_nvs2A8kWjLI/s320/vim.png" width="320" /></a></div>
<div style="text-align: center;">
Vim, the fastest editor in the world (?)</div>
<br />
<div style="text-align: justify;">
Continuing with the productivity improvements, I decided to try the legendary vim editor. Many things are said about vim like: "<i>vim allows you to edit text at of the speed of thought</i>". I'm not quite there yet, but releasing yourself from the mouse does speed up the editing, but <i>only</i> if you're a touch typist <i>and</i> after you have quite a bit of practice with this editor.</div>
<br />
<div style="text-align: justify;">
The learning curve is quite steep, when I started with vim my productivity went down, but after the struggle of learning the basics I was back to normal. What gives you the real boost are vim superpowers, namely: buffers, windows, the infinity of plugins and some stuff I haven't heard about yet.</div>
<br />
<div style="text-align: justify;">
To stay committed to my learning of vim, I'm forcing myself to use vim, by enabling it wherever it's possible:</div>
<ul>
<li>I use vi mode in the command line</li>
<li><a href="http://embeddedprogrammer.blogspot.com/2013/01/vim-for-python-development.html">I use vim as a Python IDE</a></li>
<li><a href="http://embeddedprogrammer.blogspot.com/2013/01/augmenting-octave-with-vim.html">I use vim with Octave</a></li>
<li>I use vim as the system default editor</li>
<li>I installed gvim and removed gedit</li>
</ul>
<br />
I think you get the point... The side effect is that I'm improving my productivity daily!<br />
<br />
<h3>
Drop Down Screen for the win</h3>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikkqOgwCm0aN7kqk2_V7dVVOGft540eSjJIiGY7szOlAQINHKW0MaddT8QpOm589pNaXk_drXGPlp5mzQef1MiKXAjmtJdmgzYRsWxtC8EhUCfpC1fWgse-PkVj2ZaaMoDlue3QmYq__g/s1600/drop_down_screen.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="173" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikkqOgwCm0aN7kqk2_V7dVVOGft540eSjJIiGY7szOlAQINHKW0MaddT8QpOm589pNaXk_drXGPlp5mzQef1MiKXAjmtJdmgzYRsWxtC8EhUCfpC1fWgse-PkVj2ZaaMoDlue3QmYq__g/s320/drop_down_screen.png" width="320" /></a></div>
<div style="text-align: center;">
Always available command line applications with the Gnome Drop Down Terminal and Screen</div>
<br />
<div style="text-align: justify;">
I'm a heavy user of the command line, I prefer using the keyboard that using the mouse, and pressing a key shortcut is always faster than moving the mouse to some menu and selecting an action.</div>
<br />
<div style="text-align: justify;">
Therefore I needed a way of quickly accessing multiple terminals. Opening and closing terminal when needed resulted in launching delays, and having multiple terminal windows open only added clutter to the desktop.</div>
<br />
<div style="text-align: justify;">
With Drop Down Terminal you can have a terminal permanently open, which can be hidden from view without closing it and called it back without the launching delay. And Screen lets you manage multiple command line applications in one terminal.</div>
<br />
<div style="text-align: justify;">
For more information you can check my post: <a href="http://embeddedprogrammer.blogspot.com/2013/01/screen-multitasking-in-command-line.html">Multitasking in the command line with Screen</a>.</div>
<br />
<h3>
Conky, the system monitor</h3>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIwPK7pR1llGdoXMUhDwfEpoOkZ8lf5SG80Uq6SmMR8QboqYMdf73KMKB81FFPJ9Oh_soKOylbXjSMQslO1-W3hB5cR3UtIvsUuteXoHZ2lXJOvg_aVbW4c8s4JxGilnUCusiURu7z9C0/s1600/conky.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIwPK7pR1llGdoXMUhDwfEpoOkZ8lf5SG80Uq6SmMR8QboqYMdf73KMKB81FFPJ9Oh_soKOylbXjSMQslO1-W3hB5cR3UtIvsUuteXoHZ2lXJOvg_aVbW4c8s4JxGilnUCusiURu7z9C0/s320/conky.png" width="320" /></a></div>
<div style="text-align: center;">
Conky, the customizable system monitor</div>
<br />
<div style="text-align: justify;">
Accessing your system information is important to spot any CPU/memory leak, or to monitor the network bandwidth usage, among other tasks related to maintenance.</div>
<br />
<div style="text-align: justify;">
You can have pretty much all of this information by adding gnome extensions called indicators. But there are three problems with this approach:</div>
<br />
<ul>
<li style="text-align: justify;">You'll fill your top panel with a lots of indicators, leaving little space for other extensions.</li>
<li style="text-align: justify;">Again, due to limited space you can only view a small piece of information for each indicator.</li>
<li style="text-align: justify;">To access a more detailed report, you'll need to click on each indicator, which is slow and energy consuming.</li>
</ul>
<br />
<div style="text-align: justify;">
As you can see in the screenshot above, Conky lives in your desktop and let's you access all the information you need/want thanks to its .conkyrc file, and also solves the three problems of the indicators:</div>
<ul>
<li style="text-align: justify;">With Conky, you can get rid of all or most of the indicators in the top panel.</li>
<li style="text-align: justify;">You can customize Conky to display all the information you want/need.</li>
<li style="text-align: justify;">You can easily access to Conky using a keybinding to show the desktop, which is way faster than the mouse.</li>
</ul>
<h3>
<br />
The Z shell, like bash but improved</h3>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhe7H4OnpCSoEBBZnb4h5yayQsWB9Sp3riDyUR529R_Il-jhKnre-7EDK75Lv4f4qnaug6bpcs8-5JSFfYbhv96hOA2JfRy515qIGBqFE07w55w1vt1RS3LI5hlv6lP21_egIAWLpnoooU/s1600/zsh.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhe7H4OnpCSoEBBZnb4h5yayQsWB9Sp3riDyUR529R_Il-jhKnre-7EDK75Lv4f4qnaug6bpcs8-5JSFfYbhv96hOA2JfRy515qIGBqFE07w55w1vt1RS3LI5hlv6lP21_egIAWLpnoooU/s320/zsh.png" width="320" /></a></div>
<div style="text-align: center;">
bash + better autocompletion + lots of themes + auto cd + git integration + ... = zsh</div>
<br />
<div style="text-align: justify;">
Bash is a great shell, but the Z shell is easier to customize, which can give you superpowers if correctly customized. Using the out of the box version of zsh feels a lot like bash, but thanks to the project <a href="https://github.com/robbyrussell/oh-my-zsh">oh my zsh</a>, you can get a fully customized zsh that beats vanilla bash.</div>
<br />
<div style="text-align: justify;">
These are the most relevants features of zsh customized with "oh my zsh", that beat bash:</div>
<ul>
<li style="text-align: justify;">Case insensitive auto completion.</li>
<li style="text-align: justify;">Double tab, let's you choose among the list of suggestions.</li>
<li style="text-align: justify;">Auto cd, you don't need to type the cd command, typing only the name of the directory is enough to change the file path.</li>
<li style="text-align: justify;">With the Git integration, you can add to the shell promp information about the git repository you are currently in.</li>
</ul>
<br />
<h3>MPD: The daemon of music</h3>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3jUSwnNNkb6MBn0b-GVZPntrLlsituU6mIfuF8j_dVKowBGuqvjyU6MZaonXR-D5x-8PMFwE32U3SSfGT82vtNyPm1SnohZqNLPMf_lYZ69wJ8wAbUuYPXjLtXVmwBdeXkaTBPMyCcyA/s1600/mpd_plus_client.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="173" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3jUSwnNNkb6MBn0b-GVZPntrLlsituU6mIfuF8j_dVKowBGuqvjyU6MZaonXR-D5x-8PMFwE32U3SSfGT82vtNyPm1SnohZqNLPMf_lYZ69wJ8wAbUuYPXjLtXVmwBdeXkaTBPMyCcyA/s320/mpd_plus_client.png" width="320" /></a></div>
<div style="text-align: center;">
MPD + ncmpccp, a ncurses based client.</div>
<br />
<div style="text-align: justify;">
The Music Player Daemon (MPD) is a daemon (a process that runs in the background) that uses your audio device to play music stored in a certain folder (the database) according to the order established in the playlist folder.</div>
<br />
<div style="text-align: justify;">
However to send commands like play, pause, next, etc to the MPD, a client is necessary. My choice of client is ncmpccp, which is a terminal based client that uses the ncurses library to implement a user interface.</div>
<br />
<div style="text-align: justify;">
The rationale of the selection, is again that the keyboard is faster than the mouse, also not having a GUI saves resources and finally this client can be integrated in my drop down Screen.</div>
<br />
<div style="text-align: justify;">
I have also installed <a href="https://github.com/eonpatapon/mpDris2">mpDris2</a> and a <a href="https://extensions.gnome.org/extension/55/media-player-indicator/">gnome extension</a> to control MPD via the top panel, this combination also enables notifications, which you can see in the above screenshot.</div>
<br />
<h3>
That's all!</h3>
<br />
<div style="text-align: justify;">
Those are the applications I use everyday and that have boosted my productivity. There are many other applications that I use but they may not be so useful for the average user.</div>
<br />
<div style="text-align: justify;">
If you are an Archer, please feel free to share your favorite application in the comment section.</div>
Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com81tag:blogger.com,1999:blog-1622983275835621655.post-90407847698939075082013-01-31T17:11:00.000-05:002013-01-31T17:11:10.073-05:00Screen: Multitasking in the command line<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjj9tHiZ9aKkx1yo5MJo3yiUVFPfne-X5ktRTe6ip6_jyjw2mHwzAVbInVMGN1N4WjSka35jWos5cosHiFwqbqHPWwaMfQpwjZjh7t6ui63qonW6r47EmRutPq5wSQtlKXEprzjR-EqB9Q/s1600/python_octave_multitask.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjj9tHiZ9aKkx1yo5MJo3yiUVFPfne-X5ktRTe6ip6_jyjw2mHwzAVbInVMGN1N4WjSka35jWos5cosHiFwqbqHPWwaMfQpwjZjh7t6ui63qonW6r47EmRutPq5wSQtlKXEprzjR-EqB9Q/s320/python_octave_multitask.png" width="320" /></a></div>
<div style="text-align: center;">
Multitasking Octave and Python with Screen. (Don't ask why, it's an example)</div>
<br />
<div style="text-align: justify;">
"Screen is a full-screen window manager that multiplexes a physical terminal between several processes, typically interactive shells." - definition from <a href="http://www.gnu.org/software/screen/">GNU Screen website</a>.</div>
<br />
<div style="text-align: justify;">
As the definition says Screen allows you to run multiple processes/shells in one terminal, this is priceless when you are sshing a remote server. However you can use the powers of Screen to do some command line multitask in your everyday life.</div>
<br />
<div style="text-align: justify;">
I'll cover how I use both Screen and the the <a href="https://extensions.gnome.org/extension/442/drop-down-terminal/">Gnome Drop Down Terminal</a> (alternatively <a href="http://guake.org/">Guake</a> can also be used). If you use Guake, you might say: "but I already have tabs in Guake, I don't need Screen". That's as debatable as the topic of Buffers vs Tabs in Vim, but everybody knows that Buffers beat Tabs everyday (OK, that's just my opinion).</div>
<br />
<h3>
Basics of Screen</h3>
<br />
<div style="text-align: justify;">
Install Screen from your distro repository if you haven't already. And let's see what Screen can do.</div>
<div class="terminal">
# Try this command<br />
screen
</div>
<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGRWZup31MsMYqzkO8J3PT377Nxrme7RkNLrYQlKME4ac8CMEWkzaPfIWtFZ38mYxXHpdWciuapYDh2YmqrciGNNdvOQOHBfMeFzwSHIfp_eoK2Ag4_RdhzK0xT0lhyphenhyphennqDpBEYrrczoPg/s1600/splash_screen.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGRWZup31MsMYqzkO8J3PT377Nxrme7RkNLrYQlKME4ac8CMEWkzaPfIWtFZ38mYxXHpdWciuapYDh2YmqrciGNNdvOQOHBfMeFzwSHIfp_eoK2Ag4_RdhzK0xT0lhyphenhyphennqDpBEYrrczoPg/s200/splash_screen.png" width="200" /></a></div>
</td><td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTzhTFgTKkxsNLyWW_FdNn3wdEeW-93nO4M68JjvEJlfcD_qkN650driVBTHlmeV3iXtYEcQmrr3mmIgGoPXHe-_cZlLMzSU4_o0H8IYF_3pgeeVu1rY05AmoW_iKZhI2ls9dbpSvI16Y/s1600/fist_window.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTzhTFgTKkxsNLyWW_FdNn3wdEeW-93nO4M68JjvEJlfcD_qkN650driVBTHlmeV3iXtYEcQmrr3mmIgGoPXHe-_cZlLMzSU4_o0H8IYF_3pgeeVu1rY05AmoW_iKZhI2ls9dbpSvI16Y/s200/fist_window.png" width="200" /></a></div>
</td>
</tr>
</tbody></table>
<div style="text-align: center;">
Notice the gnome-terminal screen now says "screen" in the title.</div>
<br />
<div style="text-align: justify;">
Some splash screen appears, you press enter and then looks like nothing happened... But something did happen, you are now in a Screen session!</div>
<div class="terminal">
# Try this command on your current window<br />
top
</div>
<div style="text-align: justify;">
You'll now see your running processes order by CPU usage. Now type: 'C-a c' (press both Ctrl and A, release both keys and then press the C key).</div>
<br />
<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEw34sgWGw0jTZudmqYH4MZ33i0vIcBoXjMuv4c2Cd0X3dQvh5PQpoGR5AwGLBhMLrR-wiDjpPRCuWt_jCoL4y0Jfm4qANx4sgocOg-SdwY0Nx8d60PmnhfmhTpVKuDc3TQN_zwAxh_MM/s1600/top_screen.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEw34sgWGw0jTZudmqYH4MZ33i0vIcBoXjMuv4c2Cd0X3dQvh5PQpoGR5AwGLBhMLrR-wiDjpPRCuWt_jCoL4y0Jfm4qANx4sgocOg-SdwY0Nx8d60PmnhfmhTpVKuDc3TQN_zwAxh_MM/s200/top_screen.png" width="200" /></a></div>
</td><td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp2PABwl9HZ4PCZnlk6FLviBqCrE8N7N9vQjwW2L09oxoPuj0r7Oe4aKxoYSTawFCK0_p-UufyKmscpMImdvIaQJijysWNKgpjPNkhRb5IKbvkcV8O7tnV7a4Fggah7-nBZmvp81cibDk/s1600/second_window.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp2PABwl9HZ4PCZnlk6FLviBqCrE8N7N9vQjwW2L09oxoPuj0r7Oe4aKxoYSTawFCK0_p-UufyKmscpMImdvIaQJijysWNKgpjPNkhRb5IKbvkcV8O7tnV7a4Fggah7-nBZmvp81cibDk/s200/second_window.png" width="200" /></a></div>
</td>
</tr>
</tbody></table>
<div style="text-align: center;">
Creating a new window in a Screen session.</div>
<br />
<div style="text-align: justify;">
You have just created a new window and you watching this second window. The command top is still running in the first window, just that is not visible. You can switch between these two windows using 'C-a n' or 'C-a p'.</div>
<br />
<div style="text-align: justify;">
Finally, you can "kill" a window using the command 'C-a k'. You'll see a prompt at the bottom, asking if you really want to kill window. Killing a window also terminates the process contained in it.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrz-VjXcegetsPNoqS5sypKbpYVmGDcUIXsDCMgGjVMb5G41NThbBZ1GtzISIKP9QO_k06wxHZlQ7_K4Tt8jBLUzS39RlWy5VryvM-2UceXb1aP5wGW0ULadc11q_zfuNbOJTtYkMmwIM/s1600/kill_window.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrz-VjXcegetsPNoqS5sypKbpYVmGDcUIXsDCMgGjVMb5G41NThbBZ1GtzISIKP9QO_k06wxHZlQ7_K4Tt8jBLUzS39RlWy5VryvM-2UceXb1aP5wGW0ULadc11q_zfuNbOJTtYkMmwIM/s320/kill_window.png" width="320" /></a></div>
<div style="text-align: center;">
Killing a window an a Screen session.</div>
<br />
<div style="text-align: justify;">
There are other commands, you can learn more about them using the help command 'C-a h'. There is another important feature of Screen named attaching/detaching, which is extremely useful for ssh connections, but I won't cover that here as it's not necessary to do the multitasking, as you'll see soon.</div>
<br />
<h3>
How do I know if I'm in a Screen session?</h3>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqn3yWwvDpaMRa7PIzvB-UhpQWW40t1paYEIaJdtt03D6YkAj-qMDWH9zWwE4zksTOKJX6xaU1Q26oxA9Yr06YAxEBQb-yZbBhi-IqSRuPJvZaG6AFh4stpPtdhou5X4t10yZKikYZp7s/s1600/screen_or_not.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="173" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqn3yWwvDpaMRa7PIzvB-UhpQWW40t1paYEIaJdtt03D6YkAj-qMDWH9zWwE4zksTOKJX6xaU1Q26oxA9Yr06YAxEBQb-yZbBhi-IqSRuPJvZaG6AFh4stpPtdhou5X4t10yZKikYZp7s/s320/screen_or_not.png" width="320" /></a></div>
<div style="text-align: center;">
I can't visually tell whether I'm in a Screen session or not.</div>
<br />
<div style="text-align: justify;">
If you run screen inside a a GUI terminal like the gnome-terminal, is easy to notice that you are in a Screen session because the title changes to "screen". On Guake is also easy to notice, as the tab name changes to "screen" accordingly.</div>
<br />
<div style="text-align: justify;">
But on the Gnome Drop Down Terminal you've got no way to tell. You can't tell either if you are on an X-less login session. At less not visually, but you can always test if 'C-a h' displays the Screen help.</div>
<br />
<div style="text-align: justify;">
A better way of telling Screen session apart is adding a status line, this line can also display other important information. Before adding that feature, we need to lean about the screenrc file.</div>
<br />
<h3>
screenrc</h3>
<br />
<div style="text-align: justify;">
As with many other applications, Screen has a rc file that executes certain commands at every startup, you can think of it as a configuration file. We'll work with the .screenrc file found in your home folder, that rc file only works with your current user account.</div>
<div class="terminal">
# Creating/editing the screenrc file<br />
vim ~/.screenrc</div>
<div style="text-align: justify;">
To turn off the startup message you can add this line to your .screenrc file:</div>
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
# Don't display the startup message
startup_message off
]]>
</script>
<h3>
Screen status</h3>
<br />
<div style="text-align: justify;">
To add a nice status line to Screen, you must append the following lines to your .screenrc file. (Source: <a href="https://bbs.archlinux.org/viewtopic.php?id=55618">Arch Linux Forums</a>)</div>
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
# Show status
hardstatus alwayslastline
hardstatus string '%{= kG}[ %{G}%H %{g}][%= %{= kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][%{B} %m-%d %{W}%c %{g}]'
]]>
</script>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqTtQoVj_Ssym8Sz-hZJVkcLrcI7wGOxEKHmv1qvGrEiiLfpo3pPWuMBdeBFCn43MY9YVjynNsN2l31-SFFALXgTWDpLXT0NGt8QtAZh3BqIohyphenhyphenDDKwWivXniHYigo-ukGLW3Tt-eI9as/s1600/screen_status.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqTtQoVj_Ssym8Sz-hZJVkcLrcI7wGOxEKHmv1qvGrEiiLfpo3pPWuMBdeBFCn43MY9YVjynNsN2l31-SFFALXgTWDpLXT0NGt8QtAZh3BqIohyphenhyphenDDKwWivXniHYigo-ukGLW3Tt-eI9as/s320/screen_status.png" width="320" /></a></div>
<div style="text-align: center;">
The Screen status line displays the hostname, a list of windows, the date and the time.</div>
<br />
<h3>
Launching a set of applications on every Screen call</h3>
<br />
<div style="text-align: justify;">
To start Screen with multiple windows and each window containing an application, add the following lines to your .screenrc file.</div>
<div style="text-align: justify;">
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
# Launch applications
screen -t <window_title> <command_to_run_on_this_window>
screen -t <window_title> <command_to_run_on_this_window>
...
screen -t <window_title> <command_to_run_on_this_window>
select <window_number>
]]>
</script>
On Screen the windows are numbered starting from 0. The final command selects which window will be active at startup.</div>
<br />
<div style="text-align: justify;">
For example, to start Screen with two windows, the first containing octave and the second containing the shell; and start with the shell window active, you'll need the following lines:</div>
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
# Launch octave and a shell
# (omitting the command launches the default shell)
screen -t octave octave
screen -t
select 1
]]>
</script>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilrepfEcpEv1TGqSRrjvO6j-UhOPziM9pl2jBtoiwxw3W-D7QuPMOZv1T1u-IRy1VjWhWd-AnCv-vgqBUu7_UXSLhBSdlFs_dewg7YB68W5N9uq2EgSVnG4wb9Xvyf_4ULS0kKtoXOtW4/s1600/two_windows.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilrepfEcpEv1TGqSRrjvO6j-UhOPziM9pl2jBtoiwxw3W-D7QuPMOZv1T1u-IRy1VjWhWd-AnCv-vgqBUu7_UXSLhBSdlFs_dewg7YB68W5N9uq2EgSVnG4wb9Xvyf_4ULS0kKtoXOtW4/s320/two_windows.png" width="320" /></a></div>
<div style="text-align: center;">
Start Screen with Octave and a shell (zsh in this example)</div>
<br />
<h3>
Keybindings</h3>
<br />
<div style="text-align: justify;">
Remember the command we tested at the beggining of this post? Well, we can map them to single keys for faster accessing. The following lines do just that, append them to your .screenrc:</div>
<div style="text-align: justify;">
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
# Keybindings
bindkey -k k2 screen # F2 - Open new window
bindkey -k k3 prev # F3 - Previous window
bindkey -k k4 next # F4 - Next window
bindkey -k k6 detach # F6 - Detach from this session
bindkey -k k7 copy # F7 - Enter copy/scrollback mode
bindkey -k k8 kill # F8 - Kill current window
bindkey -k k9 quit # F9 - Exit
]]>
</script>
Each keybinding has a description right next to it, for your reference.</div>
<br />
<h3>
Drop-down Multitasker Terminal</h3>
<br />
<div style="text-align: justify;">
As a final step let's integrate Screen to a drop down terminal for the ultimate command line multitasking experience.</div>
<br />
<h4>
Gnome Drop Down Terminal</h4>
<br />
<div style="text-align: justify;">
For the Gnome Drop Down Terminal, the process is straightforward: Simply head to the preferences of the extension and select screen as the custom command to run instead of the shell.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmJwehH7zT8Iv8mMSLwN59aGQc98rNz6uGAYxnLEzZaYLnVG0cFdTLbsTeqIvT1U8-TJbJtekr7aiIIefKNaRH_1ZBubfqU7OH0OAo6W5ySpKolZxn6E9BVmBEoivvhyskhjW8aQCsTx0/s1600/gnome_drop_down_preferences.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="262" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmJwehH7zT8Iv8mMSLwN59aGQc98rNz6uGAYxnLEzZaYLnVG0cFdTLbsTeqIvT1U8-TJbJtekr7aiIIefKNaRH_1ZBubfqU7OH0OAo6W5ySpKolZxn6E9BVmBEoivvhyskhjW8aQCsTx0/s320/gnome_drop_down_preferences.png" width="320" /></a></div>
<div style="text-align: center;">
Use Screen instead of the default shell in the Gnome Drop Down Terminal</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-m1Dt86Oy3kZ6YNF2eFnqRmm6VRFjnp9alZNUS8f-7SskQDIGjl9WW-nbggCqbQn9S-zUPQWfZ1SgZOf32NowhkEej3iFy_bKi63owKojZ5hyqHfqOmncoLOkDF7QQqZNzwP6Wjg9hNQ/s1600/gnome_drop_down_screen.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="173" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-m1Dt86Oy3kZ6YNF2eFnqRmm6VRFjnp9alZNUS8f-7SskQDIGjl9WW-nbggCqbQn9S-zUPQWfZ1SgZOf32NowhkEej3iFy_bKi63owKojZ5hyqHfqOmncoLOkDF7QQqZNzwP6Wjg9hNQ/s320/gnome_drop_down_screen.png" width="320" /></a></div>
<div style="text-align: center;">
Gnome Drop Down Terminal + Screen</div>
<br />
<h4>
Guake</h4>
<br />
<div style="text-align: justify;">
You can start Guake with some applications in it at startup as I explained in an <a href="http://embeddedprogrammer.blogspot.com/2012/06/ubuntu-tip-01-octave-on-guake-terminal.html">old post</a> (I used Octave as an example in that post). But using Screen and the .screenrc file is way simpler!</div>
<br />
<div style="text-align: justify;">
You'll need to run 'guake -e screen' instead of just guake, and the screenrc file will take care of launching your apps.</div>
<br />
The easiest way is to configure Guake as a startup application.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPgsKsFis4mCk95BDjruJmL55KSuHxKmoncJrE_UXp1tMw_WAoxFGXY0mycDDjwlyAgLejjBqCX6y01KKG_5hX1BNsrp1lRn-1098KpTW1RoPgVBreJGMCzqdTnutcin5LuBOd0l_Snps/s1600/guake_screen_startup.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="253" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPgsKsFis4mCk95BDjruJmL55KSuHxKmoncJrE_UXp1tMw_WAoxFGXY0mycDDjwlyAgLejjBqCX6y01KKG_5hX1BNsrp1lRn-1098KpTW1RoPgVBreJGMCzqdTnutcin5LuBOd0l_Snps/s320/guake_screen_startup.png" width="320" /></a></div>
<div style="text-align: center;">
Launch Guake with Screen inside it at startup.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisOMSDsiZM8nC8FBThgj2V_9tP6wzLcLifBYi3YHW0yDrOAIfjhG4n9Bn8GxLJAndIRAzkoWdf67IqhgU4XUJj-esT9ofPnJf9Nnhzvf64bO2kpq_ZvUNr98lPAOLG3jXhyphenhyphenK2XbfmETTg/s1600/guake_screen.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisOMSDsiZM8nC8FBThgj2V_9tP6wzLcLifBYi3YHW0yDrOAIfjhG4n9Bn8GxLJAndIRAzkoWdf67IqhgU4XUJj-esT9ofPnJf9Nnhzvf64bO2kpq_ZvUNr98lPAOLG3jXhyphenhyphenK2XbfmETTg/s320/guake_screen.png" width="320" /></a></div>
<div style="text-align: center;">
Screened Guake</div>
<br />
<div style="text-align: justify;">
I hope this post was useful to the heavy users of the command line and also pushes the casual users to get into it.</div>
Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com17tag:blogger.com,1999:blog-1622983275835621655.post-49512462046270165882013-01-31T10:23:00.001-05:002013-01-31T17:16:00.807-05:00Vim for Python Development<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQ6HXFYeOO2CZj8IsubA-UUfyznFQ42h7a81PjZ8IS2FRbJFvbtU-8xhU9H9BFrA5FLyULL4lyuPo06JgEtuSW-TQQDuT_T2pIfQgzFiyR3C9zGjkv8iRNUZ52JQOy0_wc0Kd9_X6UAYg/s1600/edit_mode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQ6HXFYeOO2CZj8IsubA-UUfyznFQ42h7a81PjZ8IS2FRbJFvbtU-8xhU9H9BFrA5FLyULL4lyuPo06JgEtuSW-TQQDuT_T2pIfQgzFiyR3C9zGjkv8iRNUZ52JQOy0_wc0Kd9_X6UAYg/s200/edit_mode.png" width="200" /></a></div>
</td><td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi72l969pZ9UTK28GqxCHIVmt9pXeagybcDSFe8cU6hvBl8iIY_pA3Wmx8g-iVjJylQOal6akF2wW-6Q9RHS7ZxwYAXFlbEgJQY7VvqH5GAETRDPfsAYpsyB5o9nou19aHvV5rMpZx4lvI/s1600/execution_mode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi72l969pZ9UTK28GqxCHIVmt9pXeagybcDSFe8cU6hvBl8iIY_pA3Wmx8g-iVjJylQOal6akF2wW-6Q9RHS7ZxwYAXFlbEgJQY7VvqH5GAETRDPfsAYpsyB5o9nou19aHvV5rMpZx4lvI/s200/execution_mode.png" width="200" /></a></div>
</td>
</tr>
</tbody></table>
<div style="text-align: center;">
Testing a PyOpenCL demo in vim.</div>
<br />
<div style="text-align: justify;">
This is my collection of hacks that turn vim into a python IDE.</div>
<br />
<h3>
Syntax Highlighting</h3>
<br />
<div style="text-align: justify;">
I'm using Arch Linux and Syntax Highlighting comes installed with my Vim package. I just need to enable the syntax highlighting in my .vimrc file:</div>
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
syntax on
]]>
</script>
<br />
<h3>
Enable line numbers</h3>
<br />
<div style="text-align: justify;">
Is as simple as adding this line to the .vimrc</div>
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
set number
]]>
</script>
<br />
<h3>
Indentation</h3>
<br />
<div style="text-align: justify;">
Adding this to the .vimrc file will enable PEP8 indentation only for *.py files.</div>
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
autocmd FileType python setlocal shiftwidth=4 tabstop=4 expandtab
]]>
</script>
<br />
<h3>
Autocompletion</h3>
<br />
<div style="text-align: justify;">
I use the great <a href="https://github.com/davidhalter/jedi-vim">jedi-vim</a> plugin from David Halter and the <a href="https://github.com/ervandew/supertab">SuperTab</a> plugin. You can find the installation steps at RedKrieg's post: <a href="http://redkrieg.com/2012/12/11/writing-python-like-a-jedi/">Writing Python like a Jedi</a>.</div>
<br />
<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzTfNIs2eWxlXJbaEynoiKtxqgm3TLPPZk-lCgkzqmr9hM8mehoAAo6vBgtE4TieyGIlG_odsM9ebMMraJPLP917zm52BB9YSl0DrrkNnZsgiF2cIdZIpSjsKfT1TPWeCT5Rx1iPItJfw/s1600/autocompletion_list.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzTfNIs2eWxlXJbaEynoiKtxqgm3TLPPZk-lCgkzqmr9hM8mehoAAo6vBgtE4TieyGIlG_odsM9ebMMraJPLP917zm52BB9YSl0DrrkNnZsgiF2cIdZIpSjsKfT1TPWeCT5Rx1iPItJfw/s200/autocompletion_list.png" width="200" /></a></div>
</td><td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSV2gbGjP9b5dVOHZSwFHHQhFHmiQa3Tc3Cyk58MEhBCbg13K3bEITA6S8TZhuJWcKfaMjDlAQBiokcXVyJNrP0RtV7MMGfTXKrOAg9j1tb7cQh_CYj2yVlEB4hPWLtSYBDTbhwjCuYX8/s1600/function_info.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSV2gbGjP9b5dVOHZSwFHHQhFHmiQa3Tc3Cyk58MEhBCbg13K3bEITA6S8TZhuJWcKfaMjDlAQBiokcXVyJNrP0RtV7MMGfTXKrOAg9j1tb7cQh_CYj2yVlEB4hPWLtSYBDTbhwjCuYX8/s200/function_info.png" width="200" /></a></div>
</td>
</tr>
</tbody></table>
<div style="text-align: center;">
Testing the jedi-vim plugin</div>
<br />
<h3>
Executing python code inside vim</h3>
<br />
<div style="text-align: justify;">
This is my favorite, press the F5 key to save the python script and execute it. Add this to the .vimrc file.</div>
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
autocmd FileType python map <buffer> <f5> :w<cr>:!python %<cr>
]]>
</script>
<br />
<h3 style="text-align: justify;">
Enable file specific features</h3>
<br />
<div style="text-align: justify;">
To enable all the filetype features I've defined above the following lines are needed in the .vimrc file.</div>
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
filetype plugin indent on
]]>
</script>
<br />
<h3>
Other plugins</h3>
<br />
<div style="text-align: justify;">
Here is a collection of other useful plugins, I recommend installing them using <a href="https://github.com/tpope/vim-pathogen">pathogen</a> if you can't get them from the repositories of your Linux distro.</div>
<br />
<ul>
<li><a href="https://github.com/fholgado/minibufexpl.vim">miniBufExplorer</a>, for easier navigation of buffers.</li>
<li><a href="https://github.com/scrooloose/nerdcommenter">NERDCommenter</a>, fast comment toggling with <leader>C<Space>.</li>
<li><a href="https://github.com/scrooloose/nerdtree">NERDTree</a>, file explorer.</li>
<li><a href="https://github.com/SirVer/ultisnips">UltiSnips</a>, snippets for fast code completion of commonly used blocks.</li>
</ul>
<br />
<div style="text-align: justify;">
If you have hacks of your own, please share them with everyone in the comments section.</div>
Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com36tag:blogger.com,1999:blog-1622983275835621655.post-70662151605615038572013-01-29T10:52:00.000-05:002013-01-29T10:52:52.104-05:00Demo: STM32F4 + OV7670 + qSerialTerm<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyhCYrfPFJ9jPTxRMCGfJHfw3Vyr44eZ1o0cPD2_aM5k3QgZ88jO3AnlaY7aT-gWBW9xmUuc5IS8qLsxzeQtL-RUjM1UTQiT1IdZHBk7VcQgPhM6nfJd7FTJFK7XrmTkh54H51TIFaqFw/s1600/setup_front.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyhCYrfPFJ9jPTxRMCGfJHfw3Vyr44eZ1o0cPD2_aM5k3QgZ88jO3AnlaY7aT-gWBW9xmUuc5IS8qLsxzeQtL-RUjM1UTQiT1IdZHBk7VcQgPhM6nfJd7FTJFK7XrmTkh54H51TIFaqFw/s200/setup_front.JPG" width="200" /></a></div>
</td><td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm_5UPgBm033PxNBLO53IVLteLUGPy6tO_p1Eejw7Q3s_ZsjPJWJ84odSd_NY0qUsBM1C8X2uSk8NFXRtJ5nNErGyRKxMRoPbowbSNCwvHaPygipCpe9TmjZg_gSWr7VLnDDOUWo8uRDI/s1600/setup_top.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm_5UPgBm033PxNBLO53IVLteLUGPy6tO_p1Eejw7Q3s_ZsjPJWJ84odSd_NY0qUsBM1C8X2uSk8NFXRtJ5nNErGyRKxMRoPbowbSNCwvHaPygipCpe9TmjZg_gSWr7VLnDDOUWo8uRDI/s200/setup_top.JPG" width="200" /></a></div>
</td>
</tr>
</tbody></table>
<div style="text-align: center;">
Yup, that mess of wires actually works.</div>
<br />
<div style="text-align: justify;">
In this post I'll cover 3 basic demo programs for the STM32F4 to interface the OV7670. Additionally, I've use qSerialTerm to receive data from the uC and display it in a human readable form.</div>
<br />
<div style="text-align: justify;">
I assume you know <a href="http://embeddedprogrammer.blogspot.com/2012/07/hacking-ov7670-camera-module-sccb-cheat.html">how the OV7670 works</a> and have some knowledge about common peripherals found in uC (GPIO, USART, DMA, etc).</div>
<br />
<div style="text-align: justify;">
The board used in this demo was the custom development board: <a href="http://embeddedprogrammer.blogspot.com/2012/08/f4dev-open-source-development-board-for.html">F4Dev</a>. The STM32F4DISCOVERY wasn't used and can't be used because the Digital Camera Interface (DCMI) peripheral pins are not fully available in that development board.</div>
<br />
<div style="text-align: justify;">
I've used <a href="http://embeddedprogrammer.blogspot.com/2012/09/stm32f4discovery-development-with-gcc.html">bareCortexM</a>, an Eclipse based IDE, and <a href="http://embeddedprogrammer.blogspot.com/2012/07/open-source-template-peripheral-library.html">libstm32pp</a>, a template peripheral library, to develop these demos for the STM32F4.</div>
<br />
<div style="text-align: justify;">
The following configuration applies to all the demos:</div>
<ul>
<li style="text-align: justify;">The STM32F4 operated at 42 MHz, the system clock, the AHB clock, the APB1 clock and the APB2 clock, all of them operated at this frequency.</li>
<li style="text-align: justify;">This 42 MHz frequency was obtained from the uC High Speed Internal (HSI) oscillator, which runs at 16 MHz, after scaling up the frequency using the uC internal PLL.</li>
<li style="text-align: justify;">The MCO1 pin was configured to output the HSI clock (16 MHz) and this output was used to drive the OV7670 XCLK.</li>
</ul>
<br />
<h3>
Demo 1: Scanning the SCCB bus (<a href="https://github.com/JorgeAparicio/libstm32pp/blob/master/demo/f4dev/ov7670/scan_sccb.hpp">Code</a>)</h3>
<br />
<div style="text-align: justify;">
In this first demo, the STM32F4 will interface the OV7670 using a <a href="https://github.com/JorgeAparicio/libstm32pp/blob/master/bits/sccb.tcc">bit bang implementation of the SCCB protocol</a>.</div>
<br />
<div style="text-align: justify;">
The uC will wait until the letter 'S' is received on the USART1 interface. Upon receiving this signal, the uC will read all the internal registers of the OV7670 using the SCCB interface.</div>
<br />
<div style="text-align: justify;">
After scanning all the OV7670 registers. The uC will report the address and values of the registers via the USART1 in a human readable format.</div>
<br />
<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvLbaUP54gRGwUw_RKlU7fkTk8dguKqHIXOrgqcw-qnNdWlr_d-ZCVRcak3h487mX3nqrbm1LHIwLwqwg7ozZV_F0-ERIPKgD0oozBDzC1aw2zofodlDlrIS5k9Yu5hllmd2v77ovCkaE/s1600/scan_sccb_top.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvLbaUP54gRGwUw_RKlU7fkTk8dguKqHIXOrgqcw-qnNdWlr_d-ZCVRcak3h487mX3nqrbm1LHIwLwqwg7ozZV_F0-ERIPKgD0oozBDzC1aw2zofodlDlrIS5k9Yu5hllmd2v77ovCkaE/s200/scan_sccb_top.png" width="200" /></a></div>
</td><td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCjhJADybTsxSJvw2DKutG8KR3FrpAm0QMTVmavwEpkTarH61a2VyBU3yBXrGwErnBrhdrI744v8_2ZniIYBqe1kJQY69HPwIU0praZBpIOBXCWcOP2rsoXZ0Fz3PwAt_i7WJQNfTfgLo/s1600/scan_sccb_bottom.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCjhJADybTsxSJvw2DKutG8KR3FrpAm0QMTVmavwEpkTarH61a2VyBU3yBXrGwErnBrhdrI744v8_2ZniIYBqe1kJQY69HPwIU0praZBpIOBXCWcOP2rsoXZ0Fz3PwAt_i7WJQNfTfgLo/s200/scan_sccb_bottom.png" width="200" /></a></div>
</td>
</tr>
</tbody></table>
<div style="text-align: center;">
Default values of the internal registers of the OV7670</div>
<br />
You can find the log file of the uC output <a href="https://docs.google.com/file/d/0B8iP1idFuKEuTFJWMUhqdU1xMmc/edit">here</a>.<br />
<br />
Under the hood details: The formatting was done using the printf function.<br />
<br />
<h3>
Demo 2: Reading a frame and visualizing the data in hex format (<a href="https://github.com/JorgeAparicio/libstm32pp/blob/master/demo/f4dev/ov7670/hex_single_shot.hpp">Code</a>)</h3>
<br />
<div style="text-align: justify;">
In this second demo, the STM32F4 will interface the OV7670 using the Digital Camera Module Interface (DCMI) to grab a frame from the OV7670 and then display the data in hexadecimal format.</div>
<br />
<div style="text-align: justify;">
The uC will wait until the letter 'S' is received on the USART1 interface. Upon receiving this signal, the uC will use the DCMI in single shot mode to grab one frame from the OV7670.</div>
<br />
<div style="text-align: justify;">
After capturing the frame, the uC will send all the data via the USART1 interface in a human readable hexadecimal format.</div>
<br />
<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdj-xus5JFwKtwfFoqWeAyvWA1ucI7AkDdIHF8_lSuTKx1CnX0nQACoZtPbvCel_XQL2KaRlquoDKRC59O7sKYJEerrzKo7KKqnP2S2HkLc2W8NqJI4b7fFEl7fbYNX6pxAlzemrhgBeY/s1600/hex_pitch_black_top.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdj-xus5JFwKtwfFoqWeAyvWA1ucI7AkDdIHF8_lSuTKx1CnX0nQACoZtPbvCel_XQL2KaRlquoDKRC59O7sKYJEerrzKo7KKqnP2S2HkLc2W8NqJI4b7fFEl7fbYNX6pxAlzemrhgBeY/s200/hex_pitch_black_top.png" width="200" /></a></div>
</td><td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH0uKWLRBzwAnAVcNtuWsfRpVo4xPSJqY_AAqGqv-Y3qyijhRK6uk2osGwK7t4yuUtx94DBE2QAPdPU_ys30a5RsAXpy2gGxVCzfTROpPWpze5-Rzbqi48nvrPU4HmkDngpfXf-DC4S9o/s1600/hex_pitch_black_bottom.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH0uKWLRBzwAnAVcNtuWsfRpVo4xPSJqY_AAqGqv-Y3qyijhRK6uk2osGwK7t4yuUtx94DBE2QAPdPU_ys30a5RsAXpy2gGxVCzfTROpPWpze5-Rzbqi48nvrPU4HmkDngpfXf-DC4S9o/s200/hex_pitch_black_bottom.png" width="200" /></a></div>
</td>
</tr>
</tbody></table>
<div style="text-align: center;">
Frame taken in a pitch black environment. Data in hex format.</div>
<br />
<div style="text-align: justify;">
You can get the full log file <a href="https://docs.google.com/file/d/0B8iP1idFuKEucV9GUjUzb0ZObTQ/edit">here</a>.</div>
<br />
<div style="text-align: justify;">
Under the hood details: The DCMI peripheral works hand to hand with the DMA peripheral. The data that is captured by the DCMI is moved by the DMA to a predetermined memory address without intervention of the uP. The formatting was done using the printf function.</div>
<br />
<h3>
Demo 3: Reading a frame and visualizing the data as an image (<a href="https://github.com/JorgeAparicio/libstm32pp/blob/master/demo/f4dev/ov7670/binary_single_shot.hpp">Code</a>)</h3>
<div style="text-align: justify;">
The last demo is pretty similar to the second demo. The difference is that the uC reports the frame data in binary form. On the PC side, this binary data is parsed and displayed in qSerialTerm.</div>
<br />
<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRL5a1un7U6-O12cwjhNDr2gRkn18CUDFo8bVR4ox5MRJXX_p-yEU4000adtYe0lIsexwzFrY-00Zwwom-DGJvHRpsWr1IMPO4K1MXxF9mENCh4FcHYEIKmtHyAdnqDH3vbXRJNHlP468/s1600/binary_electrical_tape.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRL5a1un7U6-O12cwjhNDr2gRkn18CUDFo8bVR4ox5MRJXX_p-yEU4000adtYe0lIsexwzFrY-00Zwwom-DGJvHRpsWr1IMPO4K1MXxF9mENCh4FcHYEIKmtHyAdnqDH3vbXRJNHlP468/s200/binary_electrical_tape.png" width="200" /></a></div>
</td><td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgG_JaEXFCfYcgRGK84yOyCTEBplGmZ8t0cFhL5On-Tqj9npEgV-AYTASmQ9XUCW4mXatIx3vtk7gBmNz34PqZw1TvQFJrvPU8s1dVkgHed3uF3i2DGGC2dZgYn7hMGxR0fVmHDUwyOKcU/s1600/binary_pitch_black.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgG_JaEXFCfYcgRGK84yOyCTEBplGmZ8t0cFhL5On-Tqj9npEgV-AYTASmQ9XUCW4mXatIx3vtk7gBmNz34PqZw1TvQFJrvPU8s1dVkgHed3uF3i2DGGC2dZgYn7hMGxR0fVmHDUwyOKcU/s200/binary_pitch_black.png" width="200" /></a></div>
</td>
</tr>
</tbody></table>
<div style="text-align: center;">
Frames captured by the OV7670. Left: A electrical tape. Right: Pitch black image.</div>
<br />
<div style="text-align: justify;">
Under the hood details: After capturing the frame, the data was sent through the USART interface using the DMA peripheral.</div>
<br />
<div style="text-align: justify;">
That's it. You have access to my full code, both the STM32F4 firmware and the qSerialTerm are fully available to you. I hope this information will help you in projects that involve the OV7670.</div>
Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com354tag:blogger.com,1999:blog-1622983275835621655.post-71269752372734912932013-01-28T15:58:00.000-05:002013-01-31T18:11:37.776-05:00Augmenting Octave with Vim<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhf5q44Il1T2XN9I95EDFFB4nag2mVV4uapzqmhq36TxtGn6FdqbF8aPG2Vo_XHo8vVEMNSnB0yd1Wsycp9tqcWBydbWhf4gdGxfPSVUokvtqrkqQiRhK7SGYJo1pStbux-gJxUjUUwZc/s1600/editor_mode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhf5q44Il1T2XN9I95EDFFB4nag2mVV4uapzqmhq36TxtGn6FdqbF8aPG2Vo_XHo8vVEMNSnB0yd1Wsycp9tqcWBydbWhf4gdGxfPSVUokvtqrkqQiRhK7SGYJo1pStbux-gJxUjUUwZc/s200/editor_mode.png" width="200" /></a></div>
</td>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj28Qx0mWwtrjns1JabzHAt0jCG7KoqQsm9AO7wjiVoVtymx45VqcVUAwiSY2IkfaDbm-qLGGnQ0ZiGhVQ4RPU27UOe0nhlr8AulcuuI_3v1b2HYTnqT0CaFo3wIYeIjyW2s5_zAL8mDbA/s1600/execution_mode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj28Qx0mWwtrjns1JabzHAt0jCG7KoqQsm9AO7wjiVoVtymx45VqcVUAwiSY2IkfaDbm-qLGGnQ0ZiGhVQ4RPU27UOe0nhlr8AulcuuI_3v1b2HYTnqT0CaFo3wIYeIjyW2s5_zAL8mDbA/s200/execution_mode.png" width="200" /></a></div>
</td>
</tr>
</tbody></table>
<div style="text-align: center;">
Integrating the powerful mathematical package, Octave, with the flexible editor, Vim.</div>
<br />
<div style="text-align: justify;">
Today, I'm sharing some tips to use the vim editor inside the Octave interactive command line.</div>
<br />
<h3>
The octaverc file</h3>
<br />
<div style="text-align: justify;">
The first thing towards customizing Octave is creating an .octaverc file, if you don't have one already. The .octaverc file holds some Octave commands that are executed every time you launch Octave.</div>
<br />
<div style="text-align: justify;">
We'll work with the .octaverc file that lives in your home directory, which is user specific.</div>
<div class="terminal">
# Create/modify .octaverc in your home folder<br />
vim ~/.octaverc
</div>
A good starting .octaverc file looks as follows:<br />
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
# Matlab like prompt
PS1(">> ")
# Octave working directory
cd /some/directory
#Clear the startup screen
clc;
]]>
</script>
<br />
<h3>
Using vim as editor in Octave</h3>
<br />
<div style="text-align: justify;">
Next, let's set vim as the default editor in Octave. (<a href="http://wiki.octave.org/Vim">source of information</a>)</div>
<div class="terminal">
# Add extra configuration<br />
vim ~/.octaverc</div>
<div style="text-align: justify;">
Open the .octaverc file and append the following:</div>
<div style="text-align: justify;">
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
# Use vim as editor<br />
edit mode sync
edit home .
edit editor 'vim > /dev/tty 2>&1 < /dev/tty %s'
]]>
</script>
Now you can call vim from within Octave, and use it in command line mode, i.e. without opening an (unnecessary) additional window.</div>
<br />
<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6Y6uSpByy489zIiJd1rDnA4M17YCna-03368Mxk5IkhKLx2Wgse3DFB0F0YizF80JEu40H0KZHPHWo1mAjaZibfozfMjlI0sYazofo7q4-ONs7OXAEpje7T5VC6Uxt94kVwqIdq0Yuqw/s1600/edit_m_file.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6Y6uSpByy489zIiJd1rDnA4M17YCna-03368Mxk5IkhKLx2Wgse3DFB0F0YizF80JEu40H0KZHPHWo1mAjaZibfozfMjlI0sYazofo7q4-ONs7OXAEpje7T5VC6Uxt94kVwqIdq0Yuqw/s200/edit_m_file.png" width="200" /></a></div>
</td><td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIvnfCoRmiLicUQC7B5-t1gTY3iqO6VuTRlVv8kkbedvc0i2XvsJdqvN6VlbDMaPb2pZ8uRLKs6kC0IAxE3WYDv-fFFiFfv1jIue_MEtKQ8KxN53Bskpo6trPXakRPQUEpnoj_6qQdpPU/s1600/m_file_template.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIvnfCoRmiLicUQC7B5-t1gTY3iqO6VuTRlVv8kkbedvc0i2XvsJdqvN6VlbDMaPb2pZ8uRLKs6kC0IAxE3WYDv-fFFiFfv1jIue_MEtKQ8KxN53Bskpo6trPXakRPQUEpnoj_6qQdpPU/s200/m_file_template.png" width="200" /></a></div>
</td>
</tr>
</tbody></table>
<div style="text-align: center;">
As a bonus you get a function template.</div>
<br />
<div style="text-align: justify;">
Now, let's tweak vim for extra features!</div>
<br />
<h3>
Adding syntax highlighting</h3>
<br />
<div style="text-align: justify;">
We'll add syntax coloring/highlighting to vim. Similar to the .octaverc file, vim also has a configuration file named .vimrc. Before touching the .vimrc file, you'll need to grab a vim syntax file from <a href="http://www.vim.org/scripts/script.php?script_id=3600">here</a> (grab the latest version).</div>
<br />
<div style="text-align: justify;">
Next you'll need to drop that octave.vim file in the following directory: ~/.vim/syntax.</div>
<div class="terminal">
# If you don't have the folders already<br />
mkdir -p ~/.vim/syntax<br />
mv /path/to/downloaded/octave.vim ~/.vim/syntax/octave.vim</div>
<div style="text-align: justify;">
Next, you'll need to append the following lines in your .vimrc file.</div>
<div style="text-align: justify;">
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
" enable syntax highlighting
syntax on
" .m files are "octave" files
augroup filetypedetect
au! BufRead,BufNewFile *.m, set filetype=octave
augroup END
]]>
</script>
Let's try editing a file inside Octave again.</div>
<br />
<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6Y6uSpByy489zIiJd1rDnA4M17YCna-03368Mxk5IkhKLx2Wgse3DFB0F0YizF80JEu40H0KZHPHWo1mAjaZibfozfMjlI0sYazofo7q4-ONs7OXAEpje7T5VC6Uxt94kVwqIdq0Yuqw/s1600/edit_m_file.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6Y6uSpByy489zIiJd1rDnA4M17YCna-03368Mxk5IkhKLx2Wgse3DFB0F0YizF80JEu40H0KZHPHWo1mAjaZibfozfMjlI0sYazofo7q4-ONs7OXAEpje7T5VC6Uxt94kVwqIdq0Yuqw/s200/edit_m_file.png" width="200" /></a></div>
</td><td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisPcMuKMZ4ieCXX6GXBUN_DDjYawe7nhj5FpEsTD9CNVRYIKGfd1FfN-5JdSdDP6uYOp_N0dn2sH4rEzTUJYT8mw70Yg7LFvoVJnQbdnHn_5FJSISN2d4h28y-PG3ZOjYiCqrS9xFBNU8/s1600/syntax_highlighting.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisPcMuKMZ4ieCXX6GXBUN_DDjYawe7nhj5FpEsTD9CNVRYIKGfd1FfN-5JdSdDP6uYOp_N0dn2sH4rEzTUJYT8mw70Yg7LFvoVJnQbdnHn_5FJSISN2d4h28y-PG3ZOjYiCqrS9xFBNU8/s200/syntax_highlighting.png" width="200" /></a></div>
</td>
</tr>
</tbody></table>
<div style="text-align: center;">
Added Octave syntax highlighting for vim.</div>
<br />
<h3>
Execute Octave scripts from within vim</h3>
<br />
<div style="text-align: justify;">
Here is where the magic comes in. With this hack, you'll be able to test the octave script you are editing in vim, inside vim and without leaving vim. In other words, you'll be able to use the F5 key to run your script, just like you do in the Matlab editor.</div>
<br />
<div style="text-align: justify;">
Without further ado, you'll need to add this to your .vimrc</div>
<div style="text-align: justify;">
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
# F5 executes the octave script you are editing<br />
autocmd FileType octave map <buffer> <f5> ggOpkg load all<esc>Gopause<esc>:w<cr>:!octave -qf %<cr>ddggdd:w<cr>
]]>
</script>
Let's test the magic.</div>
<br />
<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAzQrH59nvuzmkq6lOr2IJvSzMaE-cniL3cJkNn0Bpp01K9N2m3HfJtBn3Z3ZpzhF0-ZfA7y2Dga6K76oK5rb4v6V8xtKxgG_HkVHBwify1TUzHwIdGzyUoGHkR_85vU2SqzhuS4on93U/s1600/hello_world_script.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAzQrH59nvuzmkq6lOr2IJvSzMaE-cniL3cJkNn0Bpp01K9N2m3HfJtBn3Z3ZpzhF0-ZfA7y2Dga6K76oK5rb4v6V8xtKxgG_HkVHBwify1TUzHwIdGzyUoGHkR_85vU2SqzhuS4on93U/s200/hello_world_script.png" width="200" /></a></div>
<br /></td><td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6Zo9YGjqZnoX0atgZUj8Y3fDt0ZdRraa1mnkSGtVAzsT_vwigQgvEIt_ATtPwfnT0o1DRyJHjU0sfUoiAg-h0OedXdgKmtyXF1AFBQUEJZbJBDi3ysSvK1HC5uyz2NVYNT9u-NYJaUnM/s1600/testing_execution.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6Zo9YGjqZnoX0atgZUj8Y3fDt0ZdRraa1mnkSGtVAzsT_vwigQgvEIt_ATtPwfnT0o1DRyJHjU0sfUoiAg-h0OedXdgKmtyXF1AFBQUEJZbJBDi3ysSvK1HC5uyz2NVYNT9u-NYJaUnM/s200/testing_execution.png" width="200" /></a></div>
<br /></td>
</tr>
</tbody></table>
<div style="text-align: center;">
Executing an Octave script from within vim using the F5 key in normal mode.</div>
<br />
<div style="text-align: justify;">
I need to inform you that this hack adds two extra lines of code to your script:</div>
<br />
<div style="text-align: justify;">
"pkg load all" at the beginning of your code. Which grants access to all functions inside the extra Octave packages.</div>
<br />
<div style="text-align: justify;">
"pause" at the end of your code. Without this you won't be able to see the plots drawn in your script.</div>
<br />
<div style="text-align: justify;">
When the execution of the script finishes, these two lines are removed.</div>
<br />
<div style="text-align: justify;">
That's all folks, happy coding!</div>
Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com35tag:blogger.com,1999:blog-1622983275835621655.post-17906326909696691742013-01-05T23:20:00.000-05:002013-01-05T23:24:47.377-05:00Simmechanics: Simulating floor interaction/collision<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCGpORB7SUvIr7VU6Gm4TIsnBGJSh-fY3-i0ZNBxZiDyNfHNaUalTYD6pgK9qlfWchDBLrX1fUSvrZ6fCe6RbTPPdXKapahZcy64CJEj8NyTeJjpSxj3WrFZUvl9zmQgbmJQZHyc5yaHI/s1600/floorInteraction.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCGpORB7SUvIr7VU6Gm4TIsnBGJSh-fY3-i0ZNBxZiDyNfHNaUalTYD6pgK9qlfWchDBLrX1fUSvrZ6fCe6RbTPPdXKapahZcy64CJEj8NyTeJjpSxj3WrFZUvl9zmQgbmJQZHyc5yaHI/s320/floorInteraction.png" width="320" /></a></div>
<br />
I'll demonstrate how to simulate a floor in Simmechanics, this floor will prevent free falling (6 DOF) objects from falling below a threshold level ("the floor level"), i.e. I will simulate a collision/interaction between the free falling object and the floor.</div>
<br />
<div style="text-align: justify;">
I'll assume you have a basic understanding of how Simmechanics works. If you don't, you might want to check <a href="http://embeddedprogrammer.blogspot.com/2013/01/simmechanics-simulating-multibody.html">this post</a>.</div>
<br />
<h3>
The problem</h3>
<br />
<div style="text-align: justify;">
If you have used Simmechanics before, then you know it's an excellent toolbox for simulation of multibody dynamics. You can easily work with robotic arms, which are always fixed to the ground. But what happens when you want to work with legged robots, that can't be fixed to the ground. Well, then you run in a problem, if you don't fix any part of the robot to the ground, then the robot will fall and fall by action of the gravity. Removing the gravity is not an option, because you want to design the controllers of your robot with gravity compensation, even worse your robot will float if you simulate a zero gravity environment.</div>
<br />
Let's develop a minimal model to illustrate the problem: a 6 DOF ball.<br />
<br />
<h3>
Illustrating the problem</h3>
<br />
We'll start by drawing the floor. Implement the following block diagram in Simulink.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9YLeFM3rsCKHCKKWOvKQ0re_koQFJ3xAOSQe-KURdgi2WIfnXOJWikF7pVickbtTN2dKJrjd8bZ_VcylZiGPL6qXBdXZV7pga2F-yK9wBCA4-H1QRk8QAmL8JzDkqqUNOyHeP_8hEdMQ/s1600/floorModel.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="230" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9YLeFM3rsCKHCKKWOvKQ0re_koQFJ3xAOSQe-KURdgi2WIfnXOJWikF7pVickbtTN2dKJrjd8bZ_VcylZiGPL6qXBdXZV7pga2F-yK9wBCA4-H1QRk8QAmL8JzDkqqUNOyHeP_8hEdMQ/s320/floorModel.png" width="320" /></a></div>
<div style="text-align: center;">
Block diagram to visualize the floor.</div>
<br />
<div style="text-align: justify;">
Modify the Floor block parameters to match the following image, and also on the Visualization tab change the Body geometry option to "Equivalent ellipsoid from mass properties".</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEji7ajAJUyM0wrp3qp27p54MPnb5mS1wYL-p541EU72vCPRjZ1e55bG_OgYdYxOvqANps1HCNTBtP9QFOOm1DuROB0LHYJJ6Q08ypiQlNksoPBdeFOXIF3F_S808GXA_Q6wDNcxTyooDko/s1600/floorParameters.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="247" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEji7ajAJUyM0wrp3qp27p54MPnb5mS1wYL-p541EU72vCPRjZ1e55bG_OgYdYxOvqANps1HCNTBtP9QFOOm1DuROB0LHYJJ6Q08ypiQlNksoPBdeFOXIF3F_S808GXA_Q6wDNcxTyooDko/s320/floorParameters.png" width="320" /></a></div>
<div style="text-align: center;">
Parameters to draw a 1 meter radius floor.</div>
<br />
Next, start a simulation. Activate the the Isometric View and the "Enable Automatic Expanding Fit".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiI1bLXqgwxbOwbpBttXND0RIbzjQxZutQgaUw20M7tljxnJgjnqbInxuBzZzpOZHkmBmj151R0zXJUu-tvbzRpvbmNrE0zLfoYUyLSVoAViwCgk2jt3KQ-jh_dnXc8IMYlqcfIVfAOJAk/s1600/floorAnimation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiI1bLXqgwxbOwbpBttXND0RIbzjQxZutQgaUw20M7tljxnJgjnqbInxuBzZzpOZHkmBmj151R0zXJUu-tvbzRpvbmNrE0zLfoYUyLSVoAViwCgk2jt3KQ-jh_dnXc8IMYlqcfIVfAOJAk/s320/floorAnimation.png" width="320" /></a></div>
<div style="text-align: center;">
Animation showing the floor as a 1 m radius disk.</div>
<br />
Now, we add the free falling ball. Add more blocks to the model to match the following diagram.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlhtPvRFn4YocRtD90AvKpt-rgZIECqv5ISo3GSlexbOVrvOIyHOi5cK92ET_wI80pkqwHhQorXfvcEwqlYcCYWnBeAyuzWB5RsbTdCER_GL3uLTg0uVRAu-HHvgK9jBhlXylJIdo9WoE/s1600/ballModel.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="230" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlhtPvRFn4YocRtD90AvKpt-rgZIECqv5ISo3GSlexbOVrvOIyHOi5cK92ET_wI80pkqwHhQorXfvcEwqlYcCYWnBeAyuzWB5RsbTdCER_GL3uLTg0uVRAu-HHvgK9jBhlXylJIdo9WoE/s320/ballModel.png" width="320" /></a></div>
<div style="text-align: center;">
Added a free falling ball to the model.</div>
<br />
<div style="text-align: justify;">
Next, modify the parameters of the Above Ground block and the Ball block, to match the following images. On the Visualization tab of the ball block also select "Equivalent ellipsoid from mass properties" on the Body geometry option.</div>
<br />
<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6f6PK3p10ISYCyNdxkrvH-PBZvQpwIqSwzMie2C7Gy3otsDB9mpp2HNOAi0cKVLM4TYK9CNJwYYUpJzloleLJdBZxF_f_cLIsUp-b6B9nXhNq6fpdWQcdIInJJ7OqKX5jvmOepkG0jEY/s1600/aboveGroundParameters.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="114" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6f6PK3p10ISYCyNdxkrvH-PBZvQpwIqSwzMie2C7Gy3otsDB9mpp2HNOAi0cKVLM4TYK9CNJwYYUpJzloleLJdBZxF_f_cLIsUp-b6B9nXhNq6fpdWQcdIInJJ7OqKX5jvmOepkG0jEY/s200/aboveGroundParameters.png" width="200" /></a></div>
</td><td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5CGGMswWGgCPOTvCuFZLIZ71uIBL2iK3Og7tAdyN1yNhxLRRlwsQXqx-WX_zXexgbRQqXod7yjuC8Ia-865PuzUD0QOk55bKYN49F6k-VTfeCNLW6EENI130F_xbwuTM9VU95pxeD6eY/s1600/ballParameters.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="154" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5CGGMswWGgCPOTvCuFZLIZ71uIBL2iK3Og7tAdyN1yNhxLRRlwsQXqx-WX_zXexgbRQqXod7yjuC8Ia-865PuzUD0QOk55bKYN49F6k-VTfeCNLW6EENI130F_xbwuTM9VU95pxeD6eY/s200/ballParameters.png" width="200" /></a></div>
</td></tr>
<tr><td><div style="text-align: center;">
Above Ground parameters</div>
</td>
<td><div style="text-align: center;">
Ball parameters</div>
</td>
</tr>
</tbody></table>
<br />
Now simulate the system and observe the problem.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9d7uw96GI5BZf-uxGXysZLyZBEJ-iNxjUzQx-ck7eMl7XY_jB8iAM6V41jRJaU7f1XXtkfxgpCiPcdwCPEC2i73uAWuUVi9HhsUqyGRT5wAm7f7okDP1pzp-bVUyG4D21UUFLuCmJonM/s1600/fallThrough.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9d7uw96GI5BZf-uxGXysZLyZBEJ-iNxjUzQx-ck7eMl7XY_jB8iAM6V41jRJaU7f1XXtkfxgpCiPcdwCPEC2i73uAWuUVi9HhsUqyGRT5wAm7f7okDP1pzp-bVUyG4D21UUFLuCmJonM/s320/fallThrough.png" width="320" /></a></div>
<div style="text-align: center;">
Ball falling through the floor.</div>
<br />
<h3>
The Idea</h3>
<br />
<div style="text-align: justify;">
Known the problem, we must now create a solution. Let's begin by analyzing how the floor behaves. Ideally the floor is a rigid body that exerts enough force over adjacent bodies to prevent them from falling through. Now, perfect rigid bodies doesn't exist in the real world, all bodies deform when stressed or compressed. This means our floor model must be elastic, this can be modeled as a spring.</div>
<br />
<div style="text-align: justify;">
Our floor model can't be modeled only as a spring, otherwise will end with a trampoline. When we fall to the ground, we don't jump back to the sky, instead our potential energy dissipates as heat or as permanent deformation. This means our floor model must also have a dissipation element.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://upload.wikimedia.org/wikipedia/commons/4/4a/Mass-Spring-Damper.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="187" src="http://upload.wikimedia.org/wikipedia/commons/4/4a/Mass-Spring-Damper.png" width="320" /></a></div>
<div style="text-align: center;">
A mass-spring-damper system.</div>
<br />
<div style="text-align: justify;">
That description resembles a lot to a mass-spring-damper system. As you might know those system tend to vibrate, unless they are overdamped. This means our floor model must behave as an overdamped mass-spring-damper system. The final condition is that the free falling object must be the mass of the system, this means that our floor model doesn't really has a mass parameter. Other way to think of it is that the mass is detachable, and this mass is only affected by the spring and the damper when is at or below the floor level.</div>
<br />
<h3>
Implementing the floor interaction</h3>
<br />
<div style="text-align: justify;">
First, let's enable some sensor/actuator ports on the free falling ball. These two ports must be located at the same point, at the bottom of the ball.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglVPlnoAL59Z1kTGy4ifSqL-FyW-h_a8jL13E5s51SUKHEUB8Xs9KiLBgl745phY6ZsfZHUWqIP_ilnZMdXpag7EfoJUIHle_xzPW5_2sln5uLds8Gkc0FWDnhxpG2c7sDncqQCLWDMpI/s1600/sensorActuatorPorts.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="247" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglVPlnoAL59Z1kTGy4ifSqL-FyW-h_a8jL13E5s51SUKHEUB8Xs9KiLBgl745phY6ZsfZHUWqIP_ilnZMdXpag7EfoJUIHle_xzPW5_2sln5uLds8Gkc0FWDnhxpG2c7sDncqQCLWDMpI/s320/sensorActuatorPorts.png" width="320" /></a></div>
<div style="text-align: center;">
Adding sensor/actuator ports to the free falling ball.</div>
<br />
The floor control diagram can be implemented as follows:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1IcZUFWcYklJ14QfDnRVN60Ue99UCN8YHm2W1Hk2Wz22QI4gj4O_mUywlQEMXYAYjRIj9FuF6AAW_tlep5_jTpMLc2V2Z3NHrlRNcWsQb3BgckOQbAVIAPdq65TEAtCRUFAjhOgw1wy8/s1600/floorControlDiagram.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="204" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1IcZUFWcYklJ14QfDnRVN60Ue99UCN8YHm2W1Hk2Wz22QI4gj4O_mUywlQEMXYAYjRIj9FuF6AAW_tlep5_jTpMLc2V2Z3NHrlRNcWsQb3BgckOQbAVIAPdq65TEAtCRUFAjhOgw1wy8/s320/floorControlDiagram.png" width="320" /></a></div>
<div style="text-align: center;">
Floor Control Diagram.</div>
<br />
<div style="text-align: justify;">
The body sensor is configured to output the position in meters, while the body actuator is configured to exert force in newtons over the ball. Using a demuxer, we extract the Y component of the position, then we compare it to the floor level. If the Y position of the bottom of the ball is below the floor level, then we activate the spring-damper system represented by the gains 'k' and 'c', otherwise the floor exerts no force over the ball. The force developed by the spring damper system is exerted over the ball but only in the Y direction, thanks to a muxer and the body actuator.</div>
<br />
The final step is selecting 'k' and 'c'. You need to considerate the following things:<br />
<br />
<ul>
<li>The damping ratio "c / 2 / sqrt(m * k)" should be greater than 1, to guarantee <a href="http://en.wikipedia.org/wiki/Damping#Over-damping_.28.CE.B6_.3E_1.29">overdamping</a>.</li>
<li>The free falling body will sink a distance "m * g / k" into the ground, so you might want to increase 'k', right?</li>
<li>But Increasing 'k', also increases the computation load of the simulation.</li>
</ul>
<br />
<div style="text-align: justify;">
How do I select the parameters 'k' and 'c'? I first select 'k' balancing how much sinking and computation load can I tolerate. Then I compute 'c' using the biggest mass and choosing a damping ratio of 1.</div>
<br />
<h3>
The Results</h3>
<br />
I'll leave you with the simulation output.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGMY3xIhdeXTIgxnbo9ebv3woC5q4u1NUXv80ojK0rECakb8NigvV5IzzTlefLGWUmy06eAJqGnE8J4QVRM8GcmgmnyZEfllkqeAdiRAnxFh3NJvl0BKD9OZOR56eh3nr6rhQfrHqwDwk/s1600/floorInAction.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGMY3xIhdeXTIgxnbo9ebv3woC5q4u1NUXv80ojK0rECakb8NigvV5IzzTlefLGWUmy06eAJqGnE8J4QVRM8GcmgmnyZEfllkqeAdiRAnxFh3NJvl0BKD9OZOR56eh3nr6rhQfrHqwDwk/s320/floorInAction.png" width="320" /></a></div>
<div style="text-align: center;">
Floor control enabled.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihPN457taawYO8AaSa21-SwHB4hW7o4xhToSDBhOqYkGKkginFQe14TJAzNpCSluYiXb0SYEwRcutgMYBGrcSo3pYNyC97XBa2ODhiHbAtvjPTOSXn2O6nRnQ1DIYG6cZ5gdrxx7gASF0/s1600/floorSinking.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihPN457taawYO8AaSa21-SwHB4hW7o4xhToSDBhOqYkGKkginFQe14TJAzNpCSluYiXb0SYEwRcutgMYBGrcSo3pYNyC97XBa2ODhiHbAtvjPTOSXn2O6nRnQ1DIYG6cZ5gdrxx7gASF0/s320/floorSinking.png" width="320" /></a></div>
<div style="text-align: center;">
Ball interacting with the floor. (Y position)</div>
<br />
<div style="text-align: justify;">
As a closing remark, I must say that I have used this method in the <a href="http://embeddedprogrammer.blogspot.com/2012/08/simulation-of-humanoid-robot.html">simulation of a humanoid robot</a> with positive results.</div>
Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com141tag:blogger.com,1999:blog-1622983275835621655.post-41922306553685634522013-01-05T20:20:00.000-05:002013-01-05T20:20:51.822-05:00Simmechanics: Simulating multibody dynamics<div style="text-align: justify;">
In this post I'll cover how to simulate a multibody system (a "robotic arm") using the Simmechanics toolbox in Simulink, which is an extension of Matlab.</div>
<br />
<div style="text-align: justify;">
We'll build a simple "robotic arm" with 3 degree of freedom (DOF). Each DOF will be rotational and will be actuated by a "servomotor", which will be implemented as a closed loop PID position controller.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR0y9MNRvkurTVSSkWtQ_PA0pEDp3lCMntEDz13zo4Wi89EuqmMdLLjVwq32uovd9r_684KGuUVmJVzJfbNi7nl9WAUPToI4MShTT6HdFyDySg2tECWh7QfKGEe2IdCEyCrazcph7IF1Y/s1600/eyeCandy.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="159" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR0y9MNRvkurTVSSkWtQ_PA0pEDp3lCMntEDz13zo4Wi89EuqmMdLLjVwq32uovd9r_684KGuUVmJVzJfbNi7nl9WAUPToI4MShTT6HdFyDySg2tECWh7QfKGEe2IdCEyCrazcph7IF1Y/s320/eyeCandy.png" width="320" /></a></div>
<div style="text-align: center;">
We <i>won't</i> build this one in this tutorial, as it requires too many steps. We'll build something simple to illustrate the method, then you can build this one on your own. </div>
<br />
<div style="text-align: justify;">
I won't give you the final .mdl file, instead I'll give you all the necessary steps, so you can learn by doing.</div>
<br />
OK, let's go hands on!<br />
<br />
<h3>
The environment</h3>
<br />
<div style="text-align: justify;">
First, let's explore the environment. Launch Matlab and then open Simulink, either by using the command <b><i>simulink</i></b> in the command line or by clicking the simulink icon in the toolbar.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimNvALQTMFTzZ9JH4w1tykYaKo1aaAZScSvoEZ5btxhDKwgDEQLGaz6SqR1C1GjanZix4nSzS5mna7HyAUejhC6H1TbmxT5_JVZ34LOgT9PzQnOkCZHBNsJn9QJKNN1xDFM3eC_S1yNe0/s1600/launchSimulink.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="159" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimNvALQTMFTzZ9JH4w1tykYaKo1aaAZScSvoEZ5btxhDKwgDEQLGaz6SqR1C1GjanZix4nSzS5mna7HyAUejhC6H1TbmxT5_JVZ34LOgT9PzQnOkCZHBNsJn9QJKNN1xDFM3eC_S1yNe0/s320/launchSimulink.png" width="320" /></a></div>
<div style="text-align: center;">
Launching Simulink</div>
<br />
<div style="text-align: justify;">
The <i>Simulink Library Browser</i> will open, here you'll find a bunch of building blocks that can be used to assemble Simulink models. We'll be using the first generation or legacy Simmechanics blocks located under the Simscape library. After you find these blocks, create a new model by clicking the <i>blank page</i> icon.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMNj0eMPYXkOLsK7UF_TvSJWprjaTMJjEqt9o5bB-dl7zb8DNaUrfOfoQBNKP9SWRdKRfkab6goY6bTzPglRpQctCTaweFJZaI7Dc1fbVfoq9bNnTLKhoJrdAsPhxv-GazjH5IwOiYcYg/s1600/newModel.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMNj0eMPYXkOLsK7UF_TvSJWprjaTMJjEqt9o5bB-dl7zb8DNaUrfOfoQBNKP9SWRdKRfkab6goY6bTzPglRpQctCTaweFJZaI7Dc1fbVfoq9bNnTLKhoJrdAsPhxv-GazjH5IwOiYcYg/s320/newModel.png" width="320" /></a></div>
<div style="text-align: center;">
Starting a new simulink model</div>
<br />
<div style="text-align: justify;">
A new blank window, name <i>untitled</i>, will appear. This is the simulink model, we can drop blocks here to build models, which can later be simulated. You'll notice there is a <i>play</i> button which is disabled, that button starts the simulation.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjl5Fj7g_KDlDdyE6ncmPHbUxnuLhEdiPTkdwikiozZX36Kk2Ce_wLfZc32xgcjBmRTXBqeuW5NINth4g0EPB2GaQ8xWTK81nCQFIA8FZlDF-uOr9tlKdU1IWAK6eBbbDE6goJajvEXy1c/s1600/blankModel.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="151" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjl5Fj7g_KDlDdyE6ncmPHbUxnuLhEdiPTkdwikiozZX36Kk2Ce_wLfZc32xgcjBmRTXBqeuW5NINth4g0EPB2GaQ8xWTK81nCQFIA8FZlDF-uOr9tlKdU1IWAK6eBbbDE6goJajvEXy1c/s320/blankModel.png" width="320" /></a></div>
<div style="text-align: center;">
A blank Simulink model...</div>
<br />
<div style="text-align: justify;">
Let's start by dropping a Ground block in the model, I'll explain what it does soon enough. You can find the Ground block inside the <b>Bodies</b> category of the Simmechanics blocks. Drag the Ground block and drop it inside the white are of the Simulink model.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyVRmoL-cLg-pJpoo4ICWrUoBqrOLblfDeNpNWJl52I0AiKXXcJc2h5YvO_b4POH5JXoME2wtL_Gq8n1J-eZ2XPZOYDnUK5NTwlNj8xgrU1iYyEWU-SmQqjG7SLr9yevwS6an9BgPuFp4/s1600/gainingGround.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="230" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyVRmoL-cLg-pJpoo4ICWrUoBqrOLblfDeNpNWJl52I0AiKXXcJc2h5YvO_b4POH5JXoME2wtL_Gq8n1J-eZ2XPZOYDnUK5NTwlNj8xgrU1iYyEWU-SmQqjG7SLr9yevwS6an9BgPuFp4/s320/gainingGround.png" width="320" /></a></div>
<div style="text-align: center;">
Gaining ground on Simulink.</div>
<br />
<h3>
The coordinate system</h3>
<br />
<div style="text-align: justify;">
Simulink uses an XYZ <a href="http://en.wikipedia.org/wiki/Cartesian_coordinate_system">Cartesian coordinate system</a> to describe the position of the bodies and <a href="http://en.wikipedia.org/wiki/Euler_angles">Euler angles</a> to describe the orientation of the bodies. Let's take a look at the global <b>coordinate system (CS)</b> by starting a simulation.</div>
<br />
<div style="text-align: justify;">
First, head to the menu > Simulation > Configuration Parameters. On the new window, go under the Simmechanics 1G (or simply Simmechanics) category and enable the animation by checking the "Show animation during simulation" checkbox.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbhWjemSVDsRak1sTST8M7qHES1c1rR2SbLWB6kjUO8FsfVDxT0HQk99IJJrqurLqPXowI6XU7vm9NQsVRlQxt4kUuQzrgBWwzjnJIDpsa4eHfriuuxUVq2pLFqRSouvynNOip3Ysgu5o/s1600/enableAnimation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="238" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbhWjemSVDsRak1sTST8M7qHES1c1rR2SbLWB6kjUO8FsfVDxT0HQk99IJJrqurLqPXowI6XU7vm9NQsVRlQxt4kUuQzrgBWwzjnJIDpsa4eHfriuuxUVq2pLFqRSouvynNOip3Ysgu5o/s320/enableAnimation.png" width="320" /></a></div>
<div style="text-align: center;">
Enabling animation.</div>
<br />
<div style="text-align: justify;">
Click the apply button and close the window. Now hit the play button (Start simulation). In the new window that pops out, select the isometric view as shown in the next image.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxH4uX338pufqncNAoRZzDx8P10vGA6m1a62tkhn-oQr7fO7aO-fzrbd3zT7qCSEMi6tAN2lpr4oGskyKEnwO9yM8lwGu3FMLwKnX9WvYNb1Du47v9HgXv94-jhnAyG-YAfOkMhoIOEuQ/s1600/firstAnimation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxH4uX338pufqncNAoRZzDx8P10vGA6m1a62tkhn-oQr7fO7aO-fzrbd3zT7qCSEMi6tAN2lpr4oGskyKEnwO9yM8lwGu3FMLwKnX9WvYNb1Du47v9HgXv94-jhnAyG-YAfOkMhoIOEuQ/s320/firstAnimation.png" width="320" /></a></div>
<div style="text-align: center;">
The Coordinate System and an empty animation.</div>
<br />
<div style="text-align: justify;">
You just did your first animation, there is nothing in it but the global coordinate system. Now, notice that the Y axis is pointing up, this is also the axis where the gravity acts (in the -Y direction). Some people, me included, tend to draw the Z axis pointing up and use the -Z direction for the gravity. Simulink doesn't follow this Z convention, so be careful.</div>
<br />
<h3>
The multibody paradigm: bodies and joints</h3>
<br />
<div style="text-align: justify;">
As the name implies, multibody systems are composed of various bodies, where a body can be any rigid piece of matter. Two bodies are connected by joints, these joints allow one or more DOF (i.e. relative movement) between the bodies.</div>
<br />
<div style="text-align: justify;">
Most multibody system can be described as "open chains", i.e. as a series of bodies and joints that form a line or a tree, but not a loop. In Simmechanics, these chains must start with the Ground block, the Ground is a body with infinite mass and moment of inertia. Let's explore the Ground block by double-clicking it.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjikP2Xx5L1VEwq3aO0ftv_01wfsguOFPq5LXZT8kOK4qRVNxu7vUVU47ebRfA5HY8vZJq1mrF40Zt_tsQWiaJK0jkYGaeSmsSyTkOMzZth_ADkSr29voEOwXpSzfOTC38wyibUv7NS2Ds/s1600/groundParameters.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="183" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjikP2Xx5L1VEwq3aO0ftv_01wfsguOFPq5LXZT8kOK4qRVNxu7vUVU47ebRfA5HY8vZJq1mrF40Zt_tsQWiaJK0jkYGaeSmsSyTkOMzZth_ADkSr29voEOwXpSzfOTC38wyibUv7NS2Ds/s320/groundParameters.png" width="320" /></a></div>
<div style="text-align: center;">
Ground block parameters</div>
<br />
<div style="text-align: justify;">
The Ground block is located at some [x, y, z] global position. This point is where other bodies will make a joint to the Ground. Leave the default [0, 0, 0] position.</div>
<br />
<h3>
The simplest example: A pendulum</h3>
<br />
<div style="text-align: justify;">
To better understand the joint and body system, let's start by building a simple pendulum system. Add a <b><i>revolute</i></b> block, located under the <i>Joints</i> category, and a <b><i>body</i></b> block, located under the <i>Bodies</i> category, to the Simulink model. Then, link these block by click dragging a line from one block to another, the final diagram should look like the following image.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxnGPTPep42glUXNl0pYoXd9X0rpIchXs_io9hEXr7Bz_fG5qfwnpVqYmspKcw6ao44OdBKT2S4NjxS3hAIFVnpgBZiSBiH4ptQ8kn38JS6J2NZim6IsQpeF-8m2vMnXe6jbxVrT37-Do/s1600/pendulumDiagram.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="148" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxnGPTPep42glUXNl0pYoXd9X0rpIchXs_io9hEXr7Bz_fG5qfwnpVqYmspKcw6ao44OdBKT2S4NjxS3hAIFVnpgBZiSBiH4ptQ8kn38JS6J2NZim6IsQpeF-8m2vMnXe6jbxVrT37-Do/s320/pendulumDiagram.png" width="320" /></a></div>
<div style="text-align: center;">
Pendulum diagram.</div>
<br />
<div style="text-align: justify;">
Let's add parameters to the Body block. The Body will be a 1 meter zero-thickness bar with a mass of 1 Kg. Double click the Body block and modify the parameters to match the following image.</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgolcu7PXZ8DeZn1NjyAbQxByNKJMrGFDjbrc9JJgcqVQajbAKNvlXL1yrH-5080cyHqQAkfc7ZBOUtDIJFi_fFklgKtAZkzZd-7hCTFGBCjNtNWfxxuUX374r_9IBGp1-fCENAr2tMCyQ/s1600/barParameters.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="247" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgolcu7PXZ8DeZn1NjyAbQxByNKJMrGFDjbrc9JJgcqVQajbAKNvlXL1yrH-5080cyHqQAkfc7ZBOUtDIJFi_fFklgKtAZkzZd-7hCTFGBCjNtNWfxxuUX374r_9IBGp1-fCENAr2tMCyQ/s320/barParameters.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Bar parameters.</div>
<br />
<div style="text-align: justify;">
Click apply and close this window. Now change the simulation time to 2 (seconds) and hit the play button. On the new window, click the "Enable automatic expanding fit" button to take a better view at the pendulum movement.</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzpzskVaWkHkAgVkE2KVZpy7X8zs1VobVqfTc9TVi5_JkgX2TCmZBlgeJoGZEDzRlecMyXMnbjWVgkRx7cNsVE33cfgS7SRHmOMIoFmMdN1q7CgojDRxiIY-F8vowdrdwqf_FI86i8zPI/s1600/pendulumAnimation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="159" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzpzskVaWkHkAgVkE2KVZpy7X8zs1VobVqfTc9TVi5_JkgX2TCmZBlgeJoGZEDzRlecMyXMnbjWVgkRx7cNsVE33cfgS7SRHmOMIoFmMdN1q7CgojDRxiIY-F8vowdrdwqf_FI86i8zPI/s320/pendulumAnimation.png" width="320" /></a></div>
<div style="text-align: center;">
Simulating a pendulum.</div>
<br />
<h3>
Analyzing the pendulum</h3>
<br />
Now that we have a visual, I'll proceed to explain how the Coordinate Systems (CS) works.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhatThzbxK0LIUgV1BBaYpSIJ8haLgPvEyoPTZuNgPUpz5ArUu4-J1BucktN3NxoV_BhuWT46rdfhTLiwt6vhxIoPsakdvqda5VfNo7wObwcZk4bWRUQdcH7M1Q-ljbuMPX868pg-Sii2U/s1600/pendulumAnalysis.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhatThzbxK0LIUgV1BBaYpSIJ8haLgPvEyoPTZuNgPUpz5ArUu4-J1BucktN3NxoV_BhuWT46rdfhTLiwt6vhxIoPsakdvqda5VfNo7wObwcZk4bWRUQdcH7M1Q-ljbuMPX868pg-Sii2U/s320/pendulumAnalysis.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
The pendulum CSs.</div>
<br />
<div style="text-align: justify;">
Let's look at the big picture, we have the Ground, which is our reference point for this <a href="http://en.wikipedia.org/wiki/Kinematic_chain">kinematic chain</a> and is located at [0, 0, 0]. Next we have a Body (the bar) with two CSs (Coordinate Systems), each CS is attached to one particular point of the body as you can see.</div>
<br />
<div style="text-align: justify;">
The Ground and the Body are connected by a Revolute block, which is a joint. A joint is a relationship between two CS, one CS for each intervening body. The joint add restrictions between these two CS, because in 3D space an unrestricted CS has <a href="http://en.wikipedia.org/wiki/Six_degrees_of_freedom">6 DoF</a> with respect to another CS. In our example the Revolute joint only allows 1 rotational DoF in the Z axis direction ([0, 0, 1]). This means that CS1 can't translate with respect to the Ground, i.e. it will remain at the global position [0, 0, 0], and can only rotate around the global Z axis.</div>
<br />
<div style="text-align: justify;">
Let's now analyze the Body parameters. We have three Coordinate Systems: CS1, CS2 and CG. The CG is the center of gravity and the other two CS are for reference/positioning. To specify the position of any CS we need:</div>
<ul>
<li>A first CS, which I'll call the rCS: reference Coordinate System</li>
<li>A second CS, which I'll call the oCS: orientation Coordinate System</li>
<li>A [x, y, z] distance vector.</li>
</ul>
<div>
<div style="text-align: justify;">
The position of the CS will be at a distance [x, y, z] starting from the rCS and moving along the XYZ axes of the oCS.</div>
</div>
<div>
<br /></div>
<div>
<div style="text-align: justify;">
These 3 parameter allow great flexibility but also can add some confusion. To simplify your life and mine, we'll stick to the following convention:</div>
</div>
<div>
<ul>
<li style="text-align: justify;">We'll use the World CS as the oCS.</li>
<li style="text-align: justify;">We'll use CS1 as the rCS for every CS, except for CS1. For CS1 we'll use Adjoining** as the rCS.</li>
<li style="text-align: justify;">We'll also refrain from rotating bodies, i.e. we won't use the orientation tab of the body parameters.</li>
</ul>
</div>
<div>
<div style="text-align: justify;">
** Adjoining can only be used at a CS that is part of a joint, and it does reference to the other CS that is part of the joint.</div>
</div>
<br />
<div style="text-align: justify;">
The final parameter is the <a href="http://en.wikipedia.org/wiki/Moment_of_inertia">moment of inertia</a>, which is expressed as a <a href="http://en.wikipedia.org/wiki/Moment_of_inertia#Moment_of_inertia_tensor">tensor</a>. The moment inertia must be taken at the CG and is expressed along the XYZ axes of the CG. For this example I assumed a zero thickness bar, you can find the most common moment of inertia at <a href="http://en.wikipedia.org/wiki/List_of_moments_of_inertia">wikipedia</a>.</div>
<br />
<h3>
The robotic arm</h3>
<br />
<div style="text-align: justify;">
The previous section, understanding the position and orientation system, was the hardest of this tutorial. Now we can add the two missing members of our "robotic arm". In fact, I'm gonna let you do that as a homework, but I'll provide some hints.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8NK4aAlJAw51yh9rgHMd6fmz1BcjnQjl1i-_9_nC8PWalYrtrJOmewA_pfSOiaVsXWF345rxD9lCeQ0nWyiyHZUQrxez1uTDoG4duMH_-0RNm2xIdz6lanBBZesTXYCuVzx7lrA9o4YM/s1600/xyzRobot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="218" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8NK4aAlJAw51yh9rgHMd6fmz1BcjnQjl1i-_9_nC8PWalYrtrJOmewA_pfSOiaVsXWF345rxD9lCeQ0nWyiyHZUQrxez1uTDoG4duMH_-0RNm2xIdz6lanBBZesTXYCuVzx7lrA9o4YM/s320/xyzRobot.png" width="320" /></a></div>
<div style="text-align: center;">
XYZ Robot Diagram.</div>
<br />
<div style="text-align: justify;">
The "Robotic Arm" is composed of 3 zero-thickness bars, each one measure 1 m and weights 1 Kg. Each bar initial position is oriented along the X, Y an Z axes respectively. The joints of the robot are all Revolute and allow rotation in the Z, X and Y axes as the figure above shows.</div>
<br />
Below there is an animation that shows the initial position of the robot.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGxWEyBEIRmM1eO7WXrbFjtYy7fB94J7Tw8CSzyqLuE8MptAEpYAx8tf2pmiSfLvdi3QnB_lJyBkEIQutoHFA2r2IuhF08xmCToUcd9jVllL91XyebDQbFdzN1kx2Ox9yjib2GuhTf6ho/s1600/xyzAnimation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGxWEyBEIRmM1eO7WXrbFjtYy7fB94J7Tw8CSzyqLuE8MptAEpYAx8tf2pmiSfLvdi3QnB_lJyBkEIQutoHFA2r2IuhF08xmCToUcd9jVllL91XyebDQbFdzN1kx2Ox9yjib2GuhTf6ho/s320/xyzAnimation.png" width="303" /></a></div>
<div style="text-align: center;">
XYZ Robot Initial Position</div>
<br />
<div style="text-align: justify;">
You can change the color of the bodies in the Visualization tab inside the Block Parameters of each body.</div>
<br />
<h3>
Collapse under gravity</h3>
<br />
<div style="text-align: justify;">
After you've finished configuring your blocks, proceed to simulate the system. You'll see the robot collapses under gravity.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8YLY05I-jgyazxycYqGb-PQoZecMWLx5P3usSjhCNkDvY4dfrwUUZsZjH5h4NPJQrNmhaEbQAalvKM_MfldSmd-JPhTxrkUhKy9Ziq45JxchwBR6uGOQkdY6m02ysdTS-RR57Xng4SHQ/s1600/xyzGravity.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8YLY05I-jgyazxycYqGb-PQoZecMWLx5P3usSjhCNkDvY4dfrwUUZsZjH5h4NPJQrNmhaEbQAalvKM_MfldSmd-JPhTxrkUhKy9Ziq45JxchwBR6uGOQkdY6m02ysdTS-RR57Xng4SHQ/s320/xyzGravity.png" width="320" /></a></div>
<div style="text-align: center;">
XYZ Robot collapsing under gravity.</div>
<br />
<div style="text-align: justify;">
To solve this problem, we'll use some basic control theory. The basic blocks of a control system are: sensors, actuators and controllers.</div>
<br />
<h3>
Adding sensors and actuators</h3>
<br />
<div style="text-align: justify;">
Simmechanics provides an easy way to add sensors and actuators to the system. Start by double clicking any of the joint blocks of the robot.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg81xsV8lskV6DMN-ijhXd87OZ6tewyBrfzEpFB_B6yDQtcecBM_qadJ3I_vbM5Hqqbl5G6ziRD03ZVf-tqmvuBUgwi-UpblFbvyI0J7zY8VyyXJjOI_1e0qLjL36556BIa74THNxpt_Gg/s1600/sensorActuatorPorts.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="311" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg81xsV8lskV6DMN-ijhXd87OZ6tewyBrfzEpFB_B6yDQtcecBM_qadJ3I_vbM5Hqqbl5G6ziRD03ZVf-tqmvuBUgwi-UpblFbvyI0J7zY8VyyXJjOI_1e0qLjL36556BIa74THNxpt_Gg/s320/sensorActuatorPorts.png" width="320" /></a></div>
<div style="text-align: center;">
Enabling sensor / actuator ports.</div>
<br />
<div style="text-align: justify;">
Enable 2 sensor / actuator ports on each joint. Next, hook a Joint Sensor and a Joint Actuator, you can find both blocks under the Sensors and Actuators category, to each joint. Finally, connect the output of each sensor to a Scope block, you can find it under Simulink > Sinks Category.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqj9IkW8RYYcPrM7IhpgpzEXKeq_0okdWZORrujdjBX0SiCI6XpeOl0KxvXCwSlQ1OoNQSKcSqUb22p4503J7m-31mgh-ePWxOtAaUuUkcyC1Y4JXvR7HOkDq6Y69XQGbbIuOP5jwqGs4/s1600/sensorDiagram.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="163" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqj9IkW8RYYcPrM7IhpgpzEXKeq_0okdWZORrujdjBX0SiCI6XpeOl0KxvXCwSlQ1OoNQSKcSqUb22p4503J7m-31mgh-ePWxOtAaUuUkcyC1Y4JXvR7HOkDq6Y69XQGbbIuOP5jwqGs4/s320/sensorDiagram.png" width="320" /></a></div>
<div style="text-align: center;">
XYZ Robot with sensors.</div>
<br />
<div style="text-align: justify;">
Simulate the system, and take a look at each Scope, you'll see how much each body rotates with respect to its base (or predecessor body). Take a close look at the animation and the scopes and relate the sign of each signal with the rotational axis to which is associated.</div>
<br />
<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjh1I6Nyd4o8ILP-h9IMuhfftAgTuEbGhXOf2GC-KalRD4XZQH2yBVzrbMNy2PvTCRjt5e8Ax_oV5BaSKK_58qMpCSFb-vueqHZSs9n6WExynTqjVNnIuEuo3OhP6Y0qyzgSC5TQHnDo94/s1600/gravityZ.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="105" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjh1I6Nyd4o8ILP-h9IMuhfftAgTuEbGhXOf2GC-KalRD4XZQH2yBVzrbMNy2PvTCRjt5e8Ax_oV5BaSKK_58qMpCSFb-vueqHZSs9n6WExynTqjVNnIuEuo3OhP6Y0qyzgSC5TQHnDo94/s200/gravityZ.png" width="150" /></a></div>
</td><td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgctKWDR_LJUWF4gjmRfGvYxnDn62A3YB6-tyQrYIQoHiObqBRtjI4ZubYoFPNaVAj6E_s8pNjVAz__mqIqzeD8ZQSQNCIuUiCeTYrejbrVYtqEMJXgVIF7zZjWh2xnX4aXvT3l6n8-g2Q/s1600/gravityX.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="105" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgctKWDR_LJUWF4gjmRfGvYxnDn62A3YB6-tyQrYIQoHiObqBRtjI4ZubYoFPNaVAj6E_s8pNjVAz__mqIqzeD8ZQSQNCIuUiCeTYrejbrVYtqEMJXgVIF7zZjWh2xnX4aXvT3l6n8-g2Q/s200/gravityX.png" width="150" /></a></div>
</td>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUh68HSeK0Ovh1n5VR2O3Xb1FXiFjiq82TuO1vdrWa9qXMXoiHIS8TuVOqd7adVyxGAzBnAAnX3izCR20AAc48DhyVpSjfT6DX_dfPNFZO-NV2RHOPYh18Ex272nAxLl40DeczjwdVgyw/s1600/gravityY.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="105" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUh68HSeK0Ovh1n5VR2O3Xb1FXiFjiq82TuO1vdrWa9qXMXoiHIS8TuVOqd7adVyxGAzBnAAnX3izCR20AAc48DhyVpSjfT6DX_dfPNFZO-NV2RHOPYh18Ex272nAxLl40DeczjwdVgyw/s200/gravityY.png" width="150" /></a></div>
</td>
</tr>
<tr>
<td><div style="text-align: center;">
Z Joint</div>
</td>
<td><div style="text-align: center;">
X Joint</div>
</td>
<td><div style="text-align: center;">
Y Joint</div>
</td></tr>
</tbody></table>
<br />
<h3>
Closing the loop</h3>
<br />
<div style="text-align: justify;">
We already plugged both the sensors and the actuators, the only part missing is the controller. We'll add to controller to maintain the initial position of the XYZ Robots, so it doesn't collapses under gravity.</div>
<br />
<div style="text-align: justify;">
We'll need the following blocks: The PID Controller block, found under the Simulink > Continuous; the Sum block, found under Simulink > Math operations; and the Constant block, found under Simulink > Sources. You'll need to modify the Sum block parameters, so the List of Signs is: "|+-".</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYb_1_aR2eFUIwy3mudSZpFVa7dV3fV1ch9T0iCmW9TVk5wwf-H2c8r2KN_a1pEsFgqXL4tkvvl89q2JxzddOtOcyg57ZaP9gSbS7FY5dckHaUnq9suar0XIbf8IyqzE_e88JQy9c76PQ/s1600/sumParameters.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYb_1_aR2eFUIwy3mudSZpFVa7dV3fV1ch9T0iCmW9TVk5wwf-H2c8r2KN_a1pEsFgqXL4tkvvl89q2JxzddOtOcyg57ZaP9gSbS7FY5dckHaUnq9suar0XIbf8IyqzE_e88JQy9c76PQ/s320/sumParameters.png" width="298" /></a></div>
<div style="text-align: center;">
Configuring the Sum block for subtraction.</div>
<br />
Next, you'll need to wire the new blocks as shown in the next figure.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9ZA-1DU-o2GgPXdJvJdPPYq8xg_9deM7almZB4sdRqHZTtQAIljLfDbLGKAqBoQIXvttkNlicZ8xWX5S2vguLfhx29qA4mWiMSv3dfv-6ANwrtww15MghdWKDbvAkZM5CaHUOOR9RErg/s1600/xyzControlDiagram.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9ZA-1DU-o2GgPXdJvJdPPYq8xg_9deM7almZB4sdRqHZTtQAIljLfDbLGKAqBoQIXvttkNlicZ8xWX5S2vguLfhx29qA4mWiMSv3dfv-6ANwrtww15MghdWKDbvAkZM5CaHUOOR9RErg/s320/xyzControlDiagram.png" width="320" /></a></div>
<div style="text-align: center;">
XYZ Robot with PID blocks.</div>
<br />
<div style="text-align: justify;">
The final step is tuning the gains of each PID block. After some trial and error, I ended with the following gains:</div>
<br />
<table align="center">
<tbody>
<tr>
<td style="text-align: center;"></td>
<td><div style="text-align: center;">
P</div>
</td>
<td><div style="text-align: center;">
I</div>
</td>
<td><div style="text-align: center;">
D</div>
</td>
<td><div style="text-align: center;">
N</div>
</td>
</tr>
<tr>
<td><div style="text-align: center;">
Z Joint</div>
</td>
<td><div style="text-align: center;">
185</div>
</td>
<td><div style="text-align: center;">
282</div>
</td>
<td><div style="text-align: center;">
14</div>
</td>
<td><div style="text-align: center;">
239</div>
</td>
</tr>
<tr>
<td><div style="text-align: center;">
X Joint</div>
</td>
<td><div style="text-align: center;">
121</div>
</td>
<td><div style="text-align: center;">
197</div>
</td>
<td><div style="text-align: center;">
6</div>
</td>
<td><div style="text-align: center;">
435</div>
</td>
</tr>
<tr>
<td><div style="text-align: center;">
Y Joint</div>
</td>
<td><div style="text-align: center;">
17</div>
</td>
<td><div style="text-align: center;">
27</div>
</td>
<td><div style="text-align: center;">
1</div>
</td>
<td><div style="text-align: center;">
423</div>
</td>
</tr>
</tbody></table>
<br />
All that's left is to check the correctness of the controller by simulating the system.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtAK3yyOw_djxWLjyiOUwLKRlEzby2-aAQUDND4_yQYssm0VF_WqxjRvP5MU40qf-T82T9Br5xGjsAG6ZRcYIBQyk49fZihPirzHXAUGgA4w9VtCQd5bmjwnzLLIuJhFm3BhvBO7YftCs/s1600/xyzPID.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtAK3yyOw_djxWLjyiOUwLKRlEzby2-aAQUDND4_yQYssm0VF_WqxjRvP5MU40qf-T82T9Br5xGjsAG6ZRcYIBQyk49fZihPirzHXAUGgA4w9VtCQd5bmjwnzLLIuJhFm3BhvBO7YftCs/s320/xyzPID.png" width="320" /></a></div>
<div style="text-align: center;">
XYZ Robot fighting gravity with its PID controllers.</div>
<br />
<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiou-JBL_MV52bA7iT1w6gy2BKbppNCoj6LI0pdpOqMhojMbMQTPDjQGfzNcHz-gT7beWuruIX_Kx9HXep722mOIg2PSW7iUgbOWQThNtqFb-PUNqTyFV2ibXqWFCl8VzXWpkd3HUka8j8/s1600/pidZ.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="105" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiou-JBL_MV52bA7iT1w6gy2BKbppNCoj6LI0pdpOqMhojMbMQTPDjQGfzNcHz-gT7beWuruIX_Kx9HXep722mOIg2PSW7iUgbOWQThNtqFb-PUNqTyFV2ibXqWFCl8VzXWpkd3HUka8j8/s200/pidZ.png" width="150" /></a></div>
</td>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlV1n6RmKn7qkduMayaOtVwnwnBS8kx071bvFdVV66mloU-sbREUDB50sKaSPWJCk48TcBOvYglfTYrUBYUj_hJRyKFoGEeDKWi1z7DPynjlKpN2_gBVOyi-v3w872UtKcRKduKOqjtzY/s1600/pidX.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="105" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlV1n6RmKn7qkduMayaOtVwnwnBS8kx071bvFdVV66mloU-sbREUDB50sKaSPWJCk48TcBOvYglfTYrUBYUj_hJRyKFoGEeDKWi1z7DPynjlKpN2_gBVOyi-v3w872UtKcRKduKOqjtzY/s200/pidX.png" width="150" /></a></div>
</td><td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_NF7zJogXw1WYV4PQxHXsuMNp6kX81nx8p9wY4xPMvKmp41YGiOLZ0pV9fPBaDJXLaXe71Tk3D9329dBjgL_kGFgfJRbopC931G4BSqh_VDZKLGq_Kk-rbus663eUWfFHOpQeZAaNfFI/s1600/pidY.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="105" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_NF7zJogXw1WYV4PQxHXsuMNp6kX81nx8p9wY4xPMvKmp41YGiOLZ0pV9fPBaDJXLaXe71Tk3D9329dBjgL_kGFgfJRbopC931G4BSqh_VDZKLGq_Kk-rbus663eUWfFHOpQeZAaNfFI/s200/pidY.png" width="150" /></a></div>
</td>
</tr>
<tr>
<td><div style="text-align: center;">
Z Joint</div>
</td>
<td><div style="text-align: center;">
X Joint</div>
</td>
<td><div style="text-align: center;">
Y Joint</div>
</td>
</tr>
</tbody></table>
<br />
<h3>
What's next? (Homework for you)</h3>
<br />
<div style="text-align: justify;">
I hope this simple and unrealistic example had accomplished its mission of teaching you the fundamentals of the Simmechanic toolbox.</div>
<br />
If you want to keep playing, you can immediately do the following:<br />
<ul>
<li style="text-align: justify;">Change the reference signals X, Y and Z from a constant 0 to some time varying signal, like a step or a sine wave. You'll notice soon enough the controller will start misbehaving because of the high non-linearity of the system.</li>
<li style="text-align: justify;">Remove the gravity and see how that affects the performance of the controller when tracking a time varying reference. You'll need to insert a Machine Environment block and enable the Machine Environment port of the Ground block.</li>
</ul>
<div>
With some hard work you can do the following:</div>
<div>
<ul>
<li style="text-align: justify;">Implement a better model for the actuators (motors), by adding limits to the torque and speed, and also adding moment of inertia and friction to the joints.</li>
<li style="text-align: justify;">Build a more realistic robot/system. Here, CAD software like Solidworks help a lot, because you can extract real information like distances, masses and moments of inertia. For example you can find the CAD files of the robot I've shown at the beginning of this post <a href="http://www.adept.com/products/robots/6-axis/viper-s650/downloads">here</a>. You can add more realistic rendering to your model using .STL files.</li>
<li style="text-align: justify;">Implement a more robust controller using techniques like computed torque or fuzzy logic.</li>
<li style="text-align: justify;">Study about forward (see <a href="http://en.wikipedia.org/wiki/Denavit%E2%80%93Hartenberg_parameters">Denavit-Hartenberg</a>) and inverse (see <a href="http://math.ucsd.edu/~sbuss/ResearchWeb/ikmethods/iksurvey.pdf">iterative methods</a>) kinematics and implement some trajectory tracking routines for your robot.</li>
</ul>
</div>
<br />
Once you've done that, you'll be closer to <a href="http://embeddedprogrammer.blogspot.com/2012/08/simulation-of-humanoid-robot.html">simulating a humanoid robot</a>.Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com10tag:blogger.com,1999:blog-1622983275835621655.post-26118499424048084112013-01-03T17:01:00.000-05:002013-01-05T23:26:21.886-05:00Beaglebone: Using an USB WiFi dongle to connect to wireless networks at boot.<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYGcJsFc0EMykTeR6FPMsiWkURTfZSmlnTU-D5Dox8_Q50pEKznpgEjs_TRaOWD10kndCtdG78xRFy1M5lmkaUvtTUsGCu_FRzBkyC-8gUidTCwswJ4J11Q_ukIeaoQpjVT_quJWZFO20/s1600/wifiBone.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="183" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYGcJsFc0EMykTeR6FPMsiWkURTfZSmlnTU-D5Dox8_Q50pEKznpgEjs_TRaOWD10kndCtdG78xRFy1M5lmkaUvtTUsGCu_FRzBkyC-8gUidTCwswJ4J11Q_ukIeaoQpjVT_quJWZFO20/s320/wifiBone.JPG" width="320" /></a></div>
I'll cover how I configured my BeagleBone so it now (automagically) connects to wireless networks at boot.<br />
<br />
Note: I assume you are <a href="http://embeddedprogrammer.blogspot.com/2012/10/beaglebone-installing-ubuntu-1210.html">running Ubuntu 12.10 in your Beaglebone</a>.<br />
<br />
<h3>
Manual connection</h3>
<br />
First, let's check whether the Beaglebone can use the WiFi dongle by setting up a manual connection.<br />
<br />
Before starting the test, let's install some software with the ethernet cable plugged in:<br />
<div class="terminal">
#On the beaglebone<br />
sudo apt-get install lshw<br />
sudo apt-get install wpasupplicant</div>
Now unplug the Ethernet cable from the Beaglebone. And start a connection using the USB emulated Serial connection.
<br />
<div class="terminal">
# On the PC<br />
screen /dev/<ttyUSBx> 115200</div>
Now let's check if the Beaglebone has recognized the WiFi dongle.<br />
<div class="terminal">
# On the beaglebone<br />
lshw -C network</div>
I got this:<br />
<div class="terminal">
*-network:1 DISABLED<br />
description: Wireless interface<br />
physical id: 2<br />
bus info: usb@1:1<br />
logical name: wlan0<br />
serial: d8:eb:97:12:e4:c0<br />
capabilities: ethernet physical wireless<br />
configuration: broadcast=yes driver=rtl8192cu driverversion=3.2.33-psp26 firmware=N/A multicast=yes wireless=IEEE 802.11bgn</div>
If you see something similar, it means your device has been detected by the Linux kernel and an appropriate driver has been loaded.<br />
<br />
Remember the logical name, in this case is wlan0.<br />
<br />
Now, turn on the WiFi dongle. (Use the logical name obtained from the last command)<br />
<div class="terminal">
# On the beaglebone<br />
sudo ifconfig wlan0 up</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3wjrjAfrxZ1-4-7k1Au4VvA0lKpDQh8mzf2v3kCWOBkn-l2O48TZLpKJKtdWc-gNQeFPjX9R_OVT_j3raGcPZgmhBVHpolSAUho8ppPRX6Q8HoYC8JWRpR-3rMnQsEzmvDMzRg1pSl80/s1600/wifiOn.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="202" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3wjrjAfrxZ1-4-7k1Au4VvA0lKpDQh8mzf2v3kCWOBkn-l2O48TZLpKJKtdWc-gNQeFPjX9R_OVT_j3raGcPZgmhBVHpolSAUho8ppPRX6Q8HoYC8JWRpR-3rMnQsEzmvDMzRg1pSl80/s320/wifiOn.JPG" width="320" /></a></div>
<div style="text-align: center;">
Blue LED indicates that the WiFi dongle has been turned ON.</div>
<br />
Scan for visible WiFi networks.<br />
<div class="terminal">
# On the beaglebone<br />
sudo iwlist wlan0 scanning</div>
You should see your network in the list:<br />
<div class="terminal">
wlan0 Scan completed :<br />
Cell 01 - Address: 00:13:49:CA:F5:10<br />
Channel:4<br />
Frequency:2.427 GHz (Channel 4)<br />
Quality=56/70 Signal level=-54 dBm <br />
Encryption key:on<br />
ESSID:"your-ssid"<br />
...</div>
Now, let's connect to your network.<br />
<div class="terminal">
# On the beaglebone<br />
sudo nano /etc/network/interfaces</div>
Append or modify the file to include the following text (I'm assuming your network it's WEP protected):<br />
<div class="terminal">
auto wlan0<br />
iface wlan0 inet dhcp<br />
wireless-essid <ssid><br />
wireless-key s:<ascii key></div>
Next, start the connection<br />
<div class="terminal">
# On the beaglebone<br />
sudo ifup wlan0</div>
And finally, test the connection<br />
<div class="terminal">
# On the beaglebone<br />
ping www.google.com</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUS2m4oQdGNhq0eAvIcscBqXLh04Z1T6hxG3KNtK_F-BU3dpc60UBEO2sUxSBxuPfNEoepVnZFTLDuaKA6UbXq5OMgUaz8Aw0Glf6fBmc_EqvTRe9TzK6PAXe1rsjzbe4Gxq-2TTd0gUg/s1600/manualConnection.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUS2m4oQdGNhq0eAvIcscBqXLh04Z1T6hxG3KNtK_F-BU3dpc60UBEO2sUxSBxuPfNEoepVnZFTLDuaKA6UbXq5OMgUaz8Aw0Glf6fBmc_EqvTRe9TzK6PAXe1rsjzbe4Gxq-2TTd0gUg/s320/manualConnection.png" width="320" /></a></div>
<div style="text-align: center;">
Congratulations, you have connected to a wireless network.</div>
<br />
<h3>
Going automatic</h3>
<br />
We'll use wpa_supplicant to automate the connections to wireless networks.<br />
<br />
wpa_supplicant is a daemon that manages unsecure, WEP and WPA wireless connections.<br />
<br />
wpa_supplicant stores the information about the wireless networks that it can connect to in a .conf file, usually named wpa_supplicant.conf.<br />
<br />
You can create/edit it, using:<br />
<div class="terminal">
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf</div>
This is how it should look like:
<br />
<div class="terminal">
ctrl_interface=/var/run/wpa_supplicant<br />
<br />
# Unsecure Network<br />
network={<br />
ssid="<ssid>"<br />
key_mgmt=NONE<br />
priority=<unsecure_priority><br />
}<br />
<br />
# WEP Network<br />
network={<br />
ssid="<ssid>"<br />
key_mgmt=NONE<br />
wep_key0="<key>"<br />
priority=<wep_priority><br />
}<br />
<br />
# WPA Network<br />
network={<br />
ssid="<ssid>"<br />
psk="<passphrase>"<br />
priority=<wpa_priority><br />
}</div>
<br />
For more examples about the .conf file, check this <a href="http://hostap.epitest.fi/gitweb/gitweb.cgi?p=hostap.git;a=blob_plain;f=wpa_supplicant/wpa_supplicant.conf">website</a>.<br />
<br />
Let's reconfigure the network interface to add support for wpa_supplicant.<br />
<div class="terminal">
sudo nano /etc/network/interfaces</div>
Change the wlan0 part to match the following text:<br />
<div class="terminal">
auto wlan0<br />
iface wlan0 inet dhcp<br />
wpa-driver wext<br />
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf</div>
Finally reboot the BeagleBone to see the changes.<br />
<div class="terminal">
sudo reboot</div>
Done!Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com19tag:blogger.com,1999:blog-1622983275835621655.post-62599611062725418742012-10-22T23:13:00.000-05:002013-03-18T21:44:57.127-05:00Beaglebone: Installing Ubuntu 12.10I've got my hands on a <a href="http://beagleboard.org/bone">Beaglebone</a>, and the first thing I did was installing the latest Ubuntu 12.10 on it. Here how I proceeded.<br />
<br />
This post is mainly for self-documenting, feel free to follow my footsteps at your own risk. These steps will probably also work on the Beagleboard.<br />
<br />
<h3>
Back up the original image</h3>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The Beaglebone comes with the Linux Ångström distribution. So I backed up the original image, in case something failed. Even if I were to stick with the Ångström distro, it's a good idea to back up the original image.</div>
<br />
<div style="text-align: justify;">
I removed the microSD that shipped with the Beaglebone, and inserted it into my PC SD slot. Then I checked in which partition it got mounted, using the following command.</div>
<div class="terminal">
df -l</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjfIwnnQMBzOsEVX9TT32tgEIyqL1__UXXbS1tW9O4t5lsj4G0Kb6PeGG0BRiJDWltTXSUmb6AePO6sg43fNcdXp2ufJAoYPA9wDA77mHZ3uH70vIgyxeTZarO6Tbsho0Qcqix8wwDdeI/s1600/whereIsTheSD.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="129" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjfIwnnQMBzOsEVX9TT32tgEIyqL1__UXXbS1tW9O4t5lsj4G0Kb6PeGG0BRiJDWltTXSUmb6AePO6sg43fNcdXp2ufJAoYPA9wDA77mHZ3uH70vIgyxeTZarO6Tbsho0Qcqix8wwDdeI/s320/whereIsTheSD.png" width="320" /></a></div>
<div style="text-align: center;">
/dev/sda is my PC harddrive, and /dev/sdb is the Beaglebone SD card.</div>
<br />
<div style="text-align: justify;">
After identifying where the SD was mounted, I used the following command to backup the SD.</div>
<div class="terminal">
dd if=/dev/<sdx> | gzip > /path/to/image.gz</div>
<div style="text-align: justify;">
In case I needed to restore the image, I'll have to use the following command:</div>
<div class="terminal">
gzip -dc /path/to/image.gz | dd of=/dev/<sdx></div>
<br />
<h3>
Installing Ubuntu</h3>
<br />
I followed the <a href="http://elinux.org/BeagleBoardUbuntu">instructions from elinux</a>. These are the summarized steps:<br />
<ul>
<li>Download the minimal Ubuntu 12.10 image</li>
</ul>
<div class="terminal">
cd ~/Desktop<br />
wget http://rcn-ee.net/deb/rootfs/quantal/ubuntu-12.10-r2-minimal-armhf-2012-11-29.tar.xz</div>
<ul>
<li>Verify the integrity of the image</li>
</ul>
<div class="terminal">
md5sum ubuntu-12.10-r2-minimal-armhf-2012-11-29.tar.xz</div>
Which should match the following output<br />
<div class="terminal">
b0ee1964a3f8196f4f1a501d1d2ac83a ubuntu-12.10-r2-minimal-armhf-2012-11-29.tar.xz</div>
<ul>
<li>Untar the package</li>
</ul>
<div class="terminal">
tar xJf ubuntu-12.10-r2-minimal-armhf-2012-11-29.tar.xz<br />
cd ubuntu-12.10-r2-minimal-armhf-2012-11-29</div>
<ul>
<li>Flash the image into your SD</li>
</ul>
<div class="terminal">
sudo ./setup_sdcard.sh --mmc /dev/<sdx> --uboot bone</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkfMl5GPhW-QabYx7j7UnD48G18RB2UBZP32uK9YNTJeooJIhl8WOAJf6CBPwrEY9jpV1O5NYtvab5kCyadf0yrFv-V_X-_qUIVSueKJoEB2sKmICeDBfiaVxe42kjYm1bSt2ERV6TNEc/s1600/flashingTheSD.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="167" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkfMl5GPhW-QabYx7j7UnD48G18RB2UBZP32uK9YNTJeooJIhl8WOAJf6CBPwrEY9jpV1O5NYtvab5kCyadf0yrFv-V_X-_qUIVSueKJoEB2sKmICeDBfiaVxe42kjYm1bSt2ERV6TNEc/s320/flashingTheSD.jpg" width="320" /></a></div>
<div style="text-align: center;">
Finished flashing the Ubuntu image into the SD card.</div>
<br />
For the record (Older releases):<br />
<br />
Release 1: http://rcn-ee.net/deb/rootfs/quantal/ubuntu-12.10-r1-minimal-armhf-2012-10-19.tar.xz<br />
MD5: 31be6761a37af98906c5c1e892601e85
<br />
<br />
<h3>
Connecting to your Beaglebone</h3>
<br />
<div style="text-align: justify;">
After flashing the Ubuntu image, I removed the SD from my PC and plugged it back into the Beaglebone. I decided to make the first connection using the tty over USB.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
After connecting the Beaglebone to my PC using a USB cable, I had to figure out the exact name of the ttyUSBx with the following command.</div>
<div class="terminal">
dmesg | grep ttyUSB</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_By4oZjGuujilPvwp_7Jj2aKSizkIvRES5xQjDAp4e4A7TzTd8kCwpdUubMJNM9mthmKAcBUb9DfsDyqnYxC3lrgDThg_s6DuyO6B104RIjb8kxYTo_iGuuoworBLiCDLBT2yGjXFlJc/s1600/ttyUSB.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="30" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_By4oZjGuujilPvwp_7Jj2aKSizkIvRES5xQjDAp4e4A7TzTd8kCwpdUubMJNM9mthmKAcBUb9DfsDyqnYxC3lrgDThg_s6DuyO6B104RIjb8kxYTo_iGuuoworBLiCDLBT2yGjXFlJc/s320/ttyUSB.png" width="320" /></a></div>
<div style="text-align: center;">
From documentation, ttyUSB0 -> JTAG, ttyUSB1 -> UART (terminal)</div>
<br />
I used GNU screen to stablish the connection:<br />
<div class="terminal">
sudo apt-get install screen<br />
screen /dev/<ttyUSBx> 115200</div>
<div style="text-align: justify;">
After the connection was established. I saw no output so I pressed the reset button on the Beaglebone.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlObEMk9aIPRtd26VwrBgAd99uzbGRGzrIN1stuogu3RhX0HMBnD_RLTTUcVUmq77H7MTbxGQItF0pIHaHIHWQsn_HAzQFXi7eyPQGAHUnJespW1FwFNBzeTkfQFi9c7Cl3QKEMoihq_c/s1600/login.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlObEMk9aIPRtd26VwrBgAd99uzbGRGzrIN1stuogu3RhX0HMBnD_RLTTUcVUmq77H7MTbxGQItF0pIHaHIHWQsn_HAzQFXi7eyPQGAHUnJespW1FwFNBzeTkfQFi9c7Cl3QKEMoihq_c/s320/login.png" width="320" /></a></div>
<div style="text-align: center;">
Voilà</div>
<br />
The default login information is below.<br />
<ul>
<li>login: ubuntu</li>
<li>password: temppwd</li>
</ul>
<br />
<h3>
Things to do after installing Ubuntu</h3>
<br />
OK, I logged in! ... Now what?<br />
<br />
<h4>
Change your password</h4>
<br />
First thing first, I changed the default password to something stronger<br />
<div class="terminal">
# On the Beaglebone<br />
passwd</div>
<br />
<h4>
Connect the Beaglebone to the internet</h4>
<br />
<div style="text-align: justify;">
I plugged an Ethernet cable into the Beaglebone, and checked if the connection was OK.</div>
<div class="terminal">
# On the Beaglebone<br />
ping www.google.com</div>
I let ping run for a while and then I finished it with Ctrl+C.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg53VpDmh8yZZnd_Xr9Han4kJWZwVLE3r-76yc__0SpysjsJlBEVgIt5N6Vs5oqk4GJ48mbbHJ6SfLrMmZtFPpH4oQoWLgnXlP_N8czlwjQmxX8TV0yOMf4PsCw_ctGpKNKVz8QK2n4RTg/s1600/ping.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="132" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg53VpDmh8yZZnd_Xr9Han4kJWZwVLE3r-76yc__0SpysjsJlBEVgIt5N6Vs5oqk4GJ48mbbHJ6SfLrMmZtFPpH4oQoWLgnXlP_N8czlwjQmxX8TV0yOMf4PsCw_ctGpKNKVz8QK2n4RTg/s320/ping.png" width="320" /></a></div>
<div style="text-align: center;">
Notice the "0% packet lost", that's a Win.</div>
<br />
<div style="text-align: justify;">
OK I lied, it didn't work the first time, I got 100% packet lost, but resetting the Beaglebone solved the problem.</div>
<br />
<h4>
Autocompletion </h4>
<br />
Next, I enabled bash completion - a.k.a. the tab autocompletion:<br />
<div class="terminal">
# On the Beaglebone<br />
sudo apt-get update && sudo apt-get install bash-completion</div>
<br />
<h4>
Change the hostname</h4>
<br />
<div style="text-align: justify;">
The terminal prompt says "ubuntu@arm". This means the Beaglebone hostname is "arm". I changed that with the following commands. </div>
<div class="terminal">
# On the Beaglebone<br />
cat /etc/hosts</div>
I got the following output.<br />
<div class="terminal">
# On the Beaglebone<br />
127.0.0.1 localhost<br />
127.0.1.1 arm</div>
So I changed the second line with:<br />
<div class="terminal">
# On the Beaglebone<br />
sudo nano /etc/hosts<br />
# changed the second line from arm to <new-hostname></div>
Next, I did:<br />
<div class="terminal">
# On the Beaglebone<br />
cat /etc/hostname</div>
And got:<br />
<div class="terminal">
# On the Beaglebone<br />
arm</div>
I changed that with:<br />
<div class="terminal">
# On the Beaglebone<br />
sudo nano /etc/hostname<br />
# changed the hostname from arm to <new-hostname></div>
Finally I rebooted the Beaglebone to apply the changes.<br />
<div class="terminal">
# On the Beaglebone<br />
sudo reboot</div>
<br />
<h4>
Change your login name</h4>
<br />
<div style="text-align: justify;">
Now the terminal prompt says "ubuntu@beaglebone", the login is "ubuntu". I also changed that.</div>
<br />
I had to enable the root account:<br />
<div class="terminal">
# On the Beaglebone<br />
sudo passwd root<br />
# Entered a temporary password</div>
Pressed "Ctrl + D" to logout and I logged as root: <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-0glFCcLApRgTjr_kHJjhKoUh9ebTMe5J0bN2zWa16xMAt0mFLECQgYnqA7dlW-NEqpdZCumD6xEC9CPrVe99knLRqrK5x0UTEtmzqd4GFwc3jluzJnhuCJZxYE8kFZrbxTBCHQQDfzk/s1600/loggingAsRoot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="215" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-0glFCcLApRgTjr_kHJjhKoUh9ebTMe5J0bN2zWa16xMAt0mFLECQgYnqA7dlW-NEqpdZCumD6xEC9CPrVe99knLRqrK5x0UTEtmzqd4GFwc3jluzJnhuCJZxYE8kFZrbxTBCHQQDfzk/s320/loggingAsRoot.png" width="320" /></a></div>
<div style="text-align: center;">
Logging as root.</div>
<br />
I changed the old username with:<br />
<div class="terminal">
# On the Beaglebone<br />
usermod -l <new-username> ubuntu</div>
I also added a comment to my new user:<br />
<div class="terminal">
# On the Beaglebone<br />
usermod -c "<full-name-or-comment>" <new-username></div>
Next, I moved to my new home:<br />
<div class="terminal">
# On the Beaglebone<br />
usermod -md /home/<new-username> <new-username></div>
Finally, I also renamed the "ubuntu" group to match my new username:<br />
<div class="terminal">
# On the Beaglebone<br />
groupmod -n <new-username> ubuntu</div>
I logged out (Ctrl + D) and logged with my new username:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkVM2rU3WOoLQZw-0-ttDAYzaFCVDGWeAHEYXS4qk3DddmNSoUXld5D8xKLZL0GPAe4LpIdCcHzlc_yNK0rGTum3b5gxDOJlqQBCkhjXfRrAcefMJ9wSsOt1H69ECqrLbIiaG1HeqdEb4/s1600/newLogin.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkVM2rU3WOoLQZw-0-ttDAYzaFCVDGWeAHEYXS4qk3DddmNSoUXld5D8xKLZL0GPAe4LpIdCcHzlc_yNK0rGTum3b5gxDOJlqQBCkhjXfRrAcefMJ9wSsOt1H69ECqrLbIiaG1HeqdEb4/s320/newLogin.png" width="320" /></a></div>
<div style="text-align: center;">
Logged with my new username.</div>
<br />
Finally I locked the root account:<br />
<div class="terminal">
# On the Beaglebone<br />
sudo passwd -l root</div>
<br />
<h4>
Set up a zeroconf hostname</h4>
<br />
<div style="text-align: justify;">
A zeroconf hostname, simplifies SSHing with a local machine by assigning it a hostname on the LAN. This way I don't need to know the IP (which can change over time) to start a SSH session.</div>
<div class="terminal">
#On the Beaglebone<br />
sudo apt-get install avahi-daemon</div>
Now I can connect to the BeagleBone via ssh using the following command:<br />
<div class="terminal">
# On the PC<br />
ssh <beagle-username>@<beagle-hostname>.local</div>
<br />
<h4>
SSHing the Beaglebone</h4>
<div style="text-align: justify;">
<br />
I finished the screen session, using Ctrl+A and then K. I rebooted the Beaglebone, this way the avahi daemon got launched on the next boot.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq2ruKPXKqmL-VOgC19V3rv_xXG7AB8NhjPiHzBt2Cx0NkrTOmf1BzYZ0cnsymp8T7aopxcfaxf2RJlDzOYU5VG-LK8KDMlwKgH-WkSrZecUCB4oiCojM1d97_Thor3gA6QSjTKtg538U/s1600/sshingTheBeaglebone.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="82" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq2ruKPXKqmL-VOgC19V3rv_xXG7AB8NhjPiHzBt2Cx0NkrTOmf1BzYZ0cnsymp8T7aopxcfaxf2RJlDzOYU5VG-LK8KDMlwKgH-WkSrZecUCB4oiCojM1d97_Thor3gA6QSjTKtg538U/s320/sshingTheBeaglebone.png" width="320" /></a></div>
<div style="text-align: center;">
ssh jorge@beaglebone.local instead of ssh jorge@192.168.1.x</div>
<br />
<h4>
SSH login without password</h4>
<br />
<div style="text-align: justify;">
Everytime I SSH'ed the Beaglebone I needed to input the Beaglebone login and password. The next commands got rid of that.</div>
<div class="terminal">
# On the PC<br />
ssh-keygen # Don't enter a passphrase<br />
ssh-copy-id <beagle-username>@<beagle-hostname>.local</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNFrh8bXQy46woAtcK7koQpNMB3mFRJhx4YEHXcNf0xsswwgzXTaQF3v0M3NPE0PtBAcfqR4GnC3N8VLNUds_aqrC-jS-qUnOHfFnyvfNy5yGuojM8FU1TPS5sKe65S2c0SXGlXZhpYLM/s1600/sshWithoutLogin.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNFrh8bXQy46woAtcK7koQpNMB3mFRJhx4YEHXcNf0xsswwgzXTaQF3v0M3NPE0PtBAcfqR4GnC3N8VLNUds_aqrC-jS-qUnOHfFnyvfNy5yGuojM8FU1TPS5sKe65S2c0SXGlXZhpYLM/s320/sshWithoutLogin.png" width="320" /></a></div>
<div style="text-align: center;">
SSH without login</div>
<br />
<h4>
Install GNU screen</h4>
<br />
<div style="text-align: justify;">
I quickly found out that I needed multiple SSH sessions to open multiple terminals on the Beaglebone. Searching for a workaround I found GNU Screen.</div>
<br />
<div style="text-align: justify;">
With GNU screen I can create multiple "screens", with one terminal inside each of them. All this can be done with <a href="http://aperiodic.net/screen/quick_reference">keyboard commands</a>.</div>
<div class="terminal">
#On the Beaglebone<br />
sudo apt-get install screen</div>
To start screen I needed to use the following command on every login.<br />
<div class="terminal">
#On the Beaglebone<br />
screen -S 1</div>
This was annoying, so I automated the task:<br />
<div class="terminal">
# On the PC<br />
gedit ~/.bashrc</div>
I appended the following text:<br />
<div style="text-align: justify;">
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
alias sshbeaglebone='ssh -t <beagle-username>@<beagle-hostname>.local "screen -dRR"
]]>
</script>
Now with a single command, I can SSH login into the Beaglebone and enter in a running "screen" or create a new "screen", if it doesn't exists.</div>
<div class="terminal">
#On the PC<br />
sshbeaglebone</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA3NYUMi5NGWQHZ1zvbAG5fsitB32SFHFFsOveJ8vNsgSzM0DbPqdCj0ifcglFXd1OBBQIAt31m20HE8uM7RHhpwqDBCd1yzM-uVAhbfs3XZxvoiY2tPZX0Vrj_Lgi-76wTk9u2jXZed8/s1600/screenedSSH.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA3NYUMi5NGWQHZ1zvbAG5fsitB32SFHFFsOveJ8vNsgSzM0DbPqdCj0ifcglFXd1OBBQIAt31m20HE8uM7RHhpwqDBCd1yzM-uVAhbfs3XZxvoiY2tPZX0Vrj_Lgi-76wTk9u2jXZed8/s320/screenedSSH.png" width="320" /></a></div>
<div style="text-align: center;">
SSH session with the Beaglebone splitted in 3 using screen.</div>
<h4>
<br />
Other important software</h4>
<br />
I also installed additional software:<br />
<div class="terminal">
#On the Beaglebone<br />
sudo apt-get install man-db # Manuals<br />
sudo apt-get install vim # Text editor<br />
sudo apt-get install octave # Numerical package<br />
sudo apt-get install build-essential # make, gcc, et al.</div>
<br />
<h3>
What's next?</h3>
<br />
<ul>
<li><a href="http://embeddedprogrammer.blogspot.com/2013/01/vim-for-python-development.html">Convert Vim into an IDE</a>.</li>
<li><a href="http://embeddedprogrammer.blogspot.com/2013/01/beaglebone-using-usb-wifi-dongle-to.html">Using an USB WiFi dongle to connect to wireless networks at boot</a>.</li>
<li><strike>Figure out how to access (with C or ...Python?) the Beaglebone hardware registers</strike>. Sorry, no time for this one, you might want to check <a href="https://github.com/alexanderhiam/PyBBIO">PyBBIO</a>. Good Luck!</li>
</ul>
<br />
<h3>
Acknowledgements</h3>
<br />
<ul>
<li>The <a href="http://beagleboard.org/">BeagleBoard</a> community for producing the Beaglebone. </li>
<li>The <a href="http://elinux.org/Main_Page">Embedded Linux</a> community for <a href="http://elinux.org/BeagleBoardUbuntu">their tutorial</a> on how to install Ubuntu on the Beagles. </li>
<li>Brandon Mintern for his <a href="http://shebang.brandonmintern.com/tips-for-remote-unix-work-ssh-screen-and-vnc">great post</a> about SSH and Screen.</li>
</ul>
<br />Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com21tag:blogger.com,1999:blog-1622983275835621655.post-79325093466866088282012-10-21T18:06:00.000-05:002012-10-21T18:06:18.512-05:00Ubuntu: How to add Eclipse to the Unity Launcher<div style="text-align: justify;">
A quick how to: Add Eclipse to the Unity Launcher. You can add any other application to the Unity Launcher using these steps.</div>
<br />
<div style="text-align: justify;">
All the Unity Launchers (e.g. evince, gedit, etc) are implemented as .desktop files. These files are stored in the folder /usr/share/applications/. The .desktop file contains the following information: where the icon is located, where the executable is located, the launcher name, and other secondary information like a comment about the launcher.</div>
<br />
<h4>
Make Eclipse accessible from the command line</h4>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
All the commands accessible from the command line are stored in a "bin" folder. The folder destined to user binaries is located in /usr/bin.</div>
<br />
<div style="text-align: justify;">
Let's add the eclipse executable to /usr/bin using the following command.</div>
<br />
<div class="terminal">
sudo ln -s /path/to/eclipse/eclipse /usr/bin/</div>
<br />
<div style="text-align: justify;">
Now eclipse is accessible from the command line as the command <i>eclipse</i>.</div>
<br />
<h4>
Put the icon in the right place</h4>
<br />
<div style="text-align: justify;">
All the icons associated to a Unity Launcher are stored in the /usr/share/pixmap folder. Let's place the eclipse icon in the right folder.</div>
<br />
<div class="terminal">
sudo cp /path/to/eclipse/icon.xpm /usr/share/pixmap/eclipse.xpm</div>
<br />
<h4>
Create the .desktop file</h4>
<br />
<div style="text-align: justify;">
Finally, you'll need to create a new .desktop file for Eclipse. Proceed with the following command.</div>
<br />
<div class="terminal">
sudo gedit /usr/share/applications/eclipse.desktop</div>
<br />
<div style="text-align: justify;">
Insert the following text inside this new file.</div>
<br />
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
[Desktop Entry]
Type=Application
Name=Eclipse
Comment=Eclipse Integrated Development Environment
Icon=eclipse
Exec=eclipse
Terminal=false
Categories=Development;IDE;Java;
]]></script>
<div style="text-align: justify;">
Note 1: If you didn't add eclipse to /usr/bin, you'll have to use the full path in the <i>Exec</i> section, e.g. Exec=/path/to/eclipse/eclipse</div>
<br />
<div style="text-align: justify;">
Note 2: If you didn't place the eclipse icon under the /usr/share/pixmap folder, you'll have to use the full path in the <i>Icon</i> section, e.g. Icon=/path/to/eclipse/icon.xpm</div>
<br />
<div style="text-align: justify;">
This is the result.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKwjzQSzy7xUuUb58ZUTxBew9ZlbTNq5qM-zaif1sY9z4jptq0QhBBgnQGK-gmyWGynrOT9C7ZKY67k8oeQ-iRn2UEVlEFn3eHAetBAPrs21BERvZ_pFb65SDLjJ9KJHYZ4SbPncpydlU/s1600/EclipseUnityLauncher.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKwjzQSzy7xUuUb58ZUTxBew9ZlbTNq5qM-zaif1sY9z4jptq0QhBBgnQGK-gmyWGynrOT9C7ZKY67k8oeQ-iRn2UEVlEFn3eHAetBAPrs21BERvZ_pFb65SDLjJ9KJHYZ4SbPncpydlU/s320/EclipseUnityLauncher.jpg" width="320" /></a></div>
<div style="text-align: center;">
Now, Eclipse is accessible from dash and the Unity Launcher.</div>
Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com15tag:blogger.com,1999:blog-1622983275835621655.post-30947030276396517512012-10-07T19:02:00.000-05:002012-10-07T19:02:32.812-05:00Windows: Installing qwt library<a href="http://sourceforge.net/projects/qwt/">Qwt</a> is a Qt based library that extends the Qt API with plotting capabilities.<br />
<br />
<h3>
Installation</h3>
<br />
<div style="text-align: justify;">
I'm assuming you have already installed MinGW (GCC compiler) and the Qt library, if you haven't then check <a href="http://embeddedprogrammer.blogspot.com/2012/07/windows-installing-qt-creator.html">this post</a>.</div>
<br />
<div style="text-align: justify;">
Next you'll need to add the MinGW binaries to the PATH environment variable, if you haven't done so. If you don't know how to edit environment variables, check <a href="http://embeddedprogrammer.blogspot.com/2012/10/windows-environment-variables-for-mingw.html">this post</a>. </div>
<br />
<div style="text-align: justify;">
Append "C:\mingw\bin" (use the correct directory path) to the PATH variable.</div>
<br />
<div style="text-align: justify;">
Append "C:\Qt\4.8.3\bin" to the PATH variable.</div>
<br />
<div style="text-align: justify;">
Grab the latest qwt source (zip version) from <a href="http://sourceforge.net/projects/qwt/files/qwt/">here</a>.</div>
<br />
<div style="text-align: justify;">
Unzip the zip file, go inside the qwt folder and open the qwtconfig.pri file with a text editor.</div>
<br />
<div style="text-align: justify;">
Comment (i.e. add a '#' character to the leftmost side) the following line:</div>
<br />
QWT_CONFIG += QwtDesigner<br />
<br />
<div style="text-align: justify;">
Save and close the .pri file.</div>
<br />
<div style="text-align: justify;">
Now open a command line window and type the following commands:</div>
<br />
cd C:\path\to\downloaded\qwt<br />
qmake<br />
make<br />
make install<br />
<br />
<div style="text-align: justify;">
Note: Instead of "C:\path\to\downloaded\qwt" use the correct path like "C:\Users\Jorge\Downloads\qwt-6.0.1"</div>
<br />
<div style="text-align: justify;">
A new folder will be created in the C:\ drive named qwt-6.0.1 or similar.</div>
<br />
<div style="text-align: justify;">
The final step is updating the environment variables, if you don't know/remember how check <a href="http://embeddedprogrammer.blogspot.com/2012/10/windows-environment-variables-for-mingw.html">this post</a>. </div>
<br />
Append "C:\qwt-6.0.1\include" to CPLUS_INCLUDE_PATH<br />
Append "C:\qwt-6.0.1\lib" to LIBRARY_PATH<br />
<br />
<div style="text-align: justify;">
Note: You won't be able to see the qwt widgets in Qt designer with these installation steps. I haven't figured out yet how to enable that.</div>
<br />
<h3>
How to use qwt</h3>
<div style="text-align: justify;">
Create a new Qt project in Qt creator, and add to the .pro file the next line:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEht0q6Cz7Mua-OZMDyYCydpU8oIMtkYvk1y5PlRekLPqq5pBt4fkwbGowQSE78UD1PnnQCd42UdElz37xO7y6v3Ub0NdO_L8L0ghlLKujC7km0wTv3I0FAPMfsCv_X5ULpmGK5myh1xP-g/s1600/linking.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEht0q6Cz7Mua-OZMDyYCydpU8oIMtkYvk1y5PlRekLPqq5pBt4fkwbGowQSE78UD1PnnQCd42UdElz37xO7y6v3Ub0NdO_L8L0ghlLKujC7km0wTv3I0FAPMfsCv_X5ULpmGK5myh1xP-g/s320/linking.png" width="320" /></a></div>
<div style="text-align: center;">
Linking qwt library</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Next, you'll need the library header files, all of them start with "qwt_". Add them where necessary as shown in the next image:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHQYOnIx-P8y-OW5FJ5jC_I228IH7H7f6u7cmvlaGikw4runDfTtv7Uz5hG8QvhluVZPs0tFmq5ckgSTo2GdVHLexck3CK7Duy0RMe6Ly-u_5KRx9jPEMxG-_35hAnxk5lVF1hbQy29Xg/s1600/include.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHQYOnIx-P8y-OW5FJ5jC_I228IH7H7f6u7cmvlaGikw4runDfTtv7Uz5hG8QvhluVZPs0tFmq5ckgSTo2GdVHLexck3CK7Duy0RMe6Ly-u_5KRx9jPEMxG-_35hAnxk5lVF1hbQy29Xg/s320/include.png" width="320" /></a></div>
<div style="text-align: center;">
Including qwt header files.</div>
<br />
<h3>
Simple test</h3>
<br />
<div style="text-align: justify;">
Let's do a very simple test and see if everything has been installed correctly. In your mainwindow.cpp source file type the next code:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZsuXLFshs2OD1_3d8s5XUF-h-VC3VXaif0QfvZlro6RsdmTNPmF-EicBpT1kbJPvsut8QIURnV3D0v_-aq2WAMd5VbNwy0piA2W1HRU3ydVsCTLmPN7jxSxh16jcCfOY5ijL3coTrVx8/s1600/source.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZsuXLFshs2OD1_3d8s5XUF-h-VC3VXaif0QfvZlro6RsdmTNPmF-EicBpT1kbJPvsut8QIURnV3D0v_-aq2WAMd5VbNwy0piA2W1HRU3ydVsCTLmPN7jxSxh16jcCfOY5ijL3coTrVx8/s320/source.png" width="320" /></a></div>
<div style="text-align: center;">
Simple test source code.</div>
<br />
<div style="text-align: justify;">
Then run it, and you should see the following output.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsFCutvIbYFqd6RwZwNeG7QwwLlnKhZ_fupqRfv1kVhevIlQrs5RxWvHUgGMJEDifIG7Yq_FJvNv699ot1CL8i6VRVX-UKhPKABnngQEyK21Dzre_8L5ZOJWlU116K38QJAfFAV2GbXeQ/s1600/output.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="260" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsFCutvIbYFqd6RwZwNeG7QwwLlnKhZ_fupqRfv1kVhevIlQrs5RxWvHUgGMJEDifIG7Yq_FJvNv699ot1CL8i6VRVX-UKhPKABnngQEyK21Dzre_8L5ZOJWlU116K38QJAfFAV2GbXeQ/s320/output.png" width="320" /></a></div>
<div style="text-align: center;">
Simple test output.</div>
<br />
<h3>
Other Examples</h3>
<br />
For more elaborated examples check <a href="https://github.com/JorgeAparicio/qSerialTerm">qSerialTerm</a> and <a href="https://github.com/JorgeAparicio/ImageQ">ImageQ</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7TAcSOenPsR7lI4hyn-96fVfHV8r3v6lfzC3Ij8vIEKgbJ8rty383UxiRa7NyCaL-8h8yMAMmfcIA9m-q-Kx1KGzHatoSSRaGDhlVoRSXfIl-aIfVGi7JdF02mlpfpUxXON3oBFLUdmE/s1600/ImageQ.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="169" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7TAcSOenPsR7lI4hyn-96fVfHV8r3v6lfzC3Ij8vIEKgbJ8rty383UxiRa7NyCaL-8h8yMAMmfcIA9m-q-Kx1KGzHatoSSRaGDhlVoRSXfIl-aIfVGi7JdF02mlpfpUxXON3oBFLUdmE/s320/ImageQ.png" width="320" /></a></div>
<div style="text-align: center;">
ImageQ in Windows. Histogram was plotted using QwtPlot.</div>
Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com6tag:blogger.com,1999:blog-1622983275835621655.post-78744281362355286292012-10-07T11:38:00.000-05:002012-10-07T11:45:17.118-05:00Windows: Environment Variables for MinGW<div style="text-align: justify;">
Environment variables, as the name implies, are variables that hold directories paths as strings. Environment variables goal is to keep track of important files for the system.</div>
<br />
<div style="text-align: justify;">
In windows, the most important environment variable is the PATH variable. You can check its content on the command line using the following command:</div>
<br />
echo %PATH%<br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Environment variables can also keep track of important files for the compiler (e.g. MinGW GCC) like header files and static and dynamic library files.</div>
<br />
<h3>
Adding, editing or deleting environment variables</h3>
<br />
<div style="text-align: justify;">
To add, modify or delete an environment variable, you'll need to head to Control Panel > System > Advanced System Settings. On the Advanced tab, click on the Environment Variables... button.</div>
<br />
The following window will pop out.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieH-19_5A48Te0b8Jt9zvDod3nyxfLuGK98p1pJJgTtQG907xqtsieifnV8TiDyuUjBDooptIQyDFL9RpfqbB2cSJjyHOM_ufvlLmsDsOU56fSD9VqhzorE_5IHfN9ib_ePwLinRKbaL8/s1600/environment_variables.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieH-19_5A48Te0b8Jt9zvDod3nyxfLuGK98p1pJJgTtQG907xqtsieifnV8TiDyuUjBDooptIQyDFL9RpfqbB2cSJjyHOM_ufvlLmsDsOU56fSD9VqhzorE_5IHfN9ib_ePwLinRKbaL8/s320/environment_variables.png" width="289" /></a></div>
<div style="text-align: center;">
List of environment variables</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Environment variables are divided in two groups: User variables and System variables. The most important group is the System group. You can create, modify or delete variables using the button New, Edit or Delete respectively.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Let's try editing the Path variable. Click on the Path variable in the System variables group and then click the Edit button.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq3j_XnJlGzM9ApGtEgbRY-sYGeaKGdElWvdlMnGnNR0MvD6llnfq5aIlbvl073tgiWYDgiWNrF40k-GIbb_MPGd_c4Etv-_2LnJ9AuUN3ugFBKVhqpaKBBJ4rY4lht8qx85cWdqXdHfY/s1600/edit_env_var.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="137" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq3j_XnJlGzM9ApGtEgbRY-sYGeaKGdElWvdlMnGnNR0MvD6llnfq5aIlbvl073tgiWYDgiWNrF40k-GIbb_MPGd_c4Etv-_2LnJ9AuUN3ugFBKVhqpaKBBJ4rY4lht8qx85cWdqXdHfY/s320/edit_env_var.png" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
As you can see, the variable is a list of directory paths separated by the ";" character. The most safe way of adding a new directory is by appending the path as follows:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
;C:\mingw\bin</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
That way there won't be name crashes.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
There are many environment variables, let's review the most important ones.</div>
<div style="text-align: justify;">
<br /></div>
<h3>
Binary path (PATH)</h3>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The PATH (or Path, Windows is case insensitive) variable holds paths to binary files like .<a href="http://en.wikipedia.org/wiki/Exe">exe</a> files, to <a href="http://en.wikipedia.org/wiki/Command_%28computing%29">commands</a> and to .<a href="http://en.wikipedia.org/wiki/Dynamic-link_library">dll</a> files.</div>
<br />
<div style="text-align: justify;">
Be careful with this variable, do not delete the default path like System32 and so on. Generally, you'll only need to append new directory paths to this variable.</div>
<br />
For example:<br />
<br />
Append ";C:\mingw\bin" to the Path variable<br />
<br />
<div style="text-align: justify;">
<b>Important note:</b> Do NOT create a new Path or PATH (again, Windows is case insensitive) variable in the system variable group or you'll override the default paths and you'll be in trouble.</div>
<br />
<h3>
Include paths (CPLUS_INCLUDE_PATH, C_INCLUDE_PATH)</h3>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
These variable hold the directory paths to header files (like library header files). Important for linking new installed libraries.</div>
<br />
Generally you'll need to append the path to a library "include" folder.<br />
<br />
For example:<br />
<br />
Append ";C:\mingw\include" to the CPLUS_INCLUDE_PATH<br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
CPLUS_INCLUDE_PATH and C_INCLUDE_PATH are pretty much the same. When the compiler looks for a header file, it looks in both variables. So having two variables is only useful for the programmer to keep things tidy.</div>
<br />
<h3>
Library path (LIBRARY_PATH)</h3>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This variable hold the directory paths to <a href="http://en.wikipedia.org/wiki/Static_library">static library</a> (.lib or .a files). This one is also important for linking new libraries.</div>
<br />
Generally you'll need to append the path to a library "lib" folder.<br />
<br />
For example:<br />
<br />
Append ";C:\mingw\lib" to the LIBRARY_PATH<br />
<br />Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com23tag:blogger.com,1999:blog-1622983275835621655.post-39471135749530311282012-10-06T18:10:00.000-05:002012-10-09T12:07:43.806-05:00How to: OpenCV in Qt creator and ImageQ<div style="text-align: justify;">
In this post I'll cover how to glue the OpenCV libraries to Qt creator via an example. And I'll also release ImageQ, a Qt based image processing application. </div>
<br />
<h3>
OpenCV</h3>
<br />
<div style="text-align: justify;">
<a href="http://opencv.org/">OpenCV</a> is an open source library that contains various functions for computer vision and image processing. OpenCV is written in C/C++ but there are ports for Java and Python.</div>
<br />
<h3>
Qt framework</h3>
<br />
<div style="text-align: justify;">
<a href="http://qt-project.org/">Qt</a> is a framework for cross development of Graphical User Interfaces (GUI) in C++. Qt libraries are open source.</div>
<br />
<div style="text-align: justify;">
<a href="http://qt-project.org/downloads#qt-creator">Qt creator</a> is an Integrated Development Environment (IDE) for Qt applications. Qt creator was created using the Qt framework as well.</div>
<br />
<h3>
Dependencies</h3>
<br />
<div style="text-align: justify;">
You'll need the following libraries/software:</div>
<br />
<ul>
<li>Qt creator</li>
<li>Qt libraries </li>
<li>OpenCV libraries</li>
</ul>
<br />
<h4>
Ubuntu</h4>
<br />
<div style="text-align: justify;">
Open a linux terminal and type the following commands:</div>
<br />
<div class="terminal">
sudo apt-get install qtcreator # Qt creator + Qt libraries<br />
sudo apt-get install libopencv-dev # OpenCV libraries
</div>
<br />
<div style="text-align: justify;">
On Ubuntu 12.04 you'll end with Qt libraries version 4.8 and OpenCV libraries version 2.3.</div>
<br />
<h4>
Windows</h4>
First, you need Qt creator and Qt libraries. Follow the steps in <a href="http://embeddedprogrammer.blogspot.com/2012/07/windows-installing-qt-creator.html">this post</a> and come back.<br />
<br />
Now, grab and unzip OpenCV from <a href="http://opencv.org/downloads.html">here</a>.<br />
<br />
Next, install CMake (win32 exe) from <a href="http://www.cmake.org/cmake/resources/software.html">here</a>.<br />
<br />
You'll need to add C:/mingw/bin to your PATH environment variable. Check <a href="http://embeddedprogrammer.blogspot.com/2012/10/windows-environment-variables-for-mingw.html">this post </a>for a how to.<br />
<br />
Now, launch cmake-gui.<br />
<br />
Select as source folder: The unzipped version of OpenCV and as build folder: any folder you want. Then click on the configure button, from the drop down menu select the MinGW makefiles and accept. You should get the following output. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigQLkpJsCEDwrhiPJBiaQapB0I5OkBF7UdSpwAtgmDfq1PSYO5gRtKKZpo8r7Rdsd86o4lD_ubUnR6eDJkedXIEW4up0JYUS06YwCcEM4WFxE9tFZ5g0q5CaX8mtxzvbiVM-hs1RQj3cQ/s1600/cmake.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigQLkpJsCEDwrhiPJBiaQapB0I5OkBF7UdSpwAtgmDfq1PSYO5gRtKKZpo8r7Rdsd86o4lD_ubUnR6eDJkedXIEW4up0JYUS06YwCcEM4WFxE9tFZ5g0q5CaX8mtxzvbiVM-hs1RQj3cQ/s320/cmake.png" width="320" /></a></div>
<div style="text-align: center;">
OpenCV build configuration.</div>
<br />
Go with the default configuration and click the generate button.<br />
<br />
Now open a cmd and head to your "build folder" (the one you selected in CMake) and run the following command:<br />
<br />
mingw32-make<br />
<br />
Now go get a coffee, a sandwich or take a nap while the compiler does it job.<br />
<br />
(coffee break)<br />
<br />
OK, after thousands of compiler messages, you finally obtained the necessary binaries.<br />
<br />
Execute the next command:<br />
<br />
mingw32-make install<br />
<br />
A new folder name "install" will be created in your "build folder". Copy the contents of this "install" folder in any folder you like (e.g. C:/opencv). You can now delete the "source code folder" (the one you download from OpenCV website) and the intermediate compiled objects (a.k.a. your "build folder").<br />
<br />
Now you'll need to modify some environment variables. Check <a href="http://embeddedprogrammer.blogspot.com/2012/10/windows-environment-variables-for-mingw.html">this post</a> if you don't know how.<br />
<br />
I'm assuming you are using the C:\opencv folder, change the path if necessary.<br />
<br />
Append to the PATH (or Path, is the same, do NOT create a new variable) variable: C:\opencv\bin<br />
<br />
Append to the CPLUS_INCLUDE_PATH variable: C:\opencv\include<br />
<br />
Append to the LIBRARY_PATH variable: C:\opencv\lib<br />
<br />
<h3>
Setting up the Qt project</h3>
<br />
(The rest of the article is the same for Ubuntu and Windows users)<br />
<ul>
<li>Launch Qt creator.</li>
<li>Start a new project (usually Qt Gui Application). </li>
<li>Head to your .pro file.</li>
<li>Inside the .pro file add these lines: </li>
</ul>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvmmJhs-zzTjGsgC6GTF8kQOm6bKrAj6vHxVZ3GUwNZ5VJtLwAe3FB4Jp-TT7_E6tIxMbcacYXuQi4leCy0PvkPES0RVWmRKf_3FnopXwyOSpKXmDJM3UR1E8WRyWhZe6dlFz_jm1PKm8/s1600/linking.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvmmJhs-zzTjGsgC6GTF8kQOm6bKrAj6vHxVZ3GUwNZ5VJtLwAe3FB4Jp-TT7_E6tIxMbcacYXuQi4leCy0PvkPES0RVWmRKf_3FnopXwyOSpKXmDJM3UR1E8WRyWhZe6dlFz_jm1PKm8/s320/linking.png" width="320" /></a></div>
<div style="text-align: center;">
Linking OpenCV libraries (Linux)</div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: justify;">
Note: You probably won't need to link all the libraries, only link the ones you are going to use. The most common libraries are core, highgui and imgproc.</div>
<div style="text-align: justify;">
<br /></div>
<h3>
Adding the headers </h3>
<br />
<div style="text-align: justify;">
OpenCV library headers are inside the opencv2 folder. To add these headers to your application add the following line:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhR1z0_3IcsIGHIZS3SHoODKWBhlmOBDW3kPoQqedivxSpIsDlD9cBO8fjzhyVIb4fNFly6iI4qqpMpWT7yHbPL2QgmG7Jk68UFf9yGPVtmxnhfVH0sWVlE2A1MwvMb8MbtEC4FPOezjog/s1600/headers.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhR1z0_3IcsIGHIZS3SHoODKWBhlmOBDW3kPoQqedivxSpIsDlD9cBO8fjzhyVIb4fNFly6iI4qqpMpWT7yHbPL2QgmG7Jk68UFf9yGPVtmxnhfVH0sWVlE2A1MwvMb8MbtEC4FPOezjog/s320/headers.png" width="320" /></a></div>
<div style="text-align: center;">
Adding OpenCV library headers.</div>
<br />
<h3>
Displaying the images</h3>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
OpenCV offers a function named cv::imshow for displaying images. However this method won't integrate to your Qt application.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In Qt, images are usually displayed in QLabels using the method setPixmap(). As the name implies the argument for this method must be a QPixmap object. QPixmap objects are optimized for displaying, meanwhile QImage objects are optimized for pixel manipulation. Using the static method QPixmap::fromImage() a QImage can be converted in a QPixmap.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Is easier to convert a cv::Mat, the basic OpenCV image object, to a QImage object than to a QPixmap objetc.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In summary, the necessary steps are listed below:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<ul>
<li>Convert the cv::Mat object to a QImage object.</li>
<li>Convert the QImage object to a QPixmap object, using QPixmap::fromImage().</li>
<li>Add the QPixmap object to a QLabel, using setPixmap().</li>
</ul>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
To convert a cv::Mat to a QImage, you can use my implementation available on the following links: <a href="https://github.com/JorgeAparicio/ImageQ/blob/master/mat2qimage.h">header</a> and <a href="https://github.com/JorgeAparicio/ImageQ/blob/master/mat2qimage.cpp">source</a>.</div>
<div style="text-align: justify;">
<br /></div>
<h3>
An example</h3>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Let's put everything together in an example. Head to your .ui file and add a label (leave the default name "label"), as shown in the following image. (I have also added grid layout, not necessary but helps visualization)</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0P_6wJX4NEXfZzAETqD2sRuudNN8n2KJTmC2VEbOJAcQcUNvH_3UH-tETevVZ5h-fi4GlfRREv8A0B8SI1o63dPmGI4-wFJCEYTQqtlp0NLlJVKXb86r2f4Sn-PZGz8nn5_6b8q_ybfE/s1600/ui.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0P_6wJX4NEXfZzAETqD2sRuudNN8n2KJTmC2VEbOJAcQcUNvH_3UH-tETevVZ5h-fi4GlfRREv8A0B8SI1o63dPmGI4-wFJCEYTQqtlp0NLlJVKXb86r2f4Sn-PZGz8nn5_6b8q_ybfE/s320/ui.png" width="320" /></a></div>
<div style="text-align: center;">
Toy application layout</div>
<br />
Next, add the <a href="https://github.com/JorgeAparicio/ImageQ/blob/master/mat2qimage.cpp">mat2qimage.cpp</a> and <a href="https://github.com/JorgeAparicio/ImageQ/blob/master/mat2qimage.h">mat2qimage.h</a> to your project.<br />
<br />
<div style="text-align: justify;">
Now, on your mainwindow.cpp source file type the following code:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvl19rfleM7Hm98jxPbEVedPP-sTIFl9SRHZj3RbqQq_N-IUyGF_G2UZS_jCk3JkIBVuNVx17nmijuEhDz8sQrvk80OWY8hoX7c6apnWBglIW0N2zs-g4jF_wNwBAhqq_HlwCJGulhpWw/s1600/source.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvl19rfleM7Hm98jxPbEVedPP-sTIFl9SRHZj3RbqQq_N-IUyGF_G2UZS_jCk3JkIBVuNVx17nmijuEhDz8sQrvk80OWY8hoX7c6apnWBglIW0N2zs-g4jF_wNwBAhqq_HlwCJGulhpWw/s320/source.png" width="320" /></a></div>
<div style="text-align: center;">
Toy application source code.</div>
<br />
<div style="text-align: justify;">
<b>Note:</b> In Windows, I had to use the full path to the image and the '\' characters needed to be written as "\\" insted. Example: "C:\\Users\\Jorge\\Desktop\\myimage.JPG".</div>
<br />
<div style="text-align: justify;">
This is the output, after running the example:</div>
<br />
<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiFkCdCAR9Ei6QDDWachC3prEOx3epc71mbBudceQrxwyWzcz8nRiQc0GyTHSW4SYuc8QR1QMTaIBPEZQqeyHs9Rdrs2BLgx6k8LB_s1olzZr6qcjbPKKBHuQWY8aa-7QuaWdzljjsAVM/s1600/example.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="155" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiFkCdCAR9Ei6QDDWachC3prEOx3epc71mbBudceQrxwyWzcz8nRiQc0GyTHSW4SYuc8QR1QMTaIBPEZQqeyHs9Rdrs2BLgx6k8LB_s1olzZr6qcjbPKKBHuQWY8aa-7QuaWdzljjsAVM/s200/example.png" width="200" /></a></div>
</td>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBwq-goI77mOeyjt_4H7lSVNtR0nEYS8Zw61OfwYxcgN8rUc5GOTjcdDIFNXTDUi389Y19U7SoasXRDBLC4Ztpu0_Q7XfbzycmZmB3PEn3fsgHqsl1r3i6zBGcTBgeCy_lDGuNmyJqy_U/s1600/windows_example.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="153" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBwq-goI77mOeyjt_4H7lSVNtR0nEYS8Zw61OfwYxcgN8rUc5GOTjcdDIFNXTDUi389Y19U7SoasXRDBLC4Ztpu0_Q7XfbzycmZmB3PEn3fsgHqsl1r3i6zBGcTBgeCy_lDGuNmyJqy_U/s200/windows_example.png" width="200" /></a></div>
<br /></td>
</tr>
</tbody></table>
<br />
<div style="text-align: center;">
Toy example output. (Image from <a href="http://en.wikipedia.org/wiki/Coin">wikipedia</a>)</div>
<br />
<h3>
ImageQ</h3>
<br />
<div style="text-align: justify;">
Using these basics, I have developed ImageQ in Qt. ImageQ provides GUI access to some basic OpenCV functions. You can use ImageQ to learn the basics of image processing or to experiment with OpenCV function parameters.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqdYXtXwBNk0Ht6m7pHOAP57ZQy8-fce6kwip4_AZUZmE2xI7Sct1rYq16fQ31GnSNpq7brKsqY98r2AETZA3-qLKXCZfg-8BZIV39PWSP1vouHaUO87hBsNZGMU0z7md8csoDNx4ofvU/s1600/ImageQ.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqdYXtXwBNk0Ht6m7pHOAP57ZQy8-fce6kwip4_AZUZmE2xI7Sct1rYq16fQ31GnSNpq7brKsqY98r2AETZA3-qLKXCZfg-8BZIV39PWSP1vouHaUO87hBsNZGMU0z7md8csoDNx4ofvU/s320/ImageQ.png" width="320" /></a></div>
<div style="text-align: center;">
ImageQ: Coin image after Sobel operator.</div>
<br />
<div style="text-align: justify;">
You can get ImageQ source code from <a href="https://github.com/JorgeAparicio/ImageQ">this github repository</a>.<br />
<br />
P.S. For ImageQ you'll also need Qwt libraries, you can install these in Ubuntu using the following command. (Windows users, check <a href="http://embeddedprogrammer.blogspot.com/2012/10/windows-installing-qwt-library.html">this post</a> instead)<br />
<br /></div>
<div class="terminal">
sudo apt-get install libqwt-dev
</div>
Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com4tag:blogger.com,1999:blog-1622983275835621655.post-53665212375725288962012-09-13T19:14:00.000-05:002013-01-22T12:19:22.633-05:00STM32F4DISCOVERY Development with GCC in Eclipse<div style="text-align: justify;">
First of all, I want to thank the OpenOCD Project for its latest release of OpenOCD. Thanks to this release, its possible to get a working development environment for the STM32F4DISCOVERY relatively fast.</div>
<br />
<div style="text-align: justify;">
This Development Environment can also be used for other STM32 / Cortex M microcontrollers and development boards. I have tested this Development Environment with the STM32VLDISCOVERY, STM32F4DISCOVERY and <a href="http://embeddedprogrammer.blogspot.com/2012/08/f4dev-open-source-development-board-for.html">F4Dev</a>.</div>
<br />
<div style="text-align: justify;">
For now this post is Ubuntu specific. Setting the Development Enviroment on other platforms should be fairly similar. </div>
<br />
<h3>
Dependency: GCC</h3>
<br />
<div style="text-align: justify;">
You need a GCC (GNU Compiler Collection) for ARM Cortex processors: You can use <a href="https://launchpad.net/gcc-arm-embedded">the official GCC build (4.6.2)</a> or <strike><a href="http://www.mentor.com/embedded-software/sourcery-tools/sourcery-codebench/editions/lite-edition/request?id=e023fac2-e611-476b-a702-90eabb2aeca8&downloadlite=scblite2012&fmpath=/embedded-software/sourcery-tools/sourcery-codebench/editions/lite-edition/form">the Mentor Graphics (former Code Sourcery) GCC build (4.5.2)</a></strike> (Do not use the CodeSourcery GCC, the latest library code requires GCC version 4.6 or later).</div>
<br />
<div style="text-align: justify;">
I'll cover how to install the official GCC build, since it's a newer version.</div>
<br />
<h4>
Windows</h4>
<br />
<div style="text-align: justify;">
Grab the <a href="https://launchpad.net/gcc-arm-embedded/4.6/4.6-2012-q4-update/+download/gcc-arm-none-eabi-4_6-2012q4-20121016.exe">installer</a>, follow the installation steps, and check the "Add path to environment variable" checkbox just before finishing the installation.</div>
<br />
<h4>
Linux</h4>
<br />
<div style="text-align: justify;">
Grab the <a href="https://launchpad.net/gcc-arm-embedded/4.6/4.6-2012-q4-update/+download/gcc-arm-none-eabi-4_6-2012q4-20121016.tar.bz2">Linux installation tarball</a>.</div>
<br />
<div style="text-align: justify;">
Untar the tarball and that's it, no need to launch a installer.<br />
<br />
Note: Ubuntu 12.10 users, use the command line tar instead of the GUI archive manager. The latter will result in missing binaries in the bin folder. See image below.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPjRQKc1x6pPhAAOmHUrjVSs-2_tkWoQAVzZLw2pY-1_4F1KeqMoH0R2wdQHvtcu3IFWk4xHBmBcI7Y40lid7hM7NYFL9qZ2SJpkDIyo2TjeBwV674snh9okC8SWVxURynfAMLvartALU/s1600/tarVsArchiveManager.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPjRQKc1x6pPhAAOmHUrjVSs-2_tkWoQAVzZLw2pY-1_4F1KeqMoH0R2wdQHvtcu3IFWk4xHBmBcI7Y40lid7hM7NYFL9qZ2SJpkDIyo2TjeBwV674snh9okC8SWVxURynfAMLvartALU/s320/tarVsArchiveManager.jpg" width="320" /></a></div>
<div style="text-align: center;">
Do not use the GUI archive manager</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Use the following command instead:</div>
<div class="terminal">
tar jxf gcc-arm-none-eabi-4_6-2012q2-20120614.tar.bz2</div>
<div style="text-align: justify;">
Let's add the GCC binaries folder to the PATH environment variable, for easier use.</div>
<div class="terminal">
gedit $HOME/.profile</div>
<div style="text-align: justify;">
Append to this file the following lines:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
if [ -d "<path to gcc directory>/gcc-arm-none-eabi-<gcc version>/bin" ] ; then
PATH="<path to gcc directory>/gcc-arm-none-eabi-<gcc version>/bin:$PATH"
fi
]]>
</script>
Do a soft reboot to update the PATH variable.</div>
<br />
<div style="text-align: justify;">
The binaries should be accessible from the command line, let's check.</div>
<div class="terminal">
arm-none-eabi-gcc --version
</div>
<div style="text-align: justify;">
You should see an output similar to the following lines:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXwSU9x__kZRRoQtWLj3Pv5SKLbK7HPqCoJdzb984zPdkKkmGSItfd8XHOeHzfoZAeTafGIgXHZkYyXkZiDaaEKNoFBEQNwLhqtEgM1llFLMFC_e_pJs4gHHU9ctT3gTUE4wnRkmDFIYs/s1600/GCC+ARM+Embedded+test.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="30" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXwSU9x__kZRRoQtWLj3Pv5SKLbK7HPqCoJdzb984zPdkKkmGSItfd8XHOeHzfoZAeTafGIgXHZkYyXkZiDaaEKNoFBEQNwLhqtEgM1llFLMFC_e_pJs4gHHU9ctT3gTUE4wnRkmDFIYs/s400/GCC+ARM+Embedded+test.png" width="400" /></a></div>
<br />
<div style="text-align: justify;">
If instead you get the following error and you are using a 64bit Ubuntu/Linux OS:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx6Jgw8nkmphdzXD47m0iPwpVyqjTM3VV68E-4VxvDwAPwtImP0RPq1Hzino77BmXFV3l5YFpmPfJ9Blop3MtoZD2bZ6vUmm2ziMkqDnJz5fbP0YTgLs5kkLu50g4JX7yCU8FEuJKkjr4/s1600/error.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="20" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx6Jgw8nkmphdzXD47m0iPwpVyqjTM3VV68E-4VxvDwAPwtImP0RPq1Hzino77BmXFV3l5YFpmPfJ9Blop3MtoZD2bZ6vUmm2ziMkqDnJz5fbP0YTgLs5kkLu50g4JX7yCU8FEuJKkjr4/s320/error.jpg" width="320" /></a></div>
<br />
<div style="text-align: justify;">
It means you are missing some 32 bit libraries. The easiest way to solve this is to install all the 32 bit libraries using the following command:</div>
<br />
<div class="terminal">
sudo apt-get install ia32-libs
</div>
<br />
<div style="text-align: justify;">
Now test again the arm-none-eabi-gcc command and it should work. </div>
<br />
That's it for the GCC dependency.<br />
<br />
<h3>
Dependency: Eclipse CDT</h3>
<br />
<div style="text-align: justify;">
You'll need <a href="http://www.eclipse.org/cdt/">Eclipse C/C++ Development Tooling</a>.
I recommend using Eclipse Indigo instead of Eclipse Juno, because there
is a bug with the content assist when using namespaces.</div>
<br />
<div style="text-align: justify;">
Grab the correct package from <a href="http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers-includes-incubating-components/indigosr2">here</a>. (If you still want to use the Juno version, get the package from <a href="http://www.eclipse.org/downloads/packages/node/818">here</a>)</div>
<br />
<div style="text-align: justify;">
Untar / unzip the tarball / zip file, and you are done.<br />
<br />
<h4>
Windows</h4>
<br />
If you don't have Java installed, head to this <a href="http://www.java.com/en/download/manual.jsp">link</a>. Grab the correct installer (x86 or AMD64), then follow the installation steps.<br />
<br />
After installing Java, Eclipse should work.</div>
<br />
<h3>
Dependency: GNU ARM Plugin</h3>
<br />
<div style="text-align: justify;">
With this plugin, Eclipse will be able to detect the ARM GCC.</div>
<br />
<div style="text-align: justify;">
In Eclipse, go to (Help > Install New Software).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
On this new window, click the add button, and insert the following text.</div>
<br />
<div style="text-align: center;">
<i>http://gnuarmeclipse.sourceforge.net/updates</i></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYMCCTnDATiYKDSWsC1lrx5GvY2o6szpnWkinZUy62T4fMCcGUElrndEgc_IA1pTdWIWF-H0rO9PGUeMw8qrBNAYOTBN1BZTCqksiIdMvUybJG2sHLn93YSt_e-3p09oY3tRM0u2HmW_w/s1600/GNU+ARM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="139" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYMCCTnDATiYKDSWsC1lrx5GvY2o6szpnWkinZUy62T4fMCcGUElrndEgc_IA1pTdWIWF-H0rO9PGUeMw8qrBNAYOTBN1BZTCqksiIdMvUybJG2sHLn93YSt_e-3p09oY3tRM0u2HmW_w/s320/GNU+ARM.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Click OK and a component named "CDT GNU Cross Development Tools" will appear, check it, then click the Next button and following the installation instructions.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh97oanzNjsnueChmp1SCU7lhLEo-_naFZ5XOQzktqVFt5_ZBZaPHNUvNJhMUDfE9P_9_fDPZN3eJypHEZ_Y_IaWQAobwpE7Astp4QW0s73tE5qBGN4F2xI499ya4QbtqixzeV017r-yv4/s1600/GNU+ARM+Install.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="52" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh97oanzNjsnueChmp1SCU7lhLEo-_naFZ5XOQzktqVFt5_ZBZaPHNUvNJhMUDfE9P_9_fDPZN3eJypHEZ_Y_IaWQAobwpE7Astp4QW0s73tE5qBGN4F2xI499ya4QbtqixzeV017r-yv4/s320/GNU+ARM+Install.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
You'll be prompted to reset Eclipse, do so.</div>
<br />
<div style="text-align: justify;">
You're done with this plugin.</div>
<br />
<h3>
Dependency: Zylin Embedded CDT Plugin</h3>
<br />
<div style="text-align: justify;">
This plugin is necessary to flash and debug within Eclipse.</div>
<br />
<div style="text-align: justify;">
In Eclipse, go to (Help > Install New Software).</div>
<br />
<div style="text-align: justify;">
On this new window, click the add button, and insert the following text.</div>
<br />
<div style="text-align: center;">
<i>http://opensource.zylin.com/zylincdt</i></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjei6c48AJTJLV8xag2PHj_BA7H65563X30D1G4H9Y6QA0rGaf7wU05NC4Dmmgsr4j4mK95haNsSEiP5dWfpkuSDTR-zTzJn0jJV2O4X-nQaLMdHKTsPTuIKajcPNUlBHNchZfwz1h5S5o/s1600/Zylin.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="139" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjei6c48AJTJLV8xag2PHj_BA7H65563X30D1G4H9Y6QA0rGaf7wU05NC4Dmmgsr4j4mK95haNsSEiP5dWfpkuSDTR-zTzJn0jJV2O4X-nQaLMdHKTsPTuIKajcPNUlBHNchZfwz1h5S5o/s320/Zylin.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Click OK and a component named "Zylin Embedded CDT" will appear, check it, then click the Next button and following the installation instructions.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmljb8MdtiYj9OImBlSuRe1WQ799jrnodQJ2bosWhznw-kLUWKNaw1mgyrK-soDsawyG9HgzjmZAPsaZQe4pUIsf8wb1guH90QLyODJzr1teac5jdbISKX-gqgo07bFL6Zv_Ck642uSh4/s1600/Zylin+Install.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="52" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmljb8MdtiYj9OImBlSuRe1WQ799jrnodQJ2bosWhznw-kLUWKNaw1mgyrK-soDsawyG9HgzjmZAPsaZQe4pUIsf8wb1guH90QLyODJzr1teac5jdbISKX-gqgo07bFL6Zv_Ck642uSh4/s320/Zylin+Install.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
You'll be prompted to reset Eclipse, do so.</div>
<br />
<div style="text-align: justify;">
You're done with this plugin.</div>
<br />
<h3>
Dependency: OpenOCD</h3>
<br />
<div style="text-align: justify;">
With this software, your PC will be able to flash and debug STM32 targets via a USB <-> JTAG interface.</div>
<div style="text-align: justify;">
<br />
<h4>
Windows</h4>
<br />
Grab the zip from <a href="http://www.freddiechopin.info/en/download/category/4-openocd?download=77%3Aopenocd-0.6.1">here</a>. Unzip the file. Copy the uncompressed folder in your C drive.<br />
<br />
Append ";C:\openocd-0.6.1\bin" or ";C:\openocd-0.6.1\bin-x64" to your PATH variable. See this <a href="http://embeddedprogrammer.blogspot.com/2012/10/windows-environment-variables-for-mingw.html">post</a> if you don't know how to edit the PATH environment variable.<br />
<br />
<h4>
Linux</h4>
<br /></div>
<div style="text-align: justify;">
Grab the version 0.6.0 tarball from <a href="http://sourceforge.net/projects/openocd/files/latest/download?source=files">here</a>.</div>
<br />
<div style="text-align: justify;">
Untar the tarball.</div>
<br />
<div style="text-align: justify;">
Use the following installation commands:</div>
<div class="terminal">
sudo apt-get install libftdi-dev<br />
cd <path to the untared openocd tarball><br />
./configure --enable-ft2232_libftdi --enable-stlink<br />
make<br />
sudo make install
</div>
<div style="text-align: justify;">
You're done with the OpenOCD installation.<br />
<br />
<br />
<h3>
Git (Windows)</h3>
<br />
If you don't have Git installed. Grab the installer from <a href="http://git-scm.com/download/win">here</a>. Follow the installations steps, but choose the "Run Git from the Windows Command Prompt" instead of the default option.<br />
<br />
<h3>
Make (Windows)</h3>
<br />
Windows doesn't come with a "make" tool by default. The easiest way to get "make" is downloading this <a href="ftp://ftp.trolltech.com/misc/MinGW-gcc440_1.zip">MinGW (**)</a>. Then unzip the downloaded zip archive in your C drive.<br />
<br />
(**) The trolltech ftp server has been shutdown, luckily ShaoLin has posted a mirror on his Google Drive, check his <a href="http://nosymbolfound.blogspot.com/2012/12/since-until-now-qt-under-windows-is.html">post</a> for information on how to download MinGW.<br />
<br />
And append ";C:\mingw\bin" to your PATH variable. See this <a href="http://embeddedprogrammer.blogspot.com/2012/10/windows-environment-variables-for-mingw.html">post</a> if you don't know how to edit the PATH environment variable.<br />
<br /></div>
<h3>
The Eclipse Project Template</h3>
<br />
<br />
<div style="text-align: justify;">
Grab the Eclipse project template I have developed: <a href="https://github.com/JorgeAparicio/bareCortexM">bareCortexM</a></div>
<div class="terminal">
cd # choose some directory<br />
git clone https://github.com/JorgeAparicio/bareCortexM.git
</div>
<br />
<h3>
Importing the Eclipse Project</h3>
<br />
<div style="text-align: justify;">
In Eclipse, go to (File > Import).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In this window, select (General > Existing Project into Workspace).</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSwXkZTBl7tjtC6vYOOssdNXgCrdILjWQHYmGzeVEPnW7of1_QHCg9x_Qyts57HPPrBef6QUwxRtJ6VlhZOmId22r2oca3jjNhzUt7a9grN3qtFx1MNa-HLS3xVtqaudENtzpB7gZ-PMc/s1600/importProject.png" imageanchor="1"><img border="0" height="287" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSwXkZTBl7tjtC6vYOOssdNXgCrdILjWQHYmGzeVEPnW7of1_QHCg9x_Qyts57HPPrBef6QUwxRtJ6VlhZOmId22r2oca3jjNhzUt7a9grN3qtFx1MNa-HLS3xVtqaudENtzpB7gZ-PMc/s1600/importProject.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
In this new window, click the Browse button next to the "Select root directory" box and select the bareCortexM folder.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7-kmzcgyFNgHE8_2N0uw1H6u4Y1ww1oKQeiMbF0KqVvZ9qxltEDezU0m17e2kltczWudQLp8c0XZouk4DYIf0ZaAwJYCjvv3P9_54QmuAqe_uslX3Bq1gnOOA3nbBIb5T-ZfPpinwehY/s1600/importBareCortexM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7-kmzcgyFNgHE8_2N0uw1H6u4Y1ww1oKQeiMbF0KqVvZ9qxltEDezU0m17e2kltczWudQLp8c0XZouk4DYIf0ZaAwJYCjvv3P9_54QmuAqe_uslX3Bq1gnOOA3nbBIb5T-ZfPpinwehY/s320/importBareCortexM.png" width="293" /></a></div>
<br />
<div style="text-align: justify;">
In this project, go to the "src" folder and open the "main.cpp" file. You should see a single function named int main().</div>
<br />
<div style="text-align: justify;">
From the Eclipse menu select (Project > Properties).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In this windows, select the C/C++ Build.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Click the Manage Configuration button next to the Configuration combo box.</div>
<br />
<div style="text-align: justify;">
Select your platform and click the Set Active button. (By default the Linux platform is selected).</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigZgpjsEoad_bjWOBcNro7DvVVOPiAvJZWcdIaApF2Ekr8DkQcubuAO4p9POIjPqs_CH8H70JVsazcODhK9M7RyRDn7p3p3FdWOmUYva1qsgoat4Ayi6Ew6c5kppPWGDvQZBkwY2XCzs0/s1600/platformSelection.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="187" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigZgpjsEoad_bjWOBcNro7DvVVOPiAvJZWcdIaApF2Ekr8DkQcubuAO4p9POIjPqs_CH8H70JVsazcODhK9M7RyRDn7p3p3FdWOmUYva1qsgoat4Ayi6Ew6c5kppPWGDvQZBkwY2XCzs0/s320/platformSelection.png" width="320" /></a></div>
<br />
<b>** Windows</b>: Edit the (Eclipse > Project > Properties > C/C++ Build > Build command) to "mingw32-make" or whatever make you are using.<br />
<br />
<div style="text-align: justify;">
Now try building the project, if you correctly followed the previous steps the build should be successful.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDnDc-IGPkqCq1nHWWh4fHWoF9Ym026-o1m3XVlJpRmXlrjB0BddoVSQUZLJ08fEyYBXhgo2a3lbroIG1aHRBzAFKsa-ckQXsISmHRAdjQCHf1zKpmCosG6CexcBjPjbYYqUy8fBl9dw4/s1600/build.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDnDc-IGPkqCq1nHWWh4fHWoF9Ym026-o1m3XVlJpRmXlrjB0BddoVSQUZLJ08fEyYBXhgo2a3lbroIG1aHRBzAFKsa-ckQXsISmHRAdjQCHf1zKpmCosG6CexcBjPjbYYqUy8fBl9dw4/s320/build.png" width="320" /></a></div>
<br />
<h3>
Configuring the project for your target</h3>
<br />
<div style="text-align: justify;">
Before flashing your target (in this case the STM32F4DISCOVERY) it's necessary to configure the project for your specific target.</div>
<br />
<h4>
Linker Script selection</h4>
<br />
<div style="text-align: justify;">
The linker script contains the memory map of your target device.</div>
<br />
<div style="text-align: justify;">
In the Eclipse menu, go to (Project > Properties).</div>
<br />
<div style="text-align: justify;">
Now select C/C++ (Build > Settings).</div>
<br />
<div style="text-align: justify;">
Select (ARM Sourcery GCC C++ Linker > General).</div>
<br />
<div style="text-align: justify;">
Modify the file in the Script File text box, to match your target device.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYRlae73frmb1lZVhU6034GFYa_Z8fiMGBaTQLXw56WTyriqiuMqB49fNj7OvJuugYzngnIDx8Z_DwqYqvTa3kCBNMghtiVHnhoHXVPfuoYrszrZ66PGPySRy1DljFBS6ah6np0xiH-4g/s1600/linkerScript.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYRlae73frmb1lZVhU6034GFYa_Z8fiMGBaTQLXw56WTyriqiuMqB49fNj7OvJuugYzngnIDx8Z_DwqYqvTa3kCBNMghtiVHnhoHXVPfuoYrszrZ66PGPySRy1DljFBS6ah6np0xiH-4g/s320/linkerScript.png" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
You can see the list of supported devices in the linker folder.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTlTigCR2NE2Bmu-b7jP9fI9JuQPQvmDu5HIRULyNV2cCWdIMlf58uLyLX_lZbBqpD5plMVpM1uiIKT7it9SmVATrRMofbdZFsEfJtVKo0FDu8_J-PjIteY9_z6K7j4n16qCW_pSTkPC0/s1600/linkerScriptSupport.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTlTigCR2NE2Bmu-b7jP9fI9JuQPQvmDu5HIRULyNV2cCWdIMlf58uLyLX_lZbBqpD5plMVpM1uiIKT7it9SmVATrRMofbdZFsEfJtVKo0FDu8_J-PjIteY9_z6K7j4n16qCW_pSTkPC0/s320/linkerScriptSupport.png" width="135" /></a></div>
<br />
<h4>
OpenOCD interface/target configuration</h4>
<br />
<div style="text-align: justify;">
You'll need to tell OpenOCD which interface and target you plan to use.</div>
<br />
<div style="text-align: justify;">
In the Eclipse menu, (Run > External Tools > External Tool Configurations).</div>
<br />
<div style="text-align: justify;">
In this new window, select (Program > OpenOCD).</div>
<br />
<div style="text-align: justify;">
On the Main tab, make sure the OpenOCD location is correct. Then modify the arguments as necessary.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrSDqDaihJbP2R6DLUEEhTBGhwYz1_9-ku3Kez2JQm2N-hN1PfiAHu9xNqS16tjU0N2DR6sErQ8SQqCGXWpQoeAGprI0Wp3mjJINv1xYJ0BVu1cQz4E5fmhfXrB5upGGw3ZxnG8dMAQkY/s1600/OpenOCD+configuration.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrSDqDaihJbP2R6DLUEEhTBGhwYz1_9-ku3Kez2JQm2N-hN1PfiAHu9xNqS16tjU0N2DR6sErQ8SQqCGXWpQoeAGprI0Wp3mjJINv1xYJ0BVu1cQz4E5fmhfXrB5upGGw3ZxnG8dMAQkY/s320/OpenOCD+configuration.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
The first argument to modify is the interface: "-f openocd/interface/<your interface>.cfg". You can see the list of supported interfaces in the (openocd > interface) folder.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhN7SKt3VXZRubxt9syCuTR5GOwI6FDYbgy8uStBeDupw0XTXflDJoGBcNh_SsHbDZULPTey3miWM3EazptaheCe0_hgiKefmUlsQGlI_mJjnQ3bhoX9m7LsaTg0JdnwE9CIT7Op-P_bsk/s1600/interfaceSupport.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhN7SKt3VXZRubxt9syCuTR5GOwI6FDYbgy8uStBeDupw0XTXflDJoGBcNh_SsHbDZULPTey3miWM3EazptaheCe0_hgiKefmUlsQGlI_mJjnQ3bhoX9m7LsaTg0JdnwE9CIT7Op-P_bsk/s320/interfaceSupport.png" width="136" /></a></div>
<br />
<div style="text-align: justify;">
The second argument to modify is the target: "-f openocd/target/<your target>.cfg". You can see the list of supported targets in the (openocd > target) folder.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI3U8SHeE1wRTe-xsLwGfjbsRNgzLrP9HlMghVmDZe3UBAo5rMaxEXOw_HKUapUikGVuJmXYUHzWMgd6nG6CzPVfDbGgpbz-vCVkrsqfx1CF7-_u0r3JkWupUa8PwniubmLeoWY8t6UDI/s1600/targetSupport.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI3U8SHeE1wRTe-xsLwGfjbsRNgzLrP9HlMghVmDZe3UBAo5rMaxEXOw_HKUapUikGVuJmXYUHzWMgd6nG6CzPVfDbGgpbz-vCVkrsqfx1CF7-_u0r3JkWupUa8PwniubmLeoWY8t6UDI/s320/targetSupport.png" width="136" /></a></div>
<br />
<h4>
GDB script selection</h4>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The GDB script contains the flash and debug information.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In the Eclipse menu, go to (Run > Debug Configurations).</div>
<br />
<div style="text-align: justify;">
In this new window, select (Zylin Embedded debug (Native) > Flash and Debug).</div>
<br />
<div style="text-align: justify;">
On the Debugger tab, you'll need to select an appropriate GDB script in the GDB command file text box.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieOOmEgcCdCzRLkOm38mqN7KHValifP4CY_kp_vvUBHE3K8GiolcY9MADsfBPoFrZau4yvvb88mlkVyaD1meihmvIchLJUO5bqpZzb6JQZpUsJI8VqcjpqFRGYB7GKVjBpFHDogsbmlPA/s1600/gdbScriptSelection.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieOOmEgcCdCzRLkOm38mqN7KHValifP4CY_kp_vvUBHE3K8GiolcY9MADsfBPoFrZau4yvvb88mlkVyaD1meihmvIchLJUO5bqpZzb6JQZpUsJI8VqcjpqFRGYB7GKVjBpFHDogsbmlPA/s320/gdbScriptSelection.png" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
You can see the list of supported devices in the gdb folder.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjO133VyZM-wyjUP8k69Wv0_vsWe4G2-o5VNH5v0zhkFyjzs-8wnSVB9855-mxqoKPVz1kaGJmeZMLe3FXl01pGmKaai-irrzX23ZsGyusVN7AXWkOfKCW9z-jUDxfHoauPNyxZeM4VRzg/s1600/gdbScriptSupport.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjO133VyZM-wyjUP8k69Wv0_vsWe4G2-o5VNH5v0zhkFyjzs-8wnSVB9855-mxqoKPVz1kaGJmeZMLe3FXl01pGmKaai-irrzX23ZsGyusVN7AXWkOfKCW9z-jUDxfHoauPNyxZeM4VRzg/s320/gdbScriptSupport.png" width="136" /></a></div>
<br />
<br />
<h4>
Configuration table</h4>
<br />
<table border="1">
<tbody>
<tr>
<th>Board</th>
<th>Linker Script<br />
(.ld)</th>
<th>Interface<br />
(.cfg)</th>
<th>Target<br />
(.cfg)</th>
<th>GDB Script<br />
(.script)</th>
</tr>
<tr>
<td style="text-align: center;">STM32VLDISCOVERY⁽¹⁾</td>
<td style="text-align: center;">stm32f100rb</td>
<td style="text-align: center;">stlink-v1</td>
<td style="text-align: center;">stm32f1x_stlink</td>
<td style="text-align: center;">stm32vldiscovery</td>
</tr>
<tr>
<td style="text-align: center;">STM32F4DISCOVERY</td>
<td style="text-align: center;">stm32f407vg</td>
<td style="text-align: center;">stlink-v2</td>
<td style="text-align: center;">stm32f4x_stlink</td>
<td style="text-align: center;">stm32f407vg⁽²⁾</td>
</tr>
<tr>
<td style="text-align: center;"><a href="http://embeddedprogrammer.blogspot.com/2012/08/f4dev-open-source-development-board-for.html">F4Dev</a></td>
<td style="text-align: center;">stm32f407ve</td>
<td style="text-align: center;"><a href="http://embeddedprogrammer.blogspot.com/2012/08/ujtag-open-source-minimalistic-jtag.html">ujtag</a></td>
<td style="text-align: center;">stm32f4x</td>
<td style="text-align: center;">stm32f407ve⁽²⁾</td>
</tr>
</tbody></table>
<br />
<div style="text-align: justify;">
⁽¹⁾: Flash protection must be disabled (probably using other JTAG dongle) before using this configuration.</div>
<div style="text-align: justify;">
⁽²⁾: You can use other scripts like: stm32f4_16kb, stm32f4_32kb, etc. for faster flashing.</div>
<div style="text-align: justify;">
<br /></div>
<h3>
The first program</h3>
<br />
<div style="text-align: justify;">
Let's flash your first program into the STM32F4DISCOVERY.</div>
<br />
<div style="text-align: justify;">
Copy the following code in the main.cpp source file.</div>
<script class="brush:cpp" type="syntaxhighlighter">
<![CDATA[
int foo = 0;<br /><br />int main()<br />{<br /> while (true) {<br /> foo ++;<br /> }<br />}<br />
]]>
</script>
<br />
<div style="text-align: justify;">
Build the program, and then click the OpenOCD action in the External Tool menu (The green play + red toolbox icon) or go to (Menu > Run > External Tools > OpenOCD).</div>
<br />
And...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3pTUiqIy2ZhJr1cQaigRZJI_PWAO1L6zv5gdZ0dsLIb8JZkZr8K_W6J3F1x31Wc3fwUxRc5XKZWoAaLr9QZZWvUl26KYCnz18gyudY28VMwyaK2Ah5f4K9JZHSU9mP8el9pzzlJBo8KY/s1600/permissionDenied.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3pTUiqIy2ZhJr1cQaigRZJI_PWAO1L6zv5gdZ0dsLIb8JZkZr8K_W6J3F1x31Wc3fwUxRc5XKZWoAaLr9QZZWvUl26KYCnz18gyudY28VMwyaK2Ah5f4K9JZHSU9mP8el9pzzlJBo8KY/s320/permissionDenied.png" width="320" /></a></div>
<div style="text-align: center;">
What the...?</div>
<br />
<div style="text-align: justify;">
If you are a Linux user, you'll probably bump into that error. You'll need to give permission to your interface device, this way a non-rooted Eclipse will be able to flash and debug the target device.</div>
<br />
<h3>
USB Permissions/Drivers</h3>
<br />
<h4>
Windows (for FTDI devices)</h4>
<br />
Grab the <a href="http://sourceforge.net/projects/libusb-win32/files/latest/download?source=files">libusb-win32</a> library. Unzip the downloaded zip archive in your C drive. Enter in the uncompressed folder, then enter into the bin folder and execute the <i>inf-wizard</i>.<br />
<br />
Follow the instructions, select the right device ("Single RS232-HS" or similar) from the list. Save the .inf file anywhere and finally select Install Now.<br />
<br />
<h4>
Linux</h4>
<br />
<div style="text-align: justify;">
To grant permission to your interface device you'll have create a file using the following command.</div>
<br />
<div class="terminal">
gksudo gedit /etc/udev/rules.d/33-openocd.rules</div>
<br />
<div style="text-align: justify;">
(You can choose any other number, instead of 33)</div>
<br />
<div style="text-align: justify;">
In this new file you'll need to add the following text:</div>
<div style="text-align: justify;">
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
#FT232<br />ATTRS{idProduct}=="6014", ATTRS{idVendor}=="0403", MODE="666", GROUP="plugdev"<br /><br />#FT2232<br />ATTRS{idProduct}=="6010", ATTRS{idVendor}=="0403", MODE="666", GROUP="plugdev"<br /><br />#FT230X<br />ATTRS{idProduct}=="6015", ATTRS{idVendor}=="0403", MODE="666", GROUP="plugdev"<br /><br />#STLINK V1<br />ATTRS{idProduct}=="3744", ATTRS{idVendor}=="0483", MODE="666", GROUP="plugdev"<br />
#STLINK V2<br />ATTRS{idProduct}=="3748", ATTRS{idVendor}=="0483", MODE="666", GROUP="plugdev"
]]>
</script>
This will give permission to all the FTDI based JTAG-dongles and to the ST-LINK v2 JTAG interface present in the STM32F4DISCOVERY.</div>
<br />
If you are using or planning to use the STM32VLDISCOVERY, then you need these additional steps:<br />
<br />
<div class="terminal">
gksudo gedit /etc/modprobe.d/stlink_v1.conf</div>
<br />
Inside that new file, insert the following text:<br />
<br />
<script class="brush:bash" type="syntaxhighlighter">
<![CDATA[
options usb-storage quirks=483:3744:i
]]>
</script>
<br />
<div style="text-align: justify;">
NOTE: Currently, ST-LINK v1 via OpenOCD can't modify the target device flash protection. This means, that if your STM32VLDISCOVERY has its flash protection enabled, you won't be able to flash it. On the other hand, if you manage to disable the flash protection using other JTAG dongle, then you'll be able to use the ST-LINK v1 connection. OpenOCD will probably provide better support for ST-LINK v1 in the future.<br />
<br />
A reboot is necessary to update the last changes.</div>
<br />
<div style="text-align: justify;">
After that, the permission problem should be fixed.</div>
<br />
<h3>
Back to the first program</h3>
<br />
<div style="text-align: justify;">
As before, launch OpenOCD. You should get the following output this time.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxSDPtxX7yFI5_AXqC-7pvQfgMevWjJc6XGk2CmdtkoL_u_lET7Es7LIgPKBFMYB6mA0YzinJ7nVgJeAoGIUJPtdxSQSFGpGmGJiwimvuWgaFQpOfbtrlDyxDqQlXxZvhKujeR-wAs768/s1600/openOCD.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxSDPtxX7yFI5_AXqC-7pvQfgMevWjJc6XGk2CmdtkoL_u_lET7Es7LIgPKBFMYB6mA0YzinJ7nVgJeAoGIUJPtdxSQSFGpGmGJiwimvuWgaFQpOfbtrlDyxDqQlXxZvhKujeR-wAs768/s320/openOCD.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
That X breakpoints and Y watchpoints is the equivalent of success. Now that you have established a link between your PC and the microcontroller, you can begin the flash and debug session.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Click the Flash and Debug action in the Debug menu (the green bug icon). The flashing process will start, and it will take a while... around 20s (if you using a device with big flash memory, otherwise it's faster).</div>
<br />
<div style="text-align: justify;">
NOTE: Actually flashing your program is quite fast, since is probably around 200-300 bytes, what takes so much time is erasing the old memory. The whole flash memory get erased before writing the new program. You can achieve faster flashing times if you only "use" a fraction of the memory, when using scripts like stm32f4_16kb, stm32f4_32kb, etc.</div>
<br />
<div style="text-align: justify;">
After the flashing is over, you'll go into the debug session. You'll be prompted if you want to change to the Debug perspective, answer yes.</div>
<br />
<h3>
Debugging 101</h3>
<br />
<div style="text-align: justify;">
Let's do some debugging now. First, let's examine this new perspective.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFtNJIjqgJN_Rdy_LKTCH5Y3-WgXYjpiedFFMkDwEaJ37cFR8lALH9PKrTm7ehHupXS6rI4ONqyIrO1CofsqcpXXU22uRlpQX6dwH2u1Yctn7oG3CjqaW5Ps8ito6iebXspGZTzzYSvtA/s1600/debug.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="167" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFtNJIjqgJN_Rdy_LKTCH5Y3-WgXYjpiedFFMkDwEaJ37cFR8lALH9PKrTm7ehHupXS6rI4ONqyIrO1CofsqcpXXU22uRlpQX6dwH2u1Yctn7oG3CjqaW5Ps8ito6iebXspGZTzzYSvtA/s320/debug.png" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In the top left window, you'll see Debug window. Inside this window you'll see Thread 1, this is the program that's currently running, notice that it says suspended, this means that the ARM core is halted. Also, below Thread 1 you can see the stack of functions called, right now it says the program is at 0x00000000, this is because the JTAG interface hasn't asked for information yet.</div>
<br />
<div style="text-align: justify;">
Also in the debug window you can see some buttons, that I have labelled from 1 to 7. Now I'll cover what they do:</div>
<br />
<table border="1">
<tbody>
<tr>
<th>N</th>
<th>Button</th>
<th>Description</th>
</tr>
<tr>
<td style="text-align: center;">1</td>
<td style="text-align: center;">Resume (F8)</td>
<td style="text-align: justify;">Leaves the suspended status.</td>
</tr>
<tr>
<td style="text-align: center;">2</td>
<td style="text-align: center;">Suspend</td>
<td style="text-align: justify;">Halts the program execution.</td>
</tr>
<tr>
<td style="text-align: center;">3</td>
<td style="text-align: center;">Terminate (Ctrl + F2)</td>
<td style="text-align: justify;">Finishes the program.</td>
</tr>
<tr>
<td style="text-align: center;">4</td>
<td style="text-align: center;">Step into (F5)</td>
<td style="text-align: justify;">Goes (if possible) into the current subroutine.</td>
</tr>
<tr>
<td style="text-align: center;">5</td>
<td style="text-align: center;">Step over (F6)</td>
<td style="text-align: justify;">Executes the current line of code and moves onto the next.</td>
</tr>
<tr>
<td style="text-align: center;">6</td>
<td style="text-align: center;">Step return (F7)</td>
<td style="text-align: justify;">Leaves the current subroutine.</td>
</tr>
<tr>
<td style="text-align: center;">7</td>
<td style="text-align: center;">Instruction Stepping Mode</td>
<td style="text-align: justify;">Enables/disables the instruction stepping mode. (Disabled by default)</td>
</tr>
</tbody></table>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Ok, now hit the Resume button and then click the Suspend button. You'll end in a state similar to the following image.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNR6y-cQtH-zChLh8yX4ExcX_FMZiCoOZJZ0rQaT355i1IRaDGgWvyK9nDbspBP7wV8uuLQhWqGQ_XWm7QDpDvJYpxpPFTOyd6bdb7c2Keiv2bYAKLTNXqSqdzV1qiaNEqV2fBPYnKYuw/s1600/debug2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="169" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNR6y-cQtH-zChLh8yX4ExcX_FMZiCoOZJZ0rQaT355i1IRaDGgWvyK9nDbspBP7wV8uuLQhWqGQ_XWm7QDpDvJYpxpPFTOyd6bdb7c2Keiv2bYAKLTNXqSqdzV1qiaNEqV2fBPYnKYuw/s320/debug2.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
You can see that the middle left window changed, and now is showing the main.cpp file. Also, there is a highlighted line, this is where the halted program currently is. You can also see the disassembly of the current program in the middle right window, if you can't, then you can enable the disassembly from (Menu > Window > Show View > Disassembly).</div>
<br />
<div style="text-align: justify;">
NOTE: Read this note if your program ends in the defaultExceptionHandler() function instead.
This is a common error (bug?) that appears when you are using ST-LINK
connections (in the STM32VLDISCOVERY or STM32F4DISCOVERY). In this case, terminate (red square button) the debug session and the OpenOCD connection. And then do the build > launch OpenOCD > start debug session process again.</div>
<br />
<div style="text-align: justify;">
Let's watch some variables now, select the Variables tab of the top right window and right click the empty space, then click on Add Global Variables.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioisZyTNQAPpYawf-KR5hjxgc2QrFgA9rksdhYbzntgDFijVO7GuhJ7HsgwxDU6AU8G5hT0zaeSMYg8GvNqXKVchVk-89Nc911Gz7aufAeee51gedEqeQ1i0iS7RjWwKX0aZXh1bezMtE/s1600/debug3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="169" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioisZyTNQAPpYawf-KR5hjxgc2QrFgA9rksdhYbzntgDFijVO7GuhJ7HsgwxDU6AU8G5hT0zaeSMYg8GvNqXKVchVk-89Nc911Gz7aufAeee51gedEqeQ1i0iS7RjWwKX0aZXh1bezMtE/s320/debug3.png" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Check the foo variable and then click OK. You can now watch the value of foo. Try resuming the program for a while and then suspend it again. You should see a noticeable increment in the value of foo.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiieXai7_FQs300HO6XZf6MrpneCLOJfb-C7tDuAdiLSV7-zDKtZzWxqKVtSkI3yLhX3Zu3THxzrhOtzG8BgIoxRdvyte1p-DekFtWBjHe087a8JsDD_vWqrQNAb2TGrXx_1v1w_Qg0mWg/s1600/debug4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="169" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiieXai7_FQs300HO6XZf6MrpneCLOJfb-C7tDuAdiLSV7-zDKtZzWxqKVtSkI3yLhX3Zu3THxzrhOtzG8BgIoxRdvyte1p-DekFtWBjHe087a8JsDD_vWqrQNAb2TGrXx_1v1w_Qg0mWg/s320/debug4.png" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now, let's see how breakpoints work. Right click the line 27 (it doesn't matter if you can't see the line number) and select Toggle Breakpoint. Now hit the Resume button.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh81zxnDnA5y5Gb6v6uEY61nBFfKyx1ybJuRc-ddb9PS9X82u3NgWZ6xHEzwG8ENnpmyvp2sJlOEMx53YmtUnyrqhWLAiK-c-tWcuug4RJNu6_FjLTIhAIYTTL_BVMgZeI7ePOFxjSUc5k/s1600/debug5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh81zxnDnA5y5Gb6v6uEY61nBFfKyx1ybJuRc-ddb9PS9X82u3NgWZ6xHEzwG8ENnpmyvp2sJlOEMx53YmtUnyrqhWLAiK-c-tWcuug4RJNu6_FjLTIhAIYTTL_BVMgZeI7ePOFxjSUc5k/s320/debug5.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
The program will stop as soon as it reaches the breakpoint, you'll notice that foo's value increased in one.</div>
<br />
<div style="text-align: justify;">
Let's terminate the program (Flash and Debug) and then terminate the OpenOCD session and jump into something more interesting.</div>
<br />
<h3>
Blinking a LED</h3>
<br />
<div style="text-align: justify;">
bareCortexM is a barebone project template, you'll need a peripheral library to do more than just numerical operations. This is where <a href="https://github.com/JorgeAparicio/libstm32pp">libstm32pp</a> comes in.</div>
<br />
<h4>
Adding the libstm32pp library to the project</h4>
<br />
<div style="text-align: justify;">
Let's place the libstm32pp project inside the bareCortexM project.</div>
<br />
<div class="terminal">
cd <path to bareCortexM><br />
git clone https://github.com/JorgeAparicio/libstm32pp.git
</div>
<br />
<div style="text-align: justify;">
Go back to eclipse, and right click the project name (bareCortexM) and select the Refresh action. You should see the libstm32pp folder inside the project.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0OdJZupLBjDI4FI97gjlQkqxGLZ4rk_7B8agGnNqBHenQaza3sdpoeSqPi1n9LISfop15iNPBwnmn08MvrtvAntEHYSg1JunLZlZfYR-R8AMcYCuz4lWVcGGMBQPKB-aU24b547ihoPY/s1600/bareCortexM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0OdJZupLBjDI4FI97gjlQkqxGLZ4rk_7B8agGnNqBHenQaza3sdpoeSqPi1n9LISfop15iNPBwnmn08MvrtvAntEHYSg1JunLZlZfYR-R8AMcYCuz4lWVcGGMBQPKB-aU24b547ihoPY/s320/bareCortexM.png" width="135" /></a></div>
<br />
<div style="text-align: justify;">
Now, you'll need to add the library to the include path.</div>
<br />
<div style="text-align: justify;">
In Eclipse menu, go to (Project > Properties).</div>
<br />
<div style="text-align: justify;">
Go to (C/C++ General > Paths and Symbol).</div>
<br />
<div style="text-align: justify;">
In the Includes tab, select the GNU C++ in languages and then click the Add button.</div>
<br />
<div style="text-align: justify;">
In this new window, click the Workspace button and select the (libstm32pp > include) folder.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjiKRuVT936ymOVyuuM1IseDiURGIMGDaCipFT17Pk_yyYEDq31PJRoV4i3Rjklwxk8IPYZ8J7EZtNqPeI_t8bTUDAypiWDUw18by0Y8utlJqL4khFpotcn9wl9juy4c1MF8n2FdmOmdk/s1600/includePath.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="171" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjiKRuVT936ymOVyuuM1IseDiURGIMGDaCipFT17Pk_yyYEDq31PJRoV4i3Rjklwxk8IPYZ8J7EZtNqPeI_t8bTUDAypiWDUw18by0Y8utlJqL4khFpotcn9wl9juy4c1MF8n2FdmOmdk/s320/includePath.png" width="320" /></a></div>
<br />
<h4>
Configuring the library</h4>
<br />
<div style="text-align: justify;">
You'll need to configure the library to match your target, head to the (libstm32pp > include) folder and open the device_select.hpp. There you can select your target's family by commenting and uncommenting the defines in that file.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM7QfBoFnVA8ouF6WS735g5NF42SVpOsaPFFbrHsMrzMeXTCcvtNnf8BtBA_Bqdv55qSGy-V1vEuYO92rcXZt2ZdisHRnbL26VN_5T5fZQFCL8lTJKStPOazwCm_2wXSsXAlCX2WXnkUE/s1600/deviceSelection.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="214" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM7QfBoFnVA8ouF6WS735g5NF42SVpOsaPFFbrHsMrzMeXTCcvtNnf8BtBA_Bqdv55qSGy-V1vEuYO92rcXZt2ZdisHRnbL26VN_5T5fZQFCL8lTJKStPOazwCm_2wXSsXAlCX2WXnkUE/s320/deviceSelection.png" width="320" /></a></div>
<br />
<h4>
Using the library</h4>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Go into the (libstm32pp > demo) folder and open the gpio_pin.hpp file. Copy the content to your main.cpp file. You can change the LED pin from PA0 to any other pin you wish. For the STM32F4DISCOVERY you can select PD12, PD13, PD14 or PD15 to use the user LEDs available in the board. For the STM32VLDISCOVERY use the PC8 and PC9 instead.</div>
<br />
<div style="text-align: justify;">
After that, build, launch OpenOCD and start the debugging session.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQH1UkmP_PC2CfcFFi4OZZGl-1v70epGjdk-cBzqzoeaUWQmXfi6YkJRIU4xmrrvzSMOm4erfzR8nbO-mVgw0dGyJD8_VWOkGGKVfuWqLZMQBAJGoCa1LUH_Ra5XnkSKZDIPpE74wQ_iQ/s1600/ledDemo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQH1UkmP_PC2CfcFFi4OZZGl-1v70epGjdk-cBzqzoeaUWQmXfi6YkJRIU4xmrrvzSMOm4erfzR8nbO-mVgw0dGyJD8_VWOkGGKVfuWqLZMQBAJGoCa1LUH_Ra5XnkSKZDIPpE74wQ_iQ/s320/ledDemo.png" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUFJ48b5IOjacKgVyS5N1hJHihKIbfRWa1lacTQOk4XoNBxop3jUdSN7CrxBGpIwbxXLHvTzKiKTReTlGGmvTGRufP8H91hs4OtgbwxXJ0PGB2scXRtXNaYU-c0EDrGPpSmH-GOrRw85Q/s1600/orangeLED.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUFJ48b5IOjacKgVyS5N1hJHihKIbfRWa1lacTQOk4XoNBxop3jUdSN7CrxBGpIwbxXLHvTzKiKTReTlGGmvTGRufP8H91hs4OtgbwxXJ0PGB2scXRtXNaYU-c0EDrGPpSmH-GOrRw85Q/s320/orangeLED.JPG" width="320" /></a></div>
<br />
<h3>
Configuring the Clock</h3>
<br />
<div style="text-align: justify;">
If you want to configure your device clock head to the (libstm32pp
> include) folder and open the clock.hpp file. As in device_select.hpp, by
commenting / uncommenting defines you can configure the clock to fit
your needs.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEwvSZ6kTV3Q0yEsCwkiAejlH6HiLHNNLbvL7-2OEhKr2uhJR0IGNZWvMuJXTldJWC6QzpSYgLZ5CzE6SZX58kbjbpkJIUFBi6iATAixFrkpVzXWZ84rvlVTTaCevGGMvA2ApS0E7COhI/s1600/clockConfiguration.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="162" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEwvSZ6kTV3Q0yEsCwkiAejlH6HiLHNNLbvL7-2OEhKr2uhJR0IGNZWvMuJXTldJWC6QzpSYgLZ5CzE6SZX58kbjbpkJIUFBi6iATAixFrkpVzXWZ84rvlVTTaCevGGMvA2ApS0E7COhI/s320/clockConfiguration.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
The clock will be configured when you call the function clk::initialize(). You should call this function as earlier as possible in your main function. If you are using any of the external crystals/oscillators (HSE or LSE) then you'll need to define the functions: clk::hseFailureHandler and clk::lseFailureHandler. These functions will be called in case the external oscillators doesn't stabilize in some time as dictated by HSE_TIMEOUT and LSE_TIMEOUT.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZbTn3TDGJWfzto94icDQ_xZp1kHgsAv2aPY3fe_BuJb_nYlc8aNtorIk08yoqkcc5gq_EOyzvCQMvqg-LGAhFPjdaF9qAhTNxdU60keyjbokF7KPcAN59x-EVLe30xkWnCdyqVZS02a8/s1600/clockInitialize.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="165" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZbTn3TDGJWfzto94icDQ_xZp1kHgsAv2aPY3fe_BuJb_nYlc8aNtorIk08yoqkcc5gq_EOyzvCQMvqg-LGAhFPjdaF9qAhTNxdU60keyjbokF7KPcAN59x-EVLe30xkWnCdyqVZS02a8/s320/clockInitialize.png" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The STM32 microcontrollers use various buses (AHB, APB) to move data between the processor and the peripherals. These buses define the operating frequency of various peripherals and these buses can be clocked at different frequencies. All this configuration is carried in the clock.hpp file, you can check the final frequencies using the cPrint statement:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglvS4pZPI2_4cjX7X5FmX8naiFVtFa7Bhx2IjGLIKs5Fiq1k9eusPgjeH8zK6LLwDoXH__POimmW4yhK9BpoE8_bfjVJWXUl0fJNgpLvGcxXZ8RytF-a341TShV8Kifiet905IT-xB8RM/s1600/cPrint.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglvS4pZPI2_4cjX7X5FmX8naiFVtFa7Bhx2IjGLIKs5Fiq1k9eusPgjeH8zK6LLwDoXH__POimmW4yhK9BpoE8_bfjVJWXUl0fJNgpLvGcxXZ8RytF-a341TShV8Kifiet905IT-xB8RM/s320/cPrint.png" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The cPrints statement prints its argument as an error. In the above image I used the cPrint statement to print the value of clk::AHB which the working AHB frequency. You can use cPrint to print other compile time known values, as cPrint creates an error, be sure to remove it or comment it after using it.</div>
<br />
<div style="text-align: justify;">
NOTE: As far as I know, the STM32F4 devices from the revision "A" can't use the ART accelerator (see the errata sheet <a href="http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/ERRATA_SHEET/DM00037591.pdf">here</a>), for these devices the LATENCY parameter is important when configuring the clock. From my observations the following latencies work well:</div>
<br />
<table align="center" border="1">
<tbody>
<tr>
<th>Clock Frequency (AHB)</th>
<th>LATENCY</th>
<th>Comment</th>
</tr>
<tr>
<td style="text-align: center;">Up to 42 MHz</td>
<td style="text-align: center;">Zero</td>
<td>Solid Rock Stable.</td>
</tr>
<tr>
<td style="text-align: center;">From 42 Mhz to 84 MHz</td>
<td style="text-align: center;">One</td>
<td>Seems stable.</td>
</tr>
<tr>
<td style="text-align: center;">168 MHz</td>
<td style="text-align: center;">Three</td>
<td>Some WTFs when using interrupts and enabling optimization.</td>
</tr>
</tbody></table>
<br />
NOTE: 84 MHz and latency one SHOULD be equivalent to 42 MHz, since the uC will execute one instruction and wait one cycle before executing the next instruction. However, when you take in consideration that instructions can take more than one cycle (e.g. FPU operations) and program jumps (due to functions and interrupts), calculating the "real" operating frequency gets really hard. <br />
<br />
My recommendation: Stick to 42 MHz max with zero latency while developing your application. After everything works fine, try increasing the clock and try different values for the latency until you get something stable. Then check if you are actually getting better performance on the AHB bus peripherals.<br />
<br />
<h3>
Handling interrupts</h3>
<br />
<div style="text-align: justify;">
The most important feature in every microcontroller are the interrupts. With these interrupts the microcontroller can handle various internal/external events as they come by.</div>
<br />
<div style="text-align: justify;">
To enable interrupts you'll need to map the interrupt handlers in memory. I've already done this job, so you only need to include "interrupt_cpp.hpp" file in the "interrupts.cpp" source file (this is in the src folder).</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKFkWRbMTivKez23YzIbDhX8fvw0COfwmbgoZ6AZuBh4-wPqMZZs3rkHqFUoVWGCK4fx8o_0kIl_m6XdYU3su-66Ly_OBapBYGQ2WIVFEsESoEAjgJTMbqx_iSuVArV-YbOdWrf2un2u8/s1600/interrupts.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKFkWRbMTivKez23YzIbDhX8fvw0COfwmbgoZ6AZuBh4-wPqMZZs3rkHqFUoVWGCK4fx8o_0kIl_m6XdYU3su-66Ly_OBapBYGQ2WIVFEsESoEAjgJTMbqx_iSuVArV-YbOdWrf2un2u8/s320/interrupts.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Let's try a demo now, go to the (libstm32pp > demo) folder and open the tim_blink_led.hpp file, or if you are using a STM32F4DISCOVERY go to (libstm32pp > demo > f4discovery) folder and open the led_wheel.hpp file. Copy the content of the file to main.cpp.</div>
<br />
<div style="text-align: justify;">
In the tim_blink_led demo you might want to change the LED from PA0 to some other pin. In either demo you can change the LED blink frequency by changing the configurePeriodicInterrupt function argument.</div>
<br />
<div style="text-align: justify;">
Build, launch OpenOCD and start the debugging session.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsC-I9RA0WJYi6HPVX6HUZLaclDhPgcHCo-vGbFKvttG1GmxjKXk9iITuaUhWVNW3QODSCTpnyHr2pV971mDE-9FQTRUaWWJbDo_j4hIae2MRxlk4nGJ92QiGaYKN3OoN3S-VSuuo8QwE/s1600/ledWheel.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsC-I9RA0WJYi6HPVX6HUZLaclDhPgcHCo-vGbFKvttG1GmxjKXk9iITuaUhWVNW3QODSCTpnyHr2pV971mDE-9FQTRUaWWJbDo_j4hIae2MRxlk4nGJ92QiGaYKN3OoN3S-VSuuo8QwE/s320/ledWheel.JPG" width="320" /></a></div>
<div style="text-align: center;">
LED Wheel demo @ 16Hz</div>
<br />
<h3>
New, delete and printf</h3>
<br />
<div style="text-align: justify;">
Since you're developing in C++, it's possible to use the operators new, delete and input/output functions like printf. You can also use the cout function, but it takes too much flash memory, so I'll recommend using printf instead.</div>
<br />
<div style="text-align: justify;">
To enable these functions, you'll need to define the system calls. The system calls are hardware dependant standard functions like read, write, close, start, exit, sbrk, etc. libstm32pp provides a minimal implementation, which is enough to use the new, delete and printf functions.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
To enable the system calls, you'll need to include the "system_call_cpp.hpp" file in the "system_call.cpp" source file (located in the src folder).</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixxK8KyPIgNeQsEw3FNCQQVxKV_NghcAK9gpTQvWf8szcRkuoDi32A00k5yaKf7otjD5KO72JpLzxIJV_ln0eJrfbjEbAgm9TgA5ATMF9m__E-Vx537ymkWgMdUPBhtJCBbGXZN6Wtfyc/s1600/systemCall.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="166" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixxK8KyPIgNeQsEw3FNCQQVxKV_NghcAK9gpTQvWf8szcRkuoDi32A00k5yaKf7otjD5KO72JpLzxIJV_ln0eJrfbjEbAgm9TgA5ATMF9m__E-Vx537ymkWgMdUPBhtJCBbGXZN6Wtfyc/s320/systemCall.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Also you'll need to enable the startup libraries.</div>
<br />
<div style="text-align: justify;">
In Eclipse, go to (Menu > Project > Properties).</div>
<br />
<br />
<div style="text-align: justify;">
Go to (C/C++ Build > Settings).</div>
<br />
<div style="text-align: justify;">
In the Tool Settings tab, go to (ARM Sourcery GCC C++ Linker > General).</div>
<br />
<div style="text-align: justify;">
Uncheck the "No startup or default libraries".</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXK6x6lZyCKx-93oDYAyCxUzqsmDFJbq5c_MGMGE7-vF1a4WqH161EURHuuyBf2QuDR7MeuxSj5fVkiNxsYMtBh00-guy3migSBZD5oO7vqdm0dMoYmq7joYxL1N6lB7ctrEUS0jFxncw/s1600/startupLibraries.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXK6x6lZyCKx-93oDYAyCxUzqsmDFJbq5c_MGMGE7-vF1a4WqH161EURHuuyBf2QuDR7MeuxSj5fVkiNxsYMtBh00-guy3migSBZD5oO7vqdm0dMoYmq7joYxL1N6lB7ctrEUS0jFxncw/s320/startupLibraries.png" width="320" /></a></div>
<br />
<h4>
new demo</h4>
<br />
<div style="text-align: justify;">
Let's do a quick demo about the new operator. Write in your main.cpp source file the following code:</div>
<div style="text-align: justify;">
<script class="brush:cpp" type="syntaxhighlighter">
<![CDATA[
#define SIZE 10<br />int *foo;<br /><br />int main()<br />{<br /> foo = new int[SIZE];<br /><br /> for (int i = 0; i < SIZE; i++)<br /> foo[i] = 0;<br /><br /> while (true) {<br /> for (int i = 0; i < SIZE; i++)<br /> foo[i]++;<br /> }<br />}
]]>
</script>
Build, run OpenOCD and start a debugging session as usual.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl8WlRhDnzwWhITcPXrjG2OmGZFeKEddhMP0MYYrrwCmuSKq-qNFGt1vHGgP7JZ7CzzR9YQTQzPzH0csqhTcgxv7JD19wbR-Vs0lzk4rocGlnmThgg49HP1Q92FUOzk0zb5fxSA4RSp_0/s1600/newDemo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl8WlRhDnzwWhITcPXrjG2OmGZFeKEddhMP0MYYrrwCmuSKq-qNFGt1vHGgP7JZ7CzzR9YQTQzPzH0csqhTcgxv7JD19wbR-Vs0lzk4rocGlnmThgg49HP1Q92FUOzk0zb5fxSA4RSp_0/s320/newDemo.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
The first thing you'll notice is that this small program takes around 90KB of flash. That's the price to pay for using dynamically allocated memory. If you watch the foo variable after running the program for some time, you'll notice that the pointer has a value around 0x20000000, this is the address that the new operator assigned it and also you can see the value stored in that address, which would be the first element of the array.</div>
<br />
<h4>
printf demo</h4>
<br />
<div style="text-align: justify;">
There is a printf demo in the (libstm32pp > demo) folder. You can use printf with any of the 6 UART modules, which needs to be specified in the system_call.hpp file (this is in the (libstm32pp > include) folder). You'll also need a USB <-> UART converter to get the UART output into your PC. In your PC, you'll need a serial port terminal emulator like minicom or <a href="http://embeddedprogrammer.blogspot.com/2012/06/qserialterm-qt-based-serial-port.html">qSerialTerm</a>.</div>
<br />
<h3>
Optimization</h3>
<br />
<div style="text-align: justify;">
Finally, let's cover how to do optimization.</div>
<br />
<div style="text-align: justify;">
In eclipse, go to (Menu > Project > Properties).</div>
<br />
<div style="text-align: justify;">
Go to (C/C++ Build > Settings).</div>
<br />
<div style="text-align: justify;">
In the Tool Settings tab, go to (ARM GCC C++ Compiler > Optimization).</div>
<br />
<div style="text-align: justify;">
Select in the Optimization Level, the option that fits your need.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYB4TG6n4nbFVl1rERvT-64bPyQ9A6wctOPEIJxMYEi0838Cjl6IoomTsQr2XpAziQ9eFT7MYVbo7__pPBbEzSvDPeLnkOzIZ5FU4ECIkQhN1eIvfF7Pkb6yrtYGKrwSZH8Hjl89v7ET0/s1600/optimization.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYB4TG6n4nbFVl1rERvT-64bPyQ9A6wctOPEIJxMYEi0838Cjl6IoomTsQr2XpAziQ9eFT7MYVbo7__pPBbEzSvDPeLnkOzIZ5FU4ECIkQhN1eIvfF7Pkb6yrtYGKrwSZH8Hjl89v7ET0/s320/optimization.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
My recommendation: When developing an application, I recommend working with the optimization turned off and turning it on after you have finished developing. This is because the optimization will complicate the debugging process, as the compiler will optimize out some variables and also some breakpoints might misbehave.</div>
<br />
<h3>
Feedback is welcome</h3>
<br />
<div style="text-align: justify;">
There are many other demos inside the (libstm32pp > demo) folder. Please check them and inform me if you find any bug. I'll appreciate your feedback. Thanks.</div>
</div>
Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com144tag:blogger.com,1999:blog-1622983275835621655.post-7068606456762048462012-09-07T12:46:00.001-05:002012-09-07T12:46:38.274-05:00qSerialTerm: Qt based Serial Port Image Viewer<div style="text-align: justify;">
qSerialTerm, an open source Qt based Serial Port interface software, can now be used to view images streamed via a Serial Port.</div>
<br />
<div style="text-align: justify;">
Currently, qSerialTerm supports Grayscale, RGB888 and YCbCr422 formats. Below you can see the interface.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPKyVA7uIM-oEAv8fw0jcq5MoLQzvHhp6YE_Hmw5soCQMQiN_99c87cuLjvq_nQgKMTCMIGsGVS8JYfS5WiToewGjOaCdANXieEV8BKT0MCjuJi4uFYGppifJDMs2FKz4-YVGJMWEhMMc/s1600/imageViewer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPKyVA7uIM-oEAv8fw0jcq5MoLQzvHhp6YE_Hmw5soCQMQiN_99c87cuLjvq_nQgKMTCMIGsGVS8JYfS5WiToewGjOaCdANXieEV8BKT0MCjuJi4uFYGppifJDMs2FKz4-YVGJMWEhMMc/s320/imageViewer.png" width="320" /></a></div>
<br />
<div style="text-align: center;">
qSerialTerm configured to receive images.</div>
<br />
<div style="text-align: justify;">
By default, the received image is displayed at its original size. By checking the "Fit to Screen" check box, the image will be scaled to fit the screen.</div>
<br />
<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_ejqnHZ_8RTNf-8WuoiwjApJf7q2x8zISOMgTr9p_ZrfXQwP46-75_yOAomxl5ih5uJzzw5tnbfY5K2jItT5h1ILKHDt6zXp4etp96uyK3L0NrSPI964lrl521-41HmkgwxJwulR2fxA/s1600/20x20.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_ejqnHZ_8RTNf-8WuoiwjApJf7q2x8zISOMgTr9p_ZrfXQwP46-75_yOAomxl5ih5uJzzw5tnbfY5K2jItT5h1ILKHDt6zXp4etp96uyK3L0NrSPI964lrl521-41HmkgwxJwulR2fxA/s200/20x20.png" width="200" /></a></div>
</td>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisHXS0lQqAwhIT4JcjGTABNmuY3LgXzuHvFWJTGeY7VfI-waRlnjv1IVkX-urTfJXyAVvDiUE8MGEw1LzlfjZ7Z8nkHd26OYLkJB7kCyRJ8VUhx8TNSw_L4_dSn_GIHkprLi6DR933rgQ/s1600/fitToScreen.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisHXS0lQqAwhIT4JcjGTABNmuY3LgXzuHvFWJTGeY7VfI-waRlnjv1IVkX-urTfJXyAVvDiUE8MGEw1LzlfjZ7Z8nkHd26OYLkJB7kCyRJ8VUhx8TNSw_L4_dSn_GIHkprLi6DR933rgQ/s200/fitToScreen.png" width="200" /></a></div>
</td>
</tr>
<tr>
</tr>
</tbody></table>
<div style="text-align: center;">
Image scaling using "Fit to screen" check box.</div>
<br />
<h3>
Simple demo</h3>
<br />
<div style="text-align: justify;">
As usual, I'm posting a demo image. By shorting the TX and RX lines of my USB<->UART converter, I'll control the RGB levels of a single pixel. To do so, I'm using the "frame" feature and the Image Viewer mode.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN-Ace_3R9O-aYy4ZRlXgSBIPNh0OdLFNuuK633pUlW126LDUDWx88nevZHTQ9CqSbGNzc_DewW6lnSdkCnTh6XXVdeajlobWtPokzIwRdBSMIF_XJ_MBisbEAmrnSSFnGex-08Hr4OGQ/s1600/simpleDemo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN-Ace_3R9O-aYy4ZRlXgSBIPNh0OdLFNuuK633pUlW126LDUDWx88nevZHTQ9CqSbGNzc_DewW6lnSdkCnTh6XXVdeajlobWtPokzIwRdBSMIF_XJ_MBisbEAmrnSSFnGex-08Hr4OGQ/s320/simpleDemo.png" width="320" /></a></div>
<div style="text-align: center;">
Demo: Echoing back a RGB pixel.</div>
<div style="text-align: center;">
<br /></div>
<br />
<h3>
OV7670 demo</h3>
<br />
To do!<br />
<br />
<h3>
Repository</h3>
<br />
You can get qSerialTerm source code from <a href="https://github.com/JorgeAparicio/qSerialTerm">this repository</a>.<br />
<br />
<h3>
More Information</h3>
<br />
<a href="http://embeddedprogrammer.blogspot.com/2012/06/qserialterm-qt-based-serial-port.html">qSerialTerm as serial port terminal emulator</a><br />
<a href="http://embeddedprogrammer.blogspot.com/2012/08/qserialterm-improved-and-now-can-be.html">qSerialTerm for data logging</a><br />
<a href="http://embeddedprogrammer.blogspot.com/2012/08/qserialterm-serial-port-servomotor.html">qSerialTerm for servomotor control</a><br />
<a href="http://embeddedprogrammer.blogspot.com/2012/08/qserialterm-qt-based-serial-port-data.html">qSerialTerm for data acquisition</a>Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com5tag:blogger.com,1999:blog-1622983275835621655.post-46032301830786602892012-08-20T21:37:00.002-05:002012-10-09T12:18:17.551-05:00uJTAG, Open Source minimalistic JTAG dongle<div style="text-align: justify;">
I'm releasing the design files of a <a href="http://en.wikipedia.org/wiki/Jtag">JTAG</a> dongle. JTAG is a interface designed to test printed circuit boards (PCB) using boundary scan. But today, is also used to test Integrated Circuits (IC), in particular this interface is present in all (I think) ARM processors.</div>
<br />
<div style="text-align: justify;">
The JTAG dongle I designed, named uJTAG, is a minimalistic implementation with a 6 pin connector in contrast to the standard 20 pin connector. The purpose of this dongle is to flash and debug ARM microcontrollers. Especifically, this dongle has been tested with STM32 microcontrollers.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI9BjtRaPeyB30wQv3q6AdZp5q8UyMWNCMrf9aucfhGzjt-O_zWdtzieHutjgkFFSH8zV2FiKFGBBmJwhp930KCp8lBMVaAyzISDX36Ks_JCx5si-nPEvWZf1Sy0bOHyJl1E_8DlCbr7o/s1600/uJTAG.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI9BjtRaPeyB30wQv3q6AdZp5q8UyMWNCMrf9aucfhGzjt-O_zWdtzieHutjgkFFSH8zV2FiKFGBBmJwhp930KCp8lBMVaAyzISDX36Ks_JCx5si-nPEvWZf1Sy0bOHyJl1E_8DlCbr7o/s320/uJTAG.JPG" width="320" /></a></div>
<div style="text-align: center;">
uJTAG old version</div>
<span id="goog_1800332863"></span><span id="goog_1800332864"></span><br />
<div style="text-align: justify;">
<span id="goog_1800332863">On the above image you can see the previous version of uJTAG I implemented. In the current version, I have removed the EEPROM memory, which I later figured was not necessary, as the default USB <-> UART configuration is enough. Also the components have been moved to the top layer.</span></div>
<br />
<h3>
PINOUT</h3>
<br />
<div style="text-align: justify;">
As I mentioned previously the JTAG standard specifies a 20 pin connector shown below:</div>
<br />
<table align="center" border="1">
<tbody>
<tr>
<td style="text-align: center;">VDD</td>
<td style="text-align: center;">VDD<br />
(optional)</td>
</tr>
<tr>
<td style="text-align: center;">TRST</td>
<td style="text-align: center;">GND</td>
</tr>
<tr>
<td style="text-align: center;">TDI</td>
<td style="text-align: center;">GND
</td>
</tr>
<tr>
<td style="text-align: center;">TMS
</td>
<td style="text-align: center;">GND</td>
</tr>
<tr>
<td style="text-align: center;">TCK</td>
<td style="text-align: center;">GND
</td>
</tr>
<tr>
<td style="text-align: center;">RTCK
</td>
<td style="text-align: center;">GND
</td>
</tr>
<tr>
<td style="text-align: center;">TDO</td>
<td style="text-align: center;">GND
</td>
</tr>
<tr>
<td style="text-align: center;">RESET
</td>
<td style="text-align: center;">GND
</td>
</tr>
<tr>
<td style="text-align: center;">NC</td>
<td style="text-align: center;">GND</td>
</tr>
<tr>
<td style="text-align: center;">NC</td>
<td style="text-align: center;">GND
</td>
</tr>
</tbody></table>
<br />
<div style="text-align: justify;">
uJTAG connector uses only 6 pins. Pinout is shown below:</div>
<br />
<table align="center" border="1">
<tbody>
<tr align="center">
<td>TMS</td>
</tr>
<tr align="center">
<td>TDI</td>
</tr>
<tr align="center">
<td>TDO</td>
</tr>
<tr align="center">
<td>TCK
</td>
</tr>
<tr align="center">
<td>GND
</td>
</tr>
<tr align="center">
<td>VDD
</td>
</tr>
</tbody></table>
<br />
<div style="text-align: justify;">
These four signals (TMS, TDI, TDO, TCK) are the minimum necessary to use JTAG on microcontrollers. Actually, the RESET signal is also important, but with these signals a RESET can be issued by software, i.e. as a combination of the other 4 signals.</div>
<br />
<h3>
USE</h3>
<br />
<div style="text-align: justify;">
I use this JTAG dongle with STM32 microcontrollers, specifically I use it with <a href="http://embeddedprogrammer.blogspot.com/2012/08/f4dev-open-source-development-board-for.html">F4Dev</a>, an open source development board for STM32F4 microcontrollers, and with <a href="http://openocd.sourceforge.net/">openOCD</a> 0.5.0., a software that enables a transparent JTAG communication from PC to microcontroller/processor via the USB protocol.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLJNCpqZcMBzYeAuLeDeJTUXEjZKyYF3YY2N9JfXaidRUCeKgZ-vr15QGsG8RDJx3_JdTLjXxB-U8kBHq298JSIPY46TxvMZ65_rbMvRsWZ9kBW5OBa4f9z5iE_4a8_8TKxB4HBjDhcoM/s1600/implementation.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLJNCpqZcMBzYeAuLeDeJTUXEjZKyYF3YY2N9JfXaidRUCeKgZ-vr15QGsG8RDJx3_JdTLjXxB-U8kBHq298JSIPY46TxvMZ65_rbMvRsWZ9kBW5OBa4f9z5iE_4a8_8TKxB4HBjDhcoM/s320/implementation.jpg" width="320" /></a></div>
<div style="text-align: center;">
uJTAG mated with F4Dev</div>
<br />
<br />
<h3>
REPOSITORY</h3>
<br />
You can find all the design files in this <a href="https://github.com/JorgeAparicio/uJTAG">repository</a>. Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com10tag:blogger.com,1999:blog-1622983275835621655.post-78161746909552326492012-08-15T22:29:00.000-05:002012-10-09T12:16:39.031-05:00Robbie, the open humanoid robot<br />
<div style="text-align: justify;">
This is the project I have been working on this year. The tittle of the project is "Development of a Open Platform for Research on Humanoid Robots", it's basically the implementation of <a href="http://embeddedprogrammer.blogspot.com/2012/08/simulation-of-humanoid-robot.html">the project I did last year</a>.</div>
<br />
<div style="text-align: justify;">
This robot is used/will be used to test control stability, sensor fusion, stereo vision and path planning algorithms. Currently, my team and I are gradually releasing all of our source. Ultimately, a public repository will be created, containing the necessary information to replicate this project.</div>
<span id="goog_1573590268"></span><span id="goog_1573590269"></span><br />
This is a very big project, which I'll analyze in the following sections.<br />
<br />
<h3>
Simulation (Not released yet)</h3>
<br />
<div style="text-align: justify;">
Our previous project used Simulink to simulate Robbie in a virtual environment. Since simulation times were no good, we decided to switch to <a href="http://www.ode.org/">ODE</a> (Open Dynamics Engine), which doesn't looks as nice as Simulink, but its simulation times are way better.</div>
<br />
<table align="center">
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-oHXJfezvuSbJrq2LaxxkHdjVgPI4sMr9WrTxulZVuOoP_7KJDsc1TQ4P7d4L_KiYgVPmhwHgFtdTTRL9sxo3AMb0ctkofKutb_IB0BjWeZawJfmNXlmZqJ9yHJcLfCqYlfeXjqdHbWE/s1600/ode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-oHXJfezvuSbJrq2LaxxkHdjVgPI4sMr9WrTxulZVuOoP_7KJDsc1TQ4P7d4L_KiYgVPmhwHgFtdTTRL9sxo3AMb0ctkofKutb_IB0BjWeZawJfmNXlmZqJ9yHJcLfCqYlfeXjqdHbWE/s200/ode.png" width="200" /></a></div>
</td>
<td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgM5brznK89FHfdYG81OWrdZpia0P21E6XJGcWgfelm5-cNlv3zHYg6YZXwj8EA8UeTLfhoOimSKketvWyI7PJccQeBvFtj1vmk4N0L_iRM-3W0T0Ar7yaffudgpWWtHCkWosVOcL-bzGA/s1600/ode2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgM5brznK89FHfdYG81OWrdZpia0P21E6XJGcWgfelm5-cNlv3zHYg6YZXwj8EA8UeTLfhoOimSKketvWyI7PJccQeBvFtj1vmk4N0L_iRM-3W0T0Ar7yaffudgpWWtHCkWosVOcL-bzGA/s200/ode2.png" width="122" /></a></div>
</td>
</tr>
</tbody></table>
<div style="text-align: center;">
Robbie in a virtual environment. ZMP inverted pendulum not part of the simulation.</div>
<br />
<div style="text-align: justify;">
My friend Victor is in charge of this section. We haven't released the source code yet, but probably we'll release it as a Eclipse project.</div>
<div style="text-align: justify;">
<br /></div>
<h3>
Mechanics (Not released yet)</h3>
<br />
<div style="text-align: justify;">
Materials: Alluminium, 18 Hitec HS-645MG servomotors and 2 Towerpro SG-90 micro servomotors.</div>
<br />
This is how the Robbie looks today:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK27jB4D4R-NXwIJgN_Kl-UZYFTS2iu4r7v1x8gkBBUnaDXEdRtxPN3PNPfZ2wys8xWTKEJLGK0UYvWcRkNkkw7jbNDS3KA9wnSLs7EvPqEbuTlRoO8_pZ_YAjgzpY7GmBbIRxfwk_60I/s1600/robbie.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK27jB4D4R-NXwIJgN_Kl-UZYFTS2iu4r7v1x8gkBBUnaDXEdRtxPN3PNPfZ2wys8xWTKEJLGK0UYvWcRkNkkw7jbNDS3KA9wnSLs7EvPqEbuTlRoO8_pZ_YAjgzpY7GmBbIRxfwk_60I/s320/robbie.JPG" width="239" /></a></div>
<div style="text-align: center;">
Robbie, the humanoid robot</div>
<br />
<br />
Drawings not yet released.<br />
<br />
<h3>
Electronics (Partially released)</h3>
<br />
The electronics are splitted in 3:<br />
<br />
<ul>
<li><a href="http://embeddedprogrammer.blogspot.com/2012/08/f4dev-open-source-development-board-for.html">F4Dev</a>: Sensor / actuator manager and stability controller.</li>
<li>Distribution board: For servo connectors. </li>
<li><a href="http://beagleboard.org/">Beagleboard</a>: For image processing.</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgV016NLf8B3vqY235S0QLHg87lW1RmA0Ddu-drTRfEvmF92nr7n-JittHgdz2Hi_aSJZtJpTzy6sUszLnv0wAMyw1u_UbZzVA3Ri-kAywWMolr70xubwftntXVXw5X5KoFVEroCW4yk9A/s1600/electronics.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgV016NLf8B3vqY235S0QLHg87lW1RmA0Ddu-drTRfEvmF92nr7n-JittHgdz2Hi_aSJZtJpTzy6sUszLnv0wAMyw1u_UbZzVA3Ri-kAywWMolr70xubwftntXVXw5X5KoFVEroCW4yk9A/s320/electronics.png" width="319" /></a></div>
<div style="text-align: center;">
Robbie's brain</div>
<br />
<h3>
Firmware ("Partially" released)</h3>
<br />
<div style="text-align: justify;">
The firmware is built on top of <a href="http://embeddedprogrammer.blogspot.com/2012/06/bare-metal-development-for-arm-cortex-m.html">bareCortexM</a>, an Eclipse based IDE for ARM Cortex M processors, and <a href="http://embeddedprogrammer.blogspot.com/2012/07/open-source-template-peripheral-library.html">libstm32pp</a>, a template peripheral library. Both projects are open source.</div>
<br />
The final firmware has yet to be released. <br />
<br />
<h3>
Software Interface (Old version released)</h3>
<br />
The software interface, <a href="http://embeddedprogrammer.blogspot.com/2012/06/qserialterm-qt-based-serial-port.html">qSerialTerm</a>, allows the user to: <br />
<ul>
<li>Send messages to Robbie.</li>
<li>Visualize moving plots of Robbie's sensor readings</li>
<li>Manually control Robbie's servomotors.</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivEw68OkxmBAedegTrXyQGI8yZ4pWMUczTQnMEldvB1Wi07EL487Q0prNlK_eVfAiRb0Px26-2zlwF-f3u96FJ0K1yU822chiZUvaOGOyUBElzZA3fnbf4xvrIv2JPVLjEN1M255FTE48/s1600/qSerialTerm.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="173" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivEw68OkxmBAedegTrXyQGI8yZ4pWMUczTQnMEldvB1Wi07EL487Q0prNlK_eVfAiRb0Px26-2zlwF-f3u96FJ0K1yU822chiZUvaOGOyUBElzZA3fnbf4xvrIv2JPVLjEN1M255FTE48/s320/qSerialTerm.png" width="320" /></a></div>
<div style="text-align: center;">
qSerialTerm, a Qt based serial port interface</div>
<br />
<h3>
Sensor fusion</h3>
<br />
<div style="text-align: justify;">
From the orientation sensors (accelerometer, gyroscope and magnetometer) readings we compute an absolute orientation, using <a href="http://www.x-io.co.uk/node/8#open_source_imu_and_ahrs_algorithms">Madwick's MARG algorithm</a>. This algorithm computes the orientation of Robbie's torso, seen from the coordinate system formed by the gravity axis (-Z axis) and the geographic north (Y axis).</div>
<br />
<div style="text-align: center;">
I owe you a video here.<br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This computed orientation is important for the stability control and will later be used for path planning.</div>
</div>
<br />
<h3>
Control Stability</h3>
<br />
<div style="text-align: justify;">
The accelerometer data is used to compute a stability indicator, named Zero Moment Point (ZMP). This indicator plus the giroscope readings are the core of Robbie's stability control. </div>
<br />
<div style="text-align: justify;">
Robbie's stability control maximizes its support polygon, i.e. maintains its foot parallel to the floor, and also maintains its ZMP inside its support polygon, this guarantees dynamic stability.</div>
<br />
<div style="text-align: center;">
I owe you another video here.</div>
<h3>
Stereo Vision</h3>
<div style="text-align: justify;">
<br />
Robbie has a stereo camera (a Minoru 3D webcam to be precise), which in essence are two cameras properly aligned to resemble human eyes. Using a stereo vision algorithm, the video streams from these two cameras can be used to obtain a sense of depth.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilc2rxtpukoq5D41zPFNYNmx7ZLmzA11-f7PKqo_H65OUBFwMRJfNHR-tQuuUBtSjHjfVRH52hTEjYHUehgHVpMQ07NrvJqKamEDTbWwbO1X1zBSZv11vlegYD3VGPeZS1PyexSe0KlXY/s1600/minoru.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilc2rxtpukoq5D41zPFNYNmx7ZLmzA11-f7PKqo_H65OUBFwMRJfNHR-tQuuUBtSjHjfVRH52hTEjYHUehgHVpMQ07NrvJqKamEDTbWwbO1X1zBSZv11vlegYD3VGPeZS1PyexSe0KlXY/s1600/minoru.png" /></a></div>
<div style="text-align: center;">
Minoru 3D webcam, a.k.a. Robbie's head</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
We use a stereo vision algorithm to compute the distance from Robbie to objects, and this information is used as a obstacle detector.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQwHNv5dkLBPNM_ATvsrFxLSEOWRrBmp7CiCC6jSdMScOAI_HK_6_rBi5Or0LszRKHAGBAWmC_MGIVpDmKWhcpgf_Ek1GnAfPTuBwxmK7gQUWpHvUd1i7l_RvoAfLYgcM8wWfMKF3zN_4/s1600/stereo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="152" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQwHNv5dkLBPNM_ATvsrFxLSEOWRrBmp7CiCC6jSdMScOAI_HK_6_rBi5Or0LszRKHAGBAWmC_MGIVpDmKWhcpgf_Ek1GnAfPTuBwxmK7gQUWpHvUd1i7l_RvoAfLYgcM8wWfMKF3zN_4/s320/stereo.png" width="320" /></a></div>
<div style="text-align: center;">
My friend Santiago <strike>trying to punch Robbie</strike> testing Robbie's stereo vision.</div>
<br />
My friend Santiago is in charge of this part. Source code not released yet.<br />
<br />
<h3>
Early footage</h3>
<div style="text-align: justify;">
<span id="goog_1573590268"></span><span id="goog_1573590269"></span><br /></div>
<div style="text-align: justify;">
<span id="goog_1573590268">On the following video, you can see Robbie doing tracking of gait trajectories without stability control.</span></div>
<span id="goog_1573590268"></span><span id="goog_1573590269"></span><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/Wi31S4JsuEs?feature=player_embedded' frameborder='0'></iframe></div>
<div style="text-align: center;">
<span id="goog_1573590268"></span><span id="goog_1573590269"></span>Robbie walking, without stability control. (Feb 2012)</div>
<span id="goog_1573590268"></span><span id="goog_1573590269"></span><br />
<h3>
Acknowledgements</h3>
<br />
<ul>
<li>Prof. Jose Oliden, our advisor</li>
<li>Victor Paredes and Santiago Cortijo, team members</li>
<li>Control systems and Artificial Intelligence Research Group (GISCIA)</li>
<li>National University of Engineering (UNI)</li>
</ul>
<span id="goog_1573590268"></span><span id="goog_1573590269"></span><br />Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com3tag:blogger.com,1999:blog-1622983275835621655.post-48579533490881209582012-08-15T21:25:00.000-05:002012-10-18T09:11:38.173-05:00F4Dev, Open Source Development Board for the STM32F4 microcontrollers<div style="text-align: justify;">
Today, I'm releasing the design files of a board I redesigned, you may have seen the previous version in my post about <a href="http://embeddedprogrammer.blogspot.com/2012/06/3d-and-footprint-libraries-for-kicad.html">libKiCad</a>.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLJNCpqZcMBzYeAuLeDeJTUXEjZKyYF3YY2N9JfXaidRUCeKgZ-vr15QGsG8RDJx3_JdTLjXxB-U8kBHq298JSIPY46TxvMZ65_rbMvRsWZ9kBW5OBa4f9z5iE_4a8_8TKxB4HBjDhcoM/s1600/implementation.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLJNCpqZcMBzYeAuLeDeJTUXEjZKyYF3YY2N9JfXaidRUCeKgZ-vr15QGsG8RDJx3_JdTLjXxB-U8kBHq298JSIPY46TxvMZ65_rbMvRsWZ9kBW5OBa4f9z5iE_4a8_8TKxB4HBjDhcoM/s320/implementation.jpg" width="320" /></a></div>
<br />
<div style="text-align: center;">
F4Dev, previous non-released version.</div>
<br />
<div style="text-align: justify;">
This board, dubbed F4Dev, is a small (5x5 cm) TQFP-100 adapter like board loaded with various sensors and some communication interfaces.</div>
<br />
<div style="text-align: justify;">
The board was redesigned, because the old version has components on both faces and there was a problem with the USB <-> UART converter, due to a Silicon Limitation.</div>
<div style="text-align: justify;">
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2FLit4TW-5NtvDS2qQj3BdJjsJhxojrKtrwm6OjnSQ6i-DjTEKL4gYM9ZfgFgs7BK29hzBB9kjNSxQga5uzVpsnl6Js72kuQIUGpYlfvhpGrSTouh4ZNuDoujlDA6-7ATMczdsgpvVU0/s1600/newF4Dev.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="308" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2FLit4TW-5NtvDS2qQj3BdJjsJhxojrKtrwm6OjnSQ6i-DjTEKL4gYM9ZfgFgs7BK29hzBB9kjNSxQga5uzVpsnl6Js72kuQIUGpYlfvhpGrSTouh4ZNuDoujlDA6-7ATMczdsgpvVU0/s320/newF4Dev.JPG" width="320" /></a></div>
<div style="text-align: center;">
F4Dev, new released version.</div>
<br /></div>
<h3>
Specifications</h3>
<ul>
<li>Accelerometer, 3 DoF, 16 bits (LSM303DLHC)</li>
<li>Magnetometer, 3 DoF, 16 bits (LSM303DLHC)</li>
<li>Gyroscope, 3 DoF, 16 bits (L3GD20)</li>
<li>Barometer, 19 bits (BMP085)</li>
<li>======================================== Equivalent to a 10 DoF IMU</li>
<li>Omnidirectional Microphone (MP45DT02)</li>
<li>USB <-> UART (FT230X)</li>
<li>Bluetooth <-> UART (<a href="http://embeddedprogrammer.blogspot.com/2012/06/ubuntu-hacking-hc-06-bluetooth-module.html">See this post</a>)</li>
<li>6 pin JTAG connector (TMS, TDI, TDO, TCK, GND, VDD) (See <a href="http://embeddedprogrammer.blogspot.com/2012/08/ujtag-open-source-minimalistic-jtag.html">uJTAG</a>)</li>
<li>LED indicators </li>
</ul>
<br />
<h3>
Intended applications</h3>
<br />
<div style="text-align: justify;">
As you can see in the specifications, the F4Dev is loaded with a 10 DoF Inertial Measurement Unit (IMU) and wireless communication. This makes it ideal for robotics: wheeled robots, aerial robots, bipedal robots, etc.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Currently, the previous version of F4Dev, is used in <a href="http://embeddedprogrammer.blogspot.com/2012/08/robbie-open-humanoid-robot.html">Robbie</a>, a humanoid robot. And this new version will be used in a Quadrotor/Quadcopter.</div>
<br />
<h3>
Repository</h3>
<br />
You can check all the design files (in KiCad) in the following <a href="https://github.com/JorgeAparicio/F4Dev">repository</a>(github.com).Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com9tag:blogger.com,1999:blog-1622983275835621655.post-26740032854349688222012-08-13T19:10:00.000-05:002013-01-05T23:25:48.706-05:00Simulation of a humanoid robot<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg56RM6ogCWfGLn8IQKnEGkbWDl4hLerYomqPsHzD7Ccfa4upDmt6vcYCXlfz0a-hPqzbTIlX-0LZOLO-DTtV5fVY3VRS1qCvesQS0-Jq1nnspk4JdFT2dbs9RhAprxIcnCk5z_0jWQ-V4/s1600/animation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg56RM6ogCWfGLn8IQKnEGkbWDl4hLerYomqPsHzD7Ccfa4upDmt6vcYCXlfz0a-hPqzbTIlX-0LZOLO-DTtV5fVY3VRS1qCvesQS0-Jq1nnspk4JdFT2dbs9RhAprxIcnCk5z_0jWQ-V4/s320/animation.png" width="318" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Today, I'll show some of the work I did <i><b>last year</b></i> in my university. I worked in a project titled <i>"Stability Control of a Humanoid Robot"</i>. The project goal was to test a stability control algorithm on a humanoid robot in a virtual environment. This project was a first step toward the actual implementation of a humanoid robot.</div>
<br />
<div style="text-align: justify;">
I'm going to show the steps I followed to achieve a full simulation environment. And I hope these steps allow other people to do simulations of robots (not necessarily bipedal robots).</div>
<br />
<h3>
Mechanical design</h3>
<br />
<div style="text-align: justify;">
The project started with the mechanical design of the humanoid robot. Since my faculty had servomotors, they were used as part of the design. The mechanical design was developed on Solidworks, and was inspired on various commercial designs. The robot has 18 degrees of freedom, 5 per leg and 4 per arm, and has no head!</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTVF6W3iducfoaJW4-cmK9vuKWt1ohxHwQ1o35OZM26HbYg8KMgbdylwci8K8xKp6TR5B-Jpi-JGli8Cietv-KmxJcfTPOx5zGy2EOwUwokZl67b9d5akNjufxk8t10uBmzjc57lsQ3_0/s1600/design.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTVF6W3iducfoaJW4-cmK9vuKWt1ohxHwQ1o35OZM26HbYg8KMgbdylwci8K8xKp6TR5B-Jpi-JGli8Cietv-KmxJcfTPOx5zGy2EOwUwokZl67b9d5akNjufxk8t10uBmzjc57lsQ3_0/s320/design.JPG" width="320" /></a></div>
<div style="text-align: center;">
Solidworks render of the mechanical design</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The solidworks design provides pretty much all the necessary information (dimensions, mass and inertia) for a dynamic simulation.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIOEG7s4FPB5AQLl8O530Ume4H95qmZ_x66s21QsHBlBBnBvu6vGPO1srkyrYABhLOZvgFHseE1FHgwuYBBcrr3kTOMLANlqyNatN-YaukDZUBbPVZdpBOvB4dWFIU1uhek2Qgo_ip1TA/s1600/inertia.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="211" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIOEG7s4FPB5AQLl8O530Ume4H95qmZ_x66s21QsHBlBBnBvu6vGPO1srkyrYABhLOZvgFHseE1FHgwuYBBcrr3kTOMLANlqyNatN-YaukDZUBbPVZdpBOvB4dWFIU1uhek2Qgo_ip1TA/s320/inertia.png" width="320" /></a></div>
<div style="text-align: center;">
Mass properties from Solidworks</div>
<br />
<h3>
The simulation environment</h3>
<br />
<div style="text-align: justify;">
Next task was selecting a simulation environment, at that time my team and I only knew the Simulink environment from MATLAB, so the choice was limited. The Simmechanics toolbox was used to simulate the multibody dynamics of the robot.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijSyDjJKMuo25HTGpD06iaR3s3HmqjIVVNuxWKhqxMMv8fiI5MWyx4FAfpU3cRzOm63lPwYf9YeRdRCr4htRFUxj8X-KeS2t9zHyvq-hEcIAzJvuKUVTaS4RxTyrg3vNd-5CTk46WfqOM/s1600/simmechanics.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="113" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijSyDjJKMuo25HTGpD06iaR3s3HmqjIVVNuxWKhqxMMv8fiI5MWyx4FAfpU3cRzOm63lPwYf9YeRdRCr4htRFUxj8X-KeS2t9zHyvq-hEcIAzJvuKUVTaS4RxTyrg3vNd-5CTk46WfqOM/s320/simmechanics.png" width="320" /></a></div>
<div style="text-align: center;">
The simulink environment</div>
<h3>
Bodies and joints</h3>
<br />
<div style="text-align: justify;">
Simmechanics provides body and joint blocks to construct various mechanical assemblies. A body holds the inertial information necessary for a dynamic simulation. And two bodies can be connected via a joint, this joint can add zero or more degrees of freedom between the bodies.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgE8mV3Y-_mQcb-8Hx_trMIgSjFCq_ByOwLh7pXBbvOUGagLLFE8UC2rl0Gkr7BQ46JUOeP52_qltxTAqPhFwJI67FvBeboz1zu9A_QPHlXCIxh0xLXfFKcDzUQvJ4eOi5SNAvRTtgtoM/s1600/joint.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgE8mV3Y-_mQcb-8Hx_trMIgSjFCq_ByOwLh7pXBbvOUGagLLFE8UC2rl0Gkr7BQ46JUOeP52_qltxTAqPhFwJI67FvBeboz1zu9A_QPHlXCIxh0xLXfFKcDzUQvJ4eOi5SNAvRTtgtoM/s320/joint.png" width="233" /></a></div>
<div style="text-align: center;">
6 DOF Joint between the humanoid torso and the ground (absolute reference point)</div>
<br />
<div style="text-align: justify;">
The bodies and joints are referenced to each other via Coordinates Systems (CS), which can be absolute or relative. Also, sensors and actuators can be attached to the bodies or to the joints for control applications. </div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEim0ODEnzl3Pl6sfL8bTfsDgVkz4x-hXBhFH6POLCsJLdKbLEfSiy-bRy0q74dAvzybGoxODrHUm0Z9ScCngLFEYfBL3RN_Q9tTUMWldv4KI7YnqXxj1ber1KBkPsTrZbCb_IMGVbrtBiQ/s1600/inertiaProperties.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="257" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEim0ODEnzl3Pl6sfL8bTfsDgVkz4x-hXBhFH6POLCsJLdKbLEfSiy-bRy0q74dAvzybGoxODrHUm0Z9ScCngLFEYfBL3RN_Q9tTUMWldv4KI7YnqXxj1ber1KBkPsTrZbCb_IMGVbrtBiQ/s320/inertiaProperties.png" width="320" /></a></div>
<div style="text-align: center;">
Torso (body) properties: Inertial parameters and CS</div>
<br />
<div style="text-align: justify;">
There is a plugin for Solidworks called Simmechanics Link, that allows the conversion from a Solidworks assembly to a Simulink model. However, the bodies and joints were laid out manually for greater flexibility and control.</div>
<br />
<h3>
Modeling the floor</h3>
<br />
<div style="text-align: justify;">
The problem with the Simmechanics toolbox was the lack of object
collision, which is crucial for the simulation, as the normal and
friction forces between the floor and the robot are key for gait.</div>
<br />
<div style="text-align: justify;">
To solve this problem, the floor was modeled as a PD controller. This controller exerted normal forces on a few selected points of the robot sole, <i><b>only when these points were on or below the floor level</b></i>.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJgNiyBh5RvHE_7HoEy5eY7Btd0oxRhwwqs2yVEwIORZJobTV08MO6X5kvhiUfzuCga4efnfliE5VkLSvaNwa4eB9Ux1rjefoMuSy7V6o8DkDcT4UMTaN74DeJDhyw4mj8UvMRMx98srU/s1600/supportPoints.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="116" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJgNiyBh5RvHE_7HoEy5eY7Btd0oxRhwwqs2yVEwIORZJobTV08MO6X5kvhiUfzuCga4efnfliE5VkLSvaNwa4eB9Ux1rjefoMuSy7V6o8DkDcT4UMTaN74DeJDhyw4mj8UvMRMx98srU/s320/supportPoints.png" width="320" /></a></div>
<div style="text-align: center;">
8 support points selected per foot.</div>
<br />
<div style="text-align: justify;">
The error input of this PD controller was the deviation of these points from the floor level. High proportional and derivative gains were used to minimize the sinking of the feet on the floor. The floor also exerted viscous friction forces, when the feet was in contact with the floor.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQsefkFD5kZnFowkVkFAKWtK1emJpPj49cbnqNrqaa68mJ_89M3mJMZvWXCnaCrkGbBUUcJZFVu5VbVEhH56XDkHbAMGpWURSZAQqdOSm4TL_qmZycsMeqgdYSmF7nw4Unu6CEKd7IJWw/s1600/floorController.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="149" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQsefkFD5kZnFowkVkFAKWtK1emJpPj49cbnqNrqaa68mJ_89M3mJMZvWXCnaCrkGbBUUcJZFVu5VbVEhH56XDkHbAMGpWURSZAQqdOSm4TL_qmZycsMeqgdYSmF7nw4Unu6CEKd7IJWw/s320/floorController.png" width="320" /></a></div>
<div style="text-align: center;">
Floor controller block diagram.</div>
<br />
<h3>
Modeling the servomotor</h3>
<br />
<div style="text-align: justify;">
For the servomotor model, specifications like the maximum angular speed and the maximum torque were used to produce an accurate DC motor model. For the servomotor controller model, a position + speed controller with gravity compensation and angular speed feedforward was used. Full block diagram is below.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7MipIYHyFh19kcyjNGMOv30BrX94ugD-yhcT9y5hn4SjXrjJb3Edsd8yfoL9a14X-d2ZTL_kVpVxvv3bOadcP6vCptrM8xiJCHhPZG0r9TOuUAYZ8T4QIxzuJFZ0LPDISzDjtO-xUelM/s1600/servomotor.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="130" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7MipIYHyFh19kcyjNGMOv30BrX94ugD-yhcT9y5hn4SjXrjJb3Edsd8yfoL9a14X-d2ZTL_kVpVxvv3bOadcP6vCptrM8xiJCHhPZG0r9TOuUAYZ8T4QIxzuJFZ0LPDISzDjtO-xUelM/s400/servomotor.png" width="400" /></a></div>
<div style="text-align: center;">
Servomotor model</div>
<br />
<div style="text-align: justify;">
Each servomotor was attached to each joint via a joint actuator and joint sensors, as shown in the following image.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1saiR7UdNt146-z8lfg5wuqYUnAoUM54JZo0a-cs7nPKHtJG50kSSm83BjUyi3uz-wZDpnZLSZVN44bxY3YU4jJHU0Rxkc595ArjXLsZEgAQfBaIMFSTqLHng1NJdwiHiSfZO87MSplI/s1600/actuatedJoint.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="251" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1saiR7UdNt146-z8lfg5wuqYUnAoUM54JZo0a-cs7nPKHtJG50kSSm83BjUyi3uz-wZDpnZLSZVN44bxY3YU4jJHU0Rxkc595ArjXLsZEgAQfBaIMFSTqLHng1NJdwiHiSfZO87MSplI/s320/actuatedJoint.png" width="320" /></a></div>
<div style="text-align: center;">
Actuated joint</div>
<br />
<h3>
Putting it all together</h3>
<br />
<div style="text-align: justify;">
After modelling the servomotor and the floor, the rest of the work consisted in assigning each body its inertial parameters and its 3d model (.stl) and then gluing everything together with the servomotors. The final result is shown below.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg96pfOJId3EdJKBJt9YScs0YYqN-djjUOFxOfoMsc6ybs-MO9ticLTg6OhUtXpIzDyOOj9-C5_sr232LRS1q1-ySfgTlwGmRt60MQh6UVHAA1MjdgCQ3CdIOoq75jLJ-Nb2kBDNX5FEwM/s1600/fullAssembly.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="198" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg96pfOJId3EdJKBJt9YScs0YYqN-djjUOFxOfoMsc6ybs-MO9ticLTg6OhUtXpIzDyOOj9-C5_sr232LRS1q1-ySfgTlwGmRt60MQh6UVHAA1MjdgCQ3CdIOoq75jLJ-Nb2kBDNX5FEwM/s320/fullAssembly.png" width="320" /></a></div>
<div style="text-align: center;">
High level assembly</div>
<div style="text-align: center;">
<br /></div>
<h3 style="text-align: justify;">
Animation</h3>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The simulation of this whole system can take a considerable amount of time, depending on the number of degrees of freedom, CPU power, etc. Here's a tip about the animation, you can speed up a little the animation (not the simulation), by accessing the menu Simulation > Control Animation Speed and reducing the "Delay per frame" and tweaking the "Visualization sample time".</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6foTmX5-VGkqbGY3Dkl9JFO5P1z226uihOQ0lhf8GIjlRMqThnDPT77xazfceKw62UiA-XH-Zpv4iFE2lXVCZzxlUzGDfdTHPLEZDKJ26FQiyKq1ignzihGuba0nVLDGakID4VN6cToc/s1600/animationSpeed.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6foTmX5-VGkqbGY3Dkl9JFO5P1z226uihOQ0lhf8GIjlRMqThnDPT77xazfceKw62UiA-XH-Zpv4iFE2lXVCZzxlUzGDfdTHPLEZDKJ26FQiyKq1ignzihGuba0nVLDGakID4VN6cToc/s1600/animationSpeed.png" /></a></div>
<div style="text-align: center;">
Controlling the animation speed</div>
<h3>
Making it move</h3>
<br />
<div style="text-align: justify;">
Moving the robot is as simple as giving some references to the servomotors, but making it walk is a different history. The references that can be send to the servomotors are angular positions (denoted as Q), but usually you want the robot to follow trajectories in the XYZ space.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The process of going from the Q space or articular space to the XYZ space is called forward kinematics, and the reverse process is called inverse kinematics. The forward kinematics is usually easier to compute, and is required to compute the inverse kinematics.</div>
<br />
<h3>
Forward kinematics</h3>
<br />
<div style="text-align: justify;">
To compute the forward kinematics, the Denavit Hartenberg approach was used. I won't go into much detail but basically, the Denavit Hartenberg transformation matrices can map positions and orientations from one coordinate system to another.</div>
<br />
<div style="text-align: justify;">
With these Denavit Hartenberg transformation matrices, the position of any body part seen from any other body part (generally one of the feet) can be easy computed.</div>
<br />
<h3>
Inverse Kinematics</h3>
<br />
<div style="text-align: justify;">
Using the forward kinematics, an analytic expression of the position of any body part seen from any other body part can be derived, the inputs of this expression are the joint angles (Q) and the output is the XYZ position. Computing the inverse of this expression is impossible, as there are many solutions.</div>
<br />
<div style="text-align: justify;">
Since no analytical expression for the inverse kinematics can be computed, an iterative method name Damped Least Squares (DLS) was used. I won't cover the mathematics of the DLS method here, but it uses the pseudo jacobian to approach the desired position iteratively.</div>
<br />
<h3>
The trajectory</h3>
<br />
<div style="text-align: justify;">
The chosen gait trajectory consist of a spline for the foot trajectory and another spline for the hip trajectory for the single support phase, i.e. when only one foot is in contact with the floor.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbl6B5GHDNGidPOvqjHll0QCUxN_GmSwJ6Y3rDGS6Ko9HOoNU6-mt4GwVZy5SIcVZJc6JbiYbWe-0UTaVPOx1zxd9IcRzNs9n-KfuyfmDg8BuUsNSos1VBiVBVOAUP9soT-EXhadiKU7g/s1600/trajectory.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbl6B5GHDNGidPOvqjHll0QCUxN_GmSwJ6Y3rDGS6Ko9HOoNU6-mt4GwVZy5SIcVZJc6JbiYbWe-0UTaVPOx1zxd9IcRzNs9n-KfuyfmDg8BuUsNSos1VBiVBVOAUP9soT-EXhadiKU7g/s1600/trajectory.png" /></a></div>
<div style="text-align: center;">
Gait trajectory</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This continuous trajectory was discretized in 50 points, and these points were transformed to the Q space using the inverse kinematics. The Q coordinates computed were finally fed at 50Hz to the servomotors.</div>
<br />
<h3>
The stability indicator</h3>
<br />
<div style="text-align: justify;">
Trying to walk just by using the previous computed references will result in a failure, it's necessary to implement a stability control. And for that we need to select a stability indicator.</div>
<br />
<div style="text-align: justify;">
For this project, we used the Zero Moment Point (ZMP) indicator, which is basically an extension of the concept of center of mass in a dynamic context. You might know that a static object can stay in equilibrium as long as the projection (along the gravity axis) of its center of mass is inside its support polygon.</div>
<br />
<div style="text-align: justify;">
The ZMP takes in consideration the center of mass and the acceleration of the body and must reside inside the support polygon to guarantee the stability of the body.</div>
<br />
<div style="text-align: justify;">
The ZMP indicator computation can be reduced to the cart table problem, as sketched in the following image, for each plane of interest.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgcXrfbkjk3qS5Tc24s9N4q3gHSMzrZFgjj0012ckozpwemaqIMuQn3PipKj2rup0ctIc0pcquKrVr4nW8nZiK9XwWnO0ViEQKjbaplzTfdYMbZdaAH8VByULifZQbpGBpdE1bQS2YHL8/s1600/cartTable.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgcXrfbkjk3qS5Tc24s9N4q3gHSMzrZFgjj0012ckozpwemaqIMuQn3PipKj2rup0ctIc0pcquKrVr4nW8nZiK9XwWnO0ViEQKjbaplzTfdYMbZdaAH8VByULifZQbpGBpdE1bQS2YHL8/s1600/cartTable.png" /></a></div>
<div style="text-align: center;">
Cart table model for the XZ plane.</div>
<br />
<h3>
The stability control</h3>
<br />
<div style="text-align: justify;">
Our problem reduces to keeping the ZMP inside the support polygon, to achieve this we implement two separate controls.</div>
<br />
<ul>
<li style="text-align: justify;">Feet control, maintains the foot parallel to the floor maximizing the support polygon. </li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgt3l3zUhKnwoEHIKBPa0RRLc1G2RBYVF2A5a0ZqP9JwEa9llIshDDfMkYirRH53MOJvWkFoZoNXQF5kdToB3joFUawf3qNM02fMyL7KxRLHwGKXq5JnOlkV1uQMlB7soHhDIcBlDt-mNs/s1600/feetControl.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgt3l3zUhKnwoEHIKBPa0RRLc1G2RBYVF2A5a0ZqP9JwEa9llIshDDfMkYirRH53MOJvWkFoZoNXQF5kdToB3joFUawf3qNM02fMyL7KxRLHwGKXq5JnOlkV1uQMlB7soHhDIcBlDt-mNs/s320/feetControl.png" width="320" /></a></div>
<div style="text-align: center;">
Left: Feet control disabled. Right: Feet control enabled</div>
<ul>
<li style="text-align: justify;">Hip control, move the ZMP inside the support polygon. </li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZ4Y_vHaMnZW5oNG7hPwc8UwnYJ8oY387K9MGuFVSp4aiPfC22VlAVYWFlBacfrl5hQJDsqEOJuip8ZRcWK6X_7EGmky8sTVpn7sKynBBA38WiI9E9X_Z7LBh0B0eaLRiCsyTXM18Mn9M/s1600/hipControl.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZ4Y_vHaMnZW5oNG7hPwc8UwnYJ8oY387K9MGuFVSp4aiPfC22VlAVYWFlBacfrl5hQJDsqEOJuip8ZRcWK6X_7EGmky8sTVpn7sKynBBA38WiI9E9X_Z7LBh0B0eaLRiCsyTXM18Mn9M/s1600/hipControl.png" /></a></div>
<div style="text-align: center;">
Hip control in action, with disturbance at t = .25s.</div>
<div style="text-align: center;">
Yellow: ZMP, Cyan/Magente: Support polygon</div>
<br />
<h3>
The final result</h3>
<br />
<div style="text-align: justify;">
Here is your reward, for getting this far.</div>
<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/DzssA-aHsj8?feature=player_embedded' frameborder='0'></iframe></div>
<br />
<br />
<h3>
Acknowledgements</h3>
<ul>
<li>Prof. Jose Oliden, our advisor</li>
<li>Victor Paredes and Santiago Cortijo, team members</li>
<li>Control systems and Artificial Intelligence Research Group (GISCIA) </li>
<li>National University of Engineering (UNI)</li>
</ul>
<h3>
Related</h3>
<div>
<ul>
<li><a href="http://embeddedprogrammer.blogspot.com/2013/01/simmechanics-simulating-multibody.html">Simulating multibody systems in Simmechanics</a>. (Basic use, robotic arm as example)</li>
<li><a href="http://embeddedprogrammer.blogspot.com/2013/01/simmechanics-simulating-floor.html">Simulating floor interaction/collision in Simmechanics</a>.</li>
</ul>
</div>
Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com22tag:blogger.com,1999:blog-1622983275835621655.post-54652665587275625052012-08-06T12:30:00.000-05:002012-09-07T12:51:07.787-05:00qSerialTerm: Qt based Serial Port Data Acquisition Software with Moving Plots<div style="text-align: justify;">
With its latest update, qSerialTerm can now be use as a Serial Port Data Acquisition System (DAS) or as a Serial Port Terminal Emulator.</div>
<br />
<div style="text-align: justify;">
The DAS mode includes, on top of the data logger feature, a moving plot feature. To achieve these moving plots, qSerialTerm uses <a href="http://sourceforge.net/projects/qwt/">libqwt </a>for plotting. This means, that libqwt is a new dependency for qSerialTerm.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The user can select between these two modes using the "From Device" menu. In the following image, you can see qSerialTerm configured as a DAS.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBCWTav88-4viA_rnkwg5KsM74Z6-mBD3G7lyoE_NWJV0eifAPYgtmLU8Fw_Dc3C3k0QLKM-mTNjW3V14EtX5Exy1VWUHomqqeLbgRt-JEwPoYkic1jAwfjT5_2PIWD2EFfdZqANGJ-3c/s1600/qSerialTerm.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBCWTav88-4viA_rnkwg5KsM74Z6-mBD3G7lyoE_NWJV0eifAPYgtmLU8Fw_Dc3C3k0QLKM-mTNjW3V14EtX5Exy1VWUHomqqeLbgRt-JEwPoYkic1jAwfjT5_2PIWD2EFfdZqANGJ-3c/s320/qSerialTerm.png" width="320" /></a></div>
<div style="text-align: center;">
qSerialTerm in "plot" mode.</div>
<br />
<div style="text-align: justify;">
The user can configure the number of plots and the data type, endianness and format of the incoming data. </div>
<br />
<div style="text-align: justify;">
On the following image, you can see the a fully configured qSerialTerm ready to receive two "variables".</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5DlYE14fE34jJcOAMjMpADdG2e05GeXxASDoxd9zriS4Jk9hxns1fi00xMJSkqw2Z4P5y3wEISeSbuNEa03oCKPuTjP8jOKwrRSkMnpXpzky07d2rcYG2b8QdfQ0k30F-r_C4N_4dZlo/s1600/twoPlots.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5DlYE14fE34jJcOAMjMpADdG2e05GeXxASDoxd9zriS4Jk9hxns1fi00xMJSkqw2Z4P5y3wEISeSbuNEa03oCKPuTjP8jOKwrRSkMnpXpzky07d2rcYG2b8QdfQ0k30F-r_C4N_4dZlo/s320/twoPlots.png" width="320" /></a></div>
<div style="text-align: center;">
qSerialTerm configured for two plots.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
These "variables" must be grouped as packets, e.g. let's say we want to plot 3 variables, these variables are floats, and are encoded as little endian raw binary. Each packet of data will contain one data point for each variable, summing a total of 12 bytes (4 bytes per float) per packet.</div>
<br />
<table align="center" border="1">
<tbody>
<tr>
<td style="text-align: center;">Packet</td>
<td style="text-align: center;">Variable 1</td>
<td style="text-align: center;">Variable 2</td>
<td style="text-align: center;">Variable 3</td>
</tr>
<tr>
<td style="text-align: center;">1</td>
<td style="text-align: center;">float1</td>
<td style="text-align: center;">float2</td>
<td style="text-align: center;">float3</td>
</tr>
<tr>
<td style="text-align: center;">2</td>
<td style="text-align: center;">float4</td>
<td style="text-align: center;">float5</td>
<td style="text-align: center;">float6</td>
</tr>
</tbody></table>
<div style="text-align: center;">
Two structured packets</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
qSerialTerm should receive these two packets in the following order: float1, then float2, and so on until float 6. Then, two data points will be added to each plot. </div>
<div style="text-align: justify;">
<br /></div>
<h3>
Demostration</h3>
<br />
<div style="text-align: justify;">
I'll now show some screenshots of qSerialTerm in operation. For these demos, I shorted the TX and RX lines of my USB <-> Serial converter, this means that every byte I send from the PC was echoed back to the PC.</div>
<br />
<div style="text-align: justify;">
The data was sent using the qSerialTerm's <a href="http://embeddedprogrammer.blogspot.com/2012/08/qserialterm-serial-port-servomotor.html">"frame" feature</a>. Using the continuous mode, I sent data, whose values varied with sliders, this data echoed back to the PC, and ended being added to the plots.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinXV2LowBJduGfsHhXa0Z6pgsEkgPrW97oMKcvp72MP0ZdXDLKWAmssClir_wi40ZxO7Qz7-gRnI8lJrGUo_MiI7uyQnsDx2dAVc1-L6OwherRFZpNc0NKjZQpjLfYSUgluW2nt1VDXL0/s1600/rawBinary.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinXV2LowBJduGfsHhXa0Z6pgsEkgPrW97oMKcvp72MP0ZdXDLKWAmssClir_wi40ZxO7Qz7-gRnI8lJrGUo_MiI7uyQnsDx2dAVc1-L6OwherRFZpNc0NKjZQpjLfYSUgluW2nt1VDXL0/s320/rawBinary.png" width="320" /></a></div>
<div style="text-align: center;">
1 uint8 variable</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijwCotP6i3bpD383py5z_aS6KlvrMb3xHtVTq1p3KA99tksJJPcBgbK8j1H-QtEqkUN_fu5i2WTmbyhu9-HYy_BHgDqEXpRJDpSXwsSDW8VpaQJHhJXVnzgXFN-cH3tZ-bhJSzGcLzKAU/s1600/twoPlotsDemo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijwCotP6i3bpD383py5z_aS6KlvrMb3xHtVTq1p3KA99tksJJPcBgbK8j1H-QtEqkUN_fu5i2WTmbyhu9-HYy_BHgDqEXpRJDpSXwsSDW8VpaQJHhJXVnzgXFN-cH3tZ-bhJSzGcLzKAU/s320/twoPlotsDemo.png" width="320" /></a></div>
<div style="text-align: center;">
2 int8 variables</div>
<br />
I'll post a demo video later.<br />
<br />
<h3>
Repository</h3>
<br />
You can get qSerialTerm source code from this <a href="https://github.com/JorgeAparicio/qSerialTerm">repository</a>.<br />
<br />
<b>More information</b><br />
<br />
<a href="http://embeddedprogrammer.blogspot.com/2012/06/qserialterm-qt-based-serial-port.html">qSerialTerm as a serial port terminal emulator</a><br />
<a href="http://embeddedprogrammer.blogspot.com/2012/08/qserialterm-improved-and-now-can-be.html">qSerialTerm for data logging</a> <br />
<a href="http://embeddedprogrammer.blogspot.com/2012/08/qserialterm-serial-port-servomotor.html">qSerialTerm for serial servomotor control</a><br />
<a href="http://embeddedprogrammer.blogspot.com/2012/09/qserialterm-qt-based-serial-port-image.html">qSerialTerm for image visualization</a> Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com5tag:blogger.com,1999:blog-1622983275835621655.post-8980140685993423112012-08-04T23:34:00.000-05:002012-09-07T12:50:37.009-05:00qSerialTerm: Serial port servomotor control<div style="text-align: justify;">
qSerialTerm, a Qt based serial port terminal emulator, now supports a "frame" feature, intended for servomotor control applications.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This "frame" feature allows the user to send multiple data points (uint8, int8, etc) grouped in a frame. The user can send this frame by click a button or choose to periodically send these frames via a checkbox.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The value of these data points can be varied via a slider or, alternatively, via a spin box. The frame can be sent in two formats: Raw binary or hexadecimal string, where each byte is represented by two characters. e.g. 31 (one raw binary byte) or "1F" (hexadecimal string = 2 bytes).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The minimum and maximum values for the data points and the <a href="http://en.wikipedia.org/wiki/Endianness">endianness</a> of data points can also be specified by the user.</div>
<br />
<div style="text-align: justify;">
Additionally, the user can append one byte and/or prepend one byte to the frame.</div>
<br />
<div style="text-align: justify;">
A image is worth a thousand of words, the above description will be clearer with the following image.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpkSGy3ffXaNBke44KA5ynIMRaYdvp7fdI4ChL6tz_qO1gzq4aK_exx11YHEPiiP49NzaUv8SIQtQCP1g6kxa5EL2qyT9CxPr2JSYevLgc85BlSjESCQwnLa1Cjc_3oD3dQWrLcDDYMnY/s1600/qSerialTerm.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpkSGy3ffXaNBke44KA5ynIMRaYdvp7fdI4ChL6tz_qO1gzq4aK_exx11YHEPiiP49NzaUv8SIQtQCP1g6kxa5EL2qyT9CxPr2JSYevLgc85BlSjESCQwnLa1Cjc_3oD3dQWrLcDDYMnY/s320/qSerialTerm.png" width="320" /></a></div>
<div style="text-align: center;">
qSerialTerm frame feature</div>
<br />
<div style="text-align: justify;">
In the following sections, I'll show you some usage of this frame feature.</div>
<br />
<h3>
Raw binary format</h3>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDho10EELw2KuBBkF_EZknULSjOiIIrIFMgPonCKad5NPfu5I3AiXVnEl2HsHm59afhpE9WE7MbE7MWpaqK-T1d4OgqAn-VWR7x1zUUocpP0JwrOmJ9hmTX6Z-KtgYDtbs6qRj5IQQ7ug/s1600/rawBinary.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDho10EELw2KuBBkF_EZknULSjOiIIrIFMgPonCKad5NPfu5I3AiXVnEl2HsHm59afhpE9WE7MbE7MWpaqK-T1d4OgqAn-VWR7x1zUUocpP0JwrOmJ9hmTX6Z-KtgYDtbs6qRj5IQQ7ug/s320/rawBinary.png" width="320" /></a></div>
<div style="text-align: center;">
Raw binary format</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
For this example, the frame was composed of these bytes: 48, 49, 50, 51; and sent in raw binary format. These bytes are equivalent to the '0', '1', '2' and '3' characters shown in the terminal.</div>
<br />
<h3>
Hexadecimal string format and endianness</h3>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiakoziDrVR0dKoY500MCRiMlJF47L21O4CZm_MauGVoEMXBXh3A-nnpXaJWGixIzM8A22zCM-M6YTR2oC-zI0TIjWoTIYBdfUM5HybulAv5CY6S_h7vUA_P54LKM8HcsGCeY0OCNAbPd4/s1600/hexString.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiakoziDrVR0dKoY500MCRiMlJF47L21O4CZm_MauGVoEMXBXh3A-nnpXaJWGixIzM8A22zCM-M6YTR2oC-zI0TIjWoTIYBdfUM5HybulAv5CY6S_h7vUA_P54LKM8HcsGCeY0OCNAbPd4/s320/hexString.png" width="320" /></a></div>
<div style="text-align: center;">
Hexadecimal string format</div>
<br />
<div style="text-align: justify;">
In this example, these 4 words (uint16): 15, 255, 4095 and 65535 were sent in hexadecimal string format.</div>
<br />
<div style="text-align: justify;">
Notice that these 4 words should take 8 bytes, however the hexadecimal string format takes 16 characters (bytes).</div>
<br />
<div style="text-align: justify;">
Also the frame is in little endian format, this means that the least significant byte occupies the the lowest memory address. e.g. the word 15 is represented as 0x000F in big endian format, and represented as 0x0F00 in little endian format.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Finally, in little endian format 15 -> 0x0F00, 255 -> 0xFF00, 4095 ->0xFF0F and 65535 -> 0xFFFF. All this results in the following string: "0F00FF00FF0FFFFF", which is shown in the terminal.</div>
<br />
<h3>
Servomotor control demo</h3>
<br />
<div style="text-align: justify;">
I owe you this one for now. I've used this software to send signal controls to a robot. I'll post a video later.</div>
<br />
<h3>
Repository</h3>
<br />
qSerialTerm source code is available in this <a href="https://github.com/JorgeAparicio/qSerialTerm">repository</a>.<br />
<br />
<h3>
More information</h3>
<br />
<a href="http://embeddedprogrammer.blogspot.com/2012/06/qserialterm-qt-based-serial-port.html">qSerialTerm as a serial port emulator</a><br />
<a href="http://embeddedprogrammer.blogspot.com/2012/08/qserialterm-improved-and-now-can-be.html">qSerialTerm for data logging </a><br />
<a href="http://embeddedprogrammer.blogspot.com/2012/08/qserialterm-qt-based-serial-port-data.html">qSerialTerm for data acquisition</a><br />
<a href="http://embeddedprogrammer.blogspot.com/2012/09/qserialterm-qt-based-serial-port-image.html">qSerialTerm for image visualization</a> <br />
<br />Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com2tag:blogger.com,1999:blog-1622983275835621655.post-16403873332629551082012-08-01T00:17:00.000-05:002012-09-07T12:47:25.520-05:00qSerialTerm: Improved and now can be used as Data Logger<div style="text-align: justify;">
qSerialTerm, the Qt based serial port emulator, has been improved from <a href="http://embeddedprogrammer.blogspot.com/2012/06/qserialterm-qt-based-serial-port.html">its first version</a>, and now has a data logging feature, all the improvements are listed below:</div>
<br />
<ul>
<li>Added data logging feature (rewrite file or append to file).</li>
<li>Reading data from the serial port is now periodic.</li>
<li>Fixed lose of focus when data is received.</li>
<li>Rearranged docks.</li>
<li>Docks can be called back from the "View" menu.</li>
</ul>
<div style="text-align: justify;">
<br />
You can see below the new looks of qSerialTerm.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiorioew4WXBv9FXK6L04NB2PFfu55wy31S2z0qGK_v93teHazMO2cq66XzXerBLya40bZ_mcgcieMgj6KtYG87TmEAh-W1v6DqK44DK5sx-o46KXMIipLjcDFLqcewy0Vj_keN82BzzKk/s1600/newLooks.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiorioew4WXBv9FXK6L04NB2PFfu55wy31S2z0qGK_v93teHazMO2cq66XzXerBLya40bZ_mcgcieMgj6KtYG87TmEAh-W1v6DqK44DK5sx-o46KXMIipLjcDFLqcewy0Vj_keN82BzzKk/s320/newLooks.png" width="320" /></a></div>
<div style="text-align: center;">
</div>
<div style="text-align: center;">
qSerialTerm new looks
</div>
<br />
<div style="text-align: justify;">
I'll now show you via images the new logging feature. Below you can see the log file selection dialog.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAixVgXNceMUzc7klac2zoy6hkju6Wj_2x7eRoL7yhHQ-HHv9oouSk5R1zAtdgrs1Xt2Kdv07IH0hF0aVBVWKrgF7jSJNJ-4Ahq1i4dHJOP6FVOna2ExjXF3zWtybPn6bvawUwaQbRUIU/s1600/selectLogFile.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAixVgXNceMUzc7klac2zoy6hkju6Wj_2x7eRoL7yhHQ-HHv9oouSk5R1zAtdgrs1Xt2Kdv07IH0hF0aVBVWKrgF7jSJNJ-4Ahq1i4dHJOP6FVOna2ExjXF3zWtybPn6bvawUwaQbRUIU/s320/selectLogFile.png" width="320" /></a></div>
<div style="text-align: center;">
Selecting the log file.</div>
<br />
<div style="text-align: justify;">
Before start logging, you can select whether to overwrite or to append to an existing file, using the "append" checkbox. After you start logging, a timer will show for how long you have been logging.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgG_VgXXnvoSra3ZT3q_Ps-bxaRfuHdt0dCJ5LKiOjxS0EbvzeM6cTD5BnjZ-LxvCM0qsvJhEtgXrYXw0hKJiPLRItt3ttcrZ_rgrrI7uqC0jRw-YzM-dH5nf9hq8QEoy_uIg1iNtDgRrw/s1600/testingLogging.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgG_VgXXnvoSra3ZT3q_Ps-bxaRfuHdt0dCJ5LKiOjxS0EbvzeM6cTD5BnjZ-LxvCM0qsvJhEtgXrYXw0hKJiPLRItt3ttcrZ_rgrrI7uqC0jRw-YzM-dH5nf9hq8QEoy_uIg1iNtDgRrw/s320/testingLogging.png" width="320" /></a></div>
<div style="text-align: center;">
Testing the logging feature.</div>
<br />
<div style="text-align: justify;">
On the following image, you can see the contents of the "log.txt"</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjFwU-usSkEnwVc3_TJpOUxQkOmSUDg66W8lziwypYZUGexRPhEGhShXZvG-UFlzC9oYYeJG0fNCPmE5fjRxFuxBkumiYhVgr6jYlLV0B8a9uNXH_LYXoBprLin7WQ4j5dRICBDHNZJOw/s1600/checkingTheLogFile.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjFwU-usSkEnwVc3_TJpOUxQkOmSUDg66W8lziwypYZUGexRPhEGhShXZvG-UFlzC9oYYeJG0fNCPmE5fjRxFuxBkumiYhVgr6jYlLV0B8a9uNXH_LYXoBprLin7WQ4j5dRICBDHNZJOw/s320/checkingTheLogFile.png" width="320" /></a></div>
<div style="text-align: center;">
Checking the log file.</div>
<br />
<h3>
Repository</h3>
<br />
<div style="text-align: justify;">
You can get the source code in this <a href="https://github.com/JorgeAparicio/qSerialTerm">repository</a>.<br />
<br />
<h3>
More information </h3>
<br />
<a href="http://embeddedprogrammer.blogspot.com/2012/06/qserialterm-qt-based-serial-port.html">qSerialTerm as serial port terminal emulator</a><br />
<a href="http://embeddedprogrammer.blogspot.com/2012/08/qserialterm-serial-port-servomotor.html">qSerialTerm for servomotor control</a><br />
<a href="http://embeddedprogrammer.blogspot.com/2012/08/qserialterm-qt-based-serial-port-data.html">qSerialTerm for data acquisition</a><br />
<a href="http://embeddedprogrammer.blogspot.com/2012/09/qserialterm-qt-based-serial-port-image.html">qSerialTerm for image visualization</a> </div>
Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com8tag:blogger.com,1999:blog-1622983275835621655.post-55061072778925192592012-07-23T16:38:00.002-05:002013-02-17T11:17:28.830-05:00Hacking the OV7670 camera module (SCCB cheat sheet inside)<i>An in-depth look of the OV7670 camera module</i> <br />
<br />
<div style="text-align: justify;">
The OV7670 is a low cost image sensor + DSP that can operate at a maximum of 30 fps and 640 x 480 ("VGA") resolutions, equivalent to 0.3 Megapixels. The captured image can be pre-processed by the DSP before sending it out. This preprocessing can be configured via the Serial Camera Control Bus (SCCB). You can see the full datasheet <a href="http://www.eleparts.co.kr/data/design/product_file/Board/OV7670_CMOS.pdf">here</a>.</div>
<br />
<div style="text-align: justify;">
There are many camera modules, that come with standard 0.1" spaced headers, in eBay with prices under $10. I'll be using the one shown below, it comes WITHOUT a FIFO buffer.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7IcW5C8cEoKREojebqQZUka0sAfCMms8J5ZZMz8aS8rvtDK59ywPr9pjBS1W0l7yHOa-12qZs_zPP_2VUpaTwgEq9KXNbDP-bAOtsx3xdaErjapFIBeGIdA3ZqE42uksdWpSYlwbmaOY/s1600/ov7670.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="193" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7IcW5C8cEoKREojebqQZUka0sAfCMms8J5ZZMz8aS8rvtDK59ywPr9pjBS1W0l7yHOa-12qZs_zPP_2VUpaTwgEq9KXNbDP-bAOtsx3xdaErjapFIBeGIdA3ZqE42uksdWpSYlwbmaOY/s200/ov7670.JPG" width="200" /></a></div>
<br />
<br />
<h3>
HARDWARE
</h3>
<br />
<div style="text-align: justify;">
The camera module comes with a 9x2 header, the pin diagram is shown below:</div>
<br />
<table align="center" border="1">
<tbody>
<tr>
<td style="text-align: center;">VDD</td>
<td style="text-align: center;">GND</td>
</tr>
<tr>
<td style="text-align: center;">SDIOC</td>
<td style="text-align: center;">SDIOD</td>
</tr>
<tr>
<td style="text-align: center;">VSYNC</td>
<td style="text-align: center;">HREF</td>
</tr>
<tr>
<td style="text-align: center;">PCLK</td>
<td style="text-align: center;">XCLK</td>
</tr>
<tr>
<td style="text-align: center;">D7</td>
<td style="text-align: center;">D6</td>
</tr>
<tr>
<td style="text-align: center;">D5</td>
<td style="text-align: center;">D4</td>
</tr>
<tr>
<td style="text-align: center;">D3</td>
<td style="text-align: center;">D2</td>
</tr>
<tr>
<td style="text-align: center;">D1</td>
<td style="text-align: center;">D0</td>
</tr>
<tr>
<td style="text-align: center;">RESET</td>
<td style="text-align: center;">PWDN</td>
</tr>
</tbody></table>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now, I'll cover the meaning of these pins.</div>
<br />
<table align="center" border="1">
<tbody>
<tr>
<th>Pin</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td style="text-align: center;">VDD**</td>
<td style="text-align: center;">Supply</td>
<td>Power supply</td>
</tr>
<tr>
<td style="text-align: center;">GND</td>
<td style="text-align: center;">Supply</td>
<td>Ground level</td>
</tr>
<tr>
<td style="text-align: center;">SDIOC</td>
<td style="text-align: center;">Input</td>
<td>SCCB clock</td>
</tr>
<tr>
<td style="text-align: center;">SDIOD</td>
<td style="text-align: center;">Input/Output</td>
<td>SCCB data</td>
</tr>
<tr>
<td style="text-align: center;">VSYNC</td>
<td style="text-align: center;">Output</td>
<td>Vertical synchronization</td>
</tr>
<tr>
<td style="text-align: center;">HREF</td>
<td style="text-align: center;">Output</td>
<td>Horizontal synchronization</td>
</tr>
<tr>
<td style="text-align: center;">PCLK</td>
<td style="text-align: center;">Output</td>
<td>Pixel clock</td>
</tr>
<tr>
<td style="text-align: center;">XCLK</td>
<td style="text-align: center;">Input</td>
<td>System clock</td>
</tr>
<tr>
<td style="text-align: center;">D0-D7</td>
<td style="text-align: center;">Output</td>
<td>Video parallel output</td>
</tr>
<tr>
<td style="text-align: center;">RESET</td>
<td style="text-align: center;">Input</td>
<td>Reset (Active low)</td>
</tr>
<tr>
<td style="text-align: center;">PWDN</td>
<td style="text-align: center;">Input</td>
<td>Power down (Active high)</td>
</tr>
</tbody></table>
<br />
<h4>
**A note about supply voltage and I/O voltage.</h4>
<br />
As stated in the datasheet:<br />
<br />
<ul>
<li>VDDA can range from 2.45V to 3.00V.</li>
<li>VDDC can range from 1.62V to 1.98V.</li>
<li>VDDIO can range from 1.7V to 3.00V.</li>
</ul>
<br />
<div style="text-align: justify;">
You can (hopefully) see <a href="http://www.gemmarduino.net/PM1/1-170/OV7670.rar">here</a> (sorry, it's buried among other files) the schematic of the model I'm using in this post. As you can see U1 and U2 are LDO regulators, one is a 2.8V regulator for VDDA and VDDIO and the other is a 1.8V regulator for VDDC. The actual regulator that gets soldered on the module seems to vary between modules.</div>
<br />
In conclusion, for the same model I'm using:<br />
<br />
<ul>
<li style="text-align: justify;">You can <i>safely</i> supply 3.3V (3.0V - 3.6V) to the OV7670 VDD. (I used this configuration)</li>
<li style="text-align: justify;">You can <i>safely</i> use a maximum of 3.0V for the I/O pins. However the module <i>I/O pins will work at 2.8V</i>.</li>
<li style="text-align: justify;">A 5V supply for the OV7670 VDD <i>might</i> work (try at your own risk), it depends on the maximum input voltage of the LDO regulators <i>your module</i> has.</li>
<li style="text-align: justify;">You can use 3.3V on the I/O pins, the internal I/O protection diodes will clamp the I/O voltage to 2.8V. <i>However</i>, this may degrade the OV7670 faster and/or cause more power loss. (I used this configuration)</li>
</ul>
<br />
<br />
<h3>
STRUCTURE OF AN IMAGE
</h3>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Before going into the signaling, it's necessary to understand how video and images are representend in digital format.</div>
<br />
<div style="text-align: justify;">
A video is a succession of <i><b>frames</b></i>, a frame is a still image taken at an instant of time. A frame is compromised of <b><i>lines</i></b>, and a line is compromised of <i><b>pixels</b></i>. A pixel is the smallest part of a digital image, and it looks like a colored dot.</div>
<br />
<table align="center" border="1">
<tbody>
<tr>
<td></td>
<td>P0</td>
<td>P1</td>
<td>P2</td>
<td>P3</td>
<td>P4</td>
</tr>
<tr>
<td>L0</td>
<td bgcolor="#000000"></td>
<td bgcolor="#1E1E1E"></td>
<td bgcolor="#3C3C3C"></td>
<td bgcolor="#5A5A5A"></td>
<td bgcolor="#787878"></td>
</tr>
<tr>
<td>L1</td>
<td bgcolor="#1E1E1E"></td>
<td bgcolor="#3C3C3C"></td>
<td bgcolor="#5A5A5A"></td>
<td bgcolor="#787878"></td>
<td bgcolor="#969696"></td>
</tr>
<tr>
<td>L2</td>
<td bgcolor="#3C3C3C"></td>
<td bgcolor="#5A5A5A"></td>
<td bgcolor="#787878"></td>
<td bgcolor="#969696"></td>
<td bgcolor="#B4B4B4"></td>
</tr>
<tr>
<td>L3</td>
<td bgcolor="#5A5A5A"></td>
<td bgcolor="#787878"></td>
<td bgcolor="#969696"></td>
<td bgcolor="#B4B4B4"></td>
<td bgcolor="#D2D2D2"></td>
</tr>
<tr>
<td>L4</td>
<td bgcolor="#787878"></td>
<td bgcolor="#969696"></td>
<td bgcolor="#B4B4B4"></td>
<td bgcolor="#D2D2D2"></td>
<td bgcolor="#F0F0F0"></td>
</tr>
</tbody></table>
<div style="text-align: center;">
A 5x5 image</div>
<br />
<div style="text-align: justify;">
For example, the image above has 5 lines, and each line has 5 pixels. This means the image has a resolution of 5x5 pixels. This image is monochrome, there are also color image. This color can be encoded in various formats, in the next section we'll cover the most relevant formats for the OV7670.</div>
<br />
<h3>
PIXEL FORMATS
</h3>
<br />
<h4>
Monochrome
</h4>
<br />
<div style="text-align: justify;">
In monochromes images, each pixel is stored as 8 bits, representing gray scale levels from 0 to 255. Where 0 is black, 255 is white and the intermediate values are grays.</div>
<br />
<h4>
RGB
</h4>
<br />
<div style="text-align: justify;">
Is a fact that any color can be decomposed in red, green and blue light at different intensities. This approach is known as the <a href="http://en.wikipedia.org/wiki/RGB_color_model">RGB color model</a>. Using this model, each pixel must be stored as three intensities of these red, green and blue lights.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://upload.wikimedia.org/wikipedia/commons/2/28/RGB_illumination.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://upload.wikimedia.org/wikipedia/commons/2/28/RGB_illumination.jpg" width="320" /></a></div>
<div style="text-align: center;">
RGB color model. Image from <a href="http://en.wikipedia.org/wiki/Rgb">wikipedia</a>.</div>
<br />
<br />
<div style="text-align: justify;">
The most common format is RGB888, in this format each pixel is stored in 24 bits, the red, green and blue channels are stored in 8 bits each. This means that the intensity of each light can go from 0 to 255, where 0 is the absence of light, and 255 is the maximum intensity.</div>
<br />
<div style="text-align: justify;">
The formats used by the OV7670 are the RGB565, RGB555 and RGB444. The difference with the RGB888 format, is the number of bits assigned to each channel. For example, in the RGB565 format, the red channel is stored as 5 bits, the green channel as 6 bits and the blue channel as 5 bits. These formats take less memory when stored but in exchange sacrifice the number of colors available.</div>
<br />
<h4>
YCbCr
</h4>
<br />
<div style="text-align: justify;">
YCbCr is a format in which a RGB color can be encoded. The Y or luminance component is the amount of white light of a color, and the Cb and Cr are the chroma components, which respectly encode the blue and red levels relative to the luminance component.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://upload.wikimedia.org/wikipedia/commons/2/29/Barn-yuv.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://upload.wikimedia.org/wikipedia/commons/2/29/Barn-yuv.png" width="105" /></a></div>
<div style="text-align: center;">
Decomposition of an image into its Y, Cb and Cr components. Image from <a href="http://en.wikipedia.org/wiki/Ycbcr">wikipedia</a>.</div>
<br />
<div style="text-align: justify;">
As you can see the Y channel encodes the gray scale levels of the image. Therefore, the easiest way to get a monochrome image from the OV7670 is to extract the Y channel of the YCbCr format.</div>
<br />
<div style="text-align: justify;">
As the RGB format, the YCbCr also stores each channel as 8 bits (from 0 to 255) and we can convert from YCbCr to RGB using the following expression.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://upload.wikimedia.org/wikipedia/en/math/4/e/b/4ebf7992636ec7100e2f0f68a4f2c2ca.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="52" src="http://upload.wikimedia.org/wikipedia/en/math/4/e/b/4ebf7992636ec7100e2f0f68a4f2c2ca.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
The OV7670 uses the YCbCr422 format, this format is stored as follows:</div>
<br />
<table align="center" border="1">
<tbody>
<tr>
<td><br /></td>
<td>Byte 0</td>
<td>Byte 1</td>
<td>Byte 2</td>
<td>Byte 3</td>
</tr>
<tr>
<td>Word 0</td>
<td><div style="text-align: center;">
Cb0</div>
</td>
<td><div style="text-align: center;">
Y0</div>
</td>
<td><div style="text-align: center;">
Cr0</div>
</td>
<td><div style="text-align: center;">
Y1</div>
</td>
</tr>
<tr>
<td>Word 1</td>
<td><div style="text-align: center;">
Cb2</div>
</td>
<td><div style="text-align: center;">
Y2</div>
</td>
<td><div style="text-align: center;">
Cr2</div>
</td>
<td><div style="text-align: center;">
Y3</div>
</td>
</tr>
<tr>
<td>Word 2</td>
<td><div style="text-align: center;">
Cb4</div>
</td>
<td><div style="text-align: center;">
Y4</div>
</td>
<td><div style="text-align: center;">
Cr4</div>
</td>
<td><div style="text-align: center;">
Y5</div>
</td>
</tr>
</tbody>
</table>
<div style="text-align: center;">
Data stored as words (4 bytes)</div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: justify;">
Or equivalently, the data arrives in the following order:</div>
<br />
<table align="center" border="1">
<tbody>
<tr>
<td><div style="text-align: center;">
N</div>
</td>
<td><div style="text-align: center;">
Byte</div>
</td>
</tr>
<tr>
<td><div style="text-align: center;">
1st</div>
</td>
<td><div style="text-align: center;">
Cb0</div>
</td>
</tr>
<tr>
<td><div style="text-align: center;">
2nd</div>
</td>
<td><div style="text-align: center;">
Y0</div>
</td>
</tr>
<tr>
<td><div style="text-align: center;">
3rd</div>
</td>
<td><div style="text-align: center;">
Cr0</div>
</td>
</tr>
<tr>
<td><div style="text-align: center;">
4th</div>
</td>
<td><div style="text-align: center;">
Y1</div>
</td>
</tr>
<tr>
<td><div style="text-align: center;">
5th</div>
</td>
<td><div style="text-align: center;">
Cb2</div>
</td>
</tr>
<tr>
<td><div style="text-align: center;">
6th</div>
</td>
<td><div style="text-align: center;">
Y2</div>
</td>
</tr>
<tr>
<td><div style="text-align: center;">
7th</div>
</td>
<td><div style="text-align: center;">
Cr2</div>
</td>
</tr>
<tr>
<td><div style="text-align: center;">
8th</div>
</td>
<td><div style="text-align: center;">
Y3</div>
</td>
</tr>
<tr>
<td><div style="text-align: center;">
...</div>
</td>
<td><div style="text-align: center;">
...</div>
</td>
</tr>
</tbody></table>
<br />
<div style="text-align: justify;">
And the actual pixels are the following:</div>
<br />
<table align="center" border="1">
<tbody>
<tr>
<td>Pixel 0</td>
<td>Y0 Cb0 Cr0</td>
</tr>
<tr>
<td>Pixel 1</td>
<td>Y1 Cb0 Cr0</td>
</tr>
<tr>
<td>Pixel 2</td>
<td>Y2 Cb2 Cr2</td>
</tr>
<tr>
<td>Pixel 3</td>
<td>Y3 Cb2 Cr2</td>
</tr>
<tr>
<td>Pixel 4</td>
<td>Y4 Cb4 Cr4</td>
</tr>
<tr>
<td>Pixel 5</td>
<td>Y5 Cb4 Cr4</td>
</tr>
</tbody>
</table>
<br />
<div style="text-align: justify;">
Notice each pixel is 3 byte long (e.g. Y0, Cb0 and Cr0), as in the RGB format. But, in the YCbCr422 format, the Cb and Cr channels are shared between two consecutive pixels (e.g. pixels 0 and 1 share Cb0 and Cr0). Therefore two pixels are "compressed" into 4 bytes or 32 bits, this means that in average each pixel is stored as 2 bytes or 16 bits. From the example above, 3 words (12 bytes) store 6 pixels.<br />
<br />
The extra advantage of YCbCr is that the Y channel is the grayscale image, whereas in RGB you'll need to average the 3 channels to get the grayscale image.</div>
<br />
<h3>
SIGNALING
</h3>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The OV7670 sends the data in a parallel synchronous format. First of all, to get any data out of the OV7670, is necessary to <b><i>supply a clock signal on the XCLK pin</i></b>. According to the datasheet, this clock must have a frequency between 10 and 48 MHz. However, I have successfully used a 8 MHz clock with some configuration via the SCCB.</div>
<br />
<div style="text-align: justify;">
If you are using a microcontroller that has clock output, you can use that to clock the OV7670, these can generally output their inner system clock prescaled by some factor. If your microcontroller doesn't have clock output capability, but you're using an external crystal, then you can connect the OSC_OUT pin to the OV7670.</div>
<br />
<div style="text-align: justify;">
After a clock signal has been applied to the XCLK pin, the OV7670 will start driving its VSYNC, HREF and D0-D7 pins. Let's take a look at these signals.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9FVs2rvQ1Am9ygT3yPVQRAFJUV88hW6IzX0nvytRfFa1a4TT_CJm_3QteogEO-3X5mYfDLGAk4rNjCpIi_BLAAPYdoq5QffEP7SAeYvKdXOjbCjJuiJIQXzP_lu46BCiG4dIxF1B42xM/s1600/href.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="143" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9FVs2rvQ1Am9ygT3yPVQRAFJUV88hW6IzX0nvytRfFa1a4TT_CJm_3QteogEO-3X5mYfDLGAk4rNjCpIi_BLAAPYdoq5QffEP7SAeYvKdXOjbCjJuiJIQXzP_lu46BCiG4dIxF1B42xM/s320/href.png" width="320" /></a></div>
<div style="text-align: center;">
Horizontal Synchronization</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
First thing to notice, the D0-D7 must be sampled at the rising edge of the PCLK signal. Number two, D0-D7 must be sampled only when HREF is high. Also, the rising edge of HREF signals the start of a line, and the falling edge of HREF signals the end of the line.</div>
<br />
<div style="text-align: justify;">
All these bytes sampled when HREF was high, correspond to the pixels in one line. Note that <i><b>one byte is not a pixel</b></i>, it depends on the format chosen. By default, the format is YCbCr422, this means that in average two bytes correspond to a pixel.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgj8q6VptxgELcaATkwV0i2GB7S7vw52D1hHKsxwk8BNGey4gPYwZC6sbGVZqqqUkcEsZOBfX0_xTBGu1g1rsiyUiLsilISAQhXZZth_EqguhiYTugU1BF4BFrzNaJWAg9PANG2vxE2Qj4/s1600/vga.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="139" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgj8q6VptxgELcaATkwV0i2GB7S7vw52D1hHKsxwk8BNGey4gPYwZC6sbGVZqqqUkcEsZOBfX0_xTBGu1g1rsiyUiLsilISAQhXZZth_EqguhiYTugU1BF4BFrzNaJWAg9PANG2vxE2Qj4/s320/vga.png" width="320" /></a></div>
<div style="text-align: center;">
VGA timing</div>
<br />
<div style="text-align: justify;">
The image above shows the signals for a "VGA" (640 x 480) frame. During HSYNC high state, we must capture 640 pixels, equivalent to a line. The 480 lines, equivalent to a frame, are captured during the low state of VSYNC. This means that the falling edge of VSYNC signals the start of a frame, and its rising edge signals the end of a frame.</div>
<br />
<div style="text-align: justify;">
That covers all the process of obtaining one frame, the remaining question is how fast are frames sent. By default, the PCLK will have the same frequency of XCLK, however prescalers and PPLs can be configured using the SCCB, to produce a PCLK of different frequency.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
A PCLK of 24 MHz will produce 30 fps, a PCLK of 12 MHz will produce 15 fps and so on. All this is independent of the format of the image (VGA, CIF, QCIF, etc).</div>
<br />
<h3>
SCCB (Serial Camera Control Bus)
</h3>
<br />
<div style="text-align: justify;">
What makes the OV7670 so versatile is its inner DSP, that can pre-process the image before its sent. This DSP can be accessed via a SCCB interface. This SCCB protocol is very similar to the I2C protocol. You can see the SCCB specification <a href="http://www.ovt.com/download_document.php?type=document&DID=63">here</a>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I couldn't get my STM32 microcontroller's I2C module to work with the OV7670's SCCB interface, so I implemented a <a href="https://github.com/JorgeAparicio/libstm32pp/blob/master/bits/sccb.tcc">bit bang version of the SCCB specification</a>. This implementation is my peripheral library <a href="http://embeddedprogrammer.blogspot.com/2012/07/open-source-template-peripheral-library.html">libstm32pp</a>.</div>
<br />
<div style="text-align: justify;">
After making sure the SCCB is working, we can tweak the OV7670.</div>
<br />
<h4>
Changing the FPS
</h4>
<div style="text-align: justify;">
<br />
To change the frames per second (fps), we need to change the frequency of PCLK. And for that we need to modify the following registers via the SCCB.</div>
<br />
<table align="center" border="1">
<tbody>
<tr><th>Register
</th>
<th>Address
</th>
<th>Default
</th>
<th>Description
</th>
</tr>
<tr>
<td style="text-align: center;">CLKRC</td>
<td style="text-align: center;">0x11</td>
<td style="text-align: center;">0x80</td>
<td><table>
<tbody>
<tr>
<td><b><i>Bit[6]:</i></b><br />
<span style="color: white;"><br /></span></td>
<td><b><i>0: Apply prescaler on input clock </i></b><br />
<b><i>1: Use external clock directly</i></b></td>
</tr>
<tr>
<td><b><i>Bit[0-5]:</i></b><br />
<br />
<br /></td>
<td><b><i>Clock prescaler</i></b><br />
<b><i>F(internal clock) = F(input clock) / (Bit[0-5] + 1)</i></b><br />
<b><i>Range [0 0000] to [1 1111]</i></b></td>
</tr>
</tbody></table>
</td>
</tr>
<tr>
<td style="text-align: center;">DBLV</td>
<td style="text-align: center;">0x6B</td>
<td style="text-align: center;">0x0A</td>
<td><table>
<tbody>
<tr>
<td><b><i>Bit[7-6]:</i></b><br />
<br />
<br />
<br />
<br /></td>
<td><b><i>PLL control</i></b><br />
<b><i>00: Bypass PLL</i></b><br />
<b><i>01: Input clock x4</i></b><br />
<b><i>10: Input clock x6</i></b><br />
<b><i>11: Input clock x8</i></b></td>
</tr>
<tr>
<td>Bit[4]:<br />
<br />
<br /></td>
<td>Regulator control<br />
0: Enable internal regulator<br />
1: Bypass internal regulator</td>
</tr>
</tbody></table>
</td>
</tr>
</tbody></table>
<br />
<div style="text-align: justify;">
Now that you know the involved registers, the process is straightforward. For example, say we have a 8 MHz input clock and we want a 24 MHz PCLK. The only possible configuration is prescaler by 2, and PLL x6.</div>
<ul>
<li style="text-align: justify;">CLKRC Bit[6] must be 0, to enable prescaler.</li>
<li style="text-align: justify;">CLKRC Bit[0-5] must be 1, to enable prescaler by 2.</li>
<li style="text-align: justify;">DBLV Bit[7-6] must be 10, to enable PLL x6</li>
</ul>
<div style="text-align: justify;">
Pseudocode:</div>
<script class="brush:cpp" type="syntaxhighlighter">
<![CDATA[
unsigned char tmp;
/* Configuration for 30 FPS */
// CLKRC register: Prescaler = 2
tmp = readOV7670(0x11);
writeOV7670(0x11, (tmp & 0b10000000) | 0b00000001);
// DBLV register: PLL = 6
tmp = readOV7670(0x6B);
writeOV7670(0x6B, (tmp & 0b00111111) | 0b10000000);
]]>
</script>
<br />
<h4>
Changing the frame format/resolution
</h4>
<br />
<div style="text-align: justify;">
The OV7670 can use various frame formats:</div>
<ul>
<li style="text-align: justify;">VGA (640 x 480)</li>
<li style="text-align: justify;">QVGA (320 x 240)</li>
<li style="text-align: justify;">CIF (352 x 240)</li>
<li style="text-align: justify;">QCIF (176 x 144)</li>
<li style="text-align: justify;">Manual scaling</li>
</ul>
<div style="text-align: justify;">
By default, the OV7670 uses the VGA format, if you want to do image processing on a microcontroller with the OV7670 output, this may be way too much data, and you might want the QCIF format instead. To change the format we need to modify the following registers.</div>
<br />
<table align="center" border="1">
<tbody>
<tr><th>Register
</th>
<th>Address
</th>
<th>Default
</th>
<th>Description
</th>
</tr>
<tr>
<td style="text-align: center;">COM3</td>
<td style="text-align: center;">0x0C</td>
<td style="text-align: center;">0x00</td>
<td><table>
<tbody>
<tr>
<td>Bit[6]:</td>
<td>0: Nothing<br />
1: Swap the data MSB and LSB.</td>
</tr>
<tr>
<td>Bit[5]:<br />
<br />
<br /></td>
<td>On powedown<br />
0: Tri-state the output clock<br />
1: Do not tri-state the output clock</td>
</tr>
<tr>
<td>Bit[4]:<br />
<br /></td>
<td>On powerdown <br />
0: Tri-state the output data<br />
1: Do not tri-state the output data </td>
</tr>
<tr>
<td><i><b>Bit[3]:</b></i></td>
<td><i><b>0: Disable scaling</b></i><br />
<i><b>1: Enable scaling</b></i></td>
</tr>
<tr>
<td>Bit[2]:</td>
<td>0: Disable downsampling, cropping, windowing<br />
1: Enable downsampling, cropping, windowing</td>
</tr>
</tbody></table>
</td>
</tr>
<tr>
<td style="text-align: center;">COM7</td>
<td style="text-align: center;">0x12</td>
<td style="text-align: center;">0x00</td>
<td><table>
<tbody>
<tr>
<td>Bit[7]:<br />
<br /></td>
<td>0: Nothing<br />
1: Reset all the registers to default values</td>
</tr>
<tr>
<td><i><b>Bit[5]:</b></i><br />
<i><b><br /></b></i></td>
<td><i><b>0: Nothing</b></i><br />
<i><b>1: Use CIF format</b></i></td>
</tr>
<tr>
<td><i><b>Bit[4]:</b></i><br />
<i><b><br /></b></i></td>
<td><i><b>0: Nothing</b></i><br />
<i><b>1: Use QVGA format</b></i></td>
</tr>
<tr>
<td><i><b>Bit[3]:</b></i><br />
<i><b><br /></b></i></td>
<td><b><i>0: Nothing</i></b><br />
<b><i>1: Use QCIF format</i></b></td>
</tr>
<tr>
<td>Bit[1]:<br />
<br /></td>
<td>0: Disable color bar<br />
1: Enable color bar</td>
</tr>
<tr>
<td>Bit[2, 0]:<br />
<br />
<br />
<br /></td>
<td>00: YUV<br />
01: RGB<br />
10: Bayer raw<br />
11: Processed bayer raw</td>
</tr>
</tbody></table>
</td>
</tr>
</tbody></table>
<br />
<div style="text-align: justify;">
Example, say we want to use the QCIF format, we'll need to enable the scaling, and select the QCIF format.</div>
<ul style="text-align: justify;">
<li>COM3 Bit[3] must be 1, to enable scaling</li>
<li>COM7 Bit[3] must be 1, to use the QCIF format</li>
</ul>
<div style="text-align: justify;">
Pseudocode:</div>
<script class="brush:cpp" type="syntaxhighlighter">
<![CDATA[
unsigned char tmp;
/* Configuration for QCIF format */
// COM3 register: Enable format scaling
tmp = readOV7670(0x0C);
writeOV7670(0x0C, tmp | 0b00001000);
// COM7 register: Select QCIF format
tmp = readOV7670(0x12);
writeOV7670(0x12, (tmp & 0b11000111) | 0b00001000);
]]>
</script>
<br />
<div style="text-align: justify;">
I'll add more possible configurations as I explore other features.</div>
<br />
<h3>
MY RESULTS
</h3>
<br />
<div style="text-align: justify;">
I have tested my OV7670 module, with a STM32F4 microcontroller. This microcontroller comes with a Digital CaMera Interface (DCMI) and a Direct Memory Access (DMA) controller, these two can capture the frames without the intervention of the processor.</div>
<br />
<div style="text-align: justify;">
I used an XCLK of 8 MHz, but configured the OV7670 to output a PCLK of 24 MHz, this means I was capturing 30 fps. I used the QCIF format, however I was receiving 174 x 144 pixels instead of 176 x 144. Color format was the default YCbCr422. One of every six frames was sent to a PC using a UART communication at 3 Mbps.</div>
<br />
<div style="text-align: justify;">
On the PC side, I received the frames using a modded version of <a href="http://embeddedprogrammer.blogspot.com/2012/06/qserialterm-qt-based-serial-port.html">qSerialTerm</a>, only the Y channel (gray scale version) of the incoming frames was used. The result is shown in the following image.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheCdRkoMjxmPth3mhTDxgUz6OTk7_ajXWuMCM-_FxZiv1By11fmk0d7QWmoX_MyWQ-I_kWkM99vkLlLA6cmGSQPDD5NEG6UtWLuFsAmNpfHDKDhhGvwRaEUHI3xTGJ2-XR27qdj5SUC7o/s1600/output.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheCdRkoMjxmPth3mhTDxgUz6OTk7_ajXWuMCM-_FxZiv1By11fmk0d7QWmoX_MyWQ-I_kWkM99vkLlLA6cmGSQPDD5NEG6UtWLuFsAmNpfHDKDhhGvwRaEUHI3xTGJ2-XR27qdj5SUC7o/s320/output.png" width="320" /></a></div>
<div style="text-align: center;">
A <strike>ninja star</strike> servo horn captured by the OV7670 camera module.</div>
<br />
<div style="text-align: justify;">
Now you can use qSerialTerm to visualize images streamed through the Serial Port. Check <a href="http://embeddedprogrammer.blogspot.com/2012/09/qserialterm-qt-based-serial-port-image.html">this post</a> for more info.</div>
<br />
<h3>
TROUBLESHOOTING</h3>
<br />
SCCB: <br />
<ul>
<li style="text-align: justify;">Make sure the SCCB is working properly, the OV7670 will answer with an ACK, after it has been address properly.</li>
<li style="text-align: justify;">The 7 bit SCCB/I2C address is 0x21, this translates to 0x42 for write address and 0x43 for read address.</li>
<li style="text-align: justify;">For debugging purposes, try reading some registers and check that they contain their default values. e.g. reading the 0x01 register should return 0x80.</li>
<li style="text-align: justify;">Always read a register first, modify the desired bits and then write it back to the OV7670. </li>
</ul>
<br />
Image sensor<br />
<ul>
<li style="text-align: justify;">Check wiring, pin configuration and clock configuration. </li>
<li style="text-align: justify;">Start only grabbing a snapshot (only one frame), this is from VSYNC falling edge to VSYNC rising edge. Repeat this procedure multiple times, and make sure the number of bytes per snapshot, is constant.</li>
<li style="text-align: justify;">Cover the camera lens, and verify that the snapshot have the following information (in bytes): 128 0 128 0 128 0 128 0 ... i.e. every even byte should be 128 and every odd byte should be 0. This correspond to a pitch black image.</li>
<li style="text-align: justify;">If the two previous experiments fail, your uC might be too slow to grab the OV7670 stream, either increase its clock speed or get a faster uC. If you are using a DMA controller, then give it high priority, clock it as fast as possible and/or dedicate it to this task.</li>
<li style="text-align: justify;">If you are visualizing the grabbed snapshot in a PC, for starters only use the luminance (Y) channel, i.e. only use the even bytes of the snapshot. On the PC, assign R = G = B = Y for each pixel.</li>
<li style="text-align: justify;">At this point, all the electrical/software part should be working. The only remaining issue is the camera focus (distance from the camera lens to the image sensor), you will have to vary the camera focus by trial and error until you get a clear image.</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNe3u6rjocE8HEk4C4Y9RofCo3-7sWN0yZJoYI2f7DGvm_6yCSDJR2-_d3XzstpL60XhRCkj-H83fsaMIFib31DMjvpls2CDla15t6ocODBUPQhd_2-ZCchBkvhViKoDoncOj5JTlAcgQ/s1600/cameraFocus.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNe3u6rjocE8HEk4C4Y9RofCo3-7sWN0yZJoYI2f7DGvm_6yCSDJR2-_d3XzstpL60XhRCkj-H83fsaMIFib31DMjvpls2CDla15t6ocODBUPQhd_2-ZCchBkvhViKoDoncOj5JTlAcgQ/s200/cameraFocus.JPG" width="165" /></a></div>
<div style="text-align: center;">
Varying the camera focus<br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b>UPDATE</b>: Check this <a href="http://embeddedprogrammer.blogspot.com/2013/01/demo-stm32f4-ov7670-qserialterm.html">post about 3 demos</a> that involve the STM32F4, the OV7670 and qSerialTerm. Full code available.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRL5a1un7U6-O12cwjhNDr2gRkn18CUDFo8bVR4ox5MRJXX_p-yEU4000adtYe0lIsexwzFrY-00Zwwom-DGJvHRpsWr1IMPO4K1MXxF9mENCh4FcHYEIKmtHyAdnqDH3vbXRJNHlP468/s1600/binary_electrical_tape.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRL5a1un7U6-O12cwjhNDr2gRkn18CUDFo8bVR4ox5MRJXX_p-yEU4000adtYe0lIsexwzFrY-00Zwwom-DGJvHRpsWr1IMPO4K1MXxF9mENCh4FcHYEIKmtHyAdnqDH3vbXRJNHlP468/s320/binary_electrical_tape.png" width="320" /></a></div>
<div style="text-align: center;">
qSerialTerm displaying a frame sent by the STM32F4 and was captured by the OV7670</div>
</div>
Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com296tag:blogger.com,1999:blog-1622983275835621655.post-30632035652157888302012-07-07T12:35:00.000-05:002012-07-07T12:52:05.444-05:00Windows: Communicating with a HC-06 bluetooth module<div style="text-align: justify;">
On this post, I'll cover the PC-side configuration needed to communicate with a HC-06 bluetooth module. For more information about the HC-06 module per se (pinout, recommended electrical connection, AT commands and more) check <a href="http://embeddedprogrammer.blogspot.com/2012/06/ubuntu-hacking-hc-06-bluetooth-module.html">this post</a>.</div>
<br />
<div style="text-align: justify;">
The process is straightforward in Windows.</div>
<br />
<h3>
Discovery</h3>
<div style="text-align: justify;">
<br />
Double click the Bluetooth icon in your taskbar. Or alternatively, go to Control Panel > Hardware and Sound > Devices and Printers > Add a device.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
On this new window, click on the "Add a device" button in the menu.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRSejhOgpRZU4qOEJuNupyDeWJQZRYWOmnUHcIdHDvgt0VQK2LF10SykEHyAGFWjcHWn_x79Ue-_04dAlfKvukKhycNw8lhLipG8gO012oxwBcwSXdfykmXqFDHSgFKpkUcqOYm1Jm9dc/s1600/discovery.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="169" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRSejhOgpRZU4qOEJuNupyDeWJQZRYWOmnUHcIdHDvgt0VQK2LF10SykEHyAGFWjcHWn_x79Ue-_04dAlfKvukKhycNw8lhLipG8gO012oxwBcwSXdfykmXqFDHSgFKpkUcqOYm1Jm9dc/s320/discovery.png" width="320" /></a></div>
<div style="text-align: center;">
Discovery of bluetooth devices.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Windows will start searching for nearby bluetooth devices (your HC-06 module should be powered by now).</div>
<br />
<h3>
Pairing</h3>
<div style="text-align: justify;">
<br />
From the list of discovered devices, select your HC-06 module. You should be able to see it's name (linvor is the default name) and it should be listed under the Other category.</div>
<br />
<div style="text-align: justify;">
On the new window, select the "Pair without using a code" option.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK-Tm6kScYXsxnys_41Bjm-O2Do3_jBBw7uPcqsXwFUexULMwaT-N5yy0qsY1N-R6e5pDEZL3KS-AbEG6-cYBktDSeSZ7jLqaJdU5BReddJ4WVkiblHCbIT4xZiUMPt6NKk49XhybkTkI/s1600/pairing.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="169" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK-Tm6kScYXsxnys_41Bjm-O2Do3_jBBw7uPcqsXwFUexULMwaT-N5yy0qsY1N-R6e5pDEZL3KS-AbEG6-cYBktDSeSZ7jLqaJdU5BReddJ4WVkiblHCbIT4xZiUMPt6NKk49XhybkTkI/s320/pairing.png" width="320" /></a></div>
<div style="text-align: center;">
Pairing with the HC-06 module</div>
<br />
<h3>
Checking</h3>
<br />
<div style="text-align: justify;">
You should see the "Installing device driver software" bubble by now. When the installation is done, we'll be able to check the properties of the HC-06 module. Right click on the device and select properties. The important information is under the "Services" tab of the properties window.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi7_LujkwlchaAam4caI4rzDlsQ01MKIXscaGJzD_ZQb7-FgiaxECgym1rgIORLy6czgC9BLk7d0hqjS8EKZ7Z25NUfbx99cMkOBf5vXdSIt-yw7RTywBqIHPy2G-BpvrJo9-SS50hIfI/s1600/properties.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="169" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi7_LujkwlchaAam4caI4rzDlsQ01MKIXscaGJzD_ZQb7-FgiaxECgym1rgIORLy6czgC9BLk7d0hqjS8EKZ7Z25NUfbx99cMkOBf5vXdSIt-yw7RTywBqIHPy2G-BpvrJo9-SS50hIfI/s320/properties.png" width="320" /></a></div>
<div style="text-align: center;">
Checking the HC-06 module properties.</div>
<br />
<h3>
Communication</h3>
<br />
<div style="text-align: justify;">
After pairing with the HC-06 module, it will be registered as a "COM" port, and you'll be able to communicate with it, using any serial port emulator (e.g. <a href="http://embeddedprogrammer.blogspot.com/2012/06/qserialterm-qt-based-serial-port.html">qSerialTerm</a>)</div>
<br />
<div style="text-align: justify;">
On the first connection to the module, you'll be asked for the pin (the default pin is 1234).</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfZn7V6O57noZXcNneOD3HA3momIQf5jGK5ZE8DkcXRXvvG4iaJEEC1z8v_p5gZBRbEqKmB79v-RN2DBWcAONLZLNCzj8piy9Yvm7c70E792UTcXl1tR588dFqZaesRkntBEhCixG_CYA/s1600/pin.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfZn7V6O57noZXcNneOD3HA3momIQf5jGK5ZE8DkcXRXvvG4iaJEEC1z8v_p5gZBRbEqKmB79v-RN2DBWcAONLZLNCzj8piy9Yvm7c70E792UTcXl1tR588dFqZaesRkntBEhCixG_CYA/s320/pin.png" width="320" /></a></div>
<div style="text-align: center;">
Inserting the pin on the first connection.</div>
<br />
<h3>
Enjoy</h3>
<br />
That's all, go ahead and play with your bluetooth module.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4Qj5f6CDBZfuCF6kmZRwz0pZA4dk27hF6mffP7eG7EAR2KnvnzYpuuAFIK2tDwe2rPAcbu1ILS29kOUfSK3BWIWSlstuGx9GPr51bc6kepda0rlmNzJLPidWoGO32MzqNf7Wwwo635jM/s1600/comm-test.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4Qj5f6CDBZfuCF6kmZRwz0pZA4dk27hF6mffP7eG7EAR2KnvnzYpuuAFIK2tDwe2rPAcbu1ILS29kOUfSK3BWIWSlstuGx9GPr51bc6kepda0rlmNzJLPidWoGO32MzqNf7Wwwo635jM/s320/comm-test.png" width="320" /></a></div>
<div style="text-align: center;">
Testing the bluetooth module.</div>
<br />
<br />Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com37tag:blogger.com,1999:blog-1622983275835621655.post-14503686516124489262012-07-07T10:03:00.000-05:002012-07-07T10:03:52.383-05:00Windows: Installing Qt Creator<div style="text-align: justify;">
<a href="http://en.wikipedia.org/wiki/Qt_Creator">Qt Creator</a> is a great cross-platform IDE for open source development of Qt-based applications. The cross-platform <a href="http://en.wikipedia.org/wiki/Qt_%28framework%29">Qt framework</a> allows you to create amazing GUI applications for Windows, Linux, Mac, Symbian, etc.</div>
<br />
<div style="text-align: justify;">
In this post, I'll cover the installations steps of Qt Creator and the Qt libraries.</div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Get the MinGW compiler collection</h3>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
First of all, we need a C compiler. The Qt libraries for Windows have been compiled using the MinGW 4.4 compiler collection. So we need to install the very same version, which is <a href="ftp://ftp.qt.nokia.com/misc/MinGW-gcc440_1.zip">available here</a>(ftp.qt.nokia).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
After downloading the zip file, extract it under the "C:\" path (or any other place you want).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQDCHZRWnwcEyqn3nn2xElLlveRAgDmBce5lZMep9ssqMPoXae-CpZefgLZUKW-m3pxZumH6RLpNEoJ0Q7J6rJXCZ8r_ZFbzRij3gVcWoJkcW4y67Pd-oJ42zSaZ5d88VmTPdFhus1XfE/s1600/mingw.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQDCHZRWnwcEyqn3nn2xElLlveRAgDmBce5lZMep9ssqMPoXae-CpZefgLZUKW-m3pxZumH6RLpNEoJ0Q7J6rJXCZ8r_ZFbzRij3gVcWoJkcW4y67Pd-oJ42zSaZ5d88VmTPdFhus1XfE/s320/mingw.PNG" width="320" /></a></div>
<div style="text-align: center;">
Unzipping the MinGW compiler collection in the C:/ drive.</div>
<div style="text-align: center;">
<br /></div>
</div>
<h3 style="text-align: justify;">
Get the Qt libraries</h3>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Grab the latest Qt library (the MinGW version one) from <a href="http://qt.nokia.com/downloads/downloads#qt-lib">here</a>(qt.nokia.com), and execute the installer. When asked for the path to the MinGW folder, use the same path you used in the last step.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPbjbubHAbVlrqy_HRkmsF-Z06j8NNbxkUM9RWCag8A2CNv4_PdrKl-hGZYwXYR7zSc3m2Aq0BCjHmt2ymDN4fkQxvM_Fh8EL3jIYNfskFvcVT4kBIa2jk2QPeirZcQ3SdNRt_3AGGhFM/s1600/qt-library.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="247" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPbjbubHAbVlrqy_HRkmsF-Z06j8NNbxkUM9RWCag8A2CNv4_PdrKl-hGZYwXYR7zSc3m2Aq0BCjHmt2ymDN4fkQxvM_Fh8EL3jIYNfskFvcVT4kBIa2jk2QPeirZcQ3SdNRt_3AGGhFM/s320/qt-library.PNG" width="320" /></a></div>
<div style="text-align: center;">
Qt-library installation: Selecting the MinGW installation path.</div>
<div style="text-align: justify;">
<br /></div>
</div>
<h3 style="text-align: justify;">
Get Qt creator</h3>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Get the latest version of Qt creator from <a href="http://qt.nokia.com/downloads/downloads#qt-creator">here</a>(qt.nokia.com). Follow the installer's instructions. When done, launch Qt creator and move to the next step.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsHp_sI3_kUab5RbAwuDZuwMFA4HNCrShNnXhuBCZySkbVYN7E2nKy7g3WwDpWgDdYHux4v5KwGaD25sWdytN2egbZP_jcQPZHehd8NTG8-WsMorjq3xbzCZfev_VA6jc9gQBd8-C8Y3E/s1600/qt-creator.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsHp_sI3_kUab5RbAwuDZuwMFA4HNCrShNnXhuBCZySkbVYN7E2nKy7g3WwDpWgDdYHux4v5KwGaD25sWdytN2egbZP_jcQPZHehd8NTG8-WsMorjq3xbzCZfev_VA6jc9gQBd8-C8Y3E/s320/qt-creator.png" width="320" /></a></div>
<div style="text-align: center;">
Qt Creator: Start-up window.</div>
<br /></div>
<h3 style="text-align: justify;">
Select a C compiler in Qt creator</h3>
<div style="text-align: justify;">
<br />
Go to Menu > Tools > Options.<br />
<br />
Click on the "Build and Run" section and go under the "Tool Chains" tab, then click on the "Add" button and select the MinGW option. Configure the C compiler as in the following example.</div>
<div style="text-align: justify;">
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_04hypkC03voJAH2k4RoFu1PsizoRook0HcXF0HXfhYNTbfG9LL85ZEPHPSrMXueS9COniaHuUkUPHcPH5ssYr4qYh7qEw0hio9J3nVcoP2sxqM1orSosQSCZpFeW_q2ftRGqeTnElGA/s1600/mingw-compiler.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="185" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_04hypkC03voJAH2k4RoFu1PsizoRook0HcXF0HXfhYNTbfG9LL85ZEPHPSrMXueS9COniaHuUkUPHcPH5ssYr4qYh7qEw0hio9J3nVcoP2sxqM1orSosQSCZpFeW_q2ftRGqeTnElGA/s320/mingw-compiler.png" width="320" /></a></div>
</div>
<div style="text-align: justify;">
<div style="text-align: center;">
Selecting a toolchain.</div>
<br />
<h3 style="text-align: justify;">
Select a Qt library in Qt creator</h3>
<br />
Go to Menu > Tools > Options.<br />
<br />
Click on the "Build and Run" section and go under the "Qt Versions" tab, then click on the "Add" button. Browse to the "qmake" binary as in the following example.
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5PHzCsUaP3MDH5ew6daFCnIurfSChUAukjyEs75CNg35wCpckX-YWydW2pF_XgHLIKZgFwKrZIehAZi4f-4cRl6QvZC27W97TMyi1VLxDjrbCtzdKh8IZUgACOuFC5kptZHA5SfPbIV8/s1600/qmake.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="185" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5PHzCsUaP3MDH5ew6daFCnIurfSChUAukjyEs75CNg35wCpckX-YWydW2pF_XgHLIKZgFwKrZIehAZi4f-4cRl6QvZC27W97TMyi1VLxDjrbCtzdKh8IZUgACOuFC5kptZHA5SfPbIV8/s320/qmake.PNG" width="320" /></a></div>
<div style="text-align: center;">
Selecting the Qt library.</div>
<h3 style="text-align: justify;">
Enjoy!</h3>
<div style="text-align: justify;">
<br />
That's all. Now, take a look at the various tutorials available on the WWW, and start coding. Or take a look at my Qt-based serial port emulator (<a href="http://embeddedprogrammer.blogspot.com/2012/06/qserialterm-qt-based-serial-port.html">qSerialTerm</a>) as an example.</div>
<br />
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIGf2v4Cn0DNWuBQMWQKDZkimoyckiLUAO6523oFWjv2Q9CkxZqJ2oF0b5AhWiiZSaoHcnfzzi5Snsi8xWZducdEdZJ7IsuGYVxYX_bOCj7e9_MpKZQznSSXpZf67Xt6Xdl-x_wJixxeU/s1600/qt-example.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIGf2v4Cn0DNWuBQMWQKDZkimoyckiLUAO6523oFWjv2Q9CkxZqJ2oF0b5AhWiiZSaoHcnfzzi5Snsi8xWZducdEdZJ7IsuGYVxYX_bOCj7e9_MpKZQznSSXpZf67Xt6Xdl-x_wJixxeU/s320/qt-example.png" width="320" /></a></div>
<div style="text-align: center;">
Hello World example in Qt creator.</div>
<br /></div>Anonymoushttp://www.blogger.com/profile/05418052941788014139noreply@blogger.com0