Hallo liebe Leute!
Ich habe mich soeben hier in diesem Forum angemeldet, und das nicht grundlos! Mein Kollege und ich benötigen Hilfe bei der Realisierung unseres Balancierenden Roboters. Da wir beide absolute Grünschnäbel auf dem Gebiet der Microcontrollerprogrammierung sind benötigen wir nun fachmännische Hilfe.Dieses Projekt ist im Rahmen unserer Technikerausbildung zu realisieren. Die Hardware steht und scheint auch soweit richtig miteinander verbunden zu sein.
Wir haben einen Beschleunigungssensor des Typs "adxl335" verbaut sowie eine H-Brücke mini Motortreiber tb6612fng.Diese sind mit einem Atmega 8 (MK2 Board) verbunden.
Gänzlich falsch scheint unser Programm nicht zu sein, da der Motor bei einer ca 90° zu zucken beginnt, also einen Richtungswechsel vollzieht, allerdings sieht dies noch recht willkührlich aus.Was und wie es programmtechnisch zu verbessern ist, wissen wir nicht mehr. Wer kann uns Grünschnäbeln helfen?Wer hat Erfahrung damit?
Hier ist unser Quellcode:
#include <avr/io.h> // Header-Datei "io.h" einbinden
int32_t adwert; // Variable in die der Rueckgabewert der Auslese-Funktion
// geschrieben wird
int32_t i; // Variable i deklarieren
char buffer[20]; // String der L?nge 20 Zeichen deklarieren.
// ----------------------------------------------------------------------------------------------
// Unterprogramm "Sende"- Senden von Zeichenketten ?ber den UART --------------------------------
// ----------------------------------------------------------------------------------------------
void sende (char buffer[]) // Funktionsaufruf zum ?bermitteln einer Zeichenfolge
{
for (int i=0; buffer[i]!=0; i++) // for-Schleife: Abbruch wenn Zeichenfolge
{ // zu Ende ist, sonst "i" inkrementieren
while (bit_is_clear(UCSRA,5)) // Solange Zeichen noch nicht vollst?ndig ?bermittelt.
{
; // tue nichts! (warte)
}
UDR=buffer[i]; // Danach: Sende aktuelles ("i"-tes) Zeichen der Zeichenkette.
}
}
// ----------------------------------------------------------------------------------------------
// Unterprogramm "Zurück fahren des Roboters-----------------------------------------------------
// ----------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------
// Unterprogramm "VOR fahren des Roboters--------------------------------------------------------
// ----------------------------------------------------------------------------------------------
int Vor()
{
uint16_t ergebnis = 0; // Variable ergebnis deklarieren und auf 0 setzen.
ADMUX |= (1<<REFS1)|(1<<REFS0); // Register ADMUX des AD-Wandlers: Nutzung der internen
// Referenzspannung.
ADCSR = 0b11000101; // Register ADMUX des AD-Wandlers: Frequenzvorteiler auf
// 32 setzen und AD-Wandler aktivieren.
while (bit_is_set(ADCSR,6)); // Warten, bis Umwandlung erfolgt ist: (ADCSR-Bit 6 ist dann "1".)
ergebnis = ADCW; // AD-Wandlungs-Ergebnis in ADCW wird Variable "ergebnis" zugewiesen.
return ergebnis; // Wert von ergebnis wird an die Funktion (hier "lese()" )
// uebergeben.
}
// ----------------------------------------------------------------------------------------------
// Unterprogramm "LESE"-Lesen des Poti-Wertes mit dem ADC----------------------------------------
// ----------------------------------------------------------------------------------------------
int lese()
{
uint16_t ergebnis = 0; // Variable ergebnis deklarieren und auf 0 setzen.
ADMUX |= (1<<REFS1)|(1<<REFS0); // Register ADMUX des AD-Wandlers: Nutzung der internen
// Referenzspannung.
ADCSR = 0b11000101; // Register ADMUX des AD-Wandlers: Frequenzvorteiler auf
// 32 setzen und AD-Wandler aktivieren.
while (bit_is_set(ADCSR,6)); // Warten, bis Umwandlung erfolgt ist: (ADCSR-Bit 6 ist dann "1".)
ergebnis = ADCW; // AD-Wandlungs-Ergebnis in ADCW wird Variable "ergebnis" zugewiesen.
return ergebnis; // Wert von ergebnis wird an die Funktion (hier "lese()" )
// uebergeben.
}
// ----------------------------------------------------------------------------------------------
// Hauptprogramm --------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------
int main(void)
//UnknownType TCCR0A;
//UnknownType TCCR0B;
{
UBRRL = 23; // Quarz: 3.6864MHz, Baudrate 9600
UCSRB = 0b10011000; // Empf?nger, Sender ein UCR = UCSRB
//-----------------------MOTOR-A----------------------
TCCR1A = 0b10000011; // Timer1: 10Bit-PWM-Modus, Aufloesung=1024, nicht invertierende PWM.
TCCR1B = 0b00000001; // Timer1: Aktivieren mit Prescaler 1, also k e i n e Frequenzteilung.
//-----------------------MOTOR-A----------------------
//geht nicht warum TCCR0A = 0b10000011; // Timer1: 10Bit-PWM-Modus, Aufloesung=1024, nicht invertierende PWM.
//scheinbar gibts den tccr0 nicht TCCR0B = 0b00000001; // Timer1: Aktivieren mit Prescaler 1, also k e i n e Frequenzteilung.
DDRB = 0b00000010; // Ausgang PB1 fuer PWM-Signal Timer1 initialisieren. (vgl. Datenblatt: OC1A)
DDRD = 0b01001000; // Die Motorsteuerports werden initialisiert
DDRC = 0b00000000; // Eingang PC0 (ADC0, Potentiometer) initialisieren. (vgl. Pinout Atmega
while(1)
{
if(adwert < 900) {
PORTD &= (1<<6);
PORTD &= (1<<4);
PORTD |= (1<<7);
PORTD |= (1<<5);
} else {
PORTD &= (1<<7);
PORTD &= (1<<5);
PORTD |= (1<<6);
PORTD |= (1<<4);
}
//PORTD |= (1<<4); // Richtung des Motors
//PORTD |= (1<<6); // Richtung des Motors
adwert = lese(); // Wert des AD-Wandlers aus Unterprogramm "lese()" holen.
OCR1A = 1023; // Der gelesene Wert wird dem PWM-Vergleichswert OCR1A uebergeben.
// Timer läuft im Hintergrund.
sprintf(buffer, "ADC-Wert: %d #", adwert); // Der sprintf-Befehl schreibt die Dezimalwerte
// in eine Zeichenkette um, buffer ist der Speicher der Funktion und muss
// ausreichend gro? sein. %d ist Platzhalter f?r die umgewandelte Dezimalzahl;
// "#" dient dem Zeilenumbruch.
sende(buffer); // Aufruf des Unterprogramms sende. ?bergabe der Zeichenfolge buffer.
}
}
// ----------------------------------------------------------------------------------------------------
Lesezeichen