Problemi di calcolo...... float .. double???? bho!

Questo fine settimana ho lavorato al mio primo progetto con l'arduino Uno... sto realizzando un CW beacon, ovvero un automatismo che invia via radio una frase in codice morse ad intervalli regolari. Ci stavo lavorando con un altro sistema ma adesso con l'arduino è tutta unaltra cosa. ma veniamo a noi:

questo è il codice che ho già scritto ieri:

// personalizzazione
int intervallo = 5 * 1000; // 5 è l'intervallo in secondi tra una trasmissione e l'altra...in realtà dovrà essere dell'ordine dei minuti
int velocita = 30 ; // velocità di manipolazione in caratteri al minuto
String messaggio = "CQ CQ de IS0CFU IS0CFU etc etc"; // stringa da trasmettere
// fine personalizzazione

int lMax = 14 ; // n° di caratteri max da visulaizzare sull'LCD

int nChar = 40; // n° di caratteri di cui si compone il codice morse (lettere, numeri, punteggiatura e qualche altro segno, vedi caratteri_alfab[] e caratteri_morse[]
char   caratteri_alfab [] = { 'A'  , 'B'   , 'C'   , 'D'  , 'E' , 'F'   , 'G'  , 'H'  , 'I' , 'J'   , 'K'  , 'L'   , 'M' ,'N'  , 'O'  , 'P'   , 'Q'   , 'R'  , 'S'  , 'T', 'U'  , 'V'   , 'W'  , 'X'  ,  'Y'  , 'Z'   ,  '0'   ,  '1'   ,  '2'   ,  '3'   ,  '4'   ,  '5'   ,'6'     ,'7'     , '8'    ,'9'     ,'.'       ,','       ,'?'      , ' ' };
String caratteri_morse [] = { ".-" , "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--","-..-", "-.--", "--..", "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.", ".-.-.-", "--..--","..--..", " "};

String chrMorse;
 
const int ledPin =   13;      // the number of the LED pin
const int tonePin =  11;      // the number of the tone pin

void setup()
{
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);      
  pinMode(tonePin, OUTPUT);      
}

void stampa_seriale(String pm, char l, String m){ Serial.print(pm); Serial.print(" "); Serial.print(l); Serial.print(" "); Serial.print (m); Serial.println();}// serve solo per fare i controlli durantelo sviluppo
void stampa_lcd    (String pm, char l, String m){}// da sviluppare in un secondo tempo, dopo verificato che funziona bene tutto

void trova_chrMorse (char l){ for( int i = 0; i < nChar; i++){if (l == caratteri_alfab [i]){chrMorse = caratteri_morse[i];}}} // trova la stringa morse corrispondente al carattere l e la pone in chrMorse


void digita_chrMorse (String m)
{
  
int tempo = int(60*1000) / ( 20 * float(velocita)) ;
tempo = 100;

Serial.print(tempo);
 
char segno;

for(int i = 0; i < m.length(); i++)
      {
       segno = m.charAt(i);
       switch (segno)
        {
        case '.':
        Serial.print('.');
        digitalWrite(ledPin, HIGH); tone(11, 1000); delay (1*tempo); digitalWrite(ledPin, LOW); noTone(11); delay (2*tempo);  
        break;

        case '-':
        Serial.print('-');
        digitalWrite(ledPin, HIGH); tone(11, 1000); delay (3*tempo);  digitalWrite(ledPin, LOW); noTone(11); delay (2*tempo);  
        break;
 
        case ' ':
        Serial.print(' ');
        delay (5*tempo);
        break;
        }
      }
      Serial.println();
      delay (7*tempo);
 }


void loop()
{
  char lettera ;
  String parte_messaggio ;
  messaggio = messaggio.toUpperCase(); // trasforma tutto in maiuscolo

    for(int i = 0; i < messaggio.length(); i++)
      {
        lettera=messaggio.charAt(i);
        parte_messaggio = parte_messaggio + lettera;
        if (parte_messaggio.length() > lMax ){parte_messaggio = parte_messaggio.substring (parte_messaggio.length()-lMax );}; //taglia la parte di messaggio già trasmesso agli ultimi lMax caratteri. Per poter visualizzare sull'LCD - max 16 caratteri
        trova_chrMorse (lettera);

        //stampa_seriale (parte_messaggio, lettera, chrMorse); //invia i dati per il controllo durante lo sviluppo
        //stampa_lcd     (parte_messaggio, lettera, chrMorse); // invia i dati all'LCD
 
        digita_chrMorse(chrMorse); 
     }

delay (intervallo);
}

La prima domanda è la seguente: come mai la seguente espressione

int tempo = int(60*1000) / ( 20 * float(velocita)) ;

mi dà sempre come risultatao (mi pare) -27 ... mentre invece dovrebbe dare 100 posto che velocità e pari a 30??
ho provato in ntutti modi, variabile double, float, dentro la funzione, fuori etc.. pare che la divisione proprio non gli vada bene... spiegatemi un poco..

altra domanda:
per prelevare il tono da 1000 Hz dal piedino 11 come devo fare... perchè ho provato semplicemente con un piccolo auricolare ma non c'era nulla.. o forse c'è qualcosa di sbagliato nel codice? .. oppure l'ampiezza del segnale è così bassa da essere impercettibile senza amplificazione?... bho!!!!

altra domanda?
cè qualche suggerimento per otimizzare il codice?.. per esempio
per associare la giusta stringa di caratteri (punto - linea) alla generica lettera dell'alfabeto uso un ciclo for per scorrere l'array e quando trovo la lettera uso l'indice per leggere la stringa morse.. in questo modo:

void trova_chrMorse (char l){ for( int i = 0; i < nChar; i++){if (l == caratteri_alfab [i]){chrMorse = caratteri_morse[i];}}} // trova la stringa morse corrispondente al carattere l e la pone in chrMorse

cè qualche sistema per otimizzare questa funzione.. non è che è meglio utilizzare una struttura tipo "switch case" ... se qualcuno vuole dermi la propia opinione .. ne farò tesoro.. grazie..

per la prima domanda basta che aggiungi .0 alla fine dei numeri, atrimenti avviene un cast automatico a int che "taglia" i numeri con la virgola e ti sfasa il conto.

Per la seconda domanda, mi son basato su questa tabella: radiomarconi.com - Panduan Menang Judi Online Indonesia

Allora dividi la tabella in baseal numero di segnali, ottenendo credo 5 tabelle. Già così hai (idealmente, ovvero se ogni tabella fosse composta dallo stesso numero di elementi) diviso in 5 il costo computazionale. Altra sotto scrematura può essere dividere le tabelle in ulteriori tabelle in base se iniziano con la riga o con il punto. Così hai 10 tabelle di 5 o 6 elementi idealmente, poi in relatà ci sara 1 elemento nella prima tabella e 12 nell'ultima, se non erro. Comunque saranno molto più veloci da sfogliare di una sola grossa tabella di 50 e passa elementi.

Carina l'idea, poi come trasmetti/ricevi il messaggio?

Grazie lesto....

il primo problema l'ho già risolto in altro modo... per l'ottimizzazione della ricerca del codice associato alla lettera ci penso un poco...

in realtà il prototipo l'ho già finito e fatto funzionare ieri...
questo è il codice, che ha funzionato ieri per la prima volta,

// personalizzazione
int intervallo = 10 * 1000; // 10 è l'intervallo in secondi tra una trasmissione e l'altra...in realtà dovrà essere dell'ordine dei minuti
int velocita = 25 ; // velocità di manipolazione in caratteri al minuto, molto approssimativamente
String messaggio = "test      test IS0CFU IS0CFU test Abcdefghilmnopqrs 1234567890"; // stringa da trasmettere
// fine personalizzazione


#include <LiquidCrystal.h>
int lMax = 16 ; // n° di caratteri max da visulaizzare sull'LCD

