Showing posts with label Software. Show all posts
Showing posts with label Software. Show all posts

May 16, 2014

Módulo de acesso a redes TCP/IP ENC28J60

Ola

Já faz algum tempo que não posto nada sobre Arduino / sistemas embarcados; bom, como você já deve saber... ok, não vou usar a velha desculpa de falta de tempo.

Estou aqui para dizer que não estou estagnado no meu aprendizado sobre o Arduino e também para falar sobre minha última vitória; a mais ou menos um ano e meio, eu comprei um módulo Ethernet (ENC28J60) igual ao que segue abaixo para fazer alguns experimentos.

Acontece que eu nunca consegui fazer o mesmo funcionar; acabei apelando e comprando um Ethernet Shield (baseado no W5100) o qual funcionou sem maiores problemas. Outro dia eu estava mexendo nas minhas tralhas de eletrônica e encontrei o dito cujo (aquele que eu não havia conseguido fazer funcionar) e decidi que iria tentar novamente.

Depois de ler vários blogs, artigos, etc na internet, acabei obtendo sucesso. Abaixo segue a configuração que eu utilizei:
Veja abaixo como ficaram as conexões:

ArduinoENC28J60
ICSP
HEADER
MISOSO
MOSISI
SCKSCK
RESETRST
PINOS
I/O
VCC (3.3V)VCC
GNDGND
10CS
INT(2)INT






Veja abaixo um ótimo diagrama do Arduino Leonardo.



Observe que no Arduino Mega / Uno e outros, o conector ICSP também esta conectado aos pinos normais de I/O (mas não no Leonardo).


Como eu comentei, tive que fazer uma mudança na biblioteca utilizada para acessar o módulo. Básicamente no arquivo EtherCard/enc28j60.cpp eu mudei:

void ENC28J60::initSPI () {
    pinMode(SS, OUTPUT);
    digitalWrite(SS, HIGH);

    // rest of the code....
}

para:

void ENC28J60::initSPI () {
     pinMode(10, OUTPUT);
     digitalWrite(10, HIGH);


    // rest of the code....

Isso porque o pino SS esta definido com um valor (17) diferente do pino que eu escolhi, 10.

E pronto! Depois disso foi só abrir um dos exemplos da biblioteca, modificá-lo um pouco e temos temos um web server rodando no Arduino.

O que você acha? Eu acho isso muito massa ;)

Não hesite em deixar comentários / perguntas / sugestões / críticas.

Happy Coding.

OBS: Antes de postar eu notei no esquema de pinagens que no Leornardo o pino SS (17) é o pino A3; então teóricamente é possível utilizar a biblioteca citada sem modificações (basta ligar o pino CS do módulo no pino A3 do Arduino; teóricamente pois eu não testei :)

(Read this post in English)

Arduino Ethernet module ENC28J60

Hi

It has been some time since my last post about Arduino / embedded development, you know..... well, I'll not give the usual excuse of lack of time ;)

This post is about my last victory! Some one and half years ago I bought, a cheap, Ethernet module (ENC28J60) (similar to the one in the picture below) so I could do some experiments.

It happens that I failed miserably to get it working and I ended up ordering a Ethernet Shield (W5100) (which worked with no problems) and gave up on this module. 

Some days ago while I was checking my electronics junk stuff I found it again and decided I was ready to give it another try.

After reading a lot of blog posts, articles, documentation, etc, I finally succeeded and get it to work with the following configuration:
  • Arduino Leonardo
  • This library to access TCP/IP thought the ENC28J60 module (with the suggested modifications from this post) (which are only required / necessary for Arduino Leonardo)
  • Connections as described on the same post cited above.
To make it easier I posted the connections below:

ArduinoENC28J60
ICSP
HEADER
MISOSO
MOSISI
SCKSCK
RESETRST
I/O
PINS
VCC (3.3V)VCC
GNDGND
10CS
INT(2)INT






Below you can see a nice Arduino Leonardo diagram.



Note that on another Arduinos (like Mega / Uno), ICSP connector is also connected to the "normal I/O pins" but not on Leonardo so you must use the ICSP connector in order to connect the Arduino to the module.


The last piece that is missing was to change the file EtherCard/enc28j60.cpp as follows:

void ENC28J60::initSPI () {
    pinMode(SS, OUTPUT);
    digitalWrite(SS, HIGH);

    // rest of the code....
}

to:

void ENC28J60::initSPI () {
     pinMode(10, OUTPUT);
     digitalWrite(10, HIGH);


    // rest of the code....

This change was required because the SS constant is defined with a different value (17) than the pin I chosed (10).

Finished! Now it was only a matter of taking one of the ENC28J60 library examples, change it a little bit and some 60 mins later I had an web server running on my Arduino Leonardo.

What do you think? Pretty cool, IMO! :)

Happy Coding.

(Leia este post em Portugues)

Mar 5, 2014

Running scripts on google drive documents

Hi.

I admit I have always looked to "cloud based" document editing (such as google drive, Microsoft Office 365, etc) with certain dislike, mainly due to the misconception that these applications would not allow me to use my precious scripts (after all, any true developer shall use scripts everywhere, right? ;)

Even though I somewhat disliked the idea, I ended up ceding (the convenience of having it available anywhere is so hard to ignore :) and,for some time, I have been using one spreadsheet to store a piece of information I use on a monthly basis.

It happens that last week I decided that one of the tasks involving that spreadsheet should be automated (basically, given some condition I'd like to add some information to a specific cell, which is a perfect job for a script) so I was considering moving the spreadsheet to my box and use LibreOffice (which I highly recommend, by the way) to edit it. 

While I was poking around my google spreadsheet menus, I stumbled in "Tools/Script Editor" menu option and realized that my resistance in using such online solutions had no ground whatsoever, i.e, it was just prejudice from my side :( I just selected that menu option and voila, scripts with debugging support!

That is all I needed! Some time (and a lot of keystrokes) later and I had my first script running; but the best was yet to come: not only I was able to reference my newly created function, but I could also schedule it to run from time to time! (that's exactly what I was looking for).

Following you can see my script:
function checkDate() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheets()[0];       
    
  var range = sheet.getRange("A1");
  
  var now = new Date();
  
  if (now.getHours() <= 10 || (now.getHours() >= 15 && now.getMinutes() > 30) || (now.getHours() >= 13 && (now.getHours() <= 14 && now.getMinutes() < 30)) ) {    
    range.setBackground("ORANGE");
    range.setValue("CLOSED");
  }
  else {
    range.setBackground("GREEN");
    range.setValue("OPEN");
  }
}
And it worked like a charm.

To my astonishment, today I figured it out that I can even execute WebServices (SOAP) from within my scripts (and of course I put it in action immediately) ! 

Happy Coding!

(Leia, uma versão extendida, deste post em portugues)

Nov 15, 2012

Learning git

If you are a software developer you should already use some sort of SCM (if not I urge you to start to learn/use one now!). 

If you have not tried Git yet you should give it a try (but keep in mind it may take some time until you really appreciate its power).

I have been working with Git for at least 2 years and I am amazed how flexible / powerful it is. Actually it is so powerful I still learn new stuff about it almost every other day! Bellow you can find some useful resources to learn a little bit more about it:

Have fun!

Oct 10, 2012

Icons, Icons, Icons....

From time to time I find myself looking for icons for my own projects....

If you ever had the same need check this out.

I really recommend it :)

Happy programming.

Sep 25, 2012

Angry user...

Sorry, I could not resist the pun :)

Well, some time ago (to be more precise 1 1/2 years ago) I've bought a (Chinese) Android Tablet so I could experiment, play games and may be try to develop some program (of course I've failed miserable to write any application for it :(. You can see a picture of the device bellow (it ended up to be much more resistant than what I expected! You can see its cracked 
screen due to 2 ~ 3 not so smooth landings - thanks to my young daughter):

Anyway, I use it regularly for reading ebooks, email reading and playing basic games. Talking about games I used to play "Angry Birds" (all free editions) on this device with no problems at all; but at some point in time something has changed and since then I am not able to play it anymore. The symptoms are always the same: I launch the game, its "splash screen" shows up followed by some screens and finally the "loading" screen shows up but then the application just dies without any trace! 


I had just accepted the fact that I'd not be able to play this game again on this device but last weekend I was recovering from a small surgery and I decided to investigate it a little bit more.


First thing I did was to install a log viewer (I'm using aLogCat) to check if I could find anything on Android logs. Indeed it was pretty easy to find the information I was looking for:


E/HttpRequestHelper( 4956): Exception from HttpClient.execute.
E/HttpRequestHelper( 4956): java.net.UnknownHostException: rovio.events.medio.com
E/HttpRequestHelper( 4956): at java.net.InetAddress.lookupHostByName(InetAddress.java:513)
E/HttpRequestHelper( 4956): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:278)
E/HttpRequestHelper( 4956): at java.net.InetAddress.getAllByName(InetAddress.java:242)
E/HttpRequestHelper( 4956): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:136)
E/HttpRequestHelper( 4956): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
E/HttpRequestHelper( 4956): at


Huum... ok, so the application tried to resolve the host "rovio.events.medio.com" and it failed bringing the whole app down! WTF? (I tried to access this host from my desktop and the result is the same (
Interesting enough, medio.com as well events.medio.com does exist) so I assume the problem is directly related to the subdomain "rovio" on events.medio.com.

Searching on net for this error did not bring any useful answer. Also I've tried to clear Angry Birds application data, 
re-install it and even a device factory reset (due to other issues) to no avail :(. 

Have you seem this error? Any ideas how to fix it? I doubt I am the first one to stumble on it!

Aug 15, 2012

Windows 8 / Visual Studio 2012

Hi

Getting back to the subject I am more comfortable with, MS just released Windows 8 / VS 2012 (for MSDN and Technet subscribers). Off course I am downloading both right now but this is the first time, since Windows 95 launch, that I am not going to install the new MS OS as soon as it gets released. 


To be honest I am not even considering installing it (on my main dev machine) in the next 6 ~ 12 months! Contrast that to what I've been doing in the past 
(I've used Vista / Windows 7 RC!) and you can see how "excited" I am about it (maybe I install it on a virtual machine so I can experiment with it). Anyway, sooner or later I'll end up formatting my dev machine and the question is: am I going to give Windows 8 a try? Or shall I take a more drastic approach and install Ubuntu? This bring me to the second MS release.. VS 2012.

One of the main reasons I'm procrastinating migrating to a Linux OS is that I really enjoy developing using .Net (yeah, I do know Mono; the problem is: the bulk of .Net development is still concentrated on MS platform. Also, 
IMHO, *nix lacks a good .Net IDE).

Of course my friends (at least the ones in the software development field) knows that that is not completely  true: I also enjoy MS technology in general (COM+ pops up as one example).


What do you think? Should I dive into Windows 8?


BTW: Visual Studio download finished! This one for sure I'll get installed in the next few days ;)

Happy codding!

May 19, 2012

API usage rant

If you have been following me recently (Facebook, Linked-in, Tweeter, etc) you probably are aware that I have been busy taking care of the building of my new house, my job and what not (not necessarily in this order ;).

Man, building a new place proved to be a huge time sink; since we've finally finished the main construction phase I expect to blog more often.

Ok, so lets start with a rant (I am really good ranting :))

Some time ago I was playing with one of my toy projects when I got an exception while adding a new entry into a dictionaryThe exception was quite self explanatory about what had happened (from the point of view of the dictionary class implementer): a duplicate key was added (which,  according to the documentation, is explicitly prohibited).

Ok, I can live with that, it was my fault after all ;) My real issue is that the message would be much more helpful had it included the actual key value (of course you override
ToString() method in all of your public classes, don't you ?).
Without this information I was forced to debug the code (of course I could catch the exception and print the key but then I'd be required to change my code just to find out what was happening) to figure out what the original exception could have told me.

To my understanding, one of the reasons for 
this is to avoid possible sensible information from leaking and, even though IMHO this is reasonable, it makes me think whether we could do it better. 

To me looks like the dictionary class developer (product owner, or whoever) was faced with the usual coast/benefit decision: make it easier, more convenient to use or make it suitable for use when sensible information is involved and he/she decided for the later.


When writing libraries I usually tend to making it easier to be used at the coast of a higher chance of developers misuse (or using it in a way that may shut then in their foots). I confess that I had never thought about this particular scenario but now I think it could be fixed (made more flexible) by allowing the user (in this case the developer) to decide what to expose in exceptions (through an enum, an interface, you name it) and choosing a safe default value.


What do you think?


Adriano

May 9, 2012

Free (open source) RAM disk for Windows (x86 / x64)

Hi


Have you ever had the need to perform some I/O intensive operation on a relative small set of files? I do, usually when I need to compile some application.

In order to speed up this operation I've recurred to the so called "RAM Disks", applications that takes part of your computer's main memory and pretends that it is an actual disk. As you can imagine read/write/etc (I/O) operations against this virtual disk are much faster than operations against your actual hard disks (be it a traditional magnetic HD or a shine new SSD).

In the past 3 years I've used at least 3 different solutions and was happy with none. My main complain is that most of them were not capable (or it was really clumsy/hard to accomplish) of creating RAM disks dynamically, i.e, one is required to create it at OS start up time. Since my needs are dynamic (I may need more disk space at some points in time during the day) it is really hard to come up with a disk size that work for me: choose a to big disk and I am wasting precious RAM space; create a disk that's to small and I may find myself facing "out of disk space" errors (then cleaning up some junk and restarting my build tasks).

Fortunately some time ago I stumbled upon a RAM disk implementation that allows me to mount and unmount disks dynamically! Since then my work flow has been much more smooth ;) The not so good side is that it is not very easy for the "not computer savvy" user.

Bottom line is: if you need a stable and flexible (but maybe not so easy to start with) RAM disk solution you can't go wrong with this one.







Mar 30, 2011

Do as I say, not as I do

It has been a long time since my last post ...


As usual I have been busy taking care of my kids (if you have two kids you have an idea how much time they require :)), studying, playing with may pet projects and what not.


But something happened and motivated me to stay late and to write this post. To make a long history short, yesterday night I was working on one of my pet projects, binboo (basically a skype plugin that I and other team mates use to add/update issues on our bug tracker) and I spot some code that looked pretty useless to me.


Since I have unit tests (yeah, some of you would argue that strictly speeking they are not unit tests, but anyway, I have automated tests in place) I was not scared of changing the code, so in the next step I just removed the "dead" code running the tests after that. To my happiness, I saw only green in the unit test runner screen. 
Perfect, I though, proud of myself.
After that I just committed my changes and went (happy) to bed only to be embarrassed in our meeting today with an ugly, idiot, ridiculous bug in the exact same code I have touched yesterday. It became clear to me that my unit test coverage can be improved.


After my normal work day I just loaded the project in VS to look at the specific test case that should have failed due to my change but, to my surprise, I had no test case for this particular scenario. Hum... stupid developer.


Lesson learned, I have written a test case before reverting the changes (and of course, I'll study the code to understand why it is required after all).


Ok, let me get back to my other pet projects.


Have fun!


Adriano

May 16, 2010

Installing Nokia SDK on a Windows 7 box

Hi


As you can figure out based on the post title, I want to start to play with Mobile development using Java (no, I haven't gave up on .Net :); it just happens that I own an N95 and I want to write a little application for it1).


After downloading latest Nokia SDK I  tried to follow the steps in the documentation (IDEs for Java Development) but I just get the infamous error:


Cannot start Series 60 SDK for MIDP


while importing the device.


Thanks God, it was just a matter of "googling" for the error message and I got the following page


http://wiki.urban.cens.ucla.edu/index.php?title=Nokia's_Java_Platform_(Carbide.j)


which fixed the issue (I just search in my hard disks and found 5 copies of the offending DLL).


Well, since my daughter has just born I guess this project will run really slowly but I hope it will not stall :) 


Best


Adriano


1. I am planning to write an application that stores information about gym exercises in a db4o database. 





Mar 10, 2009

Automating Skype through COM

Wow.. finally a technical post again :)

Those of you who knows me knows that I am a firm believer of component technologies.

Personally I really appreciate Microsoft's COM technology; ok, it does has it drawbacks (as everything in life) but when used correctly it proved to be a very powerful way to support software automation and extensibility. Let me briefly explain what those funny words means for those who don't know yet.

Basically, software automation is the process of a software controlling another one. For instance, if you have Microsoft Office installed it's possible to write a program (even a JavaScript script) that creates a Word Document through automation, i.e, your program may "control" word (and Excel, Power Point, etc). This kind of flexibility can be very helpful in some scenarios.

By extensibility I mean ways of extending a given application. A good example is Windows Explorer; it's possible to add new items to a context menu (in the same way 7-Zip and many other applications do) simply by implementing an specific COM interface (and registering your component of course).

These are just 2 examples of what's possible; of course other softwares also support some level of automation (for instance Adobe Acrobat).

In this post I just want to talk (again, briefly) about Skype and how it's possible to extend it through COM (Skype also supports automation through Java, XXX, etc).

First let me just explain that the possibilities are infinite; what you may want to do with automation is not my business :); all I can say is that if you think a little bit you'll be able to find some nice use for skype automation.

For instance (as I said in my last posts) I use Skype heavily on my work to communicate with other team's members. At least once per week we do a Skype meeting in order to decide what we're going to do in that week; to manage these tasks we have a "queue" of tasks in our Jira installation.

One annoyance during this meeting is that once someone decide he wants to take a specific task the process involves at least 2 steps: to announce in the chat meeting and going to the browser to update Jira.

Since it's possible to automate Skype I wrote (to be more precise I am debugging it right now) a "plug-in" that simply keeps listening all chat messages and react accordingly for specific patterns; for instance if I want to take a task (let's say TSK-1) I may just type:

$jira assign TSK-1 myself

This way I announce to the team and update Jira at once :) (I don't need to go to the browser anymore)

The plugin is "smart" enough (through configuration) to figure out who I am ("myself") and to go to Jira (through a WebService) and update the specific issue (task).

And this is only a basic example about what can be done (the sky is the limit :).

For more information about Skype automation visit
https://developer.skype.com/.

If you want to take a look into this plugin, just grab the code at: git@github.com:adrianoc/binboo.git or browse the code online at https://github.com/adrianoc/binboo (just keep in mind that there're lots of assumptions/dependencies to our Jira installation but I guess one can learn a lot about how to integrate to either Jira or Skype). 


See you.

Adriano

Nov 5, 2008

Are you a C# developer?

If so, you should go and grab a copy (for free) of CodeRush Xpress for Visual Studio!

(I already own a copy of another addin, but I'll give it a try anyway :)

Adriano 

Jul 15, 2008

Another one in the obscure codding practices ...

As I said in this post, today I've found an interesting site about C++ programing practices. While reading this pages I learned another way to write a fragile application (as always, writing bad code is enough :) So, let's go for it! What will be the output of the following program?
void main(int argc, char* argv[])
{
  int n = 255;
  size_t size = sizeof(++n);
  printf("%d", n);
}
Maybe this be can pretty obvious to you, but it was not to me (maybe because I avoid to write obscure code as much as I can :) Adriano

CERT C++ Secure Coding Standard

Hi. Today I reached this page (on cert.org) site talking about C++ secure standard practices. I haven't read it to the end yet but at a first glance it looks pretty interesting (and useful) to me. Wait, don't call yet!! There's a page regarding safe practices for C also! I'll be reading this as soon as I get some time to ;) Adriano

May 22, 2008

Where do you search for .Net tools?

Hi. This will be a very short, but I hope useful, post! Of course I usually do a google search when I want to find some system/programing tools. Also I do keep an eye on some pretty helpful sites:
  • The Free Country (www.thefreecountry.net)
  • Source Forge (www.sourceforge.net)
  • Codeplex (www.codeplex.com)
  • Fresgmeat (freshmeat.net/)
One site that I really like when I want anything related to .Net is sharptoolbox (sharptoolbox.com). If you are a .Net developer you should take a serious look into this site. Which sites do you visit to get system/programing tools? Adriano

May 10, 2008

Linq Console Update

Hi! I've just updated the Linq Console application! Now you don't need to copy your model assemblies to Linq Console folder anymore! You can use the load command as follow: :load "c:\my projects\test\Test.Model.dll" and the application will be able to load it :) The source code can be downloaded from our svn server: https://source.db4o.com/db4o/trunk/sandbox/rodrigo/NonOptimizedLinqSpikes/LinqConsole/ Adriano

Apr 24, 2008

Redirecting standard error output in cmd.exe

Hi. Suppose you have the following C++ program (in a Windows box):
#include "stdafx.h"
#include "string.h"


void write(char *str, FILE *target)
{
fwrite(str, strlen(str), 1, target);
}

void _tmain(int argc, _TCHAR* argv[])
{
write("Test:stderr\r\n", stderr);
write("Test:stdout\r\n", stdout);
}
and you want to redirect its output to a file. We could try something like in Windows console:
test.exe > myfile.txt

Unfortunately the naive approach don't work because there are data being outputted to stderr and we are redirecting only the standard output (stdout). In order to redirect stderr we can use the following syntax:
command handler# > target

let's try a sample:
test.exe 1>myfile.txt

This will redirect stdout (handle 1) to myfile.txt To redirect stderr (handle 2) we can use:
test.exe 2>myfile.txt

Ok. Now we can try:
test.exe > myfile.txt 2>myfile.txt

but, again, this doesn't work; instead we get an error message:
D:\temp\cpp\Test\Debug>Test > myfile.txt 2>myfile.txt
The process cannot access the file because it is being used by another process.
Ok, there's one last trick we can try (duplicate stderr to stdout):
test.exe > myfile.txt 2>&1

Great! Now it works as expected! Last, but not least,
you can find more information here. Hope this can be useful :) Adriano

Apr 22, 2008

Db4o news!

Hi, Db4o just announced a new release! Check it out here and let us know what you think about these new (IMO) cool features! Adriano

Jun 15, 2007

Stream de dados alternativas

Para muitos usuários (e mesmo desenvolvedores) do Windows o conceito de arquivo esta tão sedimentado que muitas vezes melhorias significativas no sistema de arquivos deste sistema operacional (no caso o NTFS) são ignoradas.

Neste post apresento um dos recursos mais desconhecidos, stream alternativas de dados ou ADS (do inglês, Alternate Data Stream).

Para compreendermos este recurso é necessário primeiro definirmos (ou relembrarmos) alguns conceitos:

  • Uma stream de dados nada mais é que um conjunto de bytes arranjados de forma seqüencial.
  • Um arquivo é composto por uma ou mais streams de dados.
  • Streams de dados possuem um nome associado através do qual a mesma é referenciada. A regra básica para formação do nome de streams é: nome-arquivo.ext:nome-stream:tipo-stream
  • O nome da stream pode conter qualquer caracter válido para um nome de arquivo.

Como o Windows não possui meios (tanto no Explorer quanto no console) para detectar / mostrar arquivos que possuem ADS, abaixo listei algumas ferramentas úteis para tal finalidade:

Usando ADSs

A forma mais simples para demonstrarmos este conceito é através do console do Windows. Abra o console (cmd.exe) e digite:

echo teste de streams > teste.txt:dados

Simples assim! O comando acima cria uma stream chamada dados com o conteúdo teste de streams.

Agora você pode conferir que o arquivo teste.txt foi criado mas o comando dir reporta o mesmo com 0 (zero) bytes.

Finalmente, para visualisar o conteúdo da stream digite

more < teste.txt:dados

Abaixo apresento um pequeno programa de exemplo para criar ADSs (note que o mesmo não possui nenhum tratamento especial, ou seja, a forma de acessar data streams alternativas é idêntica à utilizada para acessar a data stream default).

#include "stdio.h"
#include "Windows.h" 
void main(int argc, char *argv[])
{
    HANDLE handle;
    if (argc < 3)
    {
        printf("Nome da stream (formato: arquivo.ext:stream) ou dados nao especificados.\r\nUso: ads.exe nome-stream dados");
        return;
    }
    else    
    {
        printf("\r\nGravando dados em %s", argv[1]);
    }
    
    handle = CreateFile(argv[1], 
                        GENERIC_WRITE, 
                        0, 
                        NULL, 
                        OPEN_ALWAYS, 
                        0, 0);
                        
    if (handle != INVALID_HANDLE_VALUE)
    {
        DWORD numberOfBytesWritten;
        int n = WriteFile(  handle, 
                            argv[2], 
                            strlen(argv[2]), 
                            &numberOfBytesWritten, 
                            NULL);
                            
        printf("\r\n%ld bytes gravados", numberOfBytesWritten);
        
        CloseHandle(handle);
    }
    else
    {
        printf("Não foi possivel criar a stream de dados.");
    }
}
[Editado: Correção de um erros de português]

experimente executar o programa com alguns parâmetros como por exemplo:

ads teste.txt:dados "Teste de streams"

É isso ai.

Até a próxima.