Forum: Mikrocontroller und Digitale Elektronik SoftUart + RFID Tag filtern


von Lars L. (lars_l)


Lesenswert?

Moin,


ich bin gerade dabei in einen Atmega16 ModbusSlave einen RFID leser zu 
intierieren...es klappt auch soweit der Master empfängt auch den RFID 
Tag, nur habe ich sehr viele fehl lesungen.


Ich habe die Vermutung das der SoftUart das Problem ist da dieser ja 
keinen Buffer hat oder??

Also unterbricht er die lesungen wenn mein Timer0 kommt? Richtig?

Sehe ich das Richtig?




Lars
von Lars L. (lars_l)


Lesenswert?

Ahso oder Code
1
Dim Serial_in As Byte
2
Dim I As Byte
3
Dim Bytes As Byte
4
Dim Rfid_data(40) As Byte
5
Dim Data_d(40) As Byte
6
Dim Send_d(20) As Byte
7
Dim Quit As Byte
8
Dim New As Word
9
Dim Index As Word
10
Dim Tick5s As Boolean
11
12
Open "comb.1:4800,8,n,1" For Input As #2
13
14
15
Do
16
17
If New = 0 Then                                             'lesen wenn new = 0
18
   New = 0
19
20
   Serial_in = Inkey(#2)
21
   If Serial_in > 0 And Serial_in < 127 Then                'If there are Data, read it !
22
      Incr Bytes
23
      Rfid_data(bytes) = Serial_in
24
   End If
25
26
   If Bytes > 20 Then                                       'When all 11 Bytes read then print it over Serial output.
27
28
    I = 0                                                   'Zähler auf 0
29
30
      For Index = 1 To 40                                   'Array kopieren
31
         Data_d(index) = Rfid_data(index)
32
      Next Index
33
34
      Do                                                    'Schleife 32 ( SP ) finden
35
36
       If Data_d(i) = 32 Then
37
38
            Send_d(1) = Data_d(i + 1)                       'Daten Felder aus dem RFID
39
            Send_d(2) = Data_d(i + 2)
40
            Send_d(3) = Data_d(i + 3)
41
            Send_d(4) = Data_d(i + 4)
42
            Send_d(5) = Data_d(i + 5)
43
            Send_d(6) = Data_d(i + 6)
44
            Send_d(7) = Data_d(i + 7)
45
            Send_d(8) = Data_d(i + 8)
46
            Send_d(9) = Data_d(i + 9)
47
            Send_d(10) = Data_d(i + 10)
48
49
            New = 1                                         ' neuer RFID gelesen
50
51
            Bytes = 0                                       'Reset bytes
52
            Exit Do
53
       Else
54
       I = I + 1                                            'Schleife Hochzählen
55
       End If
56
57
      Loop
58
59
   End If
60
61
End If
von Lars L. (lars_l)


Lesenswert?

Mhh kann mir da keiner ne Tip geben ob das das evtl das Problem sein 
könnte?
von Krapao (Gast)


Lesenswert?

Die folgende Stelle halte ich für einen Fehler, weil beim ersten 
Durchlauf der inneren DO-Schleife auf Data_d(0) zugegriffen wird:
>      I = 0 'Zähler auf 0
>      ...
>      Do 'Schleife 32 ( SP ) finden
>        If Data_d(i) = 32 Then

Die folgende Stelle kommt mir spanisch vor, weil ich nicht erkenne, 
warum du New auf 0 setzt, wenn eine Zeile vorher fest steht, dass New = 
0 ist.
>  If New = 0 Then
>    New = 0

Und da passt irgendwie der Kommentar nicht zum Code 20 <> 11
> If Bytes > 20 Then 'When all 11 Bytes read
>                    'then print it over Serial output.
Und dann wenn 11 oder 20 Zeichen da sind, werden in der FOR-Schleife 40 
kopiert, hmm...

Ich sehe auch die Stelle nicht an der du jetzt den "print it over Serial 
output" machst.

Musst du eigentlich die Eingangsdaten zweimal umkopieren? Das kostet 
auch Zeit und Speicher!

Weisst du, dass du bei den Feldgrenzen oft ohne Netz und doppelten Boden 
arbeitest, d.h. keine Überwachung vorhanden ist, ob Feldgrenzen 
eingehalten werden?

Beispiel in der inneren DO-Schleife kann es vorkommen, dass weit über 
die 40 DIMensionierten (geschweige denn tatsächlich eingelesenen) 
Zeichen von Data_d(40) hinaus nach einem Leerzeichen gesucht wird und 
dann irgendwas aus dem Speicher den If-Fall triggert und dann irgendwas 
aus dem Speicher kopiert und ausgegeben wird.

Das Programm ist auch nicht vollständig. Z.B. fehlt der Endcode zu der 
äußeren DO-Schleife. Möglicherweise kommt noch Code der ausgeführt wird, 
wenn New = 1 ist? Dort könnte auch die Problemursache stecken...

Kurze Rede langer Sinn - Zum Umzingeln der Fehlerursache würde ich ein 
einfacheres Programm schreiben.

Jedes per Inkey(#2) eingelesene RFID Byte sofort per PRINT über die 
Hardware UART ausgeben.

Besser noch - falls ein Logikanalysator vorhanden ist - das RFID-Byte 
auf einen Port ausgeben und das inkl. Timing protokollieren. Dann ist 
fast nur noch die SoftUART zum Einlesen vorhanden.

Anderer Weg - falls die RFID-Sequenz bekannt und immer gleich sein 
sollte, kannst du auch von der empfangenen Sequenz eine "Prüfsumme" 
berechnen und mit der richtigen Prüfsumme vergleichen. Dann z.B. 
entweder eine grüne oder rote LED ansteuern.
von Lars L. (lars_l)


Lesenswert?

Ja okay danke...ja das nicht das ganze Programm...der teil steckt mitten 
drin in dem ModbusSlave programm.....also so blanke gehts eigendlich nur 
in dem slave...


Hab das etwas schnell zusammen geschustert :-D

Also es gibt einen Timer0 der gestartet mir wenn ein Modbus Request 
kommt...kann es sein das der mir denn Software Uart durcheinander 
bringt?
von Krapao (Gast)


Lesenswert?

Leider weiss ich zu wenig von den BASCOM Interna zur SoftUART.

Bei 4800 Baud liegt (bei 0/1 Symbolen wie hier) ein Bit 1000/4800 ms = 
203 µs an einem Pin an.

Läuft die Timer0 ISR so lange, dass ein oder mehrere Bits verloren gehen 
können? Was treibt der Timer0?
von Lars L. (lars_l)


Lesenswert?

Der Timer wir gestartet wenn über den Uart(Hardware) ein Request kommt 
und nach 1,5ms Ruft der die Modbusauswertung aus....

Nagut die SPS Pollt natürlich immer hintereinander....

Mh ja der RFID Tag is ja 10 Bytes lang + 2 mal Leer
von Krapao (Gast)


Lesenswert?

Sorry ich verstehe das so nicht, anders als du bin ich nicht in deinem 
Projekt drin.

Deine Zeitvorgaben im Programm sind:

1) ISRs von Interrupts (Timer) dürfen nicht länger dauern als das Pollen 
eines Bits der Software UART. Wenn sie länger dauern, geht dir der 
Bitzustand bei der Software UART verloren und die kommt aus dem Tritt, 
d.h. es kommen falsche Zeichen.

2) Die Inkey() Funktion muss so regelmäßig aufgerufen werden, dass keine 
kompletten Zeichen verloren gehen, weil der Empfangspuffer voll ist. Ich 
weiss nicht, wie viele Zeichen die Software UART puffern kann. Bei der 
Hardware UART kann man das ja CONFIGurieren. Ich "hasse" die BASCOM Doku 
;-)
von Krapao (Gast)


Lesenswert?

Muss jetzt in die Falle.
von Lars L. (lars_l)


Lesenswert?

Mhhh also es scheint an dem Interrupt des Timer0 zu liegen......da wenn 
ich das Kontinuirliche lesen des Masters deaktiviere, dann einen RFID 
lesen und denn den Master wieder lesen lasse kommen die Richtigen werte 
rein....

Wie könnte ich das denn lösen? Leider hat der Atmega16 ja nur ein 
Hardware Uart...
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.