PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ProBot mit asuro-Mega8



radbruch
13.08.2009, 12:02
Hallo

Der ProBot (zum selbst Zusammenlöten) wird ohne Kontroller geliefert. Da liegt es doch nahe selbst einen Kontroller draufzubasteln. Wegen der Ähnlichkeit beider Roboter würde sich dazu der ATMega8 des asuros geradezu aufdrängen. Ein vergleichender Blick in die Schaltpläne der beiden zeigt ähnliche bis teilweise identische Bestückungen:

Netzteil: Nahezu identisch. ProBot mit Ladefunktion und stromfressender Status-LED. Aref und Spannungsteiler für Batteriemessung identisch:)

IR: Empfänger hat beim ProBot günstigeren Wert (R11), Senden mit drei LEDs in Reihe (D6-8) scheint mir mit 150 Ohm in Reihe etwas schwach. Beides sollte aber mit dem Mega8 auch funktionieren.

Odo: ProBot hat kleineren Vorwiderstand vor den LEDs (R5), Empfänger identisch.

Line: Identisch bis auf R1/3 (20k-22k;)

Motor: ProBot benötigt drei Pins, asuro sechs. Das sollte funktionieren.

Taster: Der Reset-Taster geht wohl direkt auf den Reset-Pin, Boot-Taster an Tastenpin des asuro. Passt.

LEDs: Zwei LEDs ersetzen die StatusLED.

I2C: Der Mega8 kann auch das EEPROM des ProBot verwenden.

Sound: Irgendwann gehen dem Mega8 die Pins aus. Durch die gesparten Motorpins könnte man noch den Lautsprecher bedienen und das Mic könnte am ADC4 des Mega8 angeschlossen werden (Boot-Taster dann auf gespartem Motorpin).

ACS: Wenn das oben alles funktioniert ist noch ein Pin fürs ACS übrig :)


Für die Verdrahtung des Adapters sehe ich eigentlich zwei Ansätze:

Nach ProBot-Belegung: Soweit möglich werden die Pinbelegungen des Mega128 übernommen. Basis für die Software wird die ProBot-Library sein. Diese wird nach GCC übersetzt und an den Mega8 angepasst.

Nach ProBot-Belegung (mit angepasster asuro-Lib): Die Funktionen werden, soweit möglich, wie beim ProBot angeschlossen. Die asuo-Library wird an die geändete Pinbelegung angepasst.

Nach asuro-Belegung: Die ProBot-Hardware imitiert den orginalen asuro-Aufbau, Änderungen in der asuro-Lib für Motor, Tasten und alles was der orginale asuro-Aufbau nicht kann. Die Variante werde ich in Angriff nehmen.

Die Kosten für das Projekt halten sich in Grenzen. Neben dem ProBot (Bausatz) benötigt man einen Adapter der nur ein paar zusätzliche Bauteile benötigt: Den 8MHz-Quarzschwinger, ein paar Kondensatoren, der Reset-Pullup, Sockel für Mega8, Stiftleisten zum Aufstecken auf den Probot und ein (geätztes?) Platinenstück. Zusätzlich benötigt man noch den asuro-Mega8 und einen IR-USB-Transceiver. asuro-Besitzer (wie ich) benötigen dagegen nur den Probot-Bausatz:)

Wenn alles so funktioniert erhält man einen gut erweiterbaren asuro oder einen ProBot ohne Conrad-Software. Der nächste Schritt wäre dann noch der Einsatz eines ATMegas (8 oder 32) ohne Bootlader. Mal gespannt was draus wird.

Gruß

mic

[Edit]
Titel geändert

Robotniks
13.08.2009, 13:36
Hallo Radbruch,

die Idee finde ich nicht schlecht, bin mal gespannt wenn du fertig bist.

Grüße Robotniks

oberallgeier
13.08.2009, 14:21
Ja mic, das hört sich wirklich gut an.

Wenn Du schon von Erweiterungen sprichst - und von Kompatibilitäten - dann wäre es zu überlegen, ob man statt des mega8 einen mega328p nimmt. Die Pinbelegung ist "gleich", beim 328 mit erweiterten Funktionen - allerdings anderen Steuerregistern.

Mir war der m8 von Anfang an etwas sparsam mit Speicherplatz ausgerüstet, daher hatte ich frühzeitig den 168 (experimentell auch am asuro) genommen. Jetzt bin ich auf den 328p umgestiegen: viermal soviel Speicher wie der m8. Das ist für so gnaden- bzw. ahnungslose C-Programmiere wie mich genug Reserve. Der Funktionsbereich ist breiter als beim 8L - nämlich bis 1,8V statt der 2,7V beim 8L. Andere Unterschiede sind gering. Die etwa 0,3V höhere Ansprechschwelle ("... VIH, I/O Pin read as ‘1’ ...") könnte eher von Vorteil sein. Zeitweise war ja eine 168er Bibliothek für den asuro im Gespräch - die würde 1:1 auch beim 328er passen.

Insgesamt glaube ich, dass bei der angesprochenen Anwendung die Vorteile die Nachteile z.B. durch die anderen Steuerregister aufwiegen können.

radbruch
13.08.2009, 15:11
Hallo


1 Stück
ROBOTERSYSTEM PRO-BOT128 BAUSATZ 191919 - ZA (http://conrad.de/goto.php?artikel=191919)
1 Stück
OSZILLATOR 8MHZ 158119 - ZA (http://conrad.de/goto.php?artikel=158119)

Gerade eben bestellt. Blöderweise konnte ich meinen 20€-Gutschein ('Burtstag) nicht einlösen weil die Online-Kasse meine Nummer nicht fressen wollte. Während ich auf's Päckchen warte könnte ich schon mal (ohne langes googlen) ein paar Infos einholen:

Sind die 16-poligen Stecker X1 bis X4 wirklich so asymetrisch aufgebaut wie es im Schaltplan (Doku S. 36 (http://www.produktinfo.conrad.com/datenblaetter/175000-199999/191919-an-01-de-ROBOTERSYSTEM_PRO_BO_128_BAUSATZ.pdf)) dargestellt ist?

Conrad bietet keinen dreibeinigen Quarz-Oszillator an. Funktioniert mein Ersatztyp? Wie müßte ich den anschließen?

Wie erkennt der Motortreiber (IC2, CD4093 (http://pdf1.alldatasheet.com/datasheet-pdf/view/50862/FAIRCHILD/CD4093.html)) die Drehrichtung?

Könnte man die orginale ProBot-Programmierschnittstelle irgendwie nutzen? Verwendet die auch einen Bootlader?

Im Moment orientiere ich mich am orginalen asuro-Mega8. Es könnte im Sockel natürlich auch ein anderer Mega thronen. Speichergrenzen hatte ich bisher noch nicht erreicht. Vielleicht liegt die Begrenzung aber auch eher bei mir. Nettes Sommerlochthema :)

Gruß

mic

Robotniks
13.08.2009, 15:51
Hallo Radbruch,

ja die sind asymmetrisch aufgebaut.
Den Oszillator versorgst du mit Vcc und GND, am
Singalout-Pin kommt das Signal raus das du am
Controller am XTAL1 anschließt. Du könntest aber auch
den internen Oszillator benutzen?!

Der Motortreiber ist so aufgebaut das bei einen Puls- Pausenverhältnis
von 50% oder eben 1:1 der Motor steht (Bremsen). Bei einer 8Bit
PWM-Auflösung wäre Stopp der Wert 128, vorwärts größer 128 und ein Wert kleiner 128 rückwärts.

http://www.datasheetcatalog.org/datasheet/texasinstruments/l293.pdf
Siehe Seite 8.

Die Original Schnittstelle geht an den TxD und RxD des ATmega128. Die Programmierung des Asuro-Controllers könnte funktionieren.


Grüße Robotniks

radbruch
13.08.2009, 16:20
Hallo

Danke für die schnelle Antwort.


Du könntest aber auch den internen Oszillator benutzen?Leider nicht weil der asuro-M8 auf externen Oszillator eingestellt ist.


das bei...Puls- Pausenverhältnis
von 50% oder eben 1:1 der Motor steht (Bremsen)Das scheint mir etwas ungenau. Wenn genau so oft vorwärts wie rückwärts gefahren wird steht zwar der Antrieb, der Strom ist aber sehr hoch. War das PWM-Timing nicht auch hier das Problem?
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=49197


Bedenke auch das bei einen PWM Tastverhältnis von 1:1 also 50% der Stromverbrauch am größten ist! Also in der Software bis auf 50% fahren (Bremsen) und bei Stillstand des Roboters die Enable Leitung des L239D auf Low (Treiber "Aus").Aha. Und was macht man bei 49%? Beim asuro werden den Motoren immer nur die Leistung zugeführt die sie benötigen. Beim ProBot ist es halbe Leistung linksdrehend minus halbe Leistung rechtsdrehend. Noch weiß ich nicht wie das funktionieren soll.


Möglicherweise könnte man mit Kabel programmieren. Ich teste aber erst die IR-Schnittstelle ala asuro.

Gruß

mic

radbruch
14.08.2009, 17:07
Hallo

Inzwischen habe ich mir die Datenblätter der Motordriver-ICs und den Schaltplan genauer angeschaut. Schauderhaft! Im Plan fehlen wichtige Verbindungen (IC2:3-IC1:2) und das Konzept scheint mir falsch. Um niedrige Drehzahlen zu erhalten werden beide Richtungen gleichzeitig angesteuert. So stelle ich mir die Funktion einer PWM-Steuerung mit H-Brücken nicht vor. Deshalb "verbrät" der asuro auch sechs Pins nur um die Motoren anzusteuern. Vielleicht kann man aus dem IC2 noch eine Drehrichtung/PWM-Ansteuerung für beide Motoren rauskitzeln. Nötigenfalls mit zusätzlichen Leitungen zur Ansteuerung.

Kann das PWM-Signal beim L293D auch über Enable eingespeist werden? Dann könnte man die PWM-Leitungen direkt auf IC1:1/9 legen. Dazu müßte man nur die Enableleitungen vom IC1 trennen und mit den PWM-Ausgängen des Kontrollers verbinden. Die PWM-Eingänge am NAND wären dann Drehrichtungsauswahl. Damit könnte man den Motor dann zwar nicht kurzschliesen, aber PWM 0% wäre dann auch null Strom. Das würde auch gut zu MotorSpeed() und MotorDir() der asuro-Lib passen.

Gruß

mic

[Edit]
Der Schaltplan wurde inzwischen wohl richtiggestellt:
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=486143#486143

oberallgeier
14.08.2009, 17:24
... "verbrät" der asuro auch sechs Pins nur um die Motoren anzusteuern ...Hmm, ich verbrate auch sechs Pin für zwei Motoren. Mein Datenblatt von SGS THOMSON vom Juni 1996 nennt auch (Beispiel für eine Seite): 1 enable, 2 input1 und 9 input2. Enable ist der PWM-Eingang, input1 bzw. ~2 schaltet vorwärts oder rückwärts - wobei die jeweils gegensinnig bedient werden ==> ausgenommen man will bremsen, dann werden beide Eingänge high versorgt oder man stoppt, dann sind beide auf low. Das läuft bei mir und läuft und läuft . . .

radbruch
14.08.2009, 18:39
Hallo

Danke für die Infos.


Enable ist der PWM-EingangWunderbar. Dann verwende ich die orginalen PWM-Leitungen zum NAND zur Drehrichtungsauswahl an PB4/5 des Mega8, unterbreche die orginalen Enableleitungen am IC1 und verbinde diese (irgendwie) direkt mit OC1A/B des Mega8. Dadurch werden PD4 und PD5 frei.


ausgenommen man will bremsenEben, bei sechs Leitungen kann man jede Halbbrücke einzeln ansteuern und die Motoren bei Bedarf kurzschliessen. Mit vier Leitungen und dem NAND kann ich dann immerhin unbestromt stehenbleiben. Die Schutzdioden dürften zusätzlich bremsend wirken, wenn die Ausgänge auf Z geschaltet sind.

Die Tasterlösung gefällt mir noch nicht wirklich. Ich bin noch unentschieden ob ich den Tasten-ADC des asuros wirklich für das Mikrofon opfern soll oder ob ich hier besser die sechs Tasten des asuro nachbilde. Möglicherweise kann man das Signal aus dem Verstärker-IC3(LM386 (http://www.biltek.tubitak.gov.tr/gelisim/elektronik/dosyalar/6/LM386.pdf)) auch mit einem digitalen Eingang auswerten. (1-Bit-Sampling oder einstellbarer Schwellwert mit Poti als Ersatz für Ausgangsteiler R19/20).

Die StatusLed des ProBot (D5) ist LowCurrent, damit ist meine Anmerkung oben hinfällig. Die Vorwiderstände für die IR-LEDs (R12,D6-8 bzw. R13, D9-11) erscheinen mir ungünstig. Die verwendeten LEDs (TSUS520 (http://pdf1.alldatasheet.com/datasheet-pdf/view/26681/VISAY/TSUS520.html)) haben eine typische Vorwärtsspannung von 1,3V (max. 1,7). Das ergibt (5V-3*1,3V)/150Ohm=0,007A pro Strang bei möglichen 150mA (Peek 300). Da scheint noch mehr Potentional vorhanden zu sein. Wellenlänge ist übrigends 950 nm.

In der Doku werden folgende Motorfunktionen beschrieben:

DRIVE_INIT()
Initialisiert den Antrieb. Bevor der Antrieb benutzt wird, muss diese Routine aufgerufen werden.
DRIVE_ON()
Setzt den Enable-Eingang des L293D auf High. Der Antrieb ist eingeschalten.
DRIVE_OFF()
Setzt den Enable-Eingang des L293 auf Low. Der Antrieb ist ausgeschalten.
DRIVE(left as byte, right as byte)
Timer1 PWM für den Antrieb:
Werte zwischen 1 bis 128 = rückwärts
Werte zwischen 128 bis 255 = forwärts
Wert 128 = Antrieb stopp
Motor_POWER(left as byte, right as byte)
Geschwindigkeit, Werte zwischen 1 und 255
Es muss zuvor mit MOTOR_DIR die Richtung vorgegeben werden.
MOTOR_DIR(left as byte, right as byte)
Gibt die Drehrichtung der Motoren für die Funktion MOTOR_POWER vor.
1 = vorwärts
0 = rückwärts
MOTOR_STOP()
Motor wird gestoppt, PWM wird auf 128 gesetzt.Wird das MotorDir() reingerechnet? Gibt es öffentlichen Quellcode der ProBot-Lib?

Gruß

mic

Besserwessi
14.08.2009, 20:44
Bei den IR LEDs ist die Durchlassspannung oft deutlich unter 1,3 V, wenn man den Strom nicht bis 100 mA hat. Bei etwa 10 mA kann das auch mal nur 1 V sein. Damit kommt man dann auch auf einen Strom von rund 15 mA. Das scheint hier ja auszureichen und Strom sparen ist sicher nicht Verkehrt bei Batteriebetrieb.

Die originalschaltung zur Motorsteuerung sieht wirklich nicht gut aus. Änderungen sind da wirklich sinnvoll. Eine Steuerung mit 4 Leitungen sollte auch reichen.

Für den Takt braucht man nicht unbedingt einen Oszillatorbaustein. Ein Quarz reicht aus und ist in der Regel kleiner, günstiger, leichter zu bekommen und sparsamer.

Das Mikrofon nur digital auszuwerten, wird glaube ich schwer. Da kann man besser auf die direkte Messung der Versorgungsspannung verzichten. Das kann mämlich auch ohne einen extra Pin haben: Man stellt AVCC als Ref. ein, und die 1,3 V Bandgap als zu messende Spannung. Das Ergebnis ist dann halt 1023 * 1,3 V / AVcc.

radbruch
14.08.2009, 21:47
Hallo

Ich werde den Strangstrom der IR-LEDs messen, wenn ich den ProBot soweit zusammengelötet habe. Mehr als ca. 20mA sollten es nicht werden, weil die LEDs direkt vom Kontrollerpin getrieben werden. Stromsparen ist hier nicht so entscheidend, weil die LEDs eh mit 36kHz getaktet werden und nur bei der IR-Kommunikation, beim ACS und beim Flashen aktiv sind.

Die Motoransteuerung werde ich wie oben beschrieben mit vier Leitungen versuchen. Die gemeinsame Enableleitung werde ich am IC1 splitten und die zweite fehlende Verbindung zum X1-Prozessorsockel (Pin5?) über die Con1/Con3-Leitung versuchen.

Da ich jetzt den extrem überteuerten Quarzoszillator mitbestellt habe werde ich es damit zuerst versuchen. Ich glaube, der "Schwinger" im orginalen asuro ist eigentlich ein Quarz-Resonator, selbst beim C ein Cent-Artikel.

Der asuro prüft die Batteriespannung automatisch und streikt, wenn sie zu niedrig ist (VL-Meldung). Deshalb brauche ich (vorerst?) diese Messung. Außerdem ist PC5 auch Clock für den I2C-Bus. Hier werde ich mir was überlegen müssen, weil ich doch das ProBot-EEProm per I2C ansprechen möchte.

Die Resettaste des ProBot geht offensichtlich nicht direkt zum Mega128-Resetpin (Anleitung S.42), weshalb ich wohl einen zweiten Eingang opfern werde. Ohne die asuro-Tasten währe zusätzlich zu PD4/5 (Motor) auch PD3 frei. Leider ist der zweite freie Tastenpin PC4 neben ADC4 auch SDA. Soundeingang oder I2C ist nun die Frage.


Das Mikrofon nur digital auszuwerten, wird glaube ich schwer.Als Schallsensor würde es ausreichen, wenn das verstärkte Mikrofonsignal einen Pegelwechsel an einem digitalen Eingang erzeugen würde.

Gruß

mic

Besserwessi
14.08.2009, 22:14
Die origninal Lib. wird man vermutlich sowieso nicht nehmen können, schon wegen dem Motor. Dann sollte es auch kein Problem sein die Messung der Versorgungsspannung rauszunehmen, oder duch die indirekte Methode zu ersetzen.

Für die Tasten müßten sonst den I2C Bus nutzen, statt der Notlösung via ADC.

Wenn man den Mega8 (bzw, Mega168) im SMD Gehäuse hat, hätte man 2 extra ADC Eingänge).

radbruch
14.08.2009, 23:06
Hallo

Die Batterieüberwachung erledigt beim asuro der Bootlader, oder? Mein Umbau soll ja die asuro-Library nur als Basis verwenden. Angedacht habe ich eine angepasste ProBot-Version die ich aus einer älteren Version mit wastes IR-Mod schnitzen möchte.

Als Kontroller möchte ich in erster Linie einen programmierten asuro-Mega8 verwenden. Ziel ist ein weitgehend asurokompatibler ProBot. Der wäre sicher nicht nur für asuro-Besitzer als "Upgrade" interessant, auch als Einsteigerbot wäre das bestimmt eine Alternative zum orginalen asuro. Die störungsanfällige H-Brücke des asuro entfällt, die zickige Tastenabfrage (vorerst) ebenfalls. Hinzu kommt das ACS und Sound. Durch die größere Platinenfläche dürfte der ProBot nicht so fummelig zu löten sein wie der asuro. Die neue Ladefunktion scheint mir auch vorteilhaft. Fehlt eigentlich nur noch die pfiffige Adapterlösung für einen Verkaufsschlager ;)

Interessanterweise wird beim ProBot die FrontLED zwischen Vcc und Kontrollerpin angeschlossen.

Mit den LEDs D14/15 könnte man die BackLEDs nachbilden. Allerdings müßte man dazu etwas auf der ProBot-Platine rumkratzen: Vcc anodenseitig unterbrechen und an Mega8-PD7(ODO-LEDs), die LEDs verpolt einlöten und die Widerstände (R26/27) an Mega8-PC0/1 (ODO-Eingänge).

Gruß

mic

Besserwessi
15.08.2009, 11:12
Soweit ich gelesen habe, geht es ja auch den orginal Prozessor direkt mit GCC / bascom zu beschreiben. Man ist also nicht auf den eher langsamen Zwischencode Interpreter angewiesen. Den einzigen Vorteil den man damit durch den Mega8 hat, wäre ein günstigerer Preis, vor allem wenn man gegegentlich mal einen µC zerschießt, weil die Spannung nicht mal geregelt ist. Wenn man den Preis vergeleicht, ist zumidenstens das Einstigsset mit dem CControl Modul nicht so viel teurer als der Bausatz ohne das Modul.
Das CControll Modul hat ja auch ein paar Vorteile gegen einen Mega8: Man hat deutlich mehr Speicher und wohl auch mehr IO Ports.


Änderungen bei den Motortreiben wären ja unabhängig von einem Austausch der µCs. Auch ein mehr oder weniger Asuro compatible Software wäre mit den Ccontrol Modul als µC wohl möglich. Der Unterschied zwischen einem Mega128 und Mega8 ist bei der Programmierung nicht groß. Da sind die unterschiede in den Sensoren schon wesentlicher.

radbruch
21.08.2009, 20:28
Hallo

Hier mal ein Zwischenstand (damit ihr nicht denkt ich tu nix):

http://radbruch.bplaced.net/robot/asuro-probot/asuro-probot1_klein.jpg (http://radbruch.bplaced.net/robot/asuro-probot/asuro-probot1.jpg) http://radbruch.bplaced.net/robot/asuro-probot/asuro-probot2_klein.jpg (http://radbruch.bplaced.net/robot/asuro-probot/asuro-probot2.jpg)
http://i3.ytimg.com/vi/fEu8T7Z2TwQ/2.jpg (http://www.youtube.com/watch?v=fEu8T7Z2TwQ)
http://www.youtube.com/watch?v=fEu8T7Z2TwQ

Die ProBot-Main-Platine mit minimaler Bestückung, der Adapter mit dem asuro-Mega8, 8MHz Quarz-Resonator (den ich inzwischen besorgt habe) bringt es immerhin zur VL-Meldung im Terminal :) Das bedeutet: Mega8 läuft mit richtigem Takt und kann Senden (der TSOP ist noch nicht eingelötet), irgendwas stimmt mit der Batteriespannung nicht (2,4V gemessen an Pin28). das sieht doch vielversprechend aus :)

Der ProBot-Bausatz kommt im hübschen bunten Karton mit übersichtlichem Kunstoffsorter (Lieferzeitbei mir: 2 Tage) und ist leider nicht so optimal wie ich es erwartet hätte. Löten klappt prima, Doku dazu ist gut , aber leider war der Bausatz nicht komplett :(

Statt der fünf 1,5k Ohm-Widerstände (Vorwiderstände für die Low-Current_Leds) war nur einer im Bausatz, dafür hatte ich zusätzlich 4 7,5k-Widerstände im Paket. Als Ersatz verwende ich nun 1K für R24-R27.

Dass der Vorwiderstand für den TSOP zu groß ist hat sich wohl inzwischen rumgesprochen. Im ProBot-Schaltplan ist deshalb R11 150 Ohm anstatt 470 beim asuro. Blöderweise ist im Bausatz ein 470er, den habe ich nun durch 120 Ohm ersetzt. Im Datenblatt des TSOP werden 100 Ohm und 4,7µF vorgeschlagen. Warum sowohl ProBot (150/10) wie auch asuro(470/220-100nF) von dieser Empfehlung abweichen ist mir unklar)

Da ich sicher nur Akkus verwenden werde habe ich die Diode(D4) nicht bestückt, wohl aber den Jumper(JP1) um später einfache Strommessungen durchführen zu können. Dabei habe ich einen kleinen Fehler im Schaltplan entdeckt: Der Widerstand R8 für die LED D5 (grüner DauerLED) geht nicht nach dem Jumper ab sondern direkt nach dem Schalter(SW1) Es ist mir unverständlich warum in solch einem einfachen Bausatz heutzutage noch solche Fehler auftauchen. Aber die Ansteuerung der Motortreiber ließ ja schon erahnen, dass auch der Probot nicht perfekt ist.

Gruß

mic

Besserwessi
21.08.2009, 20:59
Die 7,5 K Widerststände wären für Low Current LEDs auch nicht so verkehrt. Mit kamen die 1,5 K schon recht klein vor als ich den Plan überflogen hatte.
Wenn die faschen Widerstände das einzige Problem ist, dann geht es ja noch.

So ganz Ideal ist die Schaltung nicht. Was mit wirklich verwirrt hat ist der Mikrofonverstärker. Da wäre ein OP wie der LM358 deutlich besser als ein kleiner Leistungs Audioverstärker. Das hätte auch noch mal gut 3 mA an Strom gespart. So viel günstiger als ein LM358 kann der LM386 auch nicht sein. Bei Rechelt ist der sogar etwa doppelt so teurer.

Wenn man schon Motortreiber wie die L293 nimmt, könnte man die auch besser direkt von der Batterie speisen, und nicht erst über die Diode. Sinnvoll wäre dann auch die Option einen Low Drop spannungsregler für den µC und die Sensoren zu spendieren. Für den Bausatz kann man es ja ruhig bei der Diode lassen, aber der Regler als Option wäre echt gut: Man ist sich sicher den µC nicht duch zu hohe Spannung zu beschädigen und selbst 7,2 V Akkus sollten gehen, für mehr power.

Die ansteuerung der Motoren ist ja ohnehin ein kleiner Witz. Wozu so mit Pins geizen, wo der Mega128 bzw. Das CControll Modul doch genug hat.

radbruch
22.08.2009, 18:21
Hallo

Es geht voran:
http://radbruch.bplaced.net/robot/asuro-probot/pics/asuro-probot1_klein.jpg (http://radbruch.bplaced.net/robot/asuro-probot/pics/asuro-probot1.jpg) http://radbruch.bplaced.net/robot/asuro-probot/pics/asuro-probot2_klein.jpg (http://radbruch.bplaced.net/robot/asuro-probot/pics/asuro-probot2.jpg) http://radbruch.bplaced.net/robot/asuro-probot/pics/asuro-probot3_klein.jpg (http://radbruch.bplaced.net/robot/asuro-probot/pics/asuro-probot3.jpg)

Alles bestückt und getestet was man benötigt um mit dem Probot einen asuro zu simulieren. Hier eine kleine Liste der Probleme und Erkenntnisse:

Motortreiber:
Wie geplant sind die PWM-Signale mit den Enable-Eingängen verbunden. Dazu habe ich auf der Motorplatine die Leiterbahn zwischen IC1:1 und IC1:9 unterbrochen. Dadurch ist Pin9 frei. Ein 10k-Widerstand (R4a) gegen GND als PullDown und ein Drähtchen zwischen Pin9 und dem freien Pin am Stecker 1 (CON1). Auf der Hauptplatine ist diese freie Steckerverbindung schon vorgesehen, neben Con3 gibt es ein freies Lötauge das mit "free" bezeichnet ist. Von hier geht's nach X1:5 und weiter nach Mega8:16 (OC1B, PWM-Rechts). IC1:1 geht nach Mega8:15 (OC1A, PWM-Links) mit PullDown R4. Richtungsauswahl sind am Mega8 PB4 (X1:18) und PB5 (X1:19). Was dann links oder rechts ist muss ich noch austesten;) Beim Probelauf zeigte sich, dass MR+ nicht an Pin7 von IC1 angeschlossen ist...

Taster:
Um Pins zu sparen habe ich die Taster (gegen GND schaltend) parallel zu den ODO-Transistoren T3/T4 angeschlossen (Mega8:23/24, ADC0/1). Die Idee dahinter: Wenn man eine Taste drückt sollte der Antrieb stehen und keine OdoWerte liefern. Mit dem ADC sollte der Unterschied zwischen Fototransistor und Taster ermittelt werden können (vielleicht sogar einfach nur digital ohne ADC;)

LEDS:
Die LEDs D14/15 sind (vorläufig) an den gesparten Motorpins angeschlossen. Somit haben alle vier LEDs einen eigenen Pin (den man später auch als freien Portpin nutzen könnte):
D12-PD2 (StatusLED red)
D13-PB0 (StatusLED green)
D14-PD3
D15-PD4

Speaker (X1:4) und rechte IR-LEDs (X2:14):
Diese habe ich beide an Mega8:11 (PD5). Besser wäre wohl ein Pintausch mit PB0. Dann könnte man D12-15 über PD2-5 ansprechen. (Schön, dass wir darüber gesprochen haben *lol*)

Sonstiges:
Ärgerlich ist, dass der ProBot die LEDs gegen Vcc schaltet. Beim Zusammenbau unbedingt die Anleitung befolgen! Die Ladekurve von C2(22µF an 12K) ist so flach, dass der asuro-Bootlader beim Starten VL erkennt. Lösung: C2 entfernen. Die LEDs D12-15 mit 1k-Vorwiderstand sind deutlich heller als D5 (1,5k). 7,5k währen wohl zuviel. Getrennte Motorversorgung war auch mein erster Gedanke als ich den L293D gesehen hatte. Besser wäre grundsätzlich die Batterie an der Motor-Platine anzuschliesen (mit Schalter, Led und Ladebuchse. Dann würde der Motorstrom nicht über Hauptplatine und CON3/1 fließen und die Hauptplatine wäre spannungsfrei wenn man CON1/3 unterbricht. Allerdings müßte dann jede andere (selbstgebaute) Motorplatine ihre eigene Spannungsversorgung mitbringen. *grins*

Bisher ein großes Fummeln, schön wäre eine geätzte Platine. Jetzt biege ich mal die Lib zurecht, ein neuer Selbsttest muss auch her. Es gibt noch viel zu erforschen...

Gruß

mic

[Edit]
Das klappt ja schon prima:
http://i2.ytimg.com/vi/AoFFV_OtUzw/default.jpg (http://www.youtube.com/watch?v=AoFFV_OtUzw) http://i2.ytimg.com/vi/mE18QeMeH4M/default.jpg (http://www.youtube.com/watch?v=mE18QeMeH4M) http://i2.ytimg.com/vi/T_XtO6FwsJk/default.jpg (http://www.youtube.com/watch?v=T_XtO6FwsJk) http://i3.ytimg.com/vi/bLftu-9mhl0/3.jpg (http://www.youtube.com/watch?v=bLftu-9mhl0)
http://www.youtube.com/watch?v=AoFFV_OtUzw
http://www.youtube.com/watch?v=mE18QeMeH4M
http://www.youtube.com/watch?v=T_XtO6FwsJk
http://www.youtube.com/watch?v=bLftu-9mhl0

radbruch
30.08.2009, 18:17
Hallo

Ein kleines Video gefällig?

http://i1.ytimg.com/vi/Hmy_6wn5HFg/2.jpg (http://www.youtube.com/watch?v=Hmy_6wn5HFg)
http://www.youtube.com/watch?v=Hmy_6wn5HFg

Das einfache "links dunkler als rechts"-Programm:

// Einfaches Linienfolgen mit dem asuro-ProBot 30.8.09 mic

#include "selftest.h"

void Init(void);
void Sleep(unsigned char time36kHz);
void Msleep(int dauer);
void SerWrite(unsigned char *data,unsigned char length);
void PrintInt(int wert);
void PrintBin(char wert);
inline void StatusLED(unsigned char color);
inline void FrontLED(unsigned char status);
void BackLED(unsigned char left, unsigned char right);
inline void MotorSpeed(unsigned char left_speed, unsigned char right_speed);
inline void MotorDir(unsigned char left_dir, unsigned char right_dir);
void LineData(unsigned int *data);
inline void StatusLED(unsigned char color);
void SetLEDs(unsigned char status);

int main(void) {

unsigned int data[2];
//unsigned char i;

Init();
SerWrite("\n\rasuro-ProBot-Linienfolgen\n\r",29);
SerWrite("30.8.09 mic \n\r", 14);
DDRD |= (1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD6); // D12-15 und FrontLED
PORTD |= (1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD6); // high bedeutet LEDs aus
//PORTD &= ~((1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD5)); // D12-15 an
//SetLEDs(0b11111); // FrontLED, D14(red), D15, D13, D12(green)

FrontLED(ON);
MotorSpeed(225,225);
while(1)
{
LineData(data);
if(data[0]<data[1]) MotorSpeed(200,250); else MotorSpeed(250,200);
/*
PrintInt(data[0]);
SerWrite("- ", 2);
PrintInt(data[1]);
SerWrite("\n\r", 2);
Msleep(100);
*/
Sleep(255);
}
return(0); // wird nie erreicht!
}

volatile unsigned char count36kHz;
volatile unsigned long timebase;

/* uses timer2 (36kHz for IR communication */
SIGNAL (SIG_OVERFLOW2)
{
TCNT2 += 0x25;
count36kHz ++;
if (!count36kHz) timebase ++;
}

void Init (void)
{
//-------- seriell interface programmed in boot routine and already running -------
// prepare 36kHz for IR - Communication
TCCR2 = (1 << WGM20) | (1 << WGM21) | (1 << COM20) | (1 << COM21) | (1 << CS20);
OCR2 = 0x91; // duty cycle for 36kHz
TIMSK |= (1 << TOIE2); // 36kHz counter for sleep

// prepare RS232
UCSRA = 0x00;
UCSRB = 0x00;
UCSRC = 0x86; // No Parity | 1 Stop Bit | 8 Data Bit
UBRRL = 0xCF; // 2400bps @ 8.00MHz

// I/O Ports
DDRB = IRTX | LEFT_DIR | PWM | GREEN_LED;
//DDRD = RIGHT_DIR | FRONT_LED | ODOMETRIE_LED | RED_LED;

// for PWM (8-Bit PWM) on OC1A & OC1B
TCCR1A = (1 << WGM10) | (1 << COM1A1) | (1 << COM1B1);
// tmr1 running on MCU clock/8
TCCR1B = (1 << CS11);

// A/D Conversion
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // clk/64
ODOMETRIE_LED_OFF;

StatusLED(GREEN);
MotorDir(FWD,FWD);
MotorSpeed(0,0);
sei();
}

void Sleep(unsigned char time36kHz)
{ unsigned char ziel=(time36kHz+count36kHz) & 0x00FF;
while (count36kHz != ziel);
}

void Msleep(int dauer)
{
while(dauer--) Sleep(36);
}

void SerWrite(unsigned char *data,unsigned char length)
{
unsigned char i = 0;
UCSRB = 0x08; // enable transmitter
while (length > 0) {
if (UCSRA & 0x20) { // wait for empty transmit buffer
UDR = data[i++];
length --;
}
}
while (!(UCSRA & 0x40));
for (i = 0; i < 0xFE; i++)
for(length = 0; length < 0xFE; length++);
}

void PrintInt(int wert)
{ char text[6]=" ";
itoa(wert,text,10);
SerWrite(text,5);
}
void PrintBin(char wert)
{ char text[8]=" ";
itoa(wert,text,2);
SerWrite(text,8);
}

/* Set motor speed */
inline void MotorSpeed(unsigned char left_speed, unsigned char right_speed)
{
OCR1A = left_speed;
OCR1B = right_speed;
}

/* Set motor direction */
inline void MotorDir(unsigned char left_dir, unsigned char right_dir)
{
if(left_dir) PORTB &= ~(1 << PB5); else PORTB |= (1 << PB5);
if(right_dir) PORTB &= ~(1 << PB4); else PORTB |= (1 << PB4);
}
void LineData(unsigned int *data)
{
ADMUX = (1 << REFS0) | IR_LEFT; // AVCC reference with external capacitor
Sleep(10);
ADCSRA |= (1 << ADSC); // Start conversion
while (!(ADCSRA & (1 << ADIF))); // wait for conversion complete
ADCSRA |= (1 << ADIF); // clear ADCIF
data[0] = ADCL + (ADCH << 8);

ADMUX = (1 << REFS0) | IR_RIGHT; // AVCC reference with external capacitor
Sleep(10);
ADCSRA |= (1 << ADSC); // Start conversion
while (!(ADCSRA & (1 << ADIF))); // wait for conversion complete
ADCSRA |= (1 << ADIF); // clear ADCIF
data[1] = ADCL + (ADCH << 8);
}
inline void StatusLED(unsigned char color)
{
if (color == OFF) {GREEN_LED_OFF; RED_LED_OFF;}
if (color == GREEN) {GREEN_LED_ON; RED_LED_OFF;}
if (color == YELLOW) {GREEN_LED_ON; RED_LED_ON;}
if (color == RED) {GREEN_LED_OFF; RED_LED_ON;}
}
void SetLEDs(unsigned char status)
{
status = ~(status<<2); // LEDs sind PD2-7 gegen Vcc schaltend!
PORTD &= status; // nur gesetzte LEDs einschalten
PORTD |= status & ~3; // PD0 und PD1 nicht verändern!
}
inline void FrontLED(unsigned char status)
{
if(status) FRONT_LED_on; else FRONT_LED_off;
}


Und die Header-Datei dazu:

// Einfaches Linienfolgen mit dem asuro-ProBot 30.8.09 mic

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>

#define FALSE 0
#define TRUE 1

#define OFF 0
#define ON 1

#define GREEN 1
#define RED 2
#define YELLOW 3

/* --------------- INTERNAL ------------- */
#define GREEN_LED_OFF PORTD |= GREEN_LED
#define GREEN_LED_ON PORTD &= ~GREEN_LED
#define RED_LED_OFF PORTD |= RED_LED
#define RED_LED_ON PORTD &= ~RED_LED

#define FWD 0
#define RWD 1
#define BREAK 0x00
#define FREE (1 << PB4) | (1 << PB5) /* (1 << PD4) | (1 << PD5)*/

#define IRTX (1 << PB3)
#define GREEN_LED (1 << PD5)
#define RED_LED (1 << PD2)

#define PWM (1 << PB1) | (1 << PB2)
#define RIGHT_DIR (1 << PB4) | (1 << PB5)
#define LEFT_DIR (1 << PD4) | (1 << PD5)

#define BATTERIE (1 << MUX0) | (1 << MUX2) //ADC5
#define SWITCH (1 << MUX2) //ADC4
#define IR_LEFT (1 << MUX0) | (1 << MUX1) //ADC3
#define IR_RIGHT (1 << MUX1) //ADC2

#define Speaker (1 << PD5) // speaker an D14
#define Speaker_on PORTD &= ~(1<<PD5)
#define Speaker_off PORTD |= (1<<PD5)

#define FRONT_LED (1 << PD6)
#define FRONT_LED_on PORTD &= ~(1<<PD6)
#define FRONT_LED_off PORTD |= (1<<PD6)

#define ODOMETRIE_LED (1 << PD7)
#define ODOMETRIE_LED_ON PORTD |= ODOMETRIE_LED
#define ODOMETRIE_LED_OFF PORTD &= ~ODOMETRIE_LED

#define WHEEL_LEFT (1 << MUX0) //ADC1
#define WHEEL_RIGHT 0 //ADC0

#define LED12_on PORTD &= ~(1<<PD2)
#define LED13_on PORTD &= ~(1<<PD3)
#define LED14_on PORTD &= ~(1<<PD5) // Achtung Reihenfolge D14/15 getauscht!
#define LED15_on PORTD &= ~(1<<PD4)

#define LED12_off PORTD |= (1<<PD2)
#define LED13_off PORTD |= (1<<PD3)
#define LED14_off PORTD |= (1<<PD5)
#define LED15_off PORTD |= (1<<PD4)

:)

btw kann ich den Motortreiberumbau nur empfehlen.

Gruß

mic

vistauser
09.09.2009, 11:37
Hi mic,
ich verfolge dein Projekt von Beginn an mit großem Interesse.
Habe auch Asuro und ProBot128 erfolgreich zusammengelötet.

Meine Frage betrifft deine Mod zum Motortreiber:
Funktioniert die auch, nebenwirkungsfrei, mit der C-Control Pro128?

Programmierung des ProBot128 mit der Asuro USB-IR-Methode wäre
auch eine gute Sache denn mein Voltcraft-Programmierer hat den Geist aufgegeben.
Wenn ich den ProBot128 neu programmieren will, muß ich ihn in das Application Board stecken (oder einen neuen Voltcraft kaufen, brrrrrr...).

Weiterhin viel Erfolg mit deinem interessanten Projekt
Olaf

radbruch
09.09.2009, 14:53
Hallo

Die Motortreibermodifikation ist beim C-Control Pro128 nicht ganz so einfach, weil die Leitungen hier direkt auf die Kontrollerpins gehen. Neben der Änderung auf der Motorplatine müssen deshalb auch die Enable/PWM-Leitungen getauscht werden. Zusätzlich muss natürlich in der Library des ProBot die Ansteuerung geändert werden.

Zum Tauschen der Leitungen würde sich das Verbindungskabel von CON1 nach CON3 anbieten. Hier könnte man auf einer Seite das Flachkabel in drei Pärchen auftrennen: Vcc+GND, OC1A und Enable(orginal), OC1B und Enable (neu). Vcc und GND bleiben, die anderen beiden Pärchen werden in der Steckerquetschung getauscht. Dann gehen die PWM-Pins des Kontrollers auf die Enable-Leitungen von IC1 und die Richtungsauswahlen gehen auf IC2.

Die Anpassung der Lib und eventuelle Auswirkungen auf die Programme habe ich noch nicht untersucht. Das sollte aber auch eher ein C-Control Pro128-Benutzer tun ;)

Kleine Fortschritte gibt es auch bei meinem Projekt, ich experimentiere mit dem ACS:
http://i1.ytimg.com/vi/0EVu3qImZ0k/default.jpg (http://www.youtube.com/watch?v=0EVu3qImZ0k) http://i3.ytimg.com/vi/ri9kHphFiPI/default.jpg (http://www.youtube.com/watch?v=ri9kHphFiPI) http://i2.ytimg.com/vi/5exIBE11L04/2.jpg (http://www.youtube.com/watch?v=5exIBE11L04)
http://www.youtube.com/watch?v=0EVu3qImZ0k
http://www.youtube.com/watch?v=ri9kHphFiPI
http://www.youtube.com/watch?v=5exIBE11L04

Die IR-LEDs sind noch nicht mit Schrumpfschlauch abgedeckt.

Aktuelle Software:

// ACS-Test 12.9.09 mic

#include "asuro-probot.h"
#include "asuro-probot.c"

unsigned int data[2];

int main(void)
{
Init();
FrontLED(ON);
while(1)
{

ACSData(data);
MotorSpeed(255,245); // linker Motor schwächelt ;)
if(data[0] > 244) MotorSpeed(255,0);
if(data[1] > 244) MotorSpeed(0,245);
if((data[0]>248) && (data[1]>248)) MotorSpeed(0,0);
Msleep(300);
}
return(0);
}


Die Lib dazu:

// asuro-ProBot-Lib asuro-probot.c 12.9.09 mic

volatile unsigned char count36kHz=0;
volatile unsigned char acs=0;
volatile unsigned long timebase=0;

/* uses timer2 (36kHz for IR communication */
SIGNAL (SIG_OVERFLOW2)
{
TCNT2 += 0x25;
count36kHz ++;
if (!count36kHz) timebase ++;
if(acs) acs--;
}

void Sleep(unsigned char time36kHz)
{ unsigned char ziel=(time36kHz+count36kHz) & 0x00FF;
while (count36kHz != ziel);
}

void Msleep(int dauer)
{
while(dauer--) Sleep(36);
}

void SerWrite(unsigned char *data,unsigned char length)
{
unsigned char i = 0;
UCSRB = 0x08; // enable transmitter
while (length > 0) {
if (UCSRA & 0x20) { // wait for empty transmit buffer
UDR = data[i++];
length --;
}
}
while (!(UCSRA & 0x40));
for (i = 0; i < 0xFE; i++)
for(length = 0; length < 0xFE; length++);
}

void PrintInt(int wert)
{ char text[6]=" ";
itoa(wert,text,10);
SerWrite(text,5);
}
void PrintBin(char wert)
{ char text[8]=" ";
itoa(wert,text,2);
SerWrite(text,8);
}

/* Set motor speed */
inline void MotorSpeed(unsigned char left_speed, unsigned char right_speed)
{
OCR1A = left_speed;
OCR1B = right_speed;
}

/* Set motor direction */
inline void MotorDir(unsigned char left_dir, unsigned char right_dir)
{
if(left_dir) PORTB &= ~(1 << PB5); else PORTB |= (1 << PB5);
if(right_dir) PORTB &= ~(1 << PB4); else PORTB |= (1 << PB4);
}
void LineData(unsigned int *data)
{
ADMUX = (1 << REFS0) | IR_LEFT; // AVCC reference with external capacitor
Sleep(10);
ADCSRA |= (1 << ADSC); // Start conversion
while (!(ADCSRA & (1 << ADIF))); // wait for conversion complete
ADCSRA |= (1 << ADIF); // clear ADCIF
data[0] = ADCL + (ADCH << 8);

ADMUX = (1 << REFS0) | IR_RIGHT; // AVCC reference with external capacitor
Sleep(10);
ADCSRA |= (1 << ADSC); // Start conversion
while (!(ADCSRA & (1 << ADIF))); // wait for conversion complete
ADCSRA |= (1 << ADIF); // clear ADCIF
data[1] = ADCL + (ADCH << 8);
}
void OdometrieData(unsigned int *data)
{
DDRC &= ~((1 << PC0) | (1 << PC1)); // Input => no break LED
ODOMETRIE_LED_ON;
Sleep(5);

ADMUX = (1 << REFS0) | WHEEL_LEFT; // AVCC reference with external capacitor
ADCSRA |= (1 << ADSC); // Start conversion
while (!(ADCSRA & (1 << ADIF))); // wait for conversion complete
ADCSRA |= (1 << ADIF); // clear ADCIF
data[0] = ADCL + (ADCH << 8);

ADMUX = (1 << REFS0) | WHEEL_RIGHT; // AVCC reference with external capacitor
ADCSRA |= (1 << ADSC); // Start conversion
while (!(ADCSRA & (1 << ADIF))); // wait for conversion complete
ADCSRA |= (1 << ADIF); // clear ADCIF
data[1] = ADCL + (ADCH << 8);
}
void ACSData(unsigned int *data)
{
UCSRB &= ~(1<<TXEN); // USART TX disable

OCR2=0xff;
DDRD |= (1<<PD1);
PORTD &= ~(1<<PD1); // ACS LED left on
while(PIND & 1)
{
acs=15;
while(acs);
OCR2--;
}
PORTD |= (1<<PD1); // ACS LED left off
data[0]=OCR2;
while(!(PIND &1));

OCR2=0xff;
PORTB &= ~(1<<PB0); // ACS LED right on
while(PIND & 1)
{
acs=15;
while(acs);
OCR2--;
}
PORTB |= (1<<PB0); // ACS LED right off 6
data[1]=OCR2;
while(!(PIND &1));

OCR2=0x91; //36kHz
}
inline void StatusLED(unsigned char color)
{
if (color == OFF) {GREEN_LED_OFF; RED_LED_OFF;}
if (color == GREEN) {GREEN_LED_ON; RED_LED_OFF;}
if (color == YELLOW) {GREEN_LED_ON; RED_LED_ON;}
if (color == RED) {GREEN_LED_OFF; RED_LED_ON;}
}
void SetLEDs(unsigned char status)
{
status = ~(status<<2); // LEDs sind PD2-7 gegen Vcc schaltend!
PORTD &= status; // nur gesetzte LEDs einschalten
PORTD |= status & ~3; // PD0 und PD1 nicht verändern!
}
inline void FrontLED(unsigned char status)
{
if(status==ON) FRONT_LED_on; else FRONT_LED_off;
}
unsigned char PollSwitch (void)
{
ODOMETRIE_LED_OFF;
Sleep(10);
return(~PINC & 3);
}
void Init (void)
{
//-------- seriell interface programmed in boot routine and already running -------
// prepare 36kHz for IR - Communication
TCCR2 = (1 << WGM20) | (1 << WGM21) | (1 << COM20) | (1 << COM21) | (1 << CS20);
OCR2 = 0x91; // duty cycle for 36kHz
TIMSK |= (1 << TOIE2); // 36kHz counter for sleep and ACS

// prepare RS232
UCSRA = 0x00;
UCSRB = 0x00;
UCSRC = 0x86; // No Parity | 1 Stop Bit | 8 Data Bit
UBRRL = 0xCF; // 2400bps @ 8.00MHz

// I/O Ports
DDRB = IRTX | RIGHT_DIR | LEFT_DIR | PWM;
// PD2-5=D12-15, PD6=FrontLED und PD7=OdoLED, alle LEDs ausschalten
DDRD |= (1<<PD7) | (1<<PD6) | (1<<PD5) | (1<<PD4) | (1<<PD3) | (1<<PD2);
PORTD|= (0<<PD7) | (1<<PD6) | (1<<PD5) | (1<<PD4) | (1<<PD3) | (1<<PD2);

// for PWM (8-Bit PWM) on OC1A & OC1B
TCCR1A = (1 << WGM10) | (1 << COM1A1) | (1 << COM1B1);
// tmr1 running on MCU clock/8
TCCR1B = (1 << CS11);

// A/D Conversion
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // clk/64

//ACS-Init (muss noch gecheckt werden
DDRB |= (1<<PB3); // OC2 (36kHz an Timer2)
//DDRD |= (1<<PD1); // ACS_LED_LEFT (TXD)
DDRB |= (1<<PB0); // ACS_LED_RIGHT
PORTB |= (1<<PB0); // off
//PORTB &= ~(1<<PB0); // on

//ODOMETRIE_LED_OFF;
StatusLED(GREEN);
MotorDir(FWD,FWD);
MotorSpeed(0,0);
sei();
}

// asuro-ProBot-Lib asuro-probot.h 12.9.09 mic

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>

#define FALSE 0
#define TRUE 1

#define OFF 0
#define ON 1

#define GREEN 1
#define RED 2
#define YELLOW 3

/* --------------- INTERNAL ------------- */
#define GREEN_LED_OFF PORTD |= GREEN_LED
#define GREEN_LED_ON PORTD &= ~GREEN_LED
#define RED_LED_OFF PORTD |= RED_LED
#define RED_LED_ON PORTD &= ~RED_LED

#define FWD 0
#define RWD 1
#define BREAK 0x00
#define FREE (1 << PB4) | (1 << PB5) /* (1 << PD4) | (1 << PD5)*/

#define GREEN_LED (1 << PD2)
#define RED_LED (1 << PD3)

#define PWM (1 << PB1) | (1 << PB2)
#define IRTX (1 << PB3)
#define RIGHT_DIR (1 << PB4)
#define LEFT_DIR (1 << PD5)

#define BATTERIE (1 << MUX0) | (1 << MUX2) //ADC5
#define SWITCH (1 << MUX2) //ADC4
#define IR_LEFT (1 << MUX0) | (1 << MUX1) //ADC3
#define IR_RIGHT (1 << MUX1) //ADC2

#define ACS_RIGHT_LED (1 << PB0)
#define ACS_LEFT_LED (1 << PD1)
#define ACS_RIGHT_LED_on PORTB &= ~ACS_RIGHT_LED
#define ACS_RIGHT_LED_off PORTB |= ACS_RIGHT_LED
#define ACS_LEFT_LED_on PORTD &= ~ACS_LEFT_LED
#define ACS_LEFT_LED_off PORTD |= ACS_LEFT_LED

#define Speaker (1 << PD5) // speaker an D14
#define Speaker_on PORTD &= ~(1<<PD5)
#define Speaker_off PORTD |= (1<<PD5)

#define FRONT_LED (1 << PD6)
#define FRONT_LED_on PORTD &= ~(1<<PD6)
#define FRONT_LED_off PORTD |= (1<<PD6)

#define ODOMETRIE_LED (1 << PD7)
#define ODOMETRIE_LED_ON PORTD |= ODOMETRIE_LED
#define ODOMETRIE_LED_OFF PORTD &= ~ODOMETRIE_LED

#define WHEEL_LEFT (1 << MUX0) //ADC1
#define WHEEL_RIGHT 0 //ADC0

#define LED12_on PORTD &= ~(1<<PD2)
#define LED13_on PORTD &= ~(1<<PD3)
#define LED14_on PORTD &= ~(1<<PD5) // Achtung Reihenfolge D14/15 getauscht!
#define LED15_on PORTD &= ~(1<<PD4)

#define LED12_off PORTD |= (1<<PD2)
#define LED13_off PORTD |= (1<<PD3)
#define LED14_off PORTD |= (1<<PD5)
#define LED15_off PORTD |= (1<<PD4)


Gruß

mic

radbruch
19.10.2009, 15:52
Hallo

Recht einfach kann man beim Probot die Antriebsplatine austauschen:

http://i3.ytimg.com/vi/Z7VJT-kw9VQ/default.jpg (http://www.youtube.com/watch?v=Z7VJT-kw9VQ)
http://www.youtube.com/watch?v=Z7VJT-kw9VQ

Die Steuerplatine treibt die Motoren der umgebauten Servos über die orginalen Servoplatinen an. Die Potis dienen nun zum Kalibrieren des Nullpunkts (am Anfang des Videos). Leider haben meine Omniwheels fast keinen Grip auf dem Laminat.

Das kleine Demo erzeugt die Servoimpulse asurolike mit Sleep():

// Erster Test mit Omniwheels 19.10.09 mic

#include "asuro-probot.h"
#include "asuro-probot.c"

void omniwheels(char x, char y, char z, int t)
{
int i;
while(t--)
{
PORTB |= (1<<PB1);
Sleep(36+x);
PORTB &= ~(1<<PB1);
PORTB |= (1<<PB2);
Sleep(36+y);
PORTB &= ~(1<<PB2);
PORTB |= (1<<PB4);
Sleep(36+z);
PORTB &= ~(1<<PB4);
for(i=15; i--; Sleep(36));
}
}
int main(void)
{
Init();
PORTC |= 3; // Odo-PullUps simulieren für PollSwitch()
PORTB &= ~(1<<PB5 | 1<<PB4 | 1<<PB2 | 1<<PB1);
while(!PollSwitch());
while(PollSwitch());
StatusLED(RED);

while(!PollSwitch()) // kalibrieren
{
omniwheels(0,0,0,10);
}
while(PollSwitch()); //fertig
StatusLED(YELLOW);
Beep(200);
Msleep(200);
Beep(1000);

while(1) // Demo
{
omniwheels(2,2,2,200);
Beep(100);
omniwheels(-2,-2,-2,300);
Beep(200);
omniwheels(5,5,5,400);
Beep(100);
omniwheels(-7,-7,-7,400);
Beep(200);
Msleep(200);
Beep(200);
omniwheels(2,-2,0,300);
Beep(200);
omniwheels(4,-4,0,300);
Beep(200);
omniwheels(0,5,-3,300);
Beep(200);
omniwheels(5,3,-5,300);
Beep(200);
Msleep(200);
Beep(200);
}
}

Gruß

mic

radbruch
24.07.2011, 22:58
Hallo

Da ich mich immer noch nicht für ein richtig großes Projekt entscheiden kann, spiele ich mit den Dingen, die ich hier so rumliegen habe:


http://www.youtube.com/watch?v=C9xVNq2Z1KA


http://www.youtube.com/watch?v=I0GNsYDZaB8

Outtake:

http://www.youtube.com/watch?v=NR-b-f1DS_s

Diesmal alles in Bascom:

' asuro sendet vt100 23.7.2001 mic

' https://www.roboternetz.de/community/showthread.php?41788-Kameramodul&p=399123&viewfull=1#post399123
' https://www.roboternetz.de/community/showthread.php?47457-Hardware-Mitmach-Projekt-Kamera-f%FCr-den-RP6&p=463226&viewfull=1#post463226
'

$regfile = "m8def.dat" ' asuro mit Mega8
$crystal = 8000000 ' taktet mit 8MHz
$baud = 2400 ' IR-Baudrate

' https://www.roboternetz.de/community/showthread.php?44458-Grundsatzfrage-zu-Arrays-in-Bascom
' (Trick zu Index 0?)
Dim Bildspeicher_000 As Byte ' Bildspeicher für 16*24 byte
Dim Bildspeicher(383) As Byte

'allgemeine Variablen
Dim X As Byte , Y As Byte
Dim S As String * 30 ' max 30 Positionen

' VT100-Funktionen
Declare Sub Set_cursor(byval X As Byte , Byval Y As Byte )
Declare Sub Print_at(byval X As Byte , Byval Y As Byte , Text As String )

' Tasten
Portc.0 = 1 ' Tastenpullups einschalten (ODOLed)
Portc.1 = 1 ' beist sich mit den Servos :(

' Charlieplexing
Declare Sub Charlie(byval Bitnr As Byte)
Dim Charliedata(12) As Byte ' Bitmuster fürs Charlieplexing an PC0 bis PC3
Charliedata(01) = &B11001000 ' Highnipple ist DDR, Lownipple ist Port
Charliedata(02) = &B10101000
Charliedata(03) = &B10011000
Charliedata(04) = &B11000100
Charliedata(05) = &B01100100
Charliedata(06) = &B01010100
Charliedata(07) = &B10100010
Charliedata(08) = &B01100010
Charliedata(09) = &B00110010
Charliedata(10) = &B10010001
Charliedata(11) = &B01010001
Charliedata(12) = &B00110001

' Beeper
Declare Sub Beep(byval Dauer As Word) ' Dauer in ms
Config Pind.5 = Output ' Beeper

' Servos
Declare Sub Servoimpuls()
Dim Servo1 As Byte , Servo2 As Byte , Servo3 As Byte , Tmp As Byte
Config Pinb.1 = Output
Config Pinb.2 = Output
Config Pinb.4 = Output

' Kamera
Config Adc = Free , Prescaler = Auto , Reference = Avcc ' Dummy-Setup!!!

Admux = 0
Set Admux.refs1 ' Internal 2.56V Voltage Reference
Set Admux.refs0 ' with external capacitor at AREF pin
Set Admux.adlar ' ausrichtung links (adch) für 8-bit
Set Admux.2 ' Kanal 4
'Sfior = 0
' eventuell besser für andere Funktionen:
Sfior = Sfior And &B00011111 ' adts2=0 adts1=0 adts0=0
Adcsr = 0
Set Adcsr.aden ' ADC Enable
Set Adcsr.adps0 ' ADC Prescaler Select Bits (2)

Set Adcsr.5 ' adate (ADC Auto Trigger Enable)
Set Adcsr.adif ' ADC Interrupt Flag

Set Adcsr.adsc ' ADC Start Conversion

Start Adc
Enable Interrupts


Dim Rewrite As Byte
S = "asuro mit VT100-Terminal"
Rewrite = 0

Print "{027}[1;1H"; ' Home
Print "{027}[2J"; ' clear terminal screen
Call Set_cursor(5 , 2)
Print "hallo"
Print "{027}[1m"; ' bold on
Call Print_at(10 , 5 , S)
Print "{027}[0m"; ' Attribute off

Call Set_cursor(5 , 2)
Print "calibrieren.."

Call Beep(150)
Waitms 100
Call Beep(150)
Waitms 100
Call Beep(150)
Waitms 100
Call Beep(150)

Servo1 = 10
Servo2 = 10
Servo3 = 10
While Pinc.0 = 1 ' Servos kalibrieren, Abruch mit Taste "Boot"
Call Servoimpuls()
Waitms 17
Wend
While Pinc.0 = 0
Wend
Call Set_cursor(5 , 2)
Print "and go! "
Call Beep(1000)

Servo1 = 10 ' 3 Sekunden vorwärts
servo2 = 5
Servo3 = 15
For X = 0 To 150
Call Servoimpuls()
Waitms 17
Next X
Servo2 = 10
Servo3 = 10
Waitms 1000
' Liniendemo
Do
Do ' Auf Bildanfang warten
X = 0
While Adch > 30
Wend
While Adch < 50
Incr X
Wend
Loop Until X > 40
X = 50 ' die zu lesende Zeile
While X > 0
While Adch > 30
Wend
While Adch < 50
Wend
Decr X
Wend
X = 0
While Adch > 65 ' Hell/Dunkel-Schwelle
Incr X
Wend

Servo1 = 10 ' zum Strich schwenken
'Servo2 = 10
'Servo3 = 10
If X > 13 Then ' gegenuhrzeiger
Servo1 = 5
'Servo2 = 5
'Servo3 = 5
End If
If X < 11 Then ' uhrzeiger
Servo1 = 15
'Servo2 = 15
'Servo3 = 15
End If

Call Servoimpuls() ' hihi :)

If Rewrite > 0 Then ' Debug
Decr Rewrite
Else
Call Set_cursor(0 , 15)
Print X;
Print " ";
'S = Space(x)
'Print S;
'Print "***"
'Waitms 300
Rewrite = 20
End If

X = X / 2 ' Ausgabe per Charlieplexing
Call Charlie(x)
Loop

End

Sub Servoimpuls()
Tmp = Servo1 * 10 'Servoansteuerung
If Tmp > 0 Then
Portb.1 = 1
While Tmp > 0
Waitus 10
Decr Tmp
Wend
Portb.1 = 0
End If

Tmp = Servo2 * 10
If Tmp > 0 Then
Portb.2 = 1
While Tmp > 0
Waitus 10
Decr Tmp
Wend
Portb.2 = 0
End If

Tmp = Servo3 * 10
If Tmp > 0 Then
Portb.4 = 1
While Tmp > 0
Waitus 10
Decr Tmp
Wend
Portb.4 = 0
End If
End Sub


Sub Beep(byval Dauer As Word) ' 2kHz, Dauer in ms
While Dauer > 0
Portd.5 = 0
Waitus 250
Portd.5 = 1
Waitus 250
Portd.5 = 0
Waitus 250
Portd.5 = 1
Waitus 250
Decr Dauer
Wend
End Sub

Sub Set_cursor(byval X As Byte , Byval Y As Byte )
Print Chr(27) ; "[" ; Str(y) ; ";" ; Str(x) ; "H"; ' set cursorpos
End Sub

Sub Print_at(byval X As Byte , Byval Y As Byte , Text As String)
Print Chr(27) ; "[" ; Str(y) ; ";" ; Str(x) ; "H"; ' set cursorpos
Print Text;
End Sub

Sub Charlie(byval Bitnr As Byte) ' Bitnummer 0-11
Incr Bitnr ' Startindex bei Arrays ist 1!
Ddrc = 0
Portc = 0
If Bitnr > 0 Then
If Bitnr < 13 Then
Ddrc = Charliedata(bitnr) / 16
Portc = Charliedata(bitnr) And 15
End If
End If
End Sub

Die Kamera hängt am Tasten-ADC des asuro, dieser wird bei meinem Clone nicht verwendet. Basis für das Kameraprogramm war die Bascomversion vom RP6 das ich nahezu unverändert eingebaut habe:
https://www.roboternetz.de/community/showthread.php?41788-Kameramodul&p=399123&viewfull=1#post399123

Die Servoimpulse werden recht trickreich erzeugt, denn die Impulspause wird durch das Einlesen der Kamera erzeugt. 50 Bilder pro Sekunde ergeben fast genau 20ms Impulspause;)

Die 12 Leds werden per Charlieplexing an PC0 bis PC3 angesteuert. Beim asuro sind das die Pins für die Linien- und ODO-Sensoren. Da diese Anschlüsse von meiner Omniplatine nicht verwendet werden, drängt sich diese Verwendung geradezu auf. Blöderweise überschneidet sich das aber mit der Tastenauswertung...

Das Kugelrad ist ein aufgeschnittener Tennisball mit Skaterlagern, Laminatlagerhaltern und Zollstockachse. Das ist eigentlich der Grund für meine aktuelle Omniwheel-Aktivität:
https://www.roboternetz.de/community/showthread.php?53671-rovio-mit-zweiachsigem-kugelrad-statt-omniwheel

Da ich ja normalerweise in C programmiere, verblüffen mich die gelegentlichen Ausflüge in die Basccom-Welt. Ganz schön clever, was da alles geboten wird. Der Printbefehl z.B. funktioniert prima auch ohne eigenes Setup für den Timer2 (36kHz), weil dies schon im Bootloader erledigt wird. Wirklich überraschend ist auch das Terminal von Bascom, weil es offensichtlich doch TV100-Codes interpretieren kann:
https://www.roboternetz.de/community/showthread.php?48073-VT100-Ansi-Terminal-f%FCr-den-RP6

Es gibt noch viel zu erforschen...

Gruß

mic