ARDUINO: PILOTARE IL REGOLATORE MST_K16S - 2





IMPLEMENTAZIONE SOFTWARE

Utilizzando il monitor seriale del programma IDE dell'Arduino e' possibile inviare una serie di comandi per controllare il regolatore. Al tempo stesso e' possibile visualizzare messaggi di stato e di warning provenienti dalla scheda Arduino in funzione dello stato del regolatore e di eventuali allarmi. I comandi sono:

a : accensione del regolatore al valore di regolazione fissato dal comando rxxx. Alla prima accensione bisogna aver impostato prima il valore di regolazione tramite il comando rxxx - il segnale SS e' settato HIGH;

s : spegnimento del regolatore. Il valore di regolazione e' messo a zero mentre il valore impostato tramite il comando rxxx non viene perso ma memorizzato perché usato alla successiva accensione - il segnale SS e' settato LOW;

o : setta il verso di rotazione orario. Nel cambio di rotazione il motore e' stoppato e poi riportato al valore di regolazione attuale - il segnale ROT e' settato HIGH;

l : setta il verso di rotazione anti-orario. Nel cambio di rotazione il motore e' stoppato e poi riportato al valore di regolazione attuale - il segnale ROT e' settato LOW;

rxxx: imposta il valore di regolazione: xxx e' la percentuale di regolazione che può variare da 0 a 100; Quindi impostare il valore di regolazione senza aver mandato il comando di start non ha nessun effetto se non di aggiornare il valore di regolazione reso attivo solo dal comando di accensione.

q: ritorna lo status del motore, verso di rotazione e livello di regolazione attuale;

Ecco il codice per Arduino che può essere scaricato tramite il seguente link: Drive_MST_K16S.zip Tramite l'interfaccia seriale del programma IDE di Arduino si inviano i comandi alla scheda che li traduce in comandi per il MST_K16S:

/*PROGRAMMA CONTROLLO DEL REGOLATORE MST_K16 TRAMITE INTERFACCIA SERIALE BIDIREZIONALE
 Codice per pilotaggio del regolatore di velocità MST_K16S tramite arduino MEGA 2560. Il regolatore potrà
essere
controllato inviando comandi tramite il monitor seriale della IDE dell'arduino con velocita settata a 9600.
 I comandi accettati sono i seguenti:

 a -  accende il MOTORE
 s -  spenge il MOTORE
 o -  imposta la rotazione oraria
 l -  imposta la rotazione anti-oraria
 q - richiede lo stato del MOTORE.
 rxxx - scrive un valore di regolazione in %. Possibili
 valori per "xxx" vanno da 0 a 100. Gli spazi sono ignorati.
 I caratteri accettati sono solo quelli numerici (da 0 a 9).
 In caso di attivazione di uno dei fine corsa vien visualizzato un messaggio di warning
*/

//pin
const byte vcnt = 13; //pin di output pwm
const int SST = 31; // pin di output: start = 1 stop =0
const int ROT = 51; //pin di output: rotazione orario = 1 antiorario = 0  
const int OUT_O = A15; //pin di input : feedback  finecorsa orario
const int OUT_A = A14; //pin di input : feedback  finecorsa anti-orario


//variabili globali
byte regolazione = 0;  //contiene il valore in % del pwm sul pin 13
int start =0;          // abilita la accensione del regolatore
int rot =0;
void setup() {
 pinMode(vcnt,OUTPUT);
 pinMode(SST,OUTPUT);
 pinMode(ROT,OUTPUT);  
 pinMode(OUT_A,INPUT_PULLUP);
 pinMode(OUT_O,INPUT_PULLUP);
 
 analogWrite(vcnt, regolazione);
 Serial.begin(9600); // apro la seriale
 delay(1000); //attendo che l'utente faccia altrettanto
 Serial.println(F("Interfaccia Seriale Pronta ")); //sono pronto
 Serial.println(F(" a= accensione; s= spegnimento; rxxx = regolazione al xxx%; o= orario; l= antiorario;
q= status motore"
));
 
}

//programma principale
void loop() {
 int lettura; //contiene il valore di PWM letto dalla seriale
 unsigned long tempMillis; //serve per il timeout sulla ricezione del valore di PWM
 byte caratteri; //contiene il numero di caratteri ricevuti
 byte tempChar; //contiene il carattere letto
if (digitalRead(OUT_A) == LOW)  {Serial.println(F(" fine corsa anti orario attivato, motore fermo"));}
if (digitalRead(OUT_O) == LOW)  {Serial.println(F(" fine corsa orario attivato, motore fermo"));}
while (digitalRead(OUT_A) == LOW || digitalRead(OUT_O) == LOW ) {;}
 //controllo se c'è qualcosa in arrivo sulla seriale
 if (Serial.available()) {
   byte command = Serial.read(); //leggo il primo byte
   switch (command) { //controllo che sia un comando valido
     case 'a': //accendo il MOTORE
       //;regolazione = 100;
       start =1;
       analogWrite(vcnt, start*regolazione*255/100);
       digitalWrite(SS,HIGH);
       Serial.print(F("MOTORE"));
       Serial.print(F(" acceso con regolazione al "));
       Serial.print(regolazione, DEC);
       Serial.println("%");
       break;
     case 's': //spengo il MOTORE
       start=0;
       analogWrite(vcnt, 0);
       digitalWrite(SS,LOW);
       Serial.println(F("MOTORE spento"));
       break;
     case 'o': //setta verso orario
       rot=1;
       digitalWrite(ROT,HIGH);
       Serial.println(F("rotazione oraria"));
       break;
     case 'l': //setta verso anti orario
       rot=0;
       digitalWrite(ROT,LOW);
       Serial.println(F("rotazione anti-oraria"));
       break;
     case 'q': //l'utente vuole lo stato del MOTORE
       Serial.print(F("MOTORE "));
       if (start == 0) {
         Serial.print(F("spento"));
       } else if (start == 1) {
         Serial.print(F("acceso"));
       }
         Serial.print(F(" regolazione al "));
         Serial.print(regolazione, DEC);
         Serial.print("%");
         Serial.print(F(" rotazione "));
          if (rot == 0) {
         Serial.println(F("anti oraria"));
       } else if (rot == 1) {
         Serial.println(F("oraria"));
       }
       break;
     case 'r': //imposto il PWM sul MOTORE
       lettura = 0;
       tempMillis = millis();
       caratteri = 0;
       //mi servono altri caratteri
       do {
         if (Serial.available()) {
           tempChar = Serial.read();
           caratteri++;
           if ((tempChar >= 48) && (tempChar <= 57)) { //è un numero? ok
             lettura = (lettura * 10) + (tempChar - 48);
           } else if ((tempChar == 10) || (tempChar == 13)) {
             //con invio e/o nuova linea esco
             break;
           }
         }
         //esco per timeout, per un valore di PWM maggiore di 255
         //oppure per troppi caratteri senza senso ricevuti
       } while ((millis() - tempMillis < 500) && (lettura <= 100) && (caratteri < 10));
       //se il valore di PWM è valido, lo imposto sul pin
       if (lettura <= 100) {
         regolazione = lettura;
         analogWrite(vcnt, start*regolazione*255/100);
         Serial.print(F("regolazione impostata a "));
         Serial.print(regolazione, DEC);
         Serial.println("%");
        }
       break;
   }
   //svuoto il buffer da eventuali altri caratteri che non mi servono più
   while (Serial.available()) {
     byte a = Serial.read();
   }
 }
}