Go Down

Topic: Creating a pulse multiplier? (Read 1 time) previous topic - next topic

polar8

May 22, 2012, 08:49 pm Last Edit: May 23, 2012, 04:23 am by polar8 Reason: 1
I'd like to use the Arduino to create a pulse divider. My input is a 1PPS, 8us 5v pulse from a GPS that I will use for timekeeping. I'd like to use that to create a 10hz 10us 5v output pulse.

Any suggestions or example projects to look at?

Thanks!

dc42

1Hz input and 10Hz output is a pulse multiplier, not a divider. Google for "software phase locked loop".
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

CrossRoads

There's 1,000,000uS in a second.
(1,000mS in a second)
So once a second you're like a little burst of 10uS pulses at a 10 Hz rate?

from: High for 8uS, Low for 999,992us
__|--|_____________________________________________________________|--|_____________
to: High for 10uS, Low for 99,990uS, repeat 10 times, repeat with next 1PPS pulse
__|---|__|---|__|---|__|---|__|---|__|---|__|---|__|---|__|---|__|---|___
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

polar8

Ok, I understand how it would be a multiplier.


There's 1,000,000uS in a second.
(1,000mS in a second)
So once a second you're like a little burst of 10uS pulses at a 10 Hz rate?

from: High for 8uS, Low for 999,992us
__|--|_____________________________________________________________|--|_____________
to: High for 10uS, Low for 99,990uS, repeat 10 times, repeat with next 1PPS pulse
__|---|__|---|__|---|__|---|__|---|__|---|__|---|__|---|__|---|__|---|___



Yes! That's what I would like to implement. I'm not sure how to do it though, because you would need to wait for a couple input pulses before performing the arithmetic though, right?

Grumpy_Mike

Quote
because you would need to wait for a couple input pulses before performing the arithmetic though, right?

wrong, look at reply #1.

polar8

#5
May 23, 2012, 12:28 am Last Edit: May 23, 2012, 12:30 am by polar8 Reason: 1
Ok, since this is my first Arduino program I have started simple in hopes of moving my way up.

What I have succeeded in doing is measuring an interval between button presses, then blinking an LED at a fraction of that interval for a certain number of times.

The problem is that while the LED blinks correctly (at a rate proportional to the interval measured), I can only get it to do it for a fixed number of times using my While loop.

I would like to modify this so that the LED blinks at a fraction of the latest interval measured, until the next button press is registered (signalling a new interval.)

Code: [Select]
#define  DELAY_START   HIGH   
#define  DELAY_END   !DELAY_START  
int ledPin = 3;    
int inputPin = 2;  
int x;
long start, duration, fduration, interval;

void setup() {
 pinMode(ledPin, OUTPUT);
 pinMode(inputPin, INPUT);    
 Serial.begin(9600);
}

void loop(){
 while( digitalRead(inputPin) != DELAY_START   )
;
 start = millis();
 while( digitalRead(inputPin) != DELAY_END   )
;
 duration = start - millis();
 fduration = 0 - duration;                //for some reason my duration was negative so this makes it positive
 interval = fduration / 10;
 Serial.println(fduration);

 for(int x = 0; x < 10; x++){
 digitalWrite(ledPin, HIGH);
 delay(10);
 digitalWrite(ledPin, LOW);
 delay(interval);
 
}
}

polar8

Well I abandoned the attempt above because I realized that using delay() wasn't going to work as it pauses the entire program. Instead I found an example, called Blink Without Delay, and added/modified the following lines:

Code: [Select]
outputInterval = interval / 500;
  if(currentMillis - previousMillis > outputInterval)


Since I am trying to create subintervals out of an input pulse, that was in hopes of taking the measured interval and dividing it by a constant to get a faster pulse.

However that part didn't work, the output pulse stayed precisely 2x slower than the input pulse regardless of what I changed the constant to be.

Any suggestions?

My full code:
Code: [Select]
const int ledPin =  7;      // the number of the LED pin

int ledState = LOW;             // ledState used to set the LED
int pin = 2;
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval;           // interval at which to blink (milliseconds)
long outputInterval;

void setup() {

pinMode(ledPin, OUTPUT);   
pinMode(pin, INPUT);
Serial.begin(115200);
}

void loop()

  interval = pulseIn(pin, HIGH);
  Serial.println(interval);
  unsigned long currentMillis = millis();

outputInterval = interval / 500;
  if(currentMillis - previousMillis > outputInterval) {
    previousMillis = currentMillis; 

    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;


    digitalWrite(ledPin, ledState);
  }
}

CrossRoads

millis() returns unsigned long change your time variables to be unsigned long also.

You are only changing ledState one time after the end of the pulse measuring.
You need a for next loop after measuring the pulse width:
Code: [Select]

for (int i = 0; i<10; i+i+1){
//write the LED hi, lo with delay that is = to outputInterval
digitalWrite (ledPin, HIGH);
delay (outputInterval);
digitalWrite (ledPin, LOW);
delay (outputInterval);
}

That will get you to a set of pulses at the end of a pulse measurement; I think that will look like a burst of pulses during the off time of your initial pulse.

digitalWrite might slow the response down, in which case you use direct port manipulation:
Code: [Select]

// set output bit High, leave rest alone
PORTD = PIND | B10000000; // assumes ledPin is PortD, bit 7 for this example
delay(outputInterval);
// clear the output bit, leave rest alone
PORTD = PIND & B01111111;
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Go Up