[Résolu] PB fct analogWrite dans fonctions imbriquées

Bonjour,

Je travaille sur la finalisation d’une extension pour le logiciel mBlock afin que mes élèves programment un robot que j’ai conçu.

J’ai réalisé une librairie (Robot) qui permet de piloter la commande des moteurs :
void Robot::motor(byte mode, byte vitesse)
avec mode le mode de déplacement : 1-> Avancer ; 2 → Reculer ; 3 → Tourner à droite : etc.
et avec vitesse une variable pour définir la vitesse 0<V<255.

Il y a aussi la réception des signaux IF d’une télécommandes NEC.
boolean Robot::ir(byte touche, unsigned long &valeur){

Indépendamment ces deux fonctions fonctionnent très bien mais il y a un pb quand j’imbrique l’une dans l’autre.

if(robot.ir(2,valeur) 
    ){
        robot.motor(1,200); 
    }

La fonction motor ne fonctionne que si le deuxième paramètre (vitesse) est égal à 0 ou 255.
Si je mets une autre valeur le programme ne réagit plus ?
La valeur du paramètre vitesse est bien transmise correctement mais le programme ne réagit plus.

Voici l’ensemble du Code
Le Programme principal

#include <Arduino.h>
#include <Wire.h>
#include <SoftwareSerial.h>

#include "robot.h"
#include <IRremote.h>

int RECV_PIN = 8;
IRrecv irrecv(RECV_PIN);
decode_results results;

unsigned long valeur;

double angle_rad = PI/180.0;
double angle_deg = 180.0/PI;
Robot robot; 



void setup(){
    Serial.begin(9600);
    irrecv.enableIRIn(); // Start the receiver
}

void loop(){
    
    if(robot.ir(2,valeur) 
    ){
        robot.motor(1,200); 
    }
    if(robot.ir(1,valeur) 
    ){
        robot.motor(1,0); 
    }
    if(robot.ir(3,valeur) 
    ){
        robot.motor(2,255); 
    }
    if(robot.ir(5,valeur) 
    ){
        robot.motor(3,255); 
    }
    if(robot.ir(4,valeur) 
    ){
        robot.motor(4,255); 
    }
    if (irrecv.decode(&results)) {
        valeur = results.value;
        irrecv.resume();
    }
    
}

Robot.h

#ifndef Robot_h
#define Robot_h

#include "Arduino.h"

class Robot
{
 public:
 Robot();
 void motor(byte mode, byte vitesse);
 void singleMotor(byte mot, byte speed_direction);
 boolean ir(byte touche, unsigned long &valeur);
 private:
    byte mode,vitesse,mot,speed_direction,touche; 
    unsigned long &valeur;
};

#endif

Robot.cpp

#include "Arduino.h"
#include "Robot.h"

#include "IRremote.h"

extern IRrecv irrecv;
extern decode_results results;

Robot::Robot(){
 pinMode(3,OUTPUT);    //Vitesse Moteur A
 pinMode(11,OUTPUT);   //Vitesse Moteur B
 pinMode(12,OUTPUT);   //Direction Moteur A
 pinMode(13,OUTPUT);   //Direction Moteur B
}

void Robot::motor(byte mode, byte vitesse){
 switch (mode)
 {
 case 1: //Avancer
 {
 Serial.println(vitesse, DEC);
 digitalWrite(12,HIGH);
 digitalWrite(13,HIGH);
 analogWrite(3,vitesse);
 analogWrite(11,vitesse);
            Serial.println("OK");
            }
 break;
 case 2:   //Reculer
 {
 Serial.println(vitesse, DEC);
 digitalWrite(12,LOW);
 digitalWrite(13,LOW);
 analogWrite(3,vitesse);
 analogWrite(11,vitesse);
            }
 break;
 case 3:   //Tourner à droite
 {
 Serial.println(vitesse, DEC);
 digitalWrite(12,HIGH);
 digitalWrite(13,HIGH);
 analogWrite(3,0);
 analogWrite(11,vitesse);
 }
 break;
 case 4:   //Tourner à Gauche
 {
 Serial.println(vitesse, DEC);
 digitalWrite(12,HIGH);
 digitalWrite(13,HIGH);
 analogWrite(3,vitesse);
 analogWrite(11,0);
 }
 break;
 case 5:   //Pivoter à droite
 {
 Serial.println(vitesse, DEC);
 digitalWrite(12,LOW);
 digitalWrite(13,HIGH);
 analogWrite(3,vitesse);
 analogWrite(11,vitesse);
 }
 break;
 case 6:   //Pivoter à Gauche
 {
 digitalWrite(12,HIGH);
 digitalWrite(13,LOW);
 analogWrite(3,vitesse);
 analogWrite(11,vitesse);
 }
 break;
 };
}

void Robot::singleMotor(byte mot, byte speed_direction){
 boolean value;
 byte pin_dir;
 byte pin_pwm;
 byte speed_value;
 if (mot == 1){
 pin_dir = 12;
 pin_pwm = 3;
 } 
 if (mot == 2){
 pin_dir = 13;
 pin_pwm = 11;
 } 
 if (speed_direction > 0 ) value = true;
 if (speed_direction < 0 ) value = false;
 speed_value = abs(speed_direction);
 digitalWrite(pin_dir,value);
 analogWrite(pin_pwm,speed_value);
}

boolean Robot::ir(byte touche, unsigned long &valeur){
 
 boolean resultat;
 resultat = false;
 
 switch (touche)
 {
 case 1:
 {
 if (valeur == 0xFF02FD) {
 resultat = true;
 valeur = 0;
 } 
 }
 break;
 
 case 2:
 {
 if (valeur == 0xFF629D) {
 resultat = true;
 valeur = 0;
 }
 }
 break;
 
 case 3:
 {
 if (valeur == 0xFFA857) {
 resultat = true;
 valeur = 0;
 }
 }
 break;
 
 case 4:
 {
 if (valeur == 0xFF22DD) {
 resultat = true;
 valeur = 0;
 }
 }
 break;
 
 case 5:
 {
 if (valeur == 0xFFC23D) {
 resultat = true;
 valeur = 0;
 }
 }
 break;
 
 case 6:
 {
 if (valeur == 0xFF4AB5) {
 resultat = true;
 valeur = 0;
 }
 }
 break;
 
 case 7:
 {
 if (valeur == 0xFF6897) {
 resultat = true;
 valeur = 0;
 }
 }
 break;
 
 case 8:
 {
 if (valeur == 0xFF9867) {
 resultat = true;
 valeur = 0;
 }
 }
 break;
 
 case 9:
 {
 if (valeur == 0xFFB04F) {
 resultat = true;
 valeur = 0;
 }
 }
 break;
 
 case 10:
 {
 if (valeur == 0xFF30CF) {
 resultat = true;
 valeur = 0;
 }
 }
 break;
 
 case 11:
 {
 if (valeur == 0xFF18E7) {
 resultat = true;
 valeur = 0;
 }
 }
 break;
 
 case 12:
 {
 if (valeur == 0xFF7A85) {
 resultat = true;
 valeur = 0;
 }
 }
 break;
 
 case 13:
 {
 if (valeur == 0xFF10EF) {
 resultat = true;
 valeur = 0;
 }
 }
 break;
 
 case 14:
 {
 if (valeur == 0xFF38C7) {
 resultat = true;
 valeur = 0;
 } 
 }
 break;
 
 case 15:
 {
 if (valeur == 0xFF5AA5) {
 resultat = true;
 valeur = 0;
 }
 }
 break;
 
 case 16:
 {
 if (valeur == 0xFF52AD) {
 resultat = true;
 valeur = 0;
 }
 }
 break;
 
 case 17:
 {
 if (valeur == 0xFF42BD) {
 resultat = true;
 valeur = 0;
 }
 }
 break;

 };
 return resultat;
}

Merci de votre aide

Essayez en n'utilisant pas les pins 11 et 3 (controlees par Timer 2) ou 9 et 10 (controlees par timer1) sur un uno. Il se peut que votre librairie IR utilise un de ces 2 timers et fasse un reset qui nuise au pwm necessaire pour le moteur

Je vous remercie beaucoup pour votre réponse.
Vous avez parfaitement identifié le problème.

Je ne pouvais pas facilement modifier le câblage car j'utilise un Shield contrôleur de moteurs Ardumoto :
https://www.generationrobots.com/fr/401606-shield-contrôleur-de-moteurs-ardumoto.html

J'ai donc essayer avec succès une autre librairie celle d'AdaFruit

Avec celle-ci cela fonctionne.

Encore merci car sans votre aide, j'aurai cherché longtemps.

Bonne nouvelle!

Une façon pas très propre de résoudre de genre de pb c'est de tordre un peu la PIN du shield pour quelle ne s'enfonce plus en dessous et de mettre un fil vers une autre pin... mais bon quand il existe une autre librairie qui fonctionne, autant en profiter!

Bonne continuation

Encore merci
Bonne continuation à vous aussi.