LCD Displaying system temperature    LCD Displaying torrent status

I previously had posted on how to communicate with an Arduino and display messages on an LCD using python. And I’ve been working on Raspberry Pi as well, setting it as a torrent box.

So I thought of hooking up these two together so that the LCD can display the torrent status. I also added two buttons so that I can scroll through the list of torrents. The Arduino is connected to the RPi via the USB, and the Arduino is powered by an external AV adapter. Initially I thought this will be unsafe, but apparently it is safe to do so (http://arduino.cc/forum/index.php/topic,22132.0.html, http://aeroquad.com/archive/index.php/t-1911.html?s=5273633e6fd3970524bf4473996b9f7d) The LCD also displays the current system temperature.

The source code the the python program and the Arduino can be accessed at: https://github.com/slayerjay/RaspberryPi_Arduino

Other Resources:

http://www.hobbytronics.co.uk/raspberry-pi-serial-port

http://www.raspberrypi.org/phpBB3/viewtopic.php?f=32&t=6832

http://raspberrypi.stackexchange.com/questions/357/how-do-i-monitor-and-or-control-the-temperature-of-the-soc

So you may have your RPi  set up as a torrent box, or a web-server  or you may want to login to it remotely out of your home network, and your ISP will be giving you a dynamic IP. This is where Dynamic DNS (DDNS) comes to the rescue. I used noip.com as my DDNS provider (which is free), but you are can use any other similar service.

The Theory

Your home network’s public IP changes time to time because it is assigned dynamically by your ISP. A DDNS service points to your public IP, and changes its records about your public IP whenever it changes. You will have to download and run a small client program that will report you IP to the DDNS service when it changes. So whenever someone accesses your domain address he/she will be pointed to your IP.

Setting Up

The different services that you are running on the RPi will be listening on different ports. The web server by default would be listening on port 80, and transmission torrent service will be listening on port 9091 (by default). You need to tell your router that any incoming packets that are coming for a specific port, (say port 80) should be forwarded to your RPi.Now the exact way to set up port forwarding depends on your router, but it is pretty straightforward if you know the above theory behind port forwarding. You can get some help from portforward.comIf port forwarding is set up you can check it using port scanner. And you will be able to access your service by your public IP.

  • Register with your DDNS provider, get a domain name, and download their client program.

I registered with noip.com and downloaded their Linux client software, and installed it (where you will have to enter your noip.com credentials)

  • Set the client program to run at startup of RPi

The following post explains how to set the noip2 client to run at startup: http://www.stuffaboutcode.com/2012/06/raspberry-pi-run-program-at-start-up.html

If all works well, you will be able to access the services on your RPi from anywhere!

I didn’t want to keep my laptop or the computer switched on 24/7 to download torrents. So downloading my torrents was the first task I wanted my Raspberry Pi to do. The torrents will be downloaded to an external hard disk or a pen drive. Transmission provides a web UI which makes it easier to remotely add and monitor downloads. As for initial preparations, the RPi has a static IP and SSH was enabled. You might want to look at my previous post on initial setting up stuff.

Preparing and Mounting the External Storage

I used one of my pen drives that is formatted as an NTFS file system. Connect the external storage to the RPi. Open a SSH session and type:

$ sudo fdisk –l

This lists all the hard drives that are connected and you will be able to find your external storage.

fdisk

Note the ‘Device Boot’ record (Mine is ‘/dev/sda1′ ).

Now let’s mound the drive. All mounted drives are accessed though /media/ folder.

$ cd /media/
$ sudo mkdir downloads
$ sudo mount –t ntfs-3g /dev/sda1 /media/downloads

If it says that ntfs-3g is an unknown type or gives a similar error message, install it by:

$  sudo apt-get install ntfs-3g

Now the device is mounted. However we want RPi to mount it automatically every time it boots up. For this you need to edit the ‘fstab’ file and enter the details of your device.

To edit the file use:

$ sudo nano /etc/fstab

It will bring up the file which contains a table as follows:

fstab

Enter the following record at the end of the table:

/dev/sda1       /media/downloads        ntfs-3g defaults        0       0

Save and exit.

This is an excellent reference on this matter.

Now your external storage is ready.

Installing and configuring Transmission

$ sudo apt-get install transmission-daemon

We need to do some configurations. For this we nead to stop the daemon and edit the settings file.

Stop the daemon using:

$ sudo service transmission-daemons stop

Bring up the settings file by:

$ sudo nano /etc/transmission-daemon/settings.json

Set the download directory to your external device that was mounted:

"download-dir": "/media/downloads",

You can enable or disable RPC Authentication. If you enabled it you can set the username and password here as well. (The plain text password entered will be changed to the hash value and stored when transmission starts up).

By default, transmission only allows a white listed set of IPs to access it. You can either enter your IPs to the whitelist or disable this.

Save and exit the settings file and start the daemon:

$ sudo service transmission-daemons start

Now open up your web browser and point to the transmission url. It should be of the format:

rpi_ip:9091/
Ex: 192.168.1.5:9091/

You can now upload your torrent files and let the RPi download it!

Transmission Web UI

I have noticed that sometimes an error occurs: “Error: Input/output error” To fix this re boot the RPi and ‘Verify local data’ of the torrent. This of course is not a permanent fix. I have tried the fixes here: http://stevenhickson.blogspot.com/2012/10/fixing-raspberry-pi-crashes.html and I’m still looking in to this issue.

Update: I’ve applied the fixes on the above link and reduced the number of peers in transmission. But apparently the main reason for the IO errors were with my Transcend flash drive. I tried with another (unbranded cheep) flash drive, and things are now working like a charm :)

