centralina kart

Ho fato uno sketch che mi legge un sensore sul pin analogico, se quest'ultimo supera un certo valore
mi accende un led e fin qui tutto ok...
lo stesso sketch se disabilito il monitor seriale sia alimentato da PC tramite usb sia da alimentatore esterno anche
se il sensore supera il valore impostato non si accende il led, in poche parole lo sketch funziona, ma funziona solo con il monitor seriale aperto, infatti mi basta scrivere nel loop anche solo Serial.println(""); senza nessun riferimento per farlo funzionare.

Grazie per l'aiuto.

vai alla riga 103 e scrivi

#error "serial abracadabra"

vbextreme:
vai alla riga 103 e scrivi

#error "serial abracadabra"

non capisco... mi stai prendendo in giro?
Ho chiesto qualcosa di tanto strano? Forse perchè non sono esperto come voi?

Forse se postavi anche lo sketch ti evitavi delle risposte simili

Nessuno di noi ha la palla di vetro

Brunello:
Forse se postavi anche lo sketch ti evitavi delle risposte simili

Nessuno di noi ha la palla di vetro

A ok ho capito...

Questo è lo sketch:
come dicevo devo aprire la seriale altrimenti il programma funziona a metà,
l' incremento / decremento lo vedo tranquillamente nel display, funziona l'accensione / spegnimeto del display,
ma se la cella dii carico supera il valore impostato non si accende il led.....

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

const int incremento = 3;             // il numero dell'ingresso del pulsante per incrementare
const int decremento = 4;             // il numero dell'ingresso del pulsante per decrementare
const int illuminazione = 5;          // il numero dell'ingresso del pulsante per accendere / spegnere l'illuminazione del display

int val = 0;                  // si userà val per conservare lo stato del pin di input
int vecchio_val = 0;          // si userà vecchio_val per conservare lo stato del pin di input al passo precedente
int stato = 0;                // ricorda lo stato in cui si trova l'illuminazione, stato = 0 display spento, stato = 1 display acceso



const int mosfet = 2;                 // il numero dell'uscita del mosfet
byte statomosfet = LOW;               // lo stato del mosfeet in questo momento
unsigned long tempopassato = 0;       // memorizziamo il tempo trascorso
int statoButton     = 0;      // stato del pulsante (inizialmente non premuto)
int lastStatoButton = 0;      // ultimo stato del pulsante (per ora non premuto)
int countButton     = 150;      // Conteggio del bottone


void setup() {
  Serial.begin(9600);
  lcd.init();
  pinMode(incremento, INPUT);          // setta il pulsante come ingresso
  pinMode(decremento, INPUT);          // setta il pulsante come ingresso
  pinMode(mosfet, OUTPUT);            // setta mosfet come un uscita
  pinMode(illuminazione, INPUT);             // setta il pulsante come ingresso

  lcd.setCursor( 0, 0 );
  lcd.print( "Cut Off = ");
  lcd.print(countButton);
  lcd.print( " ms");



}

void loop() {
  int analogValue = analogRead(0);     // legge il valore della cella di carico
  val = digitalRead(illuminazione);  // legge il valore dell'input e lo conserva




  if ((val == HIGH) && (vecchio_val == LOW)) {
    stato = 1 - stato;
    delay(15);
  }

  vecchio_val = val;

  if (stato == 1) {

    lcd.backlight();

  }
  else {

    lcd.noBacklight();
  }



  if (digitalRead(incremento))
  {

    delay(200);

    if (lastStatoButton == 0) lastStatoButton = 1;
    else lastStatoButton = 0;

    if (countButton <= 195) countButton = countButton + 5;

    lcd.clear(  );               // Pulisce lo schermo

    lcd.setCursor( 0, 0 );
    lcd.print( "Cut Off = ");

    lcd.print(countButton);
    lcd.print( " ms");



  }


  if (digitalRead(decremento))
  {

    delay(200);

    if (lastStatoButton == 0) lastStatoButton = 1;
    else lastStatoButton = 0;

    if (countButton >= 45) countButton = countButton - 5;

    lcd.clear(  );


    lcd.setCursor( 0, 0 );
    lcd.print( "Cut Off = ");

    lcd.print(countButton);
    lcd.print( " ms");

  }



  if ( analogValue >= 21 && statomosfet == LOW)  {
    digitalWrite(mosfet, HIGH);
    statomosfet = HIGH;
    tempopassato = millis();
  }


  if (statomosfet == HIGH && (millis() - tempopassato) > countButton)
  {
    digitalWrite(mosfet, LOW);
    statomosfet = LOW;
  }




  Serial.println();             //devo aprire per forza la seriale altrimenti il programma non funziona



}

spiega un attimo quello che stai facendo e quello che vuoi ottenere, la logica del tuo programma non è molto esplicita.
quel MOSFET che sta acceso 150 millisecondi( veramente pochi ) a cosa è collegato?
Dove sarebbe collegato il led?

Il mosfet mi deve tagliare la corrente alla candela nel momento in cui aziono la leva del cambio e la cella di carico sente una certa pressione...il led è "finto" mi deve simulare il taglia di corrente....

scusami, paghi a lettere scritte? sei timido?
cerca di essere un attimo più una "lingua vivace", dove sarebbe sto led che non si accende? a quale pin l'hai collegato? no perché non lo trovo!

Prenditi 30' e scrivi dettagliatamente senza tralasciare niente ciò che vuoi fare.La cella di carico dove è collegata? il led? etc,etc,etc...
tutto, dalla a alla z, ripetuti più e più volte in modo che possiamo capire tutti, vedrai che una mano arriva.

Spero di non essere stato frainteso come nel mio precedente post, è normale pensare che tutti capiscano il proprio problema, come è normale che nessuno sia nella propria testa.(ahahhaha dai che scherzo? ;p)

con 2 pulsanti incremento / decremento una variabile che poi sarebbero i millisecondi che resta chiamato il mosfet.
Quando la cella di carico (int analogValue = analogRead(0); // legge il valore della cella di carico)
supera un certo valore accende il mosfet e alla sua uscita è collegato un led che uso solo come spia per
vedere se il mosfet commuta stato. Ho messo un led collegato al mosfet perchè mi risulterebbe scomodo
collegare il mosfet all'impianto elettrico del kart per provare se lo sketch funziona per il taglio di corrente alla candela, solo quando tutto funziona allora posso togliere il led e collegare tutto in modo definitivo.

Come anticipato lo sketch non funziona nel momento in cui la cella di carico sente un valore maggiore o uguale a 21 e non accende il mosfet (lo vedo perchè ho il led spia che in questo caso non si accende)

Te fai:

int analogValue = analogRead(0);

Il pin 0 è Rx della seriale e non credo tu abbia collegato lì la cella di carico, altrimenti avresti fatto 2 errori... credo invece che tu l'abbia collegata al pin A0 e che l'errore sia solo che interroghi il pin sbagliato, per cui modifica così:

int analogValue = analogRead(A0);

A0/A5 corrisponde al valore 0/5.....

  if ( analogValue >= 21 && statomosfet == LOW)  {
    digitalWrite(mosfet, HIGH);
    statomosfet = HIGH;
    tempopassato = millis();
  }


  if (statomosfet == HIGH && (millis() - tempopassato) > countButton)
  {
    digitalWrite(mosfet, LOW);
    statomosfet = LOW;
  }

questo è il frammento incriminato, countButton vale da 45 a 200 che corrispondono ai millisecondi che rimane acceso il led, mi sembrano pochini perche tu li possa vedere.
prova cosi:

  if (statomosfet == HIGH && (millis() - tempopassato) > countButton)
  {
    delay(250);
    digitalWrite(mosfet, LOW);
    statomosfet = LOW;
  }

se ora vedi accendersi il led tieni quel delay solo in fase di debug e lo levi quando lo andrai a collegare al kart.

quando è attivo il monitor seriale e funziona tutto riesco a vedere tranquillamente i pochi millisecondi
impostati perchè ho constantemente la cella di carico sotto sforzo e quindi vedo blinkare il led,
in verità il led non lo vedo mai spegnersi però si vede benissimo tipo un tremolio dovuto
al fatto on / off.
Ho anche impostato countButton da 1000 a 4000 quindi in questo caso vedo benissimo il led fare on / off,
ma sempre se lascio la riga Serial.println();, senza di questa il led non si accende...

prova cosi:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display


#define LOAD    0
#define MOSFET  2
#define INCR    3
#define DECR    4
#define LIGHT   5

#define CUTOFF_MAX 5000
#define CUTOFF_MIN 50

unsigned long cutOff = 150;
unsigned long cutOffStart = 0;
byte light = 0;
byte mosfetActive = 0;

byte buttonPress(byte p)
{
    if ( !digitalRead(p) ) return 0;
    delay(150);
    return digitalRead(p);
}

void lcd_cutoff()
{
    lcd.clear();
    lcd.setCursor( 0, 0 );
    lcd.print( "Cut Off = ");
    lcd.print(cutOff);
    lcd.print( " ms");
}


void setup() 
{
    //Serial.begin(9600);
    lcd.init();
    pinMode(INCR, INPUT);          // setta il pulsante come ingresso
    pinMode(DECR, INPUT);          // setta il pulsante come ingresso
    pinMode(MOSFET, OUTPUT);             // setta mosfet come un uscita
    pinMode(LIGHT, INPUT);       // setta il pulsante come ingresso
    lcd_cutoff();
}


void loop() 
{
    
    if ( buttonPress(LIGHT) ) 
    {
        light = !light;
        lcd.setBacklight(light);
        while ( buttonPress(LIGHT) );
    }

    if ( buttonPress(INCR) )
    {
        while (  buttonPress(INCR) && (cutOff < CUTOFF_MAX) )
        {
            cutOff += 5; 
            lcd_cutoff();
            delay(150);
        }
    }
    else if ( buttonPress(DECR) )
    {
        while (  buttonPress(DECR) && (cutOff > CUTOFF_MIN) )
        {
            cutOff -= 5; 
            lcd_cutoff();
            delay(150);
        }
    }

    if ( analogRead(LOAD) >= 21 && !mosfetActive )
    {
        mosfetActive = 1;
        digitalWrite(MOSFET, mosfetActive);
        cutOffStart = millis();
    }


    if ( mosfetActive && ((millis() - cutOffStart) > cutOff) )
    {
        mosfetActive = 0;
        digitalWrite(MOSFET, mosfetActive);
    }
}

non ho compilato ma dovrebbe andare.
Sicuro che la LiquidCristal_I2c funzioni cosi? io non la conosco

Ho testato il tuo sketch senza monitor seriale attivo e funziona, il led resta accesso per il tempo impostato quando la cella di carico supera il valore, ho notato che se lascio la cella in carico il led resta acceso di continuo, mentre se attivo il serial monitor e lascio sempre la cella in carico il led lampeggia per il tempo impostato.
Ho ricaricato anche il mio sketch ed ora funziona come quello tuo... però ho cambiato PC, sarà per questo?
Il tuo sketch si vede che è roba professionale, il mio è proprio grezzo....
saresti ancora una volta cosi gentile da spiegarmi alcune righe del tuo codice?

questo a cosa serve? perche si trova nella parte dove di dichiarano le variabili?

byte buttonPress(byte p)
{
    if ( !digitalRead(p) ) return 0;
    delay(150);
    return digitalRead(p);
}

alla pressione dei pulsanti per incrementare / decrementare questo codice: lcd_cutoff();
dovrebbe accendere il display? Se si non lo fa

In questo caso il tmpo di cut off mica viene falsato dai vari delay?

Complimenti ancora

Non ho ben capito se il programma funziona bene, ovvero fa quello che vuoi oppure no.

Quella è una funzione e serve per semplificare il codice, quando premi un pulsante può capitare che per i primi 30/40 millisecondi il segnale passi da 1 a 0 più volte e poi si stabilizzi a 1.
Controllo dunque che il pulsante sia premuto, aspetto un po e controllo che sia ancora premuto, questo è un antirimbalzo software dei più semplici.

la funzione lcd_cutoff serve a visualizzare i dati, creata sempre per tenere pulito il codice, in teoria il display si accende solo con il relativo pulsante, si accende se premi il pulsante?
volevi si accendesse in automatico quando premevi incr e decr? se si dopo ti insegno come si fa, ma questa volta la crei te la funzione o se no mica impari niente!eheheheh...

il tempo di cutoff naturalmente viene falsato solo quando premi i pulsanti, se vuoi che rimanga sempre stabile potresti scrivere una funzione personalizzata di delay ma comunque essendo il cutoff un tempo molto piccolo è probabile che venga sfalsato anche dalla visualizzazione dei dati sul display e qui puoi attenuare solo il difetto.

Procediamo un passo alla volta, dimmi cosa vuoi fare in maniera dettagliata e ti guidero nel farlo.

Si il programma funziona bene...
però ho fatto questo ragionamento, quando aziono la leva del cambio e la cella passa a 1
immediatamente si accende il led (quindi mi taglia la corrente) fin qui tutto ok, però
se sono più lento a rilasciare la leva del cambio (ipotizziamo che il tempo di cut off sia
impostato a 200 miliisecondi) quindi impiego 350 millisecondi, credo che comunque
il tempo totale di cut off non è più 200 millisecondi ma bensì 350 millisecondi perchè
la cella resta sempre a 1.
Ci vorrebbe qualcosa che sente che la cella è a 1 interviene il cut off
e anche se per qualche istante sono ancora in tiro con la leva il cut off non deve ripetere il ciclo
di pausa...

Credevo che l'antirimbalzo era gestito dal delay in buttonpress.
Ok ho capito anche la funzioine lcd_cutoff
Il display si accende correttamente con il relativo pulsante.
Anche se il display non si accende alla pressione dei pulsanti per ora va bene, ma come mi hai
insegnato credo sia possibile cambiare lo stato a light...

Quindi se mi confermi che il tempo di cut off è falsato solo alla pressione dei pulsanti
non crea nessun problema..credo che il problema forse è prorpio quello relativo al tempo
di rilascio della leva (se supera il tempo di cut off)

da quel che ho capito il settaggio del tempo e l'intervento del cut-off non avvengono mai insieme, quindi il programma ha due stadi:
1)settaggio
2)cut-off
mentre il primo non è critico il secondo si e in questo caso il cut-off deve avere priorità maggiore del settaggio.
Per far ciò modifichiamo i due if relativi al cut-off e diciamo di fare:
In caso la cella di carico ha x valore intervieni e aspetta che la cella sia minore di k valore, in questo modo il cut-off interviene solo una volta.

#define SOGLIA_MAX 21
#define SOGLIA_MIN 21
...il resto del codice senza le if del cut-off...
...le if diventano ...

if ( analogRead(LOAD) >= SOGLIA_MAX )
{
   digitalWrite(MOSFET, 1);
   delay(cutOff);
   digitalWrite(MOSFET,0);
   while( analogRead(LOAD) > SOGLIA_MIN );
}

in questo modo interviene il cut-off e poi aspetta che la cella scenda sotto un determinato valore prima di effettuare nuovamente il loop, questo inibisce il settaggio del cut-off durante il cut-off stesso.

Hai capito meglio di me come funziona...
cosi la cella di carico viene gestita come un pulsante con la tecnica dell'antirimbalzo...
però credo ci siamo mangiati la funzione millis del cut off, in questa maniera se ho ben capito mettiamo in pausa
il programma per tutta la durata del cut off (però credo sia influente anche se poi innalzo il cut off a oltre 500 millisecondi).
Comunque più tardi posso provare lo sketch, con questa modifica si potrebbe gestire il cut off con la funzione millis?

il cut-off che tu usi è in millisecondi, delay lavora in millisecondi! perché rifare una funzione che hai già?
se noti delay attende il tempo impostato di cut-off e pertanto il cut-off sarà attivo per il tempo che hai visualizzato sul display.
Non ho inserito nessun genere di antirimbalzo perché il caso specifichio richiede una implementazione un po più complicata, per adesso puoi provare cosi.