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
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 |
Mhh kann mir da keiner ne Tip geben ob das das evtl das Problem sein könnte?
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.
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?
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?
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
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 ;-)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.