Banale...NON per me!!!

Ciao,

Vi sto per chiedere aiuto per una banalità…ma io non riesco a saltarci fuori…

Naturalmente su Arduino e C sono alle prime armi, quindi ho problemi nello scrivere uno sketch che mi permetta di fare:

1° Controllo un valore (ingresso analogico)
2°Abilito un’uscita digitale se quel valore è maggiore di…
3°Verifico se il valore è aumentato o diminuito
4°Se il valore aumenta comando una seconda uscita

Sul il punto 1e 2 nessun problema :grin:

Sul punto 3 riesco a controllarlo ma non riesco a comandare le uscite come vorrei… :~ =(

Premetto che il segnale in ingresso può sia aumentare che diminuire indipendentemente dall’uscita che ho abilitato…

Spero di aver scritto in maniera comprensibile :zipper_mouth_face:
Non posto il codice che ho fatto perchè oltre che essere banale per i primi 2 punti per il 3 e 4 punto è pieno di prove e righe a caso…

Se qualcuno a la voglia di aiutarmi a capire come fare ed approfondire il discorso\conoscenze (mie)… gli sarò molto grato :stuck_out_tongue:

Grassie e ciao…

Ciao rastino, se non ti sei ancora presentato fallo qui: http://forum.arduino.cc/index.php?topic=113640.915

Leggi il regolamento qui: http://forum.arduino.cc/index.php?topic=149082.0

Non avere remore a postare il tuo codice, quindi togli il codice che non funziona e postalo usando il tag #

Come vorresti comandare le 2 uscite? Fornisci il range di valori entro il quale uscita A deve essere HIGH e il range di quando deve essere LOW Fai la stessa cosa per l'uscita B.

Il problema sembra semplice ma nulla è banale qui, specie quando lo si affronta per la prima volta.

Ciao.

Ciao,

Per la presentazione dovrebbe già esserci un mio post....se non è stato cancellato mi ero già presentato un pò di tempo fa....poi non sono uno che scrive molto..... :) :zipper_mouth_face:

Per le uscite diciamo 2 uscite digitali "Destra e Sinistra"

Sull'ingresso analogico ha un valore che varia tipo una "U" con un punto più basso(valore minimo)......

Io devo cercare quello, qualsiasi sia il valore, l'importante che sia il minimo...... Quindi l'intenzione era far girare un motore a DX o a SX in base al valore letto.... Vedila come se avessi un potenziometro con 0 centrale....ma quello zero non sempre si trova in centro!!!! =(

Spero di essere stato chiaro nell'esporre......

Ti ringrazio

Premettiamo una cosa, qua non facciamo né corsi di programmazione né scrittura di codice su commissione ;) ;) Primo perché la programmazione è importante quanto l'elettronica, nell'ambito dei microcontrollori: sono 2 cose che vanno a braccetto, devi conoscerle entrambe, quindi se ti mancano delle basi di programmazione, devi fartele. :P Secondo, se qualcun altro scrive i programmi al posto tuo, tu non impari nulla ;)

Quindi, come ti ha detto Mauro, pubblica il codice che non ti funziona e possiamo magari dirti se ci sono errori logici o sintattici. Ma senza codice, non possiamo sapere dov'è che sbagli.

rastino:

Naturalmente su Arduino e C sono alle prime armi, quindi ho problemi nello scrivere uno sketch che mi permetta di fare:

Se qualcuno a la voglia di aiutarmi a capire come fare ed approfondire il discorso\conoscenze (mie)… gli sarò molto grato :stuck_out_tongue:

Grassie e ciao…

Ciao,

A livello di programmazione industriale mi ritengo un discreto programmatore…Lo faccio per lavoro da anni… :%
Non consco bene il C…usato a scuola anni fà, l’ho dimenticato non avendolo mai usato finito la scuola… ]:smiley:

[#]

#include <LiquidCrystal.h>
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

const int referenceVolts = 5;
const int Rif = 14;  
int Vval;
int val;
int SX = 43;
int DX = 42;

void setup(){
  lcd.begin(16, 2);
  Serial.begin(9600);
  
  pinMode(SX, OUTPUT);  
  pinMode(DX, OUTPUT);  
}

void loop()
{
  float VRif;
  VRif=analogRead(Rif);

  float Vval;
  lcd.setCursor(0, 1);
  lcd.print("Volt= ");
  Vval = (VRif/(1023/5));
  Vval = (Vval*10);
  lcd.print(Vval,1);
   
 if (Vval>12)
 {  
if (val>Vval) {digitalWrite(DX, LOW); digitalWrite(SX, HIGH);delay (1000);}

     else {digitalWrite(DX, HIGH);digitalWrite(SX, LOW);  delay (1000);}
}
else {digitalWrite(DX, LOW);digitalWrite(SX, LOW);}
 Serial.println(val);
  Serial.println(Vval);
    delay(500);
  val=Vval;
  }

Spero di aver incollato il codice in maniera corretta… :~

Chiedo scusa se non sono nato “IMPARATO” e se ho chiesto aiuto su un forum…
Non ho chiesto di scrivermi il codice…ma se qualcuno aveva voglia di spiegarmi come fare…
Non ho chiesto un corso di programmazione…ma se qualcuno aveva voglia di spiegarmi come fare…

Ringrazio ancora chi avrà voglia di SPIEGARMI come fare…altrimenti rimarrò nella mia ignoranza sgolosando di Voi guru della programmazione di Arduino… :blush:

Una prima dritta sul C. Questo può darti dei problemi:

Vval = (VRif/(1023/5));

Perchè Vval l'hai dichiarata float, ma quelle costanti 1023 e 5 vengono interpretate del C come int e perciò effettua i calcoli come int e poi il risultato viene messo in un float. Meglio scrivere forzando le virgole a zero

Vval = (VRif/(1023.0/5.0));

Sempre postare il proprio codice, si capisce anche da quello ciò che intendi fare. Ti vergognerai mica di quello che scrivi ? :grin: ]:) :grin:

nid69ita:
… Ti vergognerai mica di quello che scrivi ? :grin: ]:slight_smile: :grin:

Si…MOLTO!!!.. :blush:

Intanto grazie…

Ora che posso osservare il codice devo dire che hai un problema da affrontare di diversa natura, cioè devi esercitarti a scrivere del codice più leggibile, per io faccio molta fatica a capire cosa fa il codice.

Scrivi sempre una istruzione per riga, quindi una istruzione, il punto e virgola e poi sempre a capo nel rigo seguente.

Per le uscite diciamo 2 uscite digitali "Destra e Sinistra"

Sull'ingresso analogico ha un valore che varia tipo una "U" con un punto più basso(valore minimo)......

Io devo cercare quello, qualsiasi sia il valore, l'importante che sia il minimo...... Quindi l'intenzione era far girare un motore a DX o a SX in base al valore letto.... Vedila come se avessi un potenziometro con 0 centrale....ma quello zero non sempre si trova in centro!!!! smiley-cry

Spero di essere stato chiaro nell'esporre......

Si corretta esposizione, ma mi mancano delle informazioni. Al pin "Rif" cosa c'è collegato? un potenziometro? Chiaro il discorso della U, diciamo che visto che non ci sono valori negativi ed essendo conosciuti gli estremi di U il valore minore è 1023 / 2 = 511, ora però dici che non sempre lo zero si trova al centro. mmm.... sembra proprio che l'asse del motore è connesso meccanicamente al perno del potenziometro, ma... boo, prova a descrivere meglio l'hardware e altre info che fanno si che ciò che sai tu lo sappiamo anche noi.

Si....MOLTO!!!....... smiley-red

Intanto grazie....

A parte lo scherzo, ma se realmente è così capisci che ciò è limitante, penso che potrai sopportare una critica se poi questa è costruttiva, insomma è il prezzo da pagare per migliorare.

Ciao.

Allora.... :cold_sweat: Approfondisco il discorso U....

In realtà il valore non è 1023 / 2 = 511, perchè la base della U diciamo che si sposta!!! La forma di U era per capire di avere un valore minimo, che sicuramente non è al centro, ma spostandosi sia a DX che a SX il valore aumenta....

Vedila come un ponte di misura, dove devo regolare un "potenziometro" per trovare il valore minore letto dall'ingresso analogico tramite una "sonda"....(il valore di "0" in Volt va da un minimo di 200mV a massimo 2Volt (SPERO!!!))

Per il codice sono a conoscenza di scrivere male..... Cercherò di migliorare con il tempo....e i consigli.....

grazie

rastino: Per il codice sono a conoscenza di scrivere male.....

Oltre che seguire il consiglio di Mauro nella scrittura del codice, usa la funzione dell'IDE che trovi sotto Tools-> AutoFormat ... ti sistemerà automaticamente e correttamente tutte le indentature ;)

Guglielmo

