Hola
Mi proyecto es tratar de controlar un equipo de construccion (un minicargador) los controles de implementos (joysticks) son electrohidraulicos y trabajan con un sensor de posicion PWM
Mi pregunta es como hacer para que arduino pueda leer esta señal
Es una señal PWM digital que trabaja a una frecuencia de 500 Hz constante y aun ciclo de trabajo de 2 al 98% el voltaje varia de entre 1 a 3.8 V
Si la frecuencia es constante de 500Hz, cada ciclo durará 2 milisegundos, o lo que es lo mismo 2.000 microsegundos. Yo lo usaría así:
pulseIn(pin,HIGH,20000) ;
pin=pin entrada señal
HIGH=le decimos que mida la duración del flanco alto
20000= hará el muestreo durante 20.000 microseg. Por lo que con nuestros 550Hz hará el muestreo 10 veces para estar mas seguros de la duración del flanco.
Con el dato que devuelva pulseIn y una simple regla de 3 conocerás el % del ciclo de trabajo.
Primero vas a tener que conformar la señal de entrada para que Arduino la lea. Que varíe entre 1 a 3.8V no ayuda. Asi que usa un Smith trigger como el LM339 o tantos que hay disponibles. Esta página te ayudará a hacer los cálculos.
Luego lo mejor a mi gusto sería usar esta rutina de Nick Gammon que mide una PWM perfectamente usando INPUT CAPTURE MODE de un timer.
The sketch below is a variation on the frequency counter above. However this one measures the width of the "on" portion of the duty cycle of a pulse. This could be useful for decoding information from PWM style controls.
// Duty cycle calculation using input capture unit
// Author: Nick Gammon
// Date: 5 November 2013
// Input: Pin D8
volatile boolean first;
volatile boolean triggered;
volatile unsigned long overflowCount;
volatile unsigned long startTime;
volatile unsigned long finishTime;
// timer overflows (every 65536 counts)
ISR (TIMER1_OVF_vect)
{
overflowCount++;
} // end of TIMER1_OVF_vect
ISR (TIMER1_CAPT_vect)
{
// grab counter value before it changes any more
unsigned int timer1CounterValue;
timer1CounterValue = ICR1; // see datasheet, page 117 (accessing 16-bit registers)
unsigned long overflowCopy = overflowCount;
// if just missed an overflow
if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 0x7FFF)
overflowCopy++;
// wait until we noticed last one
if (triggered)
return;
if (first)
{
startTime = (overflowCopy << 16) + timer1CounterValue;
TIFR1 |= bit (ICF1); // clear Timer/Counter1, Input Capture Flag
TCCR1B = bit (CS10); // No prescaling, Input Capture Edge Select (falling on D8)
first = false;
return;
}
finishTime = (overflowCopy << 16) + timer1CounterValue;
triggered = true;
TIMSK1 = 0; // no more interrupts for now
} // end of TIMER1_CAPT_vect
void prepareForInterrupts ()
{
noInterrupts (); // protected code
first = true;
triggered = false; // re-arm for next time
// reset Timer 1
TCCR1A = 0;
TCCR1B = 0;
TIFR1 = bit (ICF1) | bit (TOV1); // clear flags so we don't get a bogus interrupt
TCNT1 = 0; // Counter to zero
overflowCount = 0; // Therefore no overflows yet
// Timer 1 - counts clock pulses
TIMSK1 = bit (TOIE1) | bit (ICIE1); // interrupt on Timer 1 overflow and input capture
// start Timer 1, no prescaler
TCCR1B = bit (CS10) | bit (ICES1); // plus Input Capture Edge Select (rising on D8)
interrupts ();
} // end of prepareForInterrupts
void setup ()
{
Serial.begin(115200);
Serial.println("Duty cycle width calculator");
// set up for interrupts
prepareForInterrupts ();
} // end of setup
void loop ()
{
// wait till we have a reading
if (!triggered)
return;
// period is elapsed time
unsigned long elapsedTime = finishTime - startTime;
Serial.print ("Took: ");
Serial.print (float (elapsedTime) * 62.5e-9 * 1e6); // convert to microseconds
Serial.println (" uS. ");
// so we can read it
delay (500);
prepareForInterrupts ();
} // end of loop
Como podria visualizar los datos que me envia la funcion PulseIn
Utilice el visior serial para ver los datos pero me envian en forma aleatoria a pesar de que el sensor de posicion se mantiene en posicion central es decir con un 50% de ciclo de trabajo (medido con un multimetro)