Akai MPC2500 – April 2018

nun habe ich mir eine AKAI MPC2500 über ebay gekauft. Sicher wird es weiterhin Musik mit der Mandoline geben, – aber ich habe immer etwas mit Elektronik und Musik gemacht.
Die MPC2500 ist ein “Midi Production Center”, also eine Steuerzentrale zum “Musikmachen”, – aber ohne Computer.

Die MPC2500 war ca.2005 ein Nachfolger der MPC60 oder MPC3000.
Der Brand “Akai” gehört heute zu einer anderen Firma und ab der “MPC5000″ steckt sogar Hardware eines anderen Herstellers drin.

Hier gibt es eine sehr schöne Einführung in das Thema “Akai MPC”
https://www.youtube.com/watch?v=SENzTt3ftiU

Wer Interesse hat, kann sich mal nach “J Dilla Instrumental” umsehen und in das Instrument reinhören.
Hier ein Beispiel:
https://www.youtube.com/watch?v=SENzTt3ftiU

Was ist MIDI?, – es sind einfache Steuerinformationen zwischen Musikinstrumenten, wie “Start des Songs”, “Taste A1 auf dem Keyboard gedrückt” oder “Taste A1 losgelassen” – aber eigentlich keine Känge. Diese werden von einem MIDI-Expander erzeugt oder Sampler wiedergegeben… getriggert durch MIDI-Befehle. Wenn man nun viele Musikinstrumente steuern will, dann werden das eben viele MIDI-Nachrichten, die zum richtigen Zeitpunkt ausgegeben werden sollen und von den Geräten in Töne umgesetzt werden sollen.
Vergleichen kann man das auch gut mit diesen Papierrollen mit Löchern zur Steuerung von Glockenspielen(“Musicbox”) oder automatischen Pianos.

Leider war/ist MIDI so ca. 1986 etwas schlecht implementiert worden und manchmal eiern die Spuren eher als “tight” zu bleiben. Das liegt daran, dass die MIDI-Befehle oft nicht zeitnah übertragen werden können, – das “leckt” dann eben manchmal wenn zu viele Noten über die gleiche Leitung müssen.
Die MPC2500 hat daher 4 MIDI-Ausgänge, theoretisch wären das bis zu 64 unabhängige Musikinstrumente. Praktisch geht es aber darum, dass beim parallelen Verschicken der Nachrichten die Töne präziser verschickt und abgespielt werden können.

Im Gegensatz zur reinen Musikaufnahme mit Mehrspur-Tonbandgerät kann man MIDI-Nachrichten nachträglich veränderen, – Tonhöhe, Start- und Endzeitpunkt oder Anschlaglautstärke und sogar einen anderen Sound wählen.

Technisch handelt es sich bei MIDI-Nachrichten ja nur um eine Abfolge oder Sequenz von Steuerinformationen. Die MIDI-Tools nennt man daher auch “Sequencer”.

Falls man sich fragt, warum man dazu eine “MPC” und keinen Computer nimmt? – Das ist eine eher philosophische Frage. Klar kann man heute auch einen Computer als Steuerzentrale des Musikstudios verwenden, z.B. einen MAC oder Windows-PC mit Sequencer wie Logic Pro, Cubase oder “Fruity Loops” (FL) oder Linux mit LMMS etc.
Wenn man einen Computer einsetzt, dann besteht aber immer die Gefahr, dass man dann eher wieder im Internet Surft und Emails/Facebook-Nachrichten schreibt.

Was war/ist ein Sampler?
Ein Gerät, welches Töne aufnimmt, digital speichert und wiedergeben kann. .. oder eben diese berühmten WAV-Dateien wiedergeben kann. Der Sampler kann meist über eine Tastatur, Drumpads oder eben über MIDI gesteuert werden. Heutige Studiosampler sind meist nur noch Software in einem MAC oder Windows-PC.

Die alte MPC “kann kein Internet” und war eine Kombination aus Sequencer, Drumcomputer und Sampler, … alles in einer Box.

Früher (so 1995) hatte ich einen Atari Falcon, – ohne Internet, nur zum Musikmachen. Der funktionierte tadellos. Der Umstieg auf das gleiche Programm auf einem 486er funktionierte nicht, denn die gleiche Musik-Software ist dort immer wieder abgestürzt. .. der Atari lief mit 16Mhz, und der 486er mit 133MHz und dennoch “Sch…e” und viel hat sich da bei Windows nicht geändert. Da habe ich dann irgendwann mit Musik am Computer aufgehört.

Ntürlich verwende ich auch schonmal meinen Mac mit Garageband zum “Computer-Musikmachen”, das funktioniert auch ganz gut, kann aber kein MIDI-Equipment ansteuern.

Hier noch ein Bild der MPC nach der Grundreinigung.

AKAI MPC2500

AKAI MPC2500

Elektor – ESP32-PICO-D4 Developmentboard

Ein normales ESP32-Devboard ist leider so breit, so dass auf einem Breadboard eine Pinseite nicht verwendet werden kann. Man braucht dann immer 2 Boards oder ein breiteres Board um überhaupt Experimente mit dem ESP32 machen zu können.

Genau hier ist diese Board das richtige. Im Rahmen des ESP32-Contest konnte man ein kostenloses Board erhalten.
Wie man erkennen kann, sind auf meinem Breadboard auf jeder Seite je 2 Pins frei.

Somit eignet sich dieses Board viel besser für Experimente als die anderen ESP32-Boards.
Dank der eingebauten Funktionen und der breiten Verfügbarkeit von Boards ist dieses Board ein weiterer Schritt zur Ablösung der ersten Arduino-Boards. Bei dem Preis darf bei einem Experiment auf mal etwas “abrauchen”.

ESP32_Devboard_PICO

 

 

 

 

 

 

 

Mein gemeldetes Projekt ist die digitale Stompbox bzw. der Sampleplayer basierend auf dem ESP32.

Weitere Details zum Design-Contest:

https://www.espressif.com/en/media_overview/news/esp32-pico-kit-design-contest-elektor-and-espressif

.. Kommentare zu den Transistoren auf dem Bild kann man sich sparen, die waren hier nur “geparkt”.

ESP32 Stomper – mehr als SPD:Kick oder Horsekick

Ich hatte mir eigentlich nur einen Stomper mit einem ESP8266 bauen wollen. Den Gitarristen im Freundeskreis gefiel der Stomper auch, wenngleich einige Kommentare zu Latenz und Soundauswahl vielen. .. ok, nochmal Anforderungen sammeln.

Es gab viel Diskussion und neue Wünsche …

(more…)

ESP8266 Stompbox ( Horsekick oder Finhol oder SPD::KICK ) Nachbau

Als Gitarrist und Elektroniker will man doch mal den Beat mittrampeln. Also hatte ich mir schon einige Projekte im Web angeschaut und dann Ende Oktober eine Audio-Library zum ESP8266 gefunden. Alternativen nur mit einem Piezo oder MIkrofon in einer Pappschachtel sollen auch funktionieren, – gefielen mir aber nicht.
Ein ESP8266-Development-Board gibt es für unter 10 €, der Adafruit DAC mit 3 Watt Amp hatte ich schon gekauft, – liegt auch bei 10 €.
Das OLED-Display, weitere Kleinteile wie Piezo, Taster und ein paar kleine Bauteile machen nochmal 15€. Das Holzgehäuse  bauen, bearbeiten und die Auswahl der Sounds dauert auch  länger. Als Powersupply dient eine ältere USB-Powerbank.
Wenn man alle Teile extra kaufen muss, dann rechnet sich das Projekt auf Grund von den Kosten und dem Aufwand aus meiner Sicht nicht. Ich hatte aber alle Teile herumliegen und wollte es einfach mal ausprobieren.

So sah die erste Version aus, die dann aber später in 2 Teile durchgetrennt wurde. Somit konnten dann die Bewegungen der Ferse und somit die Geräusche und Fehltrigger minimiert werden.
Die Basis bildet ein 3-Schicht Holz ca. 28 x 14cm. Unter der Unterlegscheibe befindet sich ein Hohlraum für den ESP8266 und den Piezo. Das OLED-Display ist leicht versetzt eingebaut. Rechts bzw. hier dann oben befindet sich in einer Einbuchtung ein Taster zur Soundwahl und links in der gegenüberliegenden Einbuchtung die Klinkenbuchse.

Hman-Stompbox

Halbfertige Alternativen zum ESP8266 könnten auch Raspi-Projekte wie Samplerbox oder fertige Platinen wie Wavetrigger von Robertronics sein. Beide bieten aber keinen Anschluss eines Piezos!
Raspi-Projekte könnten final noch teurer werden, denn der Zeitaufwand zur Einrichtung von Linux könnte größer ausfallen.

Als fertige Lösung gefiel mir das Ortega Horsekick Pro  ca. 170€ und vom Datenblatt und den Sounds her das Roland Boss SDP::Kick oder SDP::Wave für über 200€.

Zurück zum “selbermachen”.

Zur Ausgabe der Sounds verwende ich die fertige Audio-Library von Earle F. Philhower, III
https://github.com/earlephilhower/ESP8266Audio

Das ZIP muss entpackt werden und dann nach /Arduino/libraries/ verschoben werden.

Die Anschaltung des DACs and den ESP8266 erfolgte wie in https://github.com/bbx10/SFX-web-trigger. Der DAC ist das “Adafruit I2S 3W Class D Amplifier Breakout – MAX98357A”.

Der Lautsprecher-Ausgang des DAC geht bei mir auf die beiden äußeren Enden eines 50kOhm-Trimmer, an dem dann der Mittelpin eines 6.3mm Klinkenbuchse über einen weiteren Widerstand hängt. Die Masse der Buchse ist auf einen “Aussenpin” des Trimmers gelegt. Nachträglich habe ich zwischen den Mittelabgriff des Trimmer und “+” der Klinkenbuchse noch einen Widerstand eingebaut … ca. 10kOhm und einen Kondensator zur Entkopplung von Gleichspannungen, – also in Reihe mit dem Widerstand.

Nach dem Zusammenbau von DAC, ESP8266, einigen Kondensatoren zur Spannungsstabilisierung und dem PIEZO fehlte nur noch die Abstimmung der Empfindlichkeit, denn der Beat soll sowohl mit sehr festen Fußwerk als auch Sportschuhen oder auch ohne Schuhe nur mit Socken funktionieren.

Nach zwei frustrierenden Abenden mit Tests verschiedener Einstellungen hatte ich dann ein einfaches Testscript gefunden und dieses funktionierte auf Anhieb ausreichend gut. Es  bildet nun die Grundlage für das eigene Stompbox-Script. Statt einen MIDI-Sound zu triggern, wird ein Sample aus dem “ProgMem” des ESP8266 ausgegeben.

Vorlage für das Testscript:

https://github.com/RyoKosaka/drums/blob/master/arduino/piezo_peak_test_MIDI/piezo_peak_test_MIDI.ino

Die Samples, die im “ProgMem” abgelegt werden, sollten unterschiedlich sein, so dass ich bei den nächsten Sessions die besten Sounds auswählen und die “schlechten” gegen andere tauschen kann.
Also habe ich in meiner Sample-Sammlung und Synths nach Percussion und Kickdrum-Samples gesucht. Diese gekürzt, auf Mono und 16 Bit gesetzt, – 44.1kHz.

Earle Philhower erklärt ausreichend gut, wie man die 16Bit-Wav-Files einfach in HEX-Files konvertrieren kann, um sie in seinen Libraries als “Audio-Source-ProgMem” zu verwenden. Ich hatte dazu aber eine eigene Javascript-Webpage gebaut, die mir die Sounds in h-Files convertiert. Die WAV-Files müssen als HEX-Files vorliegen.
Die Sound-hex-Files sehen dann etwas so aus:

const unsigned char cajonbass[] PROGMEM = {0x52,0x49,0x46,0x46,0x1a,0x6c,0x00,0x00,0x57,0x41,0x56,0x45,0x66,0x6d,0x74,0x20
,0x10,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x44,0xac,0x00,0x00,0x88,0x58,0x01,0x00....
};

Ein OLED128x64Pixel (grüne Fahne) (von Amazon) wurde an den ESP8266-Pins “D1″ / “D2″ angeschaltet., an “D3″ liegt ein Taster, wenn er geschlossen ist, zieht er den Pin D3 dann gegen Masse um die Sounds zu wechseln.

Final passen 1 MByte in das System. Ich konnte damit ca. 20 sehr kurze Sounds laden.

Die Library für das OLED-Display:
https://github.com/squix78/esp8266-oled-ssd1306
Diese wird aber innerhalb der Arduino IDE zur Installation angeboten und nennt sich dort:
“ESP8266 and ESP32 OLED Driver for SSD1306 Display by Daniel Eichhorn, Fabrive Weinberg..:”

Urspünglich war statt des Tasters ein Rotary Encoder und ein kompelexeres Menü geplant. Auch die Darstellung von kleinen Icons zu den Instrumenten habe ich wieder verworfen, denn diese verbrauchten auch zusätzlichen RAM.

Eine Idee wäre die Auslagerung der Samples in externen Storage.
Die Umwandlung der Samples in andere komprimierte Formate würden zusätzliche Zeit zur Dekodierung und somit zu Latenzen beim Triggern führen.

Das Holzgehäuse besteht nun aus 2 Teilen, einem Teil mit der Elektronik und dem Piezo und einem Stück Holz. Beide Teile sind miteinander über Gummistücke verbunden und ergeben die Auflagefläche für einen Fuß. Der passive Teil liegt unter der Ferse und der aktive Teil mit dem Piezo kann sicher mit dem Fuß getrigggert werden.

Unten drunter gibt es jeweils Gummifüße gegen das Verrutschen. (Bilder folgen)
In einer ersten Version hatte ich nur eine große Holzplatte  eingeplant, musste diese Version aber verwerfen, denn schon die Bewegung des Fußes auf der Platte sorgte für Fehltrigger oder Doppeltrigger beim Runtertreten und beim Abheben des Fußes.

Technisch machen es sich die Hersteller einfach und liefern nur das aktive Teil, auf das man treten soll. Ergonomisch ist das aber nicht, denn man muss zum niedertreten den Fuß weit anheben.

Hier das vorläufige Arduino-Script:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "AudioFileSourcePROGMEM.h"
#include "AudioGeneratorWAV.h"
#include "AudioOutputI2SDAC.h"

#include <Wire.h>  
#include "SSD1306.h"

// WAV-Files
// WAV-Files, MONO 44.1 KBIT/s 16Bit
#include "fatbass.h"
#include "softkick.h"
#include "espkik03.h"
// #include "espkik04.h"
#include "cajonbass.h"
#include "espkik06.h"
#include "espkik07.h"
#include "espkik08.h"
#include "espkik09.h"
#include "espkik10.h"
#include "espkik11.h"
#include "espkik12.h"
#include "espkik13.h"
#include "espkik14.h"
#include "espkik15.h"
// #include "espkik16.h"
#include "espkik17.h"
#include "espkik18.h"
#include "espkik19.h"
#include "espkik20.h" 
#include "espkik22.h"
#include "ride1.h"
// #include "espkik28.h"

AudioGeneratorWAV *wav;
AudioFileSourcePROGMEM *file;
AudioOutputI2SDAC *out;

unsigned short buttonState = 0; // Selectbutton for the sounds
unsigned short oldButtonState = 1;
boolean piezo = false;
int maxPiezo = 400;
int gaindevider = 380;

unsigned short s = 0;
unsigned short s_old = 20; // Sample-ID


const char *samplenames1[] ={"0 Fat",
     " 1 Soft    " , " 2 Cajon  "
   , " 3 Rock   " , " 4 Ride  "
   , " 5 Cajon  " , " 6 Arabic"
   , " 7 Acoust " , " 8 Acoust"
   , " 9 R908   " , "10 R809  "
   
   , "11 Tambo- ", "12 Christ."
   , "13 Cabasa ", "14 Guiro  "
   , "15 Rattle ", "16 Rattle",
   , "16 Cow    ", "17 Claves "
   , "18 Clap   ", "19 Side   "
   , "20 Hihat  ", "21 Ride   "
   
  };

const char *samplenames2[] ={"Drum",
     "    Kick",  "    Bass"
   , "    Kick",  "    Cymbal"
   , "    Bass",  "    Bass"
   , "    Stomp", "    Stomp"
   , "    Synth", "    Synth"
   , "    Latin",  "    Latin"
   , "rine Man",  "    Bells"
   , "    Latin", "    Latin" 

   , "    Bell",  "         "
   , "    Clap",  "    Stick"
   , "   Closed","    Cymbal"

  };  


unsigned short samplecount = 21; // Anzahl der Samples für den Select-Button
SSD1306  display(0x3c, 5, 4); //Labeled D1, D2
const int buttonPin = 0; // Labeled D3, Pin is high by default, button between this pin and GND to switch the sounds


void setup() {
  WiFi.forceSleepBegin();
  display.init();
  // display.flipScreenVertically();
  display.setContrast(255);

  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.setFont(ArialMT_Plain_24);
  display.drawStringMaxWidth(0 , 0 , 128, " Heinemann");
  display.drawStringMaxWidth(0 , 24 , 128,"  Stomper");
  // display.drawXbm(20, 30, bassdrum_width, bassdrum_height, bassdrum_bits);
  display.display();

  
  // pinMode(BUILTIN_LED, OUTPUT);
  Serial.begin(115200);
  delay(3000);
  
  file = new AudioFileSourcePROGMEM( fatbass, sizeof(fatbass) ); // Short Demosound after Booting
  out = new AudioOutputI2SDAC();
  out->SetGain(0.02);
  wav = new AudioGeneratorWAV();
  wav->begin(file, out);
  
  pinMode( buttonPin, INPUT); // GPIO 0 == D03 on ESP8266 !!

}


void loop() {
  
  if ( s != s_old ) {
    if (s >= samplecount) {
      s=1;
    }
    s_old = s;
    display.clear();
    display.setTextAlignment(TEXT_ALIGN_LEFT);
    display.setFont(ArialMT_Plain_24);
    display.drawStringMaxWidth(0 , 0 , 128, samplenames1[s]);
    display.drawStringMaxWidth(0 , 24 , 128, samplenames2[s] ); // + (String) s);
    display.display();
  } 
  
  int sensorValue = analogRead(A0);
  int MAX;

  if (sensorValue > 20 &&  piezo == false) {
    int peak1 = analogRead(A0);
    MAX = peak1;
    delay(1);
    int peak2 = analogRead(A0);
    if (peak2 > MAX) {
      MAX = peak2;
    }
    // delay(1); // absichtlich deaktiviert!!
    int peak3 = analogRead(A0);
    if (peak3 > MAX) {
      MAX = peak3;
    }
    delay(1);
    int peak4 = analogRead(A0);
    if (peak4 > MAX) {
      MAX = peak4;
    }
   
    delay(1);
    int peak5 = analogRead(A0);
    if (peak5 > MAX) {
      MAX = peak5;
    }
    // delay(1); // absichtlich deaktiviert !!
    int peak6 = analogRead(A0);
    if (peak6 > MAX) {
      MAX = peak6;
    }
    if(MAX >= maxPiezo){
      MAX = maxPiezo;
    }

//     MAX = map(MAX, 10, maxPiezo, 1, 127); // entfaellt bei mir

    if(MAX <= 1){
      MAX = 1;
    }

    midiNoteOn( MAX );
    Serial.println( MAX);
    piezo = true;

    // teh next block could be replaced by delay(30); or anything similar...
    delay(1); //mask time
    Serial.println( 0);
    delay(1); //mask time
    Serial.println( 0 );
    delay(1); //mask time
    Serial.println( 0 );
    delay(1); //mask time
    Serial.println( 0 );
    delay(1); //mask time
    Serial.println( 0 );
    delay(1); //mask time
    Serial.println( 0 );
    delay(1); //mask time
    Serial.println( 0 );
    delay(1); //mask time
    Serial.println( 0 );
    delay(1); //mask time
    Serial.println( 0 );
    delay(1); //mask time
    Serial.println( 0 );
    delay(1); //mask time
    Serial.println( 0 );
    delay(1); //mask time
    Serial.println( 0 );
    delay(1); //mask time
    Serial.println( 0 );
    delay(1); //mask time
    Serial.println( 0 );
    delay(1); //mask time
    Serial.println( 0 );
    delay(1); //mask time
    Serial.println( 0 );
    delay(1); //mask time
    Serial.println( 0 );
    delay(1); //mask time
    Serial.println( 0 );
    delay(1); //mask time
    Serial.println( 0 );
    delay(1); //mask time
  }
  if (sensorValue <= 0 && piezo == true) {
    piezo = false;
  }

  
  buttonState = digitalRead(buttonPin);
  if ( buttonState == LOW &&  oldButtonState == HIGH ) {
    oldButtonState = buttonState;  
    s = s +1;    
    oldButtonState = buttonState;  
    delay(50); // debounce
  } else {
    oldButtonState = buttonState;  
  }

  if (wav->isRunning()) {
    if (!wav->loop()) { 
      wav->stop(); // wenn nicht mehr richtig looped dann stoppen
    }
  }  
}

void midiNoteOn( int midiVelocity){
  if (midiVelocity > 0) {
  switch (s) {
      case 0:
        file = new AudioFileSourcePROGMEM( fatbass, sizeof(fatbass) ); 
        break;
      case 1:
        file = new AudioFileSourcePROGMEM( softkick, sizeof(softkick) );
        break;
      case 2:
        file = new AudioFileSourcePROGMEM( softkick, sizeof(softkick) );
        break;
      case 3:
        file = new AudioFileSourcePROGMEM( espkik03, sizeof(espkik03) );
        break;

       case 4:
         file = new AudioFileSourcePROGMEM( ride1, sizeof(ride1) );
         break;
      case 5:
        file = new AudioFileSourcePROGMEM( cajonbass, sizeof(cajonbass) );
        break;
      case 6:
        file = new AudioFileSourcePROGMEM( espkik06, sizeof(espkik06) );
        break;

      case 7:
        file = new AudioFileSourcePROGMEM( espkik07, sizeof(espkik07) );
        break;
      case 8:
        file = new AudioFileSourcePROGMEM( espkik08, sizeof(espkik08) );
        break;
      case 9:
        file = new AudioFileSourcePROGMEM( espkik09, sizeof(espkik09) );
        break;
      case 10:
        file = new AudioFileSourcePROGMEM( espkik10, sizeof(espkik10) );
        break;
      case 11:
        file = new AudioFileSourcePROGMEM( espkik11, sizeof(espkik11) );
        break;
      case 12:
        file = new AudioFileSourcePROGMEM( espkik12, sizeof(espkik12) );
        break;
      case 13:
        file = new AudioFileSourcePROGMEM( espkik13, sizeof(espkik13) );
        break;
      case 14:
        file = new AudioFileSourcePROGMEM( espkik14, sizeof(espkik14) );
        break;
      case 15:
        file = new AudioFileSourcePROGMEM( espkik15, sizeof(espkik15) );
        break;
     case 16: // the same as 15
        file = new AudioFileSourcePROGMEM( espkik15, sizeof(espkik15) );
        break;

       case 17:
        file = new AudioFileSourcePROGMEM( espkik17, sizeof(espkik17) );
        break;
      case 18:
        file = new AudioFileSourcePROGMEM( espkik18, sizeof(espkik18) );
        break;
      case 19:
        file = new AudioFileSourcePROGMEM( espkik19, sizeof(espkik19) );
        break;
      case 20:
        file = new AudioFileSourcePROGMEM( espkik20, sizeof(espkik20) );
        break;
      case 21:
        file = new AudioFileSourcePROGMEM( espkik22, sizeof(espkik22) );
        break;

      default:
        file = new AudioFileSourcePROGMEM( fatbass, sizeof(fatbass) ); 
        s = 1;  
      }
        
    // file = new AudioFileSourcePROGMEM(  );
    // out = new AudioOutputI2SDAC();

    // eigentlich p statt oldPiezoVal
    out->SetGain( 0.05 +  (float) midiVelocity/gaindevider ); // 0.8(float) p/130
    
    if (wav->isRunning()) {
      wav->stop(); // wenn nicht mehr richtig looped dann stoppen
    }
    wav->begin(file, out);
  }
}

Die lange Kette von Seriel.println ist ganz praktisch um die Ausgabe per Serial-Plotter zu ermöglichen. Die Sounds hatte ich Anfangs nur durchnumeriert, werde das aber ändern und sprechende Namen verwenden.

Die hex-files liegen im Ardino-Projektordner und nicht in Unterverzeichnissen. Man muss hier auch keinen Tricks zum Upload der Files anwenden.

Mit der Fuktion “out->SetGain und der Variablen “gaindevider” kann man experimentieren und somit die “Velocity” oder Anschlagempfindlichkeit verändern.

Bootstrap 4 … still alpha

Nach einigen Jahren in denen ich Bootstrap 3.0 verwende, muss ich mich langsam mal an Bootrap 4.0 gewöhnen. Es ist immer noch alpha und die von mir bisher verwendeten Plugins in Bootstrap 3.0 wie Boostrap-Table muss ich erstmal mit Bootstrap 4.0 testen.

Einige Bereiche wurden in Bootstrap 4.0 geändert und so werde ich z.B. meine entwickelten Applikationen mit “wells” umändern, so dass sie mit “cards” funktionieren.

Hier gibt es eine schöne Webseite, die die Unterschiede schnell aufzeigt:

http://bootstrap4.guide/

Dashboards mit Gridstack

Gridsatck liefert eine einfache Funktion um mit Bootstrap auch Dashboards oder ein Grid von Widgets zu gestalten.

Gridstack finde ich persönlcih sehr praktisch, denn es gibt nicht zu viele Funktionen vor, sprich, man kann sehr viel selbst implementieren ohne schon ein großes Admin-Template oder sonstige visuelle Dinge berücksichtigen zu müssen.

Hier ein einfaches Beispiel, welches zu 95% dem Original entspricht und ich nur die Referenzierung der DIVs durch IDs in Javascript hinzugefügt habe. Somit ließe sich über die Serialisierung als JSON-String das Grid sichern und laden und je nach Widget-ID oder DIV-ID wird der passende Content asynchron geladen.

Beipiel unter: http://hman-projects.de/extraSite/fake/gridstack_serialization.html

Neue Demo mit kleinem DropDown-Menü vom 23.07.2017

http://hman-projects.de/extraSite/gridstack/demo/

Hier die offzielle Gridstack-Seite:

https://troolee.github.io/gridstack.js/

 

 

Kleine Widgets mit Speedometer wie PRTG

Vor längerer Zeit hatte ich mir mal das PRTG-DEMO-System angeschaut.

Mir gefielen die kleine Speedometer, die das PRTG-Logo beinhalten ganz gut. Da ich aber mehr mit Bootstrap und anderen Performance-Management-Tools arbeite, wollte ich das relativ prtg1kompakte Widget mal mit Bootstrap nachbauen.

Das Speedometer ist ein SVG, welches aus mehreren Elementen besteht. Die Skala des Speedometers besteht aus einigen Kreisausschnitten (path-Elemente) und würde einem bunten PIE-Chart entsprechen.
Unten wird der PIE-Chart dann in den unteren 10% der Höhe abgeschnitten. Dies geschiet durch ein Rechteck (rect-Element) in Hintergrundfarbe.
Über diesen Pie-Chart wurde dann  noch ein Kreis (circle) in Hintergrundfarbe und einem deutlichen Versatz zum Zentrum des PIE-Charts gesetzt. Dadurch ergibt sich die Skala.
In meinem Beispiel habe ich dem Kreis eine helle Umrandung gegeben, so dass man ihn erkennen kann.
Final wird ein Polygon (path) als Zeiger darübergelegt und einfach in einem passenden Winkel, hier 333.37 gedreht. Per Javascript müsste man diesen Winkel nur entsprechend dem letzten Messwert aktualisieren.

<svg width="52" height="50"  style="background-color:#eee;">
  <path d="M23,50 a25,25 0 1,0 3,-50" fill="#ffC705" stroke="#fff" stroke-width="2px" /><!--Orange-->
  <path d="M0,25  a25,25 0 0,0 50,0" fill="#ff0000" stroke="#eee" stroke-width="2px"/><!--red-->
  <path d="M26,0 a25,25 0 0,0 -3,50" fill="#5cB85c" stroke="#fff" stroke-width="2px"/><!--green-->
  <rect x="0" y="40" width="50" height="40"   style="fill: #eee;" />
  <circle style="fill: #eee;" r="19" cy="30" cx="22" fill="#eee" stroke="#fff" stroke-width="2px"></circle> 
   <g transform="translate(22,30) rotate(333.37)">
      <path style="fill: rgb(255, 0, 0); stroke: rgb(255, 0, 0); fill-opacity: 0.9;" d="M0,-23L0.19206,-18C0.3,-15,0.8,-6.7,0.9,-2.4C1,1.9,0.9,2.4,0.6,2.6C0.2,2.9,-0.28808999999999996,2.8809000000000005,-0.6241949999999999,2.6408250000000004C-0.9602999999999999,2.4007500000000004,-1.05633,1.9206000000000003,-0.912285,-2.4007500000000004C-0.76824,-6.722100000000001,-0.38412,-14.884650000000002,-0.19206,-18.965925000000002L0,-23.047200000000004"></path>
   </g>
