in der for-schleife musst du memo einen neuen wert zuweisen:
gruesseCode:if (IR_Wert[i]<memo) { memoposi = i; //Zum merken der Servoposition, bei der der kleinste //wert liegt memo=IR_Wert[i]; <------ fehlt }
Moin!
Ich habe folgendes problem:
Ich habe einen Servo der immer hin und her dreht. Auf diesen servo ist ein GP2D12 montiert. Jetzt möchte ich, das für jede Position des Servos (das sind insgesamt 51), ein ADC-Wert gespeichert wird. Später soll mein Roboter jenachdem wo der kleinste Wert liegt, eine kette vor und eine zurück bewegen, um da hinzulenken, weil beim kleinsten Wert ja das weiteste Hinderniss liegt. Hier sind ein paar auszüge aus meinem Code, wo man sieht wie ich das versucht habe:
So habe ich das Array erstmal Global deklariertCode:uint16_t IR_Wert[51]; //Array für Messwerte 0-50
Hier ist meine Interrupt routine in der unter anderem die GP2D12-Werte eingespeichert werden sollen. (posi ist meine Variable, die die position des Servos enthält also 0 bis 50)Code:ISR(ADC_vect) { if (changechannel<=0) { changechannel++; ADMUX |= (1<<MUX0); //Eingang ADC1 vorbereiten für den IR-Sensor LDR = ADC; } else { changechannel=0; ADMUX &= ~(1<<MUX0); //Eingang ADC0 vorbereiten für LDR-Messung IR_Wert[posi]=ADC; } }
hier soll der Roboter anweisung bekommen sich nach lins zu drehen, wenn links frei ist.Code:void Motorsteuerung(int Hinderniss_info) { OCR0=60; OCR2=60; if(Hinderniss_info<=20) { PORTC |= (1<<Motor_Links_Rueck); //Roboter soll nach Links drehen } else { PORTC &= ~(1<<Motor_Links_Rueck); //Roboter soll aufhören nach links //zu drehen }
hier soll die funktion GP2D12 die Position des kleinsten wertes zurückgebenCode:int GP2D12(void) { uint8_t i, memoposi=0; uint16_t memo=65535; //zum merken des kleinsten Wertes; //65535=maxwert bei 16-Bit for (i=0; i<=50; i++) { if (IR_Wert[i]<memo) { memoposi = i; //Zum merken der Servoposition, bei der der kleinste //wert liegt } } return (memoposi); }
Meine Main Function. Der GP2D12 wert soll der Funktion Motorsteuerung übergeben werden, wo dann ja geregelt wird wo der Roboter hinfährt.Code:int main(void) { Initial_ADC(); Initial_IR_Servo(); Initial_Motoren(); sei(); //Globales Interrupt gesetzt while(1) { ADCSRA |= (1<<ADSC); //ADC-Messung soll immer wenn möglich aktiv sein if (count) { count=0; IR_Servo = IR_Servoposition(); Motorsteuerung(GP2D12()); helligkeitsmessung(); } } return 0; //wird nie erreicht }
Hoffe ich hab nichts vergessen
Ach ja! Das Problem was ich habe ist, das die linke Kette dauerhaft rückwärts dreht. Ich hab keine Ahnung was schiefgelaufen sein kann. Is auch das erste mal wo ich mit Arrays arbeite.
Hoffe mir kann jemand helfen.
MfG Jan
Habe Mut, dich deines eigenen Verstandes zu bedienen.
Wenn man den Fehler anhand der Code-Schnipsel erkennen könnte, hättest du ihn selbst wahrscheinlich als erster gefunden, da du den Zusammenhang kennst.
@robocat:
Das stimmt natürlich. Hab das eben erstmal geändert.
Das mit dem schalten, fürs rückwärtsdrehen klappt jetzt.
Aber, wer hätte das gedacht, ich hab natürlich gleich noch ein Problem.
Die Motoren brummen nur und quälen sich voll rum, seitdem ich das Array programmiert hab. Hab das setzen vom ADSC-Bit auch vorher nicht in der Main-Funktion gehabt. Selbst wenn ich OCR0 und OCR2 den wert 150 gebe ändert sich nichts.
Ohne das Array laufen die Motoren ganz normal.
Hier is mein ganzer Code:
Hoffe da findet jemand was. Ich finde die sache mit dem Array eigentlich echt gut und will das am liebsten beibehalten.Code:#include <avr/io.h> #include <stdint.h> #include <avr/interrupt.h> #ifndef F_CPU #define F_CPU 16000000 #endif #define Scheinwerfer PD0 #define Rueckleuchten PD1 #define PWM_ServoPort PD5 #define IR_Servo OCR1A #define Motor_Links PB3 #define Motor_Rechts PD7 #define Motor_Links_Rueck PC0 #define Motor_Rechts_Rueck PC1 /*************************************Prototypes****************************************/ void helligkeitsmessung(void); int IR_Servoposition(void); void Motorsteuerung(int); int GP2D12(void); /***************************************************************************************/ /**********************************Globale Variablen************************************/ uint8_t count=0, reward_time=0; int8_t posi=25, a=1, changechannel=0; uint16_t LDR; uint16_t IR_Wert[51]; //Array für Messwerte 0-50 /***************************************************************************************/ /**********************************Interruptroutinen************************************/ //--------------------------------------Timer1COMB-------------------------------------- ISR(TIMER1_COMPB_vect) { count++; } //-----------------------------------------ADC------------------------------------------ ISR(ADC_vect) { if (changechannel<=0) { changechannel++; ADMUX |= (1<<MUX0); //Eingang ADC1 vorbereiten für den IR-Sensor LDR = ADC; } else { changechannel=0; ADMUX &= ~(1<<MUX0); //Eingang ADC0 vorbereiten für LDR-Messung IR_Wert[posi]=ADC; } } /****************************************************************************************/ /***************************************Routinen*****************************************/ //---------------------------------Helligkeitsmessung--------------------------------- void helligkeitsmessung(void) { if (LDR<=150) { PORTD |= (1<<Scheinwerfer); PORTD |= (1<<Rueckleuchten); } if (LDR>=190) { PORTD &= ~(1<<Scheinwerfer); PORTD &= ~(1<<Rueckleuchten); } } //-------------------------------------IR_Servosteuerung--------------------------------------- int IR_Servoposition(void) { if (a>=1) { posi++; if (posi>=50) { a=0; } } if (a<=0) { posi--; if (posi<=0) { a=1; } } return ((posi)+440); //440=min, 490=max } //--------------------------------------Motorsteuerung----------------------------------------- void Motorsteuerung(int Hinderniss_info) { OCR0=100; //Maximal 255 OCR2=100; //Maximal 255 if(Hinderniss_info<=15) { PORTC |= (1<<Motor_Rechts_Rueck); //Roboter soll sich nach Rechts drehen } else { PORTC &= ~(1<<Motor_Rechts_Rueck); //Roboter soll aufhören nach Rechts zu drehen } if(Hinderniss_info>=35) { PORTC |= (1<<Motor_Links_Rueck); //Roboter soll sich nach Links drehen } else { PORTC &= ~(1<<Motor_Links_Rueck); //Roboter soll aufhören nach Lins zu drehen } } //------------------------------------------GP2D12--------------------------------------------- int GP2D12(void) { uint8_t i, memoposi=0; uint16_t memo=0xffff; //zum merken des kleinsten Wertes; 0xffff=maxwert bei 16-Bit for (i=0; i<=50; i++) { if (IR_Wert[i]<memo) { memo = IR_Wert[i]; memoposi = i; //Zum merken der Servoposition, bei der der kleinste wert liegt } } return (memoposi); } /**********************************************************************************************/ /**************************************initialisierungen***************************************/ void Initial_ADC(void) { ADMUX |= 0x00; //AREF, resultat rechtsbündig, ADC-Eingang ADC0 ADCSRA |= ((1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)); //ADC eingeschaltet, Teilungsfaktor.. ADCSRA |= (1<<ADIE); DDRD |= ((1<<Scheinwerfer) | (1<<Rueckleuchten)); } void Initial_IR_Servo(void) { TCCR1A |= ((1<<WGM11)|(1<<COM1A1)|(1<<COM1A0)); //9-Bit PWM, Inverted Mode OC1A TCCR1A |= ((1<<COM1B1)|(1<<COM1B0)); //Inverted Mode OC1B TCCR1B |= (1<<CS12); //Prescaler 256 TIMSK |= (1<<OCIE1B); DDRD |= (1<<PWM_ServoPort); PORTD |= (1<<PWM_ServoPort); OCR1B=500; //beliebige zeit (irgendwas unter ner ms) } void Initial_Motoren(void) { //Ausgang Initialisieren (OC0) DDRB |= (1<<Motor_Links); //Setzen als Ausgang PORTB |= (1<<Motor_Links); //Pull-Up //Ausgang Initialisieren (OC2) DDRD |= (1<<Motor_Rechts); //Setzen als Ausgang PORTD |= (1<<Motor_Rechts); //Pull-Up //Initialisierung der Ausgänge für Rückwärtsfahren DDRC |= ((1<<Motor_Links_Rueck)|(1<<Motor_Rechts_Rueck)); //Initialisierung PWM für OC0 TCCR0 |= ((1<<WGM01)|(1<<WGM00)); //Fast PWM TCCR0 |= (1<<COM01); //Clear Output on Compare, Set on Top TCCR0 |= ((1<<CS02)|(1<<CS00)); //CLK/1024 (15,625kHz, 64µs/periode) //Compare Register ist OCR0 //Initialisierung PWM für OC2 TCCR2 |= ((1<<WGM21)|(1<<WGM20)); //Fast PWM TCCR2 |= (1<<COM21); //Clear Output on Compare, Set on Top TCCR2 |= ((1<<CS22)|(1<<CS21)|(1<<CS20)); //CLK/1024 (15,625kHz, 64µs/periode) //Compare Register ist OCR2 } /**************************************************************************************/ /**************************************Hauptprogramm***********************************/ int main(void) { Initial_ADC(); Initial_IR_Servo(); Initial_Motoren(); sei(); //Globales Interrupt gesetzt while(1) { ADCSRA |= (1<<ADSC); //ADC-Messung immer wieder gestartet werden, wenn möglich if (count) { count=0; IR_Servo = IR_Servoposition(); Motorsteuerung(GP2D12()); helligkeitsmessung(); } } return 0; //wird nie erreicht } /****************************************************************************************/
Kann auch sein das ich mit den Zeiten wieder irgendwas falsch gemacht habe. Ich finde aber leider nichts.
MfG Jan
Habe Mut, dich deines eigenen Verstandes zu bedienen.
Hallo,
schau dir mal diesen Thread an. könnte dir helfen.
Gruß
Jens
Moin!
Sorry das ich mich jetzt erst melde. Hab meine komplette Steuerplatine neu gebaut. Jetzt läuft alles wieder. Hab heut noch ein bisschen gerätselt, weil ich meine Quarz zwar angelötet, aber nicht mit dem uC verbunden hatte. Plötzlich ging gar nichts...Naja, bin ja froh das ich das selber gefunden hab. sonst hätt ich mich hier erstmal richtig zum Affen gemacht
Ich hab den Tip von Jens jetzt mal mit "eingebaut" und vor alle Variablen die in Interrupts verändert werden "volatile" gesetzt. Leider macht der trotzdem nichts. Der reagirt überhaupt nicht auf Hindernisse. Ohne Array macht der das. Echt komisch. Naja, vielleicht hat noch jemand einen Tipp.
Falls ich selbst was finde melde ich mich auch.
MfG Jan
Habe Mut, dich deines eigenen Verstandes zu bedienen.
bin noch etwas schläfrig...
dass du hier in der 2ten zeile der funktion TCCR1B meinst, kann es nicht sein, oder?
ansonsten finde ich grad nix -.-Code:void Initial_IR_Servo(void) { TCCR1A |= ((1<<WGM11)|(1<<COM1A1)|(1<<COM1A0)); //9-Bit PWM, Inverted Mode OC1A TCCR1A |= ((1<<COM1B1)|(1<<COM1B0)); //Inverted Mode OC1B <-- HIER TCCR1B |= (1<<CS12); //Prescaler 256
gruesse
Ich komm einfach nicht weiter.
Mein Prog sieht jetzt so aus:
Warum geht das bloß nicht???Code:#include <avr/io.h> #include <stdint.h> #include <avr/interrupt.h> #ifndef F_CPU #define F_CPU 16000000 #endif #define Scheinwerfer PD0 #define Rueckleuchten PD1 //#define Impulsgeber PD4 #define PWM_ServoPort PD5 #define IR_Servo OCR1A #define Motor_Links PB3 #define Motor_Rechts PD7 #define Motor_Links_Rueck PC0 #define Motor_Rechts_Rueck PC1 //---------------------------------Globale Variablen---------------------------------- uint8_t count=0; int8_t posi=25, a=1, ADC_Switch=1; uint16_t LDR, memo=2000; uint16_t IR_Messung[51]; //---------------------------------Interruptroutinen---------------------------------- ISR(TIMER1_COMPB_vect) { count++; } ISR(ADC_vect) { if (ADC_Switch) { ADC_Switch=0; LDR = ADC; ADMUX = 0x01; //Auf ADC1 umschalten ADCSRA |= (1<<ADSC); //Nach aufzeichnen Ergebniss in LDR, neue Messung starten } else { ADC_Switch=1; IR_Messung[posi] = ADC; ADMUX = 0x00; //Auf ADC0 umschalten ADCSRA |= (1<<ADSC); //Nach aufzeichnen Ergebniss in IR_Messung, neue Messung starten } } //---------------------------------Helligkeitsmessung--------------------------------- void helligkeitsmessung(void) { if (LDR<=140) { PORTD |= (1<<Scheinwerfer); PORTD |= (1<<Rueckleuchten); } if (LDR>=190) { PORTD &= ~(1<<Scheinwerfer); PORTD &= ~(1<<Rueckleuchten); } } //-------------------------------------IR_Servosteuerung--------------------------------------- int IR_Servoposition(void) { if (a>=1) { posi++; if (posi>=50) { a=0; } } else { posi--; if (posi<=0) { a=1; } } return ((posi)+440); //440=min, 490=max } //--------------------------------------Motorsteuerung----------------------------------------- void Motorsteuerung(void) { uint8_t i, farest=0; OCR0=100; //255=Max (Links) OCR2=100; //255=Max (Rechts) //if (IR_Messung > 150) if (posi<=0) { for (i=0; i<=51; i++) { if (IR_Messung[i] < memo) { memo=IR_Messung[i]; farest=i; } } } if (farest<=15) { PORTC |= (1<<Motor_Rechts_Rueck); } else if (farest>=35) { PORTC |= (1<<Motor_Links_Rueck); } else { PORTC &= ~((1<<Motor_Links_Rueck)|(1<<Motor_Rechts_Rueck)); } } //-------------------------------------initialisierungen--------------------------------------- void Initial_ADC(void) { ADMUX |= 0x00; //AREF, resultat rechtsbündig, ADC-Eingang ADC0 ADCSRA |= ((1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)); //ADC eingeschaltet, Teilungsfaktor.. ADCSRA |= (1<<ADIE); DDRD |= ((1<<Scheinwerfer) | (1<<Rueckleuchten)); } void Initial_IR_Servo(void) { TCCR1A |= ((1<<WGM11)|(1<<COM1A1)|(1<<COM1A0)); //9-Bit PWM, Inverted Mode OC1A //TCCR1A |= ((1<<COM1B1)|(1<<COM1B0)); //Inverted Mode OC1B TCCR1B |= (1<<CS12); //Prescaler 256 TIMSK |= (1<<OCIE1B); DDRD |= (1<<PWM_ServoPort); PORTD |= (1<<PWM_ServoPort); //DDRD |= (1<<Impulsgeber); //PORTD |= (1<<Impulsgeber); //OCR1B=500; //beliebige zeit (irgendwas unter ner ms) } void Initial_Motoren(void) { //Ausgang Initialisieren (OC0) DDRB |= (1<<Motor_Links); //Setzen als Ausgang PORTB |= (1<<Motor_Links); //Pull-Up //Ausgang Initialisieren (OC2) DDRD |= (1<<Motor_Rechts); //Setzen als Ausgang PORTD |= (1<<Motor_Rechts); //Pull-Up //Initialisierung der Ausgänge für Rückwärtsfahren DDRC |= ((1<<Motor_Links_Rueck)|(1<<Motor_Rechts_Rueck)); //Initialisierung PWM für OC0 TCCR0 |= ((1<<WGM01)|(1<<WGM00)); //Fast PWM TCCR0 |= (1<<COM01); //Clear Output on Compare, Set on Top TCCR0 |= ((1<<CS02)|(1<<CS00)); //CLK/1024 (15,625kHz, 64µs/periode) //Compare Register ist OCR0 //Initialisierung PWM für OC2 TCCR2 |= ((1<<WGM21)|(1<<WGM20)); //Fast PWM TCCR2 |= (1<<COM21); //Clear Output on Compare, Set on Top TCCR2 |= ((1<<CS22)|(1<<CS21)|(1<<CS20)); //CLK/1024 (15,625kHz, 64µs/periode) //Compare Register ist OCR2 } //---------------------------------------Hauptprogramm--------------------------------- int main(void) { Initial_ADC(); Initial_IR_Servo(); Initial_Motoren(); ADCSRA |= (1<<ADSC); //Erste Messung starten sei(); //Globales Interrupt gesetzt while(1) { if (count) { count=0; helligkeitsmessung(); IR_Servo = IR_Servoposition(); Motorsteuerung(); } } return 0; //wird nie erreicht }
Eine Kette dreht vorwärts und die andere rückwärts.
Es ändert sich auch nichts und der Sensor reagiert auch auf nichts.
Hoffe das kuckt sich noch jemand an.
@robocat:
Das war schon richtig so. Hab im datenblatt noch mal nachgesehen.
Aber jetzt benutz ich das ja gar nicht mehr.
MfG Jan
Habe Mut, dich deines eigenen Verstandes zu bedienen.
Wenn du in der Motorsteuerung farest=20; eingibst dann lauffen beide Motore in die selbe Richtung.
Du bist mit der Doku etwas sparsam, so ist es etwas mühsam nachzuvollziehen was du dir gedacht hast.
Hallo,
probier den Fehler durch vorgabe von Daten einzukreisen. Wie Hubert schon schrieb farest fest vorgeben. Wenn das Ergebnis wie erwartet ist, geht es weiter mit dem Array. Füll es in der Motorsteuerung über eine Schleife mit Werten. Einen Wert überschreibst du mit einem Kleinsten Wert. Was passiert? Alles ok? Dann geht es weiter, das Array im ADC interrupt füllen wie in der Motorsteuerung. usw, usw. Irgendwann wird was unerwartetets passieren. Das gilt es dann zu ergründen.
Gruß
Jens
Lesezeichen