[RESOLU] Gérer PWM depuis le serial

Hello à tous,

Débutant sur arduino, j'essaye actuellement de gérer la vitesse d'un ventilateur en PWM grâce à un input dans le moniteur série.
Ce montage sera par la suite intégrer dans domoticz.

Voici le code que j'utilise actuellement:

const byte OC1A_PIN = 9;
const byte OC1B_PIN = 10;

const word PWM_FREQ_HZ = 25000; //Adjust this value to adjust the frequency
const word TCNT1_TOP = 16000000/(2*PWM_FREQ_HZ);

int in = 0;

void setup() {
  
  pinMode(OC1A_PIN, OUTPUT);
  Serial.begin(9600);
  Serial.println("Demarage du PWM"); // so I can keep track of what is loaded
 


  // Clear Timer1 control and count registers
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;

  // Set Timer1 configuration
  // COM1A(1:0) = 0b10   (Output A clear rising/set falling)
  // COM1B(1:0) = 0b00   (Output B normal operation)
  // WGM(13:10) = 0b1010 (Phase correct PWM)
  // ICNC1      = 0b0    (Input capture noise canceler disabled)
  // ICES1      = 0b0    (Input capture edge select disabled)
  // CS(12:10)  = 0b001  (Input clock select = clock/1)
  
  TCCR1A |= (1 << COM1A1) | (1 << WGM11);
  TCCR1B |= (1 << WGM13) | (1 << CS10);
  ICR1 = TCNT1_TOP;
}

void loop() {
if(Serial.available()){         // Check if there's data
    in = Serial.read();
    if(in >= '0' && in <='100')
    {
    delay(5);
    }
    else 
    {
    Serial.print(in);
    Serial.println(":not valid");
    in = 0;
    } 
    Serial.println(in);// Pass the value of "in" to the pin
  }
    setPwmDuty(in); //Change this value 0-100 to adjust duty cycle
//    setPwmDuty(50);
//    delay(20000);
//    setPwmDuty(75);
//    delay(20000);
//    setPwmDuty(100);
//    delay(20000);
}

void setPwmDuty(byte duty) {
  OCR1A = (word) (duty*TCNT1_TOP)/100;
}

Tout marche nikel mais je suis obligé de donner l'instruction en ASCII pour avoir une valeur entre 0 et 100.

Ma question du coup, comment pourrais-je faire pour communiquer directement ma valeur plutôt que la correspondance ASCII?

Bonjour,

Je n'ai pas compris ce que tu veux faire, mais ceci if(in >= '0' && in <='100') est incorrect ou au moins ne fait pas ce que tu veux faire.
'0' c'est le caractère 0 (48 en ASCII) '100' c'est un caractère sur 16 bits (tronqué) soit 256*48+48=12336

Merci pour ta réponse rapide!

En faite j'essaye faire du "patchwork" avec des codes que je trouve à droite à gauche pour arriver à mes fins.

Ceci est mon premier essai sur arduino d'où surement le manque de cohérence dans le code.

Le but premier est d'envoyer une commande (chiffre) entre 0 et 100 depuis le moniteur série afin de régler la vitesse d'un ventilateur grâce au PWM.

Par quoi faudrait-il que je remplace le '0' et le '100' pour avoir des chiffres et non la correspondance ASCII?

Si ce que tu veux faire c'est entrer et envoyer le nombre sous forme de chaine de caractères tu peux faire ça:

void loop() {
  if (Serial.available()) {       // Check if there's data
    char buf[10];
    int n = Serial.readBytesUntil('\n', buf, sizeof buf - 1);
    buf[n]=0;                 // fin de la chaine
    in = atoi(buf);
    if (in > 100)
      n = 100;
    Serial.println(in);// Pass the value of "in" to the pin
    setPwmDuty(in); //Change this value 0-100 to adjust duty cycle
  }
  //    setPwmDuty(50);
  //    delay(20000);
  //    setPwmDuty(75);
  //    delay(20000);
  //    setPwmDuty(100);
  //    delay(20000);
}

Au top! Merci beaucoup Kamill!

Une dernière chose; maintenant lorsque on tape 0 on a 90 en retour dans le serial. Comment cela se fait-il?

Edit: En changeant certain n en in dans ton code kamill, tout fonctionne parfaitement.

Je ne sais pas trop. Peut être que le 9 est resté dans le buffer.
Pour que ça fonctionne correctement paramètre ton terminal pour envoyer CR LF en fin de ligne.
J'ai fait une petite correction dans le programme en ajoutant
buf[n]=0; // fin de la chaine

doodoovane:
Edit: En changeant certain n en in dans ton code kamill, tout fonctionne parfaitement.

Oups, effectivement (dans le if). Bien vu.

Problème résolu. Merci Kamill