Ma in riferimento al tuo codice, hai una serie di variabii. Non tutte con un nome chiarificatore (e non ci sono commenti). Vval e val soprattutto, quale tra queste due dovrebbe essere il tuo minimo?

Questi sono pin, giusto?

int SX = 43;
int DX = 42;

Se si, allora dichiarali const byte (e cambiagli nome, aggiungi pin davanti):

const byte pinSX = 43;
const byte pinDX = 42;

Le due variabili dichiarate nella loop(), le due float, portale in cima assieme alle altre, almeno abbiamo un unico posto dove sono dichiarate.

mmmmm... non è per niente semplice, e non ho la soluzione in tasca.

Forse: Il primo valore letto (primo all'istante T) con cosa deve essere comparato? Con 200mV con 2000mV o con un valore ricavato all'instante T+1.

La funzione analogRead() non può restituire valori negativi per cui usiamo il tipo di dato senza segno grande abbastanza per contenere il massimo valore 1023, e quindi scegliamo il tipo senza segno grande 16 bit

uint16_t aValue = 0;         
uint16_t oldValue = 0;

start loop {
    aValue = analogRead(Rif);

    if (oldValue > aValue) {
        gira a destra
        oldValue = aValue
        ferma motore
    } else {
        gira a sinistra
        oldValue = aValue
        ferma motore
    }
}

mmmmm.. sembra troppo semplice. La prima volta oldValue == 0 e aValue sarà sicuramente maggiore di oldValue, per cui il motore inizierà a girare a sinistra. Ora oldValue diventa uguale ad aValue supponiamo sia 500. La seconda volta 500 > aValue se si girerà a destra il motore se no continuera a girare a sinistra

Il problema è che andrà avanti così all'infinito se ed oscillerà in più e in meno sempre intorno ad un valore, dopo x tempo il programma potrebbe fermare il motore facendo un calcolo basato sulla storia dei valori ricavati in 5, 10, o più loop, come dire se dopo 100 loop la differenza tra il primo e il secondo e tra il secondo e il terzo e tra il terzo ed il quarto e così via è nel range di valori di es 10mV fermati.

Altro che banale.

@nid69ita Si ha riconosciuto di avere dei problemi a scrivere codice, ma ancora non ha compreso l'entità dei problemi, e cosa comporta il codice scritto così. Il codice è difficile da leggere e non si capisce quello che fa e si perde spesso il filo. Per adesso si è concentrato sul problema principale pensando erroneamente che non è di aiuto rendere il codice più leggibile.

Ciao.

Ciao,

Confermo che

int SX = 43; int DX = 42;

Sono rispettivamente le uscite che comandano il motore a girare a Destra e a Sinistra....

Vval e val soprattutto, quale tra queste due dovrebbe essere il tuo minimo?

In teoria dovrebbe essere lo stesso valore, il primo memorizzato nel ciclo precedente Vval e il secondo la lettura attuale val, per capire se il valore aumenta o diminuisce....

Il primo valore letto (primo all'istante T) con cosa deve essere comparato? Con 200mV con 2000mV o con un valore ricavato all'instante T+1.

Per il primo ciclo penso non ci siano problemi anche se viene attivato un'uscita per un ciclo.... Anche il mio schifo di codice dovrebbe fare così...almeno da quello che vedo sulla seriale.....

Si ha riconosciuto di avere dei problemi a scrivere codice, ma ancora non ha compreso l'entità dei problemi, e cosa comporta il codice scritto così. Il codice è difficile da leggere e non si capisce quello che fa e si perde spesso il filo. Per adesso si è concentrato sul problema principale pensando erroneamente che non è di aiuto rendere il codice più leggibile.

Ma in riferimento al tuo codice, hai una serie di variabii. Non tutte con un nome chiarificatore (e non ci sono commenti).

Per quanto riguarda alla "calligrafia" del codice, quello è il motivo perchè non volevo postarlo!!!! Immaginate che sia un blocco di appunti di "brutta", dove risolvere un problema.... La scrittura la devi capire solo tu.....sono appunti.....e li riporti in "bella" quando hai risolto il problema....

Provo a riscrivere il codice commentandolo.....

Grazie a tutti....

inserisco il codice scritto in “bella”??? :grin:

Il problema è che non funziona o meglio,funziona all’incirca come prima… :0
Finchè il valore scende ok, ma quando si supera la base della “U”, quindi valore minimo di quella lettura, non inverte la rotazione del motore…

#include <LiquidCrystal.h>
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

const int referenceVolts = 5; //Valore di riferimento
const int Rif = 14;  //Pin di ingresso segnale da leggere
float Vval; //Valore visualizzato sul LCD per comodità
uint16_t aValue =0; //Valore della lettura attuale
uint16_t oldValue  =0; //Valore della lettura memorizzata del ciclo prima
const byte pinSX = 43; //Pin motore rotazione SX
const byte pinDX = 42; //Pin motore rotazione DX

void setup(){
  lcd.begin(16, 2);
  Serial.begin(9600);

  pinMode(pinSX, OUTPUT);  //Setto pin come Uscita motore rotazione DX
  pinMode(pinDX, OUTPUT);  //Setto pin come Uscita motore rotazione DX


}

void loop()
{
  aValue =analogRead(Rif);             //Legge il valore di riferimento
                                       // Settiamo LCD per leggere il valore in mVolt
  lcd.setCursor(0, 1);
  lcd.print("mVolt= ");
  Vval  = (aValue/(1023.0/5000.0));
  lcd.print(Vval,1);
  
  
  if (aValue >12)                      //confronta il valore letto con il set point accettabile
  {
    if (oldValue > aValue) {
      digitalWrite(pinDX, HIGH);      // gira a destra
      delay(500);
      oldValue = aValue;              //carica il calore
      delay(500);
      digitalWrite(pinDX, LOW);       //ferma motore destra

    } 
    else {
      digitalWrite(pinSX, HIGH);    // gira a sinistra
      delay(500);
      oldValue = aValue;            //carica il calore
      delay(500);
      digitalWrite(pinSX, LOW);     //ferma motore sinistra

    }
  } 

//scrivo sulla seriale per controllo in fase di test

  Serial.println(aValue);
  Serial.println(oldValue);


}

Grazie ancora a tutti… :wink:

La togli questa :

if (aValue >12) { }

Non vorrei che aValue in dato momento fosse meno di 12. Inoltre dopo puoi provare senza delay().

Ciao.

MauroTec: La togli questa :

if (aValue >12) { }

Non vorrei che aValue in dato momento fosse meno di 12. Inoltre dopo puoi provare senza delay().

Ciao.

Sicuramente (aValue >12) questo dovrebbe servire ad evitare che continui a muovere il motore a dx o sx....

Come ho scritto nel commento del codice, dovrebbe essere il set point accettabile per la misura...(da regolare dopo alcune prove), quindi quando il valore letto scende sotto quel dato vale mi sta bene che il motore si fermi....

Comunque non inverte il senso di rotazione quando dopo essere diminuito comincia a risalire....

Avete suggerimenti???

Io sto provando ma proprio non riesco a cavarne nulla....

GRazie ancora a tutti

Ciao rastino ho preso il tuo ultimo sketh, ho collegato 2 led al posto dei motori, un potenziometro in ingresso e l'ho provato. Quando aValue diminuisce il motore gira a DX quindi nessun problema. Quando aValue aumenta partendo da un valore minore di 12 il primo comando del motore è quello di far girare a DX il motore. Penso sia legato al fatto che non aggiorni il valore di oldValue se aValue >12, infatti se il valore di aValue passa da 20 a 10 oldValue rimane 20 quindi quando aValue aumenta a 13 ti ritrovi con oldValue a 20 quindi gira a DX. ho corretto così il codice aggiungendo oldValue = aValue; fuori dal if(aVAlue>12) e così mi funziona.

p.s.

rastino: Sicuramente (aValue >12) questo dovrebbe servire ad evitare che continui a muovere il motore a dx o sx....

i due led della mia prova a potenziometro fermo continuano ad alternarsi causa lettura di aValue non stabile. se vuoi evitarlo dovresti metter un offset (ammesso che si dica così) ovvero se oldValue > aValue e oldValue - aValue > 5 (ad esempio) ecc...

ciao Pippo72

E va be…
non avevo niente da fare e così ho fatto altre modifiche.

#include <LiquidCrystal.h>
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5
const int offset = 5; // variazione oltre la quale far muovere
const int referenceVolts = 5; //Valore di riferimento
const int Rif = A0;  //Pin di ingresso segnale da leggere
float Vval; //Valore visualizzato sul LCD per comodità
uint16_t aValue =0; //Valore della lettura attuale
uint16_t oldValue  =0; //Valore della lettura memorizzata del ciclo prima
const byte pinSX = 11; //Pin motore rotazione SX
const byte pinDX = 12; //Pin motore rotazione DX
void setup(){
  lcd.begin(16, 2);
  Serial.begin(9600);
  pinMode(pinSX, OUTPUT);  //Setto pin come Uscita motore rotazione DX
  pinMode(pinDX, OUTPUT);  //Setto pin come Uscita motore rotazione DX
}
void loop()
{
  aValue =analogRead(Rif);             //Legge il valore di riferimento
  // Settiamo LCD per leggere il valore in mVolt
  lcd.setCursor(0, 1);
  lcd.print("mVolt= ");
  Vval  = (aValue/(1023.0/5000.0));
  lcd.print(Vval,1);
  if (oldValue > aValue && (oldValue - aValue > offset)) {
    digitalWrite(pinDX, HIGH);      // gira a destra
    delay(50);
    oldValue = aValue;              //carica il calore
    delay(50);
    digitalWrite(pinDX, LOW);       //ferma motore destra
  } 
  if (oldValue < aValue && (aValue - oldValue > offset)) {
    digitalWrite(pinSX, HIGH);    // gira a sinistra
    delay(50);
    oldValue = aValue;            //carica il calore
    delay(50);
    digitalWrite(pinSX, LOW);     //ferma motore sinistra
  }
  //scrivo sulla seriale per controllo in fase di test
  oldValue = aValue;
  Serial.print("attuale = ");
  Serial.print(aValue);
  Serial.print("  vecchia = ");
  Serial.println(oldValue);
}

Ho tolto if(aValue>12) e ho messo l’offset.
ciao.
Pippo72

Ciao,

Io ho buttato giù questo…

#include <LiquidCrystal.h>
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

const int referenceVolts = 5; //Valore di riferimento
const int Rif = 14;  //Pin di ingresso segnale da leggere
float Vval; //Valore visualizzato sul LCD per comodità
uint16_t aValue =0; //Valore della lettura attuale
uint16_t oldValue  =0; //Valore della lettura memorizzata del ciclo prima
const byte pinSX = 43; //Pin motore rotazione SX
const byte pinDX = 42; //Pin motore rotazione DX

void setup(){
  lcd.begin(16, 2);
  Serial.begin(9600);

  pinMode(pinSX, OUTPUT);  //Setto pin come Uscita motore rotazione DX
  pinMode(pinDX, OUTPUT);  //Setto pin come Uscita motore rotazione DX


}

void loop()
{
  aValue =analogRead(Rif);             //Legge il valore di riferimento
  // Settiamo LCD per leggere il valore in mVolt
  lcd.setCursor(0, 1);
  lcd.print("mVolt= ");
  Vval  = (aValue/(1023.0/5000.0));
  lcd.print(Vval,1);



  Serial.println (aValue);
  Serial.println (oldValue);



  while ((oldValue < aValue)&&(digitalRead(pinDX) ==HIGH))    //Confronto il valore e leggo lo stato del pin
  {
    digitalWrite(pinSX, HIGH);                               //Metto a 0 il pin
    digitalWrite(pinDX, LOW);                                //Metto a 0 il pin
    Serial.println ("punto 1");
    delay(1000);                                             //ritardo
    oldValue = aValue;                                       //Carico il Valore letto in memoria
  } 

  while ((oldValue < aValue)&&(digitalRead(pinSX) ==HIGH))    //Confronto il valore e leggo lo stato del pin
  {
    digitalWrite(pinDX, HIGH);                                //Metto a 1 il pin
    digitalWrite(pinSX, LOW);                                 //Metto a 0 il pin
    Serial.println ("punto 1a");
    delay(1000);                                              //ritardo
    oldValue = aValue;                                       //Carico il Valore letto in memoria
  } 

  while (oldValue <aValue)                                    //Confronto il valore e leggo            
  {
    digitalWrite(pinSX, HIGH);                                 //Metto a 1 il pin
    digitalWrite(pinDX, LOW);                                  //Metto a 0 il pin
    Serial.println ("punto 2");
    delay(1000);                                               //ritardo
    oldValue = aValue;                                         //Carico il Valore letto in memoria
  }

  oldValue = aValue;                                           //Carico il Valore letto in memoria
  Serial.println ("punto 3");
}

E a parte “l’ortografia” la logica di funzionamento c’è…
Quello postato sopra non funziona così…

Sostanzialmente se il valore dopo essere sceso sale dovrebbe invertire l’uscita indifferentemente che sia DX o SX…

Devo provare ad aggiungere “l’off set” come hai suggerito tu…magari domani visto l’orario…

Vi ringrazio e se volete provarlo per vedere come funziona magari mi date nuove dritte e lo commentiamo…

CIao e grazie 1000 a tutti