servo e pin

salve a tutti.
su internet non ho trovato nulla a riguardo e vi espongo il mio problema. ho intenzione di controllare la temperatura del mio case, regolare sempre all’interno del case delle luci led RGB e led RG (sarebbero quelle a 3 pin rosso e verde), il mio case essendo dotato di uno sportello superiore che si può aprire e chiudere ho deciso di adattarci un servo per il controllo di quest’ultimo.
il programma scritto non è altro che l’assieme di vari circuiti scritti separatamente (da perfezionare purtroppo è da poco che mi sono avvicinato ad arduino), mettendoli assieme ho notato che il PWM dei led non funziona quando inserisco libreria e tutto ciò che riguarda il servo, se rimuovo questi il tutto funziona.

sapreste dirmi come mai succede questo con il servo?

//servo
#include <Servo.h>
Servo servo;
int gradi;

//Display
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x20,16,2);

//Sensore
int sens = A3;
float temp;
//Led RG frontali
int Rg = 12;
int rG = 11;
int livelloRG;
//Led RGB superiori
int Rgb = 3;
int rGb = 5;
int rgB = 6;
int livelloRGB;
//Ventole frontali
int ven1 = 2;
int ven2 = 4;
//Ventole superiori
int ven3 = 7;
int ven4 = 8;

void setup() 
{
 Serial.begin(9600); 
 //servo
 servo.attach(9);
 //Display
 lcd.init();
 //sensore
 pinMode(sens, INPUT); 
 //RGB frontali (sfumature arancioni)
 pinMode(Rg, OUTPUT);
 pinMode(rG, OUTPUT);
 //Ventole inferiori
 pinMode(ven1, OUTPUT);
 pinMode(ven2, OUTPUT);
 //RGB superiori(sfumature segnaletiche)
 pinMode(Rgb, OUTPUT);
 pinMode(rGb, OUTPUT);
 pinMode(rgB, OUTPUT);
 //Ventole superiori
 pinMode(ven3, OUTPUT);
 pinMode(ven4, OUTPUT);
}

void loop() 
{
 //lettura temperatura
 temp = analogRead(sens);
 temp = (5.0*temp*100.0)/1024.0;
 temparr = ceil(temp);
 Serial.print(temp);
 Serial.print("          ");
 //Accensione ventole
 if(temp > 20)
 {
  digitalWrite(ven1, HIGH);

   if(temp > 22)
   {
    digitalWrite(ven2, HIGH);

     if(temp > 24)
     {
      digitalWrite(ven3, HIGH);

       if(temp > 26)
       {
        digitalWrite(ven4, HIGH);
       }
       else
       {
        digitalWrite(ven4, LOW);
       }
     }
     else
     {
      digitalWrite(ven3, LOW);
     }
   }
   else
   {
    digitalWrite(ven2, LOW);
   }
 }
 else
 {
  digitalWrite(ven1, LOW);
 }

 //Servo
 if(temp > 30)
 {
                   //angolo servo da stabilire
 }
 if(temp <= 30)    //gradi da stabilire
 {
   
 }

 servo.write(gradi);
 
 //Led RG frontali
 livelloRG = (255-(255*(30-temp)/30));
 if(temp > 0 && temp <= 30)
 {
  digitalWrite(Rg, HIGH);
  analogWrite(rG, (200));
 }
 if(temp > 30.5);
 {
  digitalWrite(Rg, HIGH);
  digitalWrite(rG, LOW);
 }

 //LED RGB superiori
 livelloRGB = (255*(30-temp)/30);
 if(temp < 25)
 {  
  analogWrite(rGb, (255-(255-livelloRGB)));
  digitalWrite(rgB, HIGH);  
 }
 if(temp > 25 && temp <= 30)
 {
  analogWrite(Rgb, (255-livelloRGB));
  digitalWrite(rgB, HIGH);
 }
 if(temp > 30.5)
 {
  digitalWrite(Rgb, HIGH);
  digitalWrite(rGb, LOW);
  digitalWrite(rgB, LOW);
 }
 Serial.println(livelloRG);
 delay(50);
}

ciao

RedDark:
sapreste dirmi come mai succede questo con il servo?

Perchè la libreria Servo disabilita la funzione PWM sui pin 9 e 10.

ciao
pippo72

Ciao e benvenuto sul forum.

Essendo il tuo primo post Ti invitiamo cortesemente a presentarti QUI (dicci quali conoscenze hai di elettronica e di programmazione) e a leggere attentamente il regolamento QUI se non lo hai già fatto.

Attilio

ma disabilita il pwm sui pin 9 e 10 su qualsiasi pin lo colleghi? ad esempio io l’ho collegato al pin 3 e mi disabilita i pin 5,6,9,10 non solo 9, 10. se lo collegassi sul pin 9 mi disabilita solo il 10 e gli altri sarebbero liberi?

domani mi presento al momento sono concentrato sul progetto.

grazie per gli aiuti. :smiley:

No, disabilita il PWM sui pin 9 e 10 indipendentemente dal/dai pin ceh usi per il Servo perché usa il timer che gestisce il PWM su quei 2 pin. La libreria Servo.h funziona su tutti i pin (al massimo 12 sul Arduino UNO).

Ciao Uwe

piccolo aggiornamento ho utilizzato i pin 3,5,6 per il PWM dei led RGB, il servo sul pin 9, il 10 è disabilitato e mi rimane solo l'11 libero, purtroppo il pin 11 non fa il suo dovere da PWM, se è come di te voi perchè non va?

@RedDark: sei già stato invitato a farlo ... ti rinnovo l'invito a presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto ;)) e a leggere con attenzione il REGOLAMENTO ... Grazie.

Guglielmo

non lo diciamo noi, Pwm.
Per generare un PWM il micro ha bisogno di un timer, ogni timer è collegato a 2 pin.

Timer0: pin 5/6
Timer1: pin 9/10
Timer2: pin 3/11

Il timer0 viene usato da Arduino per contare il tempo in modo da poter poi essere letto con Millis()/Microseconds(), questo timer può essere usato con la analogWrite() senza però poter cambiare di frequenza e può avere qualche problema nel portare a 0 il valore del duty cycle.

Il timer1 viene usato dalla libreria Servo, quindi non si può collegare direttamente al pin.
La libreria Servo può controllare fino a 12 servomotori su qualsiasi pin del micro.

Il timer2 la usa la libreria Tone, se non la includi puoi usare liberamente i pin 3/11.

Per poterti aiutare meglio serve lo schema, lo sketch e una spiegazione piu dettagliata, bisogna vedere quali pin hai liberi, quelli non liberi cosa fanno e vedere nel programma cosa stai facendo.
Per controllare dei led si può fare benissimo un softwarePWM, con o senza timer, oppure si potrebbe usare lo scheduler con la ServoWithoutTimer, oppure, oppure, oppure…

mi sono presentato.
vi elenco i pin occupati:

//servo
#include <Servo.h>
Servo servo;
int gradi;

//Display
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x20,16,2);

//Sensore
int sens = A3;
float temp;
//Led RG frontali
int Rg = 12;
int rG = 11;
int livelloRG;
//Led RGB superiori
int Rgb = 3;
int rGb = 5;
int rgB = 6;
int livelloRGB;
//Ventole frontali
int ven1 = 2;
int ven2 = 4;
//Ventole superiori
int ven3 = 7;
int ven4 = 8;

a me servono 4 pwm. 3 sono per i led RGB e uno per il verde del led RG perchè devo dare sfumature arancioni e il rosso rimane sempre acceso. perchè come dite voi ne ho a disposizione 4 giusti giusti. il led RGB funziona bene ma il verde no. devo collegare il servo su una porta non pwm? (questo è possibile?)

@RedDark: ti sei presentato, ma … il regolamento non lo hai letto :smiley:

In conformità al regolamento, punto 7, edita (in basso a destra del post, bottone More → Modify) il tuo post e racchiudi il codice all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone fatto così: </>, tutto a sinistra). Grazie. :wink:

Guglielmo

mi sono letto anche il regolamento. c'è altro? :D

ho inserito il programma completo che dovrò finire di scrivere dato che devo aggiungere lo schermo in i2c, da definire l'angolo di giro del servo (devo smontare tutto il pc appena avrò tempo e definirò anche questo parametro). sono ben accetti suggerimenti o metodi migliori per scrivere il programma (purtroppo non conosco tutti i codici). il problema purtroppo persiste riguardo al pwm sul pin 11

Grazie per l'aiuto

RedDark:
mi sono letto anche il regolamento. c’è altro? :smiley:

… si, avevo fatto riferimento al regolamento per il punto 7 … racchiudi il codice nei tag CODE … e non è per sfizio, è che spesso il codice viene interpretato come emoticon se non racchiuso tra detti TAG. Ad esempio 8 e ) se li scrivo affiancati danno questo: 8)

Ecco il motivo del punto 7. del regolamento :wink: Grazie.

Guglielmo

RedDark: devo collegare il servo su una porta non pwm? (questo è possibile?)

Il servo lo puoi collegare dove vuoi, NON è gestito tramite un segnale PWM, ma in PPM.

Guglielmo

forse per questo che non mi funziona la porta 11? perchè collegando il servo sul pin 9 mi si blocca il pwm sul pin 11??? o elimina solo ed esclusivamente il pwm ma abilita comunque il comando LOW HIGH sulle porte 9,10?

Ti è stato già ben spiegato che :

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. [u]Libreria e PWM su tali pin mutuamente esclusivi[/u]. 8-bit phase correct pwm mode (default 488.28125 Hz)

Timer2 Usato per il PWM sui pin 3 e 11 8-bit phase correct pwm mode (default 488.28125 Hz)

Quindi, se usi la libreria servo NON hai più a disposizione, come pin PWM, i due pin 9 e 10 (restano liberi per altre cose) dato che il Timer1 che è usato normalmente per generare il PWM su tali pin ... viene invece usato dalla Servo per generare le sue tempistiche. Gli altri pin funzionano come al solito.

Guglielmo

si lo avevo capito, ma non si spiega il perchè il pin 11 non mi funziona dato che la libreria servo disabilita il pwm ai pin 9, 10. questo non comprendo.

ah! ti ringrazio per le spiegazioni riguardate il regolamento.

Difatti dovrebbe funzionare ... ... magari puoi mettere una versione aggiornata di tutto il programma ed uno schema esatto dei collegamenti che hai fatto ? Così proviamo a vedere se sfugge qualche cosa ... ::)

Guglielmo

P.S.: Ma perché non ti fai una funzioncina per il setting dei colori ? Renderesti MOLTO più leggibile il tutto. Ad esmepio, io in una mia applicazione ho :

enum LED_colors {
  BLACK,
  RED,
  BLUE,
  GREEN,
  YELLOW,
  CYAN,
  MAGENTA,
  WHITE
};
....
....
void setLED(uint8_t color) {
  switch (color) {
     case BLACK:
        digitalWrite(LEDR, LOW);
        digitalWrite(LEDG, LOW);
        digitalWrite(LEDB, LOW);
        break;
     case RED:
        digitalWrite(LEDR, HIGH);
        digitalWrite(LEDG, LOW);
        digitalWrite(LEDB, LOW);
        break;
     case BLUE:
        digitalWrite(LEDR, LOW);
        digitalWrite(LEDG, LOW);
        digitalWrite(LEDB, HIGH);
        break;
     case GREEN:
        digitalWrite(LEDR, LOW);
        digitalWrite(LEDG, HIGH);
        digitalWrite(LEDB, LOW);
        break;
     case YELLOW:
        digitalWrite(LEDR, HIGH);
        digitalWrite(LEDG, HIGH);
        digitalWrite(LEDB, LOW);
        break;
     case CYAN:
        digitalWrite(LEDR, LOW);
        digitalWrite(LEDG, HIGH);
        digitalWrite(LEDB, HIGH);
        break;
     case MAGENTA:
        digitalWrite(LEDR, HIGH);
        digitalWrite(LEDG, LOW);
        digitalWrite(LEDB, HIGH);
        break;
     case WHITE:
        digitalWrite(LEDR, HIGH);
        digitalWrite(LEDG, HIGH);
        digitalWrite(LEDB, HIGH);
        break;
     default:
        break;
  }
}
....
....

... in questo modo mi basta chiamare la funzione con il colore che voglio ed ottenerlo, esempio, voglio il giallo, chiamo : setLED(YELLOW);

lo schema posto è quello più aggiornato se mai provo un po da solo e vedo se funziona il tutto. il tuo esempio per me al momento è arabo perchè come detto nella presentazione e se non sbaglio anche all'inizio del post ho detto che non so molto di programmazione. ho utilizzato quel modo per poter variare gradualmente in base alla temperatura l'effetto luminoso, che inferiore a 25°C va dal celeste al blu, superiore a 25°C e minore di 30°C mi da una sfumatura che va dal blu al viola. pensandoci il colore blu è sempre attivo potrei utilizzare il suo pin per far funzionare il verde.

ma sempre sono curioso di sapere il perchè non funziona :-\