Pulsein resolution

Hi
How to increase resolution of pulse in ? Right now is responding to hundreds in Compare

pwmtimer4.setCompare(TIMER_CH2, 3600);

#include "LiquidCrystal.h"
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
HardwareTimer pwmtimer4(4);

#define PIN_SENSOR PA6

unsigned long DeltaTime = 0;
unsigned long PULSEIN_TIMEOUT = 1000000;


void setup() {
  pinMode(PIN_SENSOR, INPUT_PULLUP);
  Serial.begin(9600);
  lcd.begin(16, 2);
  pinMode(PB7, PWM);
  pwmtimer4.pause();
  pwmtimer4.setPrescaleFactor(1);
  pwmtimer4.setOverflow(7200);
  pwmtimer4.setCompare(TIMER_CH2, 3600);
  pwmtimer4.refresh();
  pwmtimer4.resume();
}

void loop() {
  DeltaTime = pulseIn(PIN_SENSOR, LOW, PULSEIN_TIMEOUT);

  lcd.setCursor(0, 0);
  lcd.print("W  ");   
  lcd.print(DeltaTime); 
  delay (50);

}

I might be totally on the wrong track but why are you using PAX and PBx?

From memory (can't easily check at the moment) PAx and PBx are just numbers and don't refer to a port/pin combination. Try to serial print e.g. PA0 and PB0 and check the result.

But as said, I might be on the wrong track.

Because I am using stm32f103.
PB0 is used by LCD, PB7 is output of the timer 4 channel 2.
Ihe program is working, changing the pins will not change of it performance.

And you did not think that that was worth mentioning?

I didn't mention that because problem is not in pin configuration.

What do you mean by that? Do you mean timeout?

What Arduino are you using? Your sketch won't compile for an Arduino UNO.

Correction - in Compare = this line.

pwmtimer4.setCompare(TIMER_CH2, 1800);//Pulse width adjustment

If I change 1800 to 1700 on LCD I see different numbers, if I change 1800 to 1810 = no numbers are changing on LCD, even with 1850 no changes.
I am using stm32f103.

Without generator should compile, just change the name of the pins for LCD
But in that case I need external 10 kHz generator for testing.

The output of pulseIn() is in microseconds. On the UNO the resolution is, I think, 4 microseconds.

What is the clock frequency of your processor? Even on a 16 MHz UNO you would have to change the PWM value by 16 to get a 1-microsecond change and 64 to get a 4-microsecond change. If your clock is running at 80 MHz it makes sense that a 50-tick change (0.625 microseconds) would not show up in a microsecond counter.

72MHz
And the numbers on LCD are jumping, for 1900 I have 47.48 and for 1800 - 84.24, I can't get 85.00 or 86.00, on scope I can notice pulse with is changing if I changde 1900 to 1910.

The DeltaTime variable you show is an unsigned long integer but the values you are showing now are floats. What did you change in your sketch?

If setOverflow() is still 7200 (100 microseconds) then setCompare() of 1800 should produce 25 microseconds HIGH and 75 microseconds LOW. setCompare() of 1900 should produce 26.38 microseconds HIGH and 73.61 microseconds LOW.

Sorry , I was testing two sketches those numbers comes from second one.
The guy uses there nanoseconds which should have better resolution

//https://mousa-simple-projects.blogspot.com/2017/12/power-factor-measurment-using-arduino_18.html
#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);

HardwareTimer pwmtimer4(4);
int pin = PA7;
float rads = 57.29577951; // 1 radian = approx 57 deg.
float degree = 360;
float frequency = 10000;
float nano = 1 * pow (10, -6); // Multiplication factor to convert nano seconds into seconds

// Define floats to contain calculations

float pf;
float angle;
float pf_max = 0;
float angle_max = 0;
int ctr;

void setup()
{
  pinMode(pin, INPUT);
  Serial.begin(9600);
  lcd.begin(16, 2);
  pinMode(PB7, PWM);
  pwmtimer4.pause();
  pwmtimer4.setPrescaleFactor(1);
  pwmtimer4.setOverflow(7200);
  pwmtimer4.setCompare(TIMER_CH2, 1900);
  pwmtimer4.refresh();
  pwmtimer4.resume();
}

void loop()
{

  for (ctr = 0; ctr <= 4; ctr++) // Perform 4 measurements then reset
  {
    // 1st line calculates the phase angle in degrees from differentiated time pulse
    // Function COS uses radians not Degree's hence conversion made by dividing angle / 57.2958
    angle = ((((pulseIn(pin, HIGH)) * nano) * degree) * frequency);
    // pf = cos(angle / rads);

    if (angle > angle_max) // Test if the angle is maximum angle
    {
      angle_max = angle; // If maximum record in variable "angle_max"
      pf_max = cos(angle_max / rads); // Calc PF from "angle_max"
    }
  }
  if (angle_max > 360) // If the calculation is higher than 360 do following...
  {
    angle_max = 0; // assign the 0 to "angle_max"
    pf_max = 1; // Assign the Unity PF to "pf_max"
  }
  if (angle_max == 0) // If the calculation is higher than 360 do following...
  {
    angle_max = 0; // assign the 0 to "angle_max"
    pf_max = 1; // Assign the Unity PF to "pf_max"
  }
  Serial.print(angle_max, 2); // Print the result
  Serial.print(",");
  Serial.println(pf_max, 2);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("PF=");
  lcd.setCursor(4, 0);
  lcd.print(pf_max);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print("Ph-Shift=");
  lcd.setCursor(10, 1);
  lcd.print(angle_max);
  lcd.print(" ");

  delay(10);
  angle = 0; // Reset variables for next test
  angle_max = 0;
}

problem solved, resolution 0.26 microseconds

I would not have expected an integer microsecond value to have a resolution greater than 1.0 microseconds.

I am using nanoseconds.
resolution = 260ns

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.