PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 3 ports binär auslesen?



Gobstar
31.05.2006, 01:43
Hi leute, ich hab nen drehschalter hier an meinem AVR , er liefert mir ein 3 bit signal...

Das auslesen selber erscheint mir nicht so schwierig, nur die schreibform stört mich..kann man das irgendwie verkürzen, hab echt mit der suche nix gefunden...



If Pinb.2 = 0 And Pinb.1 = 0 And Pinb.0 = 0 Then
D = 4
End If

If Pinb.2 = 1 And Pinb.1 = 0 And Pinb.0 = 0 Then
D = 6
End If

If Pinb.2 = 0 And Pinb.1 = 1 And Pinb.0 = 0 Then
D = 8
End If

If Pinb.2 = 1 And Pinb.1 = 1 And Pinb.0 = 0 Then
D = 10
End If

If Pinb.2 = 0 And Pinb.1 = 0 And Pinb.0 = 1 Then
D = 12
End If

If Pinb.2 = 1 And Pinb.1 = 0 And Pinb.0 = 1 Then
D = 14
End If

If Pinb.2 = 0 And Pinb.1 = 1 And Pinb.0 = 1 Then
D = 16
End If

If Pinb.2 = 1 And Pinb.1 = 1 And Pinb.0 = 1 Then
D = 18
End If


Das problem ist aber dass der rest von portb als ausgang deklariert ist, also kann ich auch nicht einfach den ganzen port irgendwie in ein byte schreiben oder so..

Vll. könnt ihr mir ja helfen..
Gruss Stefan

Gento
31.05.2006, 06:19
So:
.......................................
Result = 0
Result.0 = Dip_1
Result.1 = Dip_2
Result.2 = Dip_3

Select Case Result
Case 0 : S = 5
Case 1 : S = 10
Case 2 : S = 15
Case 3 : S = 20
Case 4 : S = 25
Case 5 : S = 30
Case 6 : S = 40
Case 7 : S = 50
End Select
..........................................

Gento

PicNick
31.05.2006, 07:50
Gensauso. Wenn die Input-Pins aber so liegen, wie du es beschreibst, kannst du auch

Result = PINB AND 7 ' gibt dann die Zahl 0-7

....usw.

Gobstar
31.05.2006, 10:03
Hi Gento...

Das sieht ja mal nicht schlecht, aus, aber das überprüft doch dann nur ob das ergebnis 0 ist...?

PicNick, das hier versteh ich nicht ganz.

Result = PINB AND 7 ' gibt dann die Zahl 0-7

heisst dass die letzten 3 ports werden sozusagen in "Results gespeichert" und ich kann abfragen zb. mit case 7 oder so?


Gruss Stefan

PicNick
31.05.2006, 10:12
Na ja, die hast als Input dir Pins 0, 1 u.2 von PINB, die anderen sind Output.
durch das AND fallen die Output-Pins weg und es bleiben in "result" nur die 3 Input-Bits übrig.
Und diese Bit ergeben eine Zahl von 0 bis 7, die du eben mit select case abfragen kannst.

Gobstar
31.05.2006, 10:18
Jo, genau so dachte ich das...es reicht ja dann results als byte zu deklarieren, oder?

Supi.... :)

Gruss Stefan

PicNick
31.05.2006, 10:28
Ja, logo. das spart code.
aufpassen mit der abfrage. Dein Beispiel wäre dann so:
n.....results........ aktion
0 = 00000000 D = 4
2 = 00000010 D = 8
4 = 00000100 D = 6
6 = 00000110 D = 10
1 = 00000001 D = 12
5 = 00000101 D = 14
3 = 00000011 D = 16
7 = 00000111 D = 18

Gobstar
31.05.2006, 11:12
Na suuuper, klappt prima, vielen dank :)



Result = Pinb And 7
Select Case Result
Case 0 : D = 4
Case 1 : D = 12
Case 2 : D = 8
Case 3 : D = 16
Case 4 : D = 6
Case 5 : D = 14
Case 6 : D = 10
Case 7 : D = 18
End Select


Gruss Stefan

PicNick
31.05.2006, 11:15
Dem Inschenöör is nix zu schwöör :-)

Gobstar
31.05.2006, 11:17
Falls es euch interessiert wofür ich das brauche...

Ich hab 2 mini servo module vom rn shop...

Jetzt kann ich insgesamt 16servos ansteuern und hab 2 Modi für den drehbereich, einmal fest 180° und einmal einstellbar mit dem Dip Drehschalter von 20-160°ca.

Gruss Stefan

PicNick
31.05.2006, 11:32
Na bumm. Was baust du denn ? Einen Weberknecht ?

Gobstar
31.05.2006, 11:43
Ne, ist nicht für mich sondern für jemand anderen, der will irgend so einen Bagger ferngesteuert haben, brauch die servos für hydraulikventile und halt gleich 16..das größe was er fernsteuerungstechnisch gefunden hat sind allerdings 8 Servos...

Jetzt kann er aber 16 steuern, vorerst noch über ein kabel, später dann über rs232 funkmodul oder so..

PicNick
31.05.2006, 11:51
respekt, schaut ja sauber aus ! Dann wünsch ich viel Erfolg !

Gobstar
31.05.2006, 11:55
Jo, vielen dank....
Funzt ja jetzt..also hat eigentlich schon die ganze zeit gefunzt, hat ja auch mit dem if then else geklappt, aber wenn man das programm verschönern will, warum nicht? ist ja nicht so als würd irgendjemand das gesamte programm sehen, aber für einen selber ist das doch ok :)

Gruss Stefan

PicNick
31.05.2006, 12:04
Der Vorteil bei dem Select... ist die leicht lesbarkeit, daß man auch in einem Jahr noch ohne Schwierigkeiten sein eigenes Programm lesen und verstehen kann. (das is nämlich nicht selbstverständlich)

Gobstar
31.05.2006, 12:07
Ja das ist klar....ich arbeite selber auch viel mit dem select, das war ja auch nicht das schwierige,ich mag auch die if-sache nicht, machts immer so unübersichtlich und vermeide es wenns geht... nur wie sollte man von sich aus auf "Result = Pinb And 7" kommen? hab in der hilfe nix gefunden :(

Hab mir schon gedacht dass mal vll. die 3 werte in ein byte schreiben kann, aber wenn dann halt nur mit den restlichen Ports und da die als ausgang deklariert sind , sind sie high und verfälschen bestimmt das ergebnis..


Gruss Stefan

PicNick
31.05.2006, 12:27
Die "AND" Geschichte ist nützlich, kann man sich merken, da das Problem mit mixed Input/Output ja öfter vorkommt.
Immer eine Konstant-Zahl haben, wo die entsprechenden Input-Bits auf 1 stehen, in unserem Fall also &B00000111 = 7
Mach man dann damit AND, sind im Ergebnis die Output-Bits immer NULL, und nur die interessenten Bits haben den wert von PINx
Das Ganze nennt man "maskieren"

Gobstar
31.05.2006, 12:38
Maskieren..ok, man lernt nie aus :)

Bin ja eh nicht sooo der progger, mach lieber mechanische dinge und progg nur was ich muss, aber falls es dich interessiert poste ich dir hier gerna mal das ganze Programm....da ich aber natürlich faul bin, ist es unkommentiert, aber du kannst ja vll. trotzdem was mit anfangen :)



$regfile = "m16def.dat"
$framesize = 24
$swstack = 8
$hwstack = 32

$crystal = 16000000
$baud = 9600

Ddrc = &B10000000
Ddrb = &B11111000
Ddrd = &B00000000
Portb = 255
Portd = 0


Dim A As Word
Dim B As Byte
Dim C As Byte
Dim D As Byte
Dim Result As Byte
B = 0
C = 0
D = 0
Waitms 200
Gosub Drehbereich

Enable Interrupts
Enable Int0
Config Int0 = Change
On Int0 Drehbereich

Config Adc = Single , Prescaler = Auto
Start Adc


Do

Select Case Pind.3
Case 1 : Gosub Rechts
Case 0 : Gosub Links
End Select

Loop

Rechts:
Portb.3 = 0
Portb.4 = 1
Portc.7 = 1
A = Getadc(b)
A = A / 8


Select Case A
Case 59 To 69 : A = 64
Case 128 : A = 127
End Select

'128 ; Servodevice ; Servocommand ; Servonummer ; Servodata
Print Chr(128) ; Chr(1) ; Chr(2) ; Chr(b) ; Chr(a)

Incr B
Select Case B
Case Is > 7 : B = 0
End Select
Waitms 1

Return

Links:
Portb.3 = 1
Portb.4 = 0
Portc.7 = 0
A = Getadc(b)
A = A / 8
C = B + 8

Select Case A
Case 59 To 69 : A = 64
Case 128 : A = 127
End Select

'128 ; Servodevice ; Servocommand ; Servonummer ; Servodata
Print Chr(128) ; Chr(1) ; Chr(2) ; Chr(c) ; Chr(a)

Incr B
Select Case B
Case Is > 7 : B = 0
End Select
Waitms 1

Return

Drehbereich:

If Pind.2 = 1 Then

Result = Pinb And 7
Select Case Result
Case 0 : D = 4
Case 1 : D = 12
Case 2 : D = 8
Case 3 : D = 16
Case 4 : D = 6
Case 5 : D = 14
Case 6 : D = 10
Case 7 : D = 18
End Select

For B = 0 To 15 Step 1
'128 ; Servodevice ; Servocommand ; Servonummer ; Servodata
Print Chr(128) ; Chr(1) ; Chr(0) ; Chr(b) ; Chr(d)
Next
Else
For B = 0 To 15 Step 1
'128 ; Servodevice ; Servocommand ; Servonummer ; Servodata
Print Chr(128) ; Chr(1) ; Chr(0) ; Chr(b) ; Chr(20)
Next
End If
Return

End


Gruss Stefan

PicNick
31.05.2006, 13:21
Schau mal, ich hab das ein wenig unstrukturiert, spart Code.


$regfile = "m16def.dat"
$framesize = 24
$swstack = 8
$hwstack = 32

$crystal = 16000000
$baud = 9600

Ddrc = &B10000000
Ddrb = &B11111000
Ddrd = &B00000000
Portb = 255
Portd = 0

Dim A As Word
Dim B As Byte
Dim C As Byte
Dim D As Byte
Dim Result As Byte

B = 0
C = 0
D = 0
Waitms 200

Gosub Drehbereich

Enable Interrupts
Enable Int0
Config Int0 = Change
On Int0 Drehbereich
Config Adc = Single , Prescaler = Auto
Start Adc

Do
A = Getadc(b)
A = A / 8
Select Case A
Case 59 To 69 : A = 64
Case 128 : A = 127 ' gibt es aber eigentlich nicht
End Select

Result = Pind.3
On Result Gosub Links , Rechts

Incr B
B = B And 7
Waitms 1

Loop
End

'----------------------------------------------------
Rechts:
Portb.3 = 0
Portb.4 = 1
Portc.7 = 1
'128 ; Servodevice ; Servocommand ; Servonummer ; Servodata
Print Chr(128) ; Chr(1) ; Chr(2) ; Chr(b) ; Chr(a)
Return
'----------------------------------------------------
Links:
Portb.3 = 1
Portb.4 = 0
Portc.7 = 0
C = B + 8
'128 ; Servodevice ; Servocommand ; Servonummer ; Servodata
Print Chr(128) ; Chr(1) ; Chr(2) ; Chr(c) ; Chr(a)
Return
'----------------------------------------------------
Drehbereich:
If Pind.2 = 1 Then
Result = Pinb And 7
Select Case Result
Case 0 : D = 4
Case 1 : D = 12
Case 2 : D = 8
Case 3 : D = 16
Case 4 : D = 6
Case 5 : D = 14
Case 6 : D = 10
Case 7 : D = 18
End Select
Else
D = 20
End If

For C = 0 To 15 Step 1 'besser C, da sonst b (SrvNr) falsch ist
'128 ; Servodevice ; Servocommand ; Servonummer ; Servodata
Print Chr(128) ; Chr(1) ; Chr(0) ; Chr(c) ; Chr(d)
Next
Return

Gobstar
31.05.2006, 15:06
Na toll..ich brauch da Tage bis ich das programm soweit hab dass es gut läuft und dann kommt hier einer daher und schreibt es mal schnell in nem Stündchen um :(

Ich mein Code Sparen müsst ich eh net, mehr macht der m16 eh nicht, aber trotzdem cool..aber wenn du schon den code änderst hätte ich ein paar fragen :)

Warum zb. B=B And 7 ?ist b also die tatsächliche dezimalzahl? und nicht die anzahl der bits? ich dachte And 7 heisst sowas wie lese 7 bits aus und nicht lese die ersten 3 bits aus da die ja dezimal 7 sind?

Und da ich (was du ja nicht wissen kannst) 2 analoge 8->4 multiplexer am adc hab (16potis) und jeweils mit dem pinc.7 zwischen den potis herspringe, wär dann nicht meine art immer in den sub´s links und rechts den analogen wert frisch einzulesen besser/schneller? weil dann hat er immer nach dem umschalten der mux den aktuellen wert und nicht den zu letzt verfügbaren gewesenen wert??

So far..

Gruss Stefan

PicNick
31.05.2006, 15:17
..stündchen..
So isses nicht fair, ich muß ja mit sowas meine Frau und zwei verfressene Katzen ernähren :mrgreen:

..B AND 7..
neinein, "7" ist ein byte, bei dem die unteren 3 Bit gesetzt sind, also &B00000111

..Multiplexer..
Da hast du dann natürlich recht, getadc() gehört dann jeweils dorthin, wo du es gehabt hast :oops:

Gobstar
31.05.2006, 15:45
Na...is ja nicht schlimm, dein programm geht deshalb nicht weniger gut, hab also großartig nix gemerkt und bis man effektiv nach dem umschalten zum poti greift wirds wohl mehrmals durchgelaufen sein :)



So isses nicht fair, ich muß ja mit sowas meine Frau und zwei verfressene Katzen ernähren

Also bist du Programmierer...auch nicht schlecht :) Dann weiss ich ja an wen ich mich richten muss wenn ich demnächst an meinen Eigenbaufahrtregler gehe :)


neinein, "7" ist ein byte, bei dem die unteren 3 Bit gesetzt sind, also &B00000111
Ok, wie würde das dann bei nem word aussehen bzw. wenn b ein word wäre oder so? Habs immer noch net ganz kapiert :oops:

Achja..und da wäre noch: On Result Gosub links, rechts

Auf welchen wert schaut dabei on, auf einen high oder lowzustand? und das erste label ist dann das welches er bei dem zustand anspringt? und dann halt praktisch else zweites label?

Gruss Stefan

PicNick
31.05.2006, 16:07
Sicher, getadc brauch ein paar zerquetschte Millisekunden, da kannst du nicht viel drehen am Poti.

Word: Da ist Bascom schlau und denkt mit. Das resultat bestimmt immer das Format der anderen argumente. z.B
dim b as word
b = b and 7
--> B = B and &B0000000000000111

ON ist ja eigentlich :


ON Result gosub result_is_0, gosub result_is_1,..... gosub result_is_xx

bei dir kommt halt nur 0 und 1 vor