Auteur Sujet: servotiny13  (Lu 17440 fois)

nopxor

  • Full Member
  • ***
  • Messages: 195
    • Voir le profil
servotiny13
« le: mars 22, 2018, 08:14:24 pm »
Bonjour,

Je souhaite équiper mon réseau de sémaphores avec feux pour la signalisation.
L'idée est d'utiliser un petit ATtiny13 (1k Flash) pour commander le servo qui va contrôler chaque sémaphore.

Les librairies classiques de contrôle de servos ne peuvent pas être utilisées avec un ATtiny13 qui ne dispose que d'un seul timer (8bits).
J'ai donc reprogrammé le timer pour qu'il génère une base de temps compatible avec les impulsions classiques de commande de servos.

Ci-joint le code qui utilise moins de la moité de la Flash:  ;)
/*
 servotiny13

 Permet le contrôle d'un servomoteur sur un ATtiny13 à 9.6 MHz.
 le programme configure le timer pour générer une interruption toutes les 10us soit à une fréquence de 100 kHz.
 Toutes les 20ms (50Hz) on active la sortie pour une durée d'impulsion comprise entre 1ms et 2ms.
 La fonction classique delay() n'est plus disponible puisqu'on a reprogrammé l'unique timer.
 Le programme utilise une fonction locale: delay_() pour ralentir les mouvements du servo.
 Cette fonction "attend" pendant un nombre de ticks multiple de 10us correspondant au délai souhaité.
*/


volatile unsigned int Tick;       // 100KHz pulse
volatile unsigned int sPulse;     // Servo pulse variable
volatile unsigned int Tick_10us;  // base time for delay_ function

void setup() {
  pinMode(3, OUTPUT);     // Servo pin on PB3 = pin 2 ATtiny
 
  cli();                  // Disable global interrupts
  TCCR0A = 0;             // Initialize timer 0 registers
  TCCR0B = 0; 
  TCCR0A |= (1<<WGM01);   // Configure timer 0 for CTC mode (Clear Timer on Compare Match)
  TIMSK0 |= (1<<OCIE0A);  // Enable CTC interrupt
  OCR0A = 95;             // Set CTC compare value for 100kHz interrupt
  TCCR0B |= (1<<CS00);    // No prescaler -> 9.6 MHz
  sei();                  // Enable global interrupts

  Tick = 0;
  sPulse = 100;           // 100 x 10us = 1 ms
  Tick_10us = 0;
 
}

ISR(TIM0_COMPA_vect)      // 100 KHz interrupt frequency
{
  Tick_10us += 1;
 
  if(Tick >= 2000)        // servo frame (20ms)
     {
        Tick = 0;
     }

  Tick += 1;
 
  if(Tick <= sPulse)        // Generate servo pulse
  {
    digitalWrite(3, HIGH);  // Servo pulse high
  }
  else
  {
    digitalWrite(3, LOW);   // Servo pulse low
  }
}


void loop() {
  for(int i=0; i<=100; i++)  // Servo test
    {
      sPulse = sPulse + 1;
      delay_(2000);          // delai 2000 x 10 us = 20 ms
    }

    sPulse = 200;

    for(int i=0; i<=100; i++)
    {
      sPulse = sPulse - 1;
     delay_(2000);
    }
    sPulse = 100;
}

  void delay_(int nombre)
  {
    Tick_10us = 0;                  // initialisation pour début de comptage
    while (Tick_10us < nombre) {}   // attend jusqu'à le nombre de ticks soit atteint
  }
 

msport

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 2217
  • HO avec DCC++ en DIY Réseaux très éphémères
    • Voir le profil
Re : servotiny13
« Réponse #1 le: mars 23, 2018, 07:53:24 am »
Super, je vais pouvoir recycler mes ATTiny13 qui dormaient dans le tiroir ...
Cordialement