Update 2: I am using a SATA hard disk to store the downloads.

Accessing Downloaded Files

You can setup a Samba server on RPi to access your downloaded files from other machines. This article provides a comprehensive guide on how to set this up.

Additional References: 

http://stevenhickson.blogspot.com/2012/10/using-raspberry-pi-as-web-server-media.html
http://cumulativeparadigms.wordpress.com/2012/08/13/tutorial-1-setting-up-rpi-as-a-torrent-server/

If you have signed up in a couple of mailing lists, and your Facebook notifications are pouring in, managing your inbox is pretty hectic. It’s even worse if you couldn’t check your email for a couple of days. Gmail has provided some handy tools to make your life a little bit easier.

Priority Inbox:
Use this right, and I’m sure checking your email would be a whole lot easier. Gmail Priority Inbox automatically identifies your important emails and sorts them separately, so you can focus on those emails that matter to you most. Gmail predicts which messages are important to you based on several facts such as who you email, which messages you reply to, etc. And you can help Gmail predict by marking your emails as important or not. It does take some time for you and Gmail to get adjusted, but after that Gmail predicts your important emails accurately.

Checkout this video introducing Priority Inbox

Check this out for more information.

Labels and Filtering:
Gmail allows you to label your emails. You can do this drag and dropping a label to your messages.

You can create labels and manage your emails easily. With Gmail’s filtering you can automatically add labels to your emails.

Let’s take an example; I want to label all my emails from Facebook under a label “Facebook”
Open an email you received from Facebook, and under “More Actions”, click “Filter messages like these”.

Then you can specify any other criteria that you need, and on the bottom you will see a list of emails that match your criteria.

In the next step, check Apply the label. You can select an existing label or create a new label.

If you want the label to be applied to the currently filtered emails check “Also apply filter to…” and click “Create Filer”
And you will see that the filter is applied to the emails from Facebook. Similarly you can add filters to filter all your mailing lists.
It will take you sometime to setup all these filters, but believe me, it’s worth it.

During the previous week I found out some tricks and tips in assembly, and thought of sharing them in this brief post.  I hope you will find these useful. I used NASM compiler to compile these codes.

Clearing a register:

Suppose you want to clear the ax register. XOR’ing it with itself will set all the bits in the register to zero.

xor ax, ax

Printing a single character on screen:

The interrupt 0x10 will print a given character on screen. The following code can be used to print a single character on screen.

mov al, '@'     ; character or the ASCII code of the character to be printed
mov ah, 0x0e    ; video – teletype output
int 0x10

Extracting some bits from a register:
Suppose you want to extract bits 3 and 4 of the AX register, and then print the decimal value on screen. The following code can be used to achieve this.
‘AND’ the register with a binary number which contains 1’s in the bit positions you want to extract. For our example it would be 0b0000000000011000 or 0x0018 (in hexadecimal). Then shift it right until our bits are the right-most bits. Then add 4b to it to get the ASCII number (ASCII value of ‘0’ is 48)

and ax, 0x0018    ; mask out bits 3 – 4
shr ax, 3         ; shift it right 3 times
add ax, 48        ; add 48 to get ASCII character
mov ah, 0x0e      ; print it
int 0x10

Remember the above code will work only if you are going to print values less than 9. If you want to convert a value more than 9 to decimal this will not work (I hope you understand why it doesn’t work 😉 ).

Printing out a register in binary:
For most of our debugging work, we will need to print the contents of a register in binary format. The following code can be used to print the contents of the CX register.

_print_reg:
;print the CX reg
push dx              ; save registers dx,ax,bx
push ax
push bx
mov dx, cx
mov cx, 16           ; loop for 16 times
print_loop:
    mov ax, 32768    ; set  ax = ob1000....
    and ax, dx       ; mask out the MSB of dx and store it in ax
    shr ax, 15       ; shift it to right 15 times
    add al, 48       ; add 48 to get the ASCII (would be either 0 or 1
    mov ah, 0x0e
    int 0x10         ; print it out
    shl dx, 1        ; shift left dx by 1
loop print_loop

pop bx;              ; restore the registers
pop ax
pop dx
ret

Hope these few tips will be helpful. That’s all for now :)


Have you ever wondered how to create those textual user interfaces that appear on console type windows? In this post I will explain how to create some simple user interfaces in C under Windows. With some simple coding, and a little bit of patience you will be able add some GUI elements to your C programs. However the following examples are only for windows operating systems. First let us take a look at some interfaces that I have done.

This shows a Stock Controlling System that I did as a class project. It has text boxes and message boxes and tables.

Inventory Control System user interface with a message box

Inventory Control System user interface

The following is the user interface of our Intelligent Car Park Management System, which we did as a group project in the university.

Car Park Management System User interface

Understanding the Console Window

The console window can be considered as a grid, with top left corner having the coordinates (0, 0).

In order to display our programs correctly, we need to set the size of the console window. Remember to follow this step to change the window size for your programs.

Right click on the title bar of the program and select Properties.

Right click on the title bar of the program and select Properties.

On the Layout tab, change the values as necessary. For this example, I will be using the settings that are shown on the screen shot.

Layout tab

The above procedure can be programmed into the code as well. For this refer the msdn for SetConsoleScreenBufferSize function (http://msdn.microsoft.com/en-us/library/ms686044(v=VS.85).aspx)

Alternative conio.h

We need some functions that are not implemented in the standard conio.h library. These include functions such as gotoxy(), getx(),gety() which basically manipulates the cursor position on the console window. There are a few alternate conio.h libraries available on the internet. I used the one which is available in the following forum by Arthur Christopher Watkins:

http://www.dynamicdrive.com/forums/showthread.php?t=35174

Or you can download a little bit modified version directly from here

It’s all about printf!

Now that you got the console window size adjusted, and alternate conio set up, it’s time to code!

Get an ASCII chart, and note the characters that can be used to draw lines, bends, etc. You can use the following code to print an ascii character.

int n=205;            //ascii code of the character
printf(“%c”,n);

Now you can use your creativity and imagination (and some loops of course :) ) to write functions that will print lines, text boxes, rectangles, etc. Here are some functions that I wrote:

#include <stdio.h>
#include "altconio.h"

void DrawHLine(int x,int y, int length);
void DrawVLine(int x,int y, int height);
void DrawFrame(int beginx,int beginy,int width,int height);

int main()
{
	clrscr();
	DrawFrame(3,3,10,10);
	DrawVLine(15,3,10);
	DrawHLine(3,15,10);
	gotoxy(0,20);
	system("pause");
	return 0;
}

void DrawHLine(int x,int y, int length)
/*
 * this function draws a horizontal line when
 * the x,y values of the starting point and length
 * is given.
 */
{
	int count;
	int currX=getx();	//get the currecnt cursor position
	int currY=gety();
	gotoxy(x,y);
	for(count=0;count<length;count++)
		printf("%c",196);
	gotoxy(currX,currY);	//put the cursor back in place
}

void DrawVLine(int x,int y, int height)
/*
 * this function draws a verticle line when
 * the x,y values of the starting point and height
 * is given.
 */
{
	int count;
	int currX=getx();	//get the currecnt cursor position
	int currY=gety();
	gotoxy(x,y);
	for(count=0;count<height;count++)
	{
		gotoxy(x,y+count);
		printf("%c",179);
	}
	gotoxy(currX,currY);	//put the cursor back in place
}

