Go Down

Topic: riproduzione melodia solo se il LED è acceso.. si può?! (Read 2195 times) previous topic - next topic

uwefed

Buona idea leo, non ci sarei arrivato ....   ;) ;) ;)

La soluzione pulita é modificare la libreria (o copiare la funzione che suona il pezzo nello sketch) in modo che a ogni nota si controlla se il flag di suonare o stoppare é settato e spegnere il suono e memorizzare la posizione del brano. Dopo quando il flag cambia riprender a quel punto oppure se si vuole partire con un altro o ripartire con lo stesso ecc.

Ciao Uwe

leo72

Difatti appoggiavo la tua idea. I metodi "rustici" non sono carini.

Nik_90


Buona idea leo, non ci sarei arrivato ....   ;) ;) ;)

La soluzione pulita é modificare la libreria (o copiare la funzione che suona il pezzo nello sketch) in modo che a ogni nota si controlla se il flag di suonare o stoppare é settato e spegnere il suono e memorizzare la posizione del brano. Dopo quando il flag cambia riprender a quel punto oppure se si vuole partire con un altro o ripartire con lo stesso ecc.

Ciao Uwe


Ah questa si che sarebbe una bella soluzione.. veramente elegante.. Forse però è troppo complicato o no?! Io speravo in qualcosa di più semplice all'inizio.. proprio come si era detto in precedenza...
tipo:
Code: [Select]

if ((note) & (luce>1))
...riproduci melodia...
else
..interrompi..


solo che in questo modo non va.. =(

qualcuno può linkarmi qualche documentazione su arduino e gli interrupt?! forse è l'unica cosa fattibile veramente..

lucadentella

Ciao

se vuoi stoppare la musica e non metterla in pausa, potresti pensare di aggiungere un controllo diretto tipo

if(luce >1) return;

in tal modo esci direttamente dalla funzione play_rtttl()

bye
lucadentella.it

Nik_90


Ciao

se vuoi stoppare la musica e non metterla in pausa, potresti pensare di aggiungere un controllo diretto tipo

if(luce >1) return;

in tal modo esci direttamente dalla funzione play_rtttl()

bye


cavolo è vero.. ascolta ma è normale che riproduce sempre la stessa nota quando il led è acceso?! Mi spiego:

ho fatto in questo modo:
Code: [Select]

  if((note) & (luce>1))
    {
      Serial.print("Playing: ");
      Serial.print(scale, 10); Serial.print(' ');
      Serial.print(note, 10); Serial.print(" (");
      Serial.print(notes[(scale - 4) * 12 + note], 10);
      Serial.print(") ");
      Serial.println(duration, 10);
      tone1.play(notes[(scale - 4) * 12 + note]);
      delay(duration);
      tone1.stop();
    }
    else
   
    {
    return;
    }
     
      Serial.print("Pausing: ");
      Serial.println(duration, 10);
      delay(duration);
   
  }


Ora infatti non appena ad esempio, la stanza è buia, il led si accende, lo speker inizaia a suonare. Appena accendo la luce, il led si spenge, lo speker smette di suonare.

E' quello che voglio io! Ma perchè quando dovrebbe suonare la melodia intera mi suona sempre la prima nota e non continua a fare il resto delle note?! :smiley-eek-blue:

Eppure la condizione di luce>1 dovrebbe far in modo che continuasse a prendersi le altre note e a suonarle... non capisco.. è normale questo fatto!?!

Grazie mille

leo72

#20
Sep 01, 2011, 08:26 pm Last Edit: Sep 01, 2011, 08:38 pm by leo72 Reason: 1
Il test è errato:
Code: [Select]
if((note) & (luce>1))

deve essere

Code: [Select]
if((note) && (luce>1))

Nik_90


Il test è errato:
Code: [Select]
if((note) & (luce>1))

deve essere

Code: [Select]
if((note) && (luce>1))


Usando l'AND logico il led non risponde come con il bitwise non ho capito perchè.. praticamente facendo tornare la luce nella stanza la melodia deve finire per poter far spegnere il led..

Usando invece il bitwise, (come prima), riponde perfettametne ai cambiamenti della fotoresistenza e quindi stacca a dovere.. solo che riproduce una sola nota..

Quest'ultimo errore forse dipenda proprio dal fatto che uso & e non && non credi?!

Grazie mille!

leo72

Un attimo. Ma non aggiorni il puntatore alla nota da suonare...

Nik_90


Un attimo. Ma non aggiorni il puntatore alla nota da suonare...


