Internetabdeckung der Mobilfunkanbieter Telekom, Vodafon, EPlus und O2

Intention

Da ich jeden Tag durch längere Autofahrten auf der A7 zwischen Melsungen und Fulda auf das mobile Internet zurückgreife, musste ich mich über die schlechte Internetabdeckung von ePlus ärgern. 2 Blackberry-Inhaber die mit meiner Fahrtgemeinschaft fahren, hatten über die Firma einen Telekomvertrag. Diese schienen in fast allen Gebieten auf der A7 schnelles Internet zur Verfügung zu haben. Doch gibt es da Statistiken?

Netzabdeckungsseiten der Anbieter

http://www.vodafone.de/privat/hilfe-support/netzabdeckung.html
http://www.t-mobile.de/funkversorgung
http://eis03sn1.eplus-online.de/geo/portal/gsm?javax.portlet.events=url%28pid_JGIS-Overview-Portlet%252Fmd_view%252Fst_normal%29

Grafischer Vergleich

Eigenbewertung der Grafik

Wenn man davon ausgeht, dass die Grafiken die reelle Internetabdeckung der Mobilfunkanbieter anzeigt, müsste die Telekom die beste Netzabdeckung auf der A7 zwischen Fulda und Melsungen haben.

Arduino Roboter mit USB Host Shield (1)

Aufgabenstellung

Es wird eine Lösung benötigt, um einen Arduino Microcontroller als USB Host zu betreiben, welcher selber die Stromversorgung der angeschlossenen USB-Geräte übernimmt. Für die einfache Erweiterung des Bausatzes existieren sogenannte „Shields“, welche eine preiswerte Lösung ohne die Notwendigkeit eines eigenen Platinenentwurfs zur Verfügung stellen.

Ansatz

Durch die Verwendung des USB Host Shields von DFRobot.com lässt sich über eine Aufsteckvariante über die SPI Schnittstelle und existierender, fertiger Bibliotheken eine solche Konfiguration schnell umsetzen.

Im Nachfolgebeispiel wird der bereits existierende Roboter (siehe Kategorie Mikrocontroller) mit einem Arduino Duemilanove (Arduino UNO kombatibel) und dem USB Host Shield ausgestattet. Dieser wird über eine USB Tastatur gesteuert.

Lösung

Arduino Duemilanove mit USB Host Shield (Pan&Tilt Servos, Tamiya Twin Motor Gear Box…)

Code

Der Code benutzt die downloadbare Bibliothek des USB Host Shields, welche sich nach dem Kopieren in die Arduino IDE verwenden lässt. Darüber hinaus wird der Pan and Tilt Servo über die Servo-Bibliothek gesteuert.

#include <avr/pgmspace.h>

#include <avrpins.h>
#include <max3421e.h>
#include <usbhost.h>
#include <usb_ch9.h>
#include <Usb.h>
#include <usbhub.h>
#include <avr/pgmspace.h>
#include <address.h>
#include <hidboot.h>

#include <printhex.h>
#include <message.h>
#include <hexdump.h>
#include <parsetools.h>

#include <Servo.h> 

int E1 = 6; //M1 Speed Control
int E2 = 5; //M2 Speed Control
int M1 = 8; //M1 Direction Control
int M2 = 7; //M2 Direction Control

 
Servo myservo;  // create servo object to control a servo 
Servo myservo2;  // create servo object to control a servo 
int horizontal=64;
int vertical=64;

boolean servoLeft = false;
boolean servoRight = false;
boolean servoUp = false;
boolean servoDown = false;


class KbdRptParser : public KeyboardReportParser
{
        void PrintKey(uint8_t mod, uint8_t key);
        
protected:
	virtual void OnKeyDown	(uint8_t mod, uint8_t key);
	virtual void OnKeyUp	(uint8_t mod, uint8_t key);
	virtual void OnKeyPressed(uint8_t key);
};

void KbdRptParser::PrintKey(uint8_t m, uint8_t key)	
{
    MODIFIERKEYS mod;
    *((uint8_t*)&mod) = m;
    Serial.print((mod.bmLeftCtrl   == 1) ? "C" : " ");
    Serial.print((mod.bmLeftShift  == 1) ? "S" : " ");
    Serial.print((mod.bmLeftAlt    == 1) ? "A" : " ");
    Serial.print((mod.bmLeftGUI    == 1) ? "G" : " ");
    
    Serial.print(" >");
    PrintHex<uint8_t>(key);
    Serial.print("< ");

    Serial.print((mod.bmRightCtrl   == 1) ? "C" : " ");
    Serial.print((mod.bmRightShift  == 1) ? "S" : " ");
    Serial.print((mod.bmRightAlt    == 1) ? "A" : " ");
    Serial.println((mod.bmRightGUI    == 1) ? "G" : " ");
};

void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)	
{
    Serial.print("DN ");
    PrintKey(mod, key);
    uint8_t c = OemToAscii(mod, key);
    
    
    int leftspeed = 255; //255 is maximum speed
    int rightspeed = 255;      
    
    switch(key)
    {
       case 0x50:
       {
          horizontal-=10;
       }
       break;
       case 0x4F:
       {
          horizontal+=10;
       }
       break;       
       case 0x52:
       {
          vertical-=10;
       }
       break;       
       case 0x51:
       {
          vertical+=10;
       }
       break;             
       case 0x5C:
       {
           left (leftspeed,rightspeed);
       }
       break;
       case 0x5E:
       {
           right (leftspeed,rightspeed);
       }
       break;
       case 0x60:
       {
           forward (leftspeed,rightspeed);
       }
       break;
       case 0x5A:
       {
           reverse (leftspeed,rightspeed);
       }
       break;   
       case 0x5D:
       {
           stop();
       }
       break;          
    }  
    
    if (horizontal <= 1 || horizontal >=128) horizontal=64;    
    if (vertical <= 1 || vertical >=128) vertical=64;    
    
    if (c)
        OnKeyPressed(c);
}

void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key)	
{
    Serial.print("UP ");
    
    
  
    
    PrintKey(mod, key);
}

void KbdRptParser::OnKeyPressed(uint8_t key)	
{
    Serial.print("ASCII: ");
    Serial.println((char)key);
};

USB     Usb;
//USBHub     Hub(&Usb);
HIDBoot<HID_PROTOCOL_KEYBOARD>    Keyboard(&Usb);

uint32_t next_time;

KbdRptParser Prs;

void setup()
{
    // attaches the servo on pin 2 to the servo object 
    myservo.attach(2);  

    // attaches the servo on pin 3 to the servo object 
    myservo2.attach(3);  
  
    Serial.begin( 9600 );
    Serial.println("Start");

    if (Usb.Init() == -1)
        Serial.println("OSC did not start.");
      
    delay( 200 );
  
    next_time = millis() + 5000;
  
    Keyboard.SetReportParser(0, (HIDReportParser*)&Prs);
}



void loop()
{
  /*
    if(servoLeft) horizontal-=10;
    if(servoRight) horizontal+=10;
    if(servoUp) vertical-=10;
    if(servoDown) vertical+=10;    
    */
    
// sets the servo position according to the scaled value 
    myservo.write(horizontal);                

// sets the servo position according to the scaled value  
    myservo2.write(vertical);                  
    
    Serial.println("Horizontal: "+horizontal );
    Serial.println("Vertical: "+vertical );
      
  
    Usb.Task();
}

void stop(void) //Stop
{
  digitalWrite(E1,LOW);
  digitalWrite(E2,LOW);
}
void forward(char a,char b)
{
  analogWrite (E1,a);
  digitalWrite(M1,LOW);
  analogWrite (E2,b);
  digitalWrite(M2,LOW);
}
void reverse (char a,char b)
{
  analogWrite (E1,a);
  digitalWrite(M1,HIGH);
  analogWrite (E2,b);
  digitalWrite(M2,HIGH);
}

void left (char a,char b)
{
  analogWrite (E1,a);
  digitalWrite(M1,HIGH);
  analogWrite (E2,b);
  digitalWrite(M2,LOW);
}

void right (char a,char b)
{
  analogWrite (E1,a);
  digitalWrite(M1,LOW);
  analogWrite (E2,b);
  digitalWrite(M2,HIGH);
}

Adobe Flex 3 / C#.NET FluorineFX: Balkendiagramme, Tortendiagramme und Liniendiagramme

Aufgabenstellung

Auf der Basis einer Datenbank-Abfrage werden Balkendiagramme, Tortendiagramme und Liniendiagramme mit Flex 3 und der Middleware FluorineFX, die auf einem Microsoft IIS Server läuft, erstellt.

Ansatz

FluorineFX lässt sich über die Webseite http://www.fluorinefx.com/download.html herunterladen und installieren.
Es handelt sich hierbei lediglich um eine Web-Anwendung, die auf dem Microsoft IIS Server mit dem Enterprise Manager eingebunden werden muss.

Vorraussetzungen

  • Installation von FluorineFX auf dem Microsoft IIS Server
  • Installation von Adobe Flex
  • Installation einer .NET Umgebung
  • Konfiguration aller Komponenten

Lösung

Beispiel

Code in FluorineFX

Der folgende Code wird in Visual Studion (Express) als Projekttyp Klassenbibliothek (oder FluorineFX Service Projekt) mit der Sprache C# genutzt. Die C# Klassenbibliothek wird im kompilierten Zustand (dll-Datei) in den Order „bin“ im FluorineFX-Verzeichnis (welches als Website in IIS eingebunden wurde) kopiert.

