Problemi con pulseIn...

Ciao a tutti, sto cercando di comandare un motore DC collegato come da schema: http://bildr.org/blog/wp-content/uploads/2012/03/rfp30n06le-arduino-solenoid.png. Le uniche differenze sono che il mosfet che ho usato è un IRF540 e il motore è alimentato a 5V. Per farlo partire e fermare uso un radiocomando tipo quelli da aeromodellismo per intenderci e vado a leggere il valore dalla ricevente tramite pulseIn. Succede però che quando il motore gira pulseIn legge valori molto sporchi (tipo 2460,2460,35, 2461, 1, 2460 ecc.) facendo andare il motore a singhiozzo, mentre quando è scollegato legge valori molto stabili e puliti. Per collegato e scollegato intendo proprio fisicamente, quindi è il motore che in qualche modo va a disturbare arduino. Ho provato anche ad alimentare la ricevente e il motore con due fonti diverse (mettendo in comune le masse ovviamente), ma non cambia nulla e non riesco a spiegarmi il perchè di questo comportamento. Il codice è questo:

const  int  SERVOPIN=3;
const  int  RXSIGNAL=5;

const  byte  pwm=180;

void setup()
{
  
  Serial.begin(9600);
  pinMode(RXSIGNAL, INPUT);
  pinMode(SERVOPIN, OUTPUT);
}

void loop()
{
  int  rxCmd, pwmVal;
  
  rxCmd=pulseIn(RXSIGNAL, HIGH);
  
  Serial.println(rxCmd);
  
  if(rxCmd > 1800)  pwmVal=pwm; 
  else pwmVal=0;
    
  analogWrite(SERVOPIN, pwmVal);
  
}

Qualcuno ha qualche idea sul perchè di questo comportamento? Grazie.

Stefano

io non vedo lo schema :( ad ogni mod un IRF comandao con i 5V non è bene (se lo comandi a 5V)

come non detto lo schema si vede...... ma IRF non bene comandato a 5V confermo il motore è grosso o piccolino 8di che tensioni/correnti parliamo?)

in più puo tranquillamente essere che i disturbi genereati da un pwm su un motore "grosso" vada a creare dei signor disturbi! se non puoi fare "due linne distinte" almeno metti dei condensatorini tra ing+ e ing - e tra carcassa e d entrambi gli ingressi.... forse qualcosina ti aiuta

in più un resistenzina da non so 10... 50...100 Ohm sul gate ce la mettere (in serie al gate)

Oltre alla scelta del MOSFET (usa un IRL540 o meglio un IRLZ44), lo schema non è corretto: hai dimenticato di inserire il resistore sul gate (consiglio un 220 ohm).

Un motore che funziona a 5V non dovrebbe assorbire molto, ma la corrente erogabile da Arduino è limitata (diciamo 500mA con il collegamento USB).

Facile che il PWM sporchi l'alimentazione di Arduino e di conseguenza il buon funzionamento di pulseIn.

Alcuni motori possiedono dei condensatori ceramici sui contatti del motore e la sua carcassa: con il pilotaggio in PWM questi andrebbero rimossi.

Meglio anche aggiungere un condensatore elettrolitico da 470μF tra +5V e GND.

Il motore è un motorino molto piccolo smontato da un servocomando mini. Ho scelto l'IRF540 perchè avevo quello in casa ma per quello che consuma quel motore (e qui potrei dire una str.....) potrebbe bastare anche un transistor di piccola taglia. Comunque il motore non è alimentato direttamente da arduino ma da batteria esterna e quindi escluderei il problema della corrente fornita dalla porta usb. Faccio delle prove aggiungendo la resistenza da 220ohm e il condensatore da 470uF. Vi faccio sapere. Grazie.

Stefano

Problema risolto, è bastato mettere il condensatore da 470uF tra positivo e negativo. Per quanto riguarda la resistenza, ho seguito lo schema postato (che ho trovato in rete), però diversamente da com'è lo schema avevo già messo la resistenza da 10k piuttosto che verso massa tra arduino e gate. Ora l'ho sostituita con una da 220ohm, anche se comunque per risolvere il problema è bastato il condensatore. Grazie dell'aiuto.

Stefano

Rieccomi, sono tornatoooooo!!!! :)

Approfondendo la cosa ho visto che il condensatore ha sicuramente migliorato, però: - con pwm alto (200/255) ogni tanto c'è qualche lettura fasulla con pulseIn - con pwm medio (110/150) non c'è nessuna lettura fasulla - con pwm sotto il 110 iniziano ad esserci un sacco di letture fasulle

Ho provato a mettere un condensatore più grosso (1000uF) ma addirittura mi sembra che la cosa peggiori. Ho messo anche il diodo che si vede sullo schema (che prima non avevo messo) ma che ci sia oppure non è ininfluente. Che altro modo potrei usare per liberarmi di questi disturbi generati dal motore? Non credo ma lo chiedo lo stesso; può dipendere anche dal tipo di mosfet? (continuo ad usare l'IRF540 perchè al momento ho solo quello).

Grazie.

Stefano

Non mettere il diodo è un grave errore poiché esso riduce le extratensioni provocate dall'induttanza del motore.

Per tua fortuna il MOSFET ha incorporato un diodo tra source e drain che lo ha protetto, ma è sempre consigliabile inserirlo.

Il tuo MOSFET funziona lo stesso, ma con 5V riesce ad controllare sino a circa 10A, meno della metà della corrente di targa (28A @ 25°C).

Facci vedere uno schema di tutto il sistema e lo sketch che utilizzi.

Lo sketch che utilizzo è questo:

const  int  SERVOPIN=3;
const  int  RXSIGNAL=5;

const  byte  pwm=180;

void setup()
{
  
  Serial.begin(9600);
  pinMode(RXSIGNAL, INPUT);
  pinMode(SERVOPIN, OUTPUT);
}

void loop()
{
  int  rxCmd;
  
  rxCmd=pulseIn(RXSIGNAL, HIGH);
  
  Serial.println(rxCmd);
  
  if(rxCmd > 1800)  analogWrite(SERVOPIN, pwm);
  else analogWrite(SERVOPIN, 0);
}

Rispetto allo sketch già postato ho fatto una piccola modifica ma ininfluente per il problema che sto riscontrando.

Per quanto riguarda lo schema è sempre quello postato solo che: - Il motore è un piccolissimo motore a 5V recuperato da un mini servocomando - Il diodo sul motore non c'è - Il mosfet è un IRF540 (ok che lo sfrutto a 1/3 delle sue possibilità, ma a me basta veramente poco) - La resistenza da 10K che va dal PIN3 a GND non c'è, ma c'è invece una resistenza 220ohm che va dal PIN3 al GATE

Meglio se la variabile rxCmd la dichiari unsigned long.

Al posto di usare il pin 5 collegato al timer 0 ad 8 bit, usa il 9 od il 10 collegati al timer 1 a 16 bit.

Leggi lo stato del pin 5 alla massima velocità possibile, ma questo non è necessario in quanto la frequenza del PPM è di circa 50Hz (20ms): puoi inserire prima della fine del loop un delay(5).

Metti il diodo (un 1N4007 va bene).

il discorso del IRF non è tanto (in questo caso) su come sfruttarlo il fatto è che devi dargli moolta tesione per aprirlo completamente 5V sul gate son pochi e potresti correre il rischio di non aprire il canale o comunque non renderlo bel conduttivo con tutti i problemi poasti, cosa che con IRL invece eviti in quanto la Vth è bassa e quindi a 5V sei abbastanza sicuro che il canale sia aperto.

Ragazzi, vi ringrazio dei consigli. Appena avrò un secondo mi ci rimetto.

cyberhs: Meglio se la variabile rxCmd la dichiari unsigned long.

Fatto, ma comunque mi sono dimenticato di dire che poi questo progetto passerà da atmega328 a attiny85. Tra l'altro ho già fatto una prova con attiny e sembra che il piccolino soffra molto meno di questo problema.

Al posto di usare il pin 5 collegato al timer 0 ad 8 bit, usa il 9 od il 10 collegati al timer 1 a 16 bit.

Come già detto questo progetto sarà su attiny e quindi questo no potrò farlo.

Metti il diodo (un 1N4007 va bene).

Messo, dal punto di vista del problema riscontrato non è cambiato nulla. Ma è comunque necessario anche se il motore che sto usando è piccolissimo?

Martinix: il discorso del IRF non è tanto (in questo caso) su come sfruttarlo il fatto è che devi dargli moolta tesione per aprirlo completamente 5V sul gate son pochi e potresti correre il rischio di non aprire il canale o comunque non renderlo bel conduttivo con tutti i problemi poasti, cosa che con IRL invece eviti in quanto la Vth è bassa e quindi a 5V sei abbastanza sicuro che il canale sia aperto.

Grazie di questo appunto. Oggi vedo se riesco a recuperare un IRL.