brtaylor
Well-known member
I'm experiencing issues trying to loopback PWM. I have pin 5 connected to pin 23 using a jumper, that is the only connection.
Here is what I am trying to do:
1. Create a 1 Hz sine wave
2. Scale the sine wave from +/-1 to 1000 to 2000
3. Use analogWrite to send this as a 50 Hz, 16 bit resolution PWM to pin 5
4. Have my ISR measure the pulse width on pin 23
5. Print the results
In theory the PWM that was sent on pin 5 should be roughly the same as measured on pin 23. Individually, these functions work, I can send a PWM to a servo and have it move according to the 1 Hz sine wave. I can connect an RC receiver to pin 23 and see the PWM commands. But in this loopback function, I can see my sent PWM, but my received PWM remains 0. I am using elapsedMicros for measuring the pulse width and analogWrite for sending the PWM.
My code is below, any thoughts?
Here is what I am trying to do:
1. Create a 1 Hz sine wave
2. Scale the sine wave from +/-1 to 1000 to 2000
3. Use analogWrite to send this as a 50 Hz, 16 bit resolution PWM to pin 5
4. Have my ISR measure the pulse width on pin 23
5. Print the results
In theory the PWM that was sent on pin 5 should be roughly the same as measured on pin 23. Individually, these functions work, I can send a PWM to a servo and have it move according to the 1 Hz sine wave. I can connect an RC receiver to pin 23 and see the PWM commands. But in this loopback function, I can see my sent PWM, but my received PWM remains 0. I am using elapsedMicros for measuring the pulse width and analogWrite for sending the PWM.
My code is below, any thoughts?
Code:
/* PWM read pin */
const unsigned int ReadPin = 23;
/* PWM write pin */
const unsigned int WritePin = 5;
/* used for reading the PWM */
elapsedMicros elapsedTime_us;
/* storing the read value */
volatile unsigned int ReadVal_us;
/* storing the write value */
unsigned int WriteVal_us;
/* PWM update frequency, 50 Hz */
const unsigned int Freq = 50;
/* PWM update period */
const unsigned int Period_us = 1000000 / Freq;
/* PWM resolution */
const unsigned int PWM_Resolution = 16;
/* Time, ms */
elapsedMillis time_ms;
void meas_pwm()
{
/*
* Read the value, if it's high, we just started the pulse and need
* to zero the timer. If it's low, we just finished the pulse and
* should store the pulse width result.
*/
if (digitalReadFast(ReadPin)) {
elapsedTime_us = 0;
} else {
ReadVal_us = elapsedTime_us;
}
}
void setup()
{
/*
* Start USB serial to display results
*/
Serial.begin(115200);
while(!Serial) {}
/* setting the analog frequency to 50 Hz and resolution to 16 bit */
analogWriteFrequency(WritePin, Freq);
analogWriteResolution(PWM_Resolution);
/*
* Assign PWM pin as input
*/
pinMode(ReadPin,INPUT);
/*
* Attach our ISRs to changes in the respective pins
*/
attachInterrupt(ReadPin,meas_pwm,CHANGE);
}
void loop()
{
/*
* Print the results
*/
Serial.print(ReadVal_us);
Serial.print("\t");
Serial.println(WriteVal_us);
/* 1 Hz sine wave */
float Cmd = sinf(2.0f * M_PI * time_ms / 1000.0f);
/* Scale from +/- 1 to a range of 1000 us to 2000 us */
Cmd = Cmd * 500.0f + 1500.0f;
/* Command channel */
WriteVal_us = Cmd;
analogWrite(WritePin,WriteVal_us / Period_us * powf(2,PWM_Resolution));
delay(20);
}