int nChar = 39; // n° di caratteri di cui si compone il codice morse (lettere, numeri, punteggiatura e qualche altro segno, vedi caratteri_alfab[] e caratteri_morse[]
char   caratteri_alfab [] = { 'A'  , 'B'   , 'C'   , 'D'  , 'E' , 'F'   , 'G'  , 'H'  , 'I' , 'J'   , 'K'  , 'L'   , 'M' ,'N'  , 'O'  , 'P'   , 'Q'   , 'R'  , 'S'  , 'T', 'U'  , 'V'   , 'W'  , 'X'  ,  'Y'  , 'Z'   ,  '0'   ,  '1'   ,  '2'   ,  '3'   ,  '4'   ,  '5'   ,'6'     ,'7'     , '8'    ,'9'     ,'.'      ,','      ,'?'     };
String caratteri_morse [] = { ".-" , "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--","-..-", "-.--", "--..", "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.", ".-.-.-", "--..--","..--.."};

String chrMorse;
 
const int onRadio =  9;      // accende la radio
const int digitCW =  8;      // digita il morse
const int tonePin =  7;      // the number of the tone pin

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
  pinMode(onRadio, OUTPUT);  
  pinMode(digitCW, OUTPUT);   
  pinMode(tonePin, OUTPUT);      
  lcd.begin(16, 2);
  Serial.begin(9600);
}

void stampa_seriale(String pm, char l, String m){ Serial.print(pm); Serial.print(" "); Serial.print(l); Serial.print(" "); Serial.print (m); Serial.println();}// serve solo per fare i controlli durantelo sviluppo

void stampa_lcd (String pm, char l, String m)
{
  lcd.setCursor(0, 0);
  lcd.print("                ");
  lcd.setCursor(0, 0);
  lcd.print(pm);

  m = m.substring(0, m.length()-1) ;
  lcd.setCursor(2, 1);
  lcd.print("             ");
  lcd.setCursor(2, 1);
  lcd.print(l); lcd.print("  "); lcd.print(m);
}

void trova_chrMorse (char l)
{
  if ( l != ' ' ) 
  { 
    for( int i = 0; i < nChar; i++)
      {
        if (l == caratteri_alfab [i])
          {chrMorse = caratteri_morse[i] + 'z'; break;}
       }   
   }
else
{ chrMorse = ' ' ;}

} // trova la stringa morse corrispondente al carattere l e la pone in chrMorse


void digita_chrMorse (String m)
{
  
int tempo = int(2000 / velocita) ;

//Serial.print(tempo);
 
char segno;

for(int i = 0; i < m.length(); i++)
      {
       segno = m.charAt(i);
       switch (segno)
        {
        case '.':
        //Serial.print('.');
        digitalWrite(digitCW, HIGH); tone(7, 1000); delay (1*tempo); digitalWrite(digitCW, LOW); noTone(7); delay (1*tempo);  
        break;

        case '-':
        //Serial.print('-');
        digitalWrite(digitCW, HIGH); tone(7, 1000); delay (3*tempo);  digitalWrite(digitCW, LOW); noTone(7); delay (1*tempo);  
        break;
 
        case 'z':
        //Serial.print("fine lettera");
        delay (5*tempo);
        break;

        case ' ':
        //Serial.print("fine parola");
        delay (7*tempo);
        break;
        }
      }
      //Serial.println();
 }


void loop()
{
  digitalWrite(onRadio, HIGH);
 char lettera ;
  String parte_messaggio ;
  messaggio = messaggio.toUpperCase(); // trasforma tutto in maiuscolo

    for(int i = 0; i < messaggio.length(); i++)
      {
        lettera=messaggio.charAt(i);
        parte_messaggio = parte_messaggio + lettera;
        if (parte_messaggio.length() > lMax ){parte_messaggio = parte_messaggio.substring (parte_messaggio.length()-lMax );}; //taglia la parte di messaggio già trasmesso agli ultimi lMax caratteri. Per poter visualizzare sull'LCD - max 16 caratteri
        trova_chrMorse (lettera);

        stampa_seriale (parte_messaggio, lettera, chrMorse); //invia i dati per il controllo durante lo sviluppo
        stampa_lcd     (parte_messaggio, lettera, chrMorse); // invia i dati all'LCD
 
        digita_chrMorse(chrMorse); 
     }
digitalWrite(onRadio,LOW);
delay (intervallo);
}

