Anneau led avec AtTiny85 et bouton capacitif perso
Aujourd’hui, je mets au point un petit système...
Article mis en ligne le 19 octobre 2025

par Rémi

Aujourd’hui, je mets au point un petit système de lumière sous un "cristal" acheté à la cité de la mer à Cherbourg en Cotentin.
Le but s’est de l’illuminer par le dessous, et comme j’ai un anneau de diode (12 diodes) multicolores, autant l’utiliser. En fonction de l’utilisateur. Alors hop, un bouton capacitif, c’est plus marrant.

l’Attiny85, c’est simple. c’est pas gros. et cela tombe bien, je n’ai pas beaucoup de place. je vais installer cela dans une pièce en chêne. Mais avant, j’ai préparé un support (3D) pour le cristal, de façon à lui donner 6° d’inclinaison.
Ce sera cette pièce qui sera incluse dans le chêne, avec l’électronique.
Après pour le bouton capacitif, c’est une simple attache parisienne avec deux résistances au bout.
connectées l’une sur la pin 2 l’autre sur la pin 4 de l’At85.
L’anneau est connecté à la pin 3 pour la commande, et au 5v / Gnd pour les deux autres connexions.
Les librairies à utiliser :
#include <CapacitiveSensor.h>
#include <Adafruit_NeoPixel.h>
Le principal souci a été de gérer la sensibilité du "bouton" . Ce sera à changer dans :
#define SENSIBILITE 120

Pour le reste , rien de compliqé. J’ai repris le code de AZ-Delivery (le fournisseur de l’anneau) et adapté car il inclus de base, du code "delay(xy)" qui empèchait la prise en compte du "bouton".

J’utilise la diode interne (pinMode(LED_INTERNE, HIGH/LOW) comme indicateur d’état

Voici donc le code

/*
gestion d'un anneau led multicolore avec un bouton tactile
Le tout alimenté en 5v 
R. Suinot 
Première version: 10 oct 2025
  - gestion du tactile
Rev: 14 oct 2025 
  - ajout de neopixel
  Rev : 17 oct 2025
  - modification de mon bouton (diminution d'une des resistances: plus petite = plus sensible)
Rev 19 oct 2025
  - suppression des delay(xy) pour cause de retard à la prise en compte du bouton
*/

#include <CapacitiveSensor.h>
#include <Adafruit_NeoPixel.h>

// Def constantes
#define LED_INTERNE 1
#define SENSIBILITE 120
uint8_t onBit = 4;                              // 8 bits pour l'indicateur de changement d'état
CapacitiveSensor cs1 = CapacitiveSensor(4, 2);  // 10M resistor entre les pins 4 & 2

#define LED_PIN 3
#define LED_COUNT 12
Adafruit_NeoPixel ring(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

// Fin constantes


void setup() {
  pinMode(LED_INTERNE, OUTPUT);  // controle via la LED du module
  // gestion d'un bouton tactile
  cs1.set_CS_AutocaL_Millis(0xFFFFFFFF);

  // gestion de l'anneau led
  ring.begin();
  ring.show();
  ring.setBrightness(50);
}
void loop() {

  onBit = detection();
  if (onBit == 1) {
    colorWipe(ring.Color(255, 0, 0));  // Rouge
  } else if (onBit == 2) {
    colorWipe(ring.Color(0, 255, 0));  // Vert
  } else if (onBit == 3) {
    colorWipe(ring.Color(0, 0, 255));  // Bleu
  } else if (onBit == 4) {
    rainbow(5);  // Cycle d'arc-en-ciel sur l'ensemble de l'anneau
  }
  digitalWrite(LED_INTERNE, LOW);
}

uint8_t detection() {
  long total = cs1.capacitiveSensor(30);
  if ((total >= SENSIBILITE)) {
    // détection d'un niveau haut : bouton activé
    digitalWrite(LED_INTERNE, HIGH);
    onBit += 1;
  }
  if (onBit > 4)
    onBit = 1;

  return onBit;
}

void colorWipe(uint32_t color) {
  uint8_t my_exit=0;
  int i = 0; 
  do{
    ring.setPixelColor(i, color);
    ring.show();
    i++;
    if ( cs1.capacitiveSensor(30) >= SENSIBILITE ) {
      my_exit = 1;
      onBit +=1; // on change la valeur, si nous sommes ici, la valeur précédente était forcément < 4
    }
  } while (i < ring.numPixels() & ( my_exit ==0 ) );

}

void rainbow(int wait) {
  uint8_t my_exit=0;
  // Cycle d'arc-en-ciel sur l'ensemble de l'anneau
  long firstPixelHue = 0;
  do {
    int i = 0;
    do{ 
      int pixelHue = firstPixelHue + (i * 65536L / ring.numPixels());
      ring.setPixelColor(i, ring.gamma32(ring.ColorHSV(pixelHue)));
      if ( cs1.capacitiveSensor(30) >= SENSIBILITE ) {
        my_exit = 1;
        onBit = 1; // on change la valeur, si nous sommes ici, la valeur précédente était forcément à 4
      }
      i++;
    } while ( ( i < ring.numPixels() ) & ( my_exit == 0) );
    ring.show();
    firstPixelHue += 256;
    if ( my_exit == 0 ) {
      delay(wait);
    }
  } while ( ( firstPixelHue < 5 * 65536 ) & ( my_exit == 0 ) );
}

Ci-joint, les fichiers d’impression 3d

fichier 3d FREECAD
Fichier d’impression 3MF

Et une photo du résultat quand les diodes sont vertes (et en dessous, la pièces blanche, ce trouve être la pièce imprimée en 3D)

en vert !