Die SQL-Anweisung sollte aus Performance-Gründen möglichst stark aggregiert werden. Das Beispiel benutzt eine zweispaltige Struktur (ReportVO) und kann beliebig angepasst werden.

C# Code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Data.SqlClient;
using FluorineFx; // Wichtig! FluorineFx.dll Verweis einbinden

namespace ITReportingServices
{
    [RemotingService("ReportingService")]
    public class ReportingService
    {
        public ArrayList getReport()
        {
            ArrayList reports = new ArrayList();

            SqlConnection conn = 
            new SqlConnection(MyConfigurationManager.msSqlServerString);

            try
            {
                conn.Open();
                SqlCommand comm = new SqlCommand();
                comm.Connection = conn;
                comm.CommandText = "SELECT MONTH(buchdatum) As Monat, "+
               "sum(wert) AS Summe FROM costcenteraccounting "+
               "WHERE (YEAR(buchdatum)) = 2011 "+
               "AND costcenter='101008960' "+
               "GROUP BY (MONTH(buchdatum)), (YEAR(buchdatum))	";
                SqlDataReader reader = comm.ExecuteReader();
                while (reader.Read())
                {
                    ReportVO vo = new ReportVO();
                    vo.monat = reader.GetValue(0).ToString();
                    vo.summe = reader.GetValue(1).ToString().Replace(",",".");
                    reports.Add(vo);
                }
            }
            catch (Exception e)
            {
                reports = new ArrayList();
                ReportVO vo = new ReportVO();
                vo.monat = e.Message;
                vo.summe = e.Message;
                reports.Add(vo);
                return reports;
            }
            finally
            {
                conn.Close();
            }

            return reports;
        }
    }

    public class ReportVO
    {
        public string monat;
        public string summe;
    }
}

Code in Adobe Flex

Das Model wird auf den .NET-Namespace gemappt.

Model:

package models
{
   [RemoteClass(alias="ITReportingServices.ReportVO")]
   public class ReportVO
   {
       public var monat:String;
       public var summe:String;		
		
       public function ReportVO()
       {
       }
   }
}

Service in Flex-Code aufrufen:

<!-- unter den Script-Teil in MXML schreiben -->
<mx:RemoteObject id="reportingService" 
                             destination="GenericDestination"  
                             source="ITReportingServices.ReportingService" 
                             showBusyCursor="true" 
                             fault="faultHandler(event)" >
       <mx:method name="getReport" result="getReportHandler(event)"/>
</mx:RemoteObject>	
...

// Das hier in mx:Script Teil
[Bindable] public var reports:ArrayCollection=new ArrayCollection();

public function creationComplete():void
{
    reportingService.getReport();
}
			
public function getReportHandler(event:ResultEvent):void
{
     reports = event.result as ArrayCollection;
}
			
public function faultHandler(event:FaultEvent):void
{
   Alert.show(event.fault.toString());
}

Diagramme

Balkendiagramm:

<mx:ColumnChart dataProvider="{reports}" 
                     height="100%" width="100%" id="columnchart1">
    <mx:horizontalAxis>
      <mx:CategoryAxis id="ca" categoryField="monat" title="Market sizes" />
     </mx:horizontalAxis>
     <!-- horizontal axis renderer -->
     <mx:horizontalAxisRenderers>
    	<mx:AxisRenderer axis="{ca}" canDropLabels="false" />
      </mx:horizontalAxisRenderers>
      <mx:series>
            <mx:ColumnSeries displayName="Amount" 
        		xField="monat"
        		yField="summe"/>
       </mx:series>
</mx:ColumnChart>
<mx:Legend visible="false" dataProvider="{columnchart1}"/>		

Tortendiagramm:

<mx:Label text="Linke Seite" />
<mx:PieChart id="pie2" 
   width="100%" height="100%"
   dataaProvider="{reports}"  showDataTips="true">
      <mx:series> 
        <!--Apply the Array of radii to the PieSeries.-->
	<mx:PieSeries field="summe"
                	        nameField="monat"
                	       labelPosition="callout"/>
      </mx:series>
</mx:PieChart>
  <mx:Legend dataProvider="{pie2}"/>

Liniendiagramm:

<mx:LineChart width="100%" height="100%" 
	id="myChart" 
	dataProvider="{reports}" 
        	showDataTips="true">
   <mx:horizontalAxis>
     <mx:CategoryAxis dataProvider="{reports}" 
                	     categoryField="month"/>
    </mx:horizontalAxis>
    <mx:series>
       <mx:LineSeries yField="summe" 
                 	  displayName="Summe"/>       
    </mx:series>
</mx:LineChart>