che devo comunque ancora otimizzare......

per la trasmissione si procede così: tramite il segnale del piedino 9 si commuta la radio in trasmisioone, mentre con il segnale del piedino 8 si invia la manipolazione del codice... sul display lcd visualizzo gli ultimi 16 caratteri inviati (sulla prima riga) e il carattere e la corrispondente stringa morse (in fase di digitazione, sulla seconda riga)... utilizzo un ICOM IC 735 o un KENWOOD almeno adesso per le prove

.. si posso anche ricevere , ma questo non mi interessa poichè voglio realizzare un piccolo trasmettitore da 1 w (beacon) che trasmetta fisso 24/24 ore ad intervalli di 15 minuti .. (bada bene che lo possono fare solo i radiomatori ... io ho la licenza).. i radioamatori che ricevono, da tutto il mondo ti confermano la ricezione con una cartolina QSL, questa è la funzione di una stazione beacon .. anche per sperimentare e verificare la propazione delle onde radio in ogni parte del globo ....

aspetto suggerimenti sull'ottimizzazione del codice.. saluti

ah ho visto qualcosa in giro(sempre su arduino), si usano basse frequenze che con pochi watt fanno anche il giro di mezzo mondo, giusto?

Per la licenza mi piacerebbe ottenerla per dei lavori per cui mi servirebbero le frequenze "non standard" (la 1 giga e qualcosa), sai darmi qualche informazione?

sinceramente per il codice che hai ti sconsiglio una ottimizzazione spinta, piuttosto tieni il codice leggibile e pulito, non credo che l'arduino abbia problemi a svolgerlo anche se andasse a 8mhz(senza cristallo esterno)

Ciao lesto.. e grazie per l'attenzione...
si... le frequenze utilizzabili sono le HF.. sotto i 30 Mhz diciamo... rigorosamente dentro le bande ammesse (7.000 Mhz), (14.000 Mhz) etc. .. per lavorare a frequenze così elevate come dici tu, è molto difficile... sono pochissimi anche i radioamatori che usano frequenze oltre la UHF perche l'autocostruzione è difficile, ci vuole attrezzatura professionale con costi proibitivi, e molta competenza ...

... per la licenza si deve fare un esame presso il competente servizio territoriale del ministero delle comunicazioni .. a meno che tu non abbia un titolo di studio tipo perito elettronico, specializzato in telecomunicazioni o qualcosa di simile....

per l'ottimizzazoine del software, comunque lo lascerò leggibile appieno voglio eliminare i delay ed utilizzare un controllo con il millis(), così recupero il ritardo che si verifica nell'esecuzione del codice ... e quando gli dò la velocità questa corrisponda alla effettiva velocità di digitazione ..

.. non so se merendo ...

inoltre non ho capito se si opssono usare matrici bidimensionali ... e se così potrei ottimizzare ulteriormente ... ma paino piano.. intanto stiamo sperimentando... comunque sto aprendo un altro tread su un nuovo progetto... dammi la tua opinione...

per l'ottimizzazoine del software, comunque lo lascerò leggibile appieno voglio eliminare i delay ed utilizzare un controllo con il millis(), così recupero il ritardo che si verifica nell'esecuzione del codice ... e quando gli dò la velocità questa corrisponda alla effettiva velocità di digitazione ..

sto facendo una cosa simile per i segnali PPM, penso di uare il c++, una classe generale GestorePin, ogni pin ne avrà una, a cui posso dire scrivi questo seganale o dammi il seganle letto. Il vantaggio è che ogni ciclo chiamo solo un metodo (=funzione) update() che fa i controlli con millis() e cambia i sui valori interni (valore da scrivere /leggere, che vengono settati con metodi a parte, fa molto parallelismo ::slight_smile: ).

inoltre non ho capito se si opssono usare matrici bidimensionali

certo che puoi! anche tri-quadri-ecc... tutta questione di puntatore a puntatore a puntatore a puntatore a puntatore