Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

idontknow

unregistriert

1

08.06.2010, 15:30

[ASM] Motor-Ansteuerung über Schiebepotentiometer

Moin!

Für meine Schule mache ichn Projekt in dem ich nen Raupen-Chassis über 2 Motoren mithilfe eines Mikrokontrollers und einem Motortreiber ansteuere!
Es dreht sich um diesen Kontroller: MC 8051 / MC 80535 / C515-LN

Das ganze funktioniert mithilfe eines PWM-Signals (über den Timer 2 des Kontrollers). Damit kann ich an bis zu 4 Output Ports, software unabhängig, ein SIgnal kontinuierlich angeben und über das Programm abändern.

Das Schiebepotentiometer ist einfach ein schalter den man hin und herschieben kann und der je nach Schalterstellung ne Spannung von 0V-5V liefert. Das ganze kann ich mit nem A/D-Wandler einlesen und hab dann eine Zahl von 0-2^8.

Kurz zur Erläuterung des PWM-Signals: Das Signal kann ich an 4 Ports anschalten. Ist es aktiv, zählt der Kontroller stnadardmäßig von 0-65536 (2^16). Zusätzlich kann ich in 8 Registern (2 pro Signal) einen 16-Bit Wert abspeichern. Nach jedem Zählvorgang überprüft er ob er diesen Wert überschritten hat, wenn ja dann sendet er fortan bis zum Timerüberlauf eine 1 an den Port, andernfalls eine 0.
Dadurch kann ich über die Motorträgheit den Motor verschieden schnell betreiben. Ein Wert von 0 in den PortRegistern wäre Maximal Geschwindigkeit, ein Wert von 65536 langsamste Geschwindigkeit bzw Stop.

Soviel zur Erklärung. Da ich die Motoren aber in 2 Richtungen steuern will, muss ich beachten, dass die Mitte des Potentiometers stop wäre, ganz unten max. Rückwärts und ganz oben max. vorwärts.

jetzt bin ich mir leider unklar wie ich das lößen soll,da ASM ja relativ begrenzt ist. Ich würde es gern vermeiden irgendwelche Stufen zu nutzen, aber die geschwindigkeitsabstufung sollte doch kontinuierlich zu dem Schalter-Analog Wert sein d.h. keine 10 Stufen oder ähnliches. lediglich der "Stop-Mode" in der Mitte des Schalters sollte ne gewisse Grenzweite haben.

Hat jemand nen ASM-Pseudocode oder was in der Art? Bitte nur Leute mit Ahnung von ASSEMBLER posten, da die sprache speziell für meinen Kontroller sehr begrenzt ist (sprich keine Multiplikation soweit ich weiß und vieles mehr.)

Kann später noch genauere Infos/Meine Lößungsansätze posten,jetzt muss ich baden gehn ham hier gefühlte 40°....

mfg

edit: Meine "Lößungsidee" war/ist wie folgt:

Der Schalter hat ne Analog Spannweite von 0... 256. Dabei muss er aber 2 Richtungen abdecken + nen "Stop-Raum" beinhalten indem der Motor die geschwindigkeit 0 hat.
Würde dann ca. so aussehen:
-n(0)|....| s |....|+n(256)

d.h. die Maximal geschwindigkeit wäre: n = 256 / 2 - s / 2. Ich rechne mal mit s = 56. Daraus ergibt sich dann, n = 128 - 56 / 2 = 100;
Die Richtung der Geschwindigkeit ist vorerst kein Problem, ist lediglich eine "Umpolung" der Output Ports.

Jetzt muss ich ja erstmal mit 2 Geschwindigkeiten rechnen v1 wäre dann von 0(max.) - 100(low.) und v2 von 156(low.) - 256(max.).
Das Problem ist jetzt dass ich in Assembler keine richtigen ifs habe. Und ich muss v2 so umrechnen, dass es mit v1 identisch ist, da v1 ja nen Wert beinhaltet den ich so direkt weiterverarbeiten könnte.
Der Digitalwert steht jetztin nem Register das ich einfach mal Rv nenne. Daraus muss ich 2 Werte extrahieren, erstmal die "virtuelle" Geschwindigkeit mit der ich die tatsächliche Geschwindigkeit erstellen kann und eben die Richtung was sich in nem anderen Register mit Wert 0/1 äußert.

Das wäre jetzt in "ASM-Pseudocode":

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
bool success = false;
for(i = 0; i < 100; ++i)
{
    if(i == Rv)
    {
        RealV = 100 - i;
        dir = backwards;
        success = true;
        break;
    }
}

for(i = 156; i < 256; ++i)
{
    if(i == Rv)
    {
        RealV = Rv - 156;
        dir = forward;
        success = true;
        break;
    }
}

if(!success)
{
    RealV = 65536;
}


hmm. damit hätte ich glaube ich sogar die echte Geschwindigkeit + Richtung in COde denn ich so in ASM relativ einfach umsetzen kann. Das Problem ist jetzt:

Wenn RealV gegen 0 geht, muss X (der Wert aus den 2 PWM-Port registern bzw aus einem im quadrat) gegen 65536 gehen. D.h.
RealV = 0 => X = 256
RealV = 100 => X = 0

Dann wäre da noch das Problem, dass mein Rehcner weder mal noch geteilt rechnen kann.... werd mir was überlegen, bin mal essen dake für Tips oder falls jemand mein Psuedo Code abchecken könnte wäre super is ja wie beim AUfsatz man selebr überlioeßt gerne offensichtliche Fehler..

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »idontknow« (08.06.2010, 16:56)


BurningWave

Alter Hase

Beiträge: 1 106

Wohnort: Filderstadt/Konstanz

Beruf: Student

  • Private Nachricht senden

2

08.06.2010, 16:39

Ich glaube in einem Elektronik-Forum wie roboternetz.de können dir mehr Leute helfen, wie hier...

Ich kann kein ASM, würde es aber mit Vergleichen machen (also "analoger Wert < Maximalwert / 2 - Abstand zur Mitte" entspricht links drehen, "analoger Wert > Maximalwert / 2 + Abstand zur Mitte" entspricht rechts drehen, wenn keines von beidem erfüllt ist, dann Stop).

Den analogen Wert (8 Bit) würde ich in den PWM Wert (16 Bit) umwandeln, indem ich ihn mit 2 multipliziere.

Wie wilst du die Motoren umpolen, mit PWM geht das ja nicht...
Und seit wann kann man in Assembler keine Multiplikationen durchführen??

Edit:
Und wenn dein µC tatsächlich keine if-Befehle oder Multiplikationen unterstützt, dann nimm einen AVR µC, die kannst du sogar mit C programmieren.

idontknow

unregistriert

3

08.06.2010, 16:46

Mikrokontroller ist fest vorgegebene, auch wenn man das Ding mit C programmieren könnte soweit ich weiß. Aber werds mit AMS durchziehen.

@PWM-umpolen:
Ich habe 4 Register an denen ich dass PWM-Signal erzeigen kann und 2 Motoren. Die Motoren schließe ich eben immer an 2 dieser Ports an, d.h. +/- an je einen PWM-Port. Damit der Motor läuft muss einer auf 0 sein und der andere Port auf 5V. Wenn sich die Richtung ändert stelle ich einfahc in der Timerkonfiguration (ccen register) die 2 Ports um, und schon dreht sich der Motor in die andere Richtung.

Hab oben mal nen VOrschlag gepostet, das Problem bei dem ist, dass ich eben wie ich die Geschwindigkeit in den Wert denn ich in das Register schreibe umwandeln kann das hauptproblem ist, dass ich wegen Timerfunktion und den 2 Registern eigentlich einen Wurzel funktion bräuchte um es "perfekt" zu machen!

BurningWave

Alter Hase

Beiträge: 1 106

Wohnort: Filderstadt/Konstanz

Beruf: Student

  • Private Nachricht senden

4

08.06.2010, 17:07

Ich versteh nicht was die for-Schleifen sollen, das geht doch auch mit if und ist dabei viel praktischer. Welche Variale enthällt bei dir welchen Wert? Du solltest eine gewisse Toleranz für den Stopwert einbauen, wenn du sagst, dass Stop nur bei einem einzigen Wert ist, dann viel Spass diesen Wert zu treffen ;D

idontknow

unregistriert

5

08.06.2010, 17:12

Mein Controler kann kein if. Mein Controler kann nur sagen ob nen Wer X gleich nen Wert Y ist, und entsprchend nen Jump ausführen oder im Code weitergehen aber nen normales if kann der nicht, daher die Schleife.

Die TOleranz habe ich bei 56-"Werten" angepeilt. Sieht man ja in der Rechnung (s)

edit: mein Teil kann multiplizieren? oO
Ist aber soweit ich weiß bei dem extrem lahm!
Werds mal provisorisch nutzen!!

Damit hätte sich mein Problem erledigt :)

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »idontknow« (08.06.2010, 17:19)


BurningWave

Alter Hase

Beiträge: 1 106

Wohnort: Filderstadt/Konstanz

Beruf: Student

  • Private Nachricht senden

6

08.06.2010, 17:19

Die Rechnung versteh ich aber nicht, ohne zu wissen, was in welcher Variable steht ;)

Wie willst du < Bedingung in der Schleife einsetzen, wenn < und > nicht unterstützt werden?

idontknow

unregistriert

7

08.06.2010, 17:21

Ja der Pseudo Code ist fehlerhaft aber umsetzbasr in Assembler glaube ich im Moment zumindest :P.

Ich kann ja wie gesagt einfach auf == überprüfen :)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

08.06.2010, 18:01

Mein Controler kann kein if. Mein Controler kann nur sagen ob nen Wer X gleich nen Wert Y ist, und entsprchend nen Jump ausführen oder im Code weitergehen aber nen normales if kann der nicht, daher die Schleife.

Ohne jetzt den ganzen Thread gelesen zu haben nur als Anmerkung: Was du da beschreibst ist haargenau ein if() ;)

idontknow

unregistriert

9

08.06.2010, 18:20

Mein Controler kann kein if. Mein Controler kann nur sagen ob nen Wer X gleich nen Wert Y ist, und entsprchend nen Jump ausführen oder im Code weitergehen aber nen normales if kann der nicht, daher die Schleife.

Ohne jetzt den ganzen Thread gelesen zu haben nur als Anmerkung: Was du da beschreibst ist haargenau ein if() ;)



genau und mein controller kann das nicht...
der kann nicht überprüfen ob 2 register den selben wert haben sondern nur ob ein register einen bestimmten wert hat.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

10

08.06.2010, 18:56

Kein mit bekannter Mikroprozessor hat eine eigene if Instruction, aber die braucht es auch nicht. Wenn dein Controller bedingte Sprünge kann (was ja der Fall ist) dann kann er auch if...

Werbeanzeige