Nagios – Change date format

Hello everyone, today a customer asked me to change the default date format for the Nagios web interface since he wanted an international date format instead of the default us date format. I thought I should share the procedure so here is how to do it (I did this on Ubuntu 14.04.2):

This is how the web interface looked before:

nagios_date_format_default

Ok. First open the nagios.cfg file by running the following command:

sudo nano /usr/local/nagios/etc/nagios.cfg

nagios_change_date_format

Next search for “date_format” and change it from:

date_format=us

to:

date_format=iso8601

Save and then restart the Nagios service by running:

sudo service nagios restart

After the Nagios service has successfully restarted your web interface will look like this:

nagios_date_format_iso8601

Well, that´s it. Now all dates will be displayed in the international ISO8601 date format on your Nagios web interface. (Btw this does not change the log file format.)

I hope you liked my today´s post and I hope to see you again next time 🙂

Sources:

http://forums.meulie.net/t/nagios-log-format/2978

Tagged ,

Laptop Monitor to external Monitor

Hello everyone, today I want to show you how you can turn an old Laptop monitor to an external monitor so you are able to use your monitor even though your Laptop passed away a long time ago.

Before we begin here is short story why I am writing this post: Some years ago the first Laptop I bought with the first money I earned on my own (a Dell XPS M1530 to be precise) passed away due to heat problems. All attempts to repair it failed so I decided to buy a new Laptop. Since I did not want to throw my old one away I put it into a box which I kept in my basement. Some weeks ago I was searching for something and found the box I put my old Laptop in and I decided to at least revive a part of my old friend.

Here is a picture of the Dell XPS M1530: (Unfortunately I do not have a pre-broken picture of mine)

DellXPSM1530

Ok. Let´s get down to business 🙂

Here is what you will need:

  • An old Laptop monitor
  • The correct controller board (e.g. this one here is the correct one for my monitor)
  • A 12V power adapter which can provide at least 4A

The first thing you need to do is to separate your Monitor from your Laptop. (You need to open up your Laptop entirely and to unplug all or at least most of the cables to do so)

laptop_monitor

Now remove the case of your monitor. (This is a bit difficult and you will most likely need to break the case at least partially.)

laptop_monitor_no_case

Now have a look on the backside of your monitor. You should see a serial number like the one shown in the below picture:

laptop_monitor_serial_number

The serial number is important because you will need to search for the right controller board before you can continue.

I found this one here on ebay. (The delivery will take some weeks so be patient)

laptop_monitor_controller_board

When you have the correct controller board we can continue.

Maybe you will notice a cable like the one shown below on your monitor. (Not all monitors do have this cable hanging around separately but quite many do have them) This cable is responsible for the background lighting of the monitor so be careful not to damage it or otherwise your monitor will stay black.

laptop_monitor_backlight_cable

There should be a port on your controller board where you can plug this cable in.

laptop_monitor_backlight_cable_plugged

Now plug in the power adapter and choose a video source to test your monitor.

laptop_monitor_finished

Your monitor should now turn on and display something. (Maybe you need to choose the video source you want to use in the Menu Settings of the controller board before you can see something.)

Well, that´s it. These are the basic steps you need to know if you want to turn your Laptop monitor into an external monitor.

If you want to build a neat little extra monitor for your laptop or computer here is a good Instructable on how to do this.

I hope you liked my today´s post and I hope to see you again next time 🙂

Sources:

http://www.instructables.com/id/How-to-Convert-a-Laptop-LCD-into-an-External-Monit/

http://www.ebay.at/itm/111334125694?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1439.l2649

Tagged

Arduino – Amiibo Stand

Hello everyone. Today I want to show you something awesome I discovered on the internet.

I saw this awesome video here made by the user Modus Pwnin who created an Interactive Amiibo Stand for his Amiibos. I was absolutely amazed by his awesome project and wanted to build one for myself too. Thanks to his great tutorial he provided here I was able to do it. Since I´ve never used an Arduino before I had some troubles to get this up and running so I decided to share my experiences with you so that you can profit from them.

Ok. Let´s begin.

Here is a short list of things you will need:

Hardware:

If you have everything you need we can begin with our setup.

Setup:

All instructions you find below are from the Babel Fish tutorial of Adafruit Industries.

First we will take care of the Adafruit PN532 RFID/NFC Shield:

Solder the pins to the outer lines like in the picture below: (Source of instructions)

amiibo_stand_nfc_before

Next you need to do the following:

  • Use a knife to cut the connection between pin 2 and pin IRQ
  • Next use a piece of wire to connect pin IRQ and pin 6

It should look like this afterwards:

amiibo_stand_nfc_after

Next you need to build the Adafruit Wave Shield. (Source of instructions)

It´s not too hard to build. Here is a tutorial how to build it step by step.

Important: The black rectangles on top of the board are not included in the package of the Adafruit Wave Shield. I bought them from here.

When you have soldered all pieces to your Wave Shield board it should look like this:

amiibo_stand_waveshield

Next put your Adafruit Wave Shield on top of your Arduino Uno and put the Adafruit NFC/RFID Shield on top of the Adafruit Wave Shield.

It should look like this afterwards:

amiibo_stand_finished

And your Hardware Setup is done.

Software:

Next you will need to setup the necessary software before you can start programming your Arduino Uno.

The first step is to connect your USB A to B cable to your Arduino Uno and plug it into your computer.

Now download the Arduino software installer from here and start the installation.

After the installation has finished you need to add the following libraries to this path “C:\Program Files (x86)\Arduino\libraries“:

amiibo_stand_arduino_libraries

Now open the Arduino program.

amiibo_stand_arduino_start

Now paste this code into the Arduino program: (This code was written by Modus Pwnin)


#include <WaveHC.h>
#include <WaveUtil.h>
#include <Wire.h>
#include <Adafruit_NFCShield_I2C.h>
//#include <MemoryFree.h>

//Loading Strings into PROGMEM to save RAM
#include <avr/pgmspace.h>
//Character Intro File Names
const char string_0[] PROGMEM = "cfalc.wav";
const char string_1[] PROGMEM = "samus.wav";
const char string_2[] PROGMEM = "lmac.wav";
const char string_3[] PROGMEM = "fox.wav";
const char string_4[] PROGMEM = "wft.wav";
const char string_5[] PROGMEM = "villager.wav";
const char string_6[] PROGMEM = "marth.wav";
const char string_7[] PROGMEM = "yoshi.wav";
const char string_8[] PROGMEM = "pit.wav";
const char string_9[] PROGMEM = "kirby.wav";
const char string_10[] PROGMEM = "pikachu.wav";
const char string_11[] PROGMEM = "link.wav";
const char string_12[] PROGMEM = "luigi.wav";
const char string_13[] PROGMEM = "luigi2.wav";
const char string_14[] PROGMEM = "diddy.wav";
const char string_15[] PROGMEM = "dk.wav";
const char string_16[] PROGMEM = "peach.wav";
const char string_17[] PROGMEM = "zelda.wav";
const char string_18[] PROGMEM = "mario.wav";
const char string_19[] PROGMEM = "tlink.wav";
const char string_20[] PROGMEM = "dede.wav";
const char string_21[] PROGMEM = "lucario.wav";
const char string_22[] PROGMEM = "bowser.wav";
const char string_23[] PROGMEM = "mega.wav";
const char string_24[] PROGMEM = "sonic.wav";
const char string_25[] PROGMEM = "rosa.wav";
const char string_26[] PROGMEM = "mk.wav";
const char string_27[] PROGMEM = "shulk.wav";
const char string_28[] PROGMEM = "sheik.wav";
const char string_29[] PROGMEM = "ike.wav";
//Wave 4
const char string_60[] PROGMEM = "robin.wav";
const char string_61[] PROGMEM = "lucina.wav";
const char string_62[] PROGMEM = "char.wav";
const char string_63[] PROGMEM = "wario.wav";
const char string_64[] PROGMEM = "pacman.wav";
const char string_65[] PROGMEM = "ness.wav";
//Songs
const char string_30[] PROGMEM = "cfalc_s.wav";
const char string_31[] PROGMEM = "samus_s.wav";
const char string_32[] PROGMEM = "lmac_s.wav";
const char string_33[] PROGMEM = "fox_s.wav";
const char string_34[] PROGMEM = "wft_s.wav";
const char string_35[] PROGMEM = "vil_s.wav";
const char string_36[] PROGMEM = "marth_s.wav";
const char string_37[] PROGMEM = "yoshi_s.wav";
const char string_38[] PROGMEM = "pit_s.wav";
const char string_39[] PROGMEM = "kirby_s.wav";
const char string_40[] PROGMEM = "pika_s.wav";
const char string_41[] PROGMEM = "link_s.wav";
const char string_42[] PROGMEM = "luigi_s.wav";
const char string_43[] PROGMEM = "luigi2_s.wav";
const char string_44[] PROGMEM = "diddy_s.wav";
const char string_45[] PROGMEM = "dk_s.wav";
const char string_46[] PROGMEM = "peach_s.wav";
const char string_47[] PROGMEM = "zelda_s.wav";
const char string_48[] PROGMEM = "mario_s.wav";
const char string_49[] PROGMEM = "tlink_s.wav";
const char string_50[] PROGMEM = "dede_s.wav";
const char string_51[] PROGMEM = "luca_s.wav";
const char string_52[] PROGMEM = "bowser_s.wav";
const char string_53[] PROGMEM = "mega_s.wav";
const char string_54[] PROGMEM = "sonic_s.wav";
const char string_55[] PROGMEM = "rosa_s.wav";
const char string_56[] PROGMEM = "mk_s.wav";
const char string_57[] PROGMEM = "shulk_s.wav";
const char string_58[] PROGMEM = "sheik_s.wav";
const char string_59[] PROGMEM = "ike_s.wav";
//Wave 4
const char string_66[] PROGMEM = "robin_s.wav";
const char string_67[] PROGMEM = "lucina_s.wav";
const char string_68[] PROGMEM = "char_s.wav";
const char string_69[] PROGMEM = "wario_s.wav";
const char string_70[] PROGMEM = "pacman_s.wav";
const char string_71[] PROGMEM = "ness_s.wav";

// Then set up a table to refer to your strings.

const char* const string_table[] PROGMEM =
{
string_0,
string_1,
string_2,
string_3,
string_4,
string_5,
string_6,
string_7,
string_8,
string_9,
string_10,
string_11,
string_12,
string_13,
string_14,
string_15,
string_16,
string_17,
string_18,
string_19,
string_20,
string_21,
string_22,
string_23,
string_24,
string_25,
string_26,
string_27,
string_28,
string_29,
string_30,
string_31,
string_32,
string_33,
string_34,
string_35,
string_36,
string_37,
string_38,
string_39,
string_40,
string_41,
string_42,
string_43,
string_44,
string_45,
string_46,
string_47,
string_48,
string_49,
string_50,
string_51,
string_52,
string_53,
string_54,
string_55,
string_56,
string_57,
string_58,
string_59,
string_60,
string_61,
string_62,
string_63,
string_64,
string_65,
string_66,
string_67,
string_68,
string_69,
string_70,
string_71, };

char buffer[71];

#define IRQ 6 // this trace must be cut and rewired!
#define RESET 8

Adafruit_NFCShield_I2C nfc(IRQ, RESET);

SdReader card; // This object holds the information for the card
FatVolume vol; // This holds the information for the partition on the card
FatReader root; // This holds the information for the volumes root directory
FatReader file; // This object represent the WAV file for a pi digit or period
WaveHC wave; // This is the only wave (audio) object, since we will only play one at a time
/*
* Define macro to put error messages in flash memory
*/
#define error(msg) error_P(PSTR(msg))

//Setup()
uint32_t versiondata;

//My Added Variables
uint32_t lastcard = 0;
uint32_t currentcard = 1;
uint32_t CID = 0;
boolean songplaying = false;

//Loop()
uint32_t cardidentifier = 0;
uint8_t success;
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)

//////////////////////////////////// SETUP

void setup() {
// set up Serial library at 9600 bps
Serial.begin(115200);

PgmPrintln("Amiibo Scanner");

if (!card.init()) {
error("Card init. failed!");
}
if (!vol.init(card)) {
error("No partition!");
}
if (!root.openRoot(vol)) {
error("Couldn't open dir");
}

PgmPrintln("Files found:");
root.ls();

// find Adafruit RFID/NFC shield
nfc.begin();

versiondata = nfc.getFirmwareVersion();
if (! versiondata) {
Serial.print(F("Didn't find PN53x board"));
while (1); // halt
}
// Got ok data, print it out!
Serial.print(F("Found chip PN5")); Serial.println((versiondata>>24) & 0xFF, HEX);
Serial.print(F("Firmware ver. ")); Serial.print((versiondata>>16) & 0xFF, DEC);
Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);

// configure board to read RFID tags
nfc.SAMConfig();

//enable timeout waiting for cards
nfc.setPassiveActivationRetries(50);

}

/////////////////////////////////// LOOP

unsigned digit = 0;

