Rc receiver, cterni pwm signalu, atmega32

Dobry den, pokousim se precist signal z vystupu modelarskeho prijimace. Zjistuji kdy prisla hrana a pote merim jak dlouho je pin na 1, tuto hodnotu hned posilam do funkce pro ovladani serva. Externi preruseni pouzit nechci protoze chci cist vice nez 3 vystupy.

#include <avr/io.h>          // this contains all the IO port definitions
#include <compat/ina90.h>    // among other things, contains _NOP()
#include <avr/interrupt.h>

#define F_CPU 16E6

#include <util/delay.h>
#include <inttypes.h>

volatile unsigned int counter0;
volatile unsigned int counter1;
volatile unsigned int s1a_pos = 1550;

volatile unsigned char rc_state;
volatile unsigned char rc_state_old;
volatile unsigned int rc_start_time;
volatile unsigned int rc_end_time;
volatile unsigned int rc_total_time;

#define timer0_top 65200 //8bit = 1s
#define timer1_top 50   //in Hz

void servo_pos( unsigned int s1a)
{
        if (s1a <= 700) s1a = 700;
        if (s1a > 2500) s1a = 2500;
        //hitec c577
        //s1a_pos=700;//s1a_pos=1500;//s1a_pos=2500;
        //hitec 65hb
        //s1a_pos=600;//s1a_pos=1450;//s1a_pos=2300;
        if ( TCNT1 <= s1a)  // 0 - n
                        PORTD = 1<<PD7;
                        else
                        PORTD = 0<<PD7;
}

ISR (TIMER0_OVF_vect)
{
        ++counter0;
}

ISR (TIMER1_OVF_vect)
{
        ++counter1;
}

int main()
{
        DDRD = 0b11111111;

        DDRA = (0<<PA7);
        PORTA |= (1<<PA7); //pull up
        /* Initial TIMER1 */
        TCCR1B = (1<<WGM13) | (1<<CS11) ;//set counter1 to mode 8,with no prescaling//phase and freq correct PWM
        ICR1 = 20000;//ICR1 to produce 50Hz //(MCU_FREQ = 1600000/(2 x n=1 x 20000)) = 50Hz n=prescaler
        TIMSK |= (1<<TOIE1);

        /* Initial TIMER0 */
        TCCR0 = (1<<CS00);              // Use maximum prescale: Clk
        TIMSK |= (1<<TOIE0);            // Enable Counter Overflow Interrupt
        sei();                          // Enable Global Interrupt

        rc_state_old = rc_state = 1;
        rc_total_time = rc_end_time = rc_start_time = 1500;

        while (1)
        {
                //global(poloha serva) - resim w loop0, odskoceni kontrola TCNT1 pripadne zmena
                servo_pos(s1a_pos);

                        //ted je hrana
                        if ( rc_state != rc_state_old) {
                                if ( rc_state == 1 ) {
                                        rc_start_time = TCNT1;
                                }
                                else {
                                        rc_end_time = TCNT1;
                                        if( rc_end_time > rc_start_time )
                                                rc_total_time = rc_end_time - rc_start_time;
                                        //prectene pwm hned poslu na servo 
                                        if ( (rc_total_time > 700) && ( rc_total_time <2500) )
                                                s1a_pos = rc_total_time;
                                }
                        //zmena hrany je oblouzena
                                rc_state_old = rc_state;
                        }

                if ( (PINA & (1<<PA7)) == (1<<PA7) ) //ted neni pin zapojenej -  bez gnd
                                //stav je TRUE
                                rc_state = 1;
                        else
                                rc_state = 0;
        }
}

Muze nekdo poradit? Diky

Tez jsem vyuzil externich irq, v nich jsem menil nastaveni z rising na falling edge, pote zkousel po rising edge preruseni merit jak dlouho vydrzi 1 na vstupu. Vysledek se nedostavil. S osciloskopem jsem zjistil ze puls dosahuje pouze do 2.51V, zrejme mcu tuto hodnotu nepovazuje za log 1. Jakym zapojenim prosim dosahnu teto zmeny, jak z 2.5V dostat 5V? Z prijimace jdou pulsy po 20ms /50Hz/ a jsou dlouhe cca 1 - 2 ms. Omlouvam se amaterske dotazy, bohuzel nevim nic. Dik

Ak sa signal zo serva pohybuje v rozmedzi 0V (maximalne 0,2V) az 2,5V, potom tymto signalom otvaraj NPN tranzistor (cez bazovy odpor cca 1k a medzi bazu a emitor vloz dalsi odpor cca 10k). Kolektor trazistora prived na pin ATmega a zaroven cez odpor 2k2 na +5V. Hodnoty odporov su orientacne. Signal budes mat invertovany, ale to vadit nebude.

Druhy sposob je znizit Xtal a znizit Ucc procesora na 3V.

Ale to s tym tranzistorom sa mi paci viac.
Miesto tranzistora mozes pouzit napriklad 74HCT14, Umin log.H je 2.4V (TTL logika). Pozor! 74HCxx ma rozhodovaciu uroven log.H na 70% Ucc, takze by to uz nemuselo ist.

Z prijimace jdou pulzy z 0V na 3.18V. Na kolektor jsem dal pin megy a dale 2k a +5V, na bazi taky 2k, na emitor nic a primo na GND. Pulsy jsou nyni z 0V na 4.77V. Coz myslim je v poradku.
Princip cteni je tento: rozbehnu timer1, kazdych 50Hz mi pretece, nez pretece nabiha TCNT1 od 0 do 20000 /nastaveno ICR1 = 20000/. Jakmile ze ne pinu objevi 0, zjistim TNCT1, jakmile se objevi 1, zjistim TNCT1 a odectu. Zadne externi irq nemam nastaveno. Ctu pin PA7.
Je to takto mozne?

Pokial do toho vidim, tak urcite ano. Ten citac mozes kludne nechat pretekat cez 65535. Po odcitani boch cisel dostane spravny vysledok.
Na spravnu cinnost by malo stacit i tych 3.18V, pisal si o 2.5V. Ale tranzistor to isti :slight_smile:

Ne, uz to resim miliontou hodinu a nejsem schopen to kloudne precist. Pres ICR=20000, nechavam pretect proto abych mel tech 50Hz pro serva. Uz nevim kudy dal.

Mam tomu rozumiet tak ze vyhodnocujes hranu, alebo uroven?

Cas merim v okamziku kdy se uroven zmeni, z 1 na 0 /zacnu merit/, z 0 na 1 /zmerim opet, odecitam/. Jeste nechavam svitit jednu diodu kdyz na vstupu 1 a druhou kdyz je 0. Jas diody se meni presne podle pohybu knyplu. Zkousel jsem pullupy na vstupy, se zesilujicim tranzistorem i bez nej. Vsechno se zda ze je ok. Velikost odectu kolisa, pri dlouhem pulsu /2ms/ se hodnata /pohyb serva/ rychle meni od cca 1.6ms do 1.8ms, pri pulsu 1ms kmita stejne rychle ale vice na opacnou stranu, od 1ms do 1.7ms. Dekuju

Co vlasntne kmita? Nejako som sa v tom celom stratil :slight_smile:
Najprv sa riesila otazka velkosti Uvst pre vstupy procesora. Ako som pochopil, toto je vyriesene. Co Ti to teda vlastne teraz robi a co by si chcel aby to robilo?
Skus to prosim popisat co najzrozumitelnejsie, lebo ako citujem v predchadzajucom, popisu mi nie je jasne co ze to kmita rovnako rychlo.Co je ta prva vec s ktorou porovnavas kmitanie tej druhej (mne zatial neznamej) veci?
Pod kmitanim rozumies kolisanie?

To sa meni skutocna hodnota - pohyb serva - alebo iba namerana hodnota? Odkial vies a s akou istotou/presnostou, ze nemarana hodnota ma stabilne vlastnosti? Ako to odcitavas zo stanice? Display? Komunikacia?