Pages: 1 [2] 3 4   Go Down
Author Topic: riproduzione melodia solo se il LED è acceso.. si può?!  (Read 1740 times)
0 Members and 1 Guest are viewing this topic.
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 236
Posts: 20275
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buona idea leo, non ci sarei arrivato ....   smiley-wink smiley-wink smiley-wink

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
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21650
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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


Montalbano Jonico
Offline Offline
Sr. Member
****
Karma: 1
Posts: 284
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buona idea leo, non ci sarei arrivato ....   smiley-wink smiley-wink smiley-wink

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:
if ((note) & (luce>1))
...riproduci melodia...
else
..interrompi..

solo che in questo modo non va.. smiley-cry

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

Bergamo
Offline Offline
God Member
*****
Karma: 1
Posts: 663
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

lucadentella.it

Montalbano Jonico
Offline Offline
Sr. Member
****
Karma: 1
Posts: 284
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
  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
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21650
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

deve essere

Code:
if((note) && (luce>1))
« Last Edit: September 01, 2011, 01:38:35 pm by leo72 » Logged


Montalbano Jonico
Offline Offline
Sr. Member
****
Karma: 1
Posts: 284
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

deve essere

Code:
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!
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21650
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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


Montalbano Jonico
Offline Offline
Sr. Member
****
Karma: 1
Posts: 284
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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..
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21650
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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")
Logged


Montalbano Jonico
Offline Offline
Sr. Member
****
Karma: 1
Posts: 284
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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!
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21650
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Non so come funziona la Tone, il controllo dovrebbe funzionare.
Al max prova con
Code:
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.
Logged


Montalbano Jonico
Offline Offline
Sr. Member
****
Karma: 1
Posts: 284
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Non so come funziona la Tone, il controllo dovrebbe funzionare.
Al max prova con
Code:
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:
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.. smiley-cry..

Grazie mille !!!
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21650
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged


Montalbano Jonico
Offline Offline
Sr. Member
****
Karma: 1
Posts: 284
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
Logged

Pages: 1 [2] 3 4   Go Up
Jump to: