- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 5 von 6 ErsteErste ... 3456 LetzteLetzte
Ergebnis 41 bis 50 von 60

Thema: Mehrere Servo-Signale einlesen, ggf. manipulieren, ausgeben

  1. #41
    Neuer Benutzer Öfters hier
    Registriert seit
    25.10.2010
    Beiträge
    26
    Anzeige

    Praxistest und DIY Projekte
    Zitat Zitat von wkrug Beitrag anzeigen
    Bevor Du da die Flinte ins Korn wirfst ...
    Niemals! Dann wirds ja nie fertig. Außerdem kann man ne Flinte immer mal gebrauchen...
    Ich hoff übers Wochenende, oder dann über die Feiertage findet sich ein bisschen Zeit da noch etwas rumzuprobieren.
    Evtl. bekomm ich das Programm ja im AVR Studio Sim zum laufen, muss ich mal schaun.

    Gruß Basti

  2. #42
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.191
    Ok, Ich bin dann mal so frech und hau nen Code raus.
    Im Simulator hab ich das mal getestet - Da scheints zu funktionieren.
    Mit nem Controller kann ich leider nicht testen ( Kein ATMEGA 88 hier ).
    Ich hab das Prinzip mit dem Pinchange umgesetzt.
    Die Simulation war mit 8MHz, dabei kann ein Versatz ( Jitter ) von 30µS bei den Signalen entstehen.

    Code:
    /*****************************************************
    
    Project : Einzelimpulse zu Summensignal
    Version : 0.1
    Date    : 19.12.2014
    Author  :                  
    Company :          
    Comments: 
    
    
    Chip type           : ATmega88
    Program type        : Application
    Clock frequency     : 8,000000 MHz
    Memory model        : Small
    External SRAM size  : 0
    Data Stack size     : 256
    
    Zeitversatz beim Einlesen der Impulse 30µs!
    *****************************************************/
    
    /********
    PC0 = Kanal 1
    PC1 = Kanal 3
    PC2 = Kanal 5
    PC3 = Kanal 7
    PD0 = Kanal 2
    PD1 = Kanal 4
    PD2 = Kanal 6
    PD3 = Kanal 8
    PB1 = Summensignalausgang
    ********/
    
    #include <mega88.h>
    
    volatile unsigned int ui_timerold[8];    //Speicherwerte für die Steigende Flanke der entsprecheden Kanäle
    volatile unsigned int ui_pulslengh[8]={1500,1500,1500,1500,1500,1500,1500,1500};   //Ermittelte Pulslängen
    volatile unsigned char uc_oldgerade=0;     //Zwischenspeicher für den alten Zustand der geraden Kanäle 2,4,6,8
    volatile unsigned char uc_oldungerade=0; //Zwischenspeicher für den alten Zustand der geraden Kanäle 1,3,5,7
    volatile unsigned char uc_cyclecount;     //Zyklenzähler für die Impulsausgabe
    #define maxcycle 15
    #define interpulspause 50                 //50 = 50µs
    #define interframepause 4000              //4000 = 4ms Interframepause
    
    //#define normal                          //Bestimmt ob die Impulsausgabe normal oder invers geschehen soll
    //#define revers
    #define portsungerade PINC
    #define portsgerade PIND
    #define outport PORTB.1
    // Pin change 8-14 interrupt service routine
    interrupt [PCINT1] void pin_change_isr1(void)
    {
    unsigned char uc_portungerade,uc_result;
    unsigned int ui_timer;
    ui_timer=TCNT1H;
    ui_timer=(ui_timer<<8)+TCNT1L;
    uc_portungerade=portsungerade&0x0F;
    uc_result=uc_portungerade^uc_oldungerade;
    if(uc_result&0x01)
        {
        if(uc_portungerade&0x01)        //Es war ne steigende Flanke
            {
            ui_timerold[0]=ui_timer;
            }
        else                            //Es war ne fallende Flanke
            {
            ui_pulslengh[0]=ui_timer-ui_timerold[0];
            };
        }
    
    if(uc_result&0x02)
        {
        if(uc_portungerade&0x02)        //Es war ne steigende Flanke
            {
            ui_timerold[2]=ui_timer;
            }
        else                            //Es war ne fallende Flanke
            {
            ui_pulslengh[2]=ui_timer-ui_timerold[2];
            };
        }
        
    if(uc_result&0x04)
        {
        if(uc_portungerade&0x04)        //Es war ne steigende Flanke
            {
            ui_timerold[4]=ui_timer;
            }
        else                            //Es war ne fallende Flanke
            {
            ui_pulslengh[4]=ui_timer-ui_timerold[4];
            };
        }
        
    if(uc_result&0x08)
        {
        if(uc_portungerade&0x08)        //Es war ne steigende Flanke
            {
            ui_timerold[6]=ui_timer;
            }
        else                            //Es war ne fallende Flanke
            {
            ui_pulslengh[6]=ui_timer-ui_timerold[6];
            };
        }
    uc_oldungerade=uc_portungerade;
    }
    
    // Pin change 16-23 interrupt service routine
    interrupt [PCINT2] void pin_change_isr2(void)
    {
    unsigned char uc_portgerade,uc_result;
    unsigned int ui_timer;
    ui_timer=TCNT1H;
    ui_timer=(ui_timer<<8)+TCNT1L;
    uc_portgerade=portsgerade&0x0F;
    uc_result=uc_portgerade^uc_oldgerade;
    if(uc_result&0x01)
        {
        if(uc_portgerade&0x01)        //Es war ne steigende Flanke
            {
            ui_timerold[1]=ui_timer;
            }
        else                            //Es war ne fallende Flanke
            {
            ui_pulslengh[1]=ui_timer-ui_timerold[1];
            };
        }
    
    if(uc_result&0x02)
        {
        if(uc_portgerade&0x02)        //Es war ne steigende Flanke
            {
            ui_timerold[3]=ui_timer;
            }
        else                            //Es war ne fallende Flanke
            {
            ui_pulslengh[3]=ui_timer-ui_timerold[3];
            };
        }
        
    if(uc_result&0x04)
        {
        if(uc_portgerade&0x04)        //Es war ne steigende Flanke
            {
            ui_timerold[5]=ui_timer;
            }
        else                            //Es war ne fallende Flanke
            {
            ui_pulslengh[5]=ui_timer-ui_timerold[5];
            };
        }
        
    if(uc_result&0x08)
        {
        if(uc_portgerade&0x08)        //Es war ne steigende Flanke
            {
            ui_timerold[7]=ui_timer;
            }
        else                            //Es war ne fallende Flanke
            {
            ui_pulslengh[7]=ui_timer-ui_timerold[7];
            };
        }
    uc_oldgerade=uc_portgerade;
    }
    
    // Timer 1 output compare A interrupt service routine
    interrupt [TIM1_COMPA] void timer1_compa_isr(void)
    {
    unsigned char uc_low,uc_high;
    unsigned int ui_buffer;
    switch(uc_cyclecount)
        {
        case 0:
        outport=1;                     //Der erste Impuls
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=ui_pulslengh[0];    //Pulslänge dazuzählen
        uc_low=ui_buffer&0x00FF;       //OCR Register für nächsten Interrupt vorbelegen
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break;
        case 1:                       //Die Pausen
        case 3:
        case 5:
        case 7:
        case 9:
        case 11:
        case 13:
        outport=0;
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=interpulspause;
        uc_low=ui_buffer&0x00FF;
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break;
        case 2:
        outport=1;                     //Der zweite Impuls
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=ui_pulslengh[1];    //Pulslänge dazuzählen
        uc_low=ui_buffer&0x00FF;       //OCR Register für nächsten Interrupt vorbelegen
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break;
        
        case 4:
        outport=1;                     //Der dritte Impuls
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=ui_pulslengh[2];    //Pulslänge dazuzählen
        uc_low=ui_buffer&0x00FF;       //OCR Register für nächsten Interrupt vorbelegen
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break;
        
        case 6:
        outport=1;                     //Der vierte Impuls
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=ui_pulslengh[3];    //Pulslänge dazuzählen
        uc_low=ui_buffer&0x00FF;       //OCR Register für nächsten Interrupt vorbelegen
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break; 
        
        case 8:
        outport=1;                     //Der fünfte Impuls
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=ui_pulslengh[4];    //Pulslänge dazuzählen
        uc_low=ui_buffer&0x00FF;       //OCR Register für nächsten Interrupt vorbelegen
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break; 
        
        case 10:
        outport=1;                     //Der sechste Impuls
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=ui_pulslengh[5];    //Pulslänge dazuzählen
        uc_low=ui_buffer&0x00FF;       //OCR Register für nächsten Interrupt vorbelegen
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break; 
        
        case 12:
        outport=1;                     //Der siebte Impuls
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=ui_pulslengh[6];    //Pulslänge dazuzählen
        uc_low=ui_buffer&0x00FF;       //OCR Register für nächsten Interrupt vorbelegen
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break; 
        
        case 14:
        outport=1;                     //Der achte Impuls
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=ui_pulslengh[7];    //Pulslänge dazuzählen
        uc_low=ui_buffer&0x00FF;       //OCR Register für nächsten Interrupt vorbelegen
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break; 
        
        case 15:
        outport=0;
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=interframepause;
        uc_low=ui_buffer&0x00FF;
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break;
        
        default:
        uc_cyclecount=0;
        }
    uc_cyclecount++;
    if(uc_cyclecount>maxcycle){uc_cyclecount=0;}
    }
    
    // Declare your global variables here
    
    void main(void)
    {
    // Declare your local variables here
    
    // Crystal Oscillator division factor: 1
    #pragma optsize-
    CLKPR=0x80;
    CLKPR=0x00;
    #ifdef _OPTIMIZE_SIZE_
    #pragma optsize+
    #endif
    
    // Input/Output Ports initialization
    // Port B initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=Out Func0=In 
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=0 State0=T 
    PORTB=0x00;
    DDRB=0x02;
    
    // Port C initialization
    // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
    // State6=T State5=T State4=T State3=P State2=P State1=P State0=P 
    PORTC=0x0F;
    DDRC=0x00;
    
    // Port D initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
    // State7=T State6=T State5=T State4=T State3=P State2=P State1=P State0=P 
    PORTD=0x0F;
    DDRD=0x00;
    
    // Timer/Counter 0 initialization
    // Clock source: System Clock
    // Clock value: Timer 0 Stopped
    // Mode: Normal top=FFh
    // OC0A output: Disconnected
    // OC0B output: Disconnected
    TCCR0A=0x00;
    TCCR0B=0x00;
    TCNT0=0x00;
    OCR0A=0x00;
    OCR0B=0x00;
    
    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: 1000,000 kHz
    // Mode: Normal top=FFFFh
    // OC1A output: Discon.
    // OC1B output: Discon.
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    // Timer 1 Overflow Interrupt: Off
    // Input Capture Interrupt: Off
    // Compare A Match Interrupt: On
    // Compare B Match Interrupt: Off
    TCCR1A=0x00;
    TCCR1B=0x02;
    TCNT1H=0x00;
    TCNT1L=0x00;
    ICR1H=0x00;
    ICR1L=0x00;
    OCR1AH=0x00;
    OCR1AL=0x00;
    OCR1BH=0x00;
    OCR1BL=0x00;
    
    // Timer/Counter 2 initialization
    // Clock source: System Clock
    // Clock value: Timer 2 Stopped
    // Mode: Normal top=FFh
    // OC2A output: Disconnected
    // OC2B output: Disconnected
    ASSR=0x00;
    TCCR2A=0x00;
    TCCR2B=0x00;
    TCNT2=0x00;
    OCR2A=0x00;
    OCR2B=0x00;
    
    // External Interrupt(s) initialization
    // INT0: Off
    // INT1: Off
    // Interrupt on any change on pins PCINT0-7: Off
    // Interrupt on any change on pins PCINT8-14: On
    // Interrupt on any change on pins PCINT16-23: On
    EICRA=0x00;
    EIMSK=0x00;
    PCICR=0x06;
    PCMSK1=0x0F;
    PCMSK2=0x0F;
    PCIFR=0x06;
    
    // Timer/Counter 0 Interrupt(s) initialization
    TIMSK0=0x00;
    // Timer/Counter 1 Interrupt(s) initialization
    TIMSK1=0x02;
    // Timer/Counter 2 Interrupt(s) initialization
    TIMSK2=0x00;
    
    // Analog Comparator initialization
    // Analog Comparator: Off
    // Analog Comparator Input Capture by Timer/Counter 1: Off
    ACSR=0x80;
    ADCSRB=0x00;
    
    // Watchdog Timer initialization
    // Watchdog Timer Prescaler: OSC/128k
    // Watchdog Timer interrupt: Off
    /*#pragma optsize-
    #asm("wdr")
    WDTCSR=0x1E;
    WDTCSR=0x0E;
    #ifdef _OPTIMIZE_SIZE_
    #pragma optsize+
    #endif   */
    
    // Global enable interrupts
    #asm("sei")
    
    while (1)
          {
          #asm("wdr")
          
          // Place your code here
    
          };
    }
    Auch wenn mehrere Ports ihre Level zu gleichen Zeit ändern, sollte der Code funzen.
    Geändert von wkrug (19.12.2014 um 20:11 Uhr)

  3. #43
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Auch Bascom hat einen internen Simulator. So grundlegende Dinge wie der Timer und Interrupts sollten auch da funktionieren.

    Der Umstieg von Bascom auf C bringt vielleicht einen Faktor 2-3 bei der Geschwindigkeit . ist aber unterschiedlich je nach Aufgabe. Der Overhead bei der Interruptsroutine ist in Bascom recht groß - etwa 100 Zyklen extra gegenüber GCC bei einer eher kurzen ISR. In Bascom hat man den Vorteil das man leichter mit inline ASM kombinieren kann - das geht auch in C, aber nicht so einfach. Da Bascom einige Register normal nicht nutzt, kann man mit Bascom und ISR in ASM ggf. sogar schneller werden als mit GCC und ASM.

  4. #44
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.191
    ....inline ASM kombinieren kann
    Das hatte ich schon ein paar Post's weiter vorne auch vorgeschlagen.
    Ob man's dann mit Bascom oder nen C-Compiler macht dürfte relativ egal sein.
    Auch bei CodeVision AVR lässt sich inline Assembler problemlos einbinden.
    Wie das bei AVR GCC geht weiss ich leider nicht.
    Wenn man in der Interruptroutine nur Assembler verwendet kann man zusätzlich die automatische Registersicherung abschalten, da Bascom normalerweise bei jedem ISR-Aufruf ja alle 32 Register sichert und wieder zurückschreibt.
    Bei ASM müssen nur das SREG und die Register gesichert werden, die man selber benotigt.
    Zusätzlich ist es sinnvoll den Controller mit der maximal möglichen Taktrate zu takten weil damit der Jitter minimiert wird.
    Also einen Typen wählen der mit 20MHz läuft und auch 20MHz verwenden.

    Ein Bekannter von mir hat mit Bascom und inline Assembler einen Testbildgenerator für Fernseher gebaut und das ist noch wesentlich zeitkritischer als Servoimpulse einlesen.
    Geändert von wkrug (20.12.2014 um 09:15 Uhr)

  5. #45
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Inline ASM geht auch mit GCC. Es ist sogar recht mächtig und erlaubt dem Compiler den Code davor und dahinter entsprechend anzupassen / optimieren. Allerdings ist deshalb das Interface etwas umständlich, auch wenn man es für die ISR nicht braucht. Man kann in C auch so etwas wie die ISR als extra ASM Code teil einbinden und erst vom Linker dazu packen lassen.

    ASM in Bascom geht halt sehr einfach, weil die Registernutzung bei Bascom fest ist. Normal sind einige Register ungenutzt, die man dann in der ISR nicht mal retten muss.

  6. #46
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    52
    Beiträge
    765
    Gibt es da irgendwo eine zuverlässige Übersicht?
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  7. #47
    Neuer Benutzer Öfters hier
    Registriert seit
    25.10.2010
    Beiträge
    26
    Euch allen erst mal Frohe Weihnachten.

    Hab nun endtlich das AVR Studio 4.19 zum laufen gebracht das 6er Atmel Studio ist mir einfach viel zu überladen.
    Ich denke über die Feiertage habe ich dann auch etwas Zeit mich näher damit zu befassen.
    Die letzten Tage waren Arbeits-Technisch etwas stressiger....

    Gruß Basti

  8. #48
    Neuer Benutzer Öfters hier
    Registriert seit
    25.10.2010
    Beiträge
    26
    In C spuckt er mir leider die selben Mist Werte wie im Bascom Prog aus. Also scheint irgendwas an meinem Prinzip völlig daneben zu gehen.

    main.c
    Code:
    #include <avr/io.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    #include <util/delay.h>
    
    #include "uart.h"
    #include "input.h"
    
    /* define CPU frequency in Mhz here if not defined in Makefile */
    #ifndef F_CPU
    #define F_CPU 16000000UL
    #endif
    
    /* 9600 baud */
    #define UART_BAUD_RATE      9600      
    
    
    int main(void)
    {
    
    
        //Uart initialisieren
        uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 
    
    
        //Eingänge INT0 und INT1 initialisieren
        init_inputs();
    
    
        while(1)
        {
            char tmp[5];
            itoa(input_channel[3], tmp, 10); 
            uart_puts(tmp);
            uart_puts("\n");
            _delay_ms(50);
        }; //Endlosschleife
        
    }
    input.c
    Code:
    #include <avr/io.h>
    #include <stdint.h>
    #include <avr/interrupt.h>
    
    #include "input.h"
    
    // **************************
    //         Prototypen
    // **************************
    void init_inputs(void);//Initialisiert INT0 und INT1
    
    // **************************
    //         Deklarationen
    // **************************
    uint16_t (input_channel)[7]; //Array für die einzelnen Kanäle
    uint8_t (fail_flag); //Flag für Fail Safe Modus
    
    uint8_t (ch_cnt); //Counter für aktuellen Kanal
    
    
    void init_inputs(void)
    {
    
    
        //INT0 und INT1 als Eingang
        //DDRD = 0b11111001;
        DDRD &= ~((1 << DDD1) | (1 << DDD2));
    
        //INT0 und INT1 aktivieren
        GICR |= ((1 << INT0) | (1 << INT1));
    
        //Beide INT auf steigene Flanke konfigurieren
        MCUCR |= ((1 << ISC01) | (1 << ISC00)); //INT0
        MCUCR |= ((1 << ISC11) | (1 << ISC10)); //INT1
    
        //Timer1 Prescaler auf 1 stellen
        TCCR1B |= (1 << CS10);
    
        //Timer1 Overflow INT aktivieren
        TIMSK |= (1 << TOIE1);
    
        //Interrupts anschalten
        sei();
    };
    
    
    //ISR von INT0
    ISR(INT0_vect)
    {     
        //Wenn der CH != 0 dann speichere Zählerstand
        if(ch_cnt != 0){input_channel[ch_cnt] = TCNT1;}
    
        //Ch Zähler erhöhen
        ch_cnt++;
    
        //Zähler zurücksetzen
        TCNT1 = 0;
    
        //INT0 auf fallende Flanke
        if(ch_cnt == 6){MCUCR &= ~(1 << ISC00);}
    }
    
    
    //ISR von INT1
    ISR(INT1_vect)
    {
        //Wenn der CH != 0 dann speichere Zählerstand
        if(ch_cnt != 0){input_channel[ch_cnt] = TCNT1;}
    
        //Ch Zähler erhöhen
        ch_cnt++;
    
        //Zähler zurücksetzen
        TCNT1 = 0;
    
        //INT1 auf fallende Flanke
        if(ch_cnt == 6){MCUCR &= ~(1 << ISC10);}
    }
    
    
    //Timerüberlauf nach ~4ms, wenn nicht manuell zurückgesetzt wird
    ISR(TIMER1_OVF_vect)
    {
        //Kanalzähler zurücksetzen
        ch_cnt = 0; 
    
        //Beide INT auf steigene Flanke konfigurieren
        MCUCR |= ((1 << ISC01) | (1 << ISC00)); //INT0
        MCUCR |= ((1 << ISC11) | (1 << ISC10)); //INT1
    }
    Aus hTerm
    Code:
    ...
    ...
    ...
    9618<\n>
    9618<\n>
    9618<\n>
    9618<\n>
    9618<\n>
    9618<\n>
    8837<\n>
    8837<\n>
    8837<\n>
    8837<\n>
    8837<\n>
    8837<\n>
    8837<\n>
    8837<\n>
    8837<\n>
    8837<\n>
    8837<\n>
    8837<\n>
    8837<\n>
    8837<\n>
    8837<\n>
    8837<\n>
    8837<\n>
    8837<\n>
    8837<\n>
    8837<\n>
    6762<\n>
    6762<\n>
    6762<\n>
    6762<\n>
    6762<\n>
    6762<\n>
    6762<\n>
    6762<\n>
    6762<\n>
    6762<\n>
    6762<\n>
    6762<\n>
    6762<\n>
    6762<\n>
    6762<\n>
    6762<\n>
    6762<\n>
    6762<\n>
    6762<\n>
    6762<\n>
    -2320<\n>
    -2320<\n>
    -2320<\n>
    -2320<\n>
    -2320<\n>
    -2320<\n>
    -2320<\n>
    ...
    ...
    ...
    Ich versteh nur langsam nicht mehr so ganz wieso dieses Prinzip nicht funktioniert.
    Bei jedem INT den Zähler speichern und zurücksetzen.
    Beim letzten auf fallende Flanke, damit das Ende des letzten Puls erfasst wird.

    Die Pause nach den Pulsen ist dann größer als 4ms, sodass der Timer überläuft.
    Der setzt dann alles auf Anfang zurück. Die 4ms Pause ist quasi das Syncronistations Signal.

    Jemand ne Idee was ich falsch mache?

    Gruß Basti
    PS.: Schönen Feiertag noch

    EDIT:
    gerade festgestellt, für Ch1 passt es eigentlich. Da bringt er mir einen Wert zwischen etwa 18000 und 30000 Ticks des Timers.
    Nur die weiteren Ch haben dann falsche oder sogar negative Werte. Wie kann der Timer negativ Zählen?

    Das sind die 6Ch Daten die er mir ausspuckt....
    Code:
    23925 | -239 | 2331 | -14653 | 0 | 0<\n>
    Nur Ch1 verhält sich wie gewollt, äquivalent zum Knüpel der Fernbedienung, alle anderen springen ab und zu mal wild umher, aber nicht unbedingt auf Knüpelbewegungen.

    EDIT2:
    Weitere Erkenntnis, wenn ich beide Oszi Kanäle an die INTS halte und mir die Signale anschauen will, kommen die auch auf einmal korrekt an :-D scheinbar hängt der ganze scheiß irgendwie in der Luft und fängt sich Müll ein, sobal ich das aber - wenn auch nur minimal - mit dem Oszi belaste, haut's hin. Mal überlegen was ich da nun mache....

    EDIT3:
    Tatsache, die Ausgänge des Empfängers hingen bei Low Pegel völlig in der Luft. 10k gegen Masse und die Nummer läuft wie geschmiert.
    Is ja klar, das der mir nur Müll auswertet, wenn die INTs sich alles einfangen, nur nicht das richtige Signal :-D

    Aber aus lauter Trotz bleibe ich jetzt bei C, dann lern ich das auch endlich mal - bis dato noch NIE angefasst.
    Alles was oben steht habe ich mir in etwa 48h angelesen
    Geändert von Bomberpilot (27.12.2014 um 08:24 Uhr)

  9. #49
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.191
    Aber aus lauter Trotz bleibe ich jetzt bei C
    Ich denk mal, da machst Du sicher keinen Fehler.
    Eine der wichtigsten Erkenntnisse von C ist, das der Compiler von oben nach unten arbeitet.
    Nur das was oben definiert ist kann dein Programm darunter auch nutzen.
    Deshalb steht da auch die main Routine ganz unten.
    Wenn er mal ne Routine nicht findet, obwohl sie vorhanden ist, denk mal wie der Compiler und guck, ob die Routine vor der aufrufenden steht.
    Damit hatte ich Anfangs die meisten Probleme.

    Was mich persönlich bei C auch etwas nervt ist, das man für "Sonderfunktionen" immer erst die entsprechenden Includes im Programm machen muss.
    Also für Mathematische Funktionen, String Verarbeitung usw. müssen immer die entsprechenden Includes eingefügt werden.
    Aber C ist halt ein Baukasten, aus dem man sich halt nur nimmt, was man auch für seine Anwedung braucht.

  10. #50
    Neuer Benutzer Öfters hier
    Registriert seit
    25.10.2010
    Beiträge
    26
    Zitat Zitat von wkrug Beitrag anzeigen
    Eine der wichtigsten Erkenntnisse von C ist, das der Compiler von oben nach unten arbeitet.
    Hat mich 8 Std gekostet bis ich das im Zusammenhang mit den Header Dateien komplett verstanden habe. Jetzt ist es Logisch und ich finde die Herangehensweise, jede C Datei als "eigenständig" kompilierbares Programm zu generieren auch nicht mal schlecht.

    Zitat Zitat von wkrug Beitrag anzeigen
    Deshalb steht da auch die main Routine ganz unten.
    Wenn ich das Richtig verstanden habe ist es egal, wo die main() steht, solange ich oben bzw. in der Header Datei die Funktionen als Prototyp definiert habe, oder nicht?

    Zitat Zitat von wkrug Beitrag anzeigen
    Was mich persönlich bei C auch etwas nervt ist, das man für "Sonderfunktionen" immer erst die entsprechenden Includes im Programm machen muss.
    Also für Mathematische Funktionen, String Verarbeitung usw. müssen immer die entsprechenden Includes eingefügt werden.
    Genau das schätze ich an C Kein byte zu viel Schrott im Code, sondern nur was auch Sinn macht.

    BTT:
    Also die Eingänge laufen jetzt, Jitter werde ich mir mal ansehen, denke aber das ein gleitender Mittelwert über 3 Werte da schon einiges rausholen kann.
    Die Frage ist, was ich nun mit den Ausgängen mache. Timer1 ist ja nun blockiert :-/

    Gruß Basti

Seite 5 von 6 ErsteErste ... 3456 LetzteLetzte

Ähnliche Themen

  1. Mehrere RC Signale einlesen und mehrere Servos ausgeben
    Von R2D2 Bastler im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 74
    Letzter Beitrag: 10.01.2022, 08:35
  2. RC-Signal einlesen verändern und wieder ausgeben.
    Von DanielSan im Forum Arduino -Plattform
    Antworten: 1
    Letzter Beitrag: 21.03.2013, 11:58
  3. Atmel128 Spannungen einlesen und Ausgeben (Display3000)
    Von Gantenbein im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 31.08.2007, 21:41
  4. Mehrere Signale umschalten
    Von flexxo im Forum Elektronik
    Antworten: 1
    Letzter Beitrag: 25.02.2007, 13:56
  5. Servoimpulse einlesen und ausgeben
    Von moelski im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 21.08.2006, 07:24

Berechtigungen

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

Solar Speicher und Akkus Tests