Hallo,
suche ein Entwicklerboard mit Eigenschaften, die dem Conrad c-control 2
+ Applicationboard (Tastatur, Display etc.) entsprechen.
Es geht um die Steuerung einer Umspulmaschine (3 Motoren, 3 Encoder, 1
Endlagenschalter), die mit Conrad aufgrund der schlechten
Entwicklungsumgebung nicht machbar ist (gehen müsste es, tut es aber
nicht - die Sache mit dem OS ist ein Kreuz).
Gibt es etwas preisgünstiges, flottes, das auch für Leute, die keine
Cracks sind, zugänglich ist? Ich würde mich freuen, wenn es etwas gäbe,
bei dem man nicht irgendwie noch Funktionen für Tastatur und/oder
Display-Ansteuerung zusammenbasteln müsste und ein Spannungswandler
dabei wäre, der den Anschluss an 24Volt erlaubt, ohne dass die Masse
das Potential ändert.
Freue mich auf Antwort!!!!
Erich
Hallo Erich
Ich weiss ja nicht genau was Deine Maschinen genau können muss.
Vielleicht kommst du aber mit einem Logo-Modul von Siemens (kleine SPS)
aus.
Beste Grüsse
Geri
PS: Arbeite nicht bei Siemens oder habe oder erwarete mir dadurch
iregendwelche Vorteile;)
wenn du schon ein C-Controll 2 da hast, dann einfach das OS löschen und
in C oder ASM das Ding programmieren.
So habe ich es zumindest gemacht. Da mich das OS auch genervt hatte.
Jo, würd ich auch gerne mit Keil machen. Aber abgesehen davon, dass ich
mich damit NULL auskenne und somit das Programm nicht übersetzen kann,
weiß ich nicht, wie ich die Sache flashen soll.
Danke trotzdem!
ich hatte nen GNU Compiler der Firma HighTec, Das flashen ist ein
problem, zumindestens wenn man den gesamten Speicher braucht.
Mein Programm war ca. 30 Kb groß. Das ging in den 1 Sektor und dafür
habe ich zum flashen das Conrad flashtool benutzt. Geht ganz gut.
Oder man schreibt sich selber ein Bootloader. Na ja ich hatte keine
Zeit mehr gehabt, sonst hätte ich mir bestimmt einen geschrieben.
Ach es gibt bei ccnet oder so auch ein Tool.
beschreib doch mal die Ansteuerung der Motoren Encoder Endschalter
usw. und auch was passieren soll - evtl. geht es mit weit weniger
Aufwand? Hört sich nicht so kompliziert / aufwendig an...
Also:
Es soll ein Gut von einer Spule auf die andere gewickelt werden - beide
Spulen werden angetrieben. Die eine (nehmende Spule) wird von einem
Selbstbauencoder bzgl. der Geschwindigkeit geregelt und die andere
(gebende) von einem Tänzer gesteuert, um die Zugkraft unter Kontrolle
zu halten. Dann is da noch die Führung an einer Wandermutter, die über
ein Motorgetriebenes Gewinde bewegt wird. Der Encoderwert muss pro
Zeiteinheit in einem bestimmten Verhältnis zu dem der nehmenden Spule
sein - an einem bestimmten Punkt (abhängig von der gewählten
Trommelbreite) muss der Motor exakt in die andere Richtung drehen. Da
momentan ein Pulsverhältnis von 50% "Stopp" bedeutet, würde das ein
Schalten von X% auf 100%-X% heißen. Das wird aber noch geändert: am
inversen Motorsteuerungseingang ist momentan ein Spannungsteiler, aber
es soll stattdessen ein Port auf 1 und 0 geschaltet werden -> Ergebnis:
höhere mögliche Geschwindigkeit und Stopp bei einem Pulsverhältnis von
(warum ich nicht gleich darauf gekommen bin....????).
hier der QT in C2:
//------------
thread main
//------------
{
ports.getcount(3);
ports.getcount(1);
ports.getcount(2);
lcdext.init();
/*----------------------------------------------------------------------
---
Index 0 bezieht sich auf aufwickelnden Motor
Index 1 bezieht sich auf Faser-lenkenden Motor
Index 2 bezieht sich auf abwickelnden Motor
a, b und c werden noch festgelegt
------------------------------------------------------------------------
-*/
int
timPer,
RAbstand, TrommelBreite, VWickel, LWickel,
Hoehe[3],
tTor,
Puls0[3], Puls1[3], Puls2[3],
TrommelAbstand, Trommelbreite, counter, count1, count2, boolturn,
turncount, ok, stopp, temp;
float
a, b, c, FD, increment, decrement;
long
timerPuls, timerTor, tA, tAvgl, laenge, Lagen, laengencount,
lagencount,
port0cnt[3], port1cnt[3], port2cnt[3];
string s;
ports.getcount(1);
ports.getcount(2);
ports.getcount(3);
ports.deact(8);
ports.deact(9);
ports.deact(10);
ports.deact(11);
ports.deact(12);
boolturn = 0;
increment = 0;
decrement = 1;
timPer = 3000;
plm.setperiod(0, timPer);
plm.setperiod(1, timPer);
plm.setperiod(2, timPer);
counter = 0;
count1 = 0;
count2 = 0;
turncount = 0;
a = 2; b = 1; c = 1;
port1cnt = 0;
port2cnt = 0;
loop
{
plm.out(1,0);
if ports.get(12) != 0
break;
}
plm.out(1, 1500);
plm.out(0, 0);
plm.out(2, 0);
Puls1[0] = 1500; Puls1[1] = 1500; Puls1[2] = 1500;
Puls0[0] = 0; Puls0[1] = 0; Puls0[2] = 0;
Puls2[0] = 0; Puls2[1] = 0; Puls2[2] = 0;
lagencount = 0;
laengencount = 0;
timerPuls = system.timer();
tAvgl = system.timer();
timerTor = system.timer ();
tTor = 1500;
tA = 500; // Abtastzeit
ok = 0;
loop
{
if (ok == 1)
break;
laenge = 0;
s = "Laenge dm?";
lcdext.goto(1, 0);
lcdext.print(s);
laenge = 50*keyboardmod.getvalue(2,0);
lcdext.clear();
Lagen = 0;
if laenge == 0
{
s = "Lagen";
lcdext.goto(1, 0);
lcdext.print(s);
Lagen = keyboardmod.getvalue(2,0);
lcdext.clear();
}
TrommelAbstand = 0;
while(1==1)
{
if (TrommelAbstand != 0)
break;
s = "TrAbst mm";
lcdext.goto(1, 0);
lcdext.print(s);
TrommelAbstand = 125*(keyboardmod.getvalue(2,0)- 28);
lcdext.clear();
}
Trommelbreite = 0;
loop
{
if (Trommelbreite != 0)
break;
s = "TrBreit mm";
lcdext.goto(1, 0);
lcdext.print(s);
TrommelBreite = TrommelAbstand + 125*keyboardmod.getvalue(2,0);
lcdext.clear();
}
FD = 0;
loop
{
if (FD != 0)
break;
s = "Faserd. in um?";
lcdext.goto(1, 0);
lcdext.print(s);
FD = keyboardmod.getvalue(2,0)/4000;
lcdext.clear();
}
s = "1 = ok";
lcdext.goto(1, 0);
lcdext.print(s);
ok = keyboardmod.getvalue(2,0);
lcdext.clear();
}
counter = ports.getcount(2);
// Wickelführung: Position anfahren
temp = 0;
// while temp < TrommelAbstand
loop
{
temp = temp + ports.getcount(1);
plm.out(1, 2300);
if temp >= TrommelAbstand
break;
}
plm.out(1, 1500);
//Zähler auf Null setzen
stopp = 0;
// while stopp == 0;
loop
{
if (stopp != 0)
break;
//Abbruchbedinungen:
if ((Hoehe[0] < 100) and (increment == 1))
or ((Lagen != 0) and (lagencount == Lagen))
or ((laenge != 0) and (laenge <= counter))
stopp = 1;
//Steuerung der gebenden Trommel abhängig von der Höhe des
Abstandsmessers
if ((system.timer()-tA) >= tAvgl);
{
Hoehe[0] = ports.adc(0) - 500;
//500 wird etwa die Mitte sein... also das Soll
// Achtung! Hier umgekehrt verfahren!!!! bei steigender Höhe Puls
erhöhen!
// ==> + Hoehe[0] und - den Rest!
Puls2[0] = Puls2[2] + a*Hoehe[0] - b*Hoehe[1] - c*Hoehe[2];
//--------------------------
/* hier Regelalgorithmus für die Kraft (PID)
als Basis wird diese digitale Übertragungsfunktion verwendet:
v[k] = v[k-2] - a*u[k] + b*u[k-1] + c*u[k-2]
wobei a = (R1*R2*C1*C2 + 2*R1*C1*tA + 2*R2*C2*tA)/(2*R0*C2*tA)
b = (R1*R2*C1*C2)/(2*R0*C2*tA)
c = (4*R1*R2*C1*C2 - 2*R1*C1*tA - 2*R2*C2*tA)/(2*R0*C2*tA)
die Schaltung, aus der ich diese Algorithmen per bilinearer/Tustin-
Transformation zusammengestöpselt habe, sind auf dem Link ganz unten
zu ersehen
*/
//--------------------------
//Achtung: Reihenfolge
Hoehe[2] = Hoehe[1];
Hoehe[1] = Hoehe[0];
tAvgl = system.timer();
plm.out(2, Puls2[0]);
}
// Abtasten - Encoder der "Zugtrommel". Steuerung der Wickelführung
// abhängig von der Faserstärke. Vergleich mit Encoderwert der
Wickelführung
if ((system.timer()-tTor) >= timerTor);
{
port0cnt[0] = ports.getcount(3)/51;
count1 = ports.getcount(1)/128;
if boolturn == 0
turncount = turncount + count1;
if boolturn == 1
turncount = turncount - count1;
port1cnt[0] = count1 - port0cnt[0] * (FD);// *x/y nicht
vergessen!!!!!
// p1i soll p0i*x/y ... FD ist die Faserstärke, "4" die
Schneckensteigung -
// also das Umdrehungsverhältnis
Puls1[0] = Puls1[2] - a*port1cnt[0] + b*port1cnt[1] +
c*port1cnt[2];
if (Puls1[0] > 100)
Puls1[0] = 100;
//--------------------------
// hier "standard"Regelalgorithmus (PID)
//--------------------------
//Achtung: Reihenfolge!
Puls1[2] = Puls1[1];
Puls1[1] = Puls1[0];
port1cnt[2] = port1cnt[1];
port1cnt[1] = port1cnt[0];
timerTor = system.timer();
// so: und um boolturn zu setzen, muss die verfahrene Strecke genau per
interrupts abgezählt worden sein.
// dann wird abgefragt, ob der Zählerstand einem "RAbstand + RBreite"
entspricht
if (turncount > Trommelbreite) //fiktive Trommelwerte!
{
boolturn = 1;
lagencount = lagencount + 1;
};
if (turncount < TrommelAbstand)
{
boolturn = 0;
lagencount = lagencount + 1;
};
if (boolturn == 0)
plm.out(1, Puls1[0]);
else
plm.out(1, timPer - Puls1[0]);
// Abtasten des "Selbstbau-Encoders" an der Führungsrolle.
// Steuerung der Zugtrommel
count2 = ports.getcount(2);
// Längenmessung - auch hier wäre eine genaue Zählung unheimlich
praktisch
counter = counter + count2;
if ((counter + (5*count2)) >= laenge)
decrement = decrement - 0.2;
/////////////////////////////////////////////////////////////////////
if (decrement < 0)
decrement = 0;
port2cnt[0] = count2 - decrement*3; //Sollwert soll per Poti
eingestellt werden
// Geschwindigkeit langsam senken:
//--------------------------
// hier "standard"-Regelalgorithmus (PID)
//--------------------------
Puls0[0] = Puls0[2] - a*port2cnt[0] + b*port2cnt[1] +
c*port2cnt[2];
//Motor "0" wird ja von Eingang "2" beeinflusst
Puls0[2] = Puls0[1];
Puls0[1] = Puls0[0];
port2cnt[2] = port2cnt[1];
port2cnt[1] = port2cnt[0];
timerTor = system.timer();
// mit increment wird versucht, die Maschine langsam anzufahren
if (increment < 1)
increment = increment + 0.05;
//////////////////////////////////////////////////////////////////////
plm.out(0, increment*Puls0[0]);
}
}
plm.out(1, 3000);
lcdext.clear();
s = "Laenge: ";
str.putint(s, counter);
lcdext.goto(1, 0);
lcdext.print(s);
s = "Lagen: ";
str.putint(s, lagencount);
lcdext.goto(2, 0);
lcdext.print(s);
sleep 3000;
plm.out(1, 1500);
halt;
}
Wow.. mit was für einem Aufwand man 2 Spulen drehen kann :-) Mit
"Quältext" hast Du nicht übertrieben, etwas mehr Struktur
(Unterprogramme, Prozeduren, Funktionen, Alias-Namen) wären ganz
angenehm.
Auch habe ich aus Deiner Beschreibung trotz gedanklicher
Übersetzungsversuche einiger Begriffe (Selbstbauencoder = Impulsgeber?,
Tänzer = Fliehkraftregler?, inverser Motorsteuerungseingang =
Schrittmotor?) beim besten Willen nicht richtig herauslesen können, wie
das Ganze funktionieren soll. Mach doch mal ein Foto.
Nicht desto trotz, wenn es Dir um das eingangs genannte Problem geht,
kannst Du mit einem AVR (selbst ein Mega8 sollte das o.g. problemlos
schaffen) loslegen. Wenn Du klein und kostengünstig anfangen willst und
nicht so viel Zeit investieren, kannst Du z.B. BasCom oder C (wie hier
im Tutorial gezeigt) und eine Steckplatine verwenden. Dreh mal an
Deiner Spule, und laß Dir die Impulse anzeigen usw. (Display einrichten
kostet nur 1-2 Zeilen Quelltext..) usw.
Andererseits - wenn Du so ein kompliziertes Programm wie oben auf die
Beine gestellt hast - dannn wirst Du doch am Programmieren der
C-Control nicht scheitern? Auch dafür gibt es ein Forum.. Daß das o.g.
Programm schwer zu debuggen ist, glaube ich sofort lächel wegen
"Strukturschwäche"
Also nachteilig ist natürlich die fehlende Farbe - das hilft bei der
Übersicht echt extrem.
Der Selbstbauencoder ist nichts anderes als eine der Führungsrollen mit
8 metallenen Schrauben, die sich an einem Endlagenschalter vorbei
bewegen -> Drehzahl- und Längenmessung.
Der Tänzer ist eine nach oben und unten frei bewegliche Führungsrolle.
Er soll in etwa in der Mitte stehenbleiben. Am Träger des Tänzers
befindet sich ein induktiver Abstandssensor, der eine schiefe Ebene
abtastet und einen Strom liefert (über einen Widerstand als Spannung in
einen AD-Port). Ich kucke mal, was ich Bildern hier reinbringe.
Und eine Bitte: sagt nix vom CControl-Forum. Habs da schon versucht und
mir konnte keiner erklären, warum der Controller eine Endlosschleife
nicht unendlich lang ausführt. War ein Testprogramm.
Nunja, ein ATMega dürfte das schaffen.
Die Position des "Tänzers" bestimmt die Verstellung der
Abwickelmotordrehzahl.
Die Umlenkrolle mit "Encoder" ermittelt die umgespulte Länge. Dieser
Eingang müsste natürlich aufgrund der mechanischen Kontakte ordentlich
entprellt werden.
Für die Steuerung der "Führung" sollte aber die Aufwickelspule noch
eine Drehzahlerfassung ("Encoder") bekommen, da die Führung von den
Umdrehungen der Aufwickelspule abhängig ist und nicht von der per
Umlenkrolle ermittelten Umspullänge / Umspulgeschwindigkeit.
Dazu noch ein Text-LCD, einen Drehgeber (mit Taster) oder 4 Taster fürs
Menü, und man kann einstellen, wieviele Meter Material das Ding umspulen
soll. Alternativ könnte das Teil via UART vom PC gesteuert werden.
Um noch etwas Reserve bei den I/O-Pins zu haben, würde ich einen
ATMega8535 einsetzen und in ASM programmieren. In anderen
Programmiersprachen hätte man mit dem Mega16 etwas Reserve bei der
Codegröße.
...
würde mich interessieren für welchen Zweck das genau ist? Willst du
Film- oder Tonbandrollen aufspulen?
"Die Position des "Tänzers" bestimmt die Verstellung der
Abwickelmotordrehzahl." Wandert der Tänzer je nach Geschwindigkeit
oder was ermittelst du hier genau. Ich würde den gefederten Tänzer als
Endanschlagerkennung nehmen wenn also die Spule zu Ende gezogen wird
schlägt der Tänzer aus und das könnte man mit nem Endschalter erkennen
und dann den Motor abschalten, dann wäre das für das Band oder was du
sonst transportierst nicht so brutal. Zum gezielten abbremsen kannst du
ja den Motor Impulsweise in die entgegengesetze Richtung betreiben.
Du verwendest einen mechanischen Kontakt? Nervt dich das Tckern oder
klickern nicht. Hier solltest du nen Induktiv- oder Hallgeber oder
sogar ne Lichtschranke verwenden, das ist ersten geräusch- und
verschleißfrei. Ein Hallgeber-IC kostet um 1 und dann noch ein
Stabmagnet denn du in mehrere Stücke sägst und deinen Endcoder damit
bestückst. Es gibt auch fertige Gabellichtschranken inkl.
Winkelscheiben.
Keine Angst den Speicher des AVRs wirste damit nicht voll bekommen
Habe noch eine Idee zur Erkennung der Geschwindigkeit. Du könntest auch
nen LM2907 (ist ein Frequenz zu Spannungswandler) verwendet dieser
bekommt die Impulse deines Encoders zugeführt und macht daraus eine
Spannung die du ganz einfach per ADC einlesen kannst. Dann sparst du
dir schonmal die Arbeit mit den Timern.
Hmm?!?? Was sind daran dumme Gedanken? Aber bitte.
Hallo Leute, schaut euch doch bitte Quelltext und Bild nochmal an.
Alles, was ihr hier fragt ist im Bild oder im Quelltext schon
ersichtlich (was umgespult wird, ob dieser und jener Encoder da ist,
dass ich keinen EL-Schalter für den Tänzer brauche etc. etc. etc.).
Ansonsten sei noch anzumerken: induktive Endlagenschalter sind aufgrund
ihres Schmitt-Triggers bereits entprellt. Da ist auch keine Mechanik
drni.
Vielleicht sollte ich nochwas erwähnen: ASM mach ich nicht, weil ichs
noch weniger kann.
Ich will in erster Linie mein fertiges Programm in C haben und das dann
flashen können.
Hallo,
also ich würde dir auch einen AVR empfehlen, da kannst du z.B. einen
Mega16 nehmen, der hat sicher genügend IOs und auch genug Flash
(16kB).
Deine drei Motoren hängst du an die Hardware-PWMs. Einziges Problem
dürfte da die Steuerung der Wandermutter sein, da wäre es besser, es
wäre ein Schrittmotor dran, geht aber sicher auch so. Ist natürlich
Voraussetzung, dass dein "Encoder" genügend hoch auflöst, damit da
mindestens ein Impuls pro Spulenumdrehung kommt, das Ganze ist da dazu
da, die Spule schön gleichmässig aufzuwickeln, oder?
Beim Starten des Wickelvorgangs fährst du mit dem Motor an der
wickelnden Spule per PWM eine Rampe hoch. Damit wird die Faser erstmal
gespannt. Je höher der Tänzer dann geht, desto schneller lässt du den
abwickel-Motor drehen. Wenn der Tänzer ein analoges Signal liefert,
dann kannst du damit möglicherweise sogar direkt den PWM-Ausgang für's
Abwickeln steuern ohne überhaupt irgendwas zu rechnen.
So gesehen überhaupt kein Problem für den Controller, wenn du nicht
noch irgendwo eine Falle eingebaut hast ;)