void loop()
{

//Memory Checker

//Serial.print(F("Memory Available = "));
//Serial.println(freeMemory());

// wait for RFID card to show up!
Serial.println(F("Waiting for an Amiibo ..."));
// Wait for an ISO14443A type cards (Mifare, etc.). When one is found
// 'uid' will be populated with the UID, and uidLength will indicate
// if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);

cardidentifier = 0;
CID = 999;
if (success)
{
// Found a card!

Serial.print(F("Amiibo detected #"));
// turn the four byte UID of a mifare classic into a single variable #
cardidentifier = uid[3];
cardidentifier <<= 8; cardidentifier |= uid[2];
cardidentifier <<= 8; cardidentifier |= uid[1];
cardidentifier <<= 8; cardidentifier |= uid[0];
Serial.println(cardidentifier);

//Check the previous card

(lastcard = currentcard);
(currentcard = cardidentifier);

Serial.print(F("Last Amiibo: #"));
Serial.println(lastcard);
Serial.print(F("Current Card:"));
Serial.println(currentcard);

// Check Character ID

// Try to read the Character info page (#21)
uint8_t charID[32];
success = nfc.mifareultralight_ReadPage (21, charID);

if (success)
{
// turn page 21 into a character ID
CID = charID[6];
CID <<= 8; CID |= charID[6];
CID <<= 8; CID |= charID[5];
CID <<= 8; CID |= charID[4];
CID <<= 8; CID |= charID[3];
CID <<= 8; CID |= charID[2];
CID <<= 8; CID |= charID[1];
CID <<= 8; CID |= charID[0];
Serial.println("Character Number: ");
Serial.println(CID);

if (currentcard == lastcard)
{
/*
If there is no song playing, play a song.
*/
if (songplaying == false)
{
//Captain Falcon Song
if (CID == 6)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[30])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Samus Song
if (CID == 49157)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[31])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Little Mac Song
if (CID == 49158)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[32])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Fox Song
if (CID == 32773)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[33])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Wii Fit Song
if (CID == 7)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[34])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Villager Song
if (CID == 32769)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[35])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Marth Song
if (CID == 33)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[36])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Yoshi Song
if (CID == 768)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[37])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Pit Song
if (CID == 16391)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[38])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Kirby Song
if (CID == 31)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[39])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Pikachu Song
if (CID == 6425)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[40])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Link Song
if (CID == 1)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[41])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Luigi Song
if (CID == 256)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[42])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Diddy Song
if (CID == 2304)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[44])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//DK Song
if (CID == 2048)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[45])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Peach Song
if (CID == 512)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[46])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Zelda Song
if (CID == 257)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[47])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Mario Song
if (CID == 0)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[48])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Toonlink Song
if (CID == 65537)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[49])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Dedede Song
if (CID == 543)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[50])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Lucario Song
if (CID == 49178)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[51])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Bowser Song
if (CID == 1280)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[52])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Mega Man Song
if (CID == 32820)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[53])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Sonic Song
if (CID == 50)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[54])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Rosalina Song
if (CID == 66560)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[55])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//MetaKnight Song
if (cardidentifier == 287)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[56])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Shulk Song
if (CID == 16418)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[57])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Sheik Song
if (CID == 65793)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[58])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
//Ike Song
if (CID == 289)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[59])));
playfile(buffer);
if (wave.isplaying) {
songplaying = true;
}
}
}

if(!wave.isplaying)
{
songplaying = false;
}
}
/*
There is no song playing, play the intro sequence!
*/
else
{
//Captain Falcon
if (CID == 6)
{
strcpy_P(buffer, (char*)pgm_read_word(&(string_table[0])));
playcomplete(buffer);
}
//Samus
if (CID == 49157)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[1])));
playcomplete(buffer);
}
//Little Mac
if (CID == 49158)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[2])));
playcomplete(buffer);
}
//Fox
if (CID == 32773)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[3])));
playcomplete(buffer);
}
//Wii Fit
if (CID == 7)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[4])));
playcomplete(buffer);
}
//Villager
if (CID == 32769)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[5])));
playcomplete(buffer);
}
//Marth
if (CID == 33)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[6])));
playcomplete(buffer);
}
//Yoshi
if (CID == 768)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[7])));
playcomplete(buffer);
}
//Pit
if (CID == 16391)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[8])));
playcomplete(buffer);
}
//Kirby
if (CID == 31)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[9])));
playcomplete(buffer);
}
//Pikachu
if (CID == 6425)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[10])));
playcomplete(buffer);
}
//Link
if (CID == 1)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[11])));
playcomplete(buffer);
}
//Luigi
if (CID == 256)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[12])));
playcomplete(buffer);
}
//Diddy Kong
if (CID == 2304)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[14])));
playcomplete(buffer);
}
//DK
if (CID == 2048)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[15])));
playcomplete(buffer);
}
//Peach
if (CID == 512)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[16])));
playcomplete(buffer);
}
//Zelda
if (CID == 257)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[17])));
playcomplete(buffer);
}
//Mario
if (CID == 0)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[18])));
playcomplete(buffer);
}
//Toon Link
if (CID == 65537)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[19])));
playcomplete(buffer);
}
//Dedede
if (CID == 543)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[20])));
playcomplete(buffer);
}
//Lucario
if (CID == 49178)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[21])));
playcomplete(buffer);
}
//Bowser
if (CID == 1280)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[22])));
playcomplete(buffer);
}
//Mega Man
if (CID == 32820)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[23])));
playcomplete(buffer);
}
//Sonic
if (CID == 50)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[24])));
playcomplete(buffer);
}
//Rosalina
if (CID == 66560)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[25])));
playcomplete(buffer);
}
//Meta Knight
if (CID == 287)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[26])));
playcomplete(buffer);
}
//Shulk
if (CID == 16418)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[27])));
playcomplete(buffer);
}
//Sheik
if (CID == 65793)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[28])));
playcomplete(buffer);
}
//Ike
if (CID == 289)
{strcpy_P(buffer, (char*)pgm_read_word(&(string_table[29])));
playcomplete(buffer);
}
}
}
else
{
//if (currentcard == lastcard)
//{
// Serial.println("CID else");
wave.stop();
//}
lastcard = 123456;
currentcard = 654321;
songplaying = false;
}
}

//If the Amiibo is gone, stop the song.
else
{
//if (currentcard == lastcard)
//{
//Serial.println("UID else");
wave.stop();
//}
lastcard = 321123;
currentcard = 123321;
songplaying = false;
}
}

/////////////////////////////////// HELPERS

/*
* print error message and halt
*/
void error_P(const char *str) {
PgmPrint("Error: ");
SerialPrint_P(str);
sdErrorCheck();
while(1);
}
/*
* print error message and halt if SD I/O error
*/
void sdErrorCheck(void) {
if (!card.errorCode()) return;
PgmPrint("\r\nSD I/O error: ");
Serial.print(card.errorCode(), HEX);
PgmPrint(", ");
Serial.println(card.errorData(), HEX);
while(1);
}
/*
* Play a file and wait for it to complete
*/
void playcomplete(char *name) {
playfile(name);
while (wave.isplaying);

// see if an error occurred while playing
sdErrorCheck();
}
/*
* Open and start playing a WAV file
*/
void playfile(char *name) {
if (wave.isplaying) {// already playing something, so stop it!
wave.stop(); // stop it
}
if (!file.open(root, name)) {
PgmPrint("Couldn't open file ");
Serial.print(name);
return;
}
if (!wave.create(file)) {
PgmPrintln("Not a valid WAV");
return;
}
// ok time to play!
wave.play();
}

Next go to File -> Upload to upload the code to your Arduino Uno.

amiibo_stand_arduino_upload

If everything worked your Arduino should now be ready to use.

Prepare SD card:

Next you need to prepare your SD card. (I used a 8GB SD card which I normally use for my Raspberry Pi projects.)

amiibo_stand_sd_card

All you need to do is to format the SD card in FAT32. (You can use SD Card Formatter 4 to do this. You can download this tool from here.)

amiibo_stand_sd_card_properties

Use Audacity to prepare your Sound Files:

Before you can play your Sound Files with your Arduino Wave Shield you need to convert them into .wav files first. To do so do the following:

Open Audacity and open a Sound File (e.g. a mp3 file) you want to convert.

amiibo_stand_audacity_start

Next click on “Split Stereo to Mono” like shown in the picture:

amiibo_stand_audacity_split_to_mono

Next set Project Rate (Hz) to 22050:

amiibo_stand_audacity_hz

Next close one of the tracks (I think they are called tracks) like this:

amiibo_stand_audacity_close

Next go to File -> Export Audio…

amiibo_stand_audacity_export_audio

Make sure to save your file as .wav file.

amiibo_stand_audacity_save_wav

Edit the Metadata of your Sound file if you want to.

amiibo_stand_audacity_edit_metadata

Repeat the above steps for all Sound files you need.

Name your Sound files like this:

  • mario.wav: This file will only play once when the “Mario” Amiibo is placed on the Adafruit NFC/RFID Shield
  • mario_s.wav: This file will play as long as the “Mario” Amiibo remains on the Adafruit NFC/RFID Shield

Your file list should look like this:

amiibo_stand_wav_files

After you have finished converting and naming all your files your Arduino is ready for action.

Now you can play with your finished Amiibo Stand! Many thanks to Modus Pwnin for this awesome project. I had fun building this fun Arduino project and was able to gather some experiences using Arduino.

I hope you liked my post and I hope to see you again next time 🙂

Sources:

http://imgur.com/a/HaJBy

https://www.youtube.com/watch?v=nZ2LU7xCp8U

https://github.com/ModusPwnin/Interactive-Amiibo-Stand

https://learn.adafruit.com/adafruit-wave-shield-audio-shield-for-arduino/convert-files

http://www.reddit.com/r/amiibo/comments/31hsy7/help_me_fill_in_my_list_of_amiibo_character_ids/

http://www.reddit.com/r/amiibo/comments/2rf92p/amiibo_id_spreadsheet/

http://www.sounds-resource.com/other_systems/supersmashbrosfornintendo3ds/

http://www.arduino.cc/

https://www.youtube.com/watch?v=fCxzA9_kg6s

https://code.google.com/p/wavehc/downloads/detail?name=wavehc20110919.zip&can=2&q=

https://learn.adafruit.com/adafruit-wave-shield-audio-shield-for-arduino/wavehc-library

https://github.com/adafruit/Adafruit_NFCShield_I2C

http://stackoverflow.com/questions/26215669/windows-7-does-not-see-arduino-uno-r3-board-in-its-device-manager

https://learn.adafruit.com/adafruit-wave-shield-audio-shield-for-arduino/examples

Tagged

Boost your Wifi range with a DIY Cantenna

Hello everyone, today I want to show you how you can build yourself a Cantenna to boost the Wifi range of your computer.

Here are the things you will need:

  • A can
  • A N-Female chassis mount connector
  • A “pigtail” cable
  • A piece of thick wire you need to solder onto your N-Female chassis mount connector with a soldering iron
  • A wireless LAN adapter (Important: You will need one with an detachable antenna)
  • A piece of sandpaper (optional)

After you have gathered all materials you need you can start building your Cantenna.

Here is a picture of the can I used for my Cantenna:

cantenna_beer_can

The can I used has a diameter of 85mm and is about 18cm tall making it the perfect material for my Cantenna.

To calculate the necessary dimensions of your Cantenna you can use this online calculator here.

Here is a screenshot of the necessary dimensions for my can:

cantenna_calculations

So for example:

My can has a diameter of 85mm and is 180mm tall so I need to do the following:

  • I need to cut off the top of my can and I need to make sure that my can is still taller than 174.18mm afterwards
  • I need to drill a hole about 58.06mm above the bottom of my can for my N-Female chassis mount connector
  • I need to solder a piece of thick wire onto the pin of my N-Female chassis mount connector which is about 30.6mm in length

Here you can see a screenshot how I placed my N-Female chassis mount connector on my can:

cantenna_N_female_connector

Here is how I did this:

  • First I used some sandpaper to get of some of the cans paint
  • Next I drilled a hole about 58.06mm above the bottom of the can
  • Next I soldered the piece of thick wire with a length of about 30.6mm length onto the N-Female chassis mount connector
  • Then I drilled some more holes to mount my N-Female chassis mount connector onto the can

And here you can see the piece of thick wire inside my can pointing towards its center:

cantenna_inside_of_can

Now attach your “pigtail” cable to your N-Female chassis mount connector.

The cable should look like this:

cantenna_pigtail_cable

Then attach your wireless LAN adapter to the other end of your “pigtail” cable.

I used this one here: (I bought this one here.)

cantenna_wifi_adapter

And here is the finished Cantenna:

cantenna_finished

As you can see I added a plastic lid (don´t use one made out of metal!) to the top and painted it gray. You don´t need to do that. I just thought this would look better.

Well, that´s it. You now have a Cantenna which will allow you to connect to your Wireless networks from bigger distances. I hope you liked my post and I hope to see you again next time 🙂

Sources:

http://www.changpuak.ch/electronics/cantenna.php

http://www.turnpoint.net/wireless/cantennahowto.html

https://www.youtube.com/watch?v=NVjN9EK7B0E

Tagged

Turn SIM card into Micro SIM

Hello everyone, today I want to share a funny little Story with you. A few days ago my mother forgot her mobile phone in her pants and well, you guessed right, she put them into the washing machine. The mobile phone did not survive this and she had to buy a new one. But there was a problem with her new mobile phone: A normal SIM would not fit into it. (My mother still had a normal SIM card since her mobile phone was already quite old) I had to find a solution since my mother really needed her mobile phone and since it would be useless if nobody could call her, I tried my best to get it working.

I googled a bit and found out that you can turn a normal SIM card into a Micro SIM card simply by cutting it into the right shape. (A bit of metal was cut off when I did this but it looks like it had no impact on its functionality.)

Ok so here is what I did to turn my mothers SIM card into a Micro SIM card:

You need the following 2 things to do this:

  • A pair of sharp scissors
  • A Micro SIM card template which you can find here (german). (If the link does not work you can download it from here too.)

Here is the SIM card before the cutting process:

sim

Now print the Micro SIM template.

Important: Make sure to set the Scale to 100%.

micro_sim_template

Now put the template onto your SIM card (use some duct tape if necessary) and cut it into the right shape.

Here is the SIM card after the cutting process:

micro_sim

Sorry for the bad picture quality. As you can see the shape is not perfect but it works.

Well and this solved the problem. The now Micro SIM card fit almost perfectly into my mothers new mobile phone and worked as expected.

I hope you liked this little slice of life story post and I hope to see you again next time 🙂

Sources:

http://www.computerbild.de/downloads/4508371/Micro_SIM.pdf (german)

https://www.youtube.com/watch?v=r5NCmuyKoqQ (german)

Tagged

Raspberry Pi 2 – Windows 10 IOT Installation

Hello everyone, today I came across a great post on reddit which explains how to install Windows 10 IOT on your Raspberry Pi 2 in the most simple way I have seen so far. And I will show you how you can install the current Windows 10 IOT Build so you can lay your hands on this new topic as soon as possible 🙂

To download the new Windows 10 IOT you first need a Microsoft Account. Then click on this link to sign up on Microsoft Connect.

After you have successfully signed up for Microsoft Connect download the file “Windows_IoT_Core_RPI2_BUILD.zip“.

Now if you don´t have the Windows 10 Insider Preview Operating System installed on your computer or on a virtual machine, don´t worry: You don´t need it. The only thing yo need is a 7zip file called “DISM10074.7z” which you can download from here. (You can find the original post where this file comes from in this reddit thread here.)

Important: Don´t forget to unblock the “DISM10074.7z” file before you unzip it.

windows10iot_DISM10074_unblock

Next unzip the above zip files. In “Windows_IoT_Core_RPI2_BUILD” you will find the file “Flash.ffu“. Place this file into the “DISM10074” directory you extracted from the second zip file.

windows10iot_DISM10074

Next run PowerShell as Administrator and use the command “cd” to change into your “DISM10074” directory.

Now insert your Micro SD Card (at least 8GB) and start diskpart with the below command.

diskpart

Now find out the Disk number of your Micro SD card by using the below command:

list disk

Write down the Disk number of your Micro SD Card and exit diskpart.

exit

Now for the last step. Run the below command to write the Windows 10 IOT image to your Micro SD card:

Important: Replace the X of PhysicalDriveX with the number of your Disk before you run the below command.

.\dism.exe /Apply-Image /ImageFile:flash.ffu /ApplyDrive:\\.\PhysicalDriveX /SkipPlatformCheck

Wait for the command to complete. If it says “The operation completed successfully” everything went as expected.

Now you can close the PowerShell window and safely remove your Micro SD card and you are ready to use Windows 10 IOT.

Insert your Micro SD card into your Raspberry Pi 2 and plug in all necessary cables. Please keep in mind that the first boot will take some time so please be patient and don´t turn off your Raspberry Pi 2.

Well, that´s it. You can now start to explore Windows 10 IOT. Have fun!

I hope my post was interesting for you and I hope to see you again next time 🙂

Sources:

http://www.reddit.com/r/raspberry_pi/comments/34cad5/windows_10_iot_core_raspberry_pi_2_preview_live/

https://ms-iot.github.io/content/win10/SetupRPI.htm

https://www.raspberrypi.org/forums/viewtopic.php?f=56&t=98395

http://www.engadget.com/2015/04/30/windows-10-preview-raspberry-pi-2/

https://mariofraiss.wordpress.com/2015/05/02/setup-your-rasperry-pi-with-windows-10-iot-in-a-hyper-v-or-physical-environment/

Tagged ,

Windows God Mode

Hello everyone, today I want to show you something neat you can use to simplify Administration of your Windows Systems. This neat little trick is called “God Mode”. Well, it does not provide you with the powers of a god but it delivers you a useful toolbox with almost all settings you need to efficiently administrate your Windows System. This is especially useful on Windows 8 and Windows 8.1 Systems if you are like me and struggle with the new interface.

Ok, here are the steps to create your own God Mode Shortcut:

First you need to create a new folder.

godmode_new_folder

Next think of a good name for your God Mode Shortcut and append the following string:

.{ED7BA470-8E54-465E-825C-99712043E01C}

For example I called my God Mode Shortcut “AllSettings”:

AllSettings.{ED7BA470-8E54-465E-825C-99712043E01C}

godmode_naming

When you hit enter you will notice that the folder icon will change immediately into the Control Panel icon:

godmode_icon

Double click on it to open the Settings window:

godmode_settings

Well, that´s it. You now have a neat little toolbox with a lot of useful settings set up in less than 1 minute. Pretty cool, right?

I hope my post was useful for you and I hope to see you again next time 🙂

Sources:

http://www.tomshardware.com/news/GodMode-Windows-7-How-to,9345.html

Tagged

Raspberry Pi – Simple Garage Door Opener

Hello everyone. Today I want to show you how you can build your own Garage Door Opener which will allow you to open your Garage Door by simply pressing a button on a website. Pretty cool, huh? What we will basically do is setup a computer controlled push switch/button. A pretty good explanation can be found here.

Okay let´s do this. These are the things you will need:

  • A Raspberry Pi Model B (Plus power adapter, SD card and a LAN cable)
  • Raspbian wheezy as Operating System. You can download it from here.
  • A Raspberry Pi Relay (like this one here) or a transistor (It should work exactly the same but I did not try it out) – I recommend to use a relay since they are not very expensive and you can use them to work with higher currents and voltages. If you use a relay for this project you can reuse the same hardware to create an intelligent AC light switch without making any changes to the hardware. All you would need to do would be to change some fragments of the custom.html code from this post.

Hardware setup:

The hardware setup is pretty simple. Take you Raspberry Pi and connect it to you Raspberry Pi relay like this:

  • Connect one 5V Power Pin to the relay´s VCC Pin
  • Connect one Ground Pin to the relay´s GND Pin
  • Connect the GPIO 17 Pin (You can use any GPIO Pin you want but for this project I used GPIO Pin 17) to the relay´s IN1 Pin

RaspberryPi_Garage_Door_Pins

Now connect you relay to your Garage Door Control as if you would add a new push switch/button. Wire the relay like this:

  • Connect one wire from your Garage Door Control to the relay´s COM contact
  • Connect the other wire from your Garage Door Control to the relay´s NO contact

There are some great tutorials out there which explain how to set up electric Garage Door Openers (like this one here) so if you have trouble have a look at them. All Garage Door Openers work pretty much the same.

That´s it. You have finished the Hardware setup.

Software Setup:

Now the Software Setup. This will be easy too.

The first thing you need to do is to update your Raspberry Pi:

sudo apt-get update
sudo apt-get upgrade

Now you need to download WebIOPi:

wget https://webiopi.googlecode.com/files/WebIOPi-0.6.0.tar.gz

Unpack the archive file:

tar xvzf WebIOPi-0.6.0.tar.gz

Change into the newly created directory:

cd WebIOPi-0.6.0

And run the WebIOPi setup: (This will take some time)

sudo ./setup.sh

After the setup has finished you can run WebIOPi by running the following command:

sudo python -m webiopi

Now you should be able to access the WebIOPi web interface by entering the following URL into your Browser: (Default User: webiopi and Default Password: raspberry)

http://<IP-of-your-Raspberry-Pi>:8000/webiopi/

Now end the execution of WebIOPi by hitting Ctrl+C.

Since we want WebIOPi to be always available we need to run the below command to make sure that it will be started at boot:

sudo update-rc.d webiopi defaults

Now reboot your Raspberry Pi:

sudo reboot

If you can access WebIOPi´s web interface after the reboot everything is working correctly.

The next thing I did was to create a directory where I store my custom made code for my project:

sudo mkdir /usr/share/webiopi/htdocs/custom

And here is my code:


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content = "height = 300, width = 300, user-scalable = no, initial-scale = 1, maximum-scale = 1" />
<title>Garage Door Opener</title>
<script type="text/javascript" src="/webiopi.js"></script>
<script type="text/javascript">

webiopi().ready(function() {
content = $("#content");
});

function setGPIO17()
{
webiopi().setFunction(17,"OUT");
sleep(1000);
webiopi().setFunction(17,"IN");
}

function changeButtonPressed()
{
document.getElementById('PowerButton').src="power_on.jpg";
}

function changeButtonReleased()
{
document.getElementById('PowerButton').src="power_off.jpg";
}

function RunFunctions()
{
changeButtonPressed();
setGPIO17();
setTimeout(changeButtonReleased, 500);
}

function sleep(milliseconds)
{
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds)
{
break;
}
}
}

</script>
</head>
<body bgcolor="#191f2f">
<div id="content" align="center">
<font face="verdana" color="white">
<h1>Garage Door Opener</h1>
</font>
<input type="image" style="outline: 0" id="PowerButton" src="power_off.jpg" onclick="RunFunctions();">
</div>
</body>
</html>

So, how does the above code work? Well, it will set GPIO Pin 17 to OUT which will allow the electric current to power our relay. When the relay is powered it will short the contacts COM and NO closing the electric circuit resulting in our Garage Door to either open or close. Next the Javascript code will sleep for 1 second before setting the state of GPIO Pin 17 to IN again. This will result in our relay getting un-powered thus opening the electric circuit between COM and NO and closing the electric circuit between COM and NC.

To access the custom.html page simply enter the following URL into your Browser:

http://<IP-of-your-Raspberry-Pi>:8000/custom/custom.html

Well, that´s it. Now everything is ready to use. Pretty simple isn´t it?

Important:

Please make sure to secure the network you are using to access this control website and make sure to change the user and password of webiopi to make sure that only you can open your Garage Door and to prevent theft. Please take care not to damage your belongings when trying to set this up. I will not take responsibility for any damages or problems when you use these instructions to set this up for yourself. Do this on your own risk. And please try not to get hurt.

Of course you can have my source code as always. You can find it here.

I hope my post was useful for you and I hope to see you again next time 🙂

Sources:

http://www.themagpi.com/issue/issue-9/article/webiopi-raspberry-pi-rest-framework/

http://store.raspberrypi.com/projects/webiopi

http://mark-amos.blogspot.co.at/2013/02/web-connected-outlet-part-6.html

http://nayarweb.com/blog/2014/control-raspberry-pis-gpio-with-rest-qt-webiopi/

http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=45965

https://code.google.com/p/webiopi/wiki/JAVASCRIPT#WebIOPi.setFunction(gpio,_func[,_callback])

http://www.phpied.com/sleep-in-javascript/

https://raspbeerypi.wordpress.com/2014/01/15/webiopi-smartphone-computer-verbindung/ (german)

http://www.instructables.com/id/Raspberry-Pi-Garage-Door-Opener/step5/Wire-the-Circuit-to-the-Pi/

Tagged

Ubuntu 14.04 QEMU/KVM Gaming Virtual Machine

Hello everyone. Today I want to show you a little project I have been working on for quite a while now. I found this great post a while ago and was pretty amazed by the fact that it is possible to play Current Gen 3D games inside of virtual machines! So I decided to try it on my own to get this working as well with my own setup. I gathered some hardware from ebay and Amazon and started building my test environment. Lets go:

Here is my setup:

Hardware:

Software:

  • Operating System: Ubuntu 14.0.4.1 LTS
  • Kernel: 3.13.0 – generic
  • Qemu: 2.0.0

Virtual Machine:

  • Operating System: Windows 8.1 Enterprise 64bit
  • Driver: AMD Catalyst Packages Omega (14.12) – (Display Driver ver. 14.501.1003)
  • Game: Left 4 Dead 2 (I admit that it is not really Current Gen but you know what I mean)

Prerequisites:

Before you start with the below instructions you need to enable IOMMU in your BIOS. Please make sure that this setting is working. I read that there are motherboards out there with faulty BIOS versions which will not allow you to enable this setting. (Maybe you will need to update your BIOS version so you can use this setting.)

Here is what I did to enable IOMMU on my Asrock 970 Extreme3 2.0 motherboard:

I entered the BIOS/UEFI by hitting DEL and found the setting in Advanced -> North Bridge Configuration -> IOMMU where I enabled it. (This setting will be disabled by default on the most motherboards.) Then I clicked on Exit -> Save Changes and Exit to complete this step.

After you have successfully enabled IOMMU in your BIOS you can proceed by installing Ubuntu.

You can check your Ubuntu and kernel version with the following command:

uname -a

Here are my Ubuntu and kernel version:

Linux test-desktop 3.13.0-32-generic #57-Ubuntu SMP Tue Jul 15 03:51:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

As you can see I am currently using Ubuntu 14.04.1 LTS and my kernel version is 3.13.0 generic. (I know that 14.04.2 LTS is already out but I haven´t updated my system so far.)

I also installed an OpenSSH Server on my system so I can access my system remotely if I need to. (This step is completely optional.)

sudo apt-get install openssh-server

Installation QEMU/KVM

Now for the real deal. The first thing we need to do is to install QEMU and KVM. Simply run the below command to do so:

sudo apt-get install qemu-kvm

To check which version of QEMU got installed you can run this command:

kvm --version

The QEMU version I have installed at the moment is version 2.0.0 .

Edit modules and bootloader

The next thing you need to do is to edit the file “/etc/modules“. Simply add the modules listed below:


# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
# Parameters can be specified after the module name.

lp
rtc
pci_stub
vfio
vfio_iommu_type1
vfio_pci
kvm
kvm_amd

Important: If you are using an Intel CPU you need to replace kvm_amd with kvm_intel.

Ok. Now you need to edit the file “/etc/default/grub“. There you need to find the line below and edit it to look like this:

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash amd_iommu=on vfio_iommu_type1.allow_unsafe_interrupts=1"

Important: If you are using an Intel CPU you need to replace amd_iommu with intel_iommu.

After you have edited the file it should look like this:


# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
# info -f grub -n 'Simple configuration'

GRUB_DEFAULT=0
GRUB_HIDDEN_TIMEOUT=0
GRUB_HIDDEN_TIMEOUT_QUIET=true
GRUB_TIMEOUT=10
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash amd_iommu=on vfio_iommu_type1.allow_unsafe_interrupts=1"
GRUB_CMDLINE_LINUX=""

# Uncomment to enable BadRAM filtering, modify to suit your needs
# This works with Linux (no patch required) and with any kernel that obtains
# the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)
#GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef"

# Uncomment to disable graphical terminal (grub-pc only)
#GRUB_TERMINAL=console

# The resolution used on graphical terminal
# note that you can use only modes which your graphic card supports via VBE
# you can see them in real GRUB with the command `vbeinfo'
#GRUB_GFXMODE=640x480

# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux
#GRUB_DISABLE_LINUX_UUID=true

# Uncomment to disable generation of recovery mode menu entries
#GRUB_DISABLE_RECOVERY="true"

# Uncomment to get a beep at grub start
#GRUB_INIT_TUNE="480 440 1"

Now update Grub by running:

sudo update-grub

After the above command has finished reboot your computer to apply the changes:

sudo reboot

Blacklist Graphics Card

The next thing we need to do is to blacklist the graphics card we want to pass through to our virtual machine so that the host system will not use it for itself.

To get a list of PCI devices run the following command:

lspci -nn

Here is a list of my PCI devices:

00:00.0 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD/ATI] RD890 PCI to PCI bridge (external gfx0 port B) [1002:5a14] (rev 02)
00:00.2 IOMMU [0806]: Advanced Micro Devices, Inc. [AMD/ATI] RD990 I/O Memory Management Unit (IOMMU) [1002:5a23]
00:02.0 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD/ATI] RD890 PCI to PCI bridge (PCI express gpp port B) [1002:5a16]
00:04.0 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD/ATI] RD890 PCI to PCI bridge (PCI express gpp port D) [1002:5a18]
00:09.0 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD/ATI] RD890 PCI to PCI bridge (PCI express gpp port H) [1002:5a1c]
00:11.0 SATA controller [0106]: Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] [1002:4391] (rev 40)
00:12.0 USB controller [0c03]: Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB OHCI0 Controller [1002:4397]
00:12.2 USB controller [0c03]: Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB EHCI Controller [1002:4396]
00:13.0 USB controller [0c03]: Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB OHCI0 Controller [1002:4397]
00:13.2 USB controller [0c03]: Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB EHCI Controller [1002:4396]
00:14.0 SMBus [0c05]: Advanced Micro Devices, Inc. [AMD/ATI] SBx00 SMBus Controller [1002:4385] (rev 42)
00:14.1 IDE interface [0101]: Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 IDE Controller [1002:439c] (rev 40)
00:14.2 Audio device [0403]: Advanced Micro Devices, Inc. [AMD/ATI] SBx00 Azalia (Intel HDA) [1002:4383] (rev 40)
00:14.3 ISA bridge [0601]: Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 LPC host controller [1002:439d] (rev 40)
00:14.4 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD/ATI] SBx00 PCI to PCI Bridge [1002:4384] (rev 40)
00:14.5 USB controller [0c03]: Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB OHCI2 Controller [1002:4399]
00:15.0 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD/ATI] SB700/SB800/SB900 PCI to PCI bridge (PCIE port 0) [1002:43a0]
00:15.3 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD/ATI] SB900 PCI to PCI bridge (PCIE port 3) [1002:43a3]
00:16.0 USB controller [0c03]: Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB OHCI0 Controller [1002:4397]
00:16.2 USB controller [0c03]: Advanced Micro Devices, Inc. [AMD/ATI] SB7x0/SB8x0/SB9x0 USB EHCI Controller [1002:4396]
00:18.0 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 15h Processor Function 0 [1022:1600]
00:18.1 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 15h Processor Function 1 [1022:1601]
00:18.2 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 15h Processor Function 2 [1022:1602]
00:18.3 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 15h Processor Function 3 [1022:1603]
00:18.4 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 15h Processor Function 4 [1022:1604]
00:18.5 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 15h Processor Function 5 [1022:1605]
01:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] [1002:6779]
01:00.1 Audio device [0403]: Advanced Micro Devices, Inc. [AMD/ATI] Caicos HDMI Audio [Radeon HD 6400 Series] [1002:aa98]
02:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] [1002:6779]
02:00.1 Audio device [0403]: Advanced Micro Devices, Inc. [AMD/ATI] Caicos HDMI Audio [Radeon HD 6400 Series] [1002:aa98]
03:00.0 USB controller [0c03]: Etron Technology, Inc. EJ188/EJ198 USB 3.0 Host Controller [1b6f:7052]
06:00.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller [10ec:8168] (rev 06)

As you can see I have 2 identical graphics cards in my system which have the same identifier (This is normal). The strange thing is even after I had blacklisted them the GUI of my Ubuntu system would still continue working. The resolution dropped and windows started to open slower than before but nothing else. I´m not sure if this will cause issues in the future or not. (If you can use 2 different graphics cards. This will avoid possible issues.)

Ok. All you need to do here is to write down the addresses (02:00.0 and 02:00.1) and the identifiers (1002:6779 and 1002:aa98) of the graphics card you want to blacklist for your host and to pass through to your virtual machine.

Now you need to edit the file “/etc/initramfs-tools/modules” and add the identifiers of your graphics card. It should look like this:

# List of modules that you want to include in your initramfs.
# They will be loaded at boot time in the order below.
#
# Syntax: module_name [args ...]
#
# You must run update-initramfs(8) to effect this change.
#
# Examples:
#
# raid1
# sd_mod
pci_stub ids=1002:6779,1002:aa98

After you have done this you need to run the below command to rebuild initramfs:

sudo update-initramfs -u

And of course you need to reboot your computer after the above command has finished:

sudo reboot

After your computer is up and running again run the following command to make sure that your graphics card was successfully blacklisted:

dmesg | grep pci-stub

The command should return something like that:

[ 1.473148] pci-stub: add 1002:6779 sub=FFFFFFFF:FFFFFFFF cls=00000000/00000000
[ 1.473174] pci-stub 0000:01:00.0: claimed by stub
[ 1.473193] pci-stub 0000:02:00.0: claimed by stub
[ 1.473199] pci-stub: add 1002:AA98 sub=FFFFFFFF:FFFFFFFF cls=00000000/00000000
[ 1.473206] pci-stub 0000:01:00.1: claimed by stub
[ 1.473215] pci-stub 0000:02:00.1: claimed by stub

As I have mentioned before I use 2 graphics cards with the same identifiers which is the reason why there are 4 addresses listed in the above example. If you use 2 different graphics cards with different identifiers there will only be 2 addresses listed if you blacklist one of them.

If the command does not deliver an output like the above example or nothing at all it means that your attempt at blacklisting your graphics card failed and you need to find out why. Unfortunately I can not give you advice how to troubleshoot this issue since I could not reproduce an issue like this.

Create VFIO config file

Now we will create a file containing the addresses of our graphics card we want to pass through to our virtual machine. To do so we create a new file called “/etc/vfio-pci1.cfg” and enter our addresses.

Important: You need to add “0000:” at the beginning of your addresses to make it work. Unfortunately I do not know why.

Here is an example how this file should look:

0000:02:00.0
0000:02:00.1

Ok. That´s it. Our graphics card is now ready to use.

Create disk for the virtual machine

This step is really simple. We need a virtual disk where we can install our virtual machine. Simply run the below command to create one:

dd if=/dev/zero of=windows1.img bs=1M seek=120000 count=0

This will create a disk with 120GB storage. More than enough for our tests I think.

Create a script for the virtual machine

The next step is to create a script which will allow us to run our virtual machine. I simply used the script I found here and altered it a bit to match my system. You will need to do the same. You will need to replace the addresses and identifiers in the script to make it work. And you will need to alter the paths for the virtual disk we created in the step before and the path for your image file.

Here is my version of the script:


#!/bin/bash

configfile=/etc/vfio-pci1.cfg

vfiobind() {
dev="$1"
vendor=$(cat /sys/bus/pci/devices/$dev/vendor)
device=$(cat /sys/bus/pci/devices/$dev/device)
if [ -e /sys/bus/pci/devices/$dev/driver ]; then
echo $dev > /sys/bus/pci/devices/$dev/driver/unbind
fi
echo $vendor $device > /sys/bus/pci/drivers/vfio-pci/new_id

}

modprobe vfio-pci

cat $configfile | while read line;do
echo $line | grep ^# >/dev/null 2>&1 && continue
vfiobind $line
done

sudo qemu-system-x86_64 -enable-kvm -M q35 -m 4096 -cpu host \
-smp 4,sockets=1,cores=4,threads=1 \
-bios /usr/share/qemu/bios.bin -vga none \
-device ioh3420,bus=pcie.0,addr=1c.0,multifunction=on,port=1,chassis=1,id=root.1 \
-device vfio-pci,host=02:00.0,bus=root.1,addr=00.0,multifunction=on,x-vga=on \
-device vfio-pci,host=02:00.1,bus=root.1,addr=00.1 \
-drive file=/home/test/windows1.img,id=disk,format=raw -device ide-hd,bus=ide.0,drive=disk \
-drive file=/home/test/Downloads/Windows.iso,id=isocd -device ide-cd,bus=ide.1,drive=isocd \
-usb -usbdevice host:093a:2510 -usbdevice host:046d:c316 \
-boot menu=on

exit 0

After you have altered the script to match your system you need to run the below command to make the script executable:

sudo chmod 755 /usr/vm1

As you may have noticed I added some USB devices to my virtual machine. A mouse (093a:2510) and a keyboard (046d:c316). So that I will be able to work with the machine properly.

I would advise you to do the same since I tought that this is the easiest way to add USB devices. To find out the identifiers of your USB devices simply run:

lsusb

Here is an example of how the output will look like:

Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 004: ID 093a:2510 Pixart Imaging, Inc. Optical Mouse
Bus 001 Device 003: ID 046d:c316 Logitech, Inc. HID-Compliant Keyboard
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. 4-Port HUB
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 009 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 008 Device 002: ID 1058:1021 Western Digital Technologies, Inc. Elements 2TB
Bus 008 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

You can use the mouse and keyboard of your host system like I did. It will not cause errors to pop up but it will make the devices unavailable for the host system. (That´s also one of the reasons why I installed an OpenSSH Server)

After I completed these steps I decided to reboot my system one last time just to be sure that everything works:

sudo reboot

After my computer was up and running again I logged on to my GUI and run the following command in a terminal window on the GUI:

sudo /usr/vm1

Important: I pointed out that I ran the above command on the GUI because I ran into problems when trying to run the command from an SSH session. I got the following error message “Could not initialize SDL (No available video device) – exiting“. I was not able to solve this so far so I decided to start the script on the GUI.

Right after I ran the script a black QEMU window popped up and my mouse and keyboard were passed through to the virtual machine.

The next thing I did was to connect a VGA cable to the VGA port of the graphics card I passed through to the virtual machine. And I was greeted by the Windows 8 Logo right after plugging in the cable.

Virtual Machine Installation

The installation of Windows 8.1 on my virtual machine was exactly the same as installing it on a normal physical computer. I just went through the steps and created a Local Account for my tests.

Driver Installation

Ok. After the virtual machine was up and running I decided to install my graphics card drivers so that I can play games. But first I verified that my graphics card got passed through correctly. So I installed GPU-Z to make sure that the model of my graphics card was recognized correctly. It was. The next step for me was to download the drivers from here. Next I needed some extra steps to get the drivers running.

Here are the steps how I got my drivers running:

  • First I opened Settings -> Control Panel -> System and Security -> Administrative Tools -> Computer Management -> Device Manager -> Display Adapters and right clicked on the Microsoft Basic Display Adapter and clicked on Update Driver Software… -> Search automatically for updated driver software -> This resulted in Windows downloading some drivers and my graphics card was recognized as Radeon HD6450 after the download and installation completed. After that I rebooted the virtual machine.
  • Next I started the exe I downloaded and canceled it after it finished extracting files. Then I returned to Display Adapters in the Device Manager and right clicked on Radeon HD6450 and clicked on Update Driver Software… -> Browse my computer for driver software and I chose the Path where the Driver files were extracted. After the installation my graphics card was recognized as Radeon HD7450. That was not so strange since the description of the graphics card also got messed when I used it on a normal physical computer. Then I rebooted the virtual machine.
  • And finally I started the exe one last time and went through the whole installation like I would do it on a normal physical computer and rebooted one last time.

After all the above steps I had AMD Catalyst installed correctly and I was able to unplug the VGA cable and replace it with an HDMI cable. Now everything worked as I wanted. Now it was testing time.

Important: The installation process of your drivers may differ from mine so don´t be frustrated if the above steps don´t work for you.

Game Installation

Now I needed a game to test this whole setup. So I installed Steam and started to download Left 4 Dead 2 (I thought this game should do a good job for testing). After the download and installation both finished I started the game right away. There was no trouble at all with the game. It started and behaved normally. Sound and Video both worked as expected and as far as I can judge there was no noticeable delay. The only tiny delay I felt was from my mouse and keyboard. The reacted a split second slower than normally I would say but maybe this is because I used the hosts devices or maybe because I did not pass through an USB Controller for the virtual machine. I don´t know for sure why it behaved like this. All in all I was surprised that it all worked quite well.

Summary

Well, this was indeed an interesting project which consumed quite a lot of my time and was sometimes a bit troublesome but I enjoyed working on it and I´m quite happy that I got it running. But I will not simply drop this project as it is now. No. I want to work on it a bit more and I will try to make screenshots for each step as well as a video of the gaming experience (If possible I want to try different graphic cards too). And I would be happy if some of you could post some of their experiences with KVM and QEMU in the comment section if you have tried this too. And I would be happy if you have a look at this awesome post and give these guys some credit for their awesome work.

Well, that´s it for this post. Sorry that this post got quite long this time but I hope it was interesting for you and I hope that I see you again next time 🙂

Sources:

http://www.pugetsystems.com/labs/articles/Multiheaded-NVIDIA-Gaming-using-Ubuntu-14-04-KVM-585/

http://www.howtogeek.com/117635/how-to-install-kvm-and-create-virtual-machines-on-ubuntu/

http://ubuntuforums.org/showthread.php?t=2262280

http://apurv.me/vga-passthrough-using-kvm-in-ubuntu-14-04/

http://www.gitztalk.com/posts/2014/06/30/gaming-in-a-vm/

Tagged , , , ,

Tampermonkey – Youtube URL Rewrite Script

Hello everyone. Welcome to my first post of the year. Like last year I will try my best to share useful information with you. So here we go:

I think everyone of us got annoyed by age restricted videos at least once in our life and saw a screen like this which told us to log in:

youtube_age_restriction

(Sorry for the german screenshot.) Since I do not want to log in to watch a restricted video I tried to come up with a solution. Some of you might know this trick here. The trick is simple. Replace “watch?v=” with “v/” to circumvent the age restriction check. Not too much work but I wanted something better.

So I decided to use Tampermonkey, an extension for Google Chrome, to add custom Javascripts to websites to alter them. Here is a screenshot of the Tampermonkey Dashboard: (If you are using Firefox you can use Greasemonkey . The same script will also work in Greasemonkey.)

tampermonkey_dashboard

And here is my script which will do the work for me:


// ==UserScript==
// @name Youtube URL Rewrite Script
// @namespace https://theezitguy.wordpress.com/
// @version 1.0
// @description This script will rewrite Youtube URLs when pasted into the address bar of the browser or when the page is refreshed to unblock age restricted videos without the need to log in.
// @author theezitguy
// @include *://www.youtube.com/watch?v=*
// @grant none
// ==/UserScript==

var current_url = document.location;
var video_id = current_url.search.split('v=')[1];
var new_url = "https://www.youtube.com/v/" + video_id;
location.replace(new_url);

The script does the following: When you paste a Youtube Video Link into your address bar it will rewrite the URL. However if you click on a video on Youtube the script will only be triggered if you reload the page. Not perfect but I didn´t find a solution for this. (If you know a solution for this I would be grateful if you could post it in the comments section.)

If you want to try out the script here is a SFW video:

https://www.youtube.com/watch?v=6LZM3_wp2ps

youtube_disabled_age_restriction

That´s it. Now you can use this script to watch age restricted videos without to log in to Youtube or to alter the URL manually. I hope you liked my today´s post and I hope you can use this knowledge to improve your web experience with your own scripts. I hope to see you again next time 🙂

Sources:

https://gist.github.com/hussainm/5345bbefd35e2ec31793

http://andylangton.co.uk/blog/development/javascript-redirect-scripts

https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=en

http://lifehacker.com/watch-age-restricted-youtube-videos-without-signing-in-1529667193

Tagged