scusa ma non gestisce tutto la funzione play_rtttl(song) ?!? anche quindi l'indirizzo del prossimo puntatore da suonare?! Perchè se non metto quella condizione di luce>1 mi suona tutta la melodia tranquillamente.. solo che me la suona anche se ce luce in stanza.., quindi di continuo... e io non voglio questo..

leo72

Ma luce lo rileggi prima di quell'if? Non si potrebbe avere tutto il codice invece di quello spezzone?

(cmq il confronto si fa con &&, non con &. Se a te funziona, è per altri motivi, non perché è "giusto")

Nik_90


Ma luce lo rileggi prima di quell'if? Non si potrebbe avere tutto il codice invece di quello spezzone?

(cmq il confronto si fa con &&, non con &. Se a te funziona, è per altri motivi, non perché è "giusto")


ecco il codice completo:
Code: [Select]

#include <Tone.h>
#include <LiquidCrystal.h>
int controllo_lum(int);

// inizializzo display LCD
LiquidCrystal lcd (12, 11, 5, 4, 3, 2);


Tone tone1;

//setto i PIN
int photocellPin = 0;     // the cell and 10K pulldown are connected to a0
int photocellReading;     // the analog reading from the sensor divider
int LEDpin = 6;          // connect Red LED to pin 11 (PWM pin)
int LEDbrightness;

#define OCTAVE_OFFSET 0

int notes[] = { 0,
NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4,
NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5,
NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6,
NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7
};
//CANZONI DISPINIBILI IN RTTTL

char *song = "The Simpsons:d=4,o=5,b=160:c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g,8p,8p,8f#,8f#,8f#,8g,a#.,8c6,8c6,8c6,c6";
//char *song = "Indiana:d=4,o=5,b=250:e,8p,8f,8g,8p,1c6,8p.,d,8p,8e,1f,p.,g,8p,8a,8b,8p,1f6,p,a,8p,8b,2c6,2d6,2e6,e,8p,8f,8g,8p,1c6,p,d6,8p,8e6,1f.6,g,8p,8g,e.6,8p,d6,8p,8g,e.6,8p,d6,8p,8g,f.6,8p,e6,8p,8d6,2c6";

void setup(void)
{
 
  Serial.begin(9600);
  tone1.begin(7);          //porta a cui e connesso lo speaker
  lcd.begin(16, 2);        //setto colonne e righe display
   lcd.setCursor(0,0);      //setto il cursore sopra a sinistra
  lcd.print("CIAO");
}

void loop()
{
  photocellReading = analogRead(photocellPin); 

  //Serial.print("Analog reading = ");
  //Serial.println(photocellReading);     // the raw analog reading

  // LED gets brighter the darker it is at the sensor
  // that means we have to -invert- the reading from 0-1023 back to 1023-0

  photocellReading = 1023 - photocellReading;
  //now we have to map 0-1023 to 0-255 since thats the range analogWrite uses
 
  photocellReading = constrain(photocellReading, 600, 1023); //<-- il 970 potete cambiarlo

  LEDbrightness = map(photocellReading, 600, 1023, 0, 255);
 
  analogWrite(LEDpin, LEDbrightness);
  delay(100);
   play_rtttl(song);
  }
#define isdigit(n) (n >= '0' && n <= '9')

void play_rtttl(char *p)
{
  // Absolutely no error checking in here

  byte default_dur = 4;
  byte default_oct = 6;
  int bpm = 63;
  int num;
  long wholenote;
  long duration;
  byte note;
  byte scale;
  int luce;
  luce = LEDbrightness;

  // format: d=N,o=N,b=NNN:
  // find the start (skip name, etc)

  while(*p != ':') p++;    // ignore name
  p++;                     // skip ':'

  // get default duration
  if(*p == 'd')
  {
    p++; p++;              // skip "d="
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
    if(num > 0) default_dur = num;
    p++;                   // skip comma
  }

  Serial.print("ddur: "); Serial.println(default_dur, 10);

  // get default octave
  if(*p == 'o')
  {
    p++; p++;              // skip "o="
    num = *p++ - '0';
    if(num >= 3 && num <=7) default_oct = num;
    p++;                   // skip comma
  }

  Serial.print("doct: "); Serial.println(default_oct, 10);

  // get BPM
  if(*p == 'b')
  {
    p++; p++;              // skip "b="
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
    bpm = num;
    p++;                   // skip colon
  }

  Serial.print("bpm: "); Serial.println(bpm, 10);

  // BPM usually expresses the number of quarter notes per minute
  wholenote = (60 * 1000L / bpm) * 4;  // this is the time for whole note (in milliseconds)

  Serial.print("wn: "); Serial.println(wholenote, 10);


  // now begin note loop
  while(*p)
  {
    // first, get note duration, if available
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
   
    if(num) duration = wholenote / num;
    else duration = wholenote / default_dur;  // we will need to check if we are a dotted note after

    // now get the note
    note = 0;

    switch(*p)
    {
      case 'c':
        note = 1;
        break;
      case 'd':
        note = 3;
        break;
      case 'e':
        note = 5;
        break;
      case 'f':
        note = 6;
        break;
      case 'g':
        note = 8;
        break;
      case 'a':
        note = 10;
        break;
      case 'b':
        note = 12;
        break;
      case 'p':
      default:
        note = 0;
    }
    p++;

    // now, get optional '#' sharp
    if(*p == '#')
    {
      note++;
      p++;
    }

    // now, get optional '.' dotted note
    if(*p == '.')
    {
      duration += duration/2;
      p++;
    }
 
    // now, get scale
    if(isdigit(*p))
    {
      scale = *p - '0';
      p++;
    }
    else
    {
      scale = default_oct;
    }

    scale += OCTAVE_OFFSET;

    if(*p == ',')
      p++;       // skip comma for next note (or we may be at the end)

    // now play the note
   
   
   
    if((note) && (luce>1))
    {
      Serial.print("Playing: ");
      Serial.print(scale, 10); Serial.print(' ');
      Serial.print(note, 10); Serial.print(" (");
      Serial.print(notes[(scale - 4) * 12 + note], 10);
      Serial.print(") ");
      Serial.println(duration, 10);
      tone1.play(notes[(scale - 4) * 12 + note]);
      delay(duration);
      tone1.stop();
    }
    else
    {
    return;
   //Serial.print("Pausing: ");
   //Serial.println(duration, 10);
    //delay(duration);
    }
    }
   
  }



il controllo lo faccio proprio dove  si occupa di suaonare la nota..

Grazie!

leo72

Non so come funziona la Tone, il controllo dovrebbe funzionare.
Al max prova con
Code: [Select]
if (code && luce)
Cmq se non funziona forse una delle due variabili non ha un valore "true". Prova con un Serial.print a mandarne i valori sul terminale ed a verificare.

Nik_90


Non so come funziona la Tone, il controllo dovrebbe funzionare.
Al max prova con
Code: [Select]
if (code && luce)
Cmq se non funziona forse una delle due variabili non ha un valore "true". Prova con un Serial.print a mandarne i valori sul terminale ed a verificare.


Ciao, scusa ma sto avendo un po di confusione..xD che vuoi dire con:

al max prova con:
Code: [Select]
if (code && luce)

cioè non devo mettere la condizione di >1 ?!
Perchè se non riesco in quest'ultimo modo vedo di prendere un altra strada per risolvere qst problema.. anche se come si sta cercando di fare mi sembra il più immediato e semplice.. ma riscontro problemi.. =(..

Grazie mille !!!

leo72

In logica booleana un numero pari a 0 è un numero false, un qualunque valore pari a 1 o superiore equivale a true.
Tu scrivi:
if (tone && luce>1)

e già usi il modo di fare confronti che ti ho scritto perché
if (tone)
equivale a
if (tone>1)

quindi
if (tone && luce)
equivale a dire
se (tone > 1 && luce > 1)
e viceversa.

Hai stampato sulla seriale i valori delle variabili prima dell'if?

Nik_90


In logica booleana un numero pari a 0 è un numero false, un qualunque valore pari a 1 o superiore equivale a true.
Tu scrivi:
if (tone && luce>1)

e già usi il modo di fare confronti che ti ho scritto perché
if (tone)
equivale a
if (tone>1)

quindi
if (tone && luce)
equivale a dire
se (tone > 1 && luce > 1)
e viceversa.

Hai stampato sulla seriale i valori delle variabili prima dell'if?


Okok perfetto.. I valori ancora non li ho stampati perchè sono a lavoro ora.. appena rientro ci provo. Quindi devo stampare sulla seriale i valori di tone e luce?! Cmq per luce non dovrebbero esserci problemi.. perchè non è nient'altro che la luminosità del LED.. quindi se è completamente spento è uguale a 0.. se è poco poco acceso è alemno 1.. fino a 255.. invece per tone sinceramente non so come funzioni..
Una cosa, se in questo modo non dovesse funzionare? ci sarebbe qlk altra alternativa?! O meglio, di soluzioni se ne trovano sempre, ma un qualcosa di non troppo complesso.. Sono alle primissime armi come avrai potuto notare..xD

Grazie!

Go Up