Montag, 27. November 2017

Netzkaffeekasse


Es gibt ja diese Sparschweine mit eingebautem Münzzähler. Mein Ziel war es, so ein Ding im Internet verfügbar zu haben. Und es soll Fotos machen von den edlen Spendern und räuberischen Dieben. :)

Dieser Artikel hat drei grössere Kapitel:
1. Die Hardware.
2. Installation der Software
3. Funktionsweise der Software.
Übersichtlicherweise sollte man erst den RasPi vorbereiten (2.) bevor alles zusammengebaut wird.
Zur Info. Also wenn dich nur das Proggen interessiert, gleich nach zu unterst scrollen. ;)

Was braucht man:

1x Sparschwein mit elektronischem Münzzähler
1x Raspberry Pi v3 (mit WLAN) mit Raspian oder so + Strom.
1x Flachband-Kabel für den Pi (Flachstecker zu Female)
1x RasPi Kamera mit Kabel
1x Platine (oder Karton ;) ) und ein paar Pins und Widerstände (hier: 600 Ohm) zum drauf löten.
1x schatzige Truhe, wenn möglich Schatztruhe. :)
ein paar Kabel und Lüsterklemmen.

Lötkram und Dremel wären auch von Vorteil.

Zur Konfiguration brauchst du natürlich noch einen Bildschirm und eine Tastatur.

Die Software von mir findet sich auf diesem Repository:
https://github.com/ben0bi/Netzkaffeekasse

Die Installation wird weiter unten erklärt.

Die Hardware

Bitte richte dir dann erst den RasPi ein, bevor du alles zusammen baust. ;)
(Siehe unten.)

Ich habe mir also mehrere Sparschweine mit elektronischem Münzzähler im Interdiscount gekauft, um dies zu realisieren. (Du brauchst nur eines.) Also etwas in der Art hier, mit Schweizer-Zählwerk:

Dieses habe ich komplett auseinander genommen. Die Elektronik-Platine kannst du wegschmeissen, die brauchen wir nicht. Wir brauchen nur den Zähler selbst. Dabei kam raus, dass der "Zähler" nur eine kleine Platte mit Kontakten ist, auf welcher eine kleine Stange bewegt wird um den Kontakt zu geben. Die Stange wird von der Münze zur Seite gedrückt. Diese Platine wurde über ein Flachbandkabel mit der Elektronik-Platine verbunden. Also einfach das Flachband von der Elektronik-Platine ab- und an die eigene dranlöten. Total einfach, analog und ohne Probleme zu "verbasteln".

Den Münzschlitz oben habe ich aus dem Plastikdeckel herausgedremelt und in die Kiste eingebaut. Das Zählwerk selbst kann man nun einfach darunter anschrauben.

Ich habe das Flachband zu den Kontakten von der Elektronik weg- und an meine eigene Platine gelötet. Dort kommen die Kontakte (von der einen Seite) als Stift heraus und werden noch mit einem Widerstand jeweils zu GND geleitet. Die andere Seite wird an 3.3v gelegt und braucht kein GND. Bei mir hat die Strom-Seite drei (3) Kontakte auf dem Flachband. Desweiteren kommen noch vier weitere Kontakte dazu (jeweils zwei zusammen), welche den Türöffnungsmechanismus überwachen. Auch diese brauchen wir als Stift, und auch diese müssen jeweils noch mit einen Widerstand mit GND verbunden werden. Mehr braucht es auf "unserer" Platine jedoch nicht.

Nun wird das ganze per Flachband an ein Raspberry Pi (RasPi) Version 3 angeschlossen. Hierbei bitte darauf achten, dass 3.3v und GND richtig belegt sind. Die anderen (GPIO-Inputs) kann man dann in der Software anpassen.

Zusammengesetzt sieht die Elektronik dann etwa so aus:

Ich bin gerade zu faul, das noch mal auseinander zu nehmen. Da werden wirklich nur die Leitungen an das RasPi weiter gegeben, mehr ist da nicht ausser den Widerständen für GND jeweils.

Die grünen und roten Kabel kommen vom Türkontrollmechanismus. Dieser besteht einfach aus Kontakten, welche Strom führen, wenn die Tür zu ist.

Ein RasPi V3 brauchen wir, damit wir über WLAN Zugriff auf das (im Inneren der Kasse versteckte) Computerchen zu bekommen, ohne dass jemand einfach das Kabel durchschneiden könnte. Später wird eventuell noch eine Notfallbatterie eingebaut, damit man auch nicht einfach den Strom ausstecken kann.

Schliesslich habe ich den Münzzähler angeschraubt:

...und die Platine daneben angeklebt. Den Raspi habe ich mit einer Schraube befestigt:

Hier musste ich darauf achten, dass der Kamera-Port möglichst nah am "Türschlitz" ist. Schliesslich konnte ich einfach das Kamerakabel dazwischen durch schieben:


Zu der Kamera gab es noch eine Halterung. Diese kann man mit einem Cinch-Stecker verbinden.
Dazu habe ich aus einer beliebigen Stereoanlage alles ausgebaut, bis ich die Cinch-Stecker herausdremeln konnte:

Cinch-Stecker unten rechts...

...einfach so richtig brutal heraus gedremelt.
Achtung, das hat ziemlich gestunken und könnte giftig sein. Ich war im Keller und musste ein bisschen raus danach...

Hier solltest du einfach darauf achten, dass du das Ding auch irgendwie befestigen kannst. Bei mir hat es zwei Löcher für die Schrauben.

Schliesslich habe ich das Loch in die Truhe gedremelt. Es ist ein ganz klein bisschen breiter als gewünscht, damit das Stromkabel (und evt. HDMI) noch durch passt. Die Kabel muss man vor der Installation durchschieben, danach geht es nicht mehr.


Nachdem die Kamera befestigt wurde, ist die Hardware soweit fertig.



Die Software

Auf dem Pi brauchen wir nun folgendes:

0. Python (Version 3) und die RPi.GPIO und picamera-Bibliotheken.
Für RPi.GPIO gibt es folgende Befehle:
sudo apt-get install python{,3}-pip
sudo pip3 install RPi.GPIO


und für picamera:
sudo apt-get install python3-picamera

(Ich hoffe das ist richtig, ansonsten steht es noch im Sourcecode.)

1. Den Apache Webserver mit PHP5
sudo apt-get install apache2 php5

1.1 Das Web-Verzeichnis sollte /var/www/html sein oder in der Software unten
umgestellt werden.

2. Git brauchen wir, um die Software herunter zu laden:
sudo apt-get install git

3.  Screen brauchen wir, damit das Ganze im Hintergrund laufen kann:
sudo apt-get install screen

4. In /home/pi/Documents laden wir die Sofware herunter:
git clone https://github.com/ben0bi/Netzkaffeekasse.git

5. Nun wird die Software installiert:
cd /home/pi/Documents/Netzkaffeekasse
sudo ./install.sh

Damit werden eigentlich nur ein paar Dateien an die richtige Stelle kopiert.

Falls du Probleme mit den Berechtigungen der Dateien/Ordner hast, kannst du folgendes tun:
sudo chmod 777 dateiname gibt dateiname alle Rechte.
sudo chmod +x dateiname macht dateiname ausführbar.

6. Schliesslich stellen wir ein, dass das Ganze beim booten gestartet wird:
sudo nano /etc/rc.local

Und dort drin dann:

cd /home/pi/Documents/Netzkaffeekasse
sudo ./startbackground.sh


Diese Datei nun mit Ctrl-O speichern und mit Ctrl-X wieder in die Konsole zurück gehen. In der Software (RasPython/kassenkontroller.py) solltest du nun noch überprüfen, ob alle Pins richtig gelegt wurden und eventuell die Nummern anpassen bei den fX, rX und kontrollerX-Variablen.

frGND ist nicht GND sondern der Kontakt welcher im Ruhezustand gegeben wird (also wenn keine Münze im Schlitz ist)!

7. Nun müsstest du noch mit der Raspi-Config das WLAN einstellen.
sudo raspi-config
..und dort dann im Menü herumwuseln.

Mit ifconfig bekommst du die IP-Adresse deines RasPi heraus. Bitte stelle diese fest ein, denn mit dynamischer IP müsstest du jedesmal im Router nachgucken, da ja schliesslich am Ende kein Bildschirm mehr direkt am RasPi hängt*.

Nun sollte es laufen. Über die IP-Adresse sollte man nun eine Webseite sehen, welche das Total, Log und neueste Foto ausgibt.

*Autoboot mit Bildschirm


Um den Leuten auch ein bisschen Zucker zu geben, habe ich auch einen Bildschirm angehängt.

Damit der RasPi in den Desktop bootet, muss man in der raspi-config die Bootoption einstellen auf:
Boot into desktop with autologin.

Wenn du RetroPie benutzt, musst du das über retropie-setup machen, da er sonst zwar in den Desktop bootet, danach aber gleich die Emulationstation startet.

Hier findest du Informationen dazu, wie man Chromium direkt starten kann. Für die Netzkaffeekasse muss er natürlich auf localhost zeigen:

Damit der Bildschirm nicht nach einer Weile aus geht, habe ich xscreensaver installiert und dort dann alles ausgeschaltet:
sudo apt-get install xscreensaver

Damit sollte nun wirklich alles wie auf dem Foto oben funktionieren.

Funktionsweise der Software

Mit install.sh werden die start.sh, startbackground.sh und stop.sh ins Root-Verzeichnis (der Software) kopiert sowie die Ordner ALERT_IMAGES und EINWURF_IMAGES erstellt. Die Dateien von RasPython/html werden nach /var/www/html kopiert und dort noch der Ordner IMAGES erstellt.

stop.sh ist nur für den Zugriff auf den Screen, welcher mit startbackground.sh erstellt wird, konzipiert.
Beenden kann man die Software jeweils mit Ctrl-C.

Der Hauptbestandteil ist natürlich das Python-Script RasPython/kassenkontroller.py. Dieses macht ein Foto bei jedem Einwurf einer Münze sowie wenn man den Deckel öffnet. Dazu werden auch noch verschiedene *.nkk-Dateien angelegt.

TOTAL.nkk: Hier ist das aktuelle Total der Münzen in der Truhe angegeben.
LOG.nkk: Hier wird fein säuberlich jede Aktion hineingeschrieben.
ACTUALTEXT.nkk: Das ist der Text, der beim aktuellen Bild auf der Webseite angezeigt wird.
ACTUALTIMESTAMP.nkk: Dieser Zeitstempel wird benutzt, um das Bild auf der Webseite vom Server neu zu laden (anstatt vom Cache).

Jedes Bild wird entweder im Ordner EINWURF_IMAGES oder im Ordner ALERT_IMAGES abgelegt. Das jeweils neueste Bild wird auch noch in das /var/www/html/IMAGES-Verzeichnis kopiert als "latest.jpg" und dort von der Webseite geladen.

Das Script ist auf Schweizer Münzen ausgelegt, das heisst, die 50-Rappen Münze ist kleiner als die 10-Rappen Münze. Deshalb wird diese als 0.07 angegeben und später (weiter oben) wieder in 0.5 umgewandelt. Hier gilt nämlich, dass jeweils die grössere Nummer genommen wird wenn mehrere Kontakte gegeben werden.

Hier ist als Beispiel der Ablauf der Kontakte auf der Platine, wenn man ein 20 Rappen Stück einwirft:

GND -> 0.05 -> 0.07 -> 0.1 -> 0.2 -> 0.1 -> 0.07 -> 0.05 -> GND: Ah, es ist ein 20Rappen Stück.

Bei 0.07 wäre es ein 50Rappen Stück. Alle anderen Werte kann man direkt übernehmen.

Ich hoffe dieses Projekt hat dir gefallen und danke für die Aufmerksamkeit.

Donnerstag, 26. Oktober 2017

Eigentümer des Sol-Systems

Geliebtes Lebewesen,

Wie in diesem Post postuliert, habe ich schon 2012a.d. das Sonnensystem als mein Eigentum erklärt.
Nach den UCC (Unified Commecial Code) Regeln, muss ein neues "Gesetz" öffentlich ausliegen - was durch die Form des Internets geschah - und ist gültig nach 21 Erdentagen ohne Widerspruch.

Ich habe in den gesamten fünf Jahren keinen einzigen Widerspruch bekommen.

Somit bin ich, der Mensch Oki Wan Ben0bi, bei den Staaten durch die Person "[Name geschützt] geboren in [geschützt], Schweiz am 29.01.1982" vertreten, rechtlich gesehen der offizielle Eigentümer der unten genannten Assets:

+ Das Sonnensystem mit der Sonne Sol
+ Alle darin sich befindlichen Planeten, Monde und anderen Himmelskörper
+ Alle Resourcen auf den genannten Körpern
+ Alle Lebewesen* PERSONEN auf den genannten Körpern, welche im Sonnensystem geboren oder erschaffen wurden - so lange die Sklaverei noch existiert. (Nur weil sie für die Menschen angeblich nicht mehr existieren soll, gilt das leider noch nicht für die Mensch-Tier Beziehungen.)
*Sorry, falsch formuliert. Ich habe kein Interesse an Lebewesen und Personen sind KEINE Lebewesen sondern ein künstlich aufgedrängter Teil davon. Bitte richtig verstehen.
Dies ist unwiderruflich, denn es wurde auch beim originalen Postulat kein Widerspruch eingelegt.

Als Eigentümer der genannten Assets rufe ich hiermit die folgenden Hausregeln aus:

0. Jegliche Gesetze, Anordnungen, executive Orders, und anderen Regelsysteme auf Gaia (Sol III) - auch der UCC - werden durch diese Hausregeln ersetzt.

1. Es ist alles erlaubt, was niemandem anderen schadet.
2. Lethale Waffen sind verboten. Jegliche Herstellung von Lethalwaffensystemen ist verboten.
2.1. Waffenproduzierende Firmen müssen sich eine andere Beschäftigung suchen. Sie werden nicht mehr geduldet. Das selbe gilt für Munition und Assistenzsysteme.
2.2. Jegliche Lethalwaffensysteme (Pistolen, Gewehre, Cruise Missiles, Drohnen, Panzerwaffen, Kriegsschiff-Kanonen, etc etc) werden eingezogen und vernichtet oder in etwas Nützliches verwandelt. Dies muss mit nicht-lethalen Waffen geschehen, wenn überhaupt mit Waffen, da ja die lethalen eingezogen und vernichtet werden. Da gibt es keine Ausnahme...liebe Polizei.
3. Schutz-Objekte dürfen weiter produziert werden: Tarnung, Panzerung, Schildtechnologie...da hab ich nichts dagegen.

A. Ich behalte mir vor, die Hausregeln jederzeit zugunsten der Menschheit zu verändern oder zu erweitern.

Dienstag, 17. Oktober 2017

DIY: Emulator: TextGraphic Setup

Nun gut, das mit der Emulatorik wird wohl hinten angestellt, aber ich hoffe, ich kann trotzdem ein bisschen Wissen vermitteln mit meiner Serie hier.

Ok, nachdem wir nun eine sehr komplizierte Methode in dieser Serie kennengelernt haben, versuche ich nun eine einfachere Version zu generieren, welche den Bildschirm mit Text aufbaut. Ich hoffe, das ist dann auch schneller, wir werden sehen.

Vielleicht mache ich dies später auch mit WebGL direkt, doch erst muss ich herausfinden, wie man die verdammten Pixel auf einer Textur direkt bearbeiten kann. Das von vorher ^ kanns ja nicht wirklich sein. Also....

Kurz: Es ist zu langsam. Hier ist der Code:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Emulator TextGraphic</title>

<style>
#canvas
{
font-size: 4pt;
}
#blocker
{
position: absolute;
top: 0px;
left: 0px;
background-color: rgba(1,1,1,0.01);
width: 100%;
height: 100%;
z-index: 10;
}
</style>

</head>

<body>
<div id="canvas"></div>
<div id="blocker"></div>
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>

<script>

var RGB = function(red, green, blue) {return ((red << 16) & 0xFF0000) | ((green<<8) & 0x00FF00) | (blue & 0x0000FF);}
var RED = function(color) {return (color>>16) & 0x0000FF;}
var GREEN = function(color) {return (color>>8) & 0x0000FF;}
var BLUE = function(color) {return color & 0x0000FF;}
var HEXT = function(value) {return '#'+value.toString(16);}; // return hex string of a value with preceding #.

var c_Screen = function(xsize, ysize)
{
var blockChar='&#9600';
if(xsize<=0)
xsize=1;
if(ysize<=0)
ysize=1;

// ysize must be dividable by 2 because of the block chars.
if(ysize%2==1)
ysize+=1;

var m_width = xsize;
var m_height = ysize;
var m_screenArray = new Array();

// create a randomly coloured screen.
this.randomScreen = function()
{
m_screenArray = new Array();
for(var i=0;i<m_width*m_height;i++)
{
m_screenArray.push(RGB(Math.random()*255, Math.random()*255, Math.random()*255));
}
}
// initialize with a random screen.
this.randomScreen();

this.setPixel = function(x,y,color) {m_screenArray[x*y+x]=color;}

// build the html text from the screen array.
this.buildText=function()
{
var txt='<nobr>';
for(var y=0;y<m_height;y+=2)
{
for(var x=0;x<m_width;x++)
{
var color=HEXT(m_screenArray[x*y+x]);
var subcolor=HEXT(m_screenArray[x*(y+1)+x]);
txt+='<span style="color:'+color+'; background-color:'+subcolor+';">'+blockChar+'</span>';
}
txt+='<br />';
}
txt+='</nobr>';
return txt;
}
}

var done=false;
var scr = new c_Screen(160,160);

function loop()
{
scr.randomScreen();
var txt = scr.buildText();
$('#canvas').html(txt);
window.setTimeout(loop,20);
}

$(document).ready(function()
{
$('body').keydown(function(e){done=true;});
loop();
});
</script>

</body>

</html>

Mit setPixel kann man einen Pixel setzen, und mit buildText bekommt man den HTML-Text dazu.. Ich habe es mit verschiedenen Geschwindigkeiten versucht, es kommt nicht unter 50ms und ist somit ungeeignet. Jedoch könnte man dies für ein Rundenbasiertes Spiel benutzen, mal sehen...der ANSI-Zeichensatz ist noch geil...

Hier ist der Source-Code dazu (im Ordner HTMLVersion):
https://github.com/ben0bi/EmulatroniX/releases/tag/Blog_Series_TextGraphic_1

Danke für die Aufmerksamkeit.

Dienstag, 6. Juni 2017

RetroPie Screen Orientation

Deutsch 

(click here for the english version.)

Um auf dem RetroPie-System die Bildschirm-Orientation zu ändern, muss man einfach in /boot/config.txt die Variable display_rotate hinzufügen oder ändern.

Aufgrund meiner speziellen Konfiguration habe ich die Kompassrichtungen gewählt, wobei ich bei Nord im Norden sitze und gegen Süden schaue.

Wenn der Bildschirm vor dir steht ist Nord die normale Orientation, Süd ist um 180°, Ost um 90° nach links und West um 90° nach rechts gedreht.

Da ich den Bildschirm nach oben spiegle, braucht es manchmal eine vertikale Spiegelung anstatt einer Drehung. Hier gebe ich euch nun die Zahlen dafür (horizontal spiegeln weiss ich grad nicht mehr, brauchts aber auch nicht wirklich). Für die Spiegelung kann man einfach den Orientation-Wert mit dem Spiegelungs-Wert binär ODER-verknüpfen:

0 = Nord
1 = Ost
2 = Süd
3 = West
0x20000 = Nord vertikal gespiegelt.
0x20001 = Ost vertikal gespiegelt.
0x20002 = Süd vertikal gespiegelt.
0x20003 = West vertikal gespiegelt.

Um ganz schnell die Orientation zu ändern, habe ich mir einfach für jeden Wert eine config.txt und ein .sh-Script geschrieben und die .sh-Scripts dann in ein Menu von EmulationStatin kopiert, welches .sh-Scripts "versteht".

Hier ein Beispiel:
/home/pi/orientation/Config_East_Flipped.txt

...

display_rotate = 0x20001


/home/pi/RetroPie/MyMenu/Orientation_East_Flipped.sh

#!/bin/bash
sudo cp /home/pi/orientation/Config_East_Flipped.txt /boot/config.txt
sudo shutdown -r now


Nach dem Kopieren wird einfach der RasPi neu gestarted und gut ist.

Viel Spass damit!

Sonntag, 21. Mai 2017

DIY: Emulator Teil 2: Setup Basisgerüst (JavaScript)

Im vorigen Artikel (Part 1) haben wir uns damit befasst, was ein Emulator ist. Nun kommen wir zum Programmieren selbst.

Wir brauchen für unser Grundgerüst verschiedene JavaScript-Bibliotheken.

  • jQuery -> Vereinfacht viele Dinge.
  • PixiJS -> Die Grafikbibliothek.
  • RUNPIXI -> Diese Bibliothek habe ich geschrieben, um PixiJS ganz einfach zu initialisieren.

Ich werde diese Bibliotheken nicht herunterladen, sondern einen direkten Link dazu angeben. Somit hat man erstens immer die aktuelle Version und zweitens wird Zeit gespart, wenn andere (fremde) Webseiten denselben Link benutzen. Der Browser hat die Datei dann schon im Cache gespeichert.

Ordnerstruktur

Generieren wir erst mal die generelle Ordnerstruktur und die ersten Dateien:

  • ./  --> Das ist das root/Basis-Verzeichnis.
  • js/  --> enthält alle JavaScript-Dateien.
  • css/ --> enthält alle CSS-Dateien.

[weitere werden folgen]

Ich benutze immer diese Ordnerstruktur für meine Web-Projekte, du kannst natürlich auch eine andere Struktur anlegen.

Nun legen wir ein paar verschiedene Dateien an:

  • ./index.html
  • ./css/base.css

css/base.css

Die Datei css/base.css enthält die grundlegenden Layout-Einstellungen:

html, body
{
width: 100%;
max-width: 100%;
height: 100%;
min-height: 100%;
overflow-x: hidden;
overflow-y: hidden;
}

div, html, body
{
padding: 0;
margin: 0;
}

#wrapper
{
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
}

#pixiscreen
{
position: relative;
margin: 0 auto;
max-height: 100%;
min-height: 100%;
}

Der BODY und HTML Bereich wird auf die Fenstergrösse angepasst. Mit overflow-x: hidden wird alles versteckt, was breiter als das Fenster ist. Dasselbe wird mit der Höhe gemacht. Irgendwie ist das Div beim Chrome immer 0.2 Pixel grösser als das Fenster oder so, was zur Folge hatte, dass Scrollbalken auftauchten, welche dann sowieso noch ein bisschen mehr vom Fenster verdeckt haben. Overflow bräuchte es nicht, wenn das div zum Beispiel 99% Grösse hätte, doch ich will einen randlosen Bildschirm.

Das Padding- und Margin-Attribut wird auf 0 gesetzt, damit kein Rand übrig bleibt. Der #wrapper muss eine absolute Position haben, damit der #pixiscreen mit Margin horizontal zentriert werden kann. Dies hier nur zur Sicherheit, da der Pixi-Screen sowieso das ganze Fenster ausfüllt.

index.html

In die index.html kommt erstmal das HTML-Grundgerüst:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>EmulatroniX</title>
<link rel="stylesheet" type="text/css" href="css/base.css">
</head>
<body>
<div id="wrapper">
<div id="pixiscreen"></div>
</div>

<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
<script src="https://pixijs.download/v4.5.2/pixi.min.js"></script>
<script src="http://cdn.rawgit.com/ben0bi/RUNPIXI.js/v0.6.4/RUNPIXI/RUNPIXI.js"></script>

<script>
function mainLoop() {}

$(document).ready(function()
{
RUNPIXI.initialize('pixiscreen', mainLoop);
console.log("Ready.");
});
</script>
</body>
</html>


Mit dem DOCTYPE-Tag wird dem Browser mitgeteilt, dass wir HTML 5 benutzen.
Das Meta-Tag stellt das Characterset auf UTF-8. Somit ist immer klar das gleiche Characterset definiert. Die CSS-Dateien werden im Header eingebunden, da sie vom Browser gebraucht werden, um das Layout aufzubauen. Die JavaScript-Dateien werden jedoch am Ende des Bodys hereingeladen, so dass das Layout im Aufbau nicht blockiert wird.

Das #pixiscreen-div ist im #wrapper-div, damit man es horizontal zentrieren kann.

jQuery ist eine Bibliothek, um viele Sachen in JS zu vereinfachen.
Den jQuery-Link bekommt man hier in dieser Form.

PixiJS ist eine JavaScript 2D-Graphikbibliothek, welche auf Geschwindigkeit ausgelegt ist.
Sie benutzt wenn möglich WebGL, ansonsten wird die DOM-Struktur benutzt.
Hierin werden wir die Textur erstellen, auf welcher dann der Bildschirm des Emulators gerendert wird (sogenannte RTT-Technik: Render-To-Texture - wobei hier nicht wirklich eine Szene auf die Textur gerendert wird, sondern nur die Pixel der Textur "direkt" ausgetauscht/verändert werden).
Den Link zu Pixi habe ich selbst aus den Releases von PixiJS herausgesucht.

Schliesslich ist RUNPIXI.js eine kleine Bibliothek, welche ich geschrieben habe, um den Initialisierungsprozess von PixiJS zu vereinfachen. Man braucht nun nur noch ein Kommando auszuführen, nämlich RUNPIXI.initialize(DOMContainerID, loopFunction), alles Andere macht RUNPIXI.

Wenn die Fenstergrösse geändert wird, merkt RUNPIXI das und passt automatisch den Pixi-Renderer an.

Schliesslich wird der Pixi-Bildschirm in dem kleinen Script am Ende initialisiert. Dazu muss es eine mainLoop-Funktion haben, welche nach jedem Frame aufgerufen wird. Diese benutzen wir gerade noch nicht. Man beachte, dass beim Namen des pixiscreens in der Initialisierungsfunktion kein # davor steht: RUNPIXI verzichtet auf jQuery.

Du kannst dem Pixiscreen deine eigene Hingergrundfarbe geben oder ihn sogar transparent machen, indem du die Farbe in der Initialisierungsfunktion als Parameter angibst. Die Farbe kann hexadezimal so angegeben werden: 0xRRGGBB wobei R für Rot, G für Grün und B für Blau steht.

RUNPIXI.initialize('pixiscreen', mainLoop, 0x111133); <-- Schönes dunkles Blau.
RUNPIXI.initialize('pixiscreen', mainLoop, 'transparent'); <-- Transparent. Man sieht nur, was du auch zeichnest.

Fertig!

Wenn du nun die Index.hmtl-Datei im Browser öffnest, sollte dein gesamter Browserbildschirm türkisblau sein (ausser du hast eine andere Farbe angegeben). Damit haben wir die Basis-(Graphik-)Engine initialisiert - das war ja noch ganz einfach. :)

Ich werde für jeden Part/Artikel auf GitHub ein Release vom jeweils aktuellen Master machen.

Das ist das Release für diesen Artikel:
https://github.com/ben0bi/EmulatroniX/releases/tag/Blog_Series_Part_2

Weiter gehts mit [Bitte warten, komplett neuer Aufbau] DIY: Emulator Teil 2.1: Der Emulator Bildschirm.


Samstag, 20. Mai 2017

DIY: Emulator Teil 1: Research

Dies ist eine deutsche Neuauflage meiner How-To-Make-An-Emulator-Serie, Teil 1.
Im originalen (englischen) Artikel ist ein ziemliches Chaos, da ich mich nicht wirklich für eine Entwicklungsumgebung entscheiden konnte. Nun habe ich JavaScript gewählt und werde auch dabei bleiben.

In diesem Artikel betreiben wir erstmal ein bisschen Forschung.

[EDIT]: Ich bin ein autodidaktischer Programmierer und habe Spass daran, Dinge selbst herauszufinden oder nachzuprogrammieren (Theorie zu Praxis, nicht einfach Code kopieren ;) ). Ich habe erst mal ein bisschen komplexere Artikel geschrieben um die Grafik aufzubauen. Das wurden dann schon ein paar Artikel, und bei diesen habe ich alles "selbst erfunden". Beim Emulator-Code selbst werde ich höchstwahrscheinlich einfach die zuunterst verlinkten Artikel ins Deutsche übersetzen.

Da schon nur der Grafikaufbau in mehrere Artikel ausgeartet ist, werde ich versuchen, eine etwas andere Nummerierung zu bewerkstelligen:

[EDIT] Ich habe nun das ganze Chaos aus den veröffentlichten Artikeln heraus genommen.
Grund: Es war in jeder Version zu langsam auf Standard-Laptops. Ich versuche dies nun mit Shadern zu bewerkstelligen. Bitte warten...

Mit Nummern versehen sind die Artikel, welche sich mit dem Aufbau des Grundgerüstes befassen, welches "extern" benötigt wird um den Emulator ("intern") anzuzeigen und zu bedienen. Die Grafik und das Basisgerüst werden in Teil 2 und allen zugehörigen Artikeln abgehandelt, also Teil 2.1_12.1_22.1_3, sowie Anpassungen 1 und Demo 1.

Mit Buchstaben versehen sind die Artikel, welche sich mit dem jeweiligen Emulator selbst befassen,
zum Beispiel [TODO] Gameboy A: Die CPU, Gameboy B: ...

Du findest alle Artikel zu dieser Serie auf dieser Seite.

Was ist ein Emulator?

Ein Emulator ist eine Software, welche eine bestimmte Hardware A auf einer anderen Hardware B simuliert, so dass man die Software, welche für Hardware A konzipiert wurde, auch auf System/Hardware B laufen lassen kann.

Die geläufigsten Emulatoren sind Konsolen-Emulatoren, welche zum Beispiel den Super-Nintendo auf einem PC emulieren. Es gibt aber auch für jegliche andere Hardware Emulatoren. Von einfachsten Chips bis zu den grössten Superrechnern kann man alles emulieren - wenn man genug (Rechen-)Zeit hat.




Ich habe einst einen Sega Master System Emulator, den ein Freund geschrieben hat, mit einer besseren graphischen Ausgabe beschert. Seine Software hat das Bild direkt in einem ganz kleinen Fensterchen auf dem Bildschirm ausgegeben. Ich habe dann eine 3D-Bibliothek mit einem Texturrenderer benutzt, um zu skalieren und verschiedene Filter darüber zu legen.
Leider habe ich den Sourcecode verloren.

Hier ist der Emulator für deine Befreudigung:
SMSEmu (homeserver) (direkter Download)
SMSEmu (OneDrive)

Dieser englische Artikel bietet gute Grundlagen.
http://fms.komkon.org/EMUL8/HOWTO.html

Zuerst möchte ich das Sega Master System emulieren, doch zuallererst muss eine Basis-Engine geschrieben werden mit der Grafikausgabe und weiterem. Die Grafik wird in Part 2 herbeiprogrammiert.

Diese ROMs (Spielkassetten-Dateien) sind für das Sega Master System. Sie dürfen jedoch nicht mit deinem Produkt ausgeliefert werden. Das wäre illegal. Ich biete sie hier nur an, damit man etwas zum testen des Codes hat.
SMSRoms.zip (homeserver) (direkter Download)
SMSRoms.zip (OneDrive)

Theoretische Überlegungen

Mein Ziel ist immer noch ein Multi-Purpose-(Konsolen-)Emulator, welcher aufgrund des geladenen ROMs entscheidet, welche Hardware dafür vorgesehen ist, und diese dann emuliert. Du könntest dann ROMs von jeder unterstützten Plattform in den selben Ordner kopieren und einfach das Spiel spielen, ohne dich um die Plattform-Auswahl kümmern zu müssen.

Der Emulator liefert ein Array mit Pixeldaten, die dann dargestellt werden können wie wir uns es wünschen. Somit ist es eigentlich egal, welche Engine man benutzt. Hauptsache man kann damit irgendwie Pixel rendern. Nachdem ich nun einige Zeit PixiJS benutzt habe, will ich es mal damit versuchen. Damit kann man wirklich schöne Sachen machen.

Fakten sammeln

Um einen Emulator zu bauen, muss man natürlich die zu emulierende Hardware kennen. Dazu gibt es meistens Dokumente, die aufzeigen, wie sie funktioniert. Dann muss man diese Hardware in Software nachbauen.

Ich möchte das Sega Master System (SMS) zuerst machen. Der oben genannte Freund gab mir dazu diesen Link, wovon er das oberste Dokument empfahl, welches er selbst gebraucht hat.


Dieses Dokument hier gibt mehr Informationen als alle anderen:

Der Gameboy wäre jedoch hier besser geeignet, da jemand schon einen JS GameBoy-Emulator geschrieben hat: 

Ich werde mich vorerst nach diesem Tutorial richten.

Doch darum kümmern wir uns, wenn die Grund-Engine steht.

Anders als im oben verlinkten Artikel, werden wir zuerst die Grund-Engine bereit stellen, in der dann alle Emulatoren ausgeführt werden können. Dies wird dort "erst" ab Kapitel 5 [gar nicht(?)] abgehandelt und ich möchte dir nicht die Entscheidung der Wahl deiner zu emulierenden Hardware abnehmen, nur weil das Grundgerüst erst "später" gemacht wird.

Im Grundgerüst wird der Bildschirm aufgebaut und gezeichnet, sowie der Sound ausgegeben.

Weiter gehts mit:
Oder direkt mit: [TODO] Gameboy A: Die CPU

Dienstag, 9. Mai 2017

Mickey Rubbish


Ein Rubber Ducky als Maus getarnt.

WARNUNG: Dieser Artikel dient informativen Zwecken. Der Autor weist jegliche Haftung von sich.
Der Autor warnt vor dem Gebrauch eines solchen Gerätes. Es können schwere Schäden verursacht werden durch den falschen Gebrauch solcher Geräte. Deshalb ist oben im Bild auch ein "Warnschild" angebracht. Dieser Artikel dient der Aufklärung.

Dies ist ein erweiterter, deutscher Artikel von diesem Originalartikel. Danke dafür an tim.

Als ich den Begriff "Rubber Ducky" in der Serie "Mr. Robot" gehört habe, wollte ich unbedingt auch so ein Ding haben. Schon nur des Namens wegen.

Die Hardware

Ich habe mir also gleich ein RasPi Zero bestellt (meins hat kein WLAN), und einen USB-Stecker dran gelötet.

Hier ist das Wiring-Bild. Für dieses Projekt interessiert nur der untere Teil. Man beachte, dass man hier den male-Stecker von hinten sieht, also vom Gerät aus.
Freundlichst geklaut von hier.

Dann wusste ich erst nicht, was ich für eine Hülle machen soll und mit welchem Material. Ich habe noch eine alte Kabelmaus gefunden und dachte, das ist doch die perfekte Tarnung.

Beim USB-Kabel von der Maus musste ich erst herausfinden, welche Farbe denn nun was bedeutet. (Ich konnte es mir schon denken...)

Deshalb habe ich den USB-Stecker am Pi weggeschnitten und eine Pin-Steckerverbindung an das Restkabel gelötet. So konnte ich alle Kombinationen austesten.



Rot ist +5V, Schwarz ist GND, Grün ist D+ und Weiss ist D-.

Bei meiner Konfiguration sind also folgende Farbkombinationen vorhanden:

USB-PinRasPiMauskabelFunktion
1OrangeRot+5V
2GrauWeissData-
3BlauGrünData+
4BraunSchwarzGND

Ich musste die Platine von der Maus herausnehmen. Der Zero hätte sonst nicht reingepasst.
Desweiteren musste ich an der Seite einiges wegfräsen und einen der Pfosten für das Mausrad entfernen. Zum Glück keinen tragenden Pfosten, die Aufmachung des Rades ist auf der anderen Seite.

Das Mausrad selbst musste auch halbiert werden.


Den unteren Plastik mit der Optik wollte ich auch drin lassen, darum habe ich ihn flacher gemacht. Das war jedoch im Endeffekt nicht nötig. Der RasPi Zero hatte nun schön Platz und ein erster Test war erfolgreich.



Ich wollte das Erlebnis noch akkurater gestalten und habe die LED von der Maus von unten her an die Pins 1 und 6 vom RasPi Zero gelötet. Also den ersten Pin links oben und den dritten Pin rechts oben bei den GPIO-Pins. (3.3 V und GND). Die Halterung von der LED fixiert die Optik auf der Maus und die Optik fixiert ihrerseits den RasPi als Gesamtes. Sobald man "die Maus" einsteckt, leuchtet nun die LED auch.



Wie schon bemerkt müsste man an der Optik nichts weg fräsen. Dank der Halterung für die LED ragt nun auch der Kartenslot schön heraus, so dass man die Karte ganz einfach wechseln kann, wenn der Deckel entfernt wurde.


Schliesslich noch das Mausrad drauf gepappt...


Und so sieht es am Ende aus...total unauffällig.



Die Software

Das Duckberry-Image habe ich mit dem USB Image Tool auf die MikroSD-Karte gebrannt.

Dann muss man die payload.dd-Datei auf der Karte bearbeiten.

Ich habe erst mal den mitgelieferten payload getestet und bin schon da auf die ersten Probleme getroffen: Das OS schreibt mit der englischen UK-Tastatur, wir haben hier jedoch die Schweizer Tastatur. Ich hatte keine Lust, das gesamte OS neu zu kompilieren, nur um die Keymap zu wechseln - welche dann auch wieder nur individuell für mich stimmen würde.

Also habe ich folgenden Payload geschrieben (abgekürzt):

DELAY 500
GUI r
STRING notepad
ENTER
DELAY 1000
STRING abcdefghijklmnopqrstuvwxyz
ENTER
STRING ABCDEFGHIJKLMNOPQRSTUVWXYZ
ENTER
STRING 1234567890
ENTER
STRING Sonderzeichen
ENTER
STRING 1 +
ENTER
STRING 2 "
ENTER
STRING 3 *
ENTER
STRING 4 ç
ENTER
STRING 5 %
ENTER
STRING 6 &
ENTER
STRING 7 /
ENTER
STRING 8 (
ENTER
STRING 9 )
ENTER
STRING 10 =
ENTER
STRING 11 ?
ENTER
STRING 12 `
ENTER
REM und so weiter .... mit allen Sonderzeichen, äöüéèà, Klammern etc.
STRING 25 \
STRING 26 #

Dies liess ich dann auf meinem Laptop laufen, welches mir schön Notepad geöffnet und alle Sonderzeichen mit einer Nummer versehen dort reingeschrieben hat. Anhand der Nummerierung konnte ich dann herausfinden, wie der Youtube-Link aufgebaut sein muss: www.zoutube.com#watch_v)dQw4w9WgXcQ oder so. So hab ich das dann in den Standard-Payload hineingeschrieben und schon ging es.

Ich hoffe das hilft auf deinem Weg der Besserung. Viel Spass!