Go Down

Topic: [Risolto] Fermare un ciclo For in uno Switch Case (Read 952 times) previous topic - next topic

Gianca

Jan 06, 2012, 02:24 pm Last Edit: Jan 06, 2012, 03:28 pm by Gianca Reason: 1
Ciao a tutti, sono nuovo del forum e di Arduino in generale. Mi sono avvicinato ad Arduino per sbaglio ma ora mi sto appassionando sempre più. Purtroppo non sono ne un esperto di elettronica ne un programmatore, per cui mi ogni mio progetto è generalmente il frutto di molti taglia e cuci, sia a livello hardware che a livello software. Fortunatamente il forum ed in generale internet sono ricchi di spiegazioni e buoni esempi pratici. Tuttavia nonostante stia provando già da qualche giorno non riesco a venire a capo di un problema:

Hardware: Arduino Uno + Ethernet Shield
IDE: Arduino 1.0

Lo sketch di seguito mi serve per accendere 2 LedStripe RGB in soggiorno, le quali sono alimentate separatamente e possono quindi dare colori diversi contemporaneamente.
Attraverso Ardumote (applicativo per IPAD) mando all'ethernet shield dei caratteri, i quali vengono letti dallo sketch e posto in una variabile (var). La quale comanda uno Switch Case.
Ad ogni lettera inviata ad arduino corrisponde un "case" diverso.
Alcuni "case" accendono semplicemente tutti i led in bianco, altri case accendono i led con colori o intensità diversi un case spegne tutto. E fino qua tutto bene, in quanto in questi "case" i comandi non hanno bisogno di ciclicità, si limitano ad accendere o spegnere.
Il problema si pone nei Case Q o R i quali dovrebbero continuare a fare loop finchè io non premo un tasto su Ardumote mandando quindi un "carattere" via ethernet.

Ho provato in tutti i modi, ma nel momento in cui uno dei due cicli for (Q o R) partono non vi è più modo di fermarli se non spegnendo e riaccendendo Arduino.

Probabilmente la soluzione è sotto al mio naso, ma io non riesco proprio a trovarla, se qualcuno di voi avesse voglia di darmi la soluzione gliene sarei enormemente grato.

Premetto che ho già cercato sia su questo forum che su internet ma non riesco a trovare soluzioni funzionanti.
PS ho cancellato alcuni "case" in quanto il messaggio era troppo lungo.

Code: [Select]
#include <SPI.h>
#include <EthernetUdp.h>
#include <Ethernet.h>
#include <SoftPWM.h>

byte mac[] = {
 0x90, 0xA2, 0xDA, 0x00, 0x9B, 0x30 };
byte ip[] = {
 10,189,136,62 };
unsigned int localPort = 1337;

int LED_PinR = 4;
int LED_PinG = 2;
int LED_PinB = 3;
int LED_PinRx = 7;
int LED_PinGx = 5;
int LED_PinBx = 6;

int var;

float RGB1[3];
float RGB2[3];
float RGB3[3];
float RGB4[3];
float INC1[3];
float INC2[3];

int red1, green1, blue1;
int red2, green2, blue2;

char packBuff[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,

EthernetUDP Udp;

void setup() {

 SoftPWMBegin();

 SoftPWMSet(LED_PinR, 0);
 SoftPWMSet(LED_PinG, 0);
 SoftPWMSet(LED_PinB, 0);
 SoftPWMSet(LED_PinRx, 0);
 SoftPWMSet(LED_PinGx, 0);
 SoftPWMSet(LED_PinBx, 0);

 SoftPWMSetFadeTime(ALL, 1000, 1000);

 Ethernet.begin(mac);
 Udp.begin(localPort);

 Serial.begin(9600);

 randomSeed(analogRead(0));
 RGB1[0] = 0;
 RGB1[1] = 0;
 RGB1[2] = 0;
 RGB2[0] = random(256);
 RGB2[1] = random(256);
 RGB2[2] = random(256);
 RGB3[0] = 0;
 RGB3[1] = 0;
 RGB3[2] = 0;
 RGB4[0] = random(256);
 RGB4[1] = random(256);
 RGB4[2] = random(256);

}

void loop()
{

 int pwmValR;
 int pwmValG;
 int pwmValB;

 int packetSize = Udp.parsePacket();
 if(packetSize)
   //Serial.print(packetSize);
 {
   packetSize = packetSize - 8;
   Serial.print("Packet size: ");
   Serial.println(packetSize);

   Udp.read(packBuff,UDP_TX_PACKET_MAX_SIZE);
   Serial.println("Message: ");
   Serial.println(packBuff);

   var = (packBuff[0]);
   pwmValR = (packBuff[1] - '0')*100 + (packBuff[2] - '0')*10 + (packBuff[3] - '0');
   pwmValG = (packBuff[1] - '0')*100 + (packBuff[2] - '0')*10 + (packBuff[3] - '0');
   pwmValB = (packBuff[1] - '0')*100 + (packBuff[2] - '0')*10 + (packBuff[3] - '0');

   switch(var){

   case 'A':  // FADE ON
     {
       SoftPWMSetPercent(LED_PinR, 100);    
       SoftPWMSetPercent(LED_PinG, 100);
       SoftPWMSetPercent(LED_PinB, 100);
       SoftPWMSetPercent(LED_PinRx, 100);    
       SoftPWMSetPercent(LED_PinGx, 100);
       SoftPWMSetPercent(LED_PinBx, 100);
       delay(1200);
       break;  
     }


   case 'P': // Colore presettato 3
     {
       SoftPWMSet(LED_PinR,200);
       SoftPWMSet(LED_PinG,100);
       SoftPWMSet(LED_PinB,50);
       SoftPWMSet(LED_PinRx,200);
       SoftPWMSet(LED_PinGx,100);
       SoftPWMSet(LED_PinBx,50);
       delay(1200);
       break;
     }  

   case 'Q':  //Rotazione tra colori
     {
       for (int i = 0; i > -1; i ++)
       {
         SoftPWMSet(LED_PinR,100);
         SoftPWMSet(LED_PinG,0);
         SoftPWMSet(LED_PinB,100);
         SoftPWMSet(LED_PinRx,100);
         SoftPWMSet(LED_PinGx,0);
         SoftPWMSet(LED_PinBx,100);
         delay(2000);
         SoftPWMSet(LED_PinR,100);
         SoftPWMSet(LED_PinG,0);
         SoftPWMSet(LED_PinB,0);
         SoftPWMSet(LED_PinRx,100);
         SoftPWMSet(LED_PinGx,0);
         SoftPWMSet(LED_PinBx,0);
         delay(2000);
         SoftPWMSet(LED_PinR,0);
         SoftPWMSet(LED_PinG,100);
         SoftPWMSet(LED_PinB,0);
         SoftPWMSet(LED_PinRx,0);
         SoftPWMSet(LED_PinGx,100);
         SoftPWMSet(LED_PinBx,0);
         delay(2000);
         SoftPWMSet(LED_PinR,0);
         SoftPWMSet(LED_PinG,0);
         SoftPWMSet(LED_PinB,100);
         SoftPWMSet(LED_PinRx,0);
         SoftPWMSet(LED_PinGx,0);
         SoftPWMSet(LED_PinBx,100);
         delay(2000);
         SoftPWMSet(LED_PinR,100);
         SoftPWMSet(LED_PinG,100);
         SoftPWMSet(LED_PinB,100);
         SoftPWMSet(LED_PinRx,100);
         SoftPWMSet(LED_PinGx,100);
         SoftPWMSet(LED_PinBx,100);
         delay(2000);        
       }
     }

   case 'R':  // RANDOM
     {

       for (int i = 0; i > -1; i = i ++)
       {  
         randomSeed(analogRead(0));

         for (int x=0; x<3; x++) {
           INC1[x] = (RGB1[x] - RGB2[x]) / 256;
           INC2[x] = (RGB3[x] - RGB4[x]) / 256;
         }

         for (int x=0; x<256; x++) {

           red1 = int(RGB1[0]);
           green1 = int(RGB1[1]);
           blue1 = int(RGB1[2]);
           red2 = int(RGB3[0]);
           green2 = int(RGB3[1]);
           blue2 = int(RGB3[2]);

           SoftPWMSet (LED_PinR, red1);
           SoftPWMSet (LED_PinG, green1);
           SoftPWMSet (LED_PinB, blue1);
           SoftPWMSet (LED_PinRx, red2);
           SoftPWMSet (LED_PinGx, green2);
           SoftPWMSet (LED_PinBx, blue2);

           delay(150);

           RGB1[0] -= INC1[0];
           RGB1[1] -= INC1[1];
           RGB1[2] -= INC1[2];
           RGB3[0] -= INC2[0];
           RGB3[1] -= INC2[1];
           RGB3[2] -= INC2[2];
         }

         for (int x=0; x<3; x++) {
           RGB2[x] = random(556)-300;
           RGB2[x] = constrain(RGB2[x], 0, 255);
           RGB4[x] = random(556)-300;
           RGB4[x] = constrain(RGB4[x], 0, 255);

           delay(10000);
         }
       }
     }
     break;

   case 'S': // Luce Soft 30%
     {
       SoftPWMSetPercent(LED_PinR, 30);    
       SoftPWMSetPercent(LED_PinG, 30);
       SoftPWMSetPercent(LED_PinB, 30);
       SoftPWMSetPercent(LED_PinRx, 30);    
       SoftPWMSetPercent(LED_PinGx, 30);
       SoftPWMSetPercent(LED_PinBx, 30);
       delay(1200);
       break;    
     }
   }
 }
}/code]

bigjohnson

Il problema è che il loop principale di q e r da sempre vero
i è sempre > di -1 se continui ad incrementarla, e questo blocca il programma.
Devi implementare le due funzioni in modo non bloccante.
Ciao.

Alberto

Gianca

Grazie per la pronta risposta, ma come premesso non sono molto esperto di C e programmazione. Quindi, non è che potresti spiegarmi, magari con un esempio pratico come fare ?
Calcola che io vorrei che il loop andasse all'infinito finchè io dal mio ipad attraverso Ardumote non gli lancio un comando per fermarlo o per cambiare per esempio "case".

Che la funzione for al momento è solo incrementale lo so, l'ho messa così perchè non sapevo vome altro fare per far andare avanti all'infinito quei "case".

Ciao


bigjohnson

puoi provare a mettere
Code: [Select]
int packetSize = Udp.parsePacket();
  if(packetSize) {
         break;
}

prima della parentesi di chiusura dei cicli for di q e r
Non ho mai usato udp come protocollo, ma penso che funzioni.
In questo modo l'arrivo di un comando sblocca il ciclo for.

paolo_fiorini3

ti rispondo un attimo di corsa ma purtroppo devo uscire...purtroppo nn conosco bene la libreria UDP ma a livello di logica potresti fare :

Code: [Select]
switch(var){
....
    case 'Q' : for(){
                    fai tutte le tue operazioni
                    if(è arrivato un nuovo pacchetto == true) break;
                 }
....
}


in serata poi rileggo il post per vedere come è andata...

Gianca

#5
Jan 06, 2012, 03:26 pm Last Edit: Jan 06, 2012, 03:30 pm by Gianca Reason: 1
FUNZIONA, GRAZIE bigjohnson !!

non hai idea di quanto tempo ci ho perso dietro... ti offrirei volentieri una birra, spero tu ne possa accettare una virtuale :)

Grazie anche a Paolo, mi pare di capire che le due soluzioni sono praticamente identiche... la birra offro ad entrambi.

Ho modificato il titolo del post con un [Risolto] davanti, spero di aver fatto cosa buona e giusta. Più tardi perfeziono il codice e lo posto, sia mai che a qualcuno possa servire.

Ciao e grazie di nuovo.

Go Up