</svg>

 

Hier die Test-Datei: http://hman-projects.de/extraSite/fake/prtg_widget1.html

Die Bootstrap-Variante unterscheidet sich mehr oder weniger von der originalen PRTG-Variante, die ich so ca. 2014 bei Paessler vorgefunden hatte.

Bei einer heutigen Kontrolle der Paessler Webseite kann man erkennen, dass Paessler die Widgets nun wesentlich kompakter macht und auf einige Elemente verzichtet.

Dieses Beispiel habe ich hier aufgeführt, um zu zeigen, wie man ein Speedometer in HTML, SVG und Bootstrap realisieren kann.

Das PATH-Element in SVG ist nicht so simpel, daher hier noch ein einfacheres Beispiel und Erläuterung der Variablen:

<svg width=”135″ height=”135″>
<path d=”M125,85 a60,60 0 1,0 -115,0″ fill=”#E79A16″ /><!–Top Half–>
<path d=”M10,85 a60,60 0 0,0 115,0″ fill=”#D78500″ /><!–Bottom Half–>
</svg>

M = Move To: X, Y
L = Line
a = Bogenkurve http://svg.tutorial.aptico.de/start2.php?knr=10&kname=Pfade
Der Anweisung “A” oder “a” müssen 5 Werte und ein Koordinatenpunkt folgen:
1.    der Radius der x-Achse der Ellipse
2.    der Radius der y-Achse der Ellipse
3.    die Rotation der x-Achse der Ellipse in Grad   (0 bedeutet keine Rotation)
4.    das large-arc-flag:
0 für den kurzen Weg um die Ellipse
1 für den langen Weg um die Ellipse
5   das sweep-flag:
0 für Zeichnung entgegen den Uhrzeigersinn
1 für Zeichnung mit dem Uhrzeigersinn
6   die Koordinaten des Endpunktes.

<paths d=”M50,25 a25,25 0 1,0 -50,0″ fill=”#ffC705″ stroke=”#eee” stroke-width=”2px” /><!–Top Half–>
<paths d=”M0,25  a25,25 0 0,0 50,0″ fill=”#5cB85c” stroke=”#eee” stroke-width=”2px”/><!–Bottom Half–>

 

Phonegap – Cordova 2017 Teil 6: Scrolling im IPhone-Emulator und Font-Awesome

Scrolling

Im IPhoen Emulator lassen sich die pages nicht scrollen, – im Gegentest im richtigen IPhone zeigt, dass sie sich auf dem realen IPhone doch scrollen lassen.  Merkwürdig aber erstmal kein Hindernis.
Nach einigen Test mit dem Simulator habe ich festgestellt, dass Scrollen auch im Emulator funktioniert. Man muss nur (more…)

Phonegap – Cordova 2017 Teil 5: Javascript Alert funktioniert nicht

Der normale Alert funktioniert leider nicht. Als Programmierer verwendet man einen Debugger oder gibt Logs irgendwo aus und wenn es garnicht anders geht, dann verwendet man eben „alert“.
In Cordova gibt es ein Plugin für Dialoge, welches installiert werden muss.
cordova plugin add cordova-plugin-dialogs
Der zugehörige Code sieht wie folgt aus:

(more…)

Phonegap – Cordova 2017 Teil 4: Usersettings innerhalb der App sichern

Settings, – irgendwo muss der User ja seine Account-Daten für den Zugriff auf diese Tools sichern.

Wie sichert man Daten im Browser und funktioniert das auch noch in Cordova?
Die Maske war dazu schnell erstellt und dann um diese Accordionpane aus JQuery-Mobile erweitert.
Page mit Usersettings

Hier der Code:

(more…)

1 2 3 4