Programma per controllo motore attraverso sensore ADXL335

Salve a tutti.
Devo realizzare un programma che con l'ausilio di un accelerometro possa comandarmi un display LCD ed un motore ( più precisamente un'elettrovalvola ).

Premessa: in serial monitor ho un offset di 200 ( circa ) sugli ingressi analogici A0, A1, A2. Con il sensore collegato sui suddetti ingressi, da fermo, in serialmonitor mi visualizza 340. Provando a muore il sensore ( ad esempio sull'asse z che sarebbe l'in A2, mentre A0 è l'asse x e A1 l'asse y ) raggiunge un massimo di circa 600 ( a mano ).
Sia per la visualizzazione in seriale del sensore che per l'LCD ho guardato negli esempi già presenti su Arduino..

Quello che devo fare è leggere zpin ( A2 ) e stampare sull'LCD il suo valore. Se zpin supera una certa soglia ( nel mio caso 600 che però non so a cosa è riferito.. cioè devo convertirlo con qualche formula o..? ) metti alto il pin8 ( che quindi è in output ). Mi rendo conto che è un programma banale ma per un deficiente come me è abbastanza.. sono qui da 1 oretta e non riesco a far scattare l'elettrovalvola..

Se qualcuno vuole cortesemente darmi una mano gli sarei grato. Scusate ancora per il tempo che andrò a rubarvi e grazie in anticipo.
Cordiali Saluti.

Edit. Aggiungo il programma che ho fatto..

#include <LiquidCrystal.h>


LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int xpin = A0;                  
const int ypin = A1;                  
const int zpin = A2;                  
int valvola = 8;

void setup()
{
  lcd.begin(16, 2);
  lcd.print("zpin");
  pinMode(valvola,OUTPUT);
}

void loop()
{
  digitalWrite(valvola,LOW);
  lcd.noBlink();
  delay(3000);
  lcd.blink();
  delay(3000);
  if (zpin>500) {
    digitalWrite(valvola,HIGH);
     
}
}

Il problema è quindi che non so quale istruzione gli devo dare per stampare sul display il valore rilevato su zpin ( mi stampa la stringa zpin mentre io vorrei il valore che leggevo in serialmonitor ) e l'elettrovalvola che non scatta..

metti il codice tra i tag

, vedi primo post sticcato in ogni sezione.

[quote]lcd.print("zpin");[/quote]
così gli stai dicendo di stampare la STRINGA zpin. In oltre essendo nel setup verrà stampata una volta all'inizio del programma. Se anche tu avessi scritto giusto, al variare del valore di zpin non è che l'LCD si accorge della variazione e aggiorna la sciritta; devi essere tu a chiamare di nuovo la print() ogni volta!

