Forum: Analoge Elektronik und Schaltungstechnik 5Ton auswertung mittels Atmega8


von Daniel H. (scretchy)


Lesenswert?

Hallo.
Ich weiß, das Thema gabs schon oft, jedoch komme ich nicht so wirklich 
weiter.

Was ich vorhabe:
Ich möchte mir einen Melder für die Feuerwehr bauen, da ich zurzeit noch 
keinen bekommen kann.

Equipment:
Labornetzteil, Multimeter, STK500, Notebook, Atmega8, 16Mhz Quarz, 5Ton 
Generator

Die 5Tonfolgen werden nach dem ZVEI Standart erstellt.
Kurz Zusammengefasst:
Vorlauf(600ms)|5Töne jeder 70ms lang|Pause(600ms)|5Töne jeder 70ms 
lang|Pause(600ms)

Ton:1|2|3|4|5|6|7|8|9|0|R
Frequenz:1060|1160|1270|1400|1530|1670|1830|2000|2200|2400|2600
Schwingungen in 70ms:74,2|81,2|88,9|98|107,1|116,9|128,1|140|154|168|182

Die Schwingungen pro 70ms habe ich aus der Frequenz berechnet. Sollte 
passen oder?

So stelle ich mir den Code vor.
Die CPU arbeitet mit 16mhz. Ein Timer mit ICP zählt bei Steigender 
Flanke hoch. Aus der Zeit des Timers, wird die Frequenz berrechnet. 
Dieser Frequenz wird ein Ton der 5Ton folge zugeordnet. Entspricht der 
Ton gleich dem letzten, wird zu einer Variable die Zeit eines Tones 
hinzuaddiert. Der 5-Ton 1 dauert z.b. eine Schwingung 0,94ms. Damit der 
TOn 70ms andauert, sollte ich doch ca 74 Schwingungen haben oder? Kommt 
jetzt ein anderer Ton, wird geschaut ob der letzte 70ms lang war. Ist 
dies der Fall gehts weiter, ansonsten wird die Messung abgebrochen.

Ich hoffe es ist euch klar, was ich erreichen will.

Mein versuchsaufbau bis jetzt:
Audioausgang vom Laptop direkt an GND vom STK500 und PB0(ICP) vom 
Atmega8.

Mein Code:
1
#define F_CPU 16000000
2
#include <avr/io.h>
3
#include <stdlib.h>
4
#include <stdint.h>
5
#include <util/delay.h>
6
#include <avr/interrupt.h>
7
8
#define BAUD 9600UL
9
#define UBRR_VAL ((F_CPU + BAUD * 8) / (BAUD * 16) - 1)
10
#define BAUD_REAL (F_CPU / (16 * (UBRR_VAL + 1)))
11
#define BAUD_ERROR ((BAUD_REAL * 1000) / BAUD)
12
 
13
#if ((BAUD_ERROR < 990) || (BAUD_ERROR > 1010))
14
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
15
#endif
16
17
18
void uart_init(void)
19
{
20
  UCSRB |= (1<<TXEN) | (1 << RXEN);  // UART TX einschalten
21
  UCSRC |= (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1 
22
 
23
  UBRRH = UBRR_VAL >> 8;
24
  UBRRL = UBRR_VAL & 0xFF;
25
}
26
27
/* ATmega16 */
28
int uart_putc(unsigned char c)
29
{
30
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
31
    {
32
    }                             
33
 
34
    UDR = c;                      /* sende Zeichen */
35
    return 0;
36
}
37
 
38
 
39
/* puts ist unabhaengig vom Controllertyp */
40
void uart_puts (char *s)
41
{
42
    while (*s)
43
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
44
        uart_putc(*s);
45
        s++;
46
    }
47
  //uart_putc('\n');
48
}
49
50
uint8_t uart_getc(void)
51
{
52
    while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
53
        ;
54
    return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
55
}
56
57
volatile unsigned char NrOverflows = 0; // Anzahl der Timer Overflows die während
58
                                        // der Messung passiert sind
59
volatile unsigned int  StartTime = 0;   // ICR-Wert bei 1.High-Flanke speichern
60
volatile unsigned int  EndTime = 0;     // ICR-Wert bei 2.High-Flanke speichern
61
volatile unsigned int UpdateDisplay = 0;
62
63
ISR( TIMER1_CAPT_vect )
64
{
65
  static unsigned char ErsteFlanke = 1;
66
67
  // Bei der ersten Flanke beginnt die Messung, es wird der momentane
68
  // Timer beim Input Capture als Startwert gesichert
69
  //
70
  if( UpdateDisplay )          // Das Display wurde mit den Ergebnissen der vorhergehenden
71
    return; 
72
73
  if( ErsteFlanke )
74
  {
75
    StartTime = ICR1;
76
    NrOverflows = 0;
77
    ErsteFlanke = 0;       // Die naechste Flanke ist das Ende der Messung
78
  }
79
80
  //
81
  // das ist die zweite Flanke im Messzyklus. Die Messung wird gestoppt
82
  //
83
  else
84
  {
85
    EndTime = ICR1;
86
    UpdateDisplay = 1;      // Eine vollständige Messung. Sie kann ausgewertet werden
87
    ErsteFlanke = 1;        // Bei der naechsten Flanke beginnt der naechste Messzyklus
88
  }
89
}
90
91
92
ISR( TIMER1_OVF_vect )
93
{
94
  NrOverflows++;
95
}
96
97
98
int check(int ton, int tonlaenge)
99
{
100
  int a = 68;
101
  int b = 72;
102
  if((ton == 1) && (tonlaenge > a && tonlaenge < b)) return 1;
103
  else if((ton == 2) && (tonlaenge > a && tonlaenge < b)) return 1;
104
  else if((ton == 3) && (tonlaenge > a && tonlaenge < b)) return 1;
105
  else if((ton == 4) && (tonlaenge > a && tonlaenge < b)) return 1;
106
  else if((ton == 5) && (tonlaenge > a && tonlaenge < b)) return 1;
107
  else if((ton == 6) && (tonlaenge > a && tonlaenge < b)) return 1;
108
  else if((ton == 7) && (tonlaenge > a && tonlaenge < b)) return 1;
109
  else if((ton == 8) && (tonlaenge > a && tonlaenge < b)) return 1;
110
  else if((ton == 9) && (tonlaenge > a && tonlaenge < b)) return 1;
111
  else if((ton == 10) && (tonlaenge > a && tonlaenge < b)) return 1;
112
  else if((ton == 0) && (tonlaenge > a && tonlaenge < b)) return 1;
113
  else return 0;
114
}
115
116
int main(void)
117
{
118
  char s[32];
119
  double Erg = 0.0;
120
  int numbers[5], i, c, x, ton, lastton = 0, tonlaenge = 0;
121
122
  uart_init();
123
124
  DDRC = 0b00000000;
125
126
  TCCR1B = (1<<ICES1)  | (1<<CS10); // Input Capture Edge, kein PreScale
127
   TIMSK = (1<<TICIE1) | (1<<TOIE1); // Interrupts akivieren, Capture + Overflow
128
129
    sei();
130
  
131
132
  for(i = 0; i < 5; i++) numbers[i] = 0;
133
  c = 0;
134
135
  while(1)
136
  {
137
    if(UpdateDisplay)
138
    {
139
      Erg = (NrOverflows * 65536) + EndTime - StartTime;
140
          Erg = F_CPU / Erg;       // f = 1 / t
141
      x = Erg;
142
      
143
      if((x > 1000) && (x < 1110)) ton = 1;
144
      else if((x >= 1110) && (x < 1190)) ton = 2;
145
      else if((x >= 1190) && (x < 1335)) ton = 3;
146
      else if((x >= 1335) && (x < 1475)) ton = 4;
147
      else if((x >= 1475) && (x < 1600)) ton = 5;
148
      else if((x >= 1600) && (x < 1750)) ton = 6;
149
      else if((x >= 1750) && (x < 1915)) ton = 7;
150
      else if((x >= 1915) && (x < 2100)) ton = 8;
151
      else if((x >= 2100) && (x < 2300)) ton = 9;
152
      else if((x >= 2300) && (x < 2500)) ton = 0;
153
      else if((x >= 2500) && (x < 2700)) ton = 10;
154
      else ton = 11;
155
      uart_puts(itoa(ton, s, 10));
156
/*
157
      if(ton < 11)
158
      {
159
        uart_puts(itoa(numbers[i], s, 10));
160
        if(ton == lastton)
161
        {
162
          tonlaenge++;
163
        }
164
        else
165
        {
166
          if(check(lastton, tonlaenge))
167
          {
168
            numbers[c++] = lastton;
169
            lastton = ton;
170
            tonlaenge = 0;
171
172
            if(c == 5)
173
            {
174
              uart_puts("ende");
175
            }
176
          }
177
          else
178
          {
179
            for(i = 0; i < 5; i++) numbers[i] = 0;
180
            c = 0;
181
            lastton = 0;
182
            tonlaenge = 0;
183
          }
184
        }
185
        if(c == 0) numbers[c++] = ton;
186
        else if(numbers[c - 1] != ton)
187
        {
188
          //if(ton == 10) ton = numbers[c - 1];
189
          numbers[c++] = ton;
190
          if(c == 5)
191
          {
192
            for(i = 0; i < 5; i++)
193
            {
194
              if(i && (numbers[i] == 10)) numbers[i] = numbers[i - 1];
195
              uart_puts(itoa(numbers[i], s, 10));
196
            }
197
            c = 0;
198
            uart_puts("ende");
199
            long_delay(200);
200
          }
201
        }
202
      }*/
203
    }
204
    UpdateDisplay = 0;
205
  }
206
  return 0;
207
}
Das ausgeklammerte ignorieren wir jetzt erstmal.

Es funktioniert schon ganz gut. Ich kann halt jetzt mit einem ComPort 
Monitor, wie hterm mein Ergebnis anschauen.
Normalerweise müsste er jede Schwingung ausgeben.


Meine Probleme:
Zwischendrin habe ich mal wieder ein Ton, der nicht reinpasst.
Die anzahl der Schwingungen stimmt auch nicht.
Hier mal ein Ergebnis:
222222222226666666666666666660000000000000000000000000055555555555534444 
4444444
Die Generierte folge war 26054
Die 3 nach den 5en passt nicht. Nach meinen berrechnungen müsste ich 
81,2 Schwingungen von der 2 haben. Hier habe ich aber nur 11. Habe ich 
da einen Denkfehler?

Sollte ich das Signal eventuell aufberreiten? Komparator? Wenn ja, 
welchen könnte ich nehmen?
Habe es mit einer Diode versucht in die Signalleitung, dann kam aber 
leider garnichts mehr an. Dafür müsste ich das Signal wohl verstärken.

Bin um alle Anregungen und Tipps dankbar.

MFG Daniel

von Axel D. (axel_jeromin) Benutzerseite


Lesenswert?

Daniel Hardi schrieb:
> Ich hoffe es ist euch klar, was ich erreichen will.


Ähm, mir nicht.

Soll das Ding Töne erzeugen und an einen Lautsprecher ausgeben, oder 
Impulsfolgen empfangen und auswerten?


Axel

von Marvin S. (demo)


Lesenswert?

Ein FME empfaengt normalerweise nur, deswegen auch FM_E_. ;)

Gruesse

Marvin.

von Achim M. (minifloat)


Lesenswert?

Du bekommst doch während eines Tones mehrere "Auslöser", dass die 
Frequenz erkannt wurde. Die beim Wechsel auftretenden Zahlen lassen sich 
so sehr einfach aus dem Weg räumen, indem du deine Zahlenfolge aus dem 
Test pufferst, bis sagen wir mal mal 5-6 mal ein neuer Ton erkannt 
wurde. Dadurch wird zum Einen z.B. die in deinem kurzen Test störende 
"3" wirksam ausgeblendet und zum anderen ein größerer Störabstand 
erreicht.

Frage meinerseits an dich: Gibt es Tonfolgen, die mehrmals denselben Ton 
hintereinander enthalten?
also z.B. (1400Hz)-(1400Hz)-(1400Hz)-(1060Hz)-(1060Hz)-(600ms Pause)?
Oder enthält die von dir zu erkennende Tonsequenz immer nach jedem Ton 
einen Wechsel?

mf

von Thi L. (flothi)


Lesenswert?

Jo K. schrieb:
> Frage meinerseits an dich: Gibt es Tonfolgen, die mehrmals denselben Ton
> hintereinander enthalten?

Auch wenn ich nicht der OP bin:
Nein, gibt es nicht; wiederholende Ziffern werden mit einem 
Wiederholungston kodiert (vgl. 
http://de.wikipedia.org/wiki/5-Ton-Folge). So wird aus der Sequenz "555" 
ein Tonsignal "1530 - 2600 - 1530".

VG

von Mikrowilli (Gast)


Lesenswert?

Schau mal hier: Beitrag "ZVEI 5-Tonfolge decodieren"

Hier gibt es auch noch etwas: 
home.arcor.de/output/elektronik/5ton-AVR.pdf
(Code ist zwar BASCOM, kann aber nach C portiert werden)

von Daniel H. (scretchy)


Lesenswert?

Hallo.
Eure Fragen habt ihr euch ja gegenseitig beantwortet.
Ja das Gerät dient nur zum Empfangen und auswerten
Wenn ein Ton das zweite mal kommen soll, wird anstatt des Tones das R 
gesendet(2600Hz).

http://home.arcor.de/output/elektronik/5ton-AVR.pdf
Die Seite kenne ich schon. Habe nahe an dem Code entwickelt.
Ich werde das mit dem Durchschnitt in meinen Code reinnehmen, wird denke 
ich bessere Ergebnisse liefern.
Jetzt meine Frage:
Welcher Eingang ist besser geeignet?
Der ICP Pin für steigende Flanken oder der AIN Komperator mit dem AIN1 
gegen Masse und Signal auf AIN0?

MFG Daniel

von Guest (Gast)


Lesenswert?

wäre das nichts für eine FFT?

von Ex-FFW-Mitglied (Gast)


Lesenswert?

> Ich möchte mir einen Melder für die Feuerwehr bauen, da ich zurzeit
> noch keinen bekommen kann.

Dein Vorhaben in aller Ehre, abr so wichtig bist Du nun auch wieder 
nicht...

Und wenn die Gemeinde angeblich kein Geld dafür hat, warum hast Du dann 
Freizeit übrig für die Gemeinde?

von Daniel H. (scretchy)


Lesenswert?

Ex-FFW-Mitglied schrieb:
>> Ich möchte mir einen Melder für die Feuerwehr bauen, da ich zurzeit
>> noch keinen bekommen kann.
>
> Dein Vorhaben in aller Ehre, abr so wichtig bist Du nun auch wieder
> nicht...
>
> Und wenn die Gemeinde angeblich kein Geld dafür hat, warum hast Du dann
> Freizeit übrig für die Gemeinde?

Das hat mich wichtig garnichts zutun. Jedoch wohne ich genau in einem 
Dreieck von Sireenen verschiedener Wehren. In letzter Zeit kam es 
desöfteren vor, dass ich vor verschlossenem Feuerwehrhaus stand. War 
wieder mal ne Sirene von einer anderen Wehr.

Was soll angeblich heißen? Es ist fakt!!!

von Michael 9. (michael93) Benutzerseite


Lesenswert?

Tag,

ich glaub nicht, dass er keinen bekommen kann, weil die Gemeinde kein 
Geld dafür hat. Ich vermute schwer, dass er entweder keine 
Grundausbildung hat, noch nicht Volljährig ist, oder eben beides 
zusammen.

Wenn es so sein sollte: Das mit dem Melder kannst dir sparen, es wird 
dich kein vernünftiger Gruppenführer sofort mitnehmen, höchstens als 
Ersatz oder bei ungefährlichen Dingen.

Nun wieder OnTopic: Den Code vom Martin hab ich in C fast 1:1 
nachprogrammiert. Erste Tests (mit Sound vom Rechner mit Rauschen 
simuliert, etc) waren ziemlich erfolgreich.

Grüße,
Michael

von FMEler (Gast)


Lesenswert?

Michael 93 schrieb:
> Nun wieder OnTopic: Den Code vom Martin hab ich in C fast 1:1
> nachprogrammiert. Erste Tests (mit Sound vom Rechner mit Rauschen
> simuliert, etc) waren ziemlich erfolgreich.

Möchtest du den Code vielleicht publizieren? Kämpfe gerade mit der 
FFT-Routine rum und würde das gerne vergleichen.

vg

von Mr. K. (kaktus-)


Lesenswert?

if((x > 1000) && (x < 1110)) ton = 1;
      else if((x >= 1110) && (x < 1190)) ton = 2;
      else if((x >= 1190) && (x < 1335)) ton = 3;
      else if((x >= 1335) && (x < 1475)) ton = 4;
      else if((x >= 1475) && (x < 1600)) ton = 5;
      else if((x >= 1600) && (x < 1750)) ton = 6;
      else if((x >= 1750) && (x < 1915)) ton = 7;
      else if((x >= 1915) && (x < 2100)) ton = 8;
      else if((x >= 2100) && (x < 2300)) ton = 9;
      else if((x >= 2300) && (x < 2500)) ton = 0;
      else if((x >= 2500) && (x < 2700)) ton = 10;


Ich würde die Erkennungsgrenzen kleiner machen, dann sollte es gehen.

+-50 Hz sollten reichen

von Thorsten S. (Gast)


Lesenswert?

hilft evtl. das datenblatt vom mt8870 weiter?

von Mr. K. (kaktus-)


Lesenswert?

Thorsten S. schrieb:
> hilft evtl. das datenblatt vom mt8870 weiter?
5TON ist kein DTMF

http://de.wikipedia.org/wiki/5-Ton-Folge

von Martin (Gast)


Lesenswert?

Gibt es eine praxisnahe .WAV-Datei zum Testen?

von Thi L. (flothi)


Lesenswert?


von Thi L. (flothi)


Lesenswert?

Mr Kaktus schrieb:
> Ich würde die Erkennungsgrenzen kleiner machen, dann sollte es gehen.
>
> +-50 Hz sollten reichen

Sorry für Doppelpost:

Grenzen gem. TR-BOS:
Die größte Abweichung der Töne von Sollwert darf

bei normalen Betriebsbedingungen (A 13.1) max. = 0,5 %,
bei extremen Betriebsbedingungen (A 13.2) max. = 1    % betragen.


VG

von eProfi (Gast)


Lesenswert?

Nimm einen Goertzelfilter, dann klappt es auch noch, wenn das Signal 
rauscht.
Der wird zwar häufig für DTFM empfohlen (weil er auch mehrere Töne 
gleichzeitig erkennen kann), funktioniert bei 5Ton aber genau so gut.

von Daniel H. (scretchy)


Lesenswert?

Michael 93 schrieb:
> Tag,
>
> ich glaub nicht, dass er keinen bekommen kann, weil die Gemeinde kein
> Geld dafür hat. Ich vermute schwer, dass er entweder keine
> Grundausbildung hat, noch nicht Volljährig ist, oder eben beides
> zusammen.
>
> Wenn es so sein sollte: Das mit dem Melder kannst dir sparen, es wird
> dich kein vernünftiger Gruppenführer sofort mitnehmen, höchstens als
> Ersatz oder bei ungefährlichen Dingen.
>

Das ihr immer so aus der Ferne wisst, was sache ist das verwundert mich.
1. Ich bin seid 4 Jahren der Feuerwehr.
2. Grundausbildung habe ich sehr wohl.
3. Zusätzlich habe ich Funker und AGT.
4. Ich bin bei fast jedem Einsatz auf dem Auto.

Jeder Wehr ist eine Anzahl Melder zugeordnet. Mehr gibt es nicht!
Und was tut das hier überhaupt zur sache? Garnichts!

von Stefan P. (Gast)


Lesenswert?

Hi,
ist selber kaufen dann nicht einfacher bevor du dir selber was baust? 
Der ist dann auch Tragbar ;-) und die gebrauchten werden dir teilweise 
hinter her geschmissen.
OK reizen würds mich auch mal sowas selber zu bauen. Aber warum tut eure 
Wehr nicht noch n paar FME her. Müssen ja keine neuen sein, tun doch 
auch gebrauchte. Wir sind inzwischen schon dazu übergegangen bewust 
leuten die sich selber schon einen kaufen wollten, dann doch einen zu 
spendieren mit dem Hintergrund -> irgendwann in weiter Ferne die ich mit 
meinen 25J vielleicht gar nimmer erleben werde, wird/soll von analog auf 
digital umgebaut (Bayern). Je mehr Melder die Gemeinde besitzt, um so 
einfacher wird die Ersatzbeschaffung.

Kameradschaftliche Grüße
Stefan

von Mr. K. (kaktus-)


Lesenswert?

Select Case Durchschnitt
Case 1050 To 1070 : Ton = "1"
Case 1150 To 1170 : Ton = "2"
Case 1260 To 1280 : Ton = "3"
Case 1390 To 1410 : Ton = "4"
Case 1520 To 1540 : Ton = "5"
Case 1660 To 1680 : Ton = "6"
Case 1820 To 1840 : Ton = "7"
Case 1990 To 2010 : Ton = "8"
Case 2190 To 2210 : Ton = "9"
Case 2390 To 2410 : Ton = "0"
Case 2590 To 2610 : Ton = "w"
Case Else : Goto Main
End Select

Im Bascom Quelltext werden die +-1 % in etwa eingehalten, das könnte 
dein Problem sein.

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.