Maker Pro
Maker Pro

ADC basic theory

niki2013

Feb 21, 2021
5
Joined
Feb 21, 2021
Messages
5
Hi all hope everyone keeps well.

I am back with another of these annoying newbies questions. I am going arround the ADC modul and i have some basic understandin problems.

After function has read the analog input, puts the binary result on the High and Low address registers which is in binary. Up to here i think i am good understanding. After we assign the binary result to an integer variable through the following: digital = ((ADRESH << 8) + ADRESL); and we return to main. There we assign to a float variable voltage as follows:

voltage= digital*((float)vref/(float)1023); and then we make a sprintf to be able to write on LCD.

From the point ADC puts the results on the address registers and after i am lost. If the binary number lets say is 0011.1(3.5v) when we assign to integer digital is not after like 3. And then the whole calculation line isn't wrong [voltage= digital*((float)vref/(float)1023);]. I am loosing something
icon_sad.gif
.

All this i am asking because i don't want to use sprintf is killing my memory. I wanted to try to write code to make this instead but if i don't know what i have to convert is no meanning. I check the internet a lot about but 99.9% of the tutorials is with sprintf the easier one
bigSmile.gif
.

I don't know if there is any help to post a code for the question or the pic i use. In case is needed asked to do so.

Thanks all for reading i hope you can help me
209.gif
 

Harald Kapp

Moderator
Moderator
Nov 17, 2011
12,756
Joined
Nov 17, 2011
Messages
12,756
going arround the ADC modul
Which processor platform? PIC?
Which programming environment?
There we assign to a float variable voltage as follows:
When using a microcontroller avoid using float unless the controller has a floating point unit (not many do). Floating point math has to be emulated by a software library costing processing time and memory.
Use millivolts (mV) instead, that gives you 1000 times the resolution of using Volts (V) without the need for floating point math.
1 V = 1000 mV
voltage = digital × (vref × 1000) /1023
Assuming vref = 5 V the term in parentheses evaluates to 5000.
Next division by 1023 can be substitued by a (usually) much faster shift right by 10 places:
voltage = (digital × 5000) >> 10 //result in millivolts.
Note that you will need at least 16 bit integers to accommodate the huge intermediate result of the multiplication by 5000.
If the binary number lets say is 0011.1
The binary output from an ADC usually is an integer, not a number with decimals. Where do you get a value like 0011.1 from?
i don't want to use sprintf is killing my memory
If you want to write your own conversion from float to ASCII for printing a value, your code is likely to take up as much space as sprintf() unless you are skilled to highly optimize the code - in wich case you wouldn't be here asking ;).
If you stick to integers, thins will be easier.

Showing us sample code will make it easier for us to understand your problem. Use the "insert" menu button #9 from the right side to insert code snippets into your post.
 
Last edited:

niki2013

Feb 21, 2021
5
Joined
Feb 21, 2021
Messages
5
Yes you are right i left it with sprintf function and works fine and the memory levels are ok so i will stick with that as you recommended.
I would like to ask you a relevant question. i have expant my experiment trying to learn more about the sprintf and how to use conversions of data types. I am facing a wall at the moment. I am trying to convert a unsigned long to string. Explaining:
I use 2 timers to count pulse. i use the following expression for that freq = st_TMR1L+(st_TMR1H<<8)+(st_TMR1_ovfl<<16);
freq and st_TMR1_ovfl are unsigned long the rest are unsigned short. My sprintf looks like:
sprintf(Txt, "%lu", freq); what is should be the type of string Txt[sizeof(unsigned long)] to keep number up to F FFFF(1048574) i am measuring frequency up to 1MHz.

Thanks a million for reading
 

Harald Kapp

Moderator
Moderator
Nov 17, 2011
12,756
Joined
Nov 17, 2011
Messages
12,756
First:it is good practice to explicitly cast the data types so they match. Do not rely on the compiler to do this.
The classic cast in C is :
Code:
freq = (unsigned long) st_TMR1L + ((unsigned long) st_TMR1H<<8) + (st_TMR1_ovfl<<16);

Second:
what is should be the type of string Txt[sizeof(unsigned long)]
A string in C is an array of characters (I will not worry about using pointers here). The length of the array needs to be number of characters + 1 (or higher). "+1" for the trailing "/0" that terminates the string. For your 7 characters the array needs to be 8 characters long:
Code:
char txt[8];

My recommendation: When you switch to a new topic, create a new thread. Mixing different issues within one thread is confusing. You can always reference another thread using a link.
 

niki2013

Feb 21, 2021
5
Joined
Feb 21, 2021
Messages
5
Hi
Thank you for your answer i will open a new thread you are right on that is better for future use from someone else.
About the project i am building i will keep inform in the new thread.

Regards
 
Top