Gestion d'un signal carré

Bonjour, merci pour l'intérêt porté au projet.

Oui dans les grandes lignes c'est ça:

  • si le bouton poussoir est actionné, alors il y a lecture de la valeur donnée par le capteur analogique (qu'il est possible de simuler par un potentiomètre).
  • de cette valeur est fonction le mode choisi, par exemple:

mode 4: si 256 < valeur < 512
mode 3: si 512 < valeur < 768
mode 2: si 768 < valeur < 1023

  • si le bouton n'est plus actionné, retour à la normale en décrémentant les modes.

C'est exactement ce que je cherche à faire.

Avec le travail cette semaine je n'ai pas eu beaucoup de temps pour m'y pencher, mais ce sera chose faite ce weekend.
Au regard des copies d'écran postées, vous avez la solution... Je suis preneur de conseils mais je veux essayé de trouver une solution et de définir un code qui fonctionne, c'est en ce confrontant à la difficulté qu'on append le mieux.
En tout cas merci pour ces visuels c'est encourageant.

ok, c'est cool, code dispo si vous le demandez.
à 2000Hz

Bonjour,
J’ai passé pas mal de temps à avancer sur le projet dans sa globalité, j’ai fais une maquette avec un moteur DC équipé d’une cible dentée devant laquelle j’ai monté un capteur inductif pour créer le signal d’entrée.
Le moteur est piloté par un PWM généré par l’arduino via un L298N et modulé par un potentiomètre.
Tout fonctionne bien.
Cependant, le code dans la partie dont nous avons discuté n’a pas avancé comme je l’aurais souhaité… je n’arrive pas à créer la decrementation des modes…
Si vous êtes toujours d’accord, je suis preneur de votre code…

hello
vous auriez aussi pu faire un générateur de fréquences avec un deuxième arduino. fréquence réglable par potentiomètre.
voici le code
attention, il y a des attributions de pins à respecter pour travailler sur les ports
si questions, n'hésitez pas.

#define BP_forcage A1 //BP sera cablé: GND, BP, D3
#define impulsions_R 2 //entrée interruptible INT0
#define impulsions_F 3 //entrée interruptible INT1
//code pour UNO. 4, 5, 6, 7 impératifs pour les commandes leds/bobines
#define led_1 4 //port C bit 4 cablage obligatoire sur D4 
#define led_2 5 //port C bit 5 cablage obligatoire sur D5 
#define led_3 6 //port C bit 6 cablage obligatoire sur D6 
#define led_4 7 //port C bit 7 cablage obligatoire sur D7 
//code pour UNO. 8,9,10,11 impératifs pour sélecteur
#define selecteur_1  8 //port B bit 0 cablage obligatoire sur D8 sera cablé: GND, sélecteur, D8
#define selecteur_2  9 //port B bit 1 cablage obligatoire sur D9 sera cablé: GND, sélecteur, D9
#define selecteur_3 10 //port B bit 2 cablage obligatoire sur D10 sera cablé: GND, sélecteur, D10
#define selecteur_4 11 //port B bit 3 cablage obligatoire sur D11 sera cablé: GND, sélecteur, D11
#define capteur_analogique A0  //
boolean bridage=false;
int state     = 0;
int val       = 0;
int mode      = 0;        //sera initialisé en fonction sélecteur/sonde analogique
int cpt_state = 0;        //pour le retour à la normale
int volatile comptage_impulsion =  0;
void isr_impulsion_R() {comptage_impulsion++;}//comptage des impulsions
void isr_impulsion_F() {PORTD=PORTD|0b11110000;}//éteindra les leds/bobines
void setup() {
Serial.begin(115200);
DDRB = DDRB &0b11110000;//portB en entrée 3,2,1,0 =0 =entrée
PORTB= PORTB|0b00001111;//1 = PULLUP activées
DDRC = DDRC |0b11110000;//portC en sortie 7,6,5,4 =1 =sortie
PORTC= PORTC&0b00001111;//forçées à LOW
  pinMode(BP_forcage, INPUT_PULLUP); // BP appuyé ramenera GND sur l'entrée
  pinMode(impulsions_R, INPUT);      // voir si c'est INPUT ou INPUT_PULLUP
  pinMode(impulsions_F, INPUT);      // voir si c'est INPUT ou INPUT_PULLUP
  attachInterrupt(0, isr_impulsion_R, RISING); // voir si c'est le bon sens FALLING ou RISING
  attachInterrupt(1, isr_impulsion_F, FALLING);// voir si c'est le bon sens FALLING ou RISING
}

void loop() 
{
  state = comptage_impulsion % 5;     /// Serial.print("state ");Serial.print(state);
  if (!digitalRead(BP_forcage))        // BP pour forcer la limitation d'allumages
  {                                    /// Serial.print("   BP_forcage ");Serial.println(digitalRead(BP_forcage));
    choix_du_mode();                   ///Serial.print("  mode ");Serial.println(mode);
    bridage = true;
    switch (mode)
    {
case 1: {                                                //on ne supprime pas d'allumage
          if (state == 1 )
          {
            comptage_impulsion = 0;                        
            PORTD=PORTD&0b11101111;        /// Serial.println("led 1");                            
          }
        } break;
case 2: {                                                 //on supprime 1 allumages sur 4
          if (state == 2 )                                 
          {
            comptage_impulsion = 0;                        
            PORTD=PORTD&0b11011111;        /// Serial.println("led 2");                          
          }
        } break;
case 3: {                                                  //on supprime 2 allumages sur 4
          if (state == 3 )                                 
          {
            comptage_impulsion = 0;                         
            PORTD=PORTD&0b10111111;          /// Serial.println("led 3");                        
          }
        } break;
case 4: { 
          if (state == 4 ) 
          {  
            comptage_impulsion = 0;                              //on supprime 3 allumages sur 4  
            PORTD=PORTD&0b01111111;/// Serial.println("led 4"); 
          }
        } break;          
 default:{}break;                                         
    }
  }
  else                                    // pas d'appui sur le BP_forcage
  {
                                         /// Serial.print("  mode libre ");Serial.println(mode);
  if(bridage){mode--;}bridage=false;
   switch (mode)
    {
//case 0: {} break;
case 1: {                                  // on ne supprime pas d' allumage
          if (state == 1 )
          {
            comptage_impulsion = 0;                           
            PORTD=PORTD&0b11101111;       /// Serial.println("led 1"); 
          }
        } break;
case 2: {                                  // on supprime 1 allumages sur 4
          if (state == 2 )                                 
          {
            comptage_impulsion = 0;
            PORTD=PORTD&0b11011111;        /// Serial.println("led 2"); 
            cpt_state++;if(cpt_state>10){mode--;cpt_state=0;}                     
          }
        } break;
case 3: {                                   // on supprime 2 allumages sur 4
          if (state == 3 )                                 
          {
            comptage_impulsion = 0;
            PORTD=PORTD&0b10111111;        /// Serial.println("led 3");             
            cpt_state++;if(cpt_state>10){mode--;cpt_state=0;}                    
          }
        } break;
case 4: { 
          if (state == 4 )                  // on supprime 3 allumages sur 4
          {  
            comptage_impulsion = 0;
            PORTD=PORTD&0b01111111;        /// Serial.println("led 4"); 
            cpt_state++;if(cpt_state>10){mode--;cpt_state=0;}
          }
        } break;                           
default:{}break;        
    }
  }
}


void choix_du_mode()
{                                    // Serial.println( PINB&0b00000111); 
    if ((PINB&0b00000111) == 7) 
      {                                
        val = map(analogRead(capteur_analogique), 0, 1023, 0, 30); // capteur analogique >10, >15, >20, >25
        if (val > 20) {mode = 2;}
        else {if (val > 15) {mode = 3;}
          else {if (val > 10) {mode = 4;}
            else {mode = 1;}}}
      }
      else
      {
        mode = PINB & 0b00000111;
      }
}

Bonjour, un grand merci, j’ai bien fais de pas poster mon code, qui, bien que fonctionnel, hormis la « decrementation » est beaucoup plus long et « laborieux »…
Je vais prendre le temps d’étudier le votre qui pour moi est une vraie leçon.
Oui j’aurais peut être pu faire plus simple également pour la génération de signaux mais mon côté mécanicien est rassuré à la vue du mouvement… de plus étant pleinement novice dans l’arduino puisque c’est mon premier projet et ma première expérience de codage, je ne me sentais pas de multiplier les programmes.

hello
le code sera probablement à modifier /adapter selon le type de votre sélecteur.
chez moi, c'est 4 fils que je mets ou pas à GND.
bon courage pour la suite et surtout n'hésitez pas à poser les questions qui vous viendraient.
moi ou un autre (les bonnes volontés ne manquent pas sur le forum) vous aiderons avec plaisir.

Bonjour,
je travail actuellement sur la compréhension de votre code et j'avoue, comme énoncé précédemment, qu'il m'est un vraie leçon...
j'en suis à l'appentissage du "bitwise", pour essayer de comprendre le fonctionnement de ce type de lignes:

DDRB = DDRB &0b11110000;
PORTB= PORTB|0b00001111;
DDRC = DDRC |0b11110000;
PORTC= PORTC&0b00001111;

mais c'est pas évident avec les divers tutos que j'ai pu trouver.
Je veux absolument le comprendre parfaitement avant de l'utiliser, ce qui est le moindre des respect à vous accorder, vu le travail effectué.

Encore merci pour pour toutes les infos données.

hello
vu de très très haut,
il faut voir un micro comme une suite de cases. 1 case = 1 octet. 1octet = 8bits:
disons qu'il y a des cases appellées "registres" qui servent au fonctionnement interne et des cases de "mémoire" qui servent à écrire le prg ou a stocker des données.

il y a les registres qui correspondent aux différents ports.
ces registres ont une adresse et sont en fait un byte(octet) composé de 8 bits (de 0 à 7).

pour le port B, il y a trois registres:
DDRB qui sert à définir si les bits du port B sont des entrées ou des sorties
ex: DDRB=0b11111110 met le bit 0 du port B en entrée et les autres bits en sorties
PORB qui sert a mettre effectivement la sortie à 1 (pour ses bits qui sont en entrée)

nota: si un bit est en entrée, en écrivant un 1 dans le bit correspondant du registre de sortie, on active la pullup de la die entrée.

ex: PORTB=0b00000001 met le bit 0 du port B à 1
PINB qui sert à lire l'état du port B (pour ses bits qui sont en entrée)
ex: valeur_bit_0_du_port_B=PINB&0b00000001

avec cet exemple, nous avons utilisé un "MASK" avec la fonction logique AND
si PIND=11100100
avec & 00000001
= 00000000 ce qui est exact car le bit 0 du port B est bien à 0 ( ici, 2 lignes au dessus)

avec cet autre exemple:
si PIND=11100101
avec & 00000001
= 00000001 ce qui est exact car le bit 0 du port B est bien à 1 ( ici, 2 lignes au dessus)
adresse 0x 04 est le byte qui correspond au registre de direction du port B

nous venons d'utiliser le & AND. il existe aussi le ~ complément à 2, le | OR, le ^ XOR, le >>shift droit et le << shift gauche.

après t'avoir posté le prg, j'ai modifié le prg
voir ici pour la correspondance des bits des ports et les definitions Arduino
dans les define, le BP est passé de A1 à 12 (D12 est le bit 4 du port B)
dans le set up
DDRB = DDRB &0b11110000;//portB en entrée 3,2,1,0 =0 =entrée
PORTB= PORTB|0b00001111;//1 = PULLUP activées
est devenu
DDRB = DDRB &0b11100000;//portB en entrée 4,3,2,1,0 =0 =entrée
PORTB= PORTB|0b00011111; //1 = PULLUP activées
dans la loop
if (!digitalRead(BP_forcage))
est devenu
if ((PINB&0b00010000) == 0) //si D12==0

#define impulsions_R 2 //entrée interruptible INT0
#define impulsions_F 3 //entrée interruptible INT1
//code pour UNO. 4, 5, 6, 7 impératifs pour les commandes leds/bobines
#define led_1 4 //port C bit 4 cablage obligatoire sur D4 
#define led_2 5 //port C bit 5 cablage obligatoire sur D5 
#define led_3 6 //port C bit 6 cablage obligatoire sur D6 
#define led_4 7 //port C bit 7 cablage obligatoire sur D7 
//code pour UNO. 8,9,10,11 impératifs pour sélecteur
#define selecteur_1  8 //port B bit 0 cablage obligatoire sur D8 sera cablé: GND, sélecteur, D8
#define selecteur_2  9 //port B bit 1 cablage obligatoire sur D9 sera cablé: GND, sélecteur, D9
#define selecteur_3 10 //port B bit 2 cablage obligatoire sur D10 sera cablé: GND, sélecteur, D10
#define selecteur_4 11 //port B bit 3 cablage obligatoire sur D11 sera cablé: GND, sélecteur, D11
#define BP_forcage 12 //BP sera cablé: GND, BP, D12
#define capteur_analogique A0  //
boolean bridage=false;
int state     = 0;
int val       = 0;
int mode      = 0;        //sera initialisé en fonction sélecteur/sonde analogique
int cpt_state = 0;        //pour le retour à la normale
int volatile comptage_impulsion =  0;
void isr_impulsion_R() {comptage_impulsion++;}//comptage des impulsions
void isr_impulsion_F() {PORTD=PORTD|0b11110000;}//éteindra les leds/bobines
void setup() 
{
  Serial.begin(115200);
  DDRB = DDRB &0b11100000;//portB en entrée 3,2,1,0 =0 =entrée
  PORTB= PORTB|0b00011111;//1 = PULLUP activées
  DDRC = DDRC |0b11110000;//portC en sortie 7,6,5,4 =1 =sortie
  PORTC= PORTC&0b00001111;//forçées à LOW
  pinMode(BP_forcage, INPUT_PULLUP); // BP appuyé ramenera GND sur l'entrée
  pinMode(impulsions_R, INPUT);      // voir si c'est INPUT ou INPUT_PULLUP
  pinMode(impulsions_F, INPUT);      // voir si c'est INPUT ou INPUT_PULLUP
  attachInterrupt(0, isr_impulsion_R, RISING); // voir si c'est le bon sens FALLING ou RISING
  attachInterrupt(1, isr_impulsion_F, FALLING);// voir si c'est le bon sens FALLING ou RISING
}

void loop() 
{
  state = comptage_impulsion % 5;     /// Serial.print("state ");Serial.print(state);
                                          ///Serial.print("   BP_forcage ");Serial.println(PINB&0b00010000);
  if ((PINB&0b00010000) == 0)            // BP pour forcer la limitation d'allumages
  //if (!digitalRead(BP_forcage))        // BP pour forcer la limitation d'allumages
  {                                     ///Serial.print("   BP_forcage ");Serial.println(PINB&0b00010000);
    choix_du_mode();                   ///Serial.print("  mode ");Serial.println(mode);
    bridage = true;
    switch (mode)
    {
case 1: {                                                //on ne supprime pas d'allumage
          if (state == 1 )
          {
            comptage_impulsion = 0;                        
            PORTD=PORTD&0b11101111;        /// Serial.println("led 1");                            
          }
        } break;
case 2: {                                                 //on supprime 1 allumages sur 4
          if (state == 2 )                                 
          {
            comptage_impulsion = 0;                        
            PORTD=PORTD&0b11011111;        /// Serial.println("led 2");                          
          }
        } break;
case 3: {                                                  //on supprime 2 allumages sur 4
          if (state == 3 )                                 
          {
            comptage_impulsion = 0;                         
            PORTD=PORTD&0b10111111;          /// Serial.println("led 3");                        
          }
        } break;
case 4: { 
          if (state == 4 ) 
          {  
            comptage_impulsion = 0;                              //on supprime 3 allumages sur 4  
            PORTD=PORTD&0b01111111;/// Serial.println("led 4"); 
          }
        } break;          
 default:{}break;                                         
    }
  }
  else                                    // pas d'appui sur le BP_forcage
  {
                                         /// Serial.print("  mode libre ");Serial.println(mode);
  if(bridage){mode--;}bridage=false;
   switch (mode)
    {
//case 0: {} break;
case 1: {                                  // on ne supprime pas d' allumage
          if (state == 1 )
          {
            comptage_impulsion = 0;                           
            PORTD=PORTD&0b11101111;       /// Serial.println("led 1"); 
          }
        } break;
case 2: {                                  // on supprime 1 allumages sur 4
          if (state == 2 )                                 
          {
            comptage_impulsion = 0;
            PORTD=PORTD&0b11011111;        /// Serial.println("led 2"); 
            cpt_state++;if(cpt_state>10){mode--;cpt_state=0;}                     
          }
        } break;
case 3: {                                   // on supprime 2 allumages sur 4
          if (state == 3 )                                 
          {
            comptage_impulsion = 0;
            PORTD=PORTD&0b10111111;        /// Serial.println("led 3");             
            cpt_state++;if(cpt_state>10){mode--;cpt_state=0;}                    
          }
        } break;
case 4: { 
          if (state == 4 )                  // on supprime 3 allumages sur 4
          {  
            comptage_impulsion = 0;
            PORTD=PORTD&0b01111111;        /// Serial.println("led 4"); 
            cpt_state++;if(cpt_state>10){mode--;cpt_state=0;}
          }
        } break;                           
default:{}break;        
    }
  }
}


void choix_du_mode()
{                                    // Serial.println( PINB&0b00000111); 
    if ((PINB&0b00000111) == 7) 
      {                                
        val = map(analogRead(capteur_analogique), 0, 1023, 0, 30); // capteur analogique >10, >15, >20, >25
        if (val > 20) {mode = 2;}
        else {if (val > 15) {mode = 3;}
          else {if (val > 10) {mode = 4;}
            else {mode = 1;}}}
      }
      else
      {
        mode = PINB & 0b00000111;
      }
}