0

私は現在、インターンとしてロボットに取り組んでおり、モーターの代替ドライバーを選択する必要があります。軸の位置情報はアナログポットで与えられます。私はテクノソフトのドライバーを 3 つ持っていますが、これらのドライバーは調整作業を行うためにロータリー エンコーダー (直角位相) 情報を必要とします。このアナログ信号を適切な直交信号に変換して機能させることを考えていました。

私が設計した方法は、150hz でポット値をサンプリングする pic18 であり、現在の値から前の値を減算して、速度のアイデア (一種の導出) を取得します。速度の絶対値と方向信号を生成し、直交エンコーダの 4 つの状態でステート マシンの変化率を調整します。これらの信号を最終的に 2 つの出力に送信します。

私の質問は次のとおりです。

それは実現可能ですか?または、そうする賢い方法はありますか?それとも、仕事をすることができる専用チップでさえありますか? 私はウェブを検索して、すでに似たようなことをした人を見つけましたが、何も見つかりませんでした.

私は最後の 2 日間をこのソリューションのコーディングとデバッグに費やしましたが、成功しませんでした...スコープでは、直交信号は存在しますが、実際のロジックでは動作しません。ポットを動かしても動かさなくても、本当に速くもゆっくりも変化します。

これが私のコードです

#include <p18f4685.h>
#include <stdlib.h>
#include <stdio.h>  
#include <delays.h> 

// ----------------------
// Configuration Hardware
// ----------------------

#pragma config OSC = HSPLL
#pragma config MCLRE = ON, PWRT = OFF
#pragma config DEBUG = ON, LVP = OFF
#pragma config  FCMEN = OFF
#pragma config  IESO = OFF          
#pragma config  BOREN = OFF 
#pragma config  WDT = OFF
#pragma config  XINST = OFF

#pragma code

// Variables

unsigned int position_t0=0;                 
unsigned int position_t1=0;
signed int speed=0;
unsigned int speed_abs=0;
int direction=0; // si 0 cw, si 1 ccw
unsigned int count_1 = 0;
unsigned int state_out = 0;


//proto fonctions

void setup(void);
void get_pot(void);
void set_out(void);
void low_isr(void);
void high_isr(void);
int abval(int);


void main(void)
{
    setup();                                                //initialisation
    get_pot();
    LATE = 0b00000000;
    while(1)
    {
    }                                               
}

void setup (void)
{           
    /*config timers*/

    T0CON = 0b11000101;                                     // timer on, 8bits, internal clock, prescaler on + value 1/64 (152 interruptions par seconde)
                                                            // data acquisition interrup 
    T2CON = 0b00111100;                                     // output moditication loop timer 8bits 1/8postscale 1200 interrupt/second
    PR2 =   0b00001111;                                      

    /*config adc*/

    ADCON1 = 0b00001010;                                    // A0->A4 analo + VDD+GND reference
    ADCON2 = 0b10111000;                                    // A/D acq time (ADCON2) 20TAD, A/D conversion clock (ADCON2)
                                                            // right justified
    ADCON0 = 0b00000001;                                    // Turn on A/D module (ADCON0) + channel select

    /*config des pins*/

//  TRISA = 0b00011111;                                     // 5 entrées analogiques + 3 digitales
//  TRISB = 0b01001100;                                     // sorties pour la version finale
    TRISE = 0b00000000;                                     // sorties pour la version test
//  PORTA = 0b00000000;                                     // Clear A
    PORTE = 0b00000000;                                     // clear E

    /*config interruptions*/

    RCONbits.IPEN = 1;                                      // priority enabled
    INTCON  = 0b11100000;                                   // enable les interruption hautes et basses, Timer0 interrupt On 
    INTCON2 = 0b10000100;                                   // Pull up désactivés +timer0 high(acquisition vitesse) 
    PIE1bits.TMR2IE = 1;                                    // enable interrupt timer2
    IPR1bits.TMR2IP = 0;                                    // timer 2 en priorité basse(mise à jour des pins)
}


void get_pot (void)                                         //get the value of the pot and computes the data
{                                                   
    ADCON0bits.CHS1 = 0;                                    
    ADCON0bits.CHS0 = 0;
    ADCON0bits.GO = 1;                                      
    while(ADCON0bits.GO==1){}                               
    position_t1 = ADRESH*256+ADRESL;                        
    speed = position_t1 - position_t0;
    if(speed<0) direction = 1;
    else direction = 0;
    speed_abs = abval(speed);
    position_t0 = position_t1;
}

void set_out (void)                                         //set the output according the speed and direction
{
    if(speed_abs>1)
    {
        count_1++;
        if(count_1>=(1023-speed_abs)/4)                     //counter that makes the output change more or less faster
        {
            if(direction==1)
            {
                switch(state_out)
                {
                    case 0: 
                    {
                        LATE = 0b00000000;
                        state_out++;
                    }
                    break;
                    case 1:
                    {
                        LATE = 0b00000001;
                        state_out++;
                    }
                    break;
                    case 2: 
                    {
                        LATE = 0b00000011;
                        state_out++;
                    }       
                    break;
                    case 3:
                    {
                        LATE = 0b00000010;
                        state_out=0;
                    }
                    break;      
                }
            }
            else if(direction==0)
            {   
                switch(state_out)
                {
                    case 0: 
                    {
                        LATE = 0b00000000;
                        state_out=3;
                    }
                    break;
                    case 1:
                    {
                        LATE = 0b00000001;
                        state_out--;
                    }
                    break;
                    case 2: 
                    {
                        LATE = 0b00000011;
                        state_out--;
                    }       
                    break;
                    case 3:
                    {
                        LATE = 0b00000010;
                        state_out--;
                    }
                    break;      
                }
            }
            count_1=0;
        }
    }
}

int abval(int val)  
 { 
     return (val<0 ? (-val) : val);
 }

#pragma interrupt high_isr                                                      
void high_isr (void)                                        //interruption de récupération des adc
{   
    if(INTCONbits.TMR0IF==1)                                    
    {
        get_pot();
        INTCONbits.TMR0IF=0;
    }                                                       
}

#pragma interruptlow low_isr
void low_isr (void)                                         //interruption de mise à jour des sorties
{                                                       
    if(PIR1bits.TMR2IF==1)                              
    {
        set_out();
        PIR1bits.TMR2IF=0;
    }           
}   

/*
*********************************************************************************************************
 * Interupt Vectors
*********************************************************************************************************
*/
#pragma code low_vector=0x18
void interrupt_at_low_vector(void)
    {
        _asm goto low_isr _endasm
    }


#pragma code high_vector=0x08
void interrupt_at_high_vector(void)
    {
        _asm goto high_isr _endasm
    }

コードのコメントの一部はフランス語ですが、重要なものを翻訳しました。明らかな間違いや間違ったコーディング方法はありますか。「どこで検索するか」または何を見るかについて何かアドバイスはありますか?

よろしくお願いいたします。

ニコラス

4

0 に答える 0