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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy