Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
11 years, 6 months ago.
AnalogOut and maths probleme?
Hello,
I do sawtooth wave ramps with my mbed and his DAC and during my experiment i see a probleme.
if you take this two codes with the only change is the maths opperator you don't have the same ramps.
doesn't work
for(i=0;i<terminal;i++) sawtooth = sawtooth - 0.001;
doesn't work
for(i=0;i<terminal;i++) sawtooth = sawtooth + 0.001;
I do the test with the AnalogOut.write_u16 function and it work but not with float type.
it work
int sawtooth_u16 = sawtooth.read()*65535; if(flag) sawtooth_u16 = sawtooth_u16 - 65; else sawtooth_u16 = sawtooth_u16 + 65; sawtooth.write_u16(sawtooth_u16);
i hope a good result!
Thx, YSI
Question relating to:
3 Answers
11 years, 6 months ago.
The specification for AnalogOut says that the write method accepts a float parameter representing a percentage. That is a bit confusing since the valid range is between 0.0 and 1.0 (and not between 0.0 and 100.0 as you might expect).
Did you declare sawtooth as float in your first example? You will get a constant value of '0' when declaring sawtooth as int because of rounding,
11 years, 6 months ago.
Hi, YSI
Try this:
for(int i=0; i<1000; i++) { signal = signal + 0.001; wait_us(1); }
How did you declare i at first, when it didn't work?
-=-=-=-=-=-=-=-=
thenoble66
11 years, 6 months ago.
Hi,
@Wim Huiskamp and Gyozo Nemes thx for answers.
sawtooth is my AnalogOut so it's accepts a float parameter between 0.0 and 1.0 i am agree.
My probleme isn't my AnalogOut, it work! The bug is on opperator '+' and '-' on floating signal. For my two first code i try to illustrate that when you do '+' or '-' you dont have the same result.
i take picture of my scope for illustrate the sawtooth wave generate by the two first code.
opperator +
for(i=0;i<terminal;i++) sawtooth = sawtooth + 0.001;
opperator -
for(i=0;i<terminal;i++) sawtooth = sawtooth - 0.001;
YSI
#include "mbed.h" DigitalOut L1(LED1); DigitalIn sawtooth(p9); // this is a control line for rampup (left unconnected) or rampdown (on GND) AnalogOut signal(p18); // DAC output float justAFloat; // temporary variable for math operations int main() { sawtooth.mode(PullUp); // pullup mode for control line while(1) { if (sawtooth) { // this is the part for ramp-up justAFloat = 0.0; for(int i=0; i<1000; i++) { L1 = 1; justAFloat = justAFloat + 0.001; // do not use the signal directly L1 = 0; signal = justAFloat; // new value to DAC signal wait_us(1); }; } else { // this is the part for ramp-down justAFloat = 1.0; for(int i=0; i<1000; i++) { L1 = 1; justAFloat = justAFloat - 0.001; L1 = 0; signal = justAFloat; wait_us(1); }; } } }
At first sight it seems, that if you work on DAC output directly by some math operations, subtracting and adding work with different steps, that is why decrementing finishes faster, than incrementing. If you use a different variable for math and only the result will go to DAC, everything goes well. I'll have to read the datasheet of the 1768 and some library source to find a better explanation on this.
Regards.
posted by 24 Jun 2013Hi Gyozo Nemes,
Sorry for time to answer and my bad english level. Thanks for your help, your code works because you work always on different variable and never controle your DAC result. So the only difference beetwen our code is i use DAC read() function, if you take your code and put a read function beetwen each decrementing or incrementing you can see the bug.
code buged
#include "mbed.h" DigitalOut L1(LED1); DigitalIn sawtooth(p9); // this is a control line for rampup (left unconnected) or rampdown (on GND) AnalogOut signal(p18); // DAC output float justAFloat; // temporary variable for math operations int main() { sawtooth.mode(PullUp); // pullup mode for control line while(1) { if (sawtooth) { // this is the part for ramp-up justAFloat = 0.0; for(int i=0; i<1000; i++) { L1 = 1; justAFloat = justAFloat + 0.001; // do not use the signal directly L1 = 0; signal = justAFloat; // new value to DAC signal wait_us(1); justAFloat = signal.read(); }; } else { // this is the part for ramp-down justAFloat = 1.0; for(int i=0; i<1000; i++) { L1 = 1; justAFloat = justAFloat - 0.001; L1 = 0; signal = justAFloat; wait_us(1); justAFloat = signal.read(); }; } } }
But where i am lost and i don't understand, that is in my first post i give a working code with DAC read function but write_u16 fonction and it work ...
it work
int sawtooth_u16 = sawtooth.read()*65535; if(flag) sawtooth_u16 = sawtooth_u16 - 65; else sawtooth_u16 = sawtooth_u16 + 65; sawtooth.write_u16(sawtooth_u16);
Best is to use a seperate variable and write that to the analogOut. Problem by incrementing the analogout is that you read the rounded previously written value, so you get rounding errors continiously, and apparantly that is slightly different for incrementing an decrementing. Even if it would be the same, it still is a better idea to prevent that rounding altogether: just increment/decrement a variable and write that to AnalogOut.
posted by 02 Jul 2013Like Erik said: use a separate variable. In your working code you've just used a separate variable, namely sawtooth_u16, that is the reason why your code is working. So, don't be lost ;-)
BTW: even the documentation page says for the AnalogOut.read():
Quote:
This value may not match exactly the value set by a previous write()
Regards.
posted by 02 Jul 2013