user72368: I'm using a gyroscope, which returns angular velocity in floats. I'm trying to use this data with the arduino mouse library. The move function requires a signed character. I'm not what the best way is to convert the float data from the sensor into signed char.
In what way can I do this, losing the least in terms of precision?
I found out you can use dtostrf to transfer floats into an array of characters, but not sure what to do following this or if it's even the best way.
I would appreciate any guidance.

user7508: The mouse library expects the movement coordinates to be provided as
8-bit signed integers, which corresponds to the int8_t data type. This
type is actually an alias to signed char, but calling it this way is
confusing, as the word char somehow implies a type meant to store
characters, which is definitely not the case here.
Converting a float to any integer type can be done by plain
assignment, with two caveats:

If the float exceeds the range of the integer, the assignment will
wrap around modulo 2^(integer size in bits). This is undesirable and
can be prevented by first constrain()ing the float to the
appropriate range.
The assignment rounds towards zero, whereas rounding to the nearest
integer is better if you want to minimize the errors. This can be
achieved with the round() macro.

In summary:
// In global context:
const float scale = 0.4;  // scale factor for mouse moves

// Within loop():
float rotation = get_data_from_gyroscope();
int8_t mouse_move = round(constrain(rotation * scale, -128, +127));

Note that the optimal scale can only be determined experimentally: you
have to tweak it until your input device “feels” right.

user42015: You are misunderstanding the type char. It is named character, because in ASCII representation you can use it to save one character. But internally it just is a number. The Arduino doesn't care, if you save characters in it or numbers, because characters are also numbers for it.
A signed char, like the move() function of the library uses` has 1 byte and is signed, thus can hold numbers from -128 to 127.
While the documentation is not clear about what the x and y parameters really represent the answer to this question is clear about it. Basically the whole range from -128 to +127 represents a whole inch (or what the computer thinks is an inch). So this results in a resolution of 1" / (127 - -128) = 1" / 255 = 0.0039" (or about 0.1mm). I don't know, what values you are getting from the sensor, but you will have to scale it to somewhere in the -128 to 127 range (depends on how sensitive you want it to be). And you won't loose precision here. The sensor values most likely are more precise, than the range of the mouse move() function.
The calculation will then be as simple as
signed char mouse_x = sensor_x * factor + offset;

The result of the calculation will implicitly converted to a 1 byte signed integer (this is what signed char is). If you want to make it clearer what happens here, you can also write:
signed char mouse_x = (signed char)(sensor_x * factor + offset);

This is not needed, but you might wanna do it for clarity.

Seen in Edgar Bonets answer: You might wanna contrain the value of above calculation to the -128 to 127 range. If you get an unexpected high value from your sensor, the above calculation would overflow the mouse_x variable (not good for correct values). So capping the values to that range with the constrain() function is definitely good. Refer to Edgars answer and the documentation for this.

72368: <p>I'm using a gyroscope, which returns angular velocity in floats. I'm trying to use this data with the <a href="https://www.arduino.cc/reference/en/language/functions/usb/mouse/" rel="nofollow noreferrer">arduino mouse library</a>. The move function requires a signed character. I'm not what the best way is to convert the <code>float</code> data from the sensor into <code>signed char</code>.</p>
<p>In what way can I do this, losing the least in terms of precision?</p>
<p>I found out you can use <code>dtostrf</code> to transfer floats into an array of characters, but not sure what to do following this or if it's even the best way.</p>
<p>I would appreciate any guidance.</p>
 7508: <p>The mouse library expects the movement coordinates to be provided as
8-bit signed integers, which corresponds to the <code>int8_t</code> data type. This
type is actually an alias to <code>signed char</code>, but calling it this way is
confusing, as the word <code>char</code> somehow implies a type meant to store
characters, which is definitely not the case here.</p>
<p>Converting a <code>float</code> to any integer type can be done by plain
assignment, with two caveats:</p>
<ul>
<li>If the float exceeds the range of the integer, the assignment will
wrap around modulo 2^(integer size in bits). This is undesirable and
can be prevented by first <code>constrain()</code>ing the float to the
appropriate range.</li>
<li>The assignment rounds towards zero, whereas rounding to the nearest
integer is better if you want to minimize the errors. This can be
achieved with the <code>round()</code> macro.</li>
</ul>
<p>In summary:</p>
<pre class="lang-cpp prettyprint-override"><code>// In global context:
const float scale = 0.4;  // scale factor for mouse moves

// Within loop():
float rotation = get_data_from_gyroscope();
int8_t mouse_move = round(constrain(rotation * scale, -128, +127));
</code></pre>
<p>Note that the optimal scale can only be determined experimentally: you
have to tweak it until your input device “feels” right.</p>
 42015: <p>You are misunderstanding the type <code>char</code>. It is named character, because in ASCII representation you can use it to save one character. But internally it just is a number. The Arduino doesn't care, if you save characters in it or numbers, because characters are also numbers for it.</p>
<p>A <code>signed char</code>, like the <code>move()</code> function of the library uses` has 1 byte and is signed, thus can hold numbers from -128 to 127.</p>
<p>While the documentation is not clear about what the x and y parameters really represent the answer to <a href="https://arduino.stackexchange.com/questions/74757/mouse-move-values">this question</a> is clear about it. Basically the whole range from -128 to +127 represents a whole inch (or what the computer thinks is an inch). So this results in a resolution of <code>1&quot; / (127 - -128) = 1&quot; / 255 = 0.0039&quot;</code> (or about 0.1mm). I don't know, what values you are getting from the sensor, but you will have to scale it to somewhere in the -128 to 127 range (depends on how sensitive you want it to be). And you won't loose precision here. The sensor values most likely are more precise, than the range of the mouse <code>move()</code> function.</p>
<p>The calculation will then be as simple as</p>
<pre><code>signed char mouse_x = sensor_x * factor + offset;
</code></pre>
<p>The result of the calculation will implicitly converted to a 1 byte signed integer (this is what <code>signed char</code> is). If you want to make it clearer what happens here, you can also write:</p>
<pre><code>signed char mouse_x = (signed char)(sensor_x * factor + offset);
</code></pre>
<p>This is not needed, but you might wanna do it for clarity.</p>
<hr />
<p>Seen in Edgar Bonets answer: You might wanna contrain the value of above calculation to the -128 to 127 range. If you get an unexpected high value from your sensor, the above calculation would overflow the <code>mouse_x</code> variable (not good for correct values). So capping the values to that range with the <code>constrain()</code> function is definitely good. Refer to Edgars answer and the documentation for this.</p>
