Questa variabile LONG mi fa impazzire !!!

Ciao a tutti

sto impazzendo provando a realizzare un contacicli con un valore max importabile di 999999 che mi serve a contare i giri di una biella (decremento) e quando arriva a 0 si deve fermare.

Il problema è che anche impostando come long la variabile non va oltre a 32767 ...come mai??? A cosa serve allora una variabile long?

Ho anche provato a mettere L dopo il valore ma non cambia nulla ...come posso fare? Ho letto una marea di posts ma pur provando tutto quello che ho trovato (e capito) non sono riuscito nel mio intento.

Grazie!

Allega tutto il tuo codice. Un long arriva a + e - 2 miliardi circa. Ci sarà un errore da qualche parte. Senza vedere il codice è impossibile dirti dov'è l'errore. Regolamento, sezione 7 spiega come postare il codice. :)

Ecco il codice …il funzionamento è banale, tramite una tastiera si inserisce un numero (limitato a 999999) che poi verrà utilizzato per il contatore.

Grazie per l’aiuto, non ho mai programmato e mi sono avvicinato al mondo Arduino da pochissimo ricavandone un mondo di soddisfazioni grazie anche ad una a comunità veramente incredibile . Che bello!

#include <genieArduino.h>

int keyboardValue;
long cicli = 0;

void setup() 
{  
  genieBegin (GENIE_SERIAL, 9600); 
  genieAttachEventHandler(handleGenieEvent);

  pinMode(4, OUTPUT);  // D4 su Arduino come Output
  digitalWrite(4, 1);  // Reset il Display
  delay(100);
  digitalWrite(4, 0);  // 
  delay (3500); //
	  
  genieWriteObject (GENIE_OBJ_FORM, 0, 0);  
}

void loop (void)
{ 
  genieDoEvents();
  if (cicli >= 999998) { cicli = 999999; } //verifica che cicli non vada oltre 999999
  genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x00, cicli); //scrive su leddigits(0) il valore della variabile
}

void handleGenieEvent (void) //funzione che prende il numero digitato e lo assegna alla variabile
  {
    if (Event.reportObject.index == 0x00)	// controlla che il dato arrivi da Keyboard0
    {  
      keyboardValue = genieGetEventData(&Event); // assegna il tasto digitato Keyboard0
     
   switch (keyboardValue) {   
     case '1':
     cicli = (cicli*10) + 1;
     break;
   
     case '2':
     cicli =  (cicli*10) + 2;
     break;
     
     case '3':
     cicli =  (cicli*10) + 3;
     break;
     
     case '4':
     cicli =  (cicli*10) + 4;
     break;
     
     case '5':
     cicli =  (cicli*10) + 5;
     break;
     
     case '6':
     cicli =  (cicli*10) + 6;
     break;
     
     case '7':
     cicli =  (cicli*10) + 7;
     break;
     
     case '8':
     cicli =  (cicli*10) + 8;
     break;
     
     case '9':
     cicli =  (cicli*10) + 9;
     break;
     
     case '0':
     if (cicli != 0) {
     cicli = (cicli*10) + 0;
     }
     else cicli = 0 ;
     break;
     
     default:
     cicli = 0;
     break;
   }
  }
 }

Prova a modificare cosi i calcoli:

cicli = (cicli*10L) + 1;

oppure

cicli = (cicli*long(10)) + 1;

Ma prova a stampare su Serial Monitor la variabile. Sei sicuro che la variabile non è gestita bene ma è la genieWriteObject() che non accetta long?
Non conosco quella libreria, ma qui:
https://github.com/4dsystems/ViSi-Genie-Arduino-Library/blob/master/genieArduino/genieArduino.h
scrivono:

uint16_t	genieWriteObject	(uint16_t object, uint16_t index, uint16_t data);

Questo vuole dire che sono tutti valori unsigned int, anche l’ultimo. Quel long cicli viene castrato a int

genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x00, cicli); // cicli da long con segno a unsigned int !!!

Mi sà che dovrai convertire il valore in stringa (array di char e NON oggetto String) e usare la:

uint16_t	genieWriteStr (uint16_t index, char *string);

Avevo già provato a scrivere long(10) ma non sembrava funzionare, appena riesco riprovo controllando bene il tutto. L'assistenza di 4D mi ha detto che il limite non è dato dal monitor ma dai limiti del sw nella gestione delle variabili ...mah, adesso provo a scrivere la variabile sul serial monitor e ti faccio sapere. Grazie, buona serata

Hai ragione! In effetti usando Serial come input e come scrittura la variabile viene correttamente gestita …a questo punto mi si complica ancora di più !
Il display dovrebbe esclusivamente ricevere dei numeri (variabile cicli) e visualizzarli ma forse non è così. Allego il piccolo sketch per provare la variabile
long cicli;

//#include <genieArduino.h>

int keyboardValue;
long cicli = 0;

void setup() 
{  
//  genieBegin (GENIE_SERIAL, 9600);  //Serial1
  
  Serial.begin (9600);

// genieAttachEventHandler(handleGenieEvent);

//  pinMode(4, OUTPUT);  // Set D4 on Arduino to Output (4D Arduino Adaptor V2 - Display Reset)
//  digitalWrite(4, 1);  // Reset the Display via D4
//  delay(100);
//  digitalWrite(4, 0);  // unReset the Display via D4
  
//  delay (3500); //let the display start up
  	  
//  genieWriteObject (GENIE_OBJ_FORM, 0, 0);  
}
void loop (void)
{  
   if (Serial.available() > 0) {
   handleGenieEvent();
 } 
//  static long waitPeriod = millis();
//  static int led2Val = 0;
//  static int led2AddVal = 1 

  Serial.println (cicli); 

 // genieDoEvents();
  
//  if (cicli >= 999998) { cicli = 999999; }
//  genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x00, cicli);
  
//  if (millis() >= waitPeriod) 
//  {
    // Write to CoolGauge0 with the value in the gaugeVal variable
 //   genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x01, led2Val);
 //   led2Val += led2AddVal;
 //   if (led2Val == 9) led2AddVal = -1;
 //   if (led2Val == 0) led2AddVal = 1;
 //   waitPeriod = millis() + 300;
 // }
}


void handleGenieEvent (void)
{ 
//  genieFrame Event;
//  genieDequeueEvent(&Event); // Remove this event from the queue

// if(Event.reportObject.cmd == GENIE_REPORT_EVENT)
//  {
//  if (Event.reportObject.object == GENIE_OBJ_KEYBOARD) // If this event is from a Keyboard
//  {
//    if (Event.reportObject.index == 0x00)	// If from Keyboard0
//    {  
//      keyboardValue = genieGetEventData(&Event); // Get data from Keyboard0

 keyboardValue = Serial.read();   
    
   switch (keyboardValue) {
     
     case '1':
     cicli = (cicli*10) + 1;
     break;
     
     case '2':
     cicli =  (cicli*10) + 2;
     break;
     
     case '3':
     cicli =  (cicli*10) + 3;
     break;
     
     case '4':
     cicli =  (cicli*10) + 4;
     break;
     
     case '5':
     cicli =  (cicli*10) + 5;
     break;
     
     case '6':
     cicli =  (cicli*10) + 6;
     break;
     
     case '7':
     cicli =  (cicli*10) + 7;
     break;
     
     case '8':
     cicli =  (cicli*10) + 8;
     break;
     
     case '9':
     cicli =  (cicli*10) + 9;
     break;
     
     case '0':
     if (cicli != 0) {
     cicli = (cicli*10) + 0;
     }
     else cicli = 0 ;
     break;
     
     case ' ':
     cicli =  0;
     break;
     
  //   default:
    // cicli = 0;
   //  break;
   }
  }

Ho visto che il limite è dato dal processore dell'lcd che trasforma tutte le variabili in intere. Mi hanno consigliato di creare due numeri di 4 digit in modo da comporre numeri maggiori di 32767 ma la cosa diventa per me complicata ...come si possono decrementare due variabili come se fossero lo stesso numero?

Beh, devi fare un pò di codice in più. Quando la prima sfora 9999, la azzeri e il riporto lo sommi alla seconda:

int hVar=0,lVar=0;   // high e low part
... 
lVar++;                         // 0->9999 
if(lVar>9999)         // if low part exceed
{ lVar=0; hVar++;      
}

Oppure fare il contrario, usi una variabile long che incrementi come al solito e poi la spezzi in due quando la devi stampare. Basta una divisione e una sottrazione.

long myCnt;
int lVar,hVar;
...
hVar=int(myCnt/10000.0);       // parte alta   1234567  => int(123.4567) => 123
lVar=myCnt-(long(hVar)*10000.0));

// parte bassa 1234567-123*10000=>1234567-1230000=> 4567

…più leggo le tue risposte più mi rendo conto che ho molto, moltissimo da imparare! Il tutto risolto facilmente con un semplice gioco matematico !!!
Guarda cosa mi ero inventato io ne frattempo …

    if (cicli <= 99) { 
     cicli1 = cicli; 
     genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x10, cicli1);
    }  
    else { 
     cicli2 = cicli;
     genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x09, cicli2);

Questa parte è relativa all’input del numero di cicli

Questa parte che segue è invece relativa al conteggio (decrementale):

 cicli1 = cicli1 - 1;        
      if (cicli1 == 0 && cicli2 != 0) {
       cicli2 = cicli2 - 1;
       cicli1 = 99;
      }         
      if ( cicli1 == 0 && cicli2 == 0 ) { flag = 3;}     //Fine prova setta il Flag a 3 come se fosse premuto stop

Scusa ma non ci ho capito molto. Non conosco questo oggetto GENIE. Ma questo che fa? genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x10, cicli1); Passi un 0x10 e poi un 0x09, id di qualcosa. Ma non capisco cosa sia. E' la 10 e 9 cifra del display? Purtroppo non capisco come funziona quel display. Hai un link ?

Nel frattempo ho modificato il mio precedente post dopo aver guardato con attenzione cosa mi avevi scritto …

In pratica il numero che vedi è il numero dell’oggetto, chiamato Leddigits, che altro non è che tipo un display digitale con 4 cifre.
Nel mio esempio ho suddiviso il mio numero nel primo Leddigits 0x10 che visualizzerà le decine e le unità come variabile cicli1, mentre nel Leddigits 0x09 visualizzo la variabile cicli2 che sarà di quattro cifre per un totale max di 999999.
Il link è 4dsystems.com
Grazie mille per il tuo aiuto, ciao

Quindi

A.genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x10, cicli1);
B.genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x09, cicli2);

Con A devi visualizzare 2 cifre (unità e decine) e su B le restanti 4 cifre. Esempio 123456 56 su A e 1234 su B, giusto? Allora usa una unica variabile long così non devi cambiare il programma. Poi quando devi stampare il numero lo dividi in 2 (ciclo è la tua long, cicloA e cicloB quelle da stampare):

cicloB= int(ciclo/100L);       // 123456/100=> 1234.56  parte intera => 1234
cicloA= int(ciclo%100L);     // operatore modulo % ritorna il resto della divisione.     123456/100=>56
genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x10, cicloA);
genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x09, cicloB);

Perfetto, direi che il post si può dare per risolto!
Grazie ancora,
Sergio

Interessante il modo di spezzare un numero. Me lo segno.