PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ASURO Projekt Einen Motor pausieren



luba1248
05.05.2017, 13:42
Hallo
Ich bin Schüler und anfänger was Programmieren betrifft... weshalb ich mir leider alles zusammenschnipseln muss.

Mein Problemm ist, dass ich ein Projekt mit dem ASURO erarbeiten muss. Darum habe ich ihn zu einer Sortiermaschine umgebaut die drei verschieden große Murmeln sortiert. Ein Motor wirft meine Murmel in die Rollbahn und die Fototransistoren erkennen die jeweilige Kugelgröße durch mehr oder weniger helligkeit. Je nach Kugelgröße richtet der zweite Motor meinen Sortierarm aus, so das die Kugel in das gewünschte Fach rollt.
Problem ist nun, das der Auswerfmotor {rechter Motor} (ganz am Ende des beigefügten Programmes siehe !!!!!!!! ) die ganze zeit läuft er soll aber eine bestimmte zeit pausieren bis die Kugel jnten ankommt. Mit Msleep funktioniert das ja nicht, da sonst das ganze Programm stopt und meine Fototransistoren die vorbeirollende Kugel nicht erkennen.

Gibt es hier eine Möglichkeit nur den auswerf Motor eine bestimmte Zeit pausieren zu lasen ?

#include <avr/io.h>
#include "asuro.h"
int main(void)
{
Init();
unsigned int data[2]; //Initialisiert zwei Int-werte hintereinander
FrontLED(ON);
Msleep(1000);
while (1)
{


LineData(data);

if ((data[0]<700) && (data [1]<700))
{
MotorDir(FWD,FWD);
MotorSpeed(85,0);
Msleep(160);
MotorSpeed(0,0);
Msleep(3000);
MotorDir(RWD,RWD);
MotorSpeed(85,0);
Msleep(160);
MotorSpeed(0,0);

}

if ((data[0]>700) && (data[1]>700))
{
MotorDir(FWD,FWD);
MotorSpeed(0,0);

}

if ((data[0]>700) && (data[1]<700))
{
MotorDir(RWD,RWD);
MotorSpeed(85,0);
Msleep(160);
MotorSpeed(0,0);
Msleep(3000);
MotorDir(FWD,FWD);
MotorSpeed(85,0);
Msleep(160);
MotorSpeed(0,0);
}

MotorDir(FWD,FWD); !!!!!!!!!!!!
MotorSpeed(0,100);
Msleep(480);
MotorSpeed(0,0);


}
}
Danke

i_make_it
05.05.2017, 14:58
Kann man machen, aber zum Sortieren, sollen doch drei verschiedene Positionen angefahren werden.
Da der Asuro ja Odometrie hat,
32590
kann man auch einfach die Position anfahren und am Ende der Kugelbahn noch eine Lichtschranke anbauen.
Wenn eine Kugel die Sortierlichtschranken durchläuft wird einmal der Motor angewiesen eine Position anzufahren und eine Merkvariable gesetzt.
Wenn der Motor die Position erreicht hat (Zählen der Farbwechsel am Odometriesensor), bleibt diese Positionsvorgabe erhalten, bis die Lichtschranke am ende durchlaufne wird und diese die Merkvariable wieder löscht.
Damit ist dann auch die Freigabe für die nächste Kugel an den Motor 1 gegeben.
Du kannst Den Code übrigens auch in Code Tags packen.


Code

Dann wird der Post nicht ellenlang.

Die Funktion ist unter erweitert.

luba1248
05.05.2017, 16:18
Hallo i make it

Erstmal Danke für die Tipps nur ist es so, dass wir die Odometrie nicht verwenden sollen, da auch diese nicht 100% genau ist weshalb ich es mit einem Anschlag gebaut habe. Also bei ganz kleiner Kugel gährt der Motor garnicht bei groß nach rechts und klein nach links jeweils bis maximal Anschlag.
Die Anlage ist auch gebaut wehalb ich auch beide Fototransistoren schon verbaut habe um die Kugelgrößen auszulesen.
Nun ist es so, dass ich seit zwei Wochen versuche mein Programm umzuschreiben, um zu verhindern, dass ich meine ganze Anlage umbauen muss.
Leider habe ich wenig Programmierkenntnisse und mein Lehrer auch. Und an den Prüfer kann ich mich nicht wenden.

i_make_it
05.05.2017, 17:38
Hm, und wie findest Du wieder in die Mitte wenn die ganz kleine Kugel als drittes kommt?
Da fährt der Motor ja je nach Richtung von der aus er kommt immer bis zum jeweils gegenüberliegenden Anschlag.

Das funktioniert mit den Anschlägen also prinzipbedingt nur für zwei Positionen.
Aber selbst da könnte man mit je einem Taster pro Position arbeiten der bei Betätigen die Position als erreicht anzeigt und der Motor über diese Variable dann angehalten wird, bis die Rinne frei ist und die Nächste Kugel "vermessen" wird.

luba1248
05.05.2017, 19:37
Der Motor fährt mit einer gewissen Geschwindigeit, für eine bestimmte Zeit, wie im Programm beschrieben. Bei der ganz kleinen Kugel fährt der Motor garnicht. So funktionieren slle drei möglichkeiten. Das ist ja auch nicht das Problem, denn es funktioniert bis auf den 2. Motor. Problem ist hier der Motor der die Kugeln einzeln aus dem Sammelbehälter herausbefördert. Er soll nämlich immer zu einer bestimmten Zeit die nächste Kugel auf die Sortierbahn befördern. Doch wie bekomme ich das hin? So das der Motor alle 5 sekunden zum beispiel eine Kugel losschickt weil mit MotorDir(Break,Break); und mit Msleep funktioniert es nicht gewünscht.

i_make_it
05.05.2017, 20:22
Geh mal in die Richtung:
https://www.roboternetz.de/community/threads/44996-ASURO-Timer?p=430956&viewfull=1#post430956

luba1248
06.05.2017, 08:17
Danke für den Tipp leider funktioniert das nicht, da es eine ähnliche Funktion wie Msleep ausführt.
Ich bräuchte einen befehl der in meiner Schleife eine zeitbegrenzte Schleife startet in der der Auswerfmotor nicht inbegriffen ist, so dass das Programm meine Fototransistoren in dem Zeitraum wo die Kugeln vorbeirollen ausließt. Anschließend den Sortiermotor bewegt und dann die Schleife wieder beendet und zum Auswerfmotor springt. ?!

021aet04
06.05.2017, 11:50
Du hast verschiedene Timer, die Interrupts auslösen können. Somit kannst du Zähler bauen die bei einem Interrupt hochzählen und darauf reagieren.

PS: Codes bitte mit Codetags versehen.

MfG Hannes

i_make_it
06.05.2017, 11:59
leider funktioniert das nicht, da es eine ähnliche Funktion wie Msleep ausführt.


Ganz und gar nicht.
http://www.asurowiki.de/pmwiki/pub/html/time_8c.html
Gettime ist zwar wie Mssleep in der time.c, aber der Befehl holt nur die Systemzeit.
Damit macht man eine Zeitbegrenzte Schleife.
Bei jedem Durchlauf des Hauptprogramms holt man einmal mit Gettime die Systemzeit unf schreibt sie in Variable A.
Da wo die Wartezeit ablaufen soll, definiert man einen Wert für die Wartezeit (C)und übergibt dann einmal! den Wert der Variablen A in eine andere Variable B.
Danach vergleicht man immer nur ob A minus B kleiner ist als C.
Solange die Bedingung erfüllt ist lässt man die Motorvariable auf aus, sonst auf an.

luba1248
06.05.2017, 15:02
Okay dann tut es mir leid ich probiere es nochmal bin nur etwas unfähig... Danke noch

i_make_it
07.05.2017, 09:04
Ich habe nicht viel mit dem Asuro gemacht, und es ist schon etwas her.
Aber ich habe Deinen Code erst mal etwas besser lesbar formatiert.

Über fähig und undfähig sollte man nicht entscheiden, wenn man grade erst anfängt etwas zu lernen.
Wenn nach längerer Zeit, intensiven Befassen mit einem Thema keinerlei Verbesserung der Fähigkeiten messbar ist, dann kann man von Unfähigkeit sprechen.
Momentan von, noch unwissend und noch unerfahren.

Da es eine Referenz gibt, kann man dort nachlesen was die Befehle machen, das ist immer ganz hilfreich um sich über die Möglichkeiten die man hat zu informieren.
http://www.asurowiki.de/pmwiki/pub/html/asuro_8h.html

Die folgenden Asuro spezifischen Befehle nutzt Du:



FrontLED (unsigned char status)
Steuert die vorne, nach unten zeigende, Front-LED.

LineData (unsigned int *data)
Liest die Daten der beiden Linienverfolgungssensoren.
Die Linien-Beleuchtungs-LED kann sowohl an- als auch ausgeschaltet sein.

MotorDir (unsigned char left_dir, unsigned char right_dir)
Steuert die Drehrichtung der Motoren.

MotorSpeed (unsigned char left_speed, unsigned char right_speed)
Steuert die Geschwindigkeit der Motoren.

Msleep (int ms)
Wartefunktion in ms.




01#include <avr/io.h>
02#include "asuro.h"
03
04int main(void)
05{
06 Init();
07 unsigned int data[2]; //Initialisiert zwei Int-werte hintereinander
08 FrontLED(ON);
09
10 Msleep(1000);
11 while (1)
12 {
13 LineData(data);
14 if ((data[0]<700) && (data [1]<700))
15 {
16 MotorDir(FWD,FWD); //beide Motoren vorwärts
17 MotorSpeed(85,0); //linker Motor speed 85
18 Msleep(160);
19 MotorSpeed(0,0); //beide Motoren halt
20 Msleep(3000);
21 MotorDir(RWD,RWD); //beide Motoren rückwärts
22 MotorSpeed(85,0); // linker Motor speed 85
23 Msleep(160);
24 MotorSpeed(0,0); //beide Motoren halt
25 }
26 if ((data[0]>700) && (data[1]>700))
27 {
28 MotorDir(FWD,FWD); //beide Motoren vorwärts
29 MotorSpeed(0,0); //beide Motoren halt
30 }
31 if ((data[0]>700) && (data[1]<700))
32 {
33 MotorDir(RWD,RWD); //beide Motoren rückwärts
34 MotorSpeed(85,0); // linker Motor speed 85
35 Msleep(160);
36 MotorSpeed(0,0); //beide Motoren halt
37 Msleep(3000);
38 MotorDir(FWD,FWD); //beide Motoren vorwärts
39 MotorSpeed(85,0); // linker Motor speed 85
44 Msleep(160);
41 MotorSpeed(0,0); //beide Motoren halt
42 }
43 MotorDir(FWD,FWD); !!!!!!!!!!!! //beide Motoren vorwärts
44 MotorSpeed(0,100); // rechter Motor speed 100
45 Msleep(480);
46 MotorSpeed(0,0); //beide Motoren halt
47 }
48}


Alleine durch das Einrücken bekommt man schon mal ein Gefühl für die Struktur des Codes.

Was einem sofort ins Auge springt, sind in Zeile 14, 26 und 32 die IF Anweisungen die direkt aufeinander folgen.
Man könnte jetzt in Zeile 26 und 31 aus IF ein ELESE IF machen.

Dann hat jedes Asuro Codebeispiel das ich habe ein return (0); nach der while (1); Schleife.
Also:



47 }
48 return (0);
49}


Das hat jetz noch nichts mit der Funktion Deines Codes zu tun, hilft aber sauberen Code zu produzieren, der Dir nicht Später mal mit unerwarteten Fehlern um die Ohren fliegt.

Soweit ich das sehe nimmst Du die FrontLed als Lichtquelle und die beiden Linienfolger Sensoren LineData um mit den IF Konstruken 3 Zustände zu unterscheiden.
Dort findet dann eine reine Zeitsteuerung des linken Motors statt.
Immer 0,16 Sekunden Fahren mit rund 33% der möglichen Motorgeschwindigkeit (85 von 255) und 3 Sekunden Stillstand.
Am Ende lässt Du den rechten Motor für 0,48 Sekunden mit rund 39% der möglichen Motorgeschwindigkeit (100 von 255) laufen.

Der rechte Motor wird nun außerhalb des IF Konstrukts angesteuert. Also unabhängig davon was für Werte LineData hat.
Ergänz Doch mal Deinen Coder zuert um das return (0);
und dann definier doch mal ein Motor Halt am Anfang der WHILE Schleife, damit die Motoren erst mal sicher gestoppt sind.



.
.
.
11 while (1)
12 {
13 MotorDir(FWD,FWD);
14 MotorSpeed(0,0); //beide Motoren halt
15 LineData(data);
.
.
.
45 MotorDir(FWD,FWD); !!!!!!!!!!!! //beide Motoren vorwärts
46 MotorSpeed(0,100); // rechter Motor speed 100
47 Msleep(480);
48 MotorSpeed(0,0); //beide Motoren halt
49 }
50 return (0);
51}

luba1248
07.05.2017, 21:49
Hallo,
erst mal wollte ich sagen, dass ich es echt super finde, wie nett man hier unterstützt wird. Danke
Leider war ich heute und gestern Abend verhindert durch eine Konformation. Deshalb habe ich mich nicht direkt dahinter gesetzt und mich gemeldet.

Ich habe die Verbesserungsvorschläge umgesetzt und hatte auch schon else vor dem 2. und 3. if aber ohne hat das Program auch funktioniert. Weshalb mir die bedeutung davon nicht ganz klar war.

Wie gesagt setzt der Eine motor zum Falschen Zeitpunkt ein.
Das will ich Sie mir sagten mit Gettime versuchen zu unterbinden. Nur ist mir die Gettime Funktion nicht ganz klar.
Wie man die Begriffe (bei mir in der asuro lib ) nachließt und sie definiert sind ist mir klar und ich verstehe auch einiges nur die time.c beziehungsweise das Gettime darin nicht. Wenn ich nun dieses Programm, so wie ich es dastehen habe auf den Aduro flashe, müsste dann die Front LED alle 500 ms oder beispielsweise alle 5000 ms an und ausgehen?
Beziehungsweise macht sie nicht nach dem flashen...

#include <avr/io.h>
#include "asuro.h"
#include "myasuro.h"
int main(void)
{ // Alle 500 ms die Front-LED umschalten.
unsigned long zeit;
unsigned char on_off = TRUE;
zeit = Gettime ();
while (1)
{
if (Gettime () > zeit + 500)
{
zeit = Gettime ();
FrontLED (on_off);
on_off ^= 1;
}
}
}

Könnte mir vielleicht einer etwas dieses Programm erklären weil mir nicht ganz klar ist was on _ off bedeutet genauso dieses hoch gleich eins. Ich habe versucht, mir das klarzumachen und die Gettime Funktion in mein Programm einzubinden doch leider konnte ich mir das nicht ganz erklären.
Ich wurde leider in die ganze Thematik kopfüberhineingeworfen und bekomme wenig schulische Unterstützung. Und mein ziehl war es etwas eigenentwickeltes mit dem ASURO zu entwerfen und nichts vorhandenes zu kopieren. Leider ist mir die Informatik doch etwas fremd, wenn ich sie auch sehr interessantfinde ... Nur falls ihr euch wundert warum ich sowenig kenntnisse habe.

PS: ich hoffe, dass das nun mit dem Code stimmt 😬

i_make_it
07.05.2017, 22:57
unsigned char on_off = TRUE;

Das ist die Definition der Variable mit dem Namen "on_off".
Die Variable ist vom Typ char (also max. 265 verschiedene Zustände, 0-255).
Und sie ist unsigned (also ohne Vorzeichen, mit wäre der Wertebereich -128 bis 127)
Die Variable wird mit dem Wert TRUE (wahr) also 1 vorbelegt



on_off ^= 1;

Um diese Zeile zu verstehen, muß man die Operatoren in C/C++ kennen.
http://www2.informatik.uni-halle.de/lehre/c/c_operat.html
^= bitweises XOR (exklusives OR)

Damit wird also der Wert bei jedem Ausführen von Binär 0 auf Binär 1 und zurück geändert.
Es ist die kürzeste Schreibweise um in C ein Bit zu Togglen.
Der lange Weg wäre:


if (on_off == 1)
{
on_off = 0;
}
else if (on_off == 0)
{
on_off = 1;
}


Du mußt Dich also zum einen mit der Programiersprache C/C++ generell und zum anderen mit den Besonderheiten des Asuro befassen um den Code von Beispielen verstehen zu können und selbst sinnvollen und funktionsfähigen Code schreiben zu können.

021aet04
08.05.2017, 08:39
Ich kann dir auch das Avr gcc Tutorial von Mikrocontroller.net empfehlen https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial

Und bitte den Code in codetags schreiben (code) dein code (/code). Statt den runden Klammern nimmst du eckige.

Dann sieht es so aus

dein code

MfG Hannes

luba1248
08.05.2017, 11:34
Ich probier es mir beizubringen Problem ist nur das man das ganze in 2 Monaten lernen soll und daher nur oberflächlich schrammt weil keine Zeit da ist um einen ganzen c kurs oder ähnliches zu machen.
Und irgendwie wird mir von dem benutzen von Gettime abgeraten weil es zu komlex für die Schule sei.
Aber ich schau mal vieleicht wird es mir noch schlüßig
Danke :)