PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Rechenoperationen BASCOM??



Powell
14.05.2007, 21:09
Guten Abend

ich hab mal eine Frage, hab nun über eine Stunde blöd rumprobiert und nun die Faxen dicke, mein Problem ist für mich vollkommen unlogisch und ich möchte nun wissen warum das so ist ](*,) :
Ich möchte einen Servo über einen Mega8 ansteuern (erstmal just for fun ausprobieren). Erstes ganz simples programm mit Pulsweitendefinition über den waitus befehl hat funktioniert. Bei waitus 1000 fährt er an den Anschlag links und bei 2000 rechts.
Nun das gleiche mit Variable, da ich später ein Sub schreiben will was die Pulsweite verstellt: Dim T as byte, T= 1000, aber dann wird die zeile einfach übersprungen (Pulsweite = 0 ). Nächster Versuch (genau die gleiche Programmstruktur): Waitms = T, T = 1 - also 100% dasselbe. voila, es funktioniert. Aber warum funzt es mit dem waitms befehl und nicht mit dem waitus befehl? Mein zweiter Versuch war der, einen Umrechnungsfaktor einzubringen, also über den waitms befehl zu gehen und T so zu multiplizieren dass eine rationale zahl zwischen 1 und 2 rauskommt. Da hat mir Bascom allerdings einen Fehler ausgegebe, ich muss dazu sagen dass ich das rechnen mit Variablen noch nicht beherrsche (kann man überhaupt mit brüchen rechnen?). Bitte helft mir, ich krieg sonst noch die Kriese [-(

Grüße Paul

p_mork
14.05.2007, 21:27
Hallo Powell,

Zitat aus der BASCOM-Hilfe:
US The number of microseconds to wait. (1-65535)
This must be a constant. Not a variable!
Soll heisen, dass man waitus nicht mit Variablen verwenden darf. Gug mal dort unter "CONFIG SERVOS" nach, da findest Du, wie man ein Servo in BASCOM ansteuert.

MfG Mark

linux_80
14.05.2007, 21:31
Hallo,

zum Servo, diesem sollte man die Position ca. alle 20ms mitteilen.

Beim rechnen mit Bascom immer darauf achten, das pro Zeile nur eine Rechenoperation ausgeführt wird, bei sowas wie zB. (Max - Min)/2 kommt er schon durcheinander.

Rechnen mit Variablen ist ja nicht so kompliziert,
A= 2
B= 3
C= B+A

dann ist C = 5

BastelWastel
14.05.2007, 22:44
Also ich hab Version 1.11.8.1 und da klappt es wunderbar den Wait-Befehlen Variablen zu übergeben..
Aber du definierst T as Byte und sagst T = 1000, ein Byte geht aber nur bis 255..wenn du 1000 zuweisen willst mußt du's schon als Word declarieren..

Bit: 0/1
Byte: 0-255
Integer: -32768 - +32767
Word: 0-65535
Long/Single gehen dann schon in den 10-stelligen Bereich

Powell
15.05.2007, 07:41
Hallo

Mark: Ja genau, das war mein Problem... das mit Config Servos hab ich mal eben schnell ausprobiert, aber der Servo zuckt sich damit nur an einen Anschlag und will dann weiterdrehen... muss ich mal mit dem Oszi ran, aber auf anhieb hat es jedenfalls nicht funktioniert.

Linux: Das mit den Variablen rechnen ist einfach, ja, bloß ging es mir in meinem Fall um Brüche. Wie mach ich ihm denn z.B. klar, dass als Ergebnis einer Rechenoperation 1,7 herauskommen soll?

Wastel: Klappt es bei dir auch mit dem waitus Befehl? Mit wait und waitms geht es bei mir nämlich auch, aber nicht mit waitus.

Grüße Paul

BastelWastel
15.05.2007, 11:04
Ja, wait, waitms und waitus arbeiten bei mir ohne Probleme mit Variablen..
Declariere deine Variable T mal als Word und versuch es..

Powell
15.05.2007, 11:24
schon probiert... geht nicht... :(

Es muss doch eine Möglichkeit geben mit Brüchen zu rechnen, oder?

Oder Wie kann man noch eine PWM-Ausgabe realisieren wo man Pulsweite und Pulspause variieren kann?
Mal weg von dem Gedanke nur Servos anzusteuern: Auch wenn ich z.B. Motoren ansteuern will muss es doch eine möglichkeit geben die Pulsweite mit Variablen entsprechend zu regeln?
Mir fehlen leider die nötigen Kenntnisse in Bascom, mache das noch nicht so lange und weiß daher nicht wie man es hinbekommen könnte :(

Grüße Paul

BastelWastel
15.05.2007, 11:29
Hm..vllt mal n upgrade auf die neueste Version machen..
Muss es denn ueber Wait sein?
Hast du keinen Hardware PWM mehr frei?

Alternativ post mal deinen Code und den genauen Fehlertext..

Dani-Bruchflieger
15.05.2007, 13:15
Hi,

macht es euch doch nicht so schwer. Den PWM kannst du ganz einfach mit den Timern lösen.
Ich habe mal einige Ausschnitte aus den Programmen für Meine RC-Fernsteuerung auf Basis der XBee-Pro Funkmodule zusammengepuzzelt und angehängt, mit dem an einem Mega8 Prozessor 5 Servos angesteuert werden können sollten.
Ich hoffe es ist verständlich auskommentiert.
Es gibt ein Array mit 9 Servokanälen - 1bis 5 sind die Servos am Portb.0 bis Portb.4, Servos 6-9 gehen an eine Dummy-Variable um die Pause zwischen den Impulsen auf min ca 10ms zu halten - auch wenn alle Servos gerade nur mit 1,0ms angesteuert werden. (Die Pausenzeit ist hier Variabel - bei RC-Servos sollte sie nicht unter 10ms und nicht über 20ms liegen, alles dazwischen ist unkritisch)
Das Array beginnt mit S(1) soll aber Portb.0 ansteuern, darum das Handling mit aktservo und _aktservo.
Das ganze läuft mit 7Bit Daten (S(1)=0 erzeugt am Portb.0 einen Impuls mit 2ms Dauer, S(2)=127 erzeugt am Portb.1 einen Impuls mit 1ms Dauer)
ADC-Messungen erfolgen am Portc.1 ... Portc.5

Edit: Ich habe es aber nicht nochmal in dieser Form getestet - ich hoffe, daß es Funzt, kann es aber nicht garantieren...




$regfile = "m8def.dat"
$crystal = 8000000

Config Portb = Output
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc
Config Timer0 = Timer , Prescale = 64 'Timer für Servos
Start Timer0
On Timer0 _timer0
Enable Timer0
Enable Interrupts

Dim Durchlauf As Byte 'Zähler Servoimpulsdurchläufe
Dim Aktservo As Byte 'Aktuelles Servo (ISR)
Dim _aktservo As Byte 'Portpin des akt. Servos
Dim S(9) As Byte 'Servowertearray
Dim Servo As Word 'Dummy für verarbeitung der 4 Dummyservokanäle für die Pausenzeit
Dim A as Byte 'Zähler For Next
Dim B as Byte 'Zähler For Next
Dim C as Word 'Annahme vom ADC
Dim Temp as Word 'Mittelwertbildung ADC
'Initialisieren der Startwerte (damit Servos nicht total rumzicken oder sich im Kreis drehen...)
For A = 6 To 9 'Dummykanäle der Pausenzeit
S(a) = 64
Next

Do
For A = 1 To 5 'Die 5 Servokanäle Sollwerte erfassen
Temp = 0
For B = 1 To 16 'Mittelwertbildung aus 16 Messungen
C = Getadc(a)
Temp = Temp + C
Next
Shift Temp , Right , 7 '16 Messungen a 10Bit ergeben 14Bit, diese werden auf 7Bit runterdividiert - das geht am einfachsten und schnellsten mit Shiften
S(a) = Temp
Next
Loop

'**ISR des Servotimers**
_timer0:
If Aktservo < 6 Then 'servos 1-5 sind echte Portpins,
Portb._aktservo = 0 'Servos 6-9 gehen an Bits der Dummyvariable Servo,
Else ' um die Pausenzeiten auf ca. 13...19ms zu bringen
Servo._aktservo = 0 'Hier wird der Impuls abgeschaltet, nachdem die Zeit abgelaufen ist
End If
Incr Aktservo 'Zähler, welches Servo gerade seinen Impuls bekommt
_aktservo = Aktservo - 1 'da die Ports mit Pin 0 beginnen, wird -1 gerechnet
If Aktservo = 10 Then 'Rücksetzen nach den 9 Durchläufen
Aktservo = 1
_aktservo = 0
End If
If Aktservo < 6 Then 'Nachdem die Aktservo erhöht wurde, wird der nächste Impuls eingeschaltet
Portb._aktservo = 1
Else
Servo._aktservo = 1
End If
Timer0 = S(aktservo) + 4 'und der Timer wird passend vorgeladen - S=0 =2ms, S=127 =1ms, S=64 =1,5ms
Return

linux_80
15.05.2007, 18:02
Hallo,

zum rechen mit Kommzahlen (Fliesspunkt),
mit den standardtypen (Byte, Word, Integer) kann man nur ganze Zahlen darstellen, bei Berechnungen die Nachkommastellen hätten, werden diese einfach abgeschnitten.

Ansonsten gibts bei Bascom noch die Typen Single und Double, das wären die, die man zum rechnen mit Nachkommastelle verwendet.

Such mal in der Bascom-Hilfe nach DIM und Single, da wird das aufgezeigt.

Powell
16.05.2007, 07:02
Jap, vielen Dank Dani, mit Timer PWM erzeugen funzt... super sache

Grüße Paul