Author Topic: ADC/DAC Conversion to "decimal", best practices....  (Read 14499 times)

0 Members and 1 Guest are viewing this topic.

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3146
  • Country: ca
Re: ADC/DAC Conversion to "decimal", best practices....
« Reply #100 on: December 06, 2022, 09:06:16 pm »
I did some tests on a simulator using AVR XMega and later with a PC. There are at least two simple ways to calculate standard deviation.
There's no need to experiment. It all can be derived mathematically.

For example, for a 12-bit ADC, to calculate the sum of 100 squares exactly (without any error), you need 12 + 12 + 7 = 31 bits. So, 32-bit integers can calcuilate it exactly, floats cannot, doubles can.

For a 24-bit ADC you need 24 + 24 + 7 = 55 bits. So, 32-bit integers will not work, but 64-bit integers are Ok. Floats are not Ok. Doubles may have a very small error.

That's all there is to it.
 
The following users thanked this post: SiliconWizard

Offline jmaja

  • Frequent Contributor
  • **
  • Posts: 296
  • Country: fi
Re: ADC/DAC Conversion to "decimal", best practices....
« Reply #101 on: December 06, 2022, 09:34:16 pm »
I did some test with 32 and 64 bit unsigned integers. They seem to work a bit differently in PC and Xmega simulator. I used another way around approach without much thinking. Thus I set values as 10^n + i thus n=7 is about equal to n=-7 in the fp test.

I didn't do the final scaling (divide by 100 and by scale factor) nor sqrt in Xmega simulator and in PC I did those with double. Otherwise I would have lost accuracy.

In this case the latter standard deviation calculation method gave better results. But that may also be due to some not optimal calculation orders. With n=2 (1.01, 1.02 etc) I got quite good results, but the former method gives 2.887040 thus it has only 4 correct digits. At n=3 32 bit with the former method failed badly. The other worked fine at n=7, but at n=8 64bit with former method failed badly and 32bit with the latter even worse.

I tested only the latter method in Xmega. With 64bit it was spot on (unlike with PC) up to n=7 and failed badly at n=8. With 32bit it was spot on at n=2 but then failed totally at n=3.

32bit used about 10000 cycles and was 4 times faster than 32bit float. 64bit used about 60000 cycles and was 50% slower than 32bit fp without improving accuracy with my setup.

Most likely there is room for improvement with my quick and dirty test. Didn't even try to optimize accuracy nor speed.

 

Offline jmaja

  • Frequent Contributor
  • **
  • Posts: 296
  • Country: fi
Re: ADC/DAC Conversion to "decimal", best practices....
« Reply #102 on: December 06, 2022, 09:43:09 pm »
There's no need to experiment. It all can be derived mathematically.

For example, for a 12-bit ADC, to calculate the sum of 100 squares exactly (without any error), you need 12 + 12 + 7 = 31 bits. So, 32-bit integers can calcuilate it exactly, floats cannot, doubles can.
Of course you can derive that mathematically. I was also interested how many cycles are needed. That's easier to test. Also I was interested what you can achieve without that much thought for every operation in a case you don't really know how many bits you have in the first place. Most often there is no need to calculate exactly even when using fixed point.
 

Online DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5907
  • Country: es
Re: ADC/DAC Conversion to "decimal", best practices....
« Reply #103 on: December 07, 2022, 12:22:24 am »
Why do all the programming threads end with some (Apparently bored) tech guys kidnapping it and going mental?
And after all that, you didn't help OP at all. :popcorn:
OP asked form something simple, how to scale/convert adc value into voltage and output a string with it, avoiding floats if possible.

This is trivial, not the Large Hadron Collider, no complex scientific operations, just a damn multiplication and a division, are you going to make 200 pages of nosense overthinking?

Code: [Select]
void adc_to_str(uint16_t adc, char *out){           // Ex. adc = 3192
    const char *zero = "0.00mV";                    // For case adc = 0
    uint32_t val;
    uint8_t len=0;
    if (adc==0){
        do{
            *out++ = *zero;
        }while(*zero++);                            // Output: "0.00mV"
        return;
    }
    else{                                           // Scale adc value
        val = ((uint32_t)adc*1000244ul)+2048>>12;   // Fastest conversion
        //val = ((uint32_t)adc*1000000ul)/4095;     // Slower
    }                                               // val = 779487
    while(val){
        out[len++] = (val % 10) + '0';              // Output ascii numbers
        val /= 10;
    }                                               // Output is reversed: "784977"
    len--;
    for(uint8_t i=0; i<=(len/2); i++){              // Reverse string
        char c=out[i];
        out[i]=out[len-i];
        out[len-i]=c;
    }                                               // "779487"
    len++;
    out[len] = out[len-1];                          // Add decimal point, move last 2 digits to the right: "7794877"
    out[len-1] = out[len-2];                        // "7794887"
    out[len-2] = '.';                               // "7794.87"
    len++;
    out[len++] = 'm';                               // "7794.87m"
    out[len++] = 'V';                               // "7794.87mV"
    out[len] = '\0';                                // "7794.87mV" with NULL string termination (Finished)
}

Demo here: https://www.jdoodle.com/ia/AJc

Code: [Select]
adc: 0000    Output: 0.00mV
adc: 0512    Output: 1250.31mV
adc: 2048    Output: 5001.22mV
adc: 3192    Output: 7794.87mV
adc: 4095    Output: 10000.00mV
« Last Edit: December 07, 2022, 02:03:56 am by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline MK14

  • Super Contributor
  • ***
  • Posts: 4539
  • Country: gb
Re: ADC/DAC Conversion to "decimal", best practices....
« Reply #104 on: December 07, 2022, 01:05:21 am »
Why do all the programming threads end with some (Apparently bored) tech guys kidnapping it and going mental?
And after all that, you didn't help OP at all. :popcorn:
OP asked form something simple, how to scale/convert adc value into voltage and output a string with it, avoiding floats if possible.

This is trivial, not the Large Hadron Collider, no complex scientific operations, just a damn multiplication and a division, are you going to make 200 pages of nosense overthinking?

Code: [Select]
void adc_to_str(uint16_t adc, char *out){           // Ex. adc = 3192
    const char *zero = "0.00mV";                    // For case adc = 0
    uint32_t val;
    uint8_t len=0;
    if (adc==0){
        do{
            *out++ = *zero;
        }while(*zero++);                            // Output: "0.00mV"
        return;
    }
    else{                                           // Scale adc value
        val = ((uint32_t)adc*1000244ul)+2048>>12;   // Fastest conversion
        //val = ((uint32_t)adc*1000000ul)/4095;     // Slower
    }                                               // val = 779487
    while(val){
        out[len++] = (val % 10) + 0x30;             // Output ascii numbers
        val /= 10;
    }                                               // Output is reversed: "784977"
    len--;
    for(uint8_t i=0; i<=(len/2); i++){              // Reverse string
        char c=out[i];
        out[i]=out[len-i];
        out[len-i]=c;
    }                                               // "779487"
    len++;
    out[len] = out[len-1];                          // Add decimal point, move last 2 digits to the right: "7794877"
    out[len-1] = out[len-2];                        // "7794887"
    out[len-2] = '.';                               // "7794.87"
    len++;
    out[len++] = 'm';                               // "7794.87m"
    out[len++] = 'V';                               // "7794.87mV"
    out[len] = '\0';                                // "7794.87mV" with NULL string termination (Finished)
}

Demo here: https://www.jdoodle.com/ia/AJc

Code: [Select]
adc: 0000    Output: 0.00mV
adc: 0512    Output: 1250.31mV
adc: 2048    Output: 5001.22mV
adc: 3192    Output: 7794.87mV
adc: 4095    Output: 10000.00mV


I've tried warning people, earlier.  But this thread was started around 6.5 years ago (somewhat big necro), it was successfully answered (arguably), around the same time.  The OP doesn't seem to have logged in, for around the last 4.5 years.

Good job on the playground run-able (I tried it), program.  :)

EDIT:  Maybe the system should be configured to warn, NOT JUST the first person, to create a significant necro, to avoid possible mistakes like this.

Also, perhaps the system should more forcibly lock/hinder the necroing of threads, especially by 1 post brand new (usually/often SPAM BOT) users, or especially foolish users, in some cases.
« Last Edit: December 07, 2022, 01:17:08 am by MK14 »
 
The following users thanked this post: DavidAlfa

Online DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5907
  • Country: es
Re: ADC/DAC Conversion to "decimal", best practices....
« Reply #105 on: December 07, 2022, 02:01:34 am »
Holly cow, I didn't realize this was a 2016 necropost!

Yeah, this forum warns you with the message:

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

But if someone already ignored that and posted anyways, others coming later won't get the warning.
A necropost isn't necessary bad if you're going in the same route as the original thread...

The problem comes when RandomGuy2 posts into RandomGuy1's 2016 thread "Hey did you fix it?".
RandomGuy1 last time online: 2017 :palm:.

Other forums won't allow reopening old threads at all...
« Last Edit: December 07, 2022, 02:10:39 am by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: MK14

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8172
  • Country: fi
Re: ADC/DAC Conversion to "decimal", best practices....
« Reply #106 on: December 07, 2022, 08:49:40 am »
All this is pretty nice, but learn some arithmetics if you're not comfortable with that. It'll make you a much better programmer, I promise.

I've seen many programmers just using FP because they are not very comfortable with arithmetics and are thus just meaning to use a programming language as a glorified pocket calculator. Which was my main point.

But there sure are uses for FP, and uses for integer and fixed-point. If you know why you use one or the other with good technical reasons, then it's engineering. If you use one almost exclusively because you are more comfortable with it, then it becomes a silver bullet and it will end up equating to throwing things against the wall until they stick.
Most sensible post in ages on this thread, just hitting the thank you button is not enough.

I am truly amazed of to what lengths technical people, who really understand how to engineer these things, go when rationalizing non-technical decisions!
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8172
  • Country: fi
Re: ADC/DAC Conversion to "decimal", best practices....
« Reply #107 on: December 07, 2022, 08:55:35 am »
And after all that, you didn't help OP at all. :popcorn:
OP asked form something simple, how to scale/convert adc value into voltage and output a string with it, avoiding floats if possible.
And since the OP has not logged in in four years, it's pretty obvious no matter what we discussed, we did not help OP.

You "don't discuss anything I'm not interested in!!!" guys are weird. Why not just ignore (technical) posts you are not interested in? After all, this is all 100% relevant to the forum, subforum, and even to the thread. I'm truly baffled why discussing the accuracy of fixed points and floats triggers you, when the title says "ADC/DAC conversion to decimal, best practices". It's spot on, on topic!

Besides, I don't see a big issue discussing something in an old thread. This forum is not a helpdesk, it's a discussion forum. Live with it.

Your own mistake was to reply "to the OP" without reading the whole thread. That really sucks. But don't worry, I'm guilty of doing it all the time, too.
« Last Edit: December 07, 2022, 09:02:00 am by Siwastaja »
 

Offline voltsandjolts

  • Supporter
  • ****
  • Posts: 2300
  • Country: gb
Re: ADC/DAC Conversion to "decimal", best practices....
« Reply #108 on: December 07, 2022, 08:57:56 am »
Holly cow, I didn't realize this was a 2016 necropost!

I deliberately woke this thread.
Keeping related information together seems sensible to me, rather than starting a dozen threads about the same thing.

 
The following users thanked this post: Siwastaja

Offline MK14

  • Super Contributor
  • ***
  • Posts: 4539
  • Country: gb
Re: ADC/DAC Conversion to "decimal", best practices....
« Reply #109 on: December 07, 2022, 11:30:35 am »
It's been an ABSOLUTE DISASTER, train wreck of a thread, NECROING IT wise.

Total madness.

Let's wake up a long answered forum question.

NO, just NO!

You have ended up, by necroing this old/ancient thread, causing significant confusion, and wasted a lot of peoples time (it would seem).


Big Necro EDIT 15/03/23:
I have just striked out the entire post.
Soon or somewhat soon after making that post.  An increasing feeling of, I was TOO HARSH, making it, was felt (if I remember, correctly).

At some gentle or higher level, I agree with the post.  But the way it was originally written, was over the top.
« Last Edit: March 15, 2023, 12:28:29 pm by MK14 »
 

Offline MK14

  • Super Contributor
  • ***
  • Posts: 4539
  • Country: gb
Re: ADC/DAC Conversion to "decimal", best practices....
« Reply #110 on: December 07, 2022, 11:43:57 am »
On some forums, more like stack exchange and similar.  There is an attempt to reach the best possible technical answer, for some question.  E.g. Best/fastest way of factoring a large number.

So, keeping a thread like that alive (on the appropriate forums, especially), would make a lot of sense.

But, if someone asks for help, on a particular, fairly specific issue, on a more general help/questions and answers forum, such as this one.  It is much more geared up to leaving a long finished thread alone.

With fairly obvious exceptions, such as 'Post what your lab looks like' etc threads.

The complication with this thread, is that it has a fairly generic title, applicable to other things.  But in practice is about a very specific set of requirements, needs, to suit the original OP's, current project, at the time.
« Last Edit: December 07, 2022, 11:47:54 am by MK14 »
 

Offline voltsandjolts

  • Supporter
  • ****
  • Posts: 2300
  • Country: gb
Re: ADC/DAC Conversion to "decimal", best practices....
« Reply #111 on: March 15, 2023, 11:55:31 am »
On reflection, I don't agree at all with MK14 about necro posting.
It happens every day here on eevblog, with people regularly adding useful information to old threads, or asking in-context questions.
Better that than similar discussions spread across many threads.

If MK14 feels strongly about it, I suggest starting a poll about auto-locking threads older then x days.
Otherwise, please remember to check the post dates before joining a discussion.
 

Offline MK14

  • Super Contributor
  • ***
  • Posts: 4539
  • Country: gb
Re: ADC/DAC Conversion to "decimal", best practices....
« Reply #112 on: March 15, 2023, 12:27:02 pm »
On reflection, I don't agree at all with MK14 about necro posting.
It happens every day here on eevblog, with people regularly adding useful information to old threads, or asking in-context questions.
Better that than similar discussions spread across many threads.

If MK14 feels strongly about it, I suggest starting a poll about auto-locking threads older then x days.
Otherwise, please remember to check the post dates before joining a discussion.

Revised previous post:
https://www.eevblog.com/forum/microcontrollers/adcdac-conversion-to-_decimal_-best-practices/msg4567165/#msg4567165

I'm happy for our opinions to vary, about thread organization and necroing of older threads.

Because the original opening post, is in the form of a very specific question (in my opinion) , I think it is probably best to leave the thread alone.  As reawakening it, could cause some confusion.  As, not everyone checks the dates.  So, they may spend time trying to answer a specific question.
While unaware the question was asked many years ago, and the original poster, may have solved the problem, long ago, and could have left the forum, also many years ago.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf