Forum: Mikrocontroller und Digitale Elektronik UART - Heizungssteurung


von Ava A. (avadis)


Lesenswert?

Hi Leute,

hab heute zum ersten mal einen Mikrocontroller programmiert und brauche 
hilfe! Hab mich durch eure Tutorials geschlagen und viel gesucht und 
auch viel gefunden, nun zu meinem problem:

Ich will eine Heizungssteurung aufbauen, wo eine Uhr läuft und ich einen 
Start und einen Stoppzeitraum einstellen kann. Das ganze soll mit 
Hyperterminal zu sehen sein!
Bisher klappt die Kommunikation ZUM PC, aber ich will mit der taste "1" 
bzw. "2" in ein Auswahlmenü kommen, wo ich dann die Zeiten 
(Abschalt/Einschalt) einstellen kann. Aber irgendwie schaffe ich es 
nicht ne richtige Abfrage zu machen.
Hier mein bisheriger Code:







// Hauptinclude Datei für den Atmega32 16PU
#include <mega32.h>

// Standard Input/Output functions
#include <stdio.h>
#include <string.h>

// Globale Variabeln
char  text [31]  = "Schaltuhr Heizungssteuerung!\r\n";
flash char  timetext[] = "Es ist jetzt %02d:%02d:%02d\r\n";
flash char  Heiztext1 [] = " Die Heizung wird um %02d:%02d %p.";
flash char Heiztextan [] = "eingeschaltet";
flash char Heiztextaus [] = "ausgeschaltet";

char  * message ;
int i;

//  Zeiten
int ss_aktuel = 0;
int mm_aktuel = 0;
int hh_aktuel = 0;
int mm_start = 0;
int hh_start = 0;
int mm_stop = 0;
int hh_stop = 0;
int timercount = 0;

// Funktioen zu Seriellen Ausagbe

void sendchar( char c)
{
        while (!(UCSRA & ( 1<<UDRE))) {}
        UDR =  c;
}

// sendnewline  Zeilenvorschub an Hyperterm senden
void sendnewline()
{
     char c = 13;
     sendchar(c);
     c = 10;
     sendchar(c);
}

// sende eine textzeile an Hyperterm
void sendtextline ( char *txt )
{
    int i = 0;
    while ( i < strlen(txt) )
    sendchar(txt[i]);
}

 // Timer ISr - Interrupt
interrupt [TIM0_COMP] void timer0_Compare(void)
{
  timercount ++;
  if ( timercount > 12500)
  {
    timercount = 0;
    ss_aktuel ++;
    mm_aktuel += ss_aktuel / 60;
//    if ( ss_aktuel >= 60) ssaktuel = 0;
    ss_aktuel = ss_aktuel % 60;
    hh_aktuel += mm_aktuel / 60;
    mm_aktuel = mm_aktuel %60;
    hh_aktuel = hh_aktuel % 24;
    sprintf(message, timetext, hh_aktuel , mm_aktuel, ss_aktuel);
    sendnewline();
    sendtextline(message);
  }
}




// Main

void main(void)
{

// Port A initialization
// Func0 - 7=In und = T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
PORTB=0x00;
DDRB=0x00;

// Port C initialization
PORTC=0x00;
DDRC=0x00;

// Port D initialization
PORTD=0x00;
DDRD=0x00;

TCCR0=0x3a;// | (1 << CS01);
TCNT0=0x00;
OCR0=0x7d;// 0x00;

TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

ASSR=0x80;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00 |(1<< OCIE0);

//USART: 9600 Baud, 8 Data, 1 Stop, No Parity, Asynchron, Receiver on, 
Transmitter off
UCSRA=0x00;

UCSRB= 0x10 | ( 1 << TXEN); // |(1 << RXEN) ;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x067;

ACSR=0x80;
SFIOR=0x00;

#asm("sei")
while ( i < 31) sendchar(text[i++]);
i = 0;
sendnewline();
sprintf (message ,"","");
sprintf(message, timetext, hh_aktuel , mm_aktuel);
sendnewline();
sendtextline(message);
sendnewline();
sprintf(message , Heiztext1 , hh_start,mm_start , Heiztextan);
sendnewline();
sprintf(message , Heiztext1 , hh_stop,mm_stop , Heiztextaus);

while (1)
    {
/*
        while (!(UCSRA & ( 1 << RXC)))
        {
            char c = UDR;
            sprintf(message, timetext, hh_aktuel , mm_aktuel) ;
            sendnewline();
            sendtextline(message);
            sendnewline();
         }
 */
      };
}

von Ava A. (avadis)


Lesenswert?

Achjaaa....
Und nochwas wichtiges, wie kann ich den "bildschirm" clearen?
doch nicht etwa mit 20 Absätzen ?!?!?!

von PJ (Gast)


Lesenswert?

Bildschirm löschen geht meist mit ^L (Ctrl-L, ist ein bestimmter Code, 
ich glaube 0x0C), aber das hängt vom angeschlossenen Terminal ab.

von gast (Gast)


Lesenswert?

such mal nach VT100 das ist glaube genau das was du suchst
also ein menü im terminal

es gibt dort escapesequenzen die einiges ermöglichen

von Ava A. (avadis)


Lesenswert?

PJ schrieb:
> Bildschirm löschen geht meist mit ^L (Ctrl-L, ist ein bestimmter Code,
> ich glaube 0x0C), aber das hängt vom angeschlossenen Terminal ab.

jau, hat geklappt, danke :)

void clearscreen();
{
char c = 12; // 0x0c
sendchar(c)
}

von Karl H. (kbuchegg)


Lesenswert?

Die Frage nach dem Löschen eines Bildschirms wurde ja schon beantwortet.

In deinem Programm ist aber noch ein schwerer Fehler:

char  * message ;

...

sprintf(message, timetext, hh_aktuel , mm_aktuel);


Das geht so nicht.
message ist zwar ein Pointer. Aber auf welchen Speicher zeigt er denn? 
Damit du zb sprintf verwenden kannst, musst du eine Speicherfläche 
bereit stellen, in der sprintf den Text ablegen kann. Du hast keine 
Speicherfläche. Du hast nur einen Zeiger, der irgendwo hin zeigt. Ok, 
stimmt nicht ganz, er zeigt so wie du es geschrieben hast schon auf eine 
definierte Speicherzelle. Der springende Punkt ist aber: du darfst dort 
nicht einfach hinschreiben lassen. Der Speicher steht nicht unter deiner 
Kontrolle.

Was du brauchst ist ein char-Array, das du an sprintf übergeben kannst 
und welches groß genug ist, um den Text aufzunehmen

char message[80];

Das wäre zb so was. Da passen jetzt Texte aus maximal 79 Zeichen rein.

http://www.mikrocontroller.net/articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F

Zu deinem Problem mit dem Empfang:
1
        while (!(UCSRA & ( 1 << RXC)))
2
        {
3
            char c = UDR;
4
            sprintf(message, timetext, hh_aktuel , mm_aktuel) ;
5
            sendnewline();
6
            sendtextline(message);
7
            sendnewline();
8
         }

Nope. Das RXC Bit wird gesetzt nachdem ein Zeichen empfangen wurde. Wenn 
du also schon warten musst, dann musst du darauf warten, dass ein 
Zeichen empfangen wird.

Es muss also lauten
1
       while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
2
        ;
Und erst danach steht dir das Zeichen in UDR zur Verfügung.
Sieh dir auch mal den entsprechenden Abschnitt im Tutorial an.

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Der_UART

von PJ (Gast)


Lesenswert?

Er will vermutlich nicht NUR auf das Zeichen warten, sondern 
währenddessen weiter seinen Zustand ausgeben.
Nur hatte er noch nicht für uns klar programmiert, was dann mit dem 
empfangenen Zeichen gemacht wird.

"Besser" wäre es vielleicht, das Zeichen in einer ISR zu empfangen, 
anstatt durch eine ständige Belastung der Übertragungskette bis zum PC 
unnötig Strom zu verbraten.

Aber alles zu seiner Zeit, ist ja sein erstes Projekt.

von PJ (Gast)


Lesenswert?

Zur Auswertung des Zeichens kann man geschachtelte "if else"s verwenden, 
aber wahrscheinlich ist das "case select" Konstrukt Dir lieber.

Einfach mal danach googeln, da findet man sofort Beispiele.

von Karl H. (kbuchegg)


Lesenswert?

Ava Ava schrieb:
> PJ schrieb:
>> Bildschirm löschen geht meist mit ^L (Ctrl-L, ist ein bestimmter Code,
>> ich glaube 0x0C), aber das hängt vom angeschlossenen Terminal ab.
>
> jau, hat geklappt, danke :)
>
> void clearscreen();
> {
> char c = 12; // 0x0c
> sendchar(c)
> }

Du musst nicht für alles und jedes lokale Variablen erzeugen (gut, der 
Compiler wird sie sowieso rausschmeissen). Zuviel ist dann auch nicht 
gut, schadet der Übersicht.
1
void clearscreen();
2
{
3
  sendchar( 12 );
4
}

ist genausogut.

Wenn du es noch besser machen willst, dann machs zb so
1
...
2
3
#define CLS  12
4
5
void clearscreen();
6
{
7
  sendchar( CLS );
8
}

Selbiges kannst du auch mit der sendnewline Funktion machen.
1
...
2
3
#define CLS  12       // ASCII ^L = Clear screen
4
#define CR   '\n'     // Carriage return
5
#define LF   '\r'     // Line Feed
6
7
8
void sendnewline()
9
{
10
  sendchar( CR );
11
  sendchar( LF );
12
}
13
14
void clearscreen();
15
{
16
  sendchar( CLS );
17
}

Und deine sendtextline können wir bei der Gelegenheit auch gleich noch 
pimpen. Es gibt keinen Grund da mit Indizes oder gar strlen rumzuwerfen. 
Ist alles nur Laufzeit für nichts.
1
// sende eine textzeile an Hyperterm
2
void sendtextline ( char *txt )
3
{
4
  while ( *txt != '\0' ) {
5
    sendchar( *txt );
6
    txt++;
7
  }
8
}

von Ava A. (avadis)


Lesenswert?

jap,

Bin gerade dabei im sekundentakt an Hyperterm die Zeit + Text zu senden.
Es soll ungefähr so ausschauen am ende:


Schaltuhr Heizungssteurung
--------------------------

Es ist jetzt 22:32

Die Heizung wird um 6:00 aktiviert
Die Heizung wird um 12:00 deaktiviert

Druecken sie "1" um die Startzeit zu ändern
Druecken sie "2" um die Endzeit zu ändern

Heizung deaktiviert

von PJ (Gast)


Lesenswert?

Sowas hier meinte ich:

http://en.wikipedia.org/wiki/Switch_statement#C.2C_C.2B.2B.2C_C.23.2C_Java

switch case Konstrukt heißt es richtig.

von Karl H. (kbuchegg)


Lesenswert?

PJ schrieb:

> Aber alles zu seiner Zeit, ist ja sein erstes Projekt.

Seh ich auch so.
Ich würd ihm folgendes vorschlagen
1
  ...
2
3
  while( 1 )
4
  {
5
    ... mach das, was in jedem Schleifendurchlauf gemacht werden muss
6
7
    ... unter anderem wird auch geprüft, ob von der seriellen Schnittstelle
8
        ein Zeichen empfangen wurde
9
10
    if( UCSRA & ( 1 << RXC ) )
11
    {
12
       // ein zeichen wurde empfangen
13
       c = UDR;
14
15
       if( c == '1' )
16
         mach was
17
18
       else if( c == '2' )
19
         mach was anderes
20
    }
21
  }

Wie man das ganze weitertreibt um eine komplette Eingabezeile 
zusammenzusetzen, möcht ich jetzt noch nicht ansprechen. Ich denke im 
Moment gibt es genug zu verdauen.

von PJ (Gast)


Lesenswert?

Wenn das kaum mehr machen soll, könnte man einfach ein paar Tasten 
definieren, mit denen die Stunden und Minuten von Start und Ende erhöht 
und verringert werden können. Bei größeren Änderungen einfach die 
Tastenwiederholfunktion des PCs nutzen (oder noch 10er-Änderungstasten 
hinzufügen).

Ein umfassenderes Menüsystem braucht dann halt 'ne kleine State machine.

von Ava A. (avadis)


Lesenswert?

hört sich gut an :)

Wow, so schnelle und viele Antworten! Bin grad am Umsetzen
hab jetzt im Sekundentakt eine aktualisierte Seite, die Funktionen sind 
nun auch besser sotiert, überflüssiges gelöscht und mehr 
einheitlichkeit, war halt noch viel testerei zwischendrin :)

Versuche gerade den Vorschlag von "kbuchegg" umzusetzen :)

von Karl H. (kbuchegg)


Lesenswert?

Ava Ava schrieb:
> hört sich gut an :)
>
> Wow, so schnelle und viele Antworten! Bin grad am Umsetzen
> hab jetzt im Sekundentakt eine aktualisierte Seite, die Funktionen sind
> nun auch besser sotiert, überflüssiges gelöscht und mehr
> einheitlichkeit, war halt noch viel testerei zwischendrin :)
>
> Versuche gerade den Vorschlag von "kbuchegg" umzusetzen :)

Dein 'Sekundentakt' macht mir noch etwas Sorgen.
Du hast hoffentlich nicht vor, den sekündlichen Abstand mittels eines 
_delay_ms( 1000 ) zu erreichen?

von PJ (Gast)


Lesenswert?

Wieso nicht? Verboten ist's bestimmt nicht.

Natürlich kann man damit auch Timer und ISRs und Semaphoren üben...

Und sowie gilt ja, wer "Timer" oder "Uhr" sagt, muss auch "Uhr stellen" 
sagen.

von Karl H. (kbuchegg)


Lesenswert?

PJ schrieb:
> Wieso nicht? Verboten ist's bestimmt nicht.

Das gibt dann allerdings Schwierigkeiten mit der UART, wenn der µC immer 
wieder mal 1 Sekunde Däumchen dreht und einfach nicht hinhört, wenn der 
PC schreit :-)

von PJ (Gast)


Lesenswert?

Ach so, ja da hast Du natürlich recht.

Dann kann er ja den delay auf 100 ms verkürzen.

Natürlich ist das halb so schlimm, wenn er immer nur ab und zu 1 Taste 
drückt.

Aber vielleicht hat er eh einen delay von 0, weil das noch in der 
UART-Rx-Warteschleife steht. :-)

von Ava A. (avadis)


Lesenswert?

Karl heinz Buchegger schrieb:
> Ava Ava schrieb:
>> hört sich gut an :)
>>
>> Wow, so schnelle und viele Antworten! Bin grad am Umsetzen
>> hab jetzt im Sekundentakt eine aktualisierte Seite, die Funktionen sind
>> nun auch besser sotiert, überflüssiges gelöscht und mehr
>> einheitlichkeit, war halt noch viel testerei zwischendrin :)
>>
>> Versuche gerade den Vorschlag von "kbuchegg" umzusetzen :)
>
> Dein 'Sekundentakt' macht mir noch etwas Sorgen.
> Du hast hoffentlich nicht vor, den sekündlichen Abstand mittels eines
> _delay_ms( 1000 ) zu erreichen?

Nein!



interrupt [TIM0_COMP] void timer0_Compare(void)
{
  timercount ++;
  if ( timercount > 12500)
  {
    timercount = 0;
    ss_aktuel ++;
    mm_aktuel += ss_aktuel / 60;
    showMaintext();                                 // <- HIER 1 Sekunde
    ss_aktuel = ss_aktuel % 60;

von Karl H. (kbuchegg)


Lesenswert?

Ava Ava schrieb:

>> Dein 'Sekundentakt' macht mir noch etwas Sorgen.
>> Du hast hoffentlich nicht vor, den sekündlichen Abstand mittels eines
>> _delay_ms( 1000 ) zu erreichen?
>
> Nein!

Ah, jetzt wo du es sagst, kann ich mich erinnern das gelesen zu haben.
Na dann ist ja alles gut.

Und, klappt der Empfang?
(kleiner Hinweis: es ist am Anfang immer gut, wenn der µC gleich mal ein 
emmpfangenes Zeichen zurückschickt. So kann man gleich mal kontrollieren 
ob und wenn ja was empfangen wurde.)

von PJ (Gast)


Lesenswert?

Aber ich glaube nicht, dass es so eine gute Idee ist, in der ISR ein 
paar Zeilen Text über den UART auszugeben, vor allem, wenn die ISR 12500 
mal pro Sekunde aufgerufen wird.

Da gehen dann wohl jede Sekunde ein paar Aufrufe verloren, und schon 
geht die Uhr immer fälscher.

von Karl H. (kbuchegg)


Lesenswert?

Du rechnest da aber in deiner Uhr sehr viel herum :-)
Auch wenn man mit dem µC keine Gnade haben sollte, so muss man ihn aber 
auch nicht unbedingt quälen (Obwohl mir dein Code zeigt, dass du mit / 
und % umgehen kannst, was nicht so selbstverständlich ist)
1
// Timer ISr - Interrupt
2
interrupt [TIM0_COMP] void timer0_Compare(void)
3
{
4
  timercount ++;
5
  if ( timercount > 12500)
6
  {
7
    timercount = 0;
8
    ss_aktuel ++;
9
10
    if( ss_aktuel == 60 )
11
    {
12
      ss_aktuel = 0;
13
      mm_aktuel ++;
14
      if( mm_aktuel == 60 )
15
      {
16
        mm_aktuel = 0;
17
        hh_aktuel ++;
18
        if( hh_aktuel == 24 )
19
          hh_aktuel = 0;
20
      }
21
    }
22
23
    sprintf(message, timetext, hh_aktuel , mm_aktuel, ss_aktuel);
24
    sendnewline();
25
    sendtextline(message);
26
  }
27
}

Das erweitert sich dann schon fast von alleine auf Wochentage, was ja 
interesant sein könnte, da man am Wochenende ein anderes Heizprofil 
fahren wird als unter der Woche. Zumindest wenn alle im Haushalt 
berufstätig sind.

Alledings solltest du dich an die Grundregel halten, die da lautet: in 
einer ISR haben lang andauernde Prozesse nichts verloren. Man möchte so 
schnell wie möglich aus der ISR wieder raus.
1
// Timer ISr - Interrupt
2
interrupt [TIM0_COMP] void timer0_Compare(void)
3
{
4
  timercount ++;
5
  if ( timercount > 12500)
6
  {
7
    timercount = 0;
8
    ss_aktuel ++;
9
10
    if( ss_aktuel == 60 )
11
    {
12
      ss_aktuel = 0;
13
      mm_aktuel ++;
14
      if( mm_aktuel == 60 )
15
      {
16
        mm_aktuel = 0;
17
        hh_aktuel ++;
18
        if( hh_aktuel == 24 )
19
          hh_aktuel = 0;
20
      }
21
    }
22
23
    updateTime = 1;
24
  }
25
}
26
27
28
...
29
30
int main()
31
{
32
   ....
33
34
   while( 1 )
35
   {
36
      ....
37
38
      if( updateTime == 1 )
39
      {
40
        updateTime = 0;
41
        sprintf(message, timetext, hh_aktuel , mm_aktuel, ss_aktuel);
42
        sendnewline();
43
        sendtextline(message);
44
      }
45
46
      if( UCSRA & ( 1 << RXC ) )
47
      {
48
         ....

von Ava A. (avadis)


Lesenswert?

Karl heinz Buchegger schrieb:

> Ah, jetzt wo du es sagst, kann ich mich erinnern das gelesen zu haben.
> Na dann ist ja alles gut.
>
> Und, klappt der Empfang?
> (kleiner Hinweis: es ist am Anfang immer gut, wenn der µC gleich mal ein
> emmpfangenes Zeichen zurückschickt. So kann man gleich mal kontrollieren
> ob und wenn ja was empfangen wurde.)

Bevor deinen tread gelesen zu haben, hab ich es genauso gemacht :)

Also eine Abfrage auf 1 bzw. 2 ... wenn 1 Gedrückt wird, soll Einfach 
ein kleiner text ausgegeben werden, genauso wenn man 2 drückt.

es klappt, der text wird angezeigt, nur nach 1 sekunde halt 
logischerweise wieder wegaktualisiert :p ... Nun, muss ich also bei 
Tastendruck da raus :)

von Karl H. (kbuchegg)


Lesenswert?

Ava Ava schrieb:

> es klappt, der text wird angezeigt, nur nach 1 sekunde halt
> logischerweise wieder wegaktualisiert :p ... Nun, muss ich also bei
> Tastendruck da raus :)

Auch deshalb ist die Lösung mit den Jobflags (zb updateTime) die bessere 
Lösung. Dann verteilt sich die Logik des Programms nicht über so viele 
Codestellen, sondern bleibt mehr beisammen und bleibt besser 
überschaubar.
Das Jobflag updateTime, welches von der Timer ISR gesetzt wird, meldet 
lediglich, dass 1 Sekunde vergangen ist. Was die Konsequenz daraus ist, 
geht den Timer an sich nichts an. Die Konsequenz kann sein, dass das 
Terminal mit der aktuellen Zeit aktualisiert wird. Sie könnte aber auch 
sein, dass überprüft wird, ob die Heizung ein oder ausgeschaltet werden 
soll. Es könnte auch sein, dass eine LED umgeschaltet wird (damit man 
auch bei ausgeschaltetem Terminal sieht, dass die Steuerung noch läuft) 
etc. All das ist aber nicht das Bier der Timer-ISR. Die meldet nur, dass 
1 Sekunde vergangen ist.

von Ava A. (avadis)


Lesenswert?

Ok, hab das jetzt in meinem Code 1 zu 1 von dir übernommen (kleine 
änderung), und funktioniert auch :)

von Ava A. (avadis)


Lesenswert?

So mit dem untermenue das klappt nun auch. Wenn ich 1 drücke poppt, das 
Einstellmenü auf, wenn ich 2 drücke, das Austellmenue, nun muss ich mal 
gucken, wegen der Uhrzeitabfrage, was könnt ihr mir da raten?

von Karl H. (kbuchegg)


Lesenswert?

Ich würds so machen, wie weiter oben schon mal vorgeschlagen:
4 Tasten:  Stunden rauf, Stunden runter, Minuten rauf, Minuten runter
Mit dem Autorepeat, den Windows automatisch auf die Tasten legt, geht 
das noch komfortabel. Zusätzlicher Bonus: Fehleingaben werden 
zuverlässig ausgeschlossen.

von Ava A. (avadis)


Lesenswert?

Ich versuch das mal .... :)

von Ava A. (avadis)


Lesenswert?

Da haste recht, ging sehr schnell und klappt gut :)

Muss jetzt noch 23std ++ und 59min ++ abfangen :)


while (1)
    {

            // BIS HIER WAR NOCH ALLES RICHTIG
        if( UCSRA & ( 1 << RXC ) )
        {
       char c = UDR;    //Zeichen empfangen

       if( c == 'q' )
        hh_start ++;

       else if( c == 'w' )
        hh_start --;

       else if( c == 'e' )
        mm_start ++;

       else if( c == 'r' )
        mm_start --;
        }


    };

von Karl H. (kbuchegg)


Lesenswert?

Ava Ava schrieb:
> Da haste recht, ging sehr schnell und klappt gut :)
>
> Muss jetzt noch 23std ++ und 59min ++ abfangen :)

Die andere Richtung auch nicht vergessen :-)


Na, geht doch voran. So wies aussieht, hast du Spass daran, das Werk 
entstehen zu sehen. Das ist das Allerwichtigste.

von Ava A. (avadis)


Lesenswert?

Ich glaub spass ist etwas untertrieben :D
Das ist der Wansinn, wie das wächst, und vor allem, durch die hilfe 
macht es noch mehr laune, weil man nicht so heftig stecken bleibt :))

Andere Richtung funktioniert nun auch und die überläufe von 23std auf 00 
sowie 59 auf 00 funtkioniert ebenso. is zwar viel code nun, aber 
trotzdem verständlich!

Muss jetzt ja nur noch eine Bereichsabfrage machen, für die Steurung 
"an" bzw. "aus" ... wie man die einzelenen Ports schaltet habe ich mir 
noch nicht angeschaut...

von Oliver (Gast)


Lesenswert?

>Muss jetzt ja nur noch eine Bereichsabfrage machen, für die Steurung
>"an" bzw. "aus" ... wie man die einzelenen Ports schaltet habe ich mir
>noch nicht angeschaut...

Bis zum nächsten Winter ist ja auch noch etwas Zeit :-)

Oliver

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.