pulse generator

The "Eleven" is our Uno-equivalent Arduino-compatible board, but with a number of improvements including prototyping area, a mini-USB connector, LEDs mounted near the edge, and the D13 LED isolated using a FET. [Product page]
Post Reply
saeed
Posts: 2
Joined: Tue Aug 27, 2013 1:26 am

pulse generator

Post by saeed » Tue Aug 27, 2013 1:59 am

Hi All,

I am new to whole game of Arduino! just got my Eleven board and trying a project on it.
I want to simulate few field instruments. To start we have a valve and a meter which generates two pulses based on the flow in the pipe. Two pulses have 90d difference to detect direction of flow.

Valve is a digital one and has two inputs which can make 3 different flow demand stage (4th state is not used). They are Opening, Closing or Hold ( this is just normal way a digital valve works I added for clarification). That means i need to change the frequency of pulses based on the inputs. Maximum freq ideally would be 1kHz but if it turns out to be too much, with some compromises half of that would be okay too.

Now to generate pulse train I am using Sin() function which is standard way of making it and it works fine in C# on my PC. But here seems it is a bit too much to process in each cycle. below is simplified version of what I have tried. I had feedback inputs in as well but no luck so took them out. I don't get a consistent result for below program.

I also have tried delay() function to do the same but it puts all functions on hold so is not a good thing if we have few different things going on at the same time.

So my questions are:
1- Is there anyone else here has tried similar thing and have got better results?
2- What is the maximum freq. we can expect from Eleven ? ( any other boards that might be significantly better?)
3- How long it takes to loop() function to re-start again? I know it will be depending on how big is that but any standard figures with standard assumptions would be helpful.
4- Any better ways you can suggest to do this?

any help would be greatly appreciated :)

Cheers,

Saeed

Notes: having or not having "PI" in the equation also appears to have a big impact on the results so happy to take them out.

Code: Select all

int pulserPinA=2;
int pulserPinB=3;
int uSPin=8;
int dSPin=9;
timeCostant=100;

//---------------------------------------SETUP-------------------------------------------------------------
void setup()  { 
      pinMode(pulserPinA, OUTPUT); 
      pinMode(pulserPinB, OUTPUT); 
      pinMode(uSPin, INPUT); 
      pinMode(dSPin, INPUT); 
          } 
//---------------------------------------LOOP-------------------------------------------------------------
void loop()  {
  double t=0;
  boolean valuePulseA=false;
  boolean valuePulseB=false;
    t = millis()/timeCostant;
//      sin((2 * PI * t) + (0 * PI / 4)) > 0 ? valuePulseA=false : valuePulseA=true;
//      sin((2 * PI * t) + (2 * PI / 4)) > 0 ? valuePulseB=false : valuePulseB=true;
      sin(t) > .4 ? valuePulseA=false : valuePulseA=true;
      sin(t+2) > .4 ? valuePulseB=false : valuePulseB=true;
      digitalWrite(pulserPinA, valuePulseA);
      digitalWrite(pulserPinB, valuePulseB);

}

angusgr
Freetronics Staff
Freetronics Staff
Posts: 853
Joined: Tue Apr 09, 2013 11:19 pm
Location: Melbourne, Australia
Contact:

Re: pulse generator

Post by angusgr » Wed Aug 28, 2013 12:43 am

Hi Saeed,

Nice project, sounds like a good use for Arduino!

I have a few comments that might help you out:
saeed wrote: 2- What is the maximum freq. we can expect from Eleven ? ( any other boards that might be significantly better?)
I think an Eleven is an excellent choice for this application.

As to maximum frequency, you can flip a pin back and forth at few hundred kHz if you just call

Code: Select all

digitalWrite(pin, HIGH);
digitalWrite(pin, LOW);
... in a loop. There are ways to increase that to a few MHz by software approach, if you really need that high frequency output.

However most of the time you want to do some calculations in between just twiddling pins, and this is where then answer changes from "a few hundred kHz or more" to "it depends". :)

One of the really expensive things to do on a board like the Eleven is floating point mathematics. Because the microcontroller has no floating point unit (FPU), floating point mathematics is emulated using integer (whole number) mathematical operations. This makes calculations like sin() very, very slow (I don't know exactly how slow, but if you're seeing very bad performance in your loop then this is why.)

A common way to achieve high speed sine function output without floating point is to use "wavetable synthesis" where you pre-calculate the likely values of sin(X) for the range and resolution you need, and then store it in a precalculated table.

In this case though I think a better approach is to try and figure out a way of simulating the output without requiring a sine function at all.
3- How long it takes to loop() function to re-start again? I know it will be depending on how big is that but any standard figures with standard assumptions would be helpful.
loop() starts again as soon as the previous loop() finishes. So again it depends on how much work you're doing in the loop.
4- Any better ways you can suggest to do this?
I think you may be able to get away with just simulating the raw output of the sensor. Do you have any information on exactly what it outputs? Is it a rotary encoder signal?

You can simulate encoder output really simply by just sequencing through the four states of output. Something like:

Code: Select all

const int speedConstant = 25; // Time (in ms) between each rotation step

void loop() {
  digitalWrite(pulserPinA, LOW);
  digitalWrite(pulserPinB, LOW);
  delay(speedConstant);
  digitalWrite(pulserPinA, LOW);
  digitalWrite(pulserPinB, HIGH);
  delay(speedConstant);
  digitalWrite(pulserPinA, HIGH);
  digitalWrite(pulserPinB, HIGH);
  delay(speedConstant);
  digitalWrite(pulserPinA, HIGH);
  digitalWrite(pulserPinB, LOW);
  delay(speedConstant);
}
Would an approach like that work? In this case the overhead due to computation is almost nothing, so you can adjust the speedConstant (or make it a variable) in order to get whatever output frequency you desire (up to a few kHz anyhow.)

Finally, just a small suggestion from the code snippet you posted:

Code: Select all

      sin(t) > .4 ? valuePulseA=false : valuePulseA=true;
      sin(t+2) > .4 ? valuePulseB=false : valuePulseB=true;
This is just a suggestion when writing code like this. I know that when prototyping everyone ofen does things a funny way because they're experimenting, so that is probably what happened here, but I found this much easier to read as:

Code: Select all

valuePulseA = sin(t) <= .4;
valuePulseB = sin(t+2) <= .4;
Regards,


Angus

saeed
Posts: 2
Joined: Tue Aug 27, 2013 1:26 am

Re: pulse generator

Post by saeed » Wed Aug 28, 2013 7:04 am

Hi Angus,

thanks for your reply, I appreciate your time. Very good points and hints. Now I can see the difference on resources when changing from PC to a controller.
using Sine function then is not an option. That lookup table is an interesting way of making up the function.

The way you mentioned to make HIGH,LOW levels is what I started with, at the beginning. But that's limiting me to just one pulser unit (?) while I need more independent pulsers with different frequencies on each unit.

I did some more research and found that ATmega328P has 3 internal timers which we can have access to. I am giving them a go and see what happens.
These are some useful links if someone is looking for some more information on Timers.
Atmel datasheet:
http://www.atmel.com/Images/Atmel-8271- ... asheet.pdf

http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM

cheers,
Saeed

angusgr
Freetronics Staff
Freetronics Staff
Posts: 853
Joined: Tue Apr 09, 2013 11:19 pm
Location: Melbourne, Australia
Contact:

Re: pulse generator

Post by angusgr » Wed Aug 28, 2013 11:59 pm

Hi Saeed,

Yes, I can see how scaling this scenario to multiple sets of outputs becomes a problem.

Timers are a good solution. There are also some Arduino scheduling libraries that may make the code easier to write, for example this one (but there are others.)

Keen to hear how you get on.


Angus

Post Reply