pave Interruptions1 Interruptions6 INTERRUPTIONS
7/7


ATTINY85 DEBUG

+

DESCRIPTION

J'ai recherché sur le net des exemples pour l'utilisation d'un écran OLED, pour deboguer les codes sur les puces ATTinyXX, sans trop de succés... Jusqu'à ce que je trouve un exemple utilisant une librairie minimaliste, TinyOzOled. Malheureusement, peu d'exemples et pas de documentation. Donc, on mets les mains dans le cambouis. J'avoue avoir passer du temps avant de comprendre le fonctionnement de cette librairie. Cet article décrit l'utilisation d'un écran OLED SSD1306 sur la puce attiny85 pour analyser le code à l'aide de cette librairie. Une interruption sur un bouton poussoir en mode momentané ON / OFF, sera utilisé pour détecter la durée du front montant, la durée de l'appui de la touche et la durée du front descendant. Cet exemple peut servir de base pour deboguer le code sur d'autres puces ATTiny moyennant quelques adaptations. Le code est largement commenté suivant le même principe utilisé précédemment.

ANALYSEUR DE CODE OU DEBOGAGE

CODE

/* ATMEL ATTINY 25/45/85 - @Alain DORING (2021) - https://www.astrolynx.com/ - Original source


   ┌───────────────────────────────────────── SPI ───────────────────────────────────────────┐
   │                                ┌─────── ANALOG ──────┐                                  │
   │                                │  ┌─── DIGITAL ───┐  │                                  │
   │                                │  │    ┌─┐_┌─┐    │  │                                  │
 JAUNE       RESET/ADC0/PCINT5 PB5         1│     │8          VCC                           ROUGE
                   ADC3/PCINT3 PB3  3  3   2│     │7   2  1   PB2 PCINT2/SCK-L/ADC1/T0/INT0 BLANC
                   ADC2/PCINT4 PB4  2  4   3│     │6   1      PB1 PCINT1/MISO/DO            BLEU
 NOIR                          GND         4│     │5   0      PB0 PCINT0/MOSI/DI/SDA/AREF   VERT
                                            └─────┘         

 Vecteurs externes                 INT0_vect
 Vecteurs de changement de broches PCINT0_vect

            7       6       5       4       3       2       1       0
 GIMSK  -         INT0    PCIE  
 GIFR   -         INTF0   PCIF 
 PCMSK  -                 PCINT5  PCINT4  PCINT3  PCINT2  PCINT1  PCINT0 
 PORTB  -                 PORTB5  PORTB4  PORTB3  PORTB2  PORTB1  PORTB0 
 DDRB   -                 DDB5    DDB4    DDB3    DDB2    DDB1    DDB0 
 PINB   -                 PINB5   PINB4   PINB3   PINB2   PINB1   PINB0 
 WDTCR  - WDIF    WDIE    WDP3    WDCE    WDE     WDP2    WDP1    WDP0
 WDT    0x000C

                                 ┌───────────┐
                                 │ SSD1306   │
                                 │           │
                                 │        GND├►────────────────────┐             
                                 │        VCC├◄────────────┐       │             
                                 │        SCL├──┐          │       │             
                                 │        SDA├──│─┐        │       │             
                                 │           │  │ │        │       │             
                                 │           │  │ │  2K2   │       │             
                                 └───────────┘  ├─│─/\/\/\─┤       │             
                                                │ ├─/\/\/\─┤       │             
                                                │ │  2K2   │       │             
                                                │ │        │       │             
                                 ┌───────────┐  │ │        │       │             
 Non utilisé             RESET ─►│ PB5   VCC │◄─│─│────────┤       │             
                 _▄▄_            │           │  │ │        │       │             
 LED PB4 < BP ┌──O  O───────────►│ PB3   PB2 │◄─┘ │        │       │             
              │   „       1K     │           │    │   1K   │  „    │             
 LED VERTE    ├──┤◄├────/\/\/\──◄│ PB4   PB1 │►───│─/\/\/\─│─┤►├───┤ LED  ORANGE 
              │                  │           │    │        │       │             
              ├─────────────────◄│ GND   PB0 │◄───┘        │       │             
              │                  └───────────┘             │       │             
              ┴                                            │       ┴             
             GND                                          VCC     GND            
*/

#include "TinyWireM.h"
#include "TinyOzOLED.h"

bool Monte, Descend;
unsigned long R, Appui, F;
volatile unsigned long DM, FM, DD, FD;

volatile int oldEtatB3;
volatile int newEtatB3;

/*
  micros()
  Renvoie le nombre de microsecondes depuis le début de l'exécution du programme en cours. 
  Ce nombre va déborder (revenir à zéro), après environ 70 minutes. 
  Sur les cartes Arduino 16 MHz cette fonction a une résolution de quatre microsecondes 
  (c'est-à-dire que la valeur renvoyée est toujours un multiple de quatre). 
  Sur les cartes  8 MHz, cette fonction a une résolution de huit microsecondes.
  Ce qui est le cas ici car la puce ATTiny85 est réglée sur 8 MHz. 
*/

// Routine d'interruptions
ISR (PCINT0_vect)
{
  newEtatB3 = (PINB & B00001000); // newEtatB3 = digitalRead(3) pour PB3;

  // Détection d'un changement d'état PB3
  if (oldEtatB3 != newEtatB3) {
    if (!newEtatB3) {
      // Début du front montant pour PB3 ici
      DM = micros();
      PORTB ^= (1 << PB4);    // bascule la broche PB4 si changement logique PB3 - 8µs
      // Fin du front montant pour PB3 ici
      FM = micros();
      Monte = true;
    }
    if (newEtatB3) {
      // Début du front descendant pour PB3 ici
      DD = micros();
      PORTB ^= (1 << PB4);    // bascule la broche PB4 si changement logique PB3 - 8µs
      // Fin du front descendant pour PB3 ici
      FD = micros();
      Descend = true;
    }
    oldEtatB3 = newEtatB3;
  }
}

void setup() {
  // Initialisations des broches en entrées ou en sorties = 8 x Pinmode(pin, INPUT ou OUTPUT) 
  DDRB   = B11010010;       // 1 en sorties PB1 PB4 et 0 en entrée (PB0 PB2) PB3 et PB5 (RESET)

  // Initialisations des PULLUPs = 2 x Pinmode(pin, INPUT_PULLUP) 
  PORTB |= B00001000;       // active le pullup PB3 pour le Bouton Poussoir  
  
  // Activation du port B 
  GIMSK  = B00100000;       // active interruption de changement de broche (PCIE)

  // Déclaration des broches d'interruptions
  PCMSK |= B00001000;       // changement de broche activée pour PB3

  // Activation globale des interruptions
  sei ();                   // active les interruptions

  // Inversion logique des 2 leds commandées par les BPs sinon démarrent allumées
  PORTB ^= B00010000;       // bascule PB4 pour inverser la logique

  // Initialisations des routines d'interruptions pour forcer le démarrage leds éteintes
  PCINT0_vect();            // Initialise la routine d'interruption pour PB3 & PB4     

  Monte = false;
  Descend = false;

  OzOled.init();
  OzOled.clearDisplay();

}

void loop() {
  PORTB ^= (1 << PB1);       // Led Orange

//               /         R           F
//               │         │   APPUI   │
//     GRAPHE   ─┤    HIGH ┌───────────┐
//               │         │           │
//               \     LOW │           │
//
// Détermination du Front Montant (R) et du Front Descendant (F) issues de la routine ISR
// DM Début Montée - FM Fin Montée - DD Début Descente - FD Fin Descente ( en µs )

// Si bouton poussoir appuyé
  if (Monte == true) {
    R = FM - DM;                                 // Temps de montée en µs (R - RISING)
    OzOled.printString( "Montee",         1, 0); // Affiche le label «Montee»
    OzOled.printString( "              ", 1, 1); // Efface Données Montee précédentes 
    OzOled.printNumber(  R,            0, 3, 1); // Affiche Données Montee actuelles ◄-
    OzOled.printString( "us",            10, 1); // Affiche us pour µs
    OzOled.printString( "              ", 1, 3); // Efface Label Appui
    OzOled.printString( "              ", 1, 4); // Efface Données Appui
    OzOled.printString( "              ", 1, 6); // Efface Label Descente
    OzOled.printString( "              ", 1, 7); // Efface Données Descente
    Monte = false;
  }

// Si bouton poussoir relaché  
  if (Descend == true) {
    Appui = (DD -FM) / 1000;                     // Durée de l'appui en ms
    F = FD - DD;                                 // Temps de descente en µs (F - FALLING)
    OzOled.printString( "Duree Appui",    1, 3); // Affiche le label «Appui»
    OzOled.printString( "              ", 1, 4); // Efface Données Appui précédentes
    OzOled.printNumber(  Appui,        0, 3, 4); // Affiche Données Appui actuelles ◄-
    OzOled.printString( "ms",            10, 4); // Affiche ms 
    OzOled.printString( "Descente",       1, 6); // Affiche le label «Descente»
    OzOled.printString( "              ", 1, 7); // Efface Données Descente précédentes
    OzOled.printNumber(  F,            0, 3, 7); // Affiche Données Descente actuelles ◄-
    OzOled.printString( "us",            10, 7); // Affiche us pour µs 
    Descend = false;
  }
  // Résultats restent affichés jusqu'à l'appui suivant
}

Téléchargement du code au bas de cette page

IMPLANTATION

Cette vue permet de voir l'implantation des composants sur une breadboard.

attinyoled

VIDÉO

Cette vidéo montre la mesure des fronts montant et descendant avec un écran OLED sur un ATTiny85.
La led orange PB1.
La led verte PB4 commandée par le bouton poussoir PB3.

Télécharger les codes ATtiny85_OLED