Interfacer un joystick avec un ULN 2003 à l'aide d'un ATTiny
Répondre à la discussion
Affichage des résultats 1 à 6 sur 6

Interfacer un joystick avec un ULN 2003 à l'aide d'un ATTiny



  1. #1
    Yvan_Delaserge

    Interfacer un joystick avec un ULN 2003 à l'aide d'un ATTiny


    ------

    Bonjour,

    Marier un ATTiny avec un ULN 2003 pour contrôler un moteur pas-à-pas semble une idée géniale. On dirait qu'ils ont été conçus l'un pour l'autre. Il y a un tuto ici:

    http://www.avr-asm-tutorial.net/avr_...r/stepper.html

    ici, le gars contrôle la vitesse de son moteur pas-à-pas grâce à un potentiomètre.

    Moi, ce que j'aimerais faire, c'est presque ça: commander la vitesse et la direction d'un moteur pas à pas avec un joystick.

    En fait, pour un joystick, il s'agirait:
    1) de lire, par la patte d'entrée de l'ATTiny, disons 20 fois par seconde, la tension au niveau du curseur du joystick.
    2) de générer sur les 4 pattes de sortie, la séquence nécessaire à la commande du moteur et de l'envoyer à l'ULN 2003.

    Pour ce qu'on va lire par la patte d'entrée de l'ATTiny, en partant de la tension 0 à la tension Vcc, on aura 3 zones:
    1) d'abord une zone dans laquelle le moteur tourne en arrière de moins en moins vite.
    2) au voisinage de Vcc/2, une zone où le moteur s'arrête
    3) une zone dans laquelle le moteur tourne en avant de plus en plus vite.

    Est-ce quelqu'un l'a déjà fait? Est-ce qu'il existe une bibliothèque de programmes pour l'ATTiny? Une application simple comme ça, ça a sûrement déjà été fait...

    Merci d'avance

    Amicalement,

    Yvan

    -----

  2. #2
    invite5c0d525e

    Re : Interfacer un joystick avec un ULN 2003 à l'aide d'un ATTiny

    Pourquoi un ATTiny ?

  3. #3
    paulfjujo

    Re : Interfacer un joystick avec un ULN 2003 à l'aide d'un ATTiny

    bonjour,

    Voici un exemple adaptable , en C18 Mplab

    J'utilise un potar pour regler la frequence d'un gene BF DDS
    c'est le potar direction verticale d' un joystick

    Potar au centre ,avec une zone morte, la consigne est fixe , eteint les 2 leds UP & DOWN
    Potar vers le haut, elle augment de facon exponentielle par rapport à l'ecart angulaire et allume led Up
    Potar vers le bas, elle diminue de facon exponentielle par rapport à l'ecart angulaire et allume led Down

    ceci pour pouvoir faire un reglage fin ou grossier de la valeur
    Mf est la mesure analogique du potar joystick

    J'utilise l'autre potar Horizontal pour me deplacer dans un menu...

    il peut y avoir aussi d'autres facon,par calcul , en utilisant une fonction mathematique...
    mais l'usage du flottant ralentit et bouffe de la ram..


    Code:
    void Traite_Potar_Freq (void)
      {
        Flags.Drapeaux.Change=0;
        Mf= Mesure_ADC(1);
       if ((Mf <= 544)&&(Mf>=480) )
       { 
             Flags.Drapeaux.Change=0;
             Led_Up=1; Led_Down=1; //eteint les 2 leds
             Led_Centre=0;
             LCD_Pos(2,0);
             LCD_Put('=');LCD_Put(' '); 
              
        }
        else 
        {
            Led_Centre=1;
            Flags.Drapeaux.Change=1;
            if (Mf >544) 
            {
            Led_Up=0; Led_Down=1; 
            if ((Mf > 544)  && (ConsFreq<24999)) ConsFreq=ConsFreq+1;
            if ((Mf > 576)  && (ConsFreq<24998)) ConsFreq=ConsFreq+2;
            if ((Mf > 608)  && (ConsFreq<24997)) ConsFreq=ConsFreq+3;
            if ((Mf > 640)  && (ConsFreq<24995)) ConsFreq=ConsFreq+5;
            if ((Mf > 672)  && (ConsFreq<24990))ConsFreq=ConsFreq+10;
            if ((Mf > 704)  && (ConsFreq<24985))ConsFreq=ConsFreq+15;
            if ((Mf > 736)  && (ConsFreq<24975))ConsFreq=ConsFreq+25;
            if ((Mf > 768)  && (ConsFreq<24925))ConsFreq=ConsFreq+75;
            if ((Mf > 800)  && (ConsFreq<24900))ConsFreq=ConsFreq+100;
            if ((Mf > 832)  && (ConsFreq<24800))ConsFreq=ConsFreq+200;
            if ((Mf > 864)  && (ConsFreq<24700))ConsFreq=ConsFreq+300;
            if ((Mf > 896)  && (ConsFreq<24600))ConsFreq=ConsFreq+400;
            if ((Mf > 928)  && (ConsFreq<24500))ConsFreq=ConsFreq+500;
            if ((Mf > 960)  && (ConsFreq<24000))ConsFreq=ConsFreq+1000;
            if (ConsFreq>25000) ConsFreq=25000;
            }
            if(Mf<480)
            {
            Led_Up=1; Led_Down=0;   
            if ((Mf <480) && (ConsFreq>1)) ConsFreq=ConsFreq-1;
            if ((Mf <448) && (ConsFreq>2))ConsFreq=ConsFreq-2;
            if ((Mf <416) && (ConsFreq>3))ConsFreq=ConsFreq-3;
            if ((Mf <384) && (ConsFreq>5))ConsFreq=ConsFreq-5;
            if ((Mf <352) && (ConsFreq>10))ConsFreq=ConsFreq-10;
            if ((Mf <320) && (ConsFreq>15))ConsFreq=ConsFreq-15;
            if ((Mf <288) && (ConsFreq>25))ConsFreq=ConsFreq-25;
            if ((Mf <256) && (ConsFreq>75))ConsFreq=ConsFreq-75;
            if ((Mf <224) && (ConsFreq>100))ConsFreq=ConsFreq-100;
            if ((Mf <192) && (ConsFreq>200))ConsFreq=ConsFreq-200;
            if ((Mf <160) && (ConsFreq>300))ConsFreq=ConsFreq-300;
            if ((Mf <128) && (ConsFreq>400))ConsFreq=ConsFreq-400;
            if ((Mf <96)  && (ConsFreq>500)) ConsFreq=ConsFreq-500;
            if ((Mf <64)  && (ConsFreq>1000)) ConsFreq=ConsFreq-1000;
            if (ConsFreq<1) ConsFreq=1;
            }   
            if (Flags.Drapeaux.Change==1)
            {
              itoa(Mf,txt); 
              if(Debugging==1)
              {
              Put_RS('M');Put_RS('=');
              k=PutStr_RS(txt);Put_RS(TAB); 
              }
              LCD_Pos(2,0);
              if (Mf<480){ LCD_Put('<');LCD_Put(' ');}
              if (Mf>544) { LCD_Put('>');LCD_Put(' ');}
                             
            }
           
            Tempo(15000);   
         }
     }

  4. #4
    Yvan_Delaserge

    Re : Interfacer un joystick avec un ULN 2003 à l'aide d'un ATTiny

    Citation Envoyé par gabuzo Voir le message
    Pourquoi un ATTiny ?
    Hello gabuzo.

    Je n'ai pas d'actions chez le fabricant de l'ATTiny!

    L'idée, c'est d'utiliser un microcontrôleur 8 pattes, de faible prix, pour interfacer un joystick et un ULN 2003, qui va alimenter un moteur pas à pas.

    Naturellement, si tu connais de meilleures options, je suis tout ouïes.

    Amicalement,

    Yvan

  5. A voir en vidéo sur Futura
  6. #5
    Yvan_Delaserge

    Re : Interfacer un joystick avec un ULN 2003 à l'aide d'un ATTiny

    Hello, Paulfjujo,

    Deux excellentes idées que tu as eues.
    1) L'augmentation quasi-exponentielle de la vitesse au fur et à mesure que l'on s'éloigne du point milieu
    2) La réalisation de la loi quasi-exponentielle selon une table de comparaison.

    Le langage que tu envoies doit être de haut niveau, parce que le nombre de lignes de code est très inférieur à celui de la source de l'auteur de la référence que je donnais en début de fil. Et que voici:

    ; ****************************** **********************
    ; * Steppermotor-Driver with an ATtiny13 - Version 1 *
    ; * (C)2007 by http://www.avr-asm-tutorial.net *
    ; ****************************** **********************
    ;
    ; Debugging switches
    ;
    .equ debug_calc = 0
    .equ debug_const = 0
    .equ debug_out = 0
    ;
    .nolist
    .include "tn13def.inc"
    .list ; ______
    ; / |
    ; Hardware: | |
    ; _______ . . +12V black
    ; ___ / | | | ___ |
    ; +5V-|___|--|RES VCC|--+5V B3-|I4 O4|-|___|-+Q4 red
    ; | | | | ___ |
    ; B3--|PB3 PB2|---------|I5 O5|-|___|-+Q2 brown
    ; | | | | ___ |
    ; Analog-In--|PB4 PB1|---------|I6 O6|-|___|-+Q3 green
    ; | | | | ___ |
    ; |--|GND PB0|---------|I7 O7|-|___|-+Q1 white
    ; |________| | | |
    ; ATtiny13 |-|GND CD|-------+
    ; |_______|
    ; ULN2003
    ;
    ; Funktioning:
    ; A stepper motor is controled by an analog input voltage
    ; on pin 3. The input voltage ranges from 0 Volt to
    ; the operating voltage of the processor. The number
    ; of steps of the motor over that input range are
    ; adjusted by the constant cSmSteps (1...65535 steps).
    ; Stepmotor drive sequence and encoding:
    ; Portbit PB0 PB2 PB1 PB3 | |
    ; Color wt bn gn rd | Portbit | Byte
    ; Step Q4 Q3 Q2 Q1 | 3 2 1 0 |
    ; ------------------------+---------+------
    ; 1 1 1 0 0 | 0 1 0 1 | 05
    ; 2 0 1 1 0 | 0 1 1 0 | 06
    ; 3 0 0 1 1 | 1 0 1 0 | 0A
    ; 4 1 0 0 1 | 1 0 0 1 | 09
    ; results in the word table: .dw 0x0605,0x090A
    ;
    ; Timer TC0:
    ; The timer runs with the processor clock of 1.2 Mcs/s
    ; with a prescaler value of 1024 in normal CTC mode,
    ; with the CompareA register as TOP value. Interrupt
    ; at CompareA match resp. at CTC reset.
    ; The interrupt service routine compares the actual
    ; value of motor steps with the target value. If the
    ; actual value is too low, the actual value is
    ; increased one step, if it is too high the actual
    ; step value is decreased. If actual and target value
    ; are equal, the coils of the motor are switched off
    ; after a certain pre-selectable delay.
    ; Timing: step frequency = 1.2 Mcs/s / 1024 / CompA,
    ; with CompA = 255: step frequency = 4.57 cs/s,
    ; with CompA = 8: step frequency = 146 cs/s
    ; ADC:
    ; Conversion of the analogue voltage on pin 3 / PB4 /ADC2,
    ; summing up 64 measuring results to average results,
    ; conversion to the target value for the stepper motor
    ; Timing: clock divider for conversion = 128,
    ; 1,2 Mcs/s / 128 = 9,375 kcs/s = 106,7 us clock rate,
    ; Conversion = 13 cycles = 1,387 ms per conversion
    ; = 721 conversions per second
    ; Averaging over 64 conversions = 88,75 ms = 11,3 results
    ; per second
    ;
    ; Constants
    ;
    .equ cSmSteps = 1276 ; 2552/2, number of steps for full range
    .equ cSmFreq = 145 ; frequency stepper motor
    ; Minimum: 5 cs/s, Maximum: 1171 cs/s
    .equ cSmDelay = 390 ; number of cycles prior to switching off
    ;
    ; Derived constants
    ;
    .equ clock = 1200000 ; clock frequency Tiny13 internal
    .equ Tc0Ctc = 1024 ; prescaler value TC0
    .equ cCmpA = clock / 1024 / cSmFreq ; CompareA value
    ;
    ; Checking the constants
    ;
    .IF cCmpA > 255
    .ERROR "Steppermotor frequency too low!"
    .ENDIF
    .IF cCmpA < 1
    .ERROR "Steppermotor frequency too high!"
    .ENDIF
    ;
    ; SRAM (not used, only for stack operation)
    ;
    ; Registers
    ;
    ; used: R0 for table reading
    ; used: R8:R1 for calculation of target value
    ; free: R10:R8
    .def rAdcCL = R11 ; ADC calculation value LSB
    .def rAdcCH = R12 ; dto., MSB
    .def rAdcRL = R13 ; ADC transfer value LSB
    .def rAdcRH = R14 ; dto., MSB
    .def rSreg = R15 ; status save/restore register
    .def rmp = R16 ; Multipurpose outside Int
    .def rimp = R17 ; Multipurpose inside Int
    .def rFlg = R18 ; Flags
    .equ bAdc = 0 ; Adc conversion complete flag
    .def rAdcC = R19 ; ADC counter (64 Adc conversions)
    .def rAdcL = R20 ; ADC Adder register LSB
    .def rAdcH = R21 ; dto., MSB
    .def rSmSL = R22 ; Steppermotor target value LSB
    .def rSmSH = R23 ; dto., MSB
    .def rSmIL = R24 ; Steppermotor actual value LSB
    .def rSmIH = R25 ; dto., MSB
    ; used: X for activation delay of the coils
    ; free: Y
    ; used: Z for table access
    ;
    ; ****************************** ****
    ; Code Segment Start, Int - Vector
    ; ****************************** ****
    ;
    .cseg
    .org $0000
    ;
    rjmp Main ; Reset vector
    reti ; INT0 vector
    reti ; PCINT0 vector
    reti ; TIM0_OVF vector
    reti ; EE_RDY vector
    reti ; ANA_COMP vector
    rjmp Tc0IntCA ; TIM0_COMPA vector
    reti ; TIM0_COMPB vector
    reti ; WDT vector
    rjmp AdcInt ; ADC vector
    ;
    ; ****************************** ****
    ; Interrupt Service Routines
    ; ****************************** ****
    ;
    ; Timer-Counter 0 Compare A Interrupt Service Routine
    ;
    Tc0IntCA:
    in rSreg,SREG ; save status
    cp rSmIL,rSmSL ; compare actual with target value
    cpc rSmIH,rSmSH
    breq Tc0IntCA0 ; jump if equal
    brcs Tc0IntCAF ; actual less than target value
    sbiw rSmIL,1 ; actual greater than target, one step back
    rjmp Tc0IntCAS
    Tc0IntCAF:
    adiw rSmIL,1 ; one step forward
    Tc0IntCAS:
    mov rimp,rSmIL ; copy actual value LSB
    andi rimp,0x03 ; isolate lowest two bit
    ldi ZH,HIGH(2*SmTab) ; point Z to table in flash memory
    ldi ZL,LOW(2*SmTab)
    add ZL,rimp ; add the two lowest bits
    ldi rimp,0 ; update upper Byte
    adc ZH,rimp
    lpm ; read next value from table to R0
    .IF debug_out == 0
    out PORTB,R0 ; write value to port
    .ENDIF
    ldi XH,HIGH(cSmDelay) ; restart delay counter
    ldi XL,LOW(cSmDelay)
    out SREG,rSreg ; restore status
    reti
    Tc0IntCA0:
    sbiw XL,1 ; decrease delay counter
    brne Tc0IntCAD ; not yet zero
    ldi rimp,0 ; switch of current on coils
    out PORTB,rimp ; to output driver
    ldi XH,HIGH(cSmDelay) ; restart delay counter
    ldi XL,LOW(cSmDelay)
    Tc0IntCAD:
    out SREG,rSreg ; restore status
    reti
    ;
    SmTab:
    .dw 0x0605,0x090A
    ;
    ; Adc Conversion Complete Interrupt Service Routine
    ;
    AdcInt:
    in rSreg,SREG ; save status
    in rimp,ADCL ; read LSB of ADC result
    add rAdcL,rimp ; add to the result register
    in rimp,ADCH ; read MSB of ADC result
    adc rAdcH,rimp ; add to the result register
    dec rAdcC ; decrease counter
    brne AdcInt1 ; if not zero, go on converting
    mov rAdcRL,rAdcL ; 64 conversions, copy result
    mov rAdcRH,rAdcH
    clr rAdcH ; clear sum
    clr rAdcL
    ldi rAdcC,64 ; restart conversion counter
    sbr rFlg,1<<bAdc ; set flag
    AdcInt1:
    ldi rmp,(1<<ADEN)|(1<<ADSC)|(1<<AD IE)|(1<<ADPS2)|(1<<ADPS1)|(1<< ADPS0)
    out ADCSRA,rmp ; restart conversion
    out SREG,rSreg ; restore status
    reti
    ;
    ; ****************************** ****
    ; Main program Init and Loop
    ; ****************************** ****
    ;
    Main:
    ; Stack init
    ldi rmp, LOW(RAMEND)
    out SPL,rmp
    ; Init register
    clr rFlg ; clear flag register
    clr rSmIL ; clear actual value
    clr rSmIH
    clr rSmSL ; clear target value
    clr rSmSH
    ldi XH,HIGH(cSmDelay) ; restart delay counter
    ldi XL,LOW(cSmDelay)
    ; Init output port
    ldi rmp,0x0F ; output on portbits 0..3
    out DDRB,rmp
    ldi rmp,0x05 ; start motor at step 1
    out PORTB,rmp
    ; Debugging session
    .IF debug_calc
    .equ adc_result = 128
    ldi rmp,HIGH(adc_result)
    mov rAdcRH,rmp
    ldi rmp,LOW(adc_result)
    mov rAdcRL,rmp
    rjmp dcalc
    .ENDIF
    .IF debug_const
    .equ const = cMSteps
    ldi rmp,HIGH(const)
    mov rSmSH,rmp
    ldi rmp,LOW(const)
    mov rSmSL,rmp
    .ENDIF
    ; Init ADC
    ldi rAdcC,64 ; restart ADC conversion counter
    clr rAdcL ; clear ADC sum value
    clr rAdcH
    ldi rmp,1<<ADC2D ; Digital Input Disable on channel 2
    out DIDR0,rmp
    ldi rmp,1<<MUX1 ; ADC mux on channel 2
    out ADMUX,rmp
    ldi rmp,(1<<ADEN)|(1<<ADSC)|(1<<AD IE)|(1<<ADPS2)|(1<<ADPS1)|(1<< ADPS0)
    out ADCSRA,rmp ; start conversion
    ; TC0 init
    ldi rmp,cCmpA ; set CTC value
    out OCR0A,rmp
    ldi rmp,1<<WGM01 ; set CTC mode
    out TCCR0A,rmp
    ldi rmp,(1<<CS02)|(1<<CS00) ; prescaler = 1024
    out TCCR0B,rmp
    ldi rmp,1<<OCIE0A ; Interrupt Compare Match A enable
    out TIMSK0,rmp
    ; Sleep Mode and Int Enable
    ldi rmp,1<<SE ; sleep enable
    out MCUCR,rmp
    sei ; Int enable
    Loop:
    sleep ; sleep
    nop ; Dummy for wakeup
    sbrc rFlg,bAdc ; ADC flag set?
    rcall AdcRdy ; convert ADC result
    rjmp Loop ; sleep again
    ;
    ; ****************************** ****
    ; Calculation routine
    ; ****************************** ****
    ;
    ; ADC conversion complete calculate target value
    ;
    AdcRdy:
    cbr rFlg,1<<bAdc ; clear ADC flag
    .IF debug_const
    ret
    .ENDIF
    dcalc:
    mov rAdcCH,rAdcRH ; copy sum value
    mov rAdcCL,rAdcRL
    ldi rmp,LOW(cSmSteps) ; number of steps to R4:R3:R2:R1
    mov R1,rmp
    ldi rmp,HIGH(cSmSteps)
    mov R2,rmp
    clr R3
    clr R4
    clr R5 ; clear result in R8:R7:R6:R5
    clr R6
    clr R7
    clr R8
    AdcRdy1:
    lsr rAdcCH ; shift lowest bit to carry flag
    ror rAdcCL
    brcc AdcRdy2 ; do not add
    add R5,R1 ; add to result
    adc R6,R2
    adc R7,R3
    adc R8,R4
    AdcRdy2:
    lsl R1 ; multiply multiplicator by two
    rol R2
    rol R3
    rol R4
    mov rmp,rAdcCL ; = zero?
    or rmp,rAdcCH
    brne AdcRdy1 ; go on multiplying
    ldi rmp,0x80 ; round up
    add R5,rmp
    adc R6,rmp
    ldi rmp,0
    adc R7,rmp
    adc R8,rmp
    cli ; disable interrupts
    mov rSmSL,R7 ; set target value LSB
    mov rSmSH,R8 ; dto., set MSB
    .IF debug_out
    out PORTB,rSmSL
    .ENDIF
    sei ; enable interrupts again
    ret
    ;
    ; End of Source Code
    ;

  7. #6
    invite5c0d525e

    Re : Interfacer un joystick avec un ULN 2003 à l'aide d'un ATTiny

    Citation Envoyé par Yvan_Delaserge Voir le message

    L'idée, c'est d'utiliser un microcontrôleur 8 pattes, de faible prix, pour interfacer un joystick et un ULN 2003, qui va alimenter un moteur pas à pas.
    Salut Serge, je n'ai pas de meilleures options mais cette tendance générale à mettre systématiquement un nom de marque ou de produit sur les µC (Arduino, Picaxe, Pic, Attiny etc ) me chagrine toujours un peu. N'importe quelle marque de µC est capable de te fournir un bidule correspondant à tes besoins.

Discussions similaires

  1. interfacer un pic avec un téléphone portable
    Par invite7ddbd48e dans le forum Électronique
    Réponses: 0
    Dernier message: 21/03/2013, 10h37
  2. Besoin d'aide; Problème avec word 2003,
    Par invite5d41167c dans le forum Logiciel - Software - Open Source
    Réponses: 2
    Dernier message: 02/11/2011, 14h06
  3. besoin de l'aide pour interfacer l'eeprpm m95160
    Par LABTOOL48 dans le forum Électronique
    Réponses: 2
    Dernier message: 26/05/2010, 15h27
  4. interfacer un téléphone Alcatel OT-708 avec un PIC
    Par invitee5da24ea dans le forum Électronique
    Réponses: 11
    Dernier message: 19/12/2009, 12h53
  5. Interfacer un CNA avec un FPGA
    Par invite1237d672 dans le forum Électronique
    Réponses: 4
    Dernier message: 14/04/2008, 15h43
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...