Arduino Forum

International => Italiano => Software => Topic started by: paolometeo2 on Aug 04, 2013, 09:51 am

Title: Maledette funzioni!!
Post by: paolometeo2 on Aug 04, 2013, 09:51 am
Help software!  Scusate il titolo  :0, ma mi sono imbattuto in uno di quei problemi software che i vari siti che spiegano il C non trattano o io non sono stato bravo nel cercare.
Si tratta del passaggio di un risultato calcolato in una funzione al programma chiamante per mezzo degli argomenti.  In breve il programmino di prova con la funzione è il seguente:
Code: [Select]

#include <math.h>

  float dis ;
void setup(){
  Serial.begin(9600);
   float la1 = 45.78956;
   float lo1 =  9.36424;
   float la2 = 45.78997;
   float lo2 =  9.36514;
   float direct;
   float dis =  Distance(la1, lo1, la2, lo2, direct);
  Serial.println(dis,DEC);
  Serial.println(direct,DEC);
}
void loop(){
 
}
////////////////////////////////////////////////////////////////////////
  static float Distance(float lat1, float lon1, float lat2, float lon2, float dir){
  float rt = 6371000;  // raggio terra in m
  float pi = 3.141592654;
  float coslat = cos((lat1+lat2)*pi/360);
  float dx = rt*(lon2-lon1)*coslat*pi/180;
  float dy = rt*(lat2-lat1)*pi/180;
  float dist = sqrt(dx*dx + dy*dy);
  dir = atan2(dx,dy);  // da -pi a +pi  artg(dx/dy)
  Serial.println(dir,DEC);
  return(dist);
  }
 

I valori da passare al main sono: "dist", che viene passato tramite il return, e "dir", che viene passato tramite gli argomenti.
I numeri che escono sono:
0.9900114059
83.4928741455
0.0000000000
a dimostrazione che il valore della variabile dir non viene passato al main.

P.S.
per i curiosi, sto costruendo un GPS+bussola.
Title: Re: Maledette funzioni!!
Post by: gpb01 on Aug 04, 2013, 10:15 am
Ciao Paolo,
un paio di domande ...

1. Passi la variabile float direct, ma non l'hai inizializzata quindi, probabilmente, vale sempre zero.

2. Sei conscio del fatto che il float su Arduino ha una scarsa precisione (solo 32 bit e che "Floats have only 6-7 decimal digits of precision. That means the total number of digits, not the number to the right of the decimal point." ) e NON è adatto a fare calcoli di distanze tramite coordinate GPS senza una enorme perdita di precisione ?

Quindi, ad esempio, totalmente inutile scrivere :
Code: [Select]
float pi = 3.141592654;
dato che la precisione è comunque al massimo di 6-7 cifre (leggi bene la nota in inglese ... "... total number of digits") !

Per inciso, se prima di stampare il valore aggiungessi una Serial.print con una descrizione del valore che stai stampando ... renderesti più  comprensibili i risultati ;)

Guglielmo
Title: Re: Maledette funzioni!!
Post by: astrobeed on Aug 04, 2013, 10:19 am

Help software!  Scusate il titolo  :0, ma mi sono imbattuto in uno di quei problemi software che i vari siti che spiegano il C non trattano o io non sono stato bravo nel cercare.
I numeri che escono sono:
0.9900114059
83.4928741455
0.0000000000
a dimostrazione che il valore della variabile dir non viene passato al main.


Premesso che questo calcolo richiede la matematica a 64 bit (double) che non è disponibile su Arduino, a meno che non ti accontenti di lavorare sulle grandi distanze con risoluzione kilometrica, dir non può essere restituito al main visto che la return è per dist, se dir deve essere disponibile anche al main allora deve essere una variabile globale.
Togli quello static alla funzione che non serve a nulla.
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 04, 2013, 10:33 am
Sul problema della precisione ho riflettuto, concludendo che la quinta cifra decimale è sufficiente per una rappresentazione in gradi delle coordinate, infatti se un grado di latitudine corrisponde a circa 100 km, 1m (massima precisione per un GPS) sarà un 100000 esimo di grado. Per quanto riguarda i calcoli intermedi mi riprometto di fare delle prove. Le costanti le ho scritte con più cifre giusto per annotazione.
Ho letto che double e float sono sempre di 4 byte su Arduino, vero?
Per quanto riguarda i valori che una funzione restituisce al main, se ho capito bene, solo uno può ritornare con il nome della funzione, mentre negli argomenti non posso passare nient'altro. E' giusto? Altrimenti uso variabili globali.
Title: Re: Maledette funzioni!!
Post by: gpb01 on Aug 04, 2013, 10:51 am

Sul problema della precisione ho riflettuto, concludendo che la quinta cifra decimale è sufficiente per una rappresentazione in gradi delle coordinate, infatti se un grado di latitudine corrisponde a circa 100 km, 1m (massima precisione per un GPS) sarà un 100000 esimo di grado.


Paolo, ricorda che gli errori .... si accumulano ... su ogni operazione che fai tronchi il risultato ... non so alla fine che precisione ti rimane ...
Astro, che conosce bene l'argomento, ti ha indicato un errore di .... centinaia di Km ...


Per quanto riguarda i calcoli intermedi mi riprometto di fare delle prove. Le costanti le ho scritte con più cifre giusto per annotazione.
Ho letto che double e float sono sempre di 4 byte su Arduino, vero?


Se hai letto la mia risposta precedente hai tutte le indicazioni ... ;)


Per quanto riguarda i valori che una funzione restituisce al main, se ho capito bene, solo uno può ritornare con il nome della funzione, mentre negli argomenti non posso passare nient'altro. E' giusto? Altrimenti uso variabili globali.


In realtà il discorso è più complesso ... ad una funzione i parametri si possono passare "by value" o "by reference", e, nel secondo caso, la funzione può addirittura modificare il valore dei parametri ... ma ... credo di mettere "troppa carne al fuoco" ... ;)

Guglielmo
Title: Re: Maledette funzioni!!
Post by: leo72 on Aug 04, 2013, 11:02 am
Ti posso confermare che Arduino proprio litiga con float con tanti numeri decimali.
Potresti provare a convertire tutto in unsigned long, tipo a 32 bit, e poi in fase di stampa mettere il punto decimale dove ti serve. Oppure, usare unsigned long long, a 64 bit. Non è un tipo nativamente supportato dal micro per cui la dimensione dello sketch cresce molto, però se necessiti di grossa precisione, potrebbe essere una soluzione rapida.
Title: Re: Maledette funzioni!!
Post by: nid69ita on Aug 04, 2013, 11:45 am


Per quanto riguarda i valori che una funzione restituisce al main, se ho capito bene, solo uno può ritornare con il nome della funzione, mentre negli argomenti non posso passare nient'altro. E' giusto? Altrimenti uso variabili globali.

In realtà il discorso è più complesso ... ad una funzione i parametri si possono passare "by value" o "by reference", e, nel secondo caso, la funzione può addirittura modificare il valore dei parametri ... ma ... credo di mettere "troppa carne al fuoco" ... ;)
Guglielmo


Quotone.
Praticamente, devi usare i puntatori se vuoi poter modificare una variabile passata come parametro. Perciò occhio che con i puntatori è un attimo fare casino.  
Se vuoi saperne di più, cerca su libri di C o su internet,  il classico esempio dello swap (cambio) dei contenuti di due variabili passati ad una funzione.

In Swap1 lo scambio non avviene perchè in a e b ci sono le copie dei valori passati
Code: [Select]

int x=1,y=3;
swap1(x,y);      // contenuto delle variabili swap non funziona
Serial.print(x); Serial.print(" ");Serial.println(y);
swap2(&x,&y);    // indirizzo delle variabili
Serial.print(x); Serial.print(" ");Serial.println(y);
...
void swap1(int a,int b)
{ int tmp=a;
 a=b;
 b=tmp;            
}
void swap2(int *a,int *b)
{ int tmp=*a;
 *a=*b;
 *b=tmp;            
}
Title: Re: Maledette funzioni!!
Post by: nid69ita on Aug 04, 2013, 11:58 am
Il C++ ammette poi questa sintassi che semplifica:
Code: [Select]
int x=1,y=3;
swap3(x,y);      // sembra che passi il contenuto delle variabili ma i parametri prendono l'indirizzo perchè così vuole la funzione
                     // non dipende più dal chiamante ricordarsi di mettere &x e &y come per swap2()
...
void swap3(int &a,int &b)
{ int tmp=a;
 a=b;
 b=tmp;            
}
Title: Re: Maledette funzioni!!
Post by: gpb01 on Aug 04, 2013, 12:08 pm
Nid ... ma secondo te la mia frase ...

Quote
... credo di mettere "troppa carne al fuoco" ...


era buttata li a caso o sapevo quello che dicevo (dato che conosco Paolo) ???

Provaci a ragionare va ...

Guglielmo
Title: Re: Maledette funzioni!!
Post by: nid69ita on Aug 04, 2013, 12:45 pm
Ho scritto la prima frase, poi  ... non ho resistito :D

Ma @paolo non è abbastanza skillato? Fà molti interventi nel forum
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 04, 2013, 08:23 pm
@nid69ita, grazie per lo skillato, ma purtroppo nel software sono rimasto a vecchi concetti. In passato usavo molto le "subroutine" dove passavo tutte le variabili che volevo in input e output. Adesso devo dimenticare quel modo di programmare semplice  =(!
Quote
Quotone.
Praticamente, devi usare i puntatori se vuoi poter modificare una variabile passata come parametro. Perciò occhio che con i puntatori è un attimo fare casino. 
Se vuoi saperne di più, cerca su libri di C o su internet,  il classico esempio dello swap (cambio) dei contenuti di due variabili passati ad una funzione.

Volevo proprio evitare di usare i puntatori e concentrarmi più sul problema numerico, infatti Guglielmo mi ha capito.
@leo72, ascolterò i tuoi consigli e proverò ad usare i diversi tipi di variabile, per ora ho risolto il problema della funzione usando una variabile globale e una restituita tramite il nome della funzione. Oppure userò tutte variabili globali, che per far le prove di precisione va bene lo stesso.
Intanto vi ringrazio tutti e vi farò sapere presto cosa tiro fuori.
ciao
paolo
Title: Re: Maledette funzioni!!
Post by: gpb01 on Aug 04, 2013, 08:28 pm

...
Volevo proprio evitare di usare i puntatori e concentrarmi più sul problema numerico, infatti Guglielmo mi ha capito.
...


Paolo, hai i miei contatti e sei piuttosto vicino ... se ti serve una mano, veramente NON fare complimenti ... in un'ora e mezza sei qui da me, magari, se è un fine settimana, ci facciamo una bella grigliata e ... ti do tutto il supporto che ti serve ;)

Guglielmo
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 04, 2013, 08:58 pm
Grazie Guglielmo dell'invito. Lascio passare le vacanze e poi ci sentiamo.
Title: Re: Maledette funzioni!!
Post by: pablos71 on Aug 04, 2013, 09:25 pm
Anch'io voglio venire alla grigliata !!!  XD XD XD XD
Title: Re: Maledette funzioni!!
Post by: gpb01 on Aug 04, 2013, 09:46 pm

Anch'io voglio venire alla grigliata !!!  XD XD XD XD


Tu mica abiti qui vicino ... (http://www.nikonland.eu/forum/public/style_emoticons/default/bigemo_harabe_net-03.gif)

Guglielmo
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 05, 2013, 09:48 am
Ragazzi, come promesso vi metto al corrente degli sviluppi sulla precisione del calcolo delle distanze terrestri su Arduino.
Per fare i confronti ho usato, sia la mia fidata calcolatrice HP 11C con 10 cifre significative, sia un programma in Fortran che usa i real*8 ovvero floating point a 64 bit. Non solo, ma una delle distanze ottenute l'ho misurata anche con il "righello" di Google Earth. I risultati sono molto confortanti e li ho scritti come commenti sul codice qui sotto. (Le distanze sono in metri e le direzioni in gradi rispetto al N)
Code: [Select]
#include <math.h>
     float direct;
     float dis;
void setup(){
  Serial.begin(9600);
/*
   float la1 = 45.78956;
   float lo1 =  9.36424;
   float la2 = 45.78897;
   float lo2 =  9.36514;
   */
//   dis = 95.6; direct = 133.1     HP:  95.8   133.2  Fortran 95.6 133.1
//   Google Earth 96  133
   
   /*
   float la1 = 45.78956;
   float lo1 =  9.36424;
   float la2 = 45.77297;
   float lo2 =  9.36514;
   */
   // dis = 1846.1  direct = 177.8   HP:  1846  177.8  Fortran 1846.1  177.8
/* 
   float la1 = 45.78956;
   float lo1 =  9.36424;
   float la2 = 45.78957;
   float lo2 =  9.36514;
*/
   // dis = 69.8  direct = 89    FORTRAN  69.8  89.0
   float la1 = 45.78956;
   float lo1 =  9.36424;
   float la2 = 45.78937;
   float lo2 =  9.36426;

//  dis = 20.8  direct = 180   FORTRAN 20.8  direzione 180

   dis =  Distance(la1, lo1, la2, lo2);
   Serial.print(" distanza = ");
  Serial.println(dis);
  Serial.print(" direzione = ");
  Serial.println(direct);
}
void loop(){
 
}
////////////////////////////////////////////////////////////////////////
  float Distance(float lat1, float lon1, float lat2, float lon2){
  float rt = 6371000;  // raggio terra in m
  float pi = 3.141592654;
  float coslat = cos((lat1+lat2)*pi/360);
  float dx = rt*(lon2-lon1)*coslat*pi/180;
  float dy = rt*(lat2-lat1)*pi/180;
  float dist = sqrt(dx*dx + dy*dy);
  //
  if(dist < 4){
    direct = 0;
  }
  else{
        if(abs(dx) < 4 && dy >= 0){
              direct = 360;
         }
         else if(abs(dx) < 4 && dy < 0){
              direct = 180;
         }
         else{
              direct = 180*atan(dy/dx)/pi;
              if(dx > 0){
                 direct = 90 - direct;
              }
              if(dx < 0){
                 direct = 270 - direct;
              } 
         }
    }
      return(dist);
  }
Title: Re: Maledette funzioni!!
Post by: leo72 on Aug 05, 2013, 10:07 am
1) quindi hai risolto continuando ad usare i float. E cos'era allora che non andava?
2) abituati a fare i confronti float con float, quindi questo if:
Code: [Select]
if (dist < 4)
fallo diventare:
Code: [Select]
if (dist < 4.0)
3) l'Arduino già predefinisce pi greco come costante PI.
4) nell'Arduino hai già delle costanti predefinite per la conversione gradi/radianti e viceversa, DEG_TO_RAD e RAD_TO_GRAD.

Trovi le costanti nel file /hardware/arduino/cores/arduino/Arduino.h
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 05, 2013, 10:35 am
Il problema era iniziato con le variabili passate attraverso le funzioni, poi si è spostato sulla precisione dei calcoli fatti con le latitudini e longitudini di un GPS per calcolare distanze e direzioni. Adesso, dopo queste prove, sono abbastanza sicuro che i float di Arduino sono abbastanza precisi da garantirmi qualche metro, che è la stessa precisione di un buon GPS. 
Il mio progetto consiste nel mettere insieme il GPS Shield di Adafruit, la bussola LSM303 di Pololu e il LCD Color di Sparkfun, per fare uno strumento che ti dice dove sei e quanto sei distante da un punto di coordinate note, oltre alla direzione che devi prendere per raggiungere il punto. E' più da tracking che da navigazione in auto, ma i navigatori spesso non ti permettono certe funzioni, E poi vuoi mettere il gusto di costruirselo da solo!
Grazie dei consigli sulle costanti.
Paolo

P.S.
per chi volesse vedere i tre pezzi in funzione, ho un paio di immagini qui:

http://www.meteoenergia.it/GPS/03082013382.jpg
http://www.meteoenergia.it/GPS/03082013384.jpg
Title: Re: Maledette funzioni!!
Post by: leo72 on Aug 05, 2013, 10:45 am
Ma all'alimentazione ci hai pensato?
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 05, 2013, 11:53 am
Dovendo essere portatile, dovrò alimentarlo con una batteria, magari ricaricabile con la presa 12 V dell'auto. Non ho ancora misurato l'assorbimento di tutto il trabiccolo.
Title: Re: Maledette funzioni!!
Post by: leo72 on Aug 05, 2013, 12:05 pm
Era quello il punto, perché un modulo GPS più un display LCD immagino che succhino abbastanza corrente.
Title: Re: Maledette funzioni!!
Post by: PaoloP on Aug 05, 2013, 12:46 pm

Ma @paolo non è abbastanza skillato? Fà molti interventi nel forum


Ci sono più Paolo qui. Non è che ti confondi.  :smiley-mr-green:
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 05, 2013, 02:56 pm
Vuol dire che siamo tutti skillati!!  :smiley-mr-green: :smiley-mr-green:
Title: Re: Maledette funzioni!!
Post by: Etemenanki on Aug 05, 2013, 04:10 pm

Vuol dire che siamo tutti skillati!!  :smiley-mr-green: :smiley-mr-green:


...  :smiley-roll-blue: ...

Spero che tu non ti offenda per una battuta, ma ... sei sicuro che ci andavano le "elle" e non le "zeta" ? ... :P XD XD XD
Title: Re: Maledette funzioni!!
Post by: lestofante on Aug 05, 2013, 04:20 pm

Volevo proprio evitare di usare i puntatori e concentrarmi più sul problema numerico, infatti Guglielmo mi ha capito.


allora non puoi sfruttare i parametri, però puoi ritornare una struttura che al suo interno contiene i 2 volori, oppure un array se i valori da ritornare sono dello stesso tipo.
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 05, 2013, 07:43 pm
Ho risolto con le variabili globali.  Infatti i due valori che devo calcolare con la funzione hanno sempre lo stesso significato, sia nella funzione che nel main.
Title: Re: Maledette funzioni!!
Post by: leo72 on Aug 06, 2013, 06:20 am
Paolo, hai letto i miei suggerimenti al reply #16?
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 07, 2013, 11:00 am
oggi implemento il tutto e posto il codice con una foto
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 07, 2013, 06:14 pm
Ecco il programma finito!  :) Il GPS fa le seguenti cose:
1) Rileva i parametri GPS (lat, lon, alt..)
2) Rileva la direzione del puntatore del GPS rispetto al N con la bussola
3) Calcola la distanza tra la posizione attuale e un punto fisso assegnato all'interno del programma
4) Calcola la direzione in cui è "visto" il punto fisso rispetto al puntatore del GPS.
Purtroppo non posso postarlo perchè eccede il limite massimo, lo posto fino al setup() compreso.

Code: [Select]
// This software demonstrates the possibility of this hardware:
// Arduino UNO,
// GPS-Shield from Adafruit,
// Color-LCD from Sparkfun,
// LSM303 tilt compensated compass from Pololu,
//
//  to be working together. Futhermore it computes the distance and the direction
//  of a fixed poit from the current  position.
//
//  This code is a merge among the:
//     Adafruit GPS Library Parsing.ino
//     Color Shield Library by Jim Lindblom  TestPattern.ino
//     Pololu LSM303 Library  Heading.ino
//  with some lines from the author (Paolo Bonelli 07/August/2013)
//
/*     ******WIRING  LSM303 COMPASS******

Wiring:
pre. Arduino Uno/Duemilanove     LSM303 board
                   5V  ->  VIN
                  GND  ->  GND
         Analog Pin 5  ->  SCL
         Analog Pin 4  ->  SDA


    ******* WIRING  Adafruit GPS shield ****
     
     Cut cupper strips between D7, RX and D8, TX
     Jump RX and TX to pin D10 and D12

      ******WIRING Sparkfun Color LCD******
     
      LCD      Arduino UNO
      8          D8
      9          D9
      11         D11
      13         D13
      3.3        3.3
      5          5
      GND        GND
*/

#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#include <Wire.h>
#include <LSM303.h>
#include <ColorLCDShield.h>
#include <math.h>

    float direct;  //  direction of the fixed point respect to North in degree (from 0 to 360)
    float dis;     //  distance in m between current position and the fixed point
    float la2 = 45.51970;  //  fixed point latitude in degree
    float lo2 = 9.15294;   //  fixed point longitude in degree
    int heading = 0;       //  Compass direction respect to N in degree (from 0 to 360)
    float dismin = 4.0;    // minimum distance in m (GPS precision)
    int gpsperiod = 4000;  //  time period for updating GPS data (ms)

LSM303 compass;
LCDShield lcd;
SoftwareSerial mySerial(12, 10);
Adafruit_GPS GPS(&mySerial);
// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences.
#define GPSECHO  false
//  Set ECHO to true for printing some numbers
#define ECHO true
int buttons[3] = {3,4,5};
// this keeps track of whether we're using the interrupt
// off by default!
boolean usingInterrupt = false;
char emi[3] ="  ";    //  emisphere  (N,S,W,E)
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy
///////////////////////////////////////////////////////////////////////////////////
void setup()  
{
     for (int i=0; i<3; i++)
 {
   pinMode(buttons[i], INPUT);  // Set buttons as inputs
   digitalWrite(buttons[i], HIGH);  // Activate internal pull-up
 }
 // connect at 115200 so we can read the GPS fast enough and echo without dropping chars
 // also spit it out
 Serial.begin(115200);
 Wire.begin();
 compass.init();
 compass.enableDefault();
 // Calibration values. Use the Calibrate example program to get the values for
 // your compass.
 compass.m_min.x = -492; compass.m_min.y = -682; compass.m_min.z = -538;
 compass.m_max.x = 435; compass.m_max.y = 298; compass.m_max.z = 360;
 // 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800
 GPS.begin(9600);
 
 // uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
 GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
 // uncomment this line to turn on only the "minimum recommended" data
 //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
 // For parsing data, we don't suggest using anything but either RMC only or RMC+GGA since
 // the parser doesn't care about other sentences at this time
 // Set the update rate
 GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 1 Hz update rate
 // For the parsing code to work nicely and have time to sort thru the data, and
 // print it out we don't suggest using anything higher than 1 Hz
 // Request updates on antenna status, comment out to keep quiet
 GPS.sendCommand(PGCMD_ANTENNA);
 // the nice thing about this code is you can have a timer0 interrupt go off
 // every 1 millisecond, and read data from the GPS for you. that makes the
 // loop code a heck of a lot easier!
 useInterrupt(true);
 delay(1000);
 // Ask for firmware version
 mySerial.println(PMTK_Q_RELEASE);
  // following two required for LCD
lcd.init(EPSON);
lcd.contrast(40); // sets LCD contrast (value between 0~63)
lcd.clear(BLACK);

}


Aggiungo un paio di foto
http://www.meteoenergia.it/GPS/trepezzi.png
http://www.meteoenergia.it/GPS/07082013388.jpg
Title: Re: Maledette funzioni!!
Post by: PaoloP on Aug 07, 2013, 06:31 pm
Ma lo puoi allegare.
Vai su Additional Options... nell'editor.

Così
Code: [Select]
    for (int i=0; i<3; i++)
 {
   pinMode(buttons[i], INPUT);  // Set buttons as inputs
   digitalWrite(buttons[i], HIGH);  // Activate internal pull-up
 }


o pomì
Code: [Select]
pinMode(buttons[0], INPUT_PULLUP);  // Set buttons as inputs and Activate internal pull-up
pinMode(buttons[1], INPUT_PULLUP);
pinMode(buttons[2], INPUT_PULLUP);
Title: Re: Maledette funzioni!!
Post by: leo72 on Aug 08, 2013, 06:54 am
Code: [Select]
int buttons[3] = {3,4,5};
Usa il tipo byte per i pulsanti, tanto hanno numeri che non passeranno mai il valore max di un byte (255).
Quindi
Code: [Select]
byte buttons[3] = {3,4,5};

Inoltre vedo che istanzi la seriale software ma poi nel setup non la inizializzi. Se non ti serve, potresti toglierla per recuperare RAM (togli il suo buffer dalla memoria). Visto che lavori con i float, e che ogni variabile float prende 4 byte, più RAM hai libera e meglio è per il tuo programma.
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 12, 2013, 02:46 pm
Quote
Usa il tipo byte per i pulsanti, tanto hanno numeri che non passeranno mai il valore max di un byte (255).
Quindi

Giusto!
Quote
Inoltre vedo che istanzi la seriale software ma poi nel setup non la inizializzi. Se non ti serve, potresti toglierla per recuperare RAM (togli il suo buffer dalla memoria). Visto che lavori con i float, e che ogni variabile float prende 4 byte, più RAM hai libera e meglio è per il tuo programma.

La seriale software è richiesta dallo shield GPS. Ho copiato le istruzioni dallo sketch di esempio di Adafruit.  Credo che l'inizializzazione sia dentro la funzione di libreria GPS.begin(9600).
Title: Re: Maledette funzioni!!
Post by: leo72 on Aug 12, 2013, 05:28 pm

La seriale software è richiesta dallo shield GPS. Ho copiato le istruzioni dallo sketch di esempio di Adafruit.  Credo che l'inizializzazione sia dentro la funzione di libreria GPS.begin(9600).

Giusto, non pensavo a questo.
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 17, 2013, 02:39 pm
Ecco il programma completo in Attach. E' possibile definire 3 punti, che possono essere selezionati tramite i 3 pulsanti posti su LCD color. Il programma calcola la distanza con il punto selezionato e la direzione in cui si trova.
Title: Re: Maledette funzioni!!
Post by: PaoloP on Aug 17, 2013, 04:49 pm
Paolo, perché non cambi il titolo alla discussione e alleghi il file nel primo topic con una spiegazione?
Il titolo lo devi cambiare sempre nel primo topic.  :smiley-mr-green:
Title: Re: Maledette funzioni!!
Post by: testato on Aug 17, 2013, 07:12 pm
concordo con la modifica del titolo, e se alleghi uno schema elettrico sarebbe un ottimo topic da inserire in Megatopic.

Questo progetto e' importante, oppure e' sbagliato  :)
perche' dico questo ? perche' ci e' sempre stato detto che con arduiino non si potessero raggiungere precisioni al metro.

Come stanno le cose ?


x il discorso delle funzioni perche' dici che non puoi ragionare piu' con subroutine ?
Io ancora non uso funzioni con passaggi di parametri oppure return di valori, quindi appunto faccio tutto con funzioni Void e gestione dei dati via variabili globali. Non e' obbligatorio usare funzioni non void e con argomenti.
Domande:
ci sono casi in cui e' obbligatorio usare argomenti e return di valori?
usare funzioni "complete" e' questione di stile, di risparmio memoria, o entrambi ?
grazie
Title: Re: Maledette funzioni!!
Post by: leo72 on Aug 17, 2013, 07:31 pm
1) non so se il progetto ha tutti i requisiti per andare in Megatopic (mancherebbe la questione del "grosso interesse")
2) la questione dell'usare o meno funzioni con argomenti e/o con restituzione di valori (per favore, NON usate "ritornare": è un inglesismo schifoso, viene da "return", che suona stridente quanto "voltaggio" suona alle orecchie di un elettronico) non è una questione di gusti ma di necessità. Nel senso che le usi se ti servono. Se fai una funzione che applica un certo algoritmo ai parametri che riceve e poi restituisce il risultato in una var globale e questa funzione la chiami da più punti del programma, devi stare attento a non fare confusione nel codice perché potresti sovrascriverla.
Title: Re: Maledette funzioni!!
Post by: astrobeed on Aug 17, 2013, 07:33 pm

perche' dico questo ? perche' ci e' sempre stato detto che con arduiino non si potessero raggiungere precisioni al metro.
Come stanno le cose ?


Arduino non ha i double quindi i calcoli col GPS non si possono fare con risoluzione metrica, solo kilometrica, cosa ampiamente discussa nel topic dei quadricotteri.
Basta farsi un paio di calcoli di prova per capirlo, il gps fornisce valori fino a tre cifre intere e sei cifre decimali, i modelli migliori (=$$$) anche sette-otto, i float 32 bit al massimo rappresentano sette cifre tra parte intera e decimale.
In Italia la latidudine media è ~40°, la longitudine media è ~12° (andando molto a Nord scende sotto il valore di 10), ovvero valori con due cifre per la parte intera il che vuol dire perdere l'ultima cifra decimale fornita dal gps, poi mettiamoci gli errori di arrotondamento, molto pesanti per via della complessità del calcolo, ed ecco che la risoluzione minima reale diventa da molte decine di metri a diverse centinaia, la precisione reale è kilometrica.
Title: Re: Maledette funzioni!!
Post by: testato on Aug 17, 2013, 08:09 pm

Se fai una funzione che applica un certo algoritmo ai parametri che riceve e poi restituisce il risultato in una var globale e questa funzione la chiami da più punti del programma, devi stare attento a non fare confusione nel codice perché potresti sovrascriverla.

Pero' se faccio attenzione a non sovrascriverla funziona tutto ? possiamo dire quindi che e' soggettivo usare argomenti+restituzioni rispetto a manipolazioni di var globali ?
Sotto l'aspetto dell'occupazione di memoria, oppure di velocita', ci sono differenza tra i due metodi ?
Title: Re: Maledette funzioni!!
Post by: leo72 on Aug 17, 2013, 08:12 pm
E' vero che ogni volta che crei una funzione che accetta dei parametri devi mettere questi dati nello stack, ma se usi una var globale e poi se devi parcheggiare la variabile globale in altre variabili, alla fine occupi lo stesso della memoria per le variabili tampone.

E comunque non è elegante  ;)
Title: Re: Maledette funzioni!!
Post by: testato on Aug 17, 2013, 08:13 pm

ed ecco che la risoluzione minima reale diventa da molte decine di metri a diverse centinaia, la precisione reale è kilometrica.


quindi questo progetto ha un qualche errore di valutazione da qualche parte, visto che dichiara
Quote
Adesso, dopo queste prove, sono abbastanza sicuro che i float di Arduino sono abbastanza precisi da garantirmi qualche metro, che è la stessa precisione di un buon GPS.  
Title: Re: Maledette funzioni!!
Post by: testato on Aug 17, 2013, 08:14 pm

E' vero che ogni volta che crei una funzione che accetta dei parametri devi mettere questi dati nello stack, ma se usi una var globale e poi se devi parcheggiare la variabile globale in altre variabili, alla fine occupi lo stesso della memoria per le variabili tampone.
E comunque non è elegante  ;)

Grazie, sono metallaro  ;)
Diciamo che al punto dove sono ora, non essendo un programmatore, mi accontento di non essere elegante, l'importante e' che mentalmente mi risulta piu' facile ragionare sui codici che scrivo usando solo var globali. Logicamente resta cmq importante saper leggere una funzione con argomenti e return di valori, altrimenti non si capisce il codice che si vuole copiare scrivere  :)
Title: Re: Maledette funzioni!!
Post by: leo72 on Aug 17, 2013, 08:42 pm
Per "eleganza" intendo anche ottimizzato e leggibile. Anche per te stesso  ;)
Mi fai questo con una funzione che non restituisce niente e non accetta nessun valore?  ]:D ]:D
Code: [Select]
int e = media(media(a, b), media(c, d));

int media(int temp1, int temp2) {
  return ((temp1 + temp2) / 2);
}
Title: Re: Maledette funzioni!!
Post by: testato on Aug 17, 2013, 08:49 pm
ci lavoro  :)
Title: Re: Maledette funzioni!!
Post by: ratto93 on Aug 17, 2013, 08:52 pm
Assomiglia un sacco al mio, a Bassano non l'avevi visto Paolo ? :)
Non uso una bussola digitale però salvo su SD, ho integrato una batteria al Litio ed un carica batterie tramite mini-usb, lo schermo è il classico nokia 5100 :)
se vuoi ti posto il codice pure del mio se ti interessa :)


ed ecco che la risoluzione minima reale diventa da molte decine di metri a diverse centinaia, la precisione reale è kilometrica.


quindi questo progetto ha un qualche errore di valutazione da qualche parte, visto che dichiara
Quote
Adesso, dopo queste prove, sono abbastanza sicuro che i float di Arduino sono abbastanza precisi da garantirmi qualche metro, che è la stessa precisione di un buon GPS.  


Qui mi chiedo come sia possibile, il mio è abbastanza preciso ma tempo addietro feci delle prove nel calcolare la distanza ed in effetti l'errore era decisamente alto, ora non ho letto tutto il topic per mancanza di tempo però vorrei capire come sia possibile che l'errore su a me su cento metri ne segnava 180 e a te ? :)
ciaooo
Title: Re: Maledette funzioni!!
Post by: lestofante on Aug 22, 2013, 02:56 pm


E' vero che ogni volta che crei una funzione che accetta dei parametri devi mettere questi dati nello stack, ma se usi una var globale e poi se devi parcheggiare la variabile globale in altre variabili, alla fine occupi lo stesso della memoria per le variabili tampone.
E comunque non è elegante  ;)

Grazie, sono metallaro  ;)
Diciamo che al punto dove sono ora, non essendo un programmatore, mi accontento di non essere elegante, l'importante e' che mentalmente mi risulta piu' facile ragionare sui codici che scrivo usando solo var globali. Logicamente resta cmq importante saper leggere una funzione con argomenti e return di valori, altrimenti non si capisce il codice che si vuole copiare scrivere  :)



l'uso di funzioni è migliore per evitare di ricopiare il codice in più punti e per dividere il codice in blocchi indipendenti.
il salto di funzione impiega tempo per scrivere i dati nello stack, oltre che lo stato attuale dei registri, e poi ricaricare il tutto al momento del ritorno. Però è anche vero che il compilatore può decidere di rendere delle funzioni "inline", ovvero al momento della pre-compilazione decidere che l'uso di una funzione è inefficiente e copiare il codice contenuto nella funzione al posto della chiamata: puoi anche specificare al compilatore di comportarsi così (o meglio suggerirlo, visto che può ignorare la cosa) con la keyword "inline".

Quote
Qui mi chiedo come sia possibile, il mio è abbastanza preciso ma tempo addietro feci delle prove nel calcolare la distanza ed in effetti l'errore era decisamente alto

infatti, sarebbe da fpreparare un bell'elenco di coordinate GPS con risultati attesi calcolati con una buona precisione, e magari scelte con un criterio tra le più balorde, così d'ora in poi abbiamo tutti un buon punto di riferimento per -dimostrare- che il codice funziona.

Si usa dire "pics or it didn't happen", per il nostro caso lo cambierei in "TEST or it didn't happen"  XD
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 23, 2013, 01:11 pm
Quote
Arduino non ha i double quindi i calcoli col GPS non si possono fare con risoluzione metrica, solo kilometrica, cosa ampiamente discussa nel topic dei quadricotteri.
Basta farsi un paio di calcoli di prova per capirlo, il gps fornisce valori fino a tre cifre intere e sei cifre decimali, i modelli migliori (=$$$) anche sette-otto, i float 32 bit al massimo rappresentano sette cifre tra parte intera e decimale.
In Italia la latidudine media è ~40°, la longitudine media è ~12° (andando molto a Nord scende sotto il valore di 10), ovvero valori con due cifre per la parte intera il che vuol dire perdere l'ultima cifra decimale fornita dal gps, poi mettiamoci gli errori di arrotondamento, molto pesanti per via della complessità del calcolo, ed ecco che la risoluzione minima reale diventa da molte decine di metri a diverse centinaia, la precisione reale è kilometrica.

@astro, non capisco perché insisti sul discorso precisione. Ho fatto parecchi confronti tra distanze calcolate da Arduino, tra due punti di coordinate date dal GPS, e le stesse calcolate con un programma Fortran in doppia precisione (real*otto), oltre a calcolarle con una HP di buona memoria. Se le coordinate si riferiscono ad aree italiane con distanze dell'ordine di qualche chilometro, i calcoli danno precisioni di qualche metro. Ho fatto prove anche sul campo.
@PaoloP, se interessa posto cambiare titolo al topic, mi rimetto però al parere del moderatore. Convengo anch'io che qui si sono mischiati due topic. Uno di tipo software sulle funzioni e l'altro sul GPS.
Scusate tutti se rispondo tardi, ma sono in vacanza e non trovo spesso connessioni veloci. Comunque le discussioni innescate mi interessano.
paolo
Title: Re: Maledette funzioni!!
Post by: astrobeed on Aug 23, 2013, 01:45 pm

[@astro, non capisco perché insisti sul discorso precisione. Ho fatto parecchi confronti tra distanze calcolate da Arduino, tra due punti di coordinate date dal GPS, e le stesse calcolate con un programma Fortran in doppia precisione (real*otto),


Perché quanto affermi è impossibile, nel topic su i quadricotteri la cosa era stata sviscerata nei minimi dettagli, con tanto di calcoli e software di esempio per Arduino.
La matematica è una scienza esatta, non puoi calcolare con precisione metrica la distanza tra due coordinate gps con solo sei cinque, se non solo quattro (dipende dalla parte intera) cifre decimali significative, per giunta con dei calcoli trigonometrici di mezzo, servono almeno 10 cifre significative dopo la virgola, cosa per la quale sono indispensabili i double.
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 23, 2013, 05:03 pm
Quote
Perché quanto affermi è impossibile, nel topic su i quadricotteri la cosa era stata sviscerata nei minimi dettagli, con tanto di calcoli e software di esempio per Arduino.
La matematica è una scienza esatta, non puoi calcolare con precisione metrica la distanza tra due coordinate gps con solo sei cinque, se non solo quattro (dipende dalla parte intera) cifre decimali significative, per giunta con dei calcoli trigonometrici di mezzo, servono almeno 10 cifre significative dopo la virgola, cosa per la quale sono indispensabili i double.


Il mio ragionamento è semplice. Un grado in latitudine corrisponde a circa 110 km, questo vuol dire che 1 m è circa 1/100000 gradi. Cioè siamo sulla quinta cifra decimale della latitudine. Per la longitudine, alle nostre latitudini, la distanza è circa 70 km, quindi siamo lì. La distanza è calcolata come se lat e long fossero coordinate cartesiane su piano e questo è vero per distanze dell'ordine di pochi chilometri. La conversione tra differenze in gradi e metri è fatta moltiplicando per un fattore pari a R*pi/180 dove R è il raggio terrestre medio e pi = pi greco. L'unico calcolo trigonometrico è il coseno della latitudine quando si calcola la distanza tra due longitudini.
Ho fatto una prova su una distanza dell'ordine di un centinaio di metri, misurando con una bindella, e le cose tornano a meno di qualche metro.
Title: Re: Maledette funzioni!!
Post by: astrobeed on Aug 23, 2013, 05:22 pm

Il mio ragionamento è semplice. Un grado in latitudine corrisponde a circa 110 km, questo vuol dire che 1 m è circa 1/100000 gradi.


Se ti "inventi" dei calcoli che sono validi solo in un ristretto range di lat. e long, per giunta approssimati su un piano, è un altro paio di maniche, però un sistema che calcola il vettore tra due coordinate gps non può essere limitato a solo una certa zona e per spazi di pochi km, magari risolve il tuo problema però non va bene per un uso generico.
Io ho perso molto tempo per trovare una semplificazione per questo calcolo, rispetto a quello canonico che tiene conto del modello geodetico, con una approssimazione valida per tutto il globo, salvo le zone polari, con buoni risultati a patto di introdurre un fattore correttivo per ogni 250 metri di dislivello s.l.m., però puoi scordarti di fare questi conti con solo i float.
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 23, 2013, 05:33 pm
Concordo con te che una formula generale per tutto il globo non funzionerebbe a 32 bit, però ti assicuro che le approssimazioni che faccio, possono essere estese ad un'area abbastanza ampia, sicuramente tutta l'Italia e oltre. A meno che un quadricottero non faccia la traversata dell'Atlantico  :D, si può sempre trovare una buona approssimazione. Tieni anche conto che un normale GPS non consente precisioni maggiori di qualche metro.
Title: Re: Maledette funzioni!!
Post by: testato on Aug 23, 2013, 06:11 pm
quindi si insiste sulla questione, e questo e' bello. :)

ricapitolando paolo tu stai dicendo che con arduino uno, 328P, potresti impostare le coordinate di arrivo di un modellino in partenza da roma (ti vengo in contro  :)) verso il duomo di milano, e che questo, avendo tutto cio' di cui occorre (benzina, batterie, fortuna, aiuto del signore) e leggendo in realtime le coordinate di un gps a bordo,  riuscirebbe ad atterrare nella piazza del duomo ?
Title: Re: Maledette funzioni!!
Post by: lestofante on Aug 23, 2013, 06:19 pm
ed ecco perchè bisogna generare un elenco di coordinate su cui fare i test ;)
Title: Re: Maledette funzioni!!
Post by: leo72 on Aug 23, 2013, 06:32 pm
Il problema dei float dell'Arduino è che sono limitati a 6/7 cifre in totale, non a 6/7 cifre decimali.
Questo significa che un numero come Longitudine 1.123456 riesci a gestirlo ma se hai Longitudine 171.123457 non ce la fai perché esaurisci la capacità del float e ti ritroverai magari 171.123 oppure 171.1234 (va visto cosa fa il compilatore). E addio precisione.
Title: Re: Maledette funzioni!!
Post by: testato on Aug 23, 2013, 07:54 pm
yes, quello che ha detto in altre parole anche astro.
ed in piu' il Double, pur esistendo come funzione, non cambia nulla, e' una fotocopia del float da quel che ho capito.
Infatti mi chiedevo perche' l'hanno inserita nel reference se fa le stesse cose di float ?
Title: Re: Maledette funzioni!!
Post by: lestofante on Aug 23, 2013, 09:23 pm

esistendo come funzione

*tipo di dato


Infatti mi chiedevo perche' l'hanno inserita nel reference se fa le stesse cose di float ?

compatibilità con codice pre-esistente. per esempio se fai copia incolla di un pezzo di codice "standard" etc.
Title: Re: Maledette funzioni!!
Post by: leo72 on Aug 24, 2013, 07:09 am

ed in piu' il Double, pur esistendo come funzione, non cambia nulla, e' una fotocopia del float da quel che ho capito.
Infatti mi chiedevo perche' l'hanno inserita nel reference se fa le stesse cose di float ?

E' per via dell'implementazione del C/C++ fatta per l'architettura Avr del compilatore avr-gcc.
Siccome l'architettura Avr è limitata non era possibile integrare l'uso dei double senza sprecare un sacco di risorse. Per evitare questo e per evitare, come dice lesto, problemi di compatibilità del codice "standard" hanno strutturato i double come alias dei float normali.
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 24, 2013, 06:39 pm
Quote
Il problema dei float dell'Arduino è che sono limitati a 6/7 cifre in totale, non a 6/7 cifre decimali.
Questo significa che un numero come Longitudine 1.123456 riesci a gestirlo ma se hai Longitudine 171.123457 non ce la fai perché esaurisci la capacità del float e ti ritroverai magari 171.123 oppure 171.1234 (va visto cosa fa il compilatore). E addio precisione.

@leo, le prove che ho fatto riguardano coordinate delle nostre parti, cioè con al massimo 2 cifre per i gradi interi e 5 decimali.
Title: Re: Maledette funzioni!!
Post by: leo72 on Aug 24, 2013, 06:46 pm
Sì, capito.
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 24, 2013, 06:50 pm
Quote
ricapitolando paolo tu stai dicendo che con arduino uno, 328P, potresti impostare le coordinate di arrivo di un modellino in partenza da roma (ti vengo in contro  smiley) verso il duomo di milano, e che questo, avendo tutto cio' di cui occorre (benzina, batterie, fortuna, aiuto del signore) e leggendo in realtime le coordinate di un gps a bordo,  riuscirebbe ad atterrare nella piazza del duomo ?

Quello che dici @testato, non è impossibile! L'importante è memorizzare un certo numero di punti lungo il tracciato e dirigere il modellino su ciascun punto in sequenza!
Title: Re: Maledette funzioni!!
Post by: testato on Aug 25, 2013, 12:22 am
E perché servono punti intermedi se si ha un gps a bordo ? Tu hai parlato di tutt italia
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 25, 2013, 02:36 pm
Quote
E perché servono punti intermedi se si ha un gps a bordo ? Tu hai parlato di tutt italia

Se io devo raggiungere un punto B, partendo da A, devo sapere quale direzione seguire con la bussola. Questo si fa calcolando la direzione in cui "vedo" B da A, sulla base delle loro coordinate. Ma, se la distanza tra A e B è troppo grande, l'errore fatto dalla bussola mi può far arrivare in un punto completamente diverso. Senza contare l'effetto del vento che mi può far spostare dalla mia traiettoria. Quindi è importante avere obiettivi intermedi non troppo distanti tra loro.
Title: Re: Maledette funzioni!!
Post by: astrobeed on Aug 25, 2013, 02:42 pm

Se io devo raggiungere un punto B, partendo da A, devo sapere quale direzione seguire con la bussola.


Il GPS ti fornisce anche l'heading istantaneo, ed è molto preciso, la bussola serve solo se manca il segnale gps, per giunta la bussola ti fornisce il nord magnetico, che deve essere corretto in base alla declinazione magnetica locale, mentre il gps ti fornisce il nord reale.
Se devi andare da Roma a Milano, ipotizzando di volerlo fare volando seguendo la rotta più breve, non ti serve nessun waypoint intermedio visto che sarà il gps stesso a dirti se stai deviando dalla rotta.
Title: Re: Maledette funzioni!!
Post by: paolometeo2 on Aug 25, 2013, 05:12 pm
Quote
Il GPS ti fornisce anche l'heading istantaneo, ed è molto preciso, la bussola serve solo se manca il segnale gps, per giunta la bussola ti fornisce il nord magnetico, che deve essere corretto in base alla declinazione magnetica locale, mentre il gps ti fornisce il nord reale.
Se devi andare da Roma a Milano, ipotizzando di volerlo fare volando seguendo la rotta più breve, non ti serve nessun waypoint intermedio visto che sarà il gps stesso a dirti se stai deviando dalla rotta.

Sì, concordo. Il GPS ti dà anche la rotta, se sei in movimento. Nella mia applicazione avevo necessità di sapere la direzione stando fermo, per questo ho messo anche la bussola.