You are here

20bit voltmeter | Cypress Semiconductor

20bit voltmeter

Summary: 40 Replies, Latest post by danaaknight on 15 Aug 2013 05:11 AM PDT
Verified Answers: 1
Last post
Log in to post new comments.
Dogma's picture
15 posts

Just started using the psoc 5 and learning C programming a few days ago.

Figured I would share my frist project with everyone.

I know the coding is crude, but it was done just as a way to start using the psoc 5.

I have a few projects in mind for using it, and need to learn so much,

as there really is a lot going on in this chip.

any pointers as to using pwm for DDS in the 300KHz range and at 1Hz steps.

Also need to know how to get at the SC/CT blocks directly so I can make my own part.

So much to learn, so little time. :)

Anyways, I will post more as I learn more abot this chip and hope that other will find it useful.

user_14586677's picture
7646 posts

Your code needs some assistance.


This construct,          ADC_VoltsData[1] = '0' + (ADC_Volts/100000) % 10;   // Format results for display

is trying to add an ordinal value, '0', to a long integer, ADC_Volts, to create a string in effect.


The easy way to do this is to use sprintf() [ printf(), but to a buffer ]  to create a single formatted string,

then UART_1_PutString( ) to send it all in one command.


Attached is info for setting up format statement of sprintf().


Regards, Dana.

user_14586677's picture
7646 posts

Correction to last post, I see you are trying to extract a single digit and

save its ascii value, which is one way of doing it, except you are trying

to combine a float + a char into a char, you need some cast operators.

If you stay with this method use ftoa() to convert float A/.D result to string,

then operate on that for formatting.


But sprintf() still the easy straightforward way.


Regards, Dana.

user_14586677's picture
7646 posts

Regarding SC/ST blocks -


You can consult TRM for register control of blocks.


Regards, Dana.

user_1377889's picture
9284 posts

There are 24 UDBs in a PSoC5 (Univesal Digital Blocks) from which many of the usermodules are built. These UDBs can be used to make up own modules by programming them using VeriLog as language. There are some videos (search there and take the time to watch) showing how that works and some examples are in detail described at the PSoC Sensei Blog.

You have set the conversion mode of your ADC to Multi-Sample which is not completely wrong. This mode is used when continually switching with an analog multiplexor between different inputs. Better would be to use the "Continuous" mode. With the higher sample rate I would suggest you to average some measures (10 to 100) to reduce some noise.


As a hint for programming (folks here know me to have a strong relationship to "Readable Code") I would suggest you to

Use separate functions for separate jobs ie. void InitializeHardware(void) or (void DisplayAnalogValue(int32 Voltage)

Your commenting is excellent, I like to see that

Keep the indentation of the lines more consistent

Use highlighting different areas of interest like variable declaration and function code





Dogma's picture
15 posts

First I would like to thank youtwo for even replying to this post.


There is a little more going on with my convertion than you may see untel you dig a little deeper.

I'll try and give more details as to what I did and why.

I am doing this because this is the way I learn.

Fisrt off, the D/A results and for in floating point, it is a signed number, that is a count from the converter.

This count can be a negative number, as the D/A can go 100mv below ground.

(Yes, Bob, I did not put comments about this in the code :) )

So, I just guessed at what the count offset would be for this 100mv and wipe out any negative number from the count.

Next is my conversion form the count to a long 32 interger.

This is really just multiplying the count by the weight of what one count is equal to in voltage.

BTW there is an API to convert the results into Volts, millIvolts and microvolts, just cound not seem to get it to work.

The problem with with any results held in a interger or any variable for that matter, is that leading 0's are surpressed.

String's do not have this problem, so I have to convert my leading 0 surpressed number into a string.

This is done by checking the weight of each digit "(result/weight) % 10;",  if that weights position is 'empty',

then an ascii '0' and placed in the string, if the weights position has in value, that is just passed to the string.

To use ftoa() I would have to look at how efficient that code is, and if it's is, then sure.

now on to sprintf(), I am assuming this is a serial version of printf() you provided a PDF on.

If so, I don't think I can use it, as this would not allow for flow control of the serial data to the display.

However, printf() does have formatting commands in it. BTW thank you for that fine doc on a C function.

As I had said, very new to C programming and the biggest problem I have with it is syntax and knowing whats

availabale for a function.

The link you had posted is abut the differences between products of the SC blocks.

how about a link to the TRM for register control of blocks.


Now to reply to Bob,

Bob, I know of VeriLog, but know nothing about it, some thing else I have to learn.

This is what I meant by so much to learn, so little time :).

To fully use this chip, there is a lot of things to learn, and that takes time.

I have watched the video/classes, some 20 of them so far, and a lot of it is over my head,

as I am not even close to knowing a thing about the subject.

Anyways, gevin time, I will get there.

As far as my programming, Like I said, this was crude, just wanted results displayed.

I wanted to see some thing out of the chip and my time invested into it.

Yes, I know I should have broken it into more callable loops :), but was being lazy.

But you brought up highlighting, not sure what you mean by this, as I do thing the file gets saved

as a basic text file, no real formatting.


Again, really thank you for your insights, and will be playing more and hopefully I improve as time goes on.












user_14586677's picture
7646 posts

printf() prints to the system stdout, see this book, attached. Normally

one thinks of a console or printer. Can also be a file system.


sprintf() prints to a buffer you set up.  Uses same formatting control as



So normally using sprintf() it converts the numeric, and formats it all in one

call and places results in a buffer. Then you use string UART command to

xmit to whatever.


Regards, Dana.

user_14586677's picture
7646 posts

"This count can be a negative number, as the D/A can go 100mv below ground."

You are referring to the offset spec, which can be +/- .9 LSB. The VDAC value

you write is a uint8, unsigned. 1 LSB, in an 8 bit DAC, with a reference of 1.024 V,

equals ( 1 / 256 ) x 1.024V = 4 mV.


One way of handling offset is to write 0 to VDAC, and measure offset with A/D.

Then subtract from further DAC readings. Of course this is a crude approach

as T effects, noise, long term drift not handled.


Regards, Dana.

Dogma's picture
15 posts



Thank you so much for clearing up sprintf() in my mind, I had looked at it and just did not see how to apply it.

You have creally shown me what it can do and how it relates. I guess there will be a ver 3 of this little project. lol

As in ver 2, I did a lot of clean up from the advive you two had given me, but I did not add in more loops,

but it is more clearly written for doing so.


as far as the offest goes, I used a 7 1/2 digit volt meter and a secondary 7 digit voltage standard as the source to the adc.

yep, I did look at how well the adc did over temp, conversion speed and number of bits. 

I have to say, not bad for a cheap little chip!


I see that I said D/A, sorry about that, this whole project is using the delta sigma a/d.


BTW, thank you for the C programming book!





Dogma's picture
15 posts

OK I made some improvements to this little voltmeter.
Now using calls to functions and snprintf

However, I really don't think using snprintf over the way I was doing it is better.
snprintf used 20k of flash, come on now, 20k compared to like 30 bytes doing it my way.
I hate to see what snprintf does to cpu cycles.

If you read the comments, you'll note that I want to pass variables to and from my function calls,
just can't seem to get how that works, until I firure it out, most variables are global.

user_1377889's picture
9284 posts

Concerning the use of local vs global variables



Log in to post new comments.