Forum: Mikrocontroller und Digitale Elektronik Störungen mit Funkmodulen


von Andreas (Gast)


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 ?

von Wolfgang Horn (Gast)


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

von Thomas Kreisel (Gast)


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.

von Andreas (Gast)


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 ?

von Andreas (Gast)


Lesenswert?

Achso mit ringspeicher...dass problem iss dann ja der manchester

von Sonic (Gast)


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.

von Thomas Kreisel (Gast)


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?

von Andreas (Gast)


Lesenswert?

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

von Sonic (Gast)


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
    }
}

von Andreas (Gast)


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;
}
}

von Sonic (Gast)


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.

von Andreas (Gast)


Lesenswert?

ich invertiere jetzt den Flankentrigger d.h. ich bekomme jeden Pinchange
einen INT

von Sonic (Gast)


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.

von Andreas (Gast)


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.
}


}

von Andreas (Gast)


Lesenswert?

bitcount darf nur bis 15 laufen sorry

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.