Go Down

Topic: Arduino Nano - Problema con sorgenti (Read 590 times) previous topic - next topic

dukeluca86

Ciao, stò usando dei cloni di Nano, ma credo che il problema/i non risiedano li, vi porrò diversi problemi:

Errore N1

Sto realizzando diversi programmi, in uno ad esempio mi è capitato di leggere un valore analogico, dividerlo per 7 e stoccarlo in una variabile.

Poi vado a dire con un if che se la variabile è piu grande del valore "8" questa deve diventare comunque un "8".
Detto fatto Printo il tutto e viene fuori un bel "9"... Alla grande insomma.

Siccome di solito si inizia col dire "Ahhh è un bug... ", poi viene fuori che la cappela l'ha fatta il programmatore, vi chiedo direttamente, cosa ho sbagliato ?

Segue codice:

Code: [Select]

void loop() {
  int value = analogRead(7);
  value = (value / 7);
  if(value > 8) value == 8;
  Serial.print(value);





Errore N2

Non sò se è preferibile fare diversi post o racchiudere tutto in uno, per me era meglio questa seconda e ho fatto cosi, se non vi piace, spezzettatelo pure o fatemelo sapere che provvedo.

Le funzioni che passione(), in un altro programma, ho avuto necessità di creare una funzione per una porzione di codice molto ripetitiva, fatta, incapsulata nelle sue belle parentesi graffe e tutto il resto... non funziona niente, me la compila, però poi il programma non risponde come avrebbe dovuto, il tutto invece messo nella "loop" funziona perfettamente, non me lo spiego  :o .

Allego il codice:

Code: [Select]

  digitalWrite(2, LOW);
  delayMicroseconds(10);
  proximity = 0x8;
  Wire.beginTransmission(SENSORE);
  Wire.write(proximity);
  Wire.endTransmission(false);
  Wire.requestFrom(SENSORE, 2);
  dato[0] = Wire.read();
  dato[1] = Wire.read();
  value = (dato[1])*256 + (dato[0]);







Errore N3

Qui invece stò generando un PWM trifase leggendo una LUT che mi sono scritto (a manoooooo), qui se creo questa selezione di if genera i dati ma in modo strano, i led vengono dimmati ma non come dovrebbero, mentre se  metto tante condizioni if , con ognuna che contiene il suo blocco for( i=0; i<=8;), il tutto funzione bene.

Code: [Select]

  if(value == 0) a = 0; b = 8;
  if(value == 1) a = 9; b = 17;
  if(value == 2) a = 18; b = 26;
  if(value == 3) a = 27; b = 35;
  if(value == 4) a = 36; b = 44;
  if(value == 5) a = 45; b = 53;
  if(value == 6) a = 54; b = 62;
  if(value == 7) a = 63; b = 71;
  if(value >= 8) a = 72; b = 80;
 

  for (i = a; i <= b; ){
    if(pwm1[i]) digitalWrite(2, HIGH); else digitalWrite(2, LOW);    // Output Toggle
    if(pwm2[i]) digitalWrite(3, HIGH); else digitalWrite(3, LOW);
    if(pwm3[i]) digitalWrite(4, HIGH); else digitalWrite(4, LOW);
    i = i + 1;
    delayMicroseconds(100);
    }
}



Errore N4

Errore strano, ma qui credo non sia colpa mia, in sostanza devo rappresentare due interi che sono le letture di due sensori identici, be se faccio il classico:

Code: [Select]

Serial.print(valore1);
Serial.print("     ");
Serial.println(valore2);


Il primo valore mi viene rappresentato in modo strano e il fondoscala è a 32bit  :o , mentre il secondo valore funziona perfettamente con un fondoscala a 16bit (65mila e qualcosa). Il tutto cambia invece se aggiungo un carattere come uno spazio PRIMA del primo print. in quel casoil valore viene stampato correttamente a 16bit, si lo sò è strano ma è cosi.

L'ho fatta lunga, lo sò.

Patrick_M

#1
Jun 30, 2018, 06:32 pm Last Edit: Jun 30, 2018, 06:34 pm by Patrick_M
Errore 1
Code: [Select]

if(value > 8) value == 8;

il doppio uguale  serve per fare il confreonto non per assegnare il valore quindi
Code: [Select]

 if(value > 8) value = 8;


Errore 2
sarebbe stato meglio se avessi postato la "funzione come l'hai scritta e non solo il codice eseguito
anche per capire come sono dichiarate/passate le variabili e se ti aspetti un valore di ritorno
comunque penso che
Code: [Select]

void loop() {
  int mioValore=funzione();
}
int funzione() {
  byte dato[1];
  digitalWrite(2, LOW);
  delayMicroseconds(10);
  byte proximity = 0x8;
  Wire.beginTransmission(SENSORE);  //sensore definito globale immagino
  Wire.write(proximity);
  Wire.endTransmission(false);
  Wire.requestFrom(SENSORE, 2);
  dato[0] = Wire.read();
  dato[1] = Wire.read();
  int value = (dato[1]) * 256 + (dato[0]);
  return value;
}

dovrebbe funzionare

errore 3
il contrario di quello che hai fatto prima, se devi fare un controllo ci vuole il doppio uguale
Code: [Select]

 for (i = a; i <= b; ){

quindi
Code: [Select]

 for (i == a; i <= b; ){


per il 4 errore non ci ho capito nulla, troppo poco codice, mancano le dichiarazioni delle variabili e da dove prendono i valori
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

dukeluca86

Patrick_M Grazie per la risposta, allora, intanto qualcosa lo ho risolto, però non tutto. La faccenda del dopiio uguale... vado in un angolino...

Per l'errore 4, i due valori sono due INT, mi ero scordato di scriverlo, quindi il fatto che mi vengano stampati uno con fondoscala a 16bit l'altro a 32 mi sconcerta.

Per l'errore numero 3 non credo di aver sbagliato (oppure sbaglio e penso di essere nel giusto) nel senso che io ho un lungo array di valori ZERO e UNO, sono booleani o byte, ho provato con entrambi e funzionano bene.

poi leggo un potenziometro analogicamente, e riduco la corsa del potenziometro a un valore int con 9 casi da 0 a 8 ok fin qui no ?

Poi con degli IF controllo l'effettivo valore dalla variabile "value" e imposto i valori di A e B di conseguenza.

poi la funzione FOR deve assegnare a I il valore di A e ciclare il FOR sino a raggiungere la condizione B che è sempre traslata di 9 valori piu in alto. Nel frattempo faccio scorrere l'array e ne leggo di volta in volta il valore contenuto. Se il valore è zero mando un uscita bassa, se è uno la mando alta. fine della storia.

Però per qualche motivo non funzionacome dovrebbe.

E non capisco nemmeno perchè mi dici di mettere un uguaglianza al posto di un assegnazione nel ciclo FOR (i == a; i <=b;) ? ? ?

Gia che ci sono manifesto tutta la mia ignoranza e ti chiedo all'inizio del ciclo for, la prima iterazione della variabile "i" viene eseguita prima o dopo dell'istruzione contenuta ?

Patrick_M

Quote
E non capisco nemmeno perchè mi dici di mettere un uguaglianza al posto di un assegnazione nel ciclo FOR (i == a; i <=b;) ? ? ?

Gia che ci sono manifesto tutta la mia ignoranza e ti chiedo all'inizio del ciclo for, la prima iterazione della variabile "i" viene eseguita prima o dopo dell'istruzione contenuta ?
:D :D

mi metto io all'angolo
ragionavo come sopra con l'if e non con il for
col ciclo for praticamente dici:
assegno il valore  (mettiamo zero) 0 alla variabile x
e fino a quando non raggiungo il valore (diciamo 10) ripeti le istruzioni seguenti
e ogni volta che ritorni qui incrementi/decrementi il valore di x di quello che voglio io
quindi il primo ciclo nel caso in esempio lo esegue con x= 0
e l'ultimo con il valore 10 (se c'è scritto x<=10)

per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

Patrick_M

Quote
Per l'errore 4, i due valori sono due INT, mi ero scordato di scriverlo, quindi il fatto che mi vengano stampati uno con fondoscala a 16bit l'altro a 32 mi sconcerta.
continuo a non capire :)

1) come fai a dire fondoscala 16 bit e fondoscala32 bit cosa significa
se sono 2 int hanno valore da -32768 a + 32767 quindi non puoi assegnare un numero più grande
e quindi non è possibile che stampando il primo diventi 2,147,483,647
2) come ti avevo detto serve il codice per capire cosa fai realmente
non è che "per caso" prima di stampare quella variabile fai un'altra print senza "ln" per cui i 2 numeri si accodano diventando all'apparenza uno solo?...


per l'errore 3
Code: [Select]

  if(value == 0) a = 0; b = 8;
  if(value == 1) a = 9; b = 17;
  if(value == 2) a = 18; b = 26;
  if(value == 3) a = 27; b = 35;
  if(value == 4) a = 36; b = 44;
  if(value == 5) a = 45; b = 53;
  if(value == 6) a = 54; b = 62;
  if(value == 7) a = 63; b = 71;
  if(value >= 8) a = 72; b = 80;

questo è sbagliato!
è come se fosse scritto così:
Code: [Select]

 if (value == 0) {
   a = 0;
}
b = 8;
if (value == 1) {
   a = 9;
}
b = 17;
if (value == 2) {
   a = 18;
}
b = 26;
if (value == 3) {
   a = 27;
}
b = 35;
if (value == 4) {
   a = 36;
}
b = 44;
if (value == 5) {
   a = 45;
}
b = 53;
if (value == 6) {
   a = 54;
}
b = 62;
if (value == 7) {
   a = 63;
}
b = 71;
if (value >= 8) {
   a = 72;
}
b = 80;

cioè il valore di b a prescindere dagli if alla fina sarà sempre 80
questo perchè il ciclo if se non si usano le parentesi graffe considera come facente parte dell'if solo la prima istruzione successiva
ecco perchè è bene usare sempre le graffe ;)
e farlo diventare:
Code: [Select]

if (value == 0) {
   a = 0;
   b = 8;
}
if (value == 1) {
   a = 9;
   b = 17;
}
if (value == 2) {
   a = 18;
   b = 26;
}
if (value == 3) {
   a = 27;
   b = 35;
}
if (value == 4) {
   a = 36;
   b = 44;
}
if (value == 5) {
   a = 45;
   b = 53;
}
if (value == 6) {
   a = 54;
   b = 62;
}
if (value == 7) {
   a = 63;
   b = 71;
}
if (value >= 8) {
   a = 72;
   b = 80;
}


però..... renditi conto che tutta sta sfilza di if la puoi sostituire con 2 semplici righe ;)
Code: [Select]

a= value*9;
b=a+8;

:D
 



per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

dukeluca86

Seeeeeeee me l'hai risolta ! ! ! Effettivamente l'errore era mio eh eh, il ciclo if vuole le parentesi per piu di una istruzione, me lo devo ricordare. Un GRAZIE è d'obbligo.

Per l'altra faccenda invece, beh posso dire che stampa il numero a 16 bit perchè il fondoscala è 2 alla 16 (65mila e spicci), mentre l'altro me lo stampava a 32 bit perchè il fondoscala era 2 alla 32 (4.294.967.295).

Patrick_M

#6
Jul 02, 2018, 07:54 pm Last Edit: Jul 02, 2018, 07:55 pm by Patrick_M
Seeeeeeee me l'hai risolta ! ! ! Effettivamente l'errore era mio eh eh, il ciclo if vuole le parentesi per piu di una istruzione, me lo devo ricordare. Un GRAZIE è d'obbligo.

Per l'altra faccenda invece, beh posso dire che stampa il numero a 16 bit perchè il fondoscala è 2 alla 16 (65mila e spicci), mentre l'altro me lo stampava a 32 bit perchè il fondoscala era 2 alla 32 (4.294.967.295).
io so de coccio :D
Code: [Select]

int variabile1 = 1;
int variabile2 = 2;

Serial.print(variabile1);
Serial.print("   ");
Serial.println(variabile2);

essendo il risultato della stampa dei 2 valori qui sopra:
Code: [Select]

1   2

come fai a dirmi qual'è il fondoscala del primo e del secondo?




per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

dukeluca86

Hai ragione, ma non sei tu di coccio, sono io che non ho detto tutto eh eh.
In pratica i due valori li prelevo tramite due sensori di luce che contatto tramite i2c.

Assegno ogni valore ad una variabile e siccome i sensori mi rispondono con due parole da 8 bit che vanno poi assemblate in un int, mi aspetto in uscita un print di 16 bit, tanto piu che la variabile è esplicitata in INT quindi... boh !

Patrick_M

#8
Jul 07, 2018, 10:10 am Last Edit: Jul 07, 2018, 10:12 am by Patrick_M
la situazione non cambia :D

Code: [Select]

int sensore1= (sensore1Word1<<8) + sensore1Word2
int sensore2 = (sensore2Word1<<8) + sensore2Word2

non può diventare a 32 bit al limite se cerchi di infilarci un numero più grande (32 bit)viene comunque troncato a 16 bit cioè perdi la parte eccedente.
e ripeto se non leggi un numero superiore a 32767 come fai a dire che è a 32 bit

occhio però:
se
Code: [Select]

sensore1Word1=255
sensore1Word2=255

sensore1 non è 65535 :)
Code: [Select]

int sensore1= (sensore1Word1<<8) + sensore1Word2

ma equivale a -1 ;)
per ottenere 65535 devi cambiare tipo di variabile in:
Code: [Select]

unsigned int sensore1= (sensore1Word1<<8) + sensore1Word2

intero senza segno....
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

dukeluca86

Eh lo sò che non dovrebbe... però lo fa !

In sostanza questi sensori mi restituiscono 0 al buio totale e 65mila e spicci in saturazione.

Però per qualche assurdo motivo la prima volta che printo il valore me lo stampa cosi a 32 bit, mentre se prima printo un carattere spazio (ma forse anche altri caratteri non ho provato) sulla linea, allora tutto funziona bene.

Buggettino ?

dukeluca86

PS Magari non c'entra nulla, ma io per spostare la parola alta piu avanti l'ho moltiplicata per 256 in modo da farla scorrere, qual'è il modo piu efficente secondo te tra questi:

int sensore1= (sensore1Word1<<8) + sensore1Word2  // il tuo

int sensore1= (sensore1Word1 * 256) + sensore1Word2  // il mio

Patrick_M

è la stessa cosa
però se tu mi parli di valori da 0 a 65535 allora non devi usari int ma come ti ho detto unsigned int
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

dukeluca86

Potrebbe essere riferito a questo il problema che riscontro ? Cioè in sostanza con un normale INT se eccedo la metà della capacità dell' int, si verifica un overflow fino al minimo valore negativo giusto ?

Patrick_M

#13
Jul 08, 2018, 01:31 pm Last Edit: Jul 08, 2018, 01:39 pm by Patrick_M
Quote
Cioè in sostanza con un normale INT se eccedo la metà della capacità dell' int, si verifica un overflow fino al minimo valore negativo giusto ?
non la metà del valore (anche se poi in effetti è così) ma l'ultimo bit a sinistra, che quando è messo ad 1 significa che la cifra è negativa.
quindi
Code: [Select]

0111111111111111 = + 32767
1000000000000000 = - 32768
1111111111111111 = - 1


certamente! come dicevo devi sicuramente usare gli unsigned int oppure i long per farci stare numeri fino a 65535
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

Go Up