Aus RN-Wissen.de
Wechseln zu: Navigation, Suche
LiFePO4 Speicher Test

K (H-Brücke)
K (H-Brücke)
Zeile 177: Zeile 177:
 
===H-Brücke===
 
===H-Brücke===
  
Über die H-Brüchen werden die Motoren gesteuert.
+
Über die H-Brücken werden die Motoren gesteuert.
  
 
==Umbau-Optionen==
 
==Umbau-Optionen==

Version vom 7. April 2010, 10:39 Uhr

Der RP6

Was bisher geschah:

Mon, 02 Jul 2007 23:00 - Benachrichtigung der Tester
Die, 03 Jul 2007 15:00 - Bereitstellung der Dokumentation
Don, 05 Jul 2007 14:30 - Bereitstellung der Schaltungsunterlagen
Son, 08 Jul 2007 16:00 - Nachricht über den Versand
Mon, 09 Jul 2007 00:15 - Bereitstellung der Library und der Beispielprogramme
Die, 10 Jul 2007 - Eintreffen der RP6 bei den Testern


==Allgemein==
RP6 mit Erweiterungsboard

Der von Arexx entwickelte RP6 ist ein autonomes Raupenfahrzeug, das nicht nur für Schüler und Studenten zum Einstieg in das Gebiet Robotik sondern auch für Fortgeschrittene Elektroniker und Bastler sehr gut geeignet ist, da das System für selbstentworfene Erweiterungen ausgelegt ist. Der RP6 wird von einem, unter Roboterentwicklern beliebten, AVR Microcontroller von Atmel gesteuert und hat Lichtsensoren in Form von zwei LDRs, 2 Bumper an der Stoßstange, 6 Status LEDs, Sensoren zur Überwachung der Akkuspannung, Drehgeber mit 625 CPR, ein Infrarot Sensor zur Hinderniserkennung und Kommunikation und Motorstromsensoren zur Verfügung. Zudem liegt dem Roboter eine umfangreiche Anleitung, inklusive einem kleinen C-Crashkurs, ein USB-Interface zum Anschluss an den PC und ein USB Kabel bei.


Technische Daten

Mikrocontroller: AVR ATmega32
Speicher: 32 kB Flash-Speicher, davon 1 kB bereits vom Bootloader belegt

2 kB RAM
1 kB EEPROM

Programmierung: Über AVR-Bootloader, belegt ca. 1 kB des Flash-Speichers
Vorhandene Sensoren: 2 Lichtsensoren (LDR)

1 Infrarot (ACS - Anti Collision System)
2 Bumper
2 Drehgeber (Encoder)

Vorhandene Aktoren: 2 Motoren

6 Status-LEDs
1 IR-Sender

Abmessungen: (L × B × H) 172 × 128 × 50 mm
Ausführung: Fertig aufgebauter Roboter
Stromversorgung: 6 AA NiMH Akkus
Hersteller: Arexx Niederlande

Mechanik

Beschreibung

Getriebe-Übersetzung

Elektromechanik

Beschreibung

Odometrie

Elektronik

Beschreibung

Stromversorgung

Der RP6 wird über 6 Mignon Akkus im Chassis mit Strom versorgt. 6 x 1.2 V = 7.2 V maximal Stromstärke.

Hauptprozessor

Sensoren

Die meisten Sensoren über die der Roboter verfügt, haben wir ja schon in anderen Abschnitten kurz genannt, wollen diese nun aber etwas detaillierter betrachten. In dem Blockdiagramm sind einige der Sensoren nicht in dem blauen Bereich "Sensors" zu sehen, weil sie besser in andere Bereiche passen. Trotzdem zählen natürlich auch die Drehgeber (=“Encoder“), Motorstromsensoren und der Batteriespannungssensor zu den Sensoren und werden darum in diesem Abschnitt beschrieben!

Batteriespannungs-Sensor (Voltage Sensor)

Dieser "Sensor" ist eigentlich nur ein einfacher Spannungsteiler aus zwei Widerständen. Wir gehen davon aus, dass die Batterien insgesamt maximal 10V liefern können. 6 NiMH Akkus werden immer unterhalb davon bleiben. Die Referenzspannung des ADC, also die Spannung mit der er die gemessene Spannung vergleicht, beträgt 5V. Da auch die Betriebsspannung 5V beträgt, darf diese nicht überschritten werden. Also müssen wir die zu messende Spannung um die Hälfte herabsetzen! Dies geschieht über einen Spannungsteiler aus zwei Widerständen, der die Spannung an den Messbereich des ADCs anpasst. Der ADC löst mit 10 Bit auf (Wertebereich 0 bis 1023), was eine Auflösung von 10V/1024=9.765625mV ergibt. Ein Messwert von 512 entspricht hier also 5V und 1023 wären ungefähr 10V! Diese Grenzwerte sollten aber normalerweise nie erreicht werden! Das ist nicht besonders genau, da die Widerstände keineswegs Präzisionswiderstände sind. Abweichungen von einigen Prozent nach oben und unten sind möglich. Auch die Referenzspannung von 5V ist nicht ganz genau und kann bei normaler Belastung etwas variieren. Das stört hier nicht, denn wir brauchen ohnehin nur einen ungefähren Wert um festzustellen ob die Batterien sich langsam dem Ende nähern. Wer die Spannung genau messen will, braucht ein Multimeter um den Messfehler zu ermitteln und diesen dann in Software auszugleichen. Wenn man mit Fehlern leben kann, kann man die Spannung dank des günstigen Umrechnungsverhältnisses sogar direkt aus den ADC Werten ungefähr abschätzen: 720 entsprechen dann grob 7.2V, 700 etwa 7V und 650 wären etwa 6.5V. Bei einem konstanten Wert unter 560 kann man davon ausgehen, dass die Akkus fast leer sind.

Motorstrom

Es befinden sich zwei Leistungswiderstände in den beiden Motorstromkreisen. Aus dem Ohm'schen Gesetz U=R⋅I folgt, dass sich die Spannung die an einem bestimmten Widerstand abfällt, proportional zum Strom verhält, der diesen durchfließt! Damit die Spannungsabfälle an den Widerständen nicht zu groß werden, müssen die Widerstände klein gewählt werden. In unserem Fall haben Sie einen Wert von 0.1 Ohm Die abfallende Spannung ist also nur sehr klein (0.1V bei einem Strom von 1A) und muss verstärkt werden bevor sie mit dem ADC gemessen werden kann. Das erledigt jeweils ein sog. Operationsverstärker (OPV). In der Schaltung des RP6 wird je Motorkanal ein OPV verwendet. Der Messbereich geht etwa bis 1.8A. Bei 1.8A fallen etwa 0.18V am Widerstand ab und es ergibt sich am Ausgang des OPV eine Spannung von etwa 4V. Mehr kann der verwendete OPV bei 5V Betriebsspannung nicht ausgeben. Die Leistungswiderstände haben eine Toleranz von 10%, die Widerstände am OPV 5%, also ist das alles nur sehr ungenau (Ungenauigkeiten im Bereich von etwa 270mA sind möglich wenn man die Sensoren nicht kalibriert!). Wir brauchen allerdings auch nur den ungefähren Wert um festzustellen ob die Motoren stark oder wenig belastet werden. So kann der Roboter gut blockierte oder gar defekte Motoren bzw. Drehgeber erkennen! Die DC-Motoren benötigen mehr Strom je stärker sie belastet werden (Drehmoment) und somit steigt der Strom sehr stark an wenn die Motoren blockiert sind. Das wird von der Robotersoftware zur Notabschaltung verwendet: wenn die Motoren dauerhaft mit hohem Strom betrieben würden, könnten diese sehr heiß werden und dadurch Schaden nehmen! Und wenn die Encoder mal ausfallen sollten – aus welchem Grund auch immer – kann auch das damit erkannt werden. Man würde dann eine Drehzahl von 0 messen. Lässt man die Motoren aber auf voller Kraft laufen und der Strom bleibt trotzdem klein (also sind die Ketten nicht blockiert!), kann man genau daraus schließen, dass entweder die Encoder, oder die Motoren ausgefallen sind (oder Encoder und Motorstromsensoren nicht funktionieren... das passiert z.B. wenn man vergessen hat diese vorher per Software einzuschalten).

Encoder

Ganz anders als die letztgenannten Sensoren funktionieren die Drehgeber, die an den Getrieben der Motoren zur Drehzahlmessung angebracht sind. Es handelt sich dabei um Reflexlichtschranken, die auf Codierscheiben mit je 18 weissen und 18 schwarzen Segmenten ausgerichtet sind, also insgesamt 36 Segmente (s. Abb). Diese Codierscheiben sind wiederum an je eines der Zahnräder der beiden Getriebe geklebt worden. Wenn es sich dreht, wandern die einzelnen Segmente an der Reflexlichtschranke vorbei. Die weissen Segmente reflektieren das Infrarotlicht, die schwarzen Segmente nur wenig. Die Drehgeber erzeugen so zwar auch wie die anderen Sensoren ein analoges Signal, aber es wird digital interpretiert. Zunächst wird das Signal verstärkt und anschließend über einen sog. Schmitt Trigger in ein Rechtecksignal umgewandelt. Die Flanken dieses Signals, also die Wechsel von 5 auf 0V und umgekehrt, lösen jeweils ein Interrupt Ereignis aus und diese werden dann von der Software gezählt. So kann die zurückgelegte Wegstrecke gemessen und zusammen mit einem Timer zur Zeitmessung die Drehzahl und damit auch die Geschwindigkeit ermittelt werden. Die Ermittlung der Drehzahl ist auch Hauptanwendung der Encoder – nur mit den Encodern kann man die Drehzahl auf den gewünschten Sollwert einregeln. Ohne Regelung wäre die Drehzahl nämlich von der Akkuspannung, Belastung der Motoren usw. abhängig. Die hohe Auflösung ermöglicht es dabei, auch niedrige Geschwindigkeiten noch relativ genau einzuregeln. Jedes der zwei mittleren Stufenzahnräder des Getriebes hat 50 Zähne auf dem großen, und 12 auf dem kleineren Zahnrad (s. Abb). Die Codierscheiben befinden sich auf dem Zahnrad neben dem Motor, also rechnet man: 50/12 * 50/12 =17.13/36; 17.13/36 * 36=625 Daher haben die Encoderscheiben auch Ihre 36 Segmente, denn das gibt eine schöne runde Zahl ohne gebrochenen Anteil. Die Drehgeber erzeugen also 625 Flanken pro Radumdrehung wobei jede Flanke einem Segment entspricht. Bei einem Raddurchmesser von ca. 50mm inkl. Raupenkette, ergibt sich rein rechnerisch ein Radumfang von ca. 157mm was 0.2512mm pro Zählschritt der Drehgeber entspricht. Da sich die Raupenketten aber fast immer etwas in den Untergrund eindrücken (bzw. auch selbst eingedrückt werden) kann man aber von 0.25mm pro Zählschritt ausgehen – meist ist es sogar etwas weniger, z.B. nur 0.24 oder 0.23mm. Das muss man durch abfahren von Teststrecken ermitteln, wie es im Anhang grob beschrieben ist. Sehr genau ist das allerdings durch Radschlupf (bzw. hier müssten wir eigentlich von „Kettenschlupf“ sprechen) und ähnlichen Dingen nicht - vor allem beim Rotieren auf der Stelle. Beim normalen Geradeausfahren ist dieser Fehler klein, aber beim Rotieren kann er schnell sehr große Werte annehmen! Abweichungen muss man evtl. durch weitere Tests ermitteln und mit einkalkulieren. Das ist bei Raupenantrieben leider so – auch bei viel teureren und hochwertigeren Robotern. Dafür hat man aber den Vorteil, dass der Roboter mit Raupenantrieb recht geländegängig ist im Vergleich zu Robotern mit normalem Differentialantrieb mit zwei Antriebsrädern und Stützrad. Kleinere Hindernisse und Rampen kann er meist problemlos überwinden. Dabei sind die Encoder sehr nützlich, denn man kann die Geschwindigkeit gut einregeln, egal wie der Untergrund und die Motorbelastung gerade aussieht. Bei gemessenen 50 Segmenten pro Sekunde liegt die Geschwindigkeit bei 1.25 cm/s, sofern wir von 0.25mm pro Zählschritt ausgehen. Etwa 50 Segmente pro Sekunde ist auch die geringste gerade noch regelbare Geschwindigkeit (das variiert aber etwas von Roboter zu Roboter). Bei 1200 Segmenten pro Sekunde wären es die maximal möglichen 30 cm/s (bei 0.25mm Auflösung, bei 0.23 sind es 27.6 cm/s). Standardmäßig begrenzt die Funktionsbibliothek das aber auf 1000 Flanken pro Sekunde. Die maximale Geschwindigkeit ist vom Ladezustand der Akkus abhängig – daher wären 30cm/s nicht besonders lange haltbar. Außerdem erhöht sich die Lebensdauer der Getriebe und Motoren je langsamer man fährt! Wenn der Roboter 4000 Segmente gezählt hat, ist er übrigens etwa einen Meter weit gefahren. Aber wie schon gesagt, gilt das natürlich nur für genau 0.25mm Auflösung. Ohne Kalibrierung hat man hier immer mehr oder weniger starke Abweichungen. Wem es nicht auf jeden mm ankommt, braucht nichts zu kalibrieren und kann einfach von 0.25mm oder besser 0.24mm ausgehen! Optimal ist es, wenn man sich für Weg- und Winkelmessungen nicht auf die Encoder Daten stützen muss, sondern externe Systeme wie Infrarotbaken oder einen genauen elektronischen Kompass dazu zur Verfügung hat.

Stoßstangensensoren (Bumper)

Vorn am Roboter sind zwei Mikroschalter mit langem Schalthebel auf einer separaten Platine untergebracht, die etwas vor der anderen Sensorplatine liegt. Dadurch werden die IR LEDs auf der Sensorplatine geschützt und können nicht so leicht verbiegen wenn der Roboter mal gegen ein Hindernis fährt. Mit den zwei Schaltern kann der Mikrocontroller einen solchen Aufprall registrieren und dann beispielsweise zurücksetzen, sich etwas drehen und weiterfahren. Die Schalter sind an zwei der Ports die schon mit den LEDs verbunden sind angeschlossen und blockieren so keine anderen Ports des Mikrocontrollers. Daher leuchten die LEDs auch immer wenn man einen der Schalter drückt! Da dies normalerweise relativ selten passiert, stört das aber nicht weiter. Die Stoßstange kann man auch abmontieren und z.B. gegen eine Schuss- oder Sammelvorrichtung für Bälle o.ä. ersetzen wenn man möchte.

Lichtsensoren(LDRs)

Vorne auf der kleinen Sensorplatine des Roboters sind zwei sog. LDRs (="Light Dependant Resistors" also lichtabhängige Widerstände) platziert und nach links bzw. rechts ausgerichtet. Zwischen den beiden Sensoren ist noch eine kleine schwarze „Trennwand“ damit das Licht aus einer Richtung möglichst nur einen der Sensoren erreicht. Sie bilden zusammen mit je einem normalen Widerstand wie beim Batteriesensor einen Spannungsteiler – hier allerdings um das Umgebungslicht zu messen. Die 5V Betriebsspannung wird auch geteilt, aber hier ist einer der Widerstände variabel! Es wird also das Teilungsverhältnis je nach Intensität des Lichteinfalls verändert und somit eine vom Lichteinfall abhängige Spannung an einen der A/D Wandler Kanäle geleitet! Über den Spannungsunterschied zwischen den beiden Sensoren kann man ermitteln in welcher Richtung sich eine bzw. die hellste Lichtquelle vor dem Roboter befindet: Links, Rechts oder in der Mitte. Mit einem entsprechenden Programm, kann man so z.B. eine starke Taschenlampe in einem abgedunkelten Zimmer verfolgen, oder den Roboter die hellste Stelle in einem Raum suchen lassen! Klappt z.B. sehr gut mit einem stärkeren Hand-Halogenscheinwerfer: Wenn man damit auf den Boden leuchtet, kann der Roboter dem Lichtfleck auf dem Boden folgen. Das geht natürlich auch umgekehrt: Der Roboter könnte z.B. auch versuchen sich vor hellem Licht zu verstecken... Wenn man noch ein oder zwei LDRs hinten am Roboter anbringen würde, könnte man das noch verfeinern und die Richtung in der sich Lichtquellen befinden besser bestimmen. Der Roboter kann sonst nämlich oft nur schwer unterscheiden ob die Lichtquelle vor oder hinter ihm liegt. Zwei der A/D Wandler Kanäle sind noch frei...

Anti Collision System (ACS)

Der aus Softwaresicht komplexeste Sensor des RP6 ist das ACS - das „Anti Collision System“ (engl. für Anti Kollisions System)! Es besteht aus einem IR Empfänger (s. Abb.) und zwei vorne auf der Sensorplatine links und rechts angebrachten IR LEDs. Die IR LEDs werden direkt vom Mikrocontroller angesteuert. Die Ansteuerungsroutinen können beliebig verändert und verbessert werden! Beim Vorgängermodell war dafür noch ein eigener Controller nötig, dessen Programm aber nicht vom Anwender geändert werden konnte... Mit den IR LEDs werden kurze, mit 36kHz modulierte Infrarot Impulse ausgesandt, auf die der darauf ausgelegte IR Empfänger reagiert. Werden die IR Impule an einem Gegenstand vor dem Roboter reflektiert und vom IR Empfänger detektiert, kann der Mikrocontroller darauf reagieren und z.B. ein Ausweichmanöver einleiten. Damit das ACS nicht zu empfindlich bzw. auf eventuelle Störungen reagiert, wartet die Software bis eine bestimmte Anzahl von Impulsen in einer bestimmten Zeit empfangen worden ist. Es wird auch eine Synchronisation mit dem RC5 Empfang durchgeführt und auf die RC5 Signale von TV/Hifi Fernbedienungen wird so nicht reagiert. Bei anderen Codes kann das aber nicht garantiert werden und das ACS könnte dann Hindernisse erkennen, wo gar keine sind! Da es je eine IR LED links und rechts gibt, kann das ACS grob unterscheiden ob sich das Objekt links, rechts oder mittig vor dem Roboter befindet. Man kann zusätzlich noch die Stromstärke mit der die beiden IR LEDs gepulst werden in drei Stufen einstellen. Das ACS funktioniert aber auch in der höchsten Stufe nicht mit allen Objekten immer zuverlässig, denn es kommt auf die Beschaffenheit der Oberfläche des jeweiligen Objekts an! Ein schwarzes Objekt reflektiert das IR Licht natürlich viel schlechter als ein weisses Objekt und ein kantiges und spiegelndes Objekt könnte das IR Licht hauptsächlich in eine bestimme Richtung reflektieren. Die Reichweite ist also immer vom jeweiligen Objekt abhängig! Das ist eine prinzipielle Schwäche von so gut wie allen IR Sensoren (jedenfalls in dieser Preisklasse). Trotzdem werden die meisten Hindernisse zuverlässig erkannt und können umfahren werden. Falls das mal nicht klappt, gibt es noch die Stoßstange mit den Tastsensoren und falls auch die nicht richtig getroffen werden, kann der Roboter noch mit den Motorstromsensoren oder den Encodern erkennen, ob die Motoren blockieren (s.u.)! Wem das nicht reicht, der könnte zusätzlich z.B. noch Ultraschallsensoren anbringen...

IR-Kommunikation

Der RP6 kann über die IR-LEDs links und rechts über der Bumper-Platine Daten zu anderen IR-Empfängern senden. RC5 Codes werden über den ACS-Sensor empfangen.

H-Brücke

Über die H-Brücken werden die Motoren gesteuert.

Umbau-Optionen

Erweiterungen und Zubehör

Es sind von Arexx schon drei Erweiterungsmöglichkeiten auf dem Markt. Zum Ersten die Experimentierplatinen (191537), die zum Erstellen von eigenen Schaltungen und Sensoren gedacht sind, und von denen eine schon im Lieferumfang enthalten ist, das Erweiterungsboard RP6 CONTROL M32 (191550), welches einen weiteren AVR Controller, der doppelt so schnell getaktet wird wie der Controller vom Mainboard sowie

  • einen Piezo Tongeber
  • 4 LEDs
  • 5 Taster
  • mehr EEPROM Speicher
  • ein Mikrofon (Peak detector)
  • LC-Display Port (190911).

Das RP6 CCPRO M128 (191563), ist in CompactC und Basic programmierbar und bietet folgendes:

  • 64K SRAM Speicherweiterung
  • LC-Display Port
  • einen hochauflösender Temperatursensor
  • einen Piezo Tongeber
  • 5 LEDs
  • 19 freie I/Os davon 8 ADCs, 3 Servo Ports, 1 UART
  • Bis zu 19 weitere I/Os verfügbar durch Deaktivierung von Komponenten auf der Platine
  • SPI Bus für externe Komponenten
  • einen Sockel für 24LCxxx EEPROMs mit bis zu 1MBit Kapazität.

Die Boards kann man dann über den I2C Bus mit dem Mainboard kommunizieren lassen. Basierend auf dem Master-Slave System könnte man so bis zu 127 Slaves anschließen. Zudem ist es ratsam, qualitativ hochwertige Akkus und ein Ladegerät mit passendem Stecker zu verwenden, da man ansonsten immer das Mainboard abschrauben müsste um an die Akkus heranzukommen. Für den Fall wurde extra eine Ladebuchse eingebaut.

Experimentierplatine

RP6 Experimentierplatine

RP6 CONTROL M32 Platine

RP6 CONTROL M32

Umbau-Optionen

Dieser Absatz soll die RP6 CONTROL M32 Platine (im Folgenden "M32" genannt) nicht im Detail beschreiben, sondern die Möglichkeiten auflisten, die es gibt, um auf einfache Weise weitere Anschlüsse oder Verbindungen zu ermöglichen. Nicht beschrieben werden die Anschlußmöglichkeiten, die in Form der vorhandenen Wannenstecker sowieso gegeben sind (z.B. am LCD-, I/O- oder ADC-Stecker).

Folgende Möglichkeiten zum Umbau/Ausbau sind vorgesehen:

  • 1) Zweites SPI-EEPROM (IC5)
  • 2) Zwei analoge Sensoren, evtl. mit getrennter Stromversorgung
  • 3) ISP (In System Programming)
  • 4) JTAG-Programmierung
  • 5) USRBUS
  • 6) IRQ-Zuweisung ändern
  • 7) ADC0 und ADC1 anders nutzen
  • 8) Schieberegister kaskadieren

Im folgenden Text soll beschrieben werden, wie man die weiteren Möglichkeiten nutzen kann. Es wird jeweils erwähnt, was man an Material braucht. Beispielhaft sind da Bestell-Nummern der Firma CONRAD genannt. Natürlich kann man die Teile auch bei anderen Versendern beziehen. Durch die Nennung der Bestell-Nummer ist das jeweilige Teil aber gut zu identifizieren. Man sollte Löten können und sich bewußt sein, dass ggf. ein Garantieanspruch nicht mehr besteht, wenn man an der Platine gelötet hat.

Zweites SPI-EEPROM

Es ist sehr einfach, ein zweites SPI-EEPROM auf der M32 zu nutzen.

Man braucht dazu:

  • Einen IC-Sockel 8-pol DIP für IC5 (189600-36)
  • Einen Keramik-Vielschicht-Kondensator 100nF (C19); RM 2,54mm (453099-36)
  • Ein serielles SPI-EEPROM im PDIP8 Gehäuse (IC5)

