- 12V Akku mit 280 Ah bauen         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 12

Thema: Asuro Steuerung für Dieselmotor

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    08.09.2009
    Beiträge
    12

    Asuro Steuerung für Dieselmotor

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Moin Moin!
    Ich habe vor kurzem mal meinen Asuro wieder ausgegraben, weil ich gezwungen war mich wieder mit C zu beschäftigen. (Studium)<br>Ich habe vor mit Hilfe des Asuro und einem RC-Servo eine Drehzahlsteuerung für einen kleinen Dieselmotor zu bauen.<br>Ich hab heute den Tag über daran gearbeitet den Servo anzusteuern, funktioniert mittlerweile auch, aber ich scheitere daran den Servo über die IR Schnittstelle zu steuern
    Code:
    #include "asuro.h"
    
    int main(void)
    {
       Init();
    	unsigned char l[3];
    	while(1) {
    	SerRead(l,3,0);
         while(l > 0)
    		{
    		
    		BackLED(ON,OFF);
    		Sleep(l);
    		BackLED(OFF,OFF);
    		Sleep(144);Sleep(144);Sleep(144);Sleep(144);Sleep(144);Sleep(144);Sleep(144);Sleep(144);Sleep(144);Sleep(144);
    		}
    	}
       return 0;
    }
    Das ist das Programm.
    Ziel ist es über das Terminal eine 3 stellige Nummer einzugeben, welche die Stellung des Servos verändert. Bisher sind das noch die direkten unsigned char Werte für Sleep() (ca 60-200 Linker und Rechter Anschlag vom Servo), später bastel ich das so um, das man einen Winkel angibt.
    Was ist an meinem Progrämmchen verkehrt?
    gruss Erik

  2. #2
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Wenn du mit SerRead() Zeichen über die serielle Schnittstelle liest, dann sind das ascii-Zeichen. Die Codes für die Ziffern liegen dabei zwischen 0x30 für '0' und 0x39 für '9'. Man muss also 0x30 oder '0' vom ascii-Code abziehen um den Wert der Stelle zu erhalten. Um von drei gesendeten Zeichen auf eine dreistellige Zahl zu kommen verwendet man deshalb Formeln wie diese:

    (Zeichen1 - '0') * 100 + (Zeichen2 - '0') * 10 + (Zeichen3 - '0')

    PHP-Code:
            BackLED(ON,OFF);
            
    Sleep((l[0] - '0') * 100 + (l[1] - '0') * 10 + (l[2] - '0'));
            
    BackLED(OFF,OFF);
            
    Sleep(72);Sleep(144);Sleep(144);Sleep(144);Sleep(144);Sleep(144);Sleep(144);Sleep(144);Sleep(144);Sleep(144);  // 19ms Pause 
    l ist ein ungünstig gewählter Name für Variablen.

    Gruß

    mic
    Geändert von radbruch (19.08.2011 um 09:04 Uhr)
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    08.09.2009
    Beiträge
    12
    Danke für die schnelle Antwort! Hat super funktioniert!
    Ich hab den Tag weiter experimentiert und erst einmal versucht ein Bugrad mit dem Servo zu steuern:

    http://www.youtube.com/watch?v=uFt6hllIRMU
    klappt
    einigermaßen, aber ich habe Stromprobleme... wenn der Servo sich zu schnell bewegt bricht die Spannung zusammen und Asuro startet neu.
    Naja zum spielen hats gereicht.
    Nächster Schritt ist ein Drehzahlsensor für den Diesel zu baun.
    Fals Interesse besteht halte ich euch gerne auf dem laufenden.

  4. #4
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Irgendwie erinnert mich das an meine eigenen Schandtaten:
    http://www.youtube.com/watch?v=F45RU9yRXtI

    Bei dir sieht das aber deutlich besser aus.

    Interesse besteht immer ;)
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    08.09.2009
    Beiträge
    12
    Hier noch einmal den Code zum Linienfolgenprogramm:
    Code:
    #include "asuro.h"
    
    int main(void)
    {
       Init();
    	unsigned char l;
    	int data[2];
    	FrontLED(ON);
    	l=108;
    	Sleep(255);
    	Sleep(255);
    	MotorDir(FWD,FWD);
    	MotorSpeed(130,130);
    	int servo(unsigned char l) {
    								
    								BackLED(ON,OFF);
    								Sleep(l);
    								BackLED(OFF,OFF);
    								Sleep(144);Sleep(72);Sleep(144);Sleep(144);Sleep(144);Sleep(144);Sleep(144);Sleep(144);Sleep(144);
                                    return 0;}
    	while(1) {
    			LineData(data);
    			if(data [0] < data[1])
    				{l=l+4;
    				MotorSpeed(100,140);}
    			else if(data[0] == data[1])
    				{l=l;}
    			
    			else
    				{l=l-4;
    				MotorSpeed(140,100);}
    				servo(l);
    				
    				
    			if(l > 120)
    				{l=120;}
    			else if(l < 80)
    				{l=80;}
    			else
    				{l=l;}
    	}
       return 0;
    }
    Nun möchte ich meine Servofunktion so gestalten, das sie den PWM wie bei der MotorSpeed) Funktion funktioniert. Mit anderen Worten: Ich möchte der servo()Funktion einen Wert übergeben, der so lange ausgeführt wird, bis er geändert wird, damit der Servo einen Hebel gegen einen Federdruck halten kann.
    Bisher ist das ja so, das der Servo zwar in der richtigen Stellung bleibt, wenn servo() nicht mehr while schleife andauernd ausgeführt wird, aber inaktiv ist und damit verdrahbar.
    Lässt sich das mit dem Atmel umsetzen oder braucht man dafür multitaskting?

  6. #6
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Multitasking können die AVRs natürlich nicht. Für Aufgaben, die quasi im Hintergrund ablaufen sollen, verwendet man deshalb die Timerfunktionen der AVRs. Hier wird die "klassische" Servoansteuerung beschrieben:
    http://www.rn-wissen.de/index.php/Servo

    PHP-Code:
    #define SERVOPIN 7
    #define SERVOPORT PORTD
    #define DDRSERVO DDRD

    volatile unsigned char servopos;

    void servo_init()
    {
        
    TIMSK|=(1<<OCIE2);
        
    TCCR2 |= (1<<WGM21) | (1<<CS20);    //Prescale=1, CTC mode
        
    OCR2 F_CPU/100000;            //alle 10µS ein IRQ
        
    DDRSERVO|=(1<<SERVOPIN);
    };

    ISR(TIMER2_COMP_vect)
    {
        static 
    int count;
        if(
    count>servopos)SERVOPORT&=~(1<<SERVOPIN);
          else 
    SERVOPORT|=(1<<SERVOPIN);
        if(
    count<2000)count++;
          else 
    count=0;
    }; 
    Wie funktioniert das? Der Timer wird so programmiert, dass er alle 10µs die Interruptserviceroutine (ISR) aufruft. Die Aufrufe werden in der ISR mitgezählt (count), der Zählerstand wird zwischen den Aufrufen gespeichert (static). Zusätzlich wird in der ISR der Zählerwert mit dem Wert für die Servoposition (servopos) verglichen und dem Ergebniss entsprechend der Servoausgang gesetzt oder gelöscht. Bei 10µs oder 0,01ms pro Aufruf ist nach 100 Aufrufen eine Millisekunde vergangen, nach 2000 sind es 20ms.

    Alles klar soweit? Wie verwendet man das nun beim asuro? Man könnte Timer0 verwenden, denn der wird von der Library des asuro nicht verwendet. Oder man klinkt sich in den Timer1 ein der ja schon für die PWM-Ansteuerung der Antriebe genutzt wird:

    PHP-Code:
    #include "asuro.h"

    volatile unsigned char servopos=40// 40 ist ca. 1 ms

    SIGNAL (SIG_OVERFLOW1)
    {
        static 
    int count 1;
        if(
    count servoposBackLED(OFF,OFF); else BackLED(ON,OFF);
        if(
    count 780count++; else count=1;
    }

    int main(void)
    {
       
    Init();
        
    TIMSK |= (<< TOIE1); // Timer1 Overflow-ISR einklinken für Servo

        
    unsigned char l;
        
    int data[2];
        
    FrontLED(ON);
        
    l=108;
        
    Sleep(255);
        
    Sleep(255);
        
    MotorDir(FWD,FWD);
        
    MotorSpeed(130,130);

        while(
    1) {
                
    LineData(data);
                if(
    data [0] < data[1])
                    {
    l=l+4;
                    
    MotorSpeed(100,140);}
                else if(
    data[0] == data[1])
                    {
    l=l;}

                else
                    {
    l=l-4;
                    
    MotorSpeed(140,100);}
                    
    //servo(l);
                    
    servopos l// Servoposition setzen

                
    if(120)
                    {
    l=120;}
                else if(
    80)
                    {
    l=80;}
                else
                    {
    l=l;}
        }
       return 
    0;

    ungetestet

    Gruß

    mic
    Geändert von radbruch (21.08.2011 um 12:00 Uhr) Grund: servopos > count war falsch
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    08.09.2009
    Beiträge
    12
    Das Programm funktioniert so leider nicht und mein Verständnis für die Elektronik und C reicht nicht aus um da nach nem Fehler zu suchen.
    Der Servo zuckt hin und wieder, ich erkenne aber keine regelmäßigkeit.

  8. #8
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Oje, das war auch Schwachsinn. Der Timer1 "läuft" beim asuro mit 3,9kHz. Das ist viel zu wenig für eine brauchbare Servoansteuerung.

    Besser sieht es mit Timer2 aus. Der läuft mit 36kHz, (wie immer der Hinweis: Bei der orginalen CD-Library sind es 72kHz) und läßt sich ähnlich einfach missbrauchen:

    PHP-Code:
    #include "asuro.h"

    volatile unsigned char servopos=0p=0// p dauert ca. 20ms oder 1/50 Sekunde

    SIGNAL (SIG_OUTPUT_COMPARE2)
    {
        static 
    int count 1;
        if(
    count servoposBackLED(OFF,OFF); else BackLED(ON,OFF);
        
    //if(count > servopos) PORTC &= ~(1<<PC4); else PORTC |= (1<<PC4);
        
    if(count < (20*72)) count++; else {count=1; if(pp--;} // 20ms bei 72kHz-Lib!
    }

    int main (void)
    {

       
    Init();
       
    //DDRC |= (1<<PC4); // Tasteneingang auf Ausgabe setzen
        
    TIMSK |= (<< OCIE2); // Timer2 CompareMatch-ISR einklinken für Servo
       
    OCR2  0x91// duty cycle for 36kHz vorsichthalber OCR2 belegen

       
    while(1)
       {
          
    StatusLED(RED);
          
    servopos=70;
          
    p=50// eine Sekunde warten
          
    while(p);

          
    StatusLED(GREEN);
          
    servopos=190;
          
    p=50;
          while(
    p);
       }
       return 
    0;

    getestet ;)

    Dabei sollten die Werte wie bei der Sleep()-Ansteuerung sein. servopos=0 sendet keinen Impuls zum Servo.

    Gruß

    mic

    [Edit]
    Sehr knuffig:
    PHP-Code:
    #include "asuro.h"

    volatile unsigned char servopos=0p=0// p dauert ca. 20ms oder 1/50 Sekunde

    SIGNAL (SIG_OUTPUT_COMPARE2)
    {
        static 
    int count 1;
        if(
    count servoposBackLED(OFF,OFF); else BackLED(ON,OFF);
        
    //if(count > servopos) PORTC &= ~(1<<PC4); else PORTC |= (1<<PC4);
        
    if(count < (20*36)) count++; else {count=1; if(pp--;} // 20ms bei 36kHz-Lib!
    }

    int main (void)
    {
        
    unsigned char l[3];

        
    Init();
        
    //DDRC |= (1<<PC4); // Tasteneingang auf Ausgabe setzen
        
    TIMSK |= (<< OCIE2); // Timer2 CompareMatch-ISR einklinken für Servo
        
    OCR2  0x91// duty cycle for 36kHz vorsichthalber OCR2 belegen
       
        
    while(1)
        {
            
    SerRead(l,3,0); // drei Ziffern einlesen (blockierend!)
            
    servopos = (l[0] - '0') * 100 + (l[1] - '0') * 10 + (l[2] - '0');
        }
       return 
    0;

    Geändert von radbruch (21.08.2011 um 14:39 Uhr)
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    08.09.2009
    Beiträge
    12
    wenn ich die programme compilen will kommt folgender fehler:
    asuro.o: In function `__vector_3':
    C:\Users\Erik\Desktop\asuro_src\ASURO_src\FirstTry/asuro.c:35: multiple definition of `__vector_3'
    test.o:C:\Users\Erik\Desktop\asuro_src\ASURO_src\F irstTry/test.c:6: first defined here
    make.exe: *** [test.elf] Error 1

  10. #10
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    grrr

    Welche Library verwendest du?

    Mach mal ein Update auf 2.3 oder höher:

    http://sourceforge.net/projects/asur...%20lib%20V2.3/
    (asuro.c und asuro.h austauschen)

    Die aktuelle Lib:
    http://sourceforge.net/projects/asur...1.zip/download
    Geändert von radbruch (21.08.2011 um 16:56 Uhr)
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Einstieg in die Robotik - Asuro + NSLU + Direkte Steuerung
    Von bjoern.hoefer im Forum Suche bestimmtes Bauteil bzw. Empfehlung
    Antworten: 3
    Letzter Beitrag: 17.01.2011, 14:25
  2. Asuro Steuerung
    Von greenko im Forum C - Programmierung (GCC u.a.)
    Antworten: 8
    Letzter Beitrag: 12.06.2008, 13:00
  3. ASURO-Steuerung mit SCILAB
    Von stochri im Forum Asuro
    Antworten: 0
    Letzter Beitrag: 05.01.2006, 21:06
  4. Steuerung des Bots über Graupner RC-Steuerung
    Von Toastbrot im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 4
    Letzter Beitrag: 23.12.2004, 14:18
  5. [ERLEDIGT] Drehzahlmessung am Dieselmotor mittels Piezo
    Von im Forum Elektronik
    Antworten: 2
    Letzter Beitrag: 26.10.2004, 09:37

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests