Go Down

Topic: Digital implementation of a transferfunction, loop/sample-time? (Read 985 times) previous topic - next topic

SuperR

I am currently working on reading ADC's, performing calculations on these values, and outputting the result from that calculation through a DAC.

However, if I design a continuous time transferfunction/calculation and want to implement that in the arduino code, I need a fixed sample/run-time. If my loop-time is faster or slower than the sampletime specified in the translation from continuous time to discrete time, I have a mismatch between my designed transferfunction and the actual digital implementation of it.

Is there an option of forcing a wait until a timer reaches the set sample time (of say 100us) before the loop is run again?

UKHeliBob

Yes
Have a look at the BlinkWithoutDelay example in the IDE
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

SuperR

#2
Feb 24, 2013, 10:06 am Last Edit: Feb 24, 2013, 10:18 am by SuperR Reason: 1
Ahh ok, so if the loop is completed, I check if I may rerun it or I need to wait. I presume that this "timer" is run in the background which doesn't influence my computational power/time?!

If that's true, my next question would be;
What way is best/fastest to implement a discrete-time transferfunction/controller?
Do I store the required values from the past or can I use some sort of discrete time variable which remembers the last say 10 values?

In a different topic someone mentioned;


such a formula can be calculated quite well with an Arduino.

float x1 = ((((((7.716 * z - 37.57) * z + 73.23) * z  - 71.39) * z + 34.81) * z - 6.785) * z - 0.001332) * z - 1.96e-008  

This trick brings it down to 14 "simple" float operations instead of using power

Main problem might be that the Arduino only supports 32bit IEEE754 floats with ~7 significant digits.


-
I really feel like a noob, but since speed/performance is key in my current project, I need to start of well instead of fiddling around in crappy code I would initially write.

UKHeliBob

It does not run in the background but it does not block other code such as reading sensors or buttons, unlike the delay() function.  So, in your case start the timer, read values from the ADC, which can be quite slow, then, when the timer reaches its limit process the input.  You mention a period of 100uS in your original post. 

You will need to consider the use of micros() in your timer rather than millis() or even using one of the Arduino hardware timers.  There are other members here better placed than me to give you advice in that area.

The check to see whether the 'delay' time has passed is carried out each time loop() or another user defined control structure, such as while(), is executed.

I cannot help you explicitly with your other questions but it seems to me that an array would be a good way to hold a series of values for later access within the program.

I think that you do need to write some code to get you started, however "crappy" it is to start with.  Speed of operation, structure of code etc can often be improved but if there is no initial code then there is nothing to improve.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

SuperR

Thank you for your reply. I was aware of the micros() command after reading the example.

Concerning the code, this couple days are to get the info I need to start building the code. Some of the hardware is not available yet so this research is to get a head-start when I finish the hardware.

But, you are right, as soon as I get the HW done, I shall write my, to be expected crappy, code. Maybe the speed of the due is such high that I don't even need speed-enhancement.

Updates WILL come :), once..

majenko

A word of warning:

On the Aduino (and pretty much all microcontrollers) floating point operations are slow.

If you can use fixed point maths, in say Q15 format or similar, your calculations will be considerably faster and more efficient.

At the risk of being accused of proselytizing and willy-waving, I would also add that the Arduino is probably not the best platform for this kind of application, and something like a dsPIC based system would be more suited to your needs - although that would be harder to work with.

SuperR

If the Arduino environment won't work properly, I will try and get one of the dSpace pc's up and running.

I was hoping to built the entire thing from ground up with a DIY ADC and DAC. That would lead to the situation in which I would be 100% in control of everything and have the knowhow of every single component.

I will spend some time with the ADC IC's. If I can't get it up and running to my likings, I will bin the project and fiddle around with the dSpace setup.

majenko


If the Arduino environment won't work properly, I will try and get one of the dSpace pc's up and running.

I was hoping to built the entire thing from ground up with a DIY ADC and DAC. That would lead to the situation in which I would be 100% in control of everything and have the knowhow of every single component.

I will spend some time with the ADC IC's. If I can't get it up and running to my likings, I will bin the project and fiddle around with the dSpace setup.

It may work properly, it may not, it all depends on exactly what you are doing - the number of samples, the required sample times, the complexity of the maths, etc.

SuperR

Only time will tell :) As promised, I'll try and keep the topic updated. Tonight I will try and design a pcb for the ADC. Since I don't have the logic level converters available yet, I will use a Duemillanove or Uno for initial testing.


AWOL

Quote
Is there an option of forcing a wait until a timer reaches the set sample time (of say 100us) before the loop is run again?
note also that 100us is pretty much the time taken by analogRead which, like "delay()", is blocking.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

robtillaart


You can do ADC in asynchronous mode, start conversion and an interrupt reads value when done.

discussed here  - http://arduino.cc/forum/index.php/topic,125766.msg946608.html#msg946608 -
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

spatula


Quote
Is there an option of forcing a wait until a timer reaches the set sample time (of say 100us) before the loop is run again?
note also that 100us is pretty much the time taken by analogRead which, like "delay()", is blocking.


Can you confirm that the timing for an available() call  is much faster? In a simple loop, with timing based on micros(), it gives me 4us, which I understand is the minimum interval micros() can detect. Would it then be possible to call available() until the value returned is equal to the sample size, e.g.

Code: [Select]

while (serial.available() < sample_size)
{
// do something else
}
// now get the sample data
 

majenko

Serial.available() just returns the number of bytes in the receive buffer:

Code: [Select]

  return (unsigned int)(SERIAL_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % SERIAL_BUFFER_SIZE;

spatula


Serial.available() just returns the number of bytes in the receive buffer:


Exactly. The idea was, instead of waiting for a sample time, to check the availability of sample data of known size.

SuperR

Shame on me not not giving an update. In short;

-On the Atmega328 loop time was too high for my project
-On the Due, loop time was lower, but as soon as the uC had to perform some calculations, the loop time increased.

I finally end up using a high speed dSpace setup. And thank god for that. This made life much easier for my project. Funnily enough, once I finished the project I made a version for domestic use that consists of analogue circuitry.

The question in the OP however still remains. How to set up a proper discrete transfer function? Loop time, wise, I think I'll manage.

Ideally I want to 'enter' a transfer function. Alternatively, an IIR implementation might be sufficient.

Go Up