PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Master Slave Verbindung mit AVR2313 und 485-Bustreibern ?



Juergen151
27.08.2009, 21:52
Hallo zusammen,

bin gerade dabei ein 485-Bussystem bei mir aufzubauen (siehe Tiffs und Bas-Dateien im Anhang), der Controller-Aufbau funktioniert auch den ich hab bereits mit einem Lauflicht-Programm die Funktion getestet.

Wenn ich aber die Aktor und Sensorsoftware einspiele wie im Anhang geht im Moment nichts. Ich versteh auch nicht ganz wie das Ganze funktioniert also der Aktor hört in die Leitung und reagiert wenn eine passende Zeichenkette empfangen wird ?

Beim Sensor hab ich an Pin13 PB1 einen Taster angeschlossen der die Masse durchschaltet. Beim Aktor hab ich an Pin13 PB1 eine Leuchtdiode
angeschlossen gegen +5V, diese geht auch mittels Lauflicht-Programm
getestet.

Bei beiden Controllern ist das FuseBit über Bascom auf External gesetzt,
2xWiderstände 120Ohm Kabelanfang und Ende + 1x 4,7k gegen GBD + VCC an den Buskanälen A / B.

Wenn ich mittels Multimeter auf dem Bus messe tut sich auch was beim Taster drücken, es wird wohl schon etwas gesendet aber wohl nicht das Richtige !

Bei der Befehlsstelle versteh ich nicht ganz welche Kombination an den Dipschaltern eingestellt werden muß, PD6 Pin11 hat kein Potential wenn ich messe somit kann er auch nichts über die Dipschalter weitergeben (deshalb hab ich den Taster mal auf Masse gelegt).

Dann ist da noch ein Anschluß PD5 Pin9 K1 weiß nicht welche Funktion das hat sollen nun +5V draufgeschaltet werden oder nicht ?

Bei der Software sieht es so aus als ob etwas gesendet und dieses dann noch mal bestätigt wird, der Ablauf scheint mir etwas sehr kompliziert.

Würde es nicht reichen ich stelle den einen Controller fest auf Empfang und den anderen fest auf senden und schicke nur einen Buchstaben und sage dann höre in den Bus hinein wenn String A kommt schalte Port PB0 auf high, wenn noch einmal String A kommt schalte Port PB0 wieder auf low, und selbes wenn String B kommt dann Port PB1, String C Port PB2 usw. Ein ganz einfacher Code wenn möglich.

Die Schwierigkeit im Moment liegt bei der Software die vom Sensor zum Aktor wohl nicht ganz zusammen passt, bzw. mir die Funktion nicht ganz klar ist.

Könntet Ihr mir da noch mal auf die Sprünge helfen und kurz darüber schauen wie die Software zusammenpasst, die Funktion sollte so sein das bei Tastendruck am Eingang Pin13 PB1/Sensor am Ausgang Pin13 PB1/Aktor dieser an geht, beim nächsten Tastendruck aus, dies für alle Ein/Ausgänge des Ports gleich.

Schon mal vielen Dank im Vorraus !

Gruß, Jürgen

Vitis
27.08.2009, 22:34
Bei den BC107A fehlt am Emitter der GND-Kontakt,
die Relais haben keine Freilaufdioden ...
Der Tiny und auch der Max haben nah an den VCC-Anschlüssen gern nochmal
100nF Stützkondis, am 7805 sieht man auch gern ne Rückwärtsdiode parallel zum
78er, ne Schutzdiode zum Verpolungsschutz gefällt auch immer :)

soweit zur Hardware ...

zur Software ... sorry, die ist grausam ...
Goto ohne Ende ... da stelle nsich mir die Haare zu Berge ...
Schau mal in der Bascom Hilfe nach Gosub - Return ...
Dann die Programmverzweigungen ... brrrrrrrrrr
Was den max485 angeht, das kann man unter bascom schön elegant
lösen über config print, dann kann man sich die manuelle Umschaltung schenken
(zumindst im Code)
Das Problem bei Deinem Protokoll wird sein, dass Du nach den Print-Befehlen
zu kurz wartest bevor du umschaltest, da Du das TXC-Flag nicht verwendest
wird Dein letztes Zeichen abgeschnitten.

Select - Case würde sich für Deine erste Verzweigung im Bett_t-Code anbieten ...

In deinem Rolladen.bas fehlt vermutlich ein .... brrrr, mich schüttelts ... goto main hinter deiner Pruefung: - Routine

Juergen151
28.08.2009, 08:25
Hallo Vitis,

Danke für die Hinweise, den Hardware/ Software-Vorschlag hab ich übers Internet von jemanden bekommen, man muß wohl doch noch einiges tun damit es läuft.

Etwas Programmiererfahrung hab ich schon, evt. wurden mir schon ein paar Codeschnipsel in Bascom zur Ansteuerung der 485-Treiber reichen um es selbst hin zu bekommen.

Bisher hab ich bei mir eine Siemens-Logo mit 8xAusgängen im Einsatz, nun gibts aber einige Stellen bei mir im Haus wo ich noch gerne ein paar Schaltstellen hätte, die beste Lösung wäre über dieses einfache 485-Bussystem, nur schade das die AVR 2313 nicht so leicht zu programmieren sind wie die Logo, dann wäre ich schon fertig !

Mfg Jürgen

Vitis
29.08.2009, 18:21
Bascom Hilfe:

CONFIG PRINT
Top Previous Next
Action

Configure the UART to be used for RS-485


Syntax

CONFIG PRINT0 = pin

CONFIG PRINT1 = pin

Remarks

pin
The name of the PORT pin that is used to control the direction of an RS-485 driver.

mode
SET or RESET

Use PRINT or PRINT0 for the first serial port. Use PRINT1 for the second serial port.

When you use RS-485 half duplex communication you need a pin for the direction of the data. The CONFIG PRINT automates the manual setting/resetting. It will either SET or RESET the logic level of the specified pin before data is printed with the BASCOM print routines. After the data is sent, it will inverse the pin so it goes into receive mode.

You need to set the direction of the used pin to output mode yourself.


See also

CONFIG PRINTBIN




Example

'------------------------------------------------------------------------------

'name : rs485.bas

'copyright : (c) 1995-2006, MCS Electronics

'purpose : demonstrates

'micro : Mega48

'suited for demo : yes

'commercial addon needed : no

'------------------------------------------------------------------------------

$regfile = "m48def.dat" ' we use the M48

$crystal = 8000000

$baud = 19200



$hwstack = 32

$swstack = 32

$framesize = 32



Config Print0 = Portb.0 , Mode = Set

Config Pinb.0 = Output 'set the direction yourself



Dim Resp As String * 10

Do

Print "test message"

Input Resp ' get response

Loop




in den Plänen hab ich auch mal rumgepinselt ... siehe Anhang

Juergen151
29.08.2009, 19:08
Hallo Vitis,

ich hab vorher selber mal getestet, klappt aber noch nicht so recht, und hab versucht den Code zu vereinfachen:

'Sensor


$regfile = "attiny2313.dat"
$crystal = 3579545
$baud = 4800
Portb = &B11111111
Portd = &B1100000 'PullUp

Main:
Portd.2 = 1 '485 auf senden
Waitms 10
Do
If Pinb.0 = 0 Then
Goto 2
Elseif Pinb.1 = 0 Then
Goto 2
Elseif Pinb.2 = 0 Then
Goto 2
Elseif Pinb.3 = 0 Then
Goto 2
Elseif Pinb.4 = 0 Then
Goto 2
Elseif Pinb.5 = 0 Then
Goto 2
Elseif Pinb.6 = 0 Then
Goto 2
Elseif Pinb.7 = 0 Then
Goto 2
End If

Loop

1:

Goto Main


2:
Waitms 10
Print "100" ' oder print ? Chr(udr)
Goto Main





'Aktor Einfacher String-Empfang
$regfile = "attiny2313.dat"
$crystal = 3579545
$baud = 4800

Dim S As String * 7
Dim A As String * 4
Dim X1 As Boolean
Dim X2 As Boolean
Dim X3 As Boolean
Dim X4 As Boolean
Dim Z As String * 1


On Urxc Onrxd
Enable Urxc
Enable Interrupts


Main:
S = ""
Goto Auswerter
Goto Main



Onrxd:
S = Chr(udr) ' Wird hier das Zeichen empfangen ?
Return



Auswerter:

If S = "100" Then

Portb.1 = 1 '1 für high

End If

S = ""

Goto Main



Was ich nicht verstehe ist wie der Aktor die Zeichenkette empfängt ?

Danke für die Hinweise in der Bascom-Hilfe, schau ich mir dann an ! (der Anhang von Dir fehlt glaub ich )

Mfg, Jürgen

Vitis
30.08.2009, 16:17
Siemens Logo wird nicht programmiert, bestenfalls fast and dirty zusammengeschustert ... mit programmierung hat das nicht viel zu tun, zumindest nicht mit AVRs, die sind nmämlich ungleich mächtiger und auch felxibler einsetzbar. Das hat aber halt den Nachteil, dass man sich für die Programmierung mehr Zeit lassen muss und sich mit der Programmierung auch mehr auseinander setzen muss, damit das auch zuverlässig funktioniert.
Der erste Tip ... verabschiede dich von GOTO ... es gibt nur sehr sehr wenige Fälle, in denen Goto sinnvoll eingesetzt werden kann und sollte.
Für den Unterprogramm - Aufruf gibts Gosub und Return, bzw. Call.
Dann gibts da auch schöne Übergabe-Parameter, die sich, sinnvoll verwendet, deutlich auf die Codegröße und somit auf die Ausführungsgeschwindigkeiten auswirken.
Das nächste ist, lad dir mal das Datenblatt des verwendeten Bausteins runter auf die Platte. Das kann viele Unklarheiten schnell aufklären. Z.B. was ist UDR ... im PDF gesucht sieht man sofort, USART Data Register.
Dann überleg Dir mal ein systematisches Protokoll, das man auch "automatisieren" kann ... "!BA1" bis "!CC3" hat kein logisches System ...
einfacher wärs "!set1", "!set2", "!set3", etc. das kann man dann schön auf pinb.0, pinb.1 etc. beziehen und man kann mit 1/10 Code arbeiten.

> Was ich nicht verstehe ist wie der Aktor die Zeichenkette empfängt ?

tja, das ist auch etwas konfus zu erklären ... urxc ist der interrupt, der bei empfangenem zeichen ausgelöst wird. der Haken ist, du liest das UDR-Register aus, das hat aber nur EINEN Wert, keinen String, sondern ein ASCII Zeichen. Dann wandelst DU diesesn Zeichenwert in einen String um mit CHR (Character). Das bedeutet, Du hat als String (S) ein Zeichen, keine Zeichenkette ... Da Du aber die Zeichen nicht anreihst wird die Zeichenkette 100 (3 Zeichen) nie erreicht.


Der Anhang ist dran, als zip-File, musst aber eingeloggt sein um den ziehen zu können.

Juergen151
05.09.2009, 19:46
Hallo Vitis,

Deine Meinung zur Logo kann ich so nicht ganz teilen, da werden teilweise schon sehr große Maschinen mit gesteuert.

Bei meinem 485-Bus geht nichts im Moment, ich werde nachher mal den Hardwareaufbau zum 485-Baustein hin prüfen, es muß wohl was grundlegendes falsch sein da andere Programme auf den Controllern laufen.

Gibts eigentlich eine einfache Methode (Prog-Einzeiler, ohne Interuppt usw.) um etwas auf den Bus zu senden und gleichzeitig ein einfache Methode für den Empfang, um festzustellen ob überhaupt was drüber geht ?

Gruß, Jürgen

Vitis
06.09.2009, 12:08
Die Programmierbaren Eigenschaften der Logo sind im Vergleich
sehr begrenzt ... also im Vergleich zum ATTiny oder ATMega.
Der Vorteil der Logo ist, man nimmt das Ding, pappts auf die
Hutschiene und hat ne große Menge an Sorgen aus dem Kreuz.
Spannungsversorgung, Schaltkontakte etc.. Es ist ne kleine
SPS ... und das ne Maschine groß ist bedeutet nicht, dass sie
viel "Hirn" braucht ...
Ich hab hier große Maschinen im Betrieb die werden per
Zeitschalter und Schützschaltung gesteuert ... ziemlich "dummes"
Zeug, aber es funzt.
Der AVR kann jedes Ereignis mit praktisch jeder Aktion verbinden,
was die Anwendung sehr viel komplexer gestaltet, das sieht man
schon am Befehlssatz der verwendeten Sprache, der deutlich
umfangreicher ist als der der Logo.
Hab mit beidem gearbeitet, die Logo nehm ich wenns robust sein soll,
wenig Zeit bleibt und die Aufgabenstellung weniger komplex ist.


was den Einzeiler angeht, so hatte ich DIr doch den Auszug aus der Bascom Hilfe gepostet.
erst per config Print den Steuerpin deines 485-Busbeuasteins definieren und dann aeinfach per Print auf den Bus schreiben, das ist alles.
auf der Gegenseite kannst Du einfach per waitkey() eingehende Zeichen empfangen und dann irgendwie darstellen.
z.B. als Schaltzustand auf nem Port, z.B.
Porta=waitkey()
oder als Echo, natürlich dann auch den Schaltpin festlegen:
dima as byte

do

a=waitkey()
printbin a

loop

einfacher gehts nicht.
Um den Bus selbst zu debuggen kann ich nur zum Oszilloskop raten,
mit dem Multimeter wird das nix richtiges.

screwdriver
06.09.2009, 18:11
...
a=waitkey()
printbin a
...
einfacher gehts nicht.


Vorsicht, PRINTBIN unterstützt die automatische Sende/Empfangs-Umschaltung nicht, wie im Anhang zu sehen ist.

MFG
Screwdriver

Juergen151
06.09.2009, 22:52
Hallo Vitis,

Danke für die Tipps, eine Art der Übertragung funktioniert jetzt schon, man kann den Port schalten, jedoch überträgt der Sensor Zeichen solange man den Taster drückt und der Aktor bringt diese auch so auf den Port.

Wie es geht hab ich bisher nicht verstanden, ich sende ja nur eine 1 und diese wird auf Port B übertragen, meine Ausgangs-Led ist aber an Port B.1 angeschlossen die 1 kann aber eigentlich nur Port B.0 ansteuern ?? Rutschen die da irgendwie durch ?

'Sensor
$regfile = "attiny2313.dat"
$crystal = 3579545
$baud = 4800
Portb = &B11111111

Config Portd = Output

Do

Portd.2 = 1

If Pinb.1 = 0 Then
Waitms 5
Print "1"
Waitms 5
Portd.2 = 0
Waitms 5
End If

Loop



'Aktor
$regfile = "attiny2313.dat"
$crystal = 3579545
$baud = 4800

Config Portb = Output
Dim S As String * 5

Portd.2 = 0

Do

Portb = Waitkey()

Loop


Trotzdem versteh ich nicht ganz warum die anderen Versuche gar nicht liefen, an der Hardware hab ich auch was geändert, die Pullup-Wiederstände zu GND und VSS am Bus hab ich entfernt, der LTC 485 scheint ohne besser zu laufen vielleicht lags auch daran.

Mfg Jürgen

Juergen151
13.09.2009, 16:15
Hallo,

ich hab noch ein bischen getestet und man kann jetzt einen Port über den Bus wunderbar schalten:

'Sensor
$regfile = "attiny2313.dat"
$crystal = 3579545
$baud = 4800
Portb = &B11111111

Config Portd = Output

Config Debounce = 100
Set Portb.1

Do
Debounce Pinb.1 , 0 , Schalter , Sub
Loop

Schalter:

Portd.2 = 1
Waitms 10
Print "111"
Waitms 10
Portd.2 = 0
'Waitms 10

Return

End



'Aktor
$regfile = "attiny2313.dat"
$crystal = 3579545
$baud = 4800

Config Portb = Output
Dim Empfangen As String * 3

On Urxc Onrxd
Enable Urxc
Enable Interrupts

Portd.2 = 0

Do
If Len(empfangen) > 2 Then 'wenn mehr als 2 Zeichen empfangen

'If Empfangen = "111" Then

Waitms 200
Toggle Portb.1

Empfangen = "" 'löschen

'End if
End If
Loop
End

Onrxd:
Empfangen = Empfangen + Chr(udr)
Return


Ein gewisses Problem scheint es trotzdem noch zu geben, ich würde gerne statt If Len(empfangen) > 2 Then (also mehr als 2 Zeichen empfangen) lieber 'If Empfangen = "111" Then verwenden, aber der Wert von Empfangen scheint nicht gleich zu sein obwohl so gesendet.

Möglicherweise ein Formatproblem das evt. von ASCII auf String gewandelt werden muß ?

Was ich auch noch vermute das die Zeichen nicht sauber gesendet wird, der Sendepuffer beim Sensor noch irgendwelchen Schrott mitsendet ?
Wie kann man den Sendepuffer löschen bevor ich meine Zeichen übertrage ?

Mfg, Jürgen

Juergen151
19.09.2009, 21:41
Hallo,

ich hab jetzt den Code noch mal komplett überarbeitet
und es funktioniert, allerdings nur bei sehr kurzer Leitung, bei langer
Leitung nicht.

Sind die 485 LTCs empfindlich also ich hab die 120 Ohm an beiden Enden +
jeweils 4,7k einmal gegen + und GND sollte doch gehen.

Was müßte man am Code ändern um die Sende - Empfangsqualität zu verbessern ?

Mfg Jürgen

'Sensor
$regfile = "attiny2313.dat"
$crystal = 3579545
$baud = 4800
Portb = &B11111111

Config Print = Portd.2 , Mode = Set
Config Pind.2 = Output

Config Debounce = 70
Set Portb.1

Do
Debounce Pinb.0 , 0 , Schalter1 , Sub
Debounce Pinb.1 , 0 , Schalter2 , Sub
Loop

Schalter1:
Waitms 30
Print "!10"
Waitms 30
Return

Schalter2:
Waitms 30
Print "!11"
Waitms 30
Return

End



'Aktor
$regfile = "attiny2313.dat"
$crystal = 3579545
$baud = 4800

Config Portb = Output
Dim A As String * 3
Dim Z As String * 1
Dim B As String * 3

On Urxc Onrxd
Enable Urxc
Enable Interrupts

Portd.2 = 0

Do
If Len(a) > 2 Then
B = A
Z = Mid(a , 1 , 1 )
If Z = "!" Then
B = Mid(a , 1 , 3)
If B = "!10" Then

Toggle Portb.0
A = ""

Elseif B = "!11" Then

Toggle Portb.1
A = ""

End If
End If
End If

Waitms 100

Loop
End

Onrxd:
A = A + Chr(udr)
Return

Vitis
20.09.2009, 18:45
4800 baud ist nicht viel, daran hängts bestimmt nicht.
kann an der Außenbeschaltung der 485 Bausteine hängen ...
dreh die Pullup-Pulldown mal andersrum, möglich das Du die
vertauscht hast.

dann noch:
Print "!10"

Du sendest so automatisch nicht nur 3, sondern 5 Zeichen, nämlich als
Abschluss CR + LF, also im ASCII-Code das Zeichen 10 und 13.
Durch Ergänzung eines Semikolons am Ende kann man das unterdrücken.

Print "!10";

PicNick
21.09.2009, 07:58
Männer, hier spricht euer mod.

Nehmt doch bitte "code"-Tags. Das wird ja total unübersichtlich, ausserdem sieht Source-Code im Autoformat sehr bescheiden aus.

Juergen151
10.10.2009, 09:22
Hallo,

es läuft jetzt perfekt hier nun mein finaler Code, die wichtigen Punkte sind:

- Config Print verwenden

- print mit Strichpunkt hinten damit nur das wirkliche Zeichen gesendet wird

- Config Serialin = Buffered verwenden, da kommt es sehr auf die richtige Einstellung an

- Als Byte empfangen mit Inkey + Ischarwaiting

- und sehr viel Geduld !!




'Sensor
$regfile = "attiny2313.dat"
$crystal = 3579545
$baud = 4800
Portb = &B11111111

$hwstack = 32
$swstack = 10
$framesize = 40

Config Print = Portd.2 , Mode = Set
Config Pind.2 = Output

Config Debounce = 30

Waitms 300


Do
Debounce Pinb.0 , 0 , Schalter1 , Sub
Debounce Pinb.1 , 0 , Schalter2 , Sub
Debounce Pinb.2 , 0 , Schalter3 , Sub
Debounce Pinb.3 , 0 , Schalter4 , Sub
Debounce Pinb.4 , 0 , Schalter5 , Sub
Debounce Pinb.5 , 0 , Schalter6 , Sub
Debounce Pinb.6 , 0 , Schalter7 , Sub
Debounce Pinb.7 , 0 , Schalter8 , Sub
Loop


Schalter1:
Print "!10";
Return

Schalter2:
Print "!11";
Return

Schalter3:
Print "!12";
Return

Schalter4:
Print "!13";
Return

Schalter5:
Print "!14";
Return

Schalter6:
Print "!15";
Return

Schalter7:
Print "!16";
Return

Schalter8:
Print "!17";
Return

End





'Aktor
$regfile = "attiny2313.dat"
$crystal = 3579545
$baud = 4800

Dim A As String * 5
Dim Z As String * 1
Dim B As String * 5
Dim C As Byte

$hwstack = 32
$swstack = 10
$framesize = 40

Config Serialin = Buffered , Size = 6
Config Portb = Output

Enable Interrupts

Portd.2 = 0


Do

C = Ischarwaiting()
If C = 1 Then
C = Inkey()
A = A + Chr(c)
End If


If Len(a) > 2 Then
B = A
Z = Mid(a , 1 , 1 )
End If


If Z = "!" Then
B = Mid(a , 1 , 5)
End If


If B = "!10" Then
Toggle Portb.0
A = ""

Elseif B = "!11" Then
Toggle Portb.1
A = ""

Elseif B = "!12" Then
Toggle Portb.2
A = ""

Elseif B = "!13" Then
Toggle Portb.3
A = ""

Elseif B = "!14" Then
Toggle Portb.4
A = ""

Elseif B = "!15" Then
Toggle Portb.5
A = ""

Elseif B = "!16" Then
Toggle Portb.6
A = ""

Elseif B = "!17" Then
Toggle Portb.7
A = ""

End If

Waitms 10

Loop

End


Mfg Jürgen

Bammel
10.10.2009, 09:33
bitte wie der moderator schon sagte die code-tags benutzen "[code.]der quellcode[code/.]" die punkte in den tags entfernen

das ganze wird dann übersichtlicher.

kann man den uart port eigentlich auch frei auf andere ports setzten? da wäre für nen kleiner projekt von mir recht wichtig weil ich leider die uart ports anderweitig belegen musste.

Richard
10.10.2009, 17:52
bitte wie der moderator schon sagte die code-tags benutzen "[code.]d

kann man den uart port eigentlich auch frei auf andere ports setzten? da wäre für nen kleiner projekt von mir recht wichtig weil ich leider die uart ports anderweitig belegen musste.

Moin moin.

Ja, Wenn Du die Hardware Uart ausschaltest ($Baud) weglassen,
kannst Du ( auch mehrmals) software Uart verwenden. Dort kannst
Du (Config serial) die Port Pins selber wählen. Beispiele gibt es wie
immer in der sehr guten Bascom Hilfe. Man sollte! wenn mal etwas
Zeit übrig ist, die Bascomhilfs Beispiele alle nacheinander einmal
ausprobieren, das kann sehr sehr Lehrreich sein. :-) Außerdem ist
man angenehm überrascht was man mit Bascom so alles machen kann!

Gruß Richard

Juergen151
09.01.2010, 12:54
Hallo,

hab über die Feiertage meinen 485 Bus-Aktor überarbeitet und in meine Hausinstallation integriert, im Moment zur Steuerung der Terrassen und Außenbeleuchtung.

Es gibt jetzt 6x von einander unabhängige Comfort Zeitschaltungen (Ein - Aus wie Tasterschaltung), 2x Stromstoßschaltungen und eine Zentral Ein/Aus Steuerung.

Eine ausführliche Dokumentation des Projektes hab ich hier
http://juergen151.bplaced.net/

Mfg Jürgen



'Aktor
$regfile = "attiny2313.dat"
$crystal = 3579545
$baud = 4800

Dim A As String * 5
Dim Z As String * 1
Dim B As String * 5
Dim C As Byte
Dim B0 As Integer
Dim B1 As Integer
Dim B2 As Integer
Dim B3 As Integer
Dim B4 As Integer
Dim B5 As Integer
Dim B6 As Integer
Dim B7 As Integer

$hwstack = 32
$swstack = 10
$framesize = 40

Config Serialin = Buffered , Size = 6
Config Portb = Output

Enable Interrupts

Portd.2 = 0

B0 = 6000
B1 = 6000
B2 = 32000
B3 = 32000
B6 = 2
B7 = 2


Do

C = Ischarwaiting()
If C = 1 Then
C = Inkey()
A = A + Chr(c)
End If


If Len(a) > 2 Then
B = A
Z = Mid(a , 1 , 1 )
End If


If Z = "!" Then
B = Mid(a , 1 , 5)
End If

' 6x von einander unabhängige Comfort Zeitschaltungen 2x Stromstoßschaltungen
' Achtung Zähler Integer nur bis 32700

If B = "!10" Then 'Comfort Zeitschaltung kurz Ein - Aus wie Tasterschaltung
If Portb.0 = 0 Then
Set Portb.0
B0 = 6000
Else
Reset Portb.0
End If
A = ""
End If

If B = "!11" Then 'Comfort Zeitschaltung kurz Ein - Aus wie Tasterschaltung
If Portb.1 = 0 Then
Set Portb.1
B1 = 6000
Else
Reset Portb.1
End If
A = ""
End If

If B = "!12" Then 'Comfort Zeitschaltung Lang Ein - Aus wie Tasterschaltung
If Portb.2 = 0 Then
Set Portb.2
B2 = 32000
Else
Reset Portb.2
End If
A = ""
End If

If B = "!13" Then 'Comfort Zeitschaltung Lang Ein - Aus wie Tasterschaltung
If Portb.3 = 0 Then
Set Portb.3
B3 = 32000
Else
Reset Portb.3
End If
A = ""
End If

If B = "!14" Then 'Stromstoßschaltung
If Portb.4 = 0 Then
Set Portb.4
Else
Reset Portb.4
End If
A = ""
End If

If B = "!15" Then 'Stromstoßschaltung
If Portb.5 = 0 Then
Set Portb.5
Else
Reset Portb.5
End If
A = ""
End If

If B = "!16" Then 'Comfort Zeitschaltung kurzer Impuls für externe Ansteuerung
If Portb.6 = 0 Then
Set Portb.6
B6 = 2
Else
Reset Portb.6
End If
A = ""
End If

If B = "!17" Then 'Comfort Zeitschaltung kurzer Impuls für externe Ansteuerung
If Portb.7 = 0 Then
Set Portb.7
B7 = 2
Else
Reset Portb.7
End If
A = ""
End If

If B = "!18" Then 'Funktion Zentral Ein
Set Portb.0
Set Portb.1
Set Portb.2
Set Portb.3
Set Portb.4
Set Portb.5
Set Portb.6
Set Portb.7
A = ""
End If

If B = "!19" Then 'Funktion Zentral Aus
Reset Portb.0
Reset Portb.1
Reset Portb.2
Reset Portb.3
Reset Portb.4
Reset Portb.5
Reset Portb.6
Reset Portb.7
A = ""
End If


Decr B0
If B0 = 0 Then
Reset Portb.0
B0 = 6000
End If

Decr B1
If B1 = 0 Then
Reset Portb.1
B1 = 6000
End If

Decr B2
If B2 = 0 Then
Reset Portb.2
B2 = 32000
End If

Decr B3
If B3 = 0 Then
Reset Portb.3
B3 = 32000
End If



Decr B6
If B6 = 0 Then
Reset Portb.6
B6 = 2
End If

Decr B7
If B7 = 0 Then
Reset Portb.7
B7 = 2
End If




Waitms 20 '10 bis max 20 ms

Loop


End

Juergen151
03.06.2010, 15:32
Hallo,

beim Anschluß eines zweiten Sensor-Moduls hab ich festgestellt das es nicht richtig läuft bzw. der Aktor-Controller stürzt nach kurzer Zeit ab.

Nehme ich den zusätzlichen Sensor wieder weg vom Bus funktioniert wieder alles !

Die Hardware hab ich schon sehr genau geprüft ist ok, ich glaube fast es ist ein Softwareproblem des Sensors, kann es sein das beim Anschluß des zweiten Sensors, beide nicht mehr richtig senden können ?

Vielleicht hat jemand einen Tip woran es liegen könnte !

Mfg Jürgen



'Sensor
$regfile = "attiny2313.dat"
$crystal = 3579545
$baud = 4800
Portb = &B11111111
Portd = &B1100000 'PullUp

$hwstack = 32
$swstack = 10
$framesize = 40

Config Print = Portd.2 , Mode = Set
Config Pind.2 = Output

Config Debounce = 30

Waitms 300


Do
Debounce Pinb.0 , 0 , Schalter1 , Sub
Debounce Pinb.1 , 0 , Schalter2 , Sub
Debounce Pinb.2 , 0 , Schalter3 , Sub
Debounce Pinb.3 , 0 , Schalter4 , Sub
Debounce Pinb.4 , 0 , Schalter5 , Sub
Debounce Pinb.5 , 0 , Schalter6 , Sub
Debounce Pinb.6 , 0 , Schalter7 , Sub
Debounce Pinb.7 , 0 , Schalter8 , Sub
Loop


Schalter1:
Print "!10";
Return

Schalter2:
Print "!11";
Return

Schalter3:
Print "!12";
Return

Schalter4:
Print "!13";
Return

Schalter5:
Print "!14";
Return

Schalter6:
Print "!15";
Return

Schalter7:
Print "!16";
Return

Schalter8:
Print "!17";
Return


End






'Aktor
$regfile = "attiny2313.dat"
$crystal = 3579545
$baud = 4800

Dim A As String * 5
Dim Z As String * 1
Dim B As String * 5
Dim C As Byte
Dim B0 As Integer
Dim B1 As Integer
Dim B2 As Integer
Dim B3 As Integer
Dim B4 As Integer
Dim B5 As Integer
Dim B6 As Integer
Dim B7 As Integer

$hwstack = 32
$swstack = 10
$framesize = 40

Config Serialin = Buffered , Size = 6
Config Portb = Output

Enable Interrupts

Portd.2 = 0

B0 = 6000
B1 = 6000
B2 = 32000
B3 = 32000
B6 = 2
B7 = 2


Do

C = Ischarwaiting()
If C = 1 Then
C = Inkey()
A = A + Chr(c)
End If


If Len(a) > 2 Then
B = A
Z = Mid(a , 1 , 1 )
End If


If Z = "!" Then
B = Mid(a , 1 , 5)
End If

' 6x von einander unabhängige Comfort Zeitschaltungen 2x Stromstoßschaltungen
' Achtung Zähler Integer nur bis 32700

If B = "!10" Then 'Comfort Zeitschaltung kurz Ein - Aus wie Tasterschaltung
If Portb.0 = 0 Then
Set Portb.0
B0 = 6000
Else
Reset Portb.0
End If
A = ""
End If

If B = "!11" Then 'Comfort Zeitschaltung kurz Ein - Aus wie Tasterschaltung
If Portb.1 = 0 Then
Set Portb.1
B1 = 6000
Else
Reset Portb.1
End If
A = ""
End If

If B = "!12" Then 'Comfort Zeitschaltung Lang Ein - Aus wie Tasterschaltung
If Portb.2 = 0 Then
Set Portb.2
B2 = 32000
Else
Reset Portb.2
End If
A = ""
End If

If B = "!13" Then 'Comfort Zeitschaltung Lang Ein - Aus wie Tasterschaltung
If Portb.3 = 0 Then
Set Portb.3
B3 = 32000
Else
Reset Portb.3
End If
A = ""
End If

If B = "!14" Then 'Stromstoßschaltung
If Portb.4 = 0 Then
Set Portb.4
Else
Reset Portb.4
End If
A = ""
End If

If B = "!15" Then 'Stromstoßschaltung
If Portb.5 = 0 Then
Set Portb.5
Else
Reset Portb.5
End If
A = ""
End If

If B = "!16" Then 'Comfort Zeitschaltung kurzer Impuls für externe Ansteuerung
If Portb.6 = 0 Then
Set Portb.6
B6 = 2
Else
Reset Portb.6
End If
A = ""
End If

If B = "!17" Then 'Comfort Zeitschaltung kurzer Impuls für externe Ansteuerung
If Portb.7 = 0 Then
Set Portb.7
B7 = 2
Else
Reset Portb.7
End If
A = ""
End If

If B = "!18" Then 'Funktion Zentral Ein
Set Portb.0
Set Portb.1
Set Portb.2
Set Portb.3
Set Portb.4
Set Portb.5
Set Portb.6
Set Portb.7
A = ""
End If

If B = "!19" Then 'Funktion Zentral Aus
Reset Portb.0
Reset Portb.1
Reset Portb.2
Reset Portb.3
Reset Portb.4
Reset Portb.5
Reset Portb.6
Reset Portb.7
A = ""
End If


Decr B0
If B0 = 0 Then
Reset Portb.0
B0 = 6000
End If

Decr B1
If B1 = 0 Then
Reset Portb.1
B1 = 6000
End If

Decr B2
If B2 = 0 Then
Reset Portb.2
B2 = 32000
End If

Decr B3
If B3 = 0 Then
Reset Portb.3
B3 = 32000
End If



Decr B6
If B6 = 0 Then
Reset Portb.6
B6 = 2
End If

Decr B7
If B7 = 0 Then
Reset Portb.7
B7 = 2
End If




Waitms 20 '10 bis max 20 ms

Loop


End
[/code]

Richard
03.06.2010, 16:06
Hmmm, irgendwie blicke ich nicht wie Du mit Deinem Programm
eine RS 485 Schnittstelle realisierst??? RS 485 ist eine Differenz
Schnittstelle und braucht passende Treiber IC´s, z.B. SN75176 oder
ähnlich. Das Lesen/Schreiben muss dann über Software Protokoll
realisiert werden oder man nimmt eine 4 Draht Übertragung,
2 Leitungen fürs Senden 2 Leitungen zum Empfangen. Dabei ist das
Protokoll dann einfacher. Dafür ist dann auch die Leitungslänge
bis ca 1200 m kein Problem.

Gruß Richard

Juergen151
03.06.2010, 18:52
Hallo Richard,

Deine Frage versteh ich jetzt nicht ganz die Schaltung hab ich doch als jpg angehängt, ich sende Zeichen über den RS 485. (bzw. weiter oben meine Website zu dem Thema)

Mfg Jürgen

Vitis
04.06.2010, 13:57
tjaha ... Du hast dann zwei Busmaster dran wenn ich das richtig verstanden habe ... da wirds schon deutlich komplexer. Du müsstest dann nämlich Deinen Mastern beibringen wann der jeweilige senden darf.
Damit hat Du ziemlich exakt die Schwachstelle bei der 485-kommunikation erwischt.
Mit nem einfachen Protokoll ... ich sende-du machst wird das dann nämlich nix.
Zum Einen müsstest du beim Aktor erfassen wenn ne Kollision stattfindet, sprich beide Master senden ... das geht noch recht einfach über das FE-Flag (framing error), Dann noch ne Checksumme verarbeiten für Dein Protokoll und natürlich n Acknowledge vom Slave verwerten beim Master, sprich der Slave müsste noch antworten (ja, ich hab den Befehl verstanden bzw. Ich hab den Befehl nicht verstanden) und dieses ACK auch beim Master verarbeiten um ggf. nochmals den Befehl zu senden ...
Im Idealfall müsstest Du den Mastern noch n Token geben, wann wer jetzt den Bus belegen darf ...

Alles in allem keine einfache geschichte an der sich schon viele die Zähne ausgebissen haben.

Richard
04.06.2010, 15:18
Hallo Richard,

Deine Frage versteh ich jetzt nicht ganz die Schaltung hab ich doch als jpg angehängt, ich sende Zeichen über den RS 485. (bzw. weiter oben meine Website zu dem Thema)

Mfg Jürgen

Ich meinte nicht die Schaltung, eher die Software. Du brauchst ja ein
Protokoll um den Bustreiber im richtigen Moment von Lesen auf
Schreiben umzuschalten. Siehe auch die Post von Vitis.

Gruß Richard

Juergen151
06.06.2010, 15:18
Hallo Vitis & Richard,

ja das mit dem Umschalten von Senden auf Empfangen hatte ich ganz vergessen, so ist es halt wenn man sich nur alle 6 Monate mit damit beschäftigt.

Ein Protokoll wollte ich unbedingt vermeiden um das Ganze nicht unnötig kompliziert zu machen, mit einem Sender + einem Empfänger hats ja bisher auch wunderbar funktioniert.

Ich hab mir den Code des Senders jetzt schon mal angesehen und abgeändert für Umschaltung Senden/Empfangen, bin aber noch nicht dazu gekommen das ganze zu probieren.

Ich meine aber es sollte funktionieren, wenn man davon ausgeht das verschiedene Taster nicht gleichzeitig gedrückt werden, obwohl wenn man bedenkt wie kurz diese Zeiten sind wird man das wohl kaum schaffen genau gleichzeitig zu drücken.

Wie seht Ihr das ist das so lauffähig ?

Mfg Jürgen



'Sensor
$regfile = "attiny2313.dat"
$crystal = 3579545
$baud = 4800
Portb = &B11111111
Portd.2 = 0

$hwstack = 32
$swstack = 10
$framesize = 40

Config Print = Portd.2 , Mode = Set
Config Pind.2 = Output

Config Debounce = 30

Waitms 300


Do
Debounce Pinb.0 , 0 , Schalter1 , Sub
Debounce Pinb.1 , 0 , Schalter2 , Sub
Debounce Pinb.2 , 0 , Schalter3 , Sub
Debounce Pinb.3 , 0 , Schalter4 , Sub
Debounce Pinb.4 , 0 , Schalter5 , Sub
Debounce Pinb.5 , 0 , Schalter6 , Sub
Debounce Pinb.6 , 0 , Schalter7 , Sub
Debounce Pinb.7 , 0 , Schalter8 , Sub
Loop


Schalter1:
Portd.2 = 1
Waitms 50
Print "!10";
Waitms 50
Portd.2 = 0
Waitms 50
Return

Schalter2:
Portd.2 = 1
Waitms 50
Print "!11";
Waitms 50
Portd.2 = 0
Waitms 50
Return

Schalter3:
Portd.2 = 1
Waitms 50
Print "!12";
Waitms 50
Portd.2 = 0
Waitms 50
Return

Schalter4:
Portd.2 = 1
Waitms 50
Print "!13";
Waitms 50
Portd.2 = 0
Waitms 50
Return

Schalter5:
Portd.2 = 1
Waitms 50
Print "!14";
Waitms 50
Portd.2 = 0
Waitms 50
Return

