www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Störungen mit Funkmodulen


Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute ich habe mir eine Schaltung mit Funkmodulen (Sender
/Empfänger) aufgebaut. Der eine Controller (ATTINY2313) sendet lustig
vor sich hin. Mein Empfänger der ATMEGA 128 Empfängt auch...
Jetzt das Problem:

Wenn der ATTINY nix sendet habe ich störsignale welches mir beim
Empfangen der Daten probleme macht.. Habt ihr ne Idee für einen Filter
oder soo. Oder wie macht ihr das mit dem Empfangen. Ich mache das im
Moment über den IPC PIN messe zeit und Pegel und danach wird das
Manchester wieder decodiert. ???

Kann mir einer Helfen ?

Autor: Wolfgang Horn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja, Andreas,

Du: "Wenn der ATTINY nix sendet habe ich störsignale welches mir beim
Empfangen der Daten probleme macht"

Willkommen in der Welt der drahtlosen Kommunikation.

Im Leerlauf hast Du im Wesentlichen folgende Störquellen:
1. Das Rauschen des Empfängers.
2. Einstrahlungen von anderen Nutzern des Frequenzbandes und von
Störquellen (z.B. Oberwellen der Taktfrequenz Deines Atmega128).

Die üblichen Gegenmaßnahmen, die mit einem simplen Funkmodul machbar
sein könnten:
1. Frequenzselektiv - je schmalbandiger die Antenne und Vorfilter,
desto weniger Störsignale.
2. Pegelselektiv - der Empfänger tastet erst ab einem minimalen
Empfangspegel auf. Hilft gegen Rauschen und schwache Störer.
3. Winkelselektiv - Richtantenne. Je schmaler das Diagramm und auf den
Sender ausgerichtet, desto weniger Störsignale. (Die Polarisation
vernachlässige ich.)
4. Zeitselektiv: Der Sender sendet zu vereinbarten Zeitpunkten. Er
sendet beispielsweise alle 10 Sekunden entweder, daß er eigentlich
nicht zu senden hat, oder daß nun eine Nachricht folgt. Vorteil: Der
Empfänger braucht nur den vereinbarten Zeitpunkten auf Empfang zu
gehen, hat nur dann Störungen abzuarbeiten, und kann sich in
Sendepausen wichtigeren Aufgaben zuwenden.

Hallo Freunde, was gibt's noch?


Ciao
Wolfgang Horn

Autor: Thomas Kreisel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du die Zeit misst, filterst du dann schon zu kleine und große
Impulsbreiten raus?
Dann hast du schon mal die ständigen Nadelimpulse draußen.
Desweiteren am Anfang ein Präambel senden, also z.B. 7 Byte
"10101010", damit sich der Empfänger "einschwingt" und dann ein
Startbyte, z.B. "10101011". Danach kannst du ja dann suchen
(Stichwort: Ringspeicher, FiFo), zudem noch prüfen, ob vorher die
Präambelbytes gesendet wurden und dann erst die folgenden Daten
einlesen. Somit läßt du nur deinen Datenstrom durch.
Empfehlenswert wäre noch ein CRC-Block zur Fehlererkennung oder sogar
Hamming-Code für Fehlerkorrektur.

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Damit kann ich nicht so richtig was anfangen :

1. Frequenzselektiv - je schmalbandiger die Antenne und Vorfilter,
desto weniger Störsignale.
2. Pegelselektiv - der Empfänger tastet erst ab einem minimalen
Empfangspegel auf. Hilft gegen Rauschen und schwache Störer.

Ringspeicher hört sich gut an...den pegel bei Flankenwechsel reinshifen
und gucken wann mein Startwert drinsteht ? ist das so richtig ?

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso mit ringspeicher...dass problem iss dann ja der manchester

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab' als Präambel 3ms lang 0x55 (0b10101010) gesendet, danach 2x
0xFF, während dem 2. 0xFF lässt sich dann ganz easy der USART
zuschalten (Startbit ist low). Nach empfangenem Datenpaket (mit CRC16)
schalte ich den USART wieder ab. Funktioniert sehr zuverlässig.

Autor: Thomas Kreisel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Genau, Interrupt bei Flankenwechsel, Zeitdiffernez prüfen und dann Pegel
abfragen, somit hast du gleich den Manchester decodiert (da ja fallende
oder steigende Flanke detektiert werden muss) und Bit weiterschieben.

Warum is der Manchester dann ein Problem?

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Sonic kannst du mir mal deinen Code Zeigen ???? Irgendwie versteh
ich da nicht wie du den manchester drin hast ?

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welchen meinst du? die CRC-Berechnung oder die Impulsauswertung? Häng'
dir mal die Impulsauswertung im INT0 dran, bezieht sich auf 38400 Baud,
Präambel: 3ms 0x55 und 2x 0xFF.

/*********************************************************************** 
****************/
/*** Externer Interrupt 0 (falling edge)
***********************************************/

SIGNAL (SIG_INTERRUPT0)            // carrier-detect
{
  GICR &= ~(1<<INT0);          // INT0 disabled
  GIFR |= (1<<INT0);            // INT0-Flag löschen
  rx_cnt = 0;                // Empfangsbytezähler löschen
  _delay_ms(2);              // 2ms Pause
  Data = UDR;                // Flag löschen

unsigned char c = 0;

Rep_Strt:
  SREG |= (1<<SREG_I);          // Globalen Interrupt freigeben
  while (!(PIND &(1<<RX_PIN)))
  TCNT0 = 0;
  while ((PIND &(1<<RX_PIN)))        // auf 0xFF warten (234µs 'High')
  Temp = TCNT0;
  if ((Temp >= 210)&&(Temp <=222))
    {
      _delay_us(50);            // 50µs Pause (bis Mitte 2. 0xFF-Byte)
      UCSRB |= (1<<RXEN);              // RX freigeben
      return;
    }
  else
    {
      if (c >= 60)
      {
        PORTD &= ~(1<<RX_EN)&~(1<<TXD);    // RX enabled
        GIFR |= (1<<INT0);          // INT0-Flag löschen
        GICR |= (1<<INT0);          // INT0 enabled
        return;
      }
      c++;
      goto Rep_Strt;              // weiter auf Startbyte warten
    }
}

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bin mal gerade was am zusammenbasteln (proggen) meist du das könnt
efunktionieren ??? schau mal

ISR(SIG_INPUT_CAPTURE1)
{
TCNT1= 0x00;
if( ICR1 < TIMEOUT)
{
level = ((PIND & 0x10)>>4); // 0x10 -> PIN D4
if(ICR1 < TWO_VALUES)// EIN BIT
{
manchester_bits = manchester_bits >> 1; // 1x das lsb rausschiften
manchester_bits.bit_16 = level;    // neues msb reinkopieren
}
else // ZWEI BITS
{
manchester_bits = manchester_bits >> 1; // 2x das lsb rausschiften
manchester_bits.bit_16 = level;    // neues msb reinkopieren
manchester_bits = manchester_bits >> 1;
manchester_bits.bit_16 = level;
}

}
else // vom Timeout
{
 //Abbrechen
 bitcount = 0;
}
}

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Input-Capture misst die Periodendauer, also entweder den Abstand der
high- oder lowflanken, je nach Einstellung. Müsste also funktionieren.
Nur das Ende der Rechteckspannung zu erkenn stelle ich mir schwieriger
vor.
In meinem Code sind auch unfeine Geschichten drin (Warteschleife,
Goto), also nicht so kritisch sein! Ich habe am Transceivermodul einen
Carrier-detect-Ausgang, der wird bei erkanntem Trägersignal low (bei
mir INT0), deshalb ist das Ganze etwas einfacher auszuwerten.

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich invertiere jetzt den Flankentrigger d.h. ich bekomme jeden Pinchange
einen INT

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das geht aber nicht mit dem Input-Capture, da musst du einen
'normalen' Interrupt (1 oder 2) nehmen. Miss doch einfach nur die
Impulse und zähle sie (bei korrekter Breite) mit INT0 oder INT1 'any
edge' getriggert, nach dem letzten Impuls (Ende Präambel) weißt du
dass Daten folgen. Ist glaub' ich weniger Aufwand.

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das habe ich aber schon mal ausprobiert... mit einem Testsignal hat das
toggeln aber geklappt....

hier mein Code muss ich morgen mal testen :

ISR(SIG_INPUT_CAPTURE1)
{
TCNT1= 0x00;          // Timerregister zurücksetzen
TCCR1B ^= _BV(ICES1);     // Triggerflanke invertieren
if( ICR1 < TIMEOUT)
{

// Ringbuffer start
level = ((PIND & 0x10)>>4); // 0x10 -> PIN D4 pegel einlesen

  if(ICR1 < TWO_VALUES)// EIN BIT
  {
   bits.bitfield = bits.bitfield >> 1;   //  lsb rausschiften
   bits.bit_16 = level;  // neues msb reinkopieren
   if(raster_aktiv)  // bitcounter erst hochzählen wenn das protokoll
mit der Startkennung "eingerastet" ist
   bitcount ++;
  }
  else // ZWEI BITS
  {
   bits.bitfield = bits.bitfield >> 1; // 2x das lsb rausschiften
   bits.bit_16 = level;  // neues msb reinkopieren
  if(raster_aktiv)  // bitcounter erst hochzählen wenn das   Protokoll
mit der Startkennung "eingerastet" ist
  bitcount ++;

  bits.bitfield = bits.bitfield >> 1;
  bits.bit_16 = level;
  if(raster_aktiv)
  bitcount ++;
}


if(bits.bitfield == START ) // aktiviere Raster
{
 raster_aktiv = 1;
}
// Ringbuffer stop

// Manchester decodieren d.h. jedes 2te Bit in ein Byte zusammenführen
if( raster_aktiv )
{
  if(bitcount >= 16)
  {
 byte =
((bits.bit_1<<1)|(bits.bit_3<<2)|(bits.bit_5<<3)|(bits.bit_7<<4)|(bits.b 
it_9<<5)|(bits.bit_11<<6)|(bits.bit_13<<7)|(bits.bit_15<<8));

bitcount = 0;
  }
}

if(bits.bitfield == ENDE ) // deaktiviere Raster
{
raster_aktiv = 0;
bitcount = 0 ;
flag_send_data = 1;
TCCR1B &= ~(1<<ICES1); //auf fallende Flanke init.
}

}
else // timeout
{
//Abbrechen
bitcount = 0;
raster_aktiv = 0;
TCCR1B &= ~(1<<ICES1); //auf fallende Flanke init.
}


}

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bitcount darf nur bis 15 laufen sorry

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.