-2

The microcontroller I have to implement my digital filter does not support floating point operations.

Given an analog input signal (which can take on values from -1.65 V to 1.65 V) sampled at a given rate of 100 Hz, I can only perform fixed-point operations. So I'm guessing I have to convert my input to fixed point first. It is also stated that the output of the ADC is quantized into unsigned 10-bit values.

My problem is.

I know that there is a Qm.n format for fixed-points which includes a sign bit. And none of the references online include conversion from signed input floating point to unsigned fixed-point

AND I FOUND THIS CODE:

int fixedValue = (int)Math.Round(floatValue*Scale);

double floatValue = (double)fixedValue/Scale;

Questions: 1. How can I choose my scaling factor? 2. Is it dependent on the range of my input values and the number of bits used for the fixed-point representation? 3. The Qm.n format uses a signed bit. Can fixed point representations be unsigned?

It all boils down to choosing the scaling factor and mapping from signed input to unsigned 10 bit fixed point (which will be used for further calculations in solving a difference equation then converting it back to double at the output)

Thanks in advance.

chaine09
  • 77
  • 1
  • 1
  • 6
  • This isn't clear - where is the floating-point here? – Oliver Charlesworth Dec 05 '15 at 19:46
  • I'll edit my question sir – chaine09 Dec 05 '15 at 19:47
  • @OliverCharlesworth please see the changes in my question above – chaine09 Dec 05 '15 at 19:51
  • 1
    If you know how to convert "unsigned double floating point to fixed point",and its trivial to test/convert a negative floating point number to positive, just convert negative numbers to positive, map those to 0 to 511 and convert positive numbers to 512 to 1023. – chux - Reinstate Monica Dec 05 '15 at 19:51
  • @chux I learned conversion to fixed-point only from the internet, and all of them discussed conversion from unsigned floating points only. Can you explain further? – chaine09 Dec 05 '15 at 19:56
  • @chux how did you get the range 0 to 511 and 512 to 1023? – chaine09 Dec 05 '15 at 19:57
  • "into unsigned 10-bit values" has the range 0 to 1023. So half for the negative voltages and half for the positive ones. – chux - Reinstate Monica Dec 05 '15 at 20:03
  • @user2569770 Why is there a restriction that the fixed-point numbers cannot be signed?Signed fixed-point representations are common, e.g S15.16 stored in a signed 32-bit integer type. Since your source data is signed, use of signed fixed-point arithmetic seems like a natural match. – njuffa Dec 05 '15 at 20:04
  • @chux can you point me to references regarding mapping the values to fixed-point representations? The code I am using is (x)*(double)(1< – chaine09 Dec 05 '15 at 20:07
  • 3
    Is this an X-Y question? If you want a fixed-point representation you could work in the `int` (or even `unsigned`) value provided by the ADC converter, then scale it for output. – Weather Vane Dec 05 '15 at 20:07
  • @njuffa I'm really confused with the Q-format which includes a sign bit. – chaine09 Dec 05 '15 at 20:09
  • @njuffa "the voltages are quantized into unsigned 10-bit values" quantization refers to conversion to fixed-point right? – chaine09 Dec 05 '15 at 20:11
  • @WeatherVane can you explain it further in an answer? Im kind of new to fixed point representations. – chaine09 Dec 05 '15 at 20:12
  • @user2569770 Your question and its context is unclear to me. What is the format in which the original source data is delivered? What does the "10-bit quantized" refer to? The resolution of the ADC? – njuffa Dec 05 '15 at 20:15
  • @user2569770 I am tempted to answer, but there is so much unclarity in your requirements that I cannot. Your question is too broad, and includes ideas you may or may not be able to implement. Why not start with what you can measure, state what you want as output, and what the coding language can do? Sorry. – Weather Vane Dec 05 '15 at 20:21
  • @njuffa I have edited my question – chaine09 Dec 05 '15 at 20:23
  • @WeatherVane I have edited my question. Thanks – chaine09 Dec 05 '15 at 20:24
  • Yes, but can your compiler do `double`? If not, why is it even there in the question? – Weather Vane Dec 05 '15 at 20:25
  • Excuse me, but look at the question title. You don't even have "signed double inputs". You have `int` or `unsigned` ADC converter count inputs. – Weather Vane Dec 05 '15 at 20:31
  • @WeatherVane some microcontrollers do not support floating point operations. My input is a sine wave but the values it can take is from -1.65 V to 1.65 V. – chaine09 Dec 05 '15 at 20:35
  • @user2569770 "some microcontrollers do not support floating point operations". Please put in the **QUESTION** whether *yours* does, or does not, thanks. I am mystified why you apparently want to convert `double` to fixed point int. – Weather Vane Dec 05 '15 at 20:38
  • What have you tried? C does not have `Math.Round()`. This is getting tedious. – Weather Vane Dec 05 '15 at 20:40
  • @WeatherVane I have edited my question. I am terribly sorry for the confusion. What can I use in place of the Math.Round()? – chaine09 Dec 05 '15 at 20:45
  • @user2569770 please don't be put off. Life isn't knowing the answers, but asking the right questions. – Weather Vane Dec 05 '15 at 20:50
  • @WeatherVane yes, but english is not my first language – chaine09 Dec 05 '15 at 20:59
  • @user2569770 I didn't notice that. – Weather Vane Dec 05 '15 at 21:03
  • http://stackoverflow.com/questions/34125700/how-to-convert-from-floating-point-to-fixed-point-which-will-be-used-in-operati – chaine09 Dec 07 '15 at 04:15

1 Answers1

2

Use a simple 2-point interpolation.

#define Value_MAX  1.65
#define Value_MIN  (-1.65)
#define value10bit_MAX  1023
#define value10bit_MIN  0
#define slope ((value10bit_MAX - value10bit_MIN)/(Value_MAX - Value_MIN))

int value10bit = (int)Math.Round((floatValue - Value_MIN)*slope + value10bit_MIN);

OP reports "microcontroller that only support fixed-point operations." yet appears to be using (or wants to use) int fixedValue = (int)Math.Round(floatValue*Scale);. So maybe this works for OP

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • 1
    @chux thanks for the answer! So I no longer need a scaling factor in my code? – chaine09 Dec 05 '15 at 20:33
  • The definition of `Scale` is unclear. In fact, I would expect an embedded processor to _provide_ a 10-bit value from its Analog-to-Digital converter and so negates the need for this whole conversion. IAC, the 2-point mapping can work in either direction - basic school math. – chux - Reinstate Monica Dec 05 '15 at 20:41
  • Technically, `Value_MIN` should also be parenthesized as `-` is an operator. It is quite unlikely to cause a problem, but it is a good habit to not make exceptions in this matter, macros are tricky enough ;-) – chqrlie Dec 05 '15 at 20:48
  • @chqrlie [you are correct sir!](https://www.youtube.com/watch?v=pgewIj1tl_k). I been for so long using `(1023)` when I could have used `1023`, that carried the to `-1.65`. – chux - Reinstate Monica Dec 05 '15 at 20:51
  • 1
    @chux thanks! how can you convert it back to double? :) – chaine09 Dec 05 '15 at 20:58
  • What if `floatValue` is outside the range, should you not also add a clamping scheme? – chqrlie Dec 05 '15 at 21:03
  • 1
    @user2569770 your question added "does not support floating point operations" so it's still unclear what you want. – Weather Vane Dec 05 '15 at 21:04
  • @WeatherVane my input (sine wave) obviously can be any real number not only integers, but my microcontroller only support fixed point operations (integer) so I have to convert my input (floating point) to fixed-point for it to be processed by my microcontroller. :-) – chaine09 Dec 05 '15 at 21:11
  • @chux how about using the converted values in operations such as addition and multiplication? Do I have to add some lines of code to handle this or just convert the final answer back to double? And perform operations normally? – chaine09 Dec 05 '15 at 21:14
  • @chux your code did not yield to the correct answer after I converted it back to double. – chaine09 Dec 06 '15 at 15:06
  • @user2569770 What was the original value? What was the converted value? What was the expected value? "not yield to the correct answer after I converted it back to double" is not much to go on. Recall that a 10-bit value does not have the precision of a `double`. – chux - Reinstate Monica Dec 06 '15 at 18:16
  • @chux say I have to add (double)(1.00) + (double)(2.00), if I convert both addends to fixed-point via your code, and convert the answer back to double, I will get 4.7 (if I remembered correctly). So I think in operations such as addition and multiplication, you can't operate directly on the converted fixed-point values. I made a new question: – chaine09 Dec 07 '15 at 03:01
  • @chux http://stackoverflow.com/questions/34125700/how-to-convert-from-floating-point-to-fixed-point-which-will-be-used-in-operati – chaine09 Dec 07 '15 at 03:01