void DrawFrame(int beginx,int beginy,int width,int height)
/*
 * this function draws a box when the
 * x,y values of the top left corner
 * and hieght and width is given, and
 * clears the inside of it.
 */
{
	int count,i,j;
	int currX=getx();	//get the currecnt cursor position
	int currY=gety();
/*-------Top Horizontal line------*/
	gotoxy(beginx,beginy);
	printf("%c",201);
	for(count=1;count<=width-2;count++)
		printf("%c",205);
	printf("%c",187);

/*-------Left verticle line-------*/
	gotoxy(beginx,beginy+1);
	for(count=1;count<=height-2;count++)
	{   printf("%c",186);
		gotoxy(beginx,beginy+1+count);
	}

/*-------Right verticle line------*/
	gotoxy(beginx+width-1,beginy+1);
	for(count=1;count<=height-2;count++)
	{   printf("%c",186);
		gotoxy(beginx+width-1,beginy+1+count);
	}

/*-------Bottom Horizontal line----*/
	gotoxy(beginx,beginy+height-1);
	printf("%c",200);
	for(count=1;count<=width-2;count++)
		printf("%c",205);
	printf("%c",188);

/*-------Clearing inside the frame---*/
	for(i=1;i<=height-2;i++)
	{
		gotoxy(beginx+1,beginy+i);
		for(j=1;j<=width-2;j++)
			printf(" ");
	}
	gotoxy(currX,currY);	//put the cursor back in place
}

Note that the alternate conio.h library file (which is named as ‘altconio.h’) is in the same directory as my source file, so it is included as:

#include “altconio.h”

I’ll leave you with that for now. Try out the setcolor() function if the altconio.h header file to try out different colors. Experiment with these codes and have fun :)

#include <stdio.h>
#include “altconio.h”void DrawHLine(int x,int y, int length);
void DrawVLine(int x,int y, int height);
void DrawFrame(int beginx,int beginy,int width,int height);int main()
{
clrscr();
DrawFrame(3,3,10,10);
DrawVLine(15,3,10);
DrawHLine(3,15,10);
gotoxy(0,20);
system(“pause”);
return 0;
}void DrawHLine(int x,int y, int length)
/*
* this function draws a horizontal line when
* the x,y values of the starting point and length
* is given.
*/
{
int count;
int currX=getx();    //get the currecnt cursor position
int currY=gety();
gotoxy(x,y);
for(count=0;count<length;count++)
printf(“%c”,196);
gotoxy(currX,currY);    //put the cursor back in place
}void DrawVLine(int x,int y, int height)
/*
* this function draws a verticle line when
* the x,y values of the starting point and height
* is given.
*/
{
int count;
int currX=getx();    //get the currecnt cursor position
int currY=gety();
gotoxy(x,y);
for(count=0;count<height;count++)
{
gotoxy(x,y+count);
printf(“%c”,179);
}
gotoxy(currX,currY);    //put the cursor back in place
}

void DrawFrame(int beginx,int beginy,int width,int height)
/*
* this function draws a box when the
* x,y values of the top left corner
* and hieght and width is given, and
* clears the inside of it.
*/
{
int count,i,j;
int currX=getx();    //get the currecnt cursor position
int currY=gety();
/*——-Top Horizontal line——*/
gotoxy(beginx,beginy);
printf(“%c”,201);
for(count=1;count<=width-2;count++)
printf(“%c”,205);
printf(“%c”,187);

/*——-Left verticle line——-*/
gotoxy(beginx,beginy+1);
for(count=1;count<=height-2;count++)
{   printf(“%c”,186);
gotoxy(beginx,beginy+1+count);
}

/*——-Right verticle line——*/
gotoxy(beginx+width-1,beginy+1);
for(count=1;count<=height-2;count++)
{   printf(“%c”,186);
gotoxy(beginx+width-1,beginy+1+count);
}

/*——-Bottom Horizontal line—-*/
gotoxy(beginx,beginy+height-1);
printf(“%c”,200);
for(count=1;count<=width-2;count++)
printf(“%c”,205);
printf(“%c”,188);

/*——-Clearing inside the frame—*/
for(i=1;i<=height-2;i++)
{
gotoxy(beginx+1,beginy+i);
for(j=1;j<=width-2;j++)
printf(” “);
}
gotoxy(currX,currY);    //put the cursor back in place
}