Problemi libreria infrarossi e PWM

Ciao a tutti
spero di riuscire a spiegare il mio problema

scopo del mio “progetto” : comandare due motori con un telecomando TV

come Hardware utilizzo (in sintesi):

  • Arduino Duemilanove
  • un ricevitore IR
  • un L298N
  • libreria <IRremote.h>

PIN 11 è collegato al ENA del 298
PIN 12 è collegato al IN1 del 298
PIN 13 è collegato al IN3 del 298
PIN 7 é collegato all’uscita del sensore infrarossi
PIN 6 è collegato ad un led (comandato anche lui dal telecomando)

il problema è che il motore (per ora faccio i test su uno solo) va sempre al massimo o sta fermo
ho inserito una parte di codice (solo come test) dove aumento progressivamente il valore di “potenza” che attraverso il pin 11 dovrebbe regolarmi la potenza del motore
qusto codice funziona solo se commento la riga :

//irrecv.enableIRIn();

se non lo faccio, quella parte di codice viene “ignorata”
Se non la commento, il telecomando funziona, ma i comandi da telecomando funzionano solo per far andare avanti o in dietro il motore, ma solo alla massima potenza, se con i tasti volume abbasso la potenza ( e dal monitor seriale vedo che lo fa), il motore si ferma appena scende sotto 255 e a volte il codice va proprio nel pallone e devo riavviarlo. Anche il comando del LED funziona

di seguito inserisco il codice

grazie a tutti
Andrea

#include <IRremote.h>

 
 
//definizione dei pin
static int mA = 12; //pin digitale per determinare gli stati logici da inviare al modulo
static int mB = 13; //pin digitale per determinare gli stati logici da inviare al modulo
static int mC = 8; //pin digitale per determinare gli stati logici da inviare al modulo
static int mD = 9; //pin digitale per determinare gli stati logici da inviare al modulo
static int pinPotenza = 11; //pin digitale tramite il quale inviare un segnale di tipo PWM tramite la funzione analgWrite()
int RECV_PIN = 7; // pin segnale in uscita dal rilevatore IR
int led = 6;

IRrecv irrecv(RECV_PIN);
decode_results results;
 
//variabili usate per gestire e mostrare i valori di operaizone
int accelerazione;  //valore letto dal pin A0
int potenza;  //valore in uscita dal pin 11
bool mot1in1 = LOW;
bool mot1in2 = HIGH;
 
void setup() {
  //inizializzo la comunicazione seriale cosi da mostrare i valori nel Monitor Seriale
  Serial.begin(9600);

  irrecv.enableIRIn(); // Start the receiver - DA QUI NASCE IL PROBLEMA
 
  //inizializzo variabili

  potenza = 0;
 
  //definisco tipologia pin
  //pinMode(pinAcceleratore, INPUT); //input in quanto legge il valore analogico del pin A0
  pinMode(mA, OUTPUT); //output perche' definisce lo stato logico del pin IN1 del modulo L298N
  pinMode(mB, OUTPUT); //output perche' definisce lo stato logico del pin IN2 del modulo L298N
  pinMode(pinPotenza, OUTPUT);  //output perche' definisce il valore PWM del pin EN1 del modulo L298N
  pinMode(led, OUTPUT); 
 

  //Definisco il senso di marcia del motore
  /*
   in1 |   in2 | Evento
  -----|-------|----------------------
  LOW  | LOW   | fermo
  LOW  | HIGH  | Movimento in un senso
  HIGH | LOW   | Movimento senso opposto
  HIGH | HIGH  | Fermo
  */
  
  digitalWrite(mA, mot1in1);
  digitalWrite(mB, mot1in2);
 
}
 
 
void loop() {


    if (potenza < 0){
      potenza = 0; 
    }

    if (potenza > 255){
      potenza = 255; 
    }


  if (irrecv.decode(&results)) {
  Serial.println(results.value, HEX);
  translateIR(); 
  irrecv.resume(); // Receive the next value
  }

 // sotto : Parte di codice usato per test **********
  potenza = 50; 
  Serial.print(" - potenza = ");
  Serial.println(potenza);
  delay(1000);
  analogWrite(pinPotenza, potenza);
  potenza = potenza + 50; 
  Serial.print(" - potenza = ");
  Serial.println(potenza);
  delay(1000);
  analogWrite(pinPotenza, potenza);
  potenza = potenza + 50; 
  Serial.print(" - potenza = ");
  Serial.println(potenza);
  delay(1000);
  analogWrite(pinPotenza, potenza);
  potenza = potenza + 50; 
  Serial.print(" - potenza = ");
  Serial.println(potenza);
  delay(1000);
  analogWrite(pinPotenza, potenza);
 // sopra : Parte di codice usato per test ************

  // imposto la marcia dei motori 1 e 2
  digitalWrite(mA, mot1in1);
  digitalWrite(mB, mot1in2);
  digitalWrite(mC, mot2in3);
  digitalWrite(mD, mot2in4);
  
  Serial.print(potenza);
  Serial.print(" - ");
  Serial.println(accelerazione);

  
  //invio costantemente il valore PWM della potenza in modo da far variare la velocita' del motore in base alla posizione del potenziometro
  analogWrite(pinPotenza, potenza);


}

/*-----( Declare User-written Functions )-----*/
void translateIR() // takes action based on IR code received

// describing Car MP3 IR codes 

{
  int sensorValue=0;
  bool sensorValue2=0;
  sensorValue = digitalRead(led);
  Serial.println(sensorValue); 
  Serial.println(mot1in1);
  Serial.println(mot1in2);
  switch(results.value)
  {

  case 0xDAEA83EC: // Tasto Rosso ACCENDE/SPEGNE Led
    if (sensorValue==0){
      Serial.println(" Accensione "); 
      digitalWrite(led, HIGH); 
      break;
    }
    if (sensorValue==1){
      Serial.println(" Spegnimento "); 
      digitalWrite(led, LOW); 
      break;
    }
   case 0xC26BF044: // Tasto Freccia Su Motori Avanti
    mot1in1 = LOW;
    mot1in2 = HIGH;
    potenza = 255;
    Serial.println(" Avanti motore 1 potenza 255"); 
   break;
    
   case 0xC4FFB646: // Tasto Freccia Giu Motori indietro
    mot1in1 = HIGH;
    mot1in2 = LOW;
    potenza = 128;
    Serial.println(" Retro motore 1 potenza 255"); 
   break;

   case 0x8AF13528: // Tasto Enter/OK FERMA MOTORI
    mot1in1 = LOW;
    mot1in2 = LOW;
    potenza = 0;
    Serial.println(" MOTORI FERMI !"); 
   break;

   case 0x68733A46: // Tasto Volume su aumenta potenza
    potenza = potenza + 20;
    Serial.println(" Aumenta potenza !"); 
   break;

   case 0x83B19366: // Tasto Volume giu diminuisce potenza
    potenza = potenza - 20;
    Serial.println(" Diminuisce potenza !"); 
   break;
  
  default: 
    Serial.println(" other button   ");

  }

  


} //END translateIR

la libreria IR usa il timer 2 e percui le 2 uscite PWM ( 3 e 11) che usano quel Timer non funzionano in PWM. Devi usare altri pin PWM.

Ciao Uwe

Funziona !
da una parte mi rincuora, dall'altra conferma che bisogna conoscere bene gli strumenti che si usano :wink:

posso chiederti maggiori informazioni sul problema che si generava ?

grazie mille !
Andrea

Semplicemente un conflitto nell’uso di un timer della MCU … il Timer2 che veniva usato sia dalle libreria IRremote per le sue temporizzazioni che dal PWM per le sue … con ovvio conflitto.

Su Arduino UNO i timers sono così usati:

Timer0
Usato da millis() e delay() e per il PWM sui pin 5 e 6
fast hardware pwm
(default 976.5625 Hz)
Pin 5 è anche usato per il “pulse counting”
Pin 8 è usato per il “input capture”

Timer1
Usato dalla libreria Servo e per il PWM sui pin 9 e 10. Libreria e PWM mutuamente esclusivi.
8-bit phase correct pwm mode
(default 488.28125 Hz)

Timer2
Usato dalla funzione tone() ed usato per il PWM sui pin 3 e 11. Funzione e PWM mutuamente esclusivi.
8-bit phase correct pwm mode
(default 488.28125 Hz)

… all’utente evitare conflitti con le librerie che usa e con le funzionalità che richiede.

Guglielmo

nid69ita:
Aggiungo solo, Timer2 usato dalla tone()

Grazie, aggiunto nel post precedente :slight_smile:

Guglielmo

grazie mille !
mi appunto questa pagina :wink: