- LiFePO4 Speicher Test         
Ergebnis 1 bis 10 von 12

Thema: Asuro Steuerung für Dieselmotor

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    08.09.2009
    Beiträge
    12

    Asuro Steuerung für Dieselmotor

    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!

Ä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. 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
  •  

LiFePO4 Speicher Test