Zuerst wird der IC-Sockel eingelötet (Kerbe beachten!), dann C19. Das war's.

Sockel des 2. SPI-EEPROMs

Leider gibt es das EEPROM nicht bei den gängigeren Versendern. Bekommen kann man es aber z.B. bei Farnell. Dort hat das SPI-EEPROM mit 256 kbit die Bezeichnung 25LC256-I/P (1331398). Wenn man es noch größer mag: 25LC1024 (1331392) mit 1024 kbit.

Programmierung:

In die RP6ControlLib.h bitte einfügen:

#define SPI_EEPROM2_PAGESIZE 64

uint8_t SPI_EEPROM2_readByte(uint16_t memAddr);
void SPI_EEPROM2_writeByte(uint16_t memAddr, uint8_t data);
void SPI_EEPROM2_enableWrite(void);
void SPI_EEPROM2_disableWrite(void);
uint8_t SPI_EEPROM2_getStatus(void);

void SPI_EEPROM2_writeBytes(uint16_t startAddr, uint8_t *buffer, uint8_t length);
void SPI_EEPROM2_readBytes(uint16_t startAddr, uint8_t *buffer, uint8_t length);

Die Konstante SPI_EEPROM2_PAGESIZE ist abhängig von der Art und Größe des EEPROMs. Für ein 256 kbit-EEPROM ist die Seitengröße (pagesize) in der Regel 64, für einen 512 kbit-Typ 128 und für einen 1024 kbit-Typ 256.

In die RP6ControlLib.c bitte einfügen:

/*****************************************************************************/
// Second external SPI EEPROM:

/**
 * Reads a single Byte from the 2nd external EEPROM.
 */
uint8_t SPI_EEPROM2_readByte(uint16_t memAddr)
{
	uint8_t data;
	PORTB &= ~MEM_CS2;
	writeSPI(SPI_EEPROM_READ);
	writeWordSPI(memAddr);
	data = readSPI();
	PORTB |= MEM_CS2;
	return data;
}

/**
 * Reads "length" Bytes into the Buffer "buffer" from startAdr on. 
 * You can read the complete 2nd EEPROM into a buffer at once - if it is large enough. 
 * (But you only have 2KB SRAM on a MEGA32 ;) )
 */
void SPI_EEPROM2_readBytes(uint16_t startAddr, uint8_t *buffer, uint8_t length)
{
	PORTB &= ~MEM_CS2;
	writeSPI(SPI_EEPROM_READ);
	writeWordSPI(startAddr);
	readBufferSPI(&buffer[0], length);
	PORTB |= MEM_CS2;
}

/**
 * Enable Write Mode
 */
void SPI_EEPROM2_enableWrite(void)
{
	PORTB &= ~MEM_CS2;
	writeSPI(SPI_EEPROM_WREN);
	PORTB |= MEM_CS2;
}

/**
 * Disable Write Mode
 */
void SPI_EEPROM2_disableWrite(void)
{
	PORTB &= ~MEM_CS2;
	writeSPI(SPI_EEPROM_WRDI);
	PORTB |= MEM_CS2;
}

/**
 * Write a single data byte to the specified 2nd EEPROM address.
 */
void SPI_EEPROM2_writeByte(uint16_t memAddr, uint8_t data)
{
	while(SPI_EEPROM2_getStatus() & SPI_EEPROM_STAT_WIP);
	SPI_EEPROM2_enableWrite();
	PORTB &= ~MEM_CS2;
	writeSPI(SPI_EEPROM_WRITE);
	writeWordSPI(memAddr);
	writeSPI(data);
	PORTB |= MEM_CS2;
}

/**
 * Write "length" Bytes from the Buffer to the 2nd EEPROM. 
 * YOU CAN ONLY WRITE MAXIMAL [SPI_EEPROM2_PAGESIZE] BYTES AT ONCE!!!
 * This is the Pagesize!
 * You can NOT cross a page boundary!
 *
 */
void SPI_EEPROM2_writeBytes(uint16_t startAddr, uint8_t *buffer, uint8_t length)
{
	while(SPI_EEPROM2_getStatus() & SPI_EEPROM_STAT_WIP);
	SPI_EEPROM2_enableWrite();
	PORTB &= ~MEM_CS2;
	writeSPI(SPI_EEPROM_WRITE);
	writeWordSPI(startAddr);
	writeBufferSPI(&buffer[0], length);
	PORTB |= MEM_CS2;
}

/**
 * Returns EEPROM Status register - for checking if 2nd EEPROM is buisy. 
 * Writing takes about 5ms. 
 */
uint8_t SPI_EEPROM2_getStatus(void)
{
	uint8_t status;
	PORTB &= ~MEM_CS2;
	writeSPI(SPI_EEPROM_RDSR);
	status = readSPI();
	PORTB |= MEM_CS2;
	return status;
}

/*****************************************************************************/

Hinweis zum 1024 kbit-EEPROM:

Dieses EEPROM benötigt 24-Bit Adressen und muss daher etwas anders angesprochen werden als die "kleineren" Typen bis 512 kbit. Die Funktion SPI_EEPROM2_readByte() sieht für ein 1024 kbit-EEPROM z.B. so aus:

uint8_t SPI_EEPROM2_readByte(uint32_t memAddr)
{
	uint8_t data;
	PORTB &= ~MEM_CS2;
	writeSPI(SPI_EEPROM_READ);
	writeSPI((uint8_t)(memAddr >> 16));
	writeWordSPI((uint16_t)memAddr);
	data = readSPI();
	PORTB |= MEM_CS2;
	return data;
}

Alle weiteren Funktionen, die EEPROM-Adressen verwenden (SPI_EEPROM2_readBytes, SPI_EEPROM2_writeByte, SPI_EEPROM2_writeBytes), müssen genau so angepasst werden.

Zwei analoge Sensoren, evtl. mit getrennter Stromversorgung

Wenn man bis zu zwei analoge Sensoren (z.B. IR-Distanz-Mess-Sensoren Sharp GP2Y0A02YK 185364-36) mit höherem Stromverbrauch direkt an die M32 anschließen möchte, dann gibt es da zwei 3-polige Kontakte, beschriftet mit VDD/GND/ADCx (x = 2..3). Hier kann man 3-polige Stiftleisten auflöten, an die dann die Sensoren angeschlossen werden.

Vor dem Umbau sollte klar sein, ob man für die Sensoren eine getrennte Stromversorgung anschließen möchte, oder ob die 5V-Versorgung des RP6 mit benutzt werden soll.

Man braucht dazu:

  • 1-reihige Stiftleiste RM 2,54mm (z.B. 36-polig 732478-36)
  • Zwei Keramik-Vielschicht-Kondensatoren 100nF (C16, C17); RM 2,54mm (453099-36)
  • Ein Elektrolyt-Kondensator stehend 470 uF / 16V (C18); RM 3,5mm (446211-36)
  • Zwei 3-polige Steckbuchsen mit Litze zum Anschluß der Sensoren (z.B. aus 976261-36)
  • Evtl.: Eine Codierbrücke (z.B. aus Set 742902-36)
  • Evtl.: Eine 1-polige Steckbuchse mit Litze zur ext. Stromversorgung (z.B. aus 976261-36)

Wenn man eine GETRENNTE Stromversorgung für die beiden Sensoren vorsehen will oder mit Codierbrücke die RP6-Stromversorgung für die beiden Sensoren abschaltbar machen möchte, muss man erst etwas Vorarbeit leisten:

Es muss eine kurze Leiterbahn zwischen den Punkten "SV1" und "SV2" aufgetrennt werden. Die Leiterbahn befindet sich auf der Lötseite der Platine und muss mit einem scharfen Messer oder einem speziellen Leiterbahn-Unterbrecher zwischen den beiden Lötpunkten unterbrochen werden. Man sollte anschließend mit einem Widerstandsmeßgerät zwischen SV1 und SV2 nachmessen: Es sollte keine Verbindung mehr bestehen. Jetzt trennt man von der 1-reihigen Stiftleiste 2 Kontakte ab und lötet sie auf die Punkte SV1/SV2.

Wenn man keine getrennte Stromversorgung vorsehen will, geht es jetzt erst los: Man trennt von der 1-reihigen Stiftleiste zweimal 3 Kontakte ab und lötet sie auf die weiß umrahmten Kontakte (VDD/GND/ADCx), anschließend C16, C17 auf ihre Plätze und zum Schluß den Elko 470 uF (C18). Beim Elko auf die Polung achten: Er muss genau so sitzen wie sein Nachbar C1 (Minuspol schaut zum Beeper SND).

ADC2 ADC3

Die Sensoren lötet man an die Litzen der 3-poligen Steckbuchsen und steckt diese auf die neuen Kontakte. Wenn man auf SV1/SV2 eine Stiftleiste gelötet hat (s.o.), kann man hier zunächst die Codierbrücke aufstecken. Damit versorgt der RP6 Akku die Sensoren mit 5V an den Pins VDD. Möchte man später eine getrennte 5V-Spannung anlegen, zieht man einfach die Codierbrücke ab und speist die externe 5V-Spannung (mit einer 1-poligen Steckbuchse) am Pin SV2 ein. Achtung: An Pin SV1 wird dann nichts angeschlossen!

ISP (In System Programming)

Der ATMEGA32 der M32 wird standardmäßig über den PROG/UART Stecker programmiert. Dazu befindet sich im Prozessor ein Bootloader-Programm. Wenn man stattdessen oder zusätzlich die ISP-Programmierung mit einem dafür geeigneten ISP-Programmier-Adapter nutzen will, kann man den Adapter an den gewinkelten ISP-Stecker auf der M32 anschließen. Vorher sind aber ein paar "Umbauarbeiten" erforderlich.

Man braucht dazu:

  • 1-reihige Stiftleiste RM 2,54mm (z.B. 36-polig 732478-36)
  • Einen SMD-Widerstand 10 kOhm (406376-36)
  • Eine Codierbrücke (z.B. aus Set 742902-36)

Der SMD-Widerstand wird auf seinen Platz (R1) neben dem XBUS2-Stecker gelötet. Zwischen R1 und C1 befinden sich drei Lötpunkte (beschriftet mit ISP/DEBUG - BOOTLOAD), auf die eine 3-polige Stiftleiste gelötet werden muss. Vorher muss eine kurze Leiterbahn zwischen den Lötpunkten BOOTLOAD aufgetrennt werden. Die Leiterbahn befindet sich auf der Lötseite der Platine und muss mit einem scharfen Messer oder einem speziellen Leiterbahn-Unterbrecher zwischen den beiden Lötpunkten unterbrochen werden. Man sollte anschließend mit einem Widerstandsmeßgerät nachmessen: Es sollte keine Verbindung mehr zwischen den Lötpunkten bestehen. Man trennt dann von der 1-reihigen Stiftleiste 3 Kontakte ab und lötet sie auf die beschriebenen drei Lötpunkte.

ISP

Wenn man jetzt eine Codierbrücke auf die mit "BOOTLOAD" beschrifteten Pins steckt, bleibt alles unverändert: Die Programmierung erfolgt weiter über den PROG/UART-Stecker mithilfe des Bootloaders im Prozessor. Wird die Codierbrücke in Stellung "ISP/DEBUG" umgesteckt, kann der Prozessor mit ISP programmiert werden.

Vorsicht: Das Bootloader-Programm kann dabei zerstört werden! Es müssen zusätzlich Fusebits des ATMEGA32 verändert werden. Dabei kann der Prozessor im schlimmsten Fall nicht mehr ansprechbar sein. Man sollte diesen Umbau und die ISP-Programmierung nur machen, wenn man genau weiß, was man macht!

Eine Kopie des Bootloaders und eine Kurzanleitung zum Einstellen der Fusebits gibt es hier: RP6_M32_BOOTLOADER

JTAG

Die Programmierung und ein Debuggen sind auch mit der JTAG-Schnittstelle möglich. Das ist nur zu empfehlen, wenn man Erfahrungen mitbringt, oder der Prozessor der M32 durch eine ISP-Falschprogrammierung z.B. nicht mehr ansprechbar ist. Um die JTAG-Schnittstelle nutzen zu können, muss der ISP-Umbau durchgeführt worden sein und die dort beschriebene Codierbrücke auf "ISP/DEBUG" gesteckt sein. Der JTAG-Programmer kann dann an die Lötpunkte "JTAG" zwischen ISP- und I/O-Stecker angeschlossen werden.

JTAG

Man braucht dazu:

  • 2-reihige Stiftleiste RM 2,54mm (z.B. 2x36-polig 742007-15)

Man trennt von der 2-reihigen Stiftleiste 2x5 Kontakte ab und lötet sie auf die 10 JTAG-Lötpunkte. Hier kann jetzt der JTAG-Programmer z.B. mit einem 10-poligen Flachkabel-Stecker angeschlossen werden. Um das JTAG-Interface des ATMEGA32 nutzen zu können, müssen Änderungen an den Fusebits vorgenommen werden.

Vorsicht: Man sollte die JTAG-Programmierung und Fusebit-Manipulationen nur machen, wenn man genau weiß, was man macht!

USRBUS

Die jeweils 14 Kontakte der beiden USRBUS-Stecker sind auf der M32 nirgendwo angeschlossen, sondern können über die Lötpunkte Y1..Y14 mit beliebigen Punkten auf der M32 verbunden werden.

USRBUS

Ich würde auf Y1..Y14 eine Stiftleiste löten, damit die USRBUS-Belegung geändert werden kann.

Man braucht dazu:

  • 2-reihige Stiftleiste RM 2,54mm (z.B. 2x36-polig 742007-15)
  • Einige Steckbuchsen mit Litze (z.B. aus 976261-36)

Man trennt von der 2-reihigen Stiftleiste 2x7 Kontakte ab und lötet sie auf die Punkte Y1..Y14 neben dem Wannenstecker USRBUS2. Wird die M32 über Flachkabel mit einem USRBUS-Stecker auf einer RP6 Experimentierplatine (EP) und/oder mit dem RP6 selbst verbunden, dann hat man mit allen mit dem USRBUS verbundenen Platinen eine direkte 14-polige Verbindung,- eben den "User Bus". Den kann man dann nutzen, wie man will. Auf der M32 kann man mit Steckbuchsen die Pins Y1..Y14 mit anderen Pins verbinden.

Beispiel: Verbindet man den Pin "ADC2" mit Y1 des USRBUS, dann steht der Eingang ADC2 auf allen an den USRBUS angeschlossenen Platinen zur Verfügung. Man braucht also diesen Eingang nicht über ein eigenes Kabel auf eine EP zu führen, sondern kann dazu den USRBUS nehmen. Dadurch bleibt der Gesamtaufbau auf dem RP6 übersichtlich und komplett trennbar (man braucht nur die Stecker XBUS und USRBUS abziehen!).

Wichtig: Man sollte gut dokumentieren, wie man den USRBUS am RP6 (vorn und hinten getrennt!), auf EPs und der M32 benutzt! Sonst kann es bei einer anderen Anordnung von EPs zu USRBUS Konflikten/Kurzschlüssen kommen.

IRQ-Zuweisung ändern

Am XBUS stehen vier Interrupt-Pins (genannt INT1..INT3, INTU) zur Verfügung. INT1 ist auf der RP6 Base mit PA4 verbunden, auf der M32 mit PD2 (Prozessor INT0) und soll hier nicht weiter betrachtet werden.

INT2 und INT3 sind auf der M32 mit den ATMEGA32-Pins PD3 und PB2 (M32-Prozessor INT1 und INT2) verbunden. INTU ist identisch mit INT2. Diese Belegung kann man durch drei Codierbrücken (beschriftet mit I2-INTU/INT3-I3/I2-INT2) ändern.

Man braucht dazu:

  • 2-reihige Stiftleiste RM 2,54mm (z.B. 2x36-polig 742007-15)
  • Drei Codierbrücken (z.B. aus Set 742902-36)

Vor dem Auflöten der Stiftleiste müssen zwei kurze Leiterbahnen zwischen zwei Lötpunkten aufgetrennt werden, und zwar zwischen den Lötpunkten INT3-I3 und I2-INT2. Die Leiterbahnen müssen mit einem scharfen Messer oder einem speziellen Leiterbahn-Unterbrecher zwischen den beiden Lötpunkten unterbrochen werden. Man sollte anschließend mit einem Widerstandsmeßgerät nachmessen: Es sollte keine Verbindung mehr zwischen INT3-I3 und I2-INT2 bestehen. Man trennt dann von der 2-reihigen Stiftleiste 2x3 Kontakte ab und lötet sie auf das weiß umrahmte Feld mit der o.g. Beschriftung.

INTx

Hier kann man jetzt drei Codierbrücken aufstecken, wenn man die Standard-Belegung beibehalten will. Wenn man keine der Codierbrücken aufsteckt, sind die Pins PD3 (I2) und PB2 (I3) des M32-Prozessors nicht mehr mit dem XBUS verbunden. Auf der M32 kann man dann z.B. auch andere Verbindungen zum XBUS herstellen, indem man auf die Pins INT2, INT3 oder INTU Kabelverbindungen aufsteckt.

ADC0 und ADC1 frei nutzen

Auf der M32 ist ADC0 fest mit dem Mikrofon (MIC) und ADC1 mit den Tastern T1..T5 (KEYPAD) verbunden. Wenn man diese ADC-Eingänge für andere Sensoren benötigt, kann man das Mikrofon und die Taster von den Eingängen abtrennen.

Man braucht dazu:

  • 1-reihige Stiftleiste RM 2,54mm (z.B. 36-polig 732478-36)
  • Eine Codierbrücke (z.B. aus Set 742902-36)

MIC_KEYPAD

MIC/ADC0: Es muss eine kurze Leiterbahn zwischen zwei Lötpunkten aufgetrennt werden, die sich zwischen R2 und C19 befinden. Die Leiterbahn muss mit einem scharfen Messer oder einem speziellen Leiterbahn-Unterbrecher zwischen den beiden Lötpunkten unterbrochen werden. Man sollte anschließend mit einem Widerstandsmeßgerät nachmessen: Es sollte keine Verbindung mehr bestehen. Vorsicht: Nicht R2 beschädigen! Damit ist das Mikrofon auf der M32 ohne Funktion und ADC0 kann anders genutzt werden. ADC0 ist dann am oberen Lötpunkt zwischen R2 und C19 verfügbar, dort müßte eine Kabelverbindung angelötet werden. Soll das Mikrofon später doch wieder an ADC0 angeschlossen werden, verbindet man die beiden Lötpunkte zwischen R2 und C19 einfach mit etwas Lötzinn oder mit einem SMD Null Ohm Widerstand.

KEYPAD/ADC1: Es muss eine kurze Leiterbahn zwischen zwei Lötpunkten aufgetrennt werden, die sich unterhalb von R15 befinden. Die Leiterbahn befindet sich auf der Lötseite der Platine und muss mit einem scharfen Messer oder einem speziellen Leiterbahn-Unterbrecher zwischen den beiden Lötpunkten unterbrochen werden. Man sollte anschließend mit einem Widerstandsmeßgerät nachmessen: Es sollte keine Verbindung mehr bestehen. Jetzt trennt man von der 1-reihigen Stiftleiste 2 Kontakte ab und lötet sie auf die beiden Punkte unterhalb von R15. Hier kann man jetzt eine Codierbrücke aufstecken, wenn man die Taster weiter benutzen will. Wenn die Brücke abgezogen ist, sind die Taster ohne Funktion und ADC1 kann anders genutzt werden. ADC1 ist dann am linken Pin der 2-poligen Stiftleiste unterhalb von R15 verfügbar.

Schiebregister kaskadieren

Auf der M32 wird ein 8-Bit Schieberegister-Baustein (IC3: 74HC4094D) dazu gebraucht, vier Status-LEDs (LED1..LED4) und ein LCD (am Stecker LCD) anzusteuern. Durch Schieberegister kann man Port-Pins gewinnen, wenn die Pins des Prozessors nicht ausreichen.

Solche Schieberegister kann man "kaskadieren", d.h. weitere identische Bausteine einbauen, die weitere Port-Pins zur Verfügung stellen. Wenn man zusätzliche 74HC4094 einsetzen will, wird man das am besten auf einer EP aufbauen. Die Anschlüsse für diese Schieberegister werden auf der M32 an einer 6-poligen Reihe von Lötpunkten (beschriftet mit MISO, STR, MOSI, SCK, QS, QS*) links von IC3 zur Verfügung gestellt.

SPI

Wenn man diese 6 Signalleitungen auf eine EP führen will, gibt es dafür zwei Möglichkeiten:

  • a) Direkte 6-polige Kabelverbindung von den oben beschriebenen Lötpunkten zur EP
  • b) Nutzung des USRBUS, um die 6 Signale zur EP zu führen

Wenn man im Abschnitt "USRBUS" den entsprechenden Umbau gemacht hat, würde ich b) empfehlen! Man könnte dafür eine 6-polige Stiftleiste auf die o.g. Lötpunkte auflöten und 1:1 z.B. mit den Pins Y4, Y6, Y8, Y10, Y12, Y14 des USRBUS verbinden. Dann kann man auf der EP weitere Schieberegister- und SPI-Bausteine (z.B. SPI-EEPROMs, RFM12 Transceiver o.ä.) aufbauen.

Man braucht dazu:

  • 1-reihige Stiftleiste RM 2,54mm (z.B. 36-polig 732478-36)
  • Steckbuchsen mit Litze (z.B. aus 976261-36)

Man trennt von der 1-reihigen Stiftleiste 6 Kontakte ab und lötet sie auf die beschriebenen sechs Lötpunkte auf der M32. Mit den Steckbuchsen mit Litze wird dann die Verbindung entweder direkt zur EP (Option a) oder über den USRBUS zur EP (Option b) hergestellt.

RP6 CCPRO M128

Das CCPRO M128

Programmierung

Beschreibung

Der Roboter kann frei in C programmiert werden, dies wird, durch die umfangreiche Funktionsbibliothek und die detailiert beschriebene Anleitung, auch Anfängern sehr leicht gemacht. Die Software die zur Programmierung verwendet wird, ist ausschließlich Freeware und kann entweder der CD entnommen oder aus dem Internet heruntergeladen werden. Ein Programm kann zum Beispiel so aussehen:



#include "RP6RobotBaseLib.h" // IMMER einbinden	

int main(void)
{
	initRobotBase(); // Den Roboter initialisieren

	setLEDs(0b111111); // Alle LEDs anschalten
	moveAtSpeed(100,100); // Mit Geschwindigkeit 100 auf beiden Motoren fahren
	mSleep(2000); // 2 Sekunden warten
	Stop(); // Anhalten

	while(true)
	{
               task_motionControl; // Geschwindigkeit regeln
	}
	return 0; 

}

In dem Programm würde der RP6 als erstes alle LEDs anschalten und für 2 Sekunden mit der selben Geschwindigkeit auf beiden Motoren fahren und dann stehen bleiben.

Die RP6 Demo-Programme

Die RP6 Demo Programme sind hier zu finden.

Die RP6RobotBase Library

Timer-Nutzung

Die RP6uart Library

Die RP6I2Cmaster/slaveTWI Library

Erfahrungsberichte

...in Arbeit...(kann aber gerne ergänzt werden)



Siehe auch

Weblinks

Autoren

--Sloti 22:23, 29. Dez 2007 (CET)

--Dirk 16:47, 26. Mai 2008 (CET)

--Tobias1 18:30, 06. April 2010 (CET)


LiFePO4 Speicher Test