[quote]const int zpin = A2;[/quote]
così dici che ZPIN è uguale a A2 (cvhe a sua volta è uguale al numero 16, ovvero il secondo pin digitale che possiede anche l'ADC), e dici che è cons, ovvero che non può variare (costante).

poi fai 
[code]if (zpin>500) {

ma se abbiamo detto che ZPIN è costante e uguale a 16.... ovvio che non scatterà mai

forse tu intendevi LEGGERE IL VALORE ANALOGICO DEL PIN 16, quindi

if (analogRead(zpin)>500) {

altro problema:

appena la digitalWrite mette il pin valvola ad HIGH, il loop finisce (e ricomincia da capo), quindi viene esegiuita l'istruzione digitalWrite(valvola,LOW);che spegne la valvola... il tutto avviene in meno di un microsecondo, ovvero più velocemente di 0,0000001 secondi. Non solo tu, ma nemmeno l'elettrovalvola (per via dei tempi di reazione meccanici, che possono anche essere nell'odine dei 100 millisecondi, ovvero 0,1 secondi ) si accorge di essere stata accesa :)[/code]

confermo quello che dice lesto inoltre hai messo nel codice un

 delay(3000);

per ben 2 volte quasi di seguito questo vuol dire che il tuo arduino si blocca per 6 secondi e quello che succede dopo lo verifica ogni 6 secondi.

nel tuo caso quindi arduino verificherà una volta ogni 6 secondi quel

  if (zpin>500) {
    digitalWrite(valvola,HIGH);
}

e se in quell'esatto momento (come dice lesto si tratta di microsecondi anzi meno) non fosse così arduino non farà niente per altri 6 secondi

guarda come funzionano i while e la funzione millis()

se sei all'inizio con la programmazione butta giù un diagramma a blocchi su carta prima di ogni programma il più dettagliato possibile così poi ti verrà molto più facile applicare il tutto

Innanzitutto mi scuso per non aver inserito il codice nella maniera corretta. Grazie infinite per le risposte..

Ho modificato il codice in questo:

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int xpin = A0;                  // x-axis of the accelerometer
const int ypin = A1;                  // y-axis
const int zpin = A2;                  // z-axis (only on 3-axis models)
int valvola = 8;


void setup()
{
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  
  pinMode(valvola,OUTPUT);
}

void loop()
{
  digitalWrite(valvola,LOW);
  lcd.print(analogRead(zpin));
  delay(1000);
lcd.clear();
  // Turn off the blinking cursor:
  lcd.noBlink();
  delay(50);
   // Turn on the blinking cursor:
  lcd.blink();
  delay(50);
  if (analogRead(zpin)>500) {
    digitalWrite(valvola,HIGH);
    delay(2000);
    
     
}
}

Con questo codice l'elettrovalvola scatta correttamente.
Sul display LCD però, con l'accelerometro fermo, mi visualizza 400. Per togliere questo offset dovrei utilizzare due variabili, ad una, attraverso l'analogRead attribuisco il valore di A2 mentre all'altra attribuisco il valore della prima variabile - 400.. ma dopo come faccio a visualizzare sul display la variabile ? Per mettere una stringa banstano le virgolette mentre per leggere il dato direttamente dal pin mi avete detto di utilizzare l'analogRead ( e infatti me lo prende ) ma per dargli il valore di una variabile?

Un altro problema è che abbassando il delay successivo al noBlink e al blink ogni tanto mi scompare il valore.. e c'è qualcosa che non va con l'aggiornamento del dato visualizzato sul display, cioè a volte non faccio in tempo a visualizzare il 500 sul display che sento scattare l'elettrovalvola. Come potrei fare?

allora, l'accelerometro da un'iscita che, per esempio, va da 0 a 5v, giusto?

bene, allora dall'accelerometro normalmente uscirà 2.5V (che sono lo "zero"), se lo muovi in un senso vedrai che sale, diciamo a 3V, e se lo muovi nella direzione opposta lo vedrai scendere a diciamo 2V.

Questo però NON vale per l'asse perpendicolare alla terra: essa "sente" l'accelerazione di gravità, dunque se 1G è pari a, poniamo, 1V, vedrai uscire sempre il valore 3.5V

il problema è che una volta che hai trovato questo valore (che è la metà del voltagio massimo delle uscite), non è reale: temperatura, disturbi, meccanica e vari altri fattori fanno variare questo valore.
Di solito si effettua una calibrazione, e poi si "combatte" con lo shift (il problema che lo zero si sposta, anche se di pochissimo)

Dal datasheet puoi ricavare quanto, secondo i test del produttore, questi valori possono variare, ovvero quanto è affidabile il sensore.

Ora capisco perché il valore stampato sul display cala se lo muovo verso il basso >.< Comunque per il fatto della gravità il sensore è stato calibrato su tutte e 3 le assi e quindi il tuo discorso dovrebbe valere anche per l'asse z ( quello perpendicolare alla terra ).

Grazie comunque per il chiarimento riguardo al fatto che se mosso in una direzione aumenta l'uscita mentre se nell'altra direzione cala.

Come ho detto prima ora devo capire come stampare una variabile ( con la quale toglierò l'offset )( "stringa" mi stampa la stringa, analogRead() mi legge il dato sul pin ma per prendere una variabile? ) mantenendolo aggiornato e visualizzandolo correttamente sul display.. Se aumento il delay dopo il blink/noBlink visualizza il dato correttamente ma abbassandolo il lampeggio non è costante ed a volte non si vede..

cosa vuol dire è calibrato? se decido di usare la x perpendicolare??

bhe saltanto questo fatto, abalogread ritorna ina variabile di tipo int. se poi tu la usi in un if o la metti in una variabile aon fatti tuoi. io sinceramente ti consiglio di guardare un Po di esempi inckus nell'ide, ovvero il programma per scrivere codice. ti chiarirai un sacvo le idee, queste sono basi di programmazione

per il display, cambiando il delay cambi anche ogni qyanto lo aggiorni, e se aggiorni troppo in fretta sfarfalla. l'ideale e cambiare solo quando serve e al massimo 2 o 3 volte al secondo.. tanto comunque più in fretta non leggi :slight_smile:
per capire come fare a meno dei delay per eseguire un codice ogni tot, guarda l'esempio blink without delay

Ok ho sistemato il codice ed ora funziona correttamente.

// includere il codice della libreria:
#include <LiquidCrystal.h>

// inizializzazione libreria --> LiquidCrystal(rs, enable, d4, d5, d6, d7)
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int xpin = A0;                  // x-axis of the accelerometer
const int ypin = A1;                  // y-axis
const int zpin = A2;                  // z-axis (only on 3-axis models)
int valvola = 8;
int verde = 6;
int giallo = 7;
int rosso = 9;


void setup()
{
  lcd.begin(16, 2);             // set up the LCD's number of columns and rows
  pinMode(valvola, OUTPUT);
  pinMode(rosso, OUTPUT);
  pinMode(giallo, OUTPUT);
  pinMode(verde, OUTPUT);    
}

void loop()
{
  digitalWrite(valvola, LOW);
  digitalWrite(rosso, LOW);
  digitalWrite(giallo, LOW);
  digitalWrite(verde, LOW);
  lcd.print(analogRead(zpin));
  
  if (analogRead(zpin)>550) {
    digitalWrite(rosso, LOW);
    digitalWrite(giallo, HIGH); 
    digitalWrite(valvola, HIGH);
    delay(2000);         
  }
else
{
  if (analogRead(zpin)<400) {
    digitalWrite(rosso, LOW);
    digitalWrite(verde, HIGH);
    } 
    
 if (analogRead(zpin)>400) {
    digitalWrite(verde, LOW);
    digitalWrite(rosso, HIGH);
  }   
}
  
lcd.clear();
}

Comunque ho un ultimo dubbio..cosa fa const int ?? nei reference sul sito di arduino non lo trovo. Io l'ho preso per buono visto che si trovava tra gli esempi presenti in arduino ma ho provato a cercarne il significato ma non trovo niente..

const significa costante, e non lo trovi su Arduino perché fa parte del linguaggio c su cui si basa Wiring, il framework di Arduino.

vuol dire che quella variabile non può cambiare valore; se ci provi, ri viene generato un errore di compilazione. molto utile per evitate di gare cadini, e dare una mano al compilatore ad otimizzare il codice