µWebGen

  • Maschinensteuerung über eine WebApp bzw. Webseite durch einfache Definitionsliste im uTasker Realtime Kernel.

  • Eigenes WebInterface innerhalb von Minuten.

  • Keine HTML oder JavaScript Kentnisse notwendig!

  • Automatische Darstellung als Webseite auf dem PC und als WebApp-Oberfläche im Smartphone-Browser.

Benutzer erwarten heutzutage für jede Maschine oder Anlage eine Webseite zur Steuerung und Einrichtung.

Um diesen Prozess für Sie zu erleichtern können ELZET80-Steuerungen automatisch diese Webseite generieren.
Einfache Anweisungen im C-Code erstellen Anzeige- und Steuerelemente ohne Vorkenntnisse in HTML oder JavaScript!

Die Kommunikation zwischen Steuerung und Webseite erledigt vorgefertigter JavaScript-Code, der im Mikrocontroller eingebettet wird.

Wird von allen µTasker-Baugruppen und von Sonderlösungen mit Ethernet unterstützt.

  • Funktion
  • µTasker-Integration
  • Beispiel: Slider
  • Beispiel: Login

µWebGen bietet Ihnen einen Webinterface-Generator der Ihre Anlage spielend leicht über einen Webbrowser überwach- und oder steuerbar macht.

Der Aufbau der Webseite wird durch eine Art von Mark-Up Definitionen im C-Code beschrieben und durch vorgefertigte C-Funktionen verarbeitet.

Der daraus resultierende Code wird beim Aufruf der Webseite von eingebetteten JavaScript-Funktionen interpretiert und das Webinterface generiert.

Das besondere an dieser Strategie ist, das Sie über keinerlei Kenntnisse von Web-Technologien wie HTML und JavaScript verfügen müssen.

Standardsteuerelemente wie Buttons, Slider, und Comboboxen sind vorhanden und können ohne Mühe verwendet werden.

 

Webhandler einhängen:

µWebControl wird in den Webhandler von µTasker eingehangen (Datei: webinterface.c, Funktion: fnHandleWeb)

Als erste Abfrage in der Funtkion wird der folgende Code eingefügt:

if(ptrData[0] == '!'){// Check if the dynamic content page was requested
   return fnHandleDynamicQuery(ptrData, http_session);
}

Im obigen Code wird überprüft ob eine HTTP-Anfrage mit einem vordefinierten Sonderzeichen (hier '!') beginnt.

Die Funktion fnHandleDynamicQuery ist die Hauptfunktion des µWebControl-Codes. Sie überprüft ob für die Anfrage eine Callback-Funtkion hinterlegt ist.

Callback registrieren:

In der Datei dynamicContent.c sind zwei Kommando-Arrays definiert. Das erste Array commands enthält Befehle die ohne Authentifizierung aufgerufen werden können, das zweite Array authCommands enhält Befehle die eine Authentifizierung erfordern.

/*command storage
* CMD("commandString", callbackFunction)
* callbackFunction has to be like this:
* int callbackFunction(char * wrPtr, unsigned char message[], int * dynLen, char* query){}
*
*/
WEBCOMMAND commands[] = {
   CMD("login=",fnWebLogin),
   CMD("loginState",fnGetLoginState),
   CMD("gbv",fnGetWebVars),
   CMD("getPageDesc",fnGetPageDesc),
   CMD("curTm",fnGetCurrentTime),
   CMD("hdlVar=",fnWebHandler),
   CMD("clear",fnClearWebPars),
   CMD("btn",fnAddButton),
   CMD("getVals",fnGetValues),
};

WEBCOMMAND authCommands[] = {
   CMD("setTime=",fnSetTime),
};

Aufbau Callback-Funktion:

Die Callback-Funktionen müssen dem folgenden Funktionskopf enstsprechen:

int callbackFunction(char * wrPtr, unsigned char message[], int * dynLen, char* query);

  • wrPtr:   buffer to hold the data
  • message: The startaddress of wrPtr to calculate dynLen
  • dynLen:  an integer pointer to store the length of the data to send
  • query:   The request query

Beispielfunktion fnGetIOStates:

The following function creates a page with the current states of the NET-3A4IO I/Os.

int fnGetIOState(char * wrPtr, unsigned char message[], int * dynLen, char* query){
  long lTemp;

//first we display the three raw adc values 

  wrPtr = uStrcpy(wrPtr,"ADC1: ");
  wrPtr = fnBufferDec((fnGetADC3A4IO(0)),1,wrPtr);

  wrPtr = uStrcpy(wrPtr,"<br>ADC2: ");
  wrPtr = fnBufferDec((fnGetADC3A4IO(1)),1,wrPtr);

  wrPtr = uStrcpy(wrPtr,"<br>ADC3: ");
  wrPtr = fnBufferDec((fnGetADC3A4IO(2)),1,wrPtr);

//check if the 3A4IO is configured for PT100 or type K thermocouples and print it accordingly

  if(uc3A4IORange == RANGE_RTD_RAW){
    wrPtr = uStrcpy(wrPtr,"<br> PT100(ADC1): ");
    wrPtr = fnBufferDec(fnLinVal(fnGetADC3A4IO(0),0),1,wrPtr);
  }else if(uc3A4IORange == RANGE_TC_RAW){
    wrPtr = uStrcpy(wrPtr,"<br> Type K(ADC1): ");
    wrPtr = fnBufferDec(fnLinVal(fnGetADC3A4IO(0) + s3A4IO_ref_temp,1),1,wrPtr);
  }

//here we collect and print the states of the four outputs

  wrPtr = uStrcpy(wrPtr,"<br> OUTPUT1: ");
  wrPtr = fnBufferDec(fnGetOutput3A4IO(0),0,wrPtr);
  wrPtr = uStrcpy(wrPtr,"<br> OUTPUT2: ");
  wrPtr = fnBufferDec(fnGetOutput3A4IO(1),0,wrPtr);
  wrPtr = uStrcpy(wrPtr,"<br> OUTPUT3: ");
  wrPtr = fnBufferDec(fnGetOutput3A4IO(2),0,wrPtr);
  wrPtr = uStrcpy(wrPtr,"<br> OUTPUT4: ");
  wrPtr = fnBufferDec(fnGetOutput3A4IO(3),0,wrPtr);

 
//here we collect and print the states of the four inputs

  wrPtr = uStrcpy(wrPtr,"<br> Input1: ");
  wrPtr = fnBufferDec(fnGetInput3A4IO(0),0,wrPtr);
  wrPtr = uStrcpy(wrPtr,"<br> Input2: ");
  wrPtr = fnBufferDec(fnGetInput3A4IO(1),0,wrPtr);
  wrPtr = uStrcpy(wrPtr,"<br> Input3: ");
  wrPtr = fnBufferDec(fnGetInput3A4IO(2),0,wrPtr);
  wrPtr = uStrcpy(wrPtr,"<br> Input4: ");
  wrPtr = fnBufferDec(fnGetInput3A4IO(3),0,wrPtr);

//calculate the length of the generated content
  *dynLen = (wrPtr - (CHAR*) message);
  return 0;
}

 

Das Ergebnis sieht so aus:

ADC1: 12124
ADC2: 5125
ADC3: 12113
PT100(ADC1): 234
OUTPUT1: 0
OUTPUT2: 1
OUTPUT3: 0
OUTPUT4: 0
Input1: 1
Input2: 0
Input3: 1
Input4: 1

Coming soon...