Schalter6:
Portd.2 = 1
Waitms 50
Print "!15";
Waitms 50
Portd.2 = 0
Waitms 50
Return

Schalter7:
Portd.2 = 1
Waitms 50
Print "!16";
Waitms 50
Portd.2 = 0
Waitms 50
Return

Schalter8:
Portd.2 = 1
Waitms 50
Print "!17";
Waitms 50
Portd.2 = 0
Waitms 50
Return


End

Juergen151
10.06.2010, 20:35
Hallo Vitis, Richard,

ich habs nun ausführlich getestet, vergesst meinen Code vom letzten Posting, es ist wohl tatsächlich so wenn ein Dritter Bus-Teilnehmer dran ist gehts nicht ohne Software-Protokoll, ich war bisher immer der Meinung das der RS485 Chip dies bereits hardwaremäßig tut.

Wie schwierig ist es wohl das Protokoll in meinen biherigen Code einzufügen ? Geht das überhaupt mit Bascom ? Vitis vielleicht kannst Du das mal probieren, wäre nett ! Oder gerne auch ein anderer Bascom-Experte !

Mfg Jürgen

Richard
11.06.2010, 05:48
moin min

Grht relativ einfach. Alle Teilnehmer empfangen per IRQ, damit
nebenbei auch aqndere Aufgaben möglich sind.Dann sendet der
Master eine Auffrderung z.B. in der Art..
: Start.
#ID = Adresse des Slaves
> = für Sendeauforderung
< = für Leseaufforderung
xyz = Anzahl der folgenden Daten oder Befehls Bytes
CRC Checksumme
$00 = nack senden wenn CRC OK
.................................................. ...
CRC nicht Ok nach ? Zeit goto start
Else
xyz Daten vom Slave empfangen und verarbeiten.

Für den IRQ Empfang und auch CRC bilden/auswerten
gibt es in Bascom Befehle musst mal die Beispiele
unter samples durchsuchen und oder in der Hilfe
nach on interrupt und CRC suchen. Alle Empfangen alles,
inorieren aber alles wenn #ID nicht passt bis ein $00
kommt. Dann geht es von vorne los.

Also auch die Slaves müssen beim Antworten immer erst
ein #ID senden damit die Daten an der richtigen Stelle
ausgewertet werden, die Routine ist quasie bei allen gleich.

Die jeweilige ID sollte im EE.Prom liegen (achtung, die erste
EE-prom Speicherstelle kann beim Rest oder Einschalten
verloren gehen) also besser eine höhere wählen.

Viel Spass, Richard

Vitis
11.06.2010, 13:02
Wenn DU ne Hardwarelösung willst solltest Du Dir mal die CAN-Bus Bausteine anschauen, die machen sowas, bei 485 muss man sich um sowas selber kümmern. RS485 beschreibt nur die elektrische Seite der Übertragung, sonst nix.

Die Umwandlung Deines Codes ist sogar noch verhältnismäßig überschaubar.
Zum Einen solltest Du Dir mal das UCSRA Register anschauen, bzw. das TXC-Flag, damit kann man recht elegant die Umschaltung von Senden auf Empfangen lösen ohne Wait Befehle.
Dann noch CRC (gibts auch als Bascom Befehl) und n Array als Overlay über Deinen Sende- / Empfangsstring.
Dann noch das FE-Flag für den Empfang und n Ack vom Slave als Antwort bei verstandenem Befehl, bzw. Nack. Dann noch n Timeout beim Master für Befehle die ins Leere gegangen sind und gut ist.

Richard
11.06.2010, 13:27
Wenn DU ne Hardwarelösung willst solltest Du Dir mal die CAN-Bus Bausteine anschauen, die machen sowas,

G***** davon wollte ich jetzt nicht auch noch anfangen, CAN ist zuwar
etwas super feines aber nicht umsonst kaum im Hobby Bereich zu
finden....recht kompliziert. Weshalb Amtel auch AVR`s mit Hardware
CAN zur Verfügung stellt. Was die jetzt kosten? Aber wenn jemand seine
Wohnung komplett inklusive Musikübertragung Verkabeln will.....
Der sollte sich überlegen ob sich das nicht doch rechnet.

Da CAN aus dem Automobielbereich stammt und z.B. auch Sicherheits-
Bereiche wie ABS u.s.w. abdeckt. Sind Preislich kaum Grenzen gesetzt.

Gruß Richard

Vitis
11.06.2010, 19:41
nee, da hast Du mich falsch verstanden, da gibts
entsprechende Bausteine dafür, z.B.

MCP2515
http://www.datasheetcatalog.org/datasheet2/0/0027dto5zhyf4i01qo7dqexxwhcy.pdf

Richard
12.06.2010, 13:58
nee, da hast Du mich falsch verstanden, da gibts
entsprechende Bausteine dafür, z.B.

MCP2515
http://www.datasheetcatalog.org/datasheet2/0/0027dto5zhyf4i01qo7dqexxwhcy.pdf

Hmm, wenn ich mir so Threads (auch in anderen Foren) darüber anschaue
hatte ich den Eindruck das auch mit den IC`s etliche Probleme aufgetreten
sind?

Ich hatte einmal weil mir die Adressierung und Prioritäten verwaltung
so gut gefallen hat etwas ähnlichen aufgebaut. Einfach die TXD/RXD
noch auf 2 zusäzliche Pin`s gelegt und damit überprüft ob das gerade
gesendete Byte von einen Anderen Teilnehmer über schrieben worden ist.

Dazu muss die Datenleitung natürlich über einen Pullup an + Liegen
und mittels OC geschaltet werden. Sonst brennt etwas weg....

Allerdings ward das damals ein PIC und in Assembler realisiert.

Gruß Richard