Arduino perde i dati

Buonasera sono nuovo sul forum, ma sono già da un poco che lavoro con arduino.
Oggi arduino dopo aver caricato lo sketch lo stacco per collegare il sensore, lo riattacco al pc vado sulla seriale per vedere il risultato ma non funziona, arduino dorme, le spie led della board sono accese ma non da segno di vita dello sketch. Ricarico lo sketch e arduino funziona mi dà tutti i dati tramite seriale ma se lo stacco perde i dati dello sketch, è come quando si toglie la batteria tampone del pc per far resettare il bios.
Grazie. Lo sketch lo metterò fra poco, il progetto è misurare la distanza tramite sensore sharp link

void setup()
{
Serial.begin(9600);
}

void loop ()

{
int Distanza;
Distanza = analogRead(1);
Serial.println(Distanza);
delay (1);
if ( Distanza > 150 )
{
Serial.println("Attenzione");
}
}

Distanza = analogRead(1);

Non so che tipo di dati potevi leggere, però stai impegnando il pin 1 che è il TX della seriale invece di usare (A0 o A1) oppure il numero del pin corrispondente
A0, A1, ..., A5 equivalenti a pin 14, 15, ... 19 per la UNO, probabilmente lo sketch si inchioda e sembra a te che il programma non ci sia più.
Se per caso davvero il micro ha problemi di ram ti basta provare il blinkled.ino che trovi negli esempi, scolleghi la usb, aspetti qualche sec, la ricoleghi e puoi verificare se il 13 riprende a lampeggiare.

ciao

FilippoChiappo:
Buonasera sono nuovo sul forum,

Ti invitiamo a presentarti (dicci quali conoscenze hai di elettronica e di programmazione) qui: Presentazioni
e a leggere il regolamento: Regolamento

Il codice devi racchiuderlo nei tag code, vedi sezione 7 del regolamento, spiega bene come fare.
Altrimenti parte del codice può essere visualizzata male o mancare perchè interpretato come attributo del testo stesso.

I tutorial in giro per il sharp li ho sempre visti usando una libreria dedicata, non mi pare quel sensore dia un valore analogico proporzionale.
Qui un tutorial in italiano: http://www.mauroalfieri.it/elettronica/tutorial-sharp2d120x-e-arduino.html

nid69ita:
Qui un tutorial in italiano: http://www.mauroalfieri.it/elettronica/tutorial-sharp2d120x-e-arduino.html

La libreria consigliata in quell'articolo è pessima, inutilmente complicata e usa una LUT per la conversione, cosa non applicabile in quanto ogni sensore di quel tipo ha una risposta leggermente diversa da tutti gli altri, infatti serve una calibrazione se si vuole ottenere una precisione decente, migliore di 1 cm nel peggiore dei casi.
La risposta di quei sensori è una banale iperbolica 1/x, cosa abbastanza ovvia visto che il sensore misura l'errore di parallasse, alla quale tocca aggiungere l'offset e un gain,
La linearizzazione si fa con poche righe di codice Arduino senza ricorrere a nessuna libreria.

Esempio di codice che ho scritto per gestire tre telemetri, nel header c'è anche la spiegazione come linearizzare la lettura ed eseguire la calibrazione.

/*
 * Telemetro Sharp
 * (c) 2014 by MdA Project
 */

// assegnazione pin

/*
 Telemetro Sx A0
 Telemetro Cx A1
 Telemetro Dx A2
  
 L'ADC lavora con Aref a 3.3V
*/

/* 
  Linearizzazione lettura telemetri Sharp

La curva dei telemetri è una iperbolica, la sua funzione è 1/x a cui va aggiunto un gain e un offset per posizionare correttamente la curva sul piano cartesiano,
questi due valori sono da trovare tramite misure reali sul sensore.
In particolare abbiamo che la distanza, in cm, è data da  D = Kg/(X-Ko), ove X è la lettura ADC, Kg è la costante per il gain e Ko è la costante per l’offset.
Kg e Ko si trovano eseguendo una misura a 10 cm e una a 50 cm di distanza, eventuali valori negativi ottenuti dal calcolo vanno considerati positivi.

  Kg è il gain.
  Ko è l’offset.

  D e X sono rispettivamente la distanza, presa tramite righello, e la lettura del ADC a 10 cm  
  D' e X'  la stessa cosa a 50 cm.

  Kg = (X'-X) D'D/(D-D')
  Ko = (D'X' - DX)/(D' - D)

  Esempio pratico con I valori misurati su i miei sensori.

  d = 10cm X = 465
  d'= 50cm X'=  104
  Kg = 361 * 500/40 = 4512
  Ko = (50*87 - 10*190) / 40 = 14

Kg e Ko vanno definiti come costanti di tipo unsigned int, il calcolo è esclusivamente tra numeri interi.

*/

// analog pin
const byte IR1 = A0;       // Telemetro IR Sx
const byte IR2 = A1;       // Telemetro IR Centro
const byte IR3 = A2;       // Telemetro IR Dx
// digital pin
const byte STled  = 13;    // Status LED

// variabili sensori
unsigned int IRsx, IRdx, IRcx;

void setup()
{
  // Usa 3.3V come Aref
  analogReference(EXTERNAL);

  // preinit Out
  pinMode(STled, OUTPUT);
  
  // init UART
  Serial.begin(115200);
}

void loop() 
{
  Sens_Read();    // lettura sensori
  // solo per test
  Serial.print("IR sx : ");
  Serial.print(IRsx,DEC);
  Serial.print(" IR cx : ");
  Serial.print(IRcx,DEC);
  Serial.print(" IR dx : ");
  Serial.print(IRdx,DEC);
  // delay per attesa 66 ms(15 acquisizioni al secondo)
  delay(66); 
}

// lettura sensori.
void Sens_Read(void)
{
  // lettura input analogici, prima lettura dummy
  // IR sinistro
  IRsx = analogRead(IR1); 
  IRsx = analogRead(IR1); 
  // IR centrale
  IRcx = analogRead(IR2); 
  IRcx = analogRead(IR2);
  // IR destro
  IRdx = analogRead(IR3); 
  IRdx = analogRead(IR3); 
 
  // solo per calibrabione IR
  // Serial.print(" IR cx : ");
  // Serial.println(IRcx,DEC);

  // linearizzazione IR
  IRsx = 6375/(IRsx-93);
  if (IRsx > 80) IRsx = 100;
  IRcx = 6375/(IRcx-93);
  if (IRcx > 80) IRcx = 100;
  IRdx = 6375/(IRdx-93);
  if (IRdx > 80) IRdx = 100;  
}

pablos:
Non so che tipo di dati potevi leggere, però stai impegnando il pin 1 che è il TX della seriale invece di usare (A0 o A1) oppure il numero del pin corrispondente
A0, A1, ..., A5 equivalenti a pin 14, 15, ... 19 per la UNO, probabilmente lo sketch si inchioda e sembra a te che il programma non ci sia più.

@Pablos
La gestione dei pin analogici è diversa da quelli digitali.
digitalRead(1) legge il pin D1, mentre analogRead(1) legge il pin analogico A1 e non il D1.
Per evitare confusione è meglio scrivere analogRead(A1) o analogRead(1415), ma non è obbligatorio.

Un problema di quello sketch è che spara di continuo dati sulla seriale rendendo difficoltosa la programmazione.

Prova a mettere un delay di 1 secondo prima e dopo il serial begin e vedi se cambia qualcosa.

Per astrobeed:
la banale iperbolica abbastanza ovvia credo che risulterà per molti poco banale ed assai poco ovvia :grin:

paulus1969:
Per astrobeed:
la banale iperbolica abbastanza ovvia credo che risulterà per molti poco banale ed assai poco ovvia :grin:

Dal mio, personalissimo, punto di vista è ovvia e banale. :grin:

@Paolo P

Non ho mai provato a mettere (1) al posto di (A1 0 14) .... ma sei sicuro, sicuro, sicuro? :smiley: :smiley:

Ho risposto così perchè a logica se posso scrivere:
analogRead(14); e mi legge il pin 14
analogRead(1); mi dovrebbe leggere il pin 1

Però se ho detto una scemenza chiedo venia :-[

ciao

pablos:
Non ho mai provato a mettere (1) al posto di (A1 0 14) … ma sei sicuro, sicuro, sicuro? :smiley: :smiley:

Non è questione di logica ma di cosa c’è scritto nel codice della funzione all’interno del core di Arduino.

int analogRead(uint8_t pin)
{
	uint8_t low, high;

#if defined(analogPinToChannel)
#if defined(__AVR_ATmega32U4__)
	if (pin >= 18) pin -= 18; // allow for channel or pin numbers
#endif
	pin = analogPinToChannel(pin);
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
	if (pin >= 54) pin -= 54; // allow for channel or pin numbers
#elif defined(__AVR_ATmega32U4__)
	if (pin >= 18) pin -= 18; // allow for channel or pin numbers
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
	if (pin >= 24) pin -= 24; // allow for channel or pin numbers
#else
	if (pin >= 14) pin -= 14; // allow for channel or pin numbers
#endif

#if defined(ADCSRB) && defined(MUX5)
	// the MUX5 bit of ADCSRB selects whether we're reading from channels
	// 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
	ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
#endif
  
	// set the analog reference (high two bits of ADMUX) and select the
	// channel (low 4 bits).  this also sets ADLAR (left-adjust result)
	// to 0 (the default).
#if defined(ADMUX)
	ADMUX = (analog_reference << 6) | (pin & 0x07);
#endif

	// without a delay, we seem to read from the wrong channel
	//delay(1);

#if defined(ADCSRA) && defined(ADCL)
	// start the conversion
	sbi(ADCSRA, ADSC);

	// ADSC is cleared when the conversion finishes
	while (bit_is_set(ADCSRA, ADSC));

	// we have to read ADCL first; doing so locks both ADCL
	// and ADCH until ADCH is read.  reading ADCL second would
	// cause the results of each conversion to be discarded,
	// as ADCL and ADCH would be locked when it completed.
	low  = ADCL;
	high = ADCH;
#else
	// we dont have an ADC, return 0
	low  = 0;
	high = 0;
#endif

	// combine the two bytes
	return (high << 8) | low;
}
static const uint8_t A0 = 14;
static const uint8_t A1 = 15;
static const uint8_t A2 = 16;
static const uint8_t A3 = 17;
static const uint8_t A4 = 18;
static const uint8_t A5 = 19;
static const uint8_t A6 = 20;
static const uint8_t A7 = 21;

A1 corrisponde a 15. Il 14 è per A0.
Comunque scrivere 14 o 15 rende il codice non portabile su altri tipi di Arduino, meglio scrivere A0, A1, ecc.

Hai ragione Paolo.

Comunque penso di aver capito cosa intende quando staccando la usb non funziona più la seriale, il chè è abbastanza ovvio.
Se stacchi e riattacchi la usb noterai che sotto il menu Strumenti>porta la COM n di arduino sparisce ma se la stacchi e riattacchi una seconda volta riappare

Comunque vedo che Filippo si collega legge e fa il logout senza intervenire .... probabilmente non gli iteressa granchè ... bha!! :frowning:

ciao

Ciao a tutti,
pablos mi dispiace contraddirti è vero che entro ed esco ma non ho il tempo per usare arduino, ora che ce l'ho posso discutere.

Io intendevo dire che:
una volta inviato lo sketch ad arduino funziona tutto perfettamente
stacco arduino tutte le luci si spengono
riattacco arduino si accende ma non esegue quello che gli avevo inviato in precedenza.

Ho provato le varie soluzioni: cambiare il nome del pin ( A0, 0, 14 ) ma niente

Scusate il mio disturbo

Risolto!!!!!!!!!!!!!!!!!!

Lo sketch non parte direttamente, devo accedere all'IDE di ardu., Cliccare per mostrare la porta seriale e poi le luci sulla board di ardu. impazziscono e funziona tutto evviva!!!!!!!!!!!!!!!!!!!!!!!!! ! !! ! ! ! ! ! !! ! !!!! ! 10001 10001 10001

Hai una Arduino Leonardo?

No uno

Allora non è possibile che lo sketch si blocchi in attesa della Seriale.
Non è che hai messo qualche ciclo while() che attende un comando?

ma se riattacchi arduino all'alimentazione e premi il pulsante di reset ( senza accedere all'IDE ) che fa' ?

Brunello se premo reset non succede nulla resta bloccato, devo per forza accedere all'IDE e andare su mostra seriale altrimenti non parte.