Pages: [1]   Go Down
Author Topic: Ext. Interrupt während Seriellem einlesen ??  (Read 394 times)
0 Members and 1 Guest are viewing this topic.
Austria
Offline Offline
Full Member
***
Karma: 6
Posts: 102
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

ich möchte einen Arduino so programmieren daß er gewissermaßen "gleichzeitig" auf bestimmte serielle Daten wartet oder aber daß ein Eingangspin high wird. Je nachdem soll ein bestimmter Teil des Codes ausgeführt werden und am Ende soll er wieder warten bis entweder die richtigen ser. Daten kommen oder der eine Pin high wird.

Folgenden Code habe ich bereits:

Code:
#include <Tone.h>

Tone freq1;
Tone freq2;
const int DTMF_freq1[] = { 1336, 1209, 1336, 1477, 1209, 1336, 1477, 1209, 1336, 1477 };
const int DTMF_freq2[] = {  941,  697,  697,  697,  770,  770,  770,  852,  852,  852 };

void setup()
{
 Serial.begin(115200);
 freq1.begin(11);                                   // Pin für DTMF Ton 1
 freq2.begin(12);                                   // Pin für DTMF Ton 2
}

void playDTMF(uint8_t number, long duration)        // DTMF Generator
{
  freq1.play(DTMF_freq1[number], duration);
  freq2.play(DTMF_freq2[number], duration);
}

int getIntFromString (char *stringWithInt, byte num)    // Zahlen aus String extrahieren
// input: pointer to a char array
// returns an integer number from the string (positive numbers only!)
// num=1, returns 1st number from the string
// num=2, returns 2nd number from the string, and so on
{
  char *tail;
  while (num>0)
  {
    num--;
    // skip non-digits
    while ((!isdigit (*stringWithInt))&&(*stringWithInt!=0)) stringWithInt++;
    tail=stringWithInt;
    // find digits
    while ((isdigit(*tail))&&(*tail!=0)) tail++;
    if (num>0) stringWithInt=tail; // new search string is the string after that number
  } 
  return(strtol(stringWithInt, &tail, 0));
}

void loop(void)
{
  char commandbuffer[40];
  char c;
  int i=0;
  byte dta, dtb, dtc;
  int int1, int2;
  // Puffer mit Nullbytes fuellen und dadurch loeschen
  memset(commandbuffer,0,sizeof(commandbuffer));
  if (Serial.available())
  {
    delay(100);
    while (Serial.available())
    {
      c=Serial.read();
      if (c>32) // Nur Zeichen mit ASCII-Code oberhalb Leerzeichen
      {
        commandbuffer[i] = c;
        i++;
      } 
    }
  }
  if (strstr(commandbuffer,"CONNECT")==commandbuffer)      //CONNECT
  {
    Serial.print("Connect erkannt: ");
    Serial.println(commandbuffer);
    int1=getIntFromString(commandbuffer,1);
    Serial.print("Erste Zahl : ");Serial.println(int1);   // Monitor
    int2=getIntFromString(commandbuffer,2);
    Serial.print("Zweite Zahl: ");Serial.println(int2);   // Monitor
    dta=int2/100;                                         // Integer in einzelne Ziffern zerlegen
    dtb=int2%100/10;                                      // Integer in einzelne Ziffern zerlegen
    dtc=int2%10;                                          // Integer in einzelne Ziffern Zerlegen
    Serial.print("Zerlegt: ");Serial.print(dta);Serial.print(dtb);Serial.println(dtc);   // Monitor einzeln
    playDTMF(dta, 200); delay(250);                       // 1. DTMF Stelle generieren
    playDTMF(dtb, 200); delay(250);                       // 2. DTMF Stelle generieren
    playDTMF(dtc, 200); delay(250);                       // 3. DTMF Stelle generieren
  }
  else if (strstr(commandbuffer,"RING")==commandbuffer)   // RING
  {
    Serial.print("Ring erkannt: ");
    Serial.println(commandbuffer);
  }
  else if (strcmp(commandbuffer,"")!=0)                    // Ungültige Eingabe verwerfen
  {
    Serial.print("Eingabe verworfen: ");
    Serial.println(commandbuffer);
  }
}


Das Programm wartet quasi ewig bis sich was auf der ser. Schnittstelle tut und wertet dann aus (generiert DTMF Töne mittels der Tone Library)

Jetzt ist meine Frage, wie und wo checke ich am Besten ab ob ein bestimmter Eingangspin (z.B. Digital 2) auf High geht damit ich dann darauf reagieren kann und einen bestimten Code ausführe.  Ist da ein externer Interrupt sinnvoll oder hat jemand eine bessere Idee? Jedenfalls muß ich relativ schnell mitbekommen wenn de Pin high wird, innerhalb von höchstens 30ms...

Schon mal vielen Dank für die Ideen,h...

Christian
Logged

Elektronik funktioniert intern mit Rauch.
Beweis: Wenn der Rauch herauskommt ist es kaputt...

Germany
Offline Offline
Faraday Member
**
Karma: 58
Posts: 3046
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Jetzt ist meine Frage, wie und wo checke ich am Besten ab ob ein bestimmter Eingangspin (z.B. Digital 2) auf High geht damit ich dann darauf reagieren kann und einen bestimten Code ausführe.  Ist da ein externer Interrupt sinnvoll oder hat jemand eine bessere Idee? Jedenfalls muß ich relativ schnell mitbekommen wenn de Pin high wird, innerhalb von höchstens 30ms...

Hängt von deinem "bestimmten Code" ab, ob du den in einer Interrupt-Routine ausführen kannst. ( Digital-Pins kannst du ändern, aber deine geliebten delays oder auch Serial.write geht nicht )
Eigentlich viel besser wäre, du schmeisst alle *) delay() raus, dann sind 30 ms überhaupt kein Problem innerhalb von loop().
Und du könntest auch deine Tone.play() Sequenz jederzeit unterbrechen ( falls das eine Funktion deiner "Interrupt"- Routine ist ).


*) Um bei 115200 Bd den ganzen commandbuffer[ 40 ] zu lesen, brauchst du keine 100 sondern 4 ms, wenn die andere Seite schnell genug ist. Aber schöner wäre es natürlich, auch das evtl in mehrere loop - Runden aufzuteilen. Wenn da kein Endezeichen ist, wäre eine Fertig -Bedingung z.B. dass seit 1-2 ms kein neues Zeichen mehr angekommen ist.
Logged

Pages: [1]   Go Up
Jump to: