 <p>ADC in AVR is in unsigned 10-bit form, not a double. And the ADC can be read as two separate bytes, ADCL and ADCH. ADCL must be read first.</p> <p>If you want to send some other <code>uint16_t val</code> use</p> <pre><code>uint8_t lo = (uint8_t)val; uint8_t hi = (uint8_t)(val &gt;&gt; 8); </code></pre> <p><code>double</code> and <code>float</code> are both 4 bytes long. If you want to send a <code>double dval</code> use this trick</p> <pre><code>uint32_t val32 = * (uint32_t *) &amp;dval; </code></pre> <p>(Create a pointer to the dval with the address operator <code>&amp;</code>. Cast that pointer to a pointer to a <code>uint32_t</code>, which is a variable taking up the same number of bytes. Then dereference the pointer to get the value, which goes into val32.</p> <p>This is not the same as simply casting the dval to a uint32_t. That would truncate the number.)</p> <p>Send <code>val32</code> in 4 pieces by shifting as above. Recover by shifting and <code>|</code>, then use a similar pointer trick to turn the result back into a double.</p>