-1
\$\begingroup\$

I'm reading a sensor value and passing it to TX to view it on my computer. I have the following chunk of code:

    while(1)
    {
        unsigned int reading = ADCW;

        UDR0 = ADCL; // Low value
        UDR0 = ADCH; // High value

        if (reading > 512 )
        {
            // It's bright
        } else {
            // It's dark
        }

        _delay_ms(30);
    }

I'm getting the following output:

00000674: 00010010 00000010  ..
00000676: 00011111 00000010  ..
00000678: 00010100 00000010  ..
0000067a: 00010101 00000010  ..
0000067c: 00011111 00000010  ..
0000067e: 00000010 00011001  ..
00000680: 00000010 00011110  ..
00000682: 00000010 00010010  ..
00000684: 00000010 00011100  ..
00000686: 00000010 00011100  ..
00000688: 00000010 00010010  ..
0000068a: 00000010 00011111  ..
0000068c: 00000010 00011010  ..
0000068e: 00000010 00010100  ..
00000690: 00000010 00100001  .!
00000692: 00000010 00010111  ..
00000694: 00000010 00010110  ..
00000696: 00000010 00100001  .!
00000698: 00000010 00010101  ..
0000069a: 00000010 00011000  ..
0000069c: 00000010 00011111  ..
0000069e: 00000010 00000010  ..
000006a0: 00011001 00000010  ..
000006a2: 00011011 00000010  ..
000006a4: 00001111 00000010  ..

Now the problem is, I don't understand how to put these two binary numbers together. I should get a decimal in a range of 0 - 1023. What bit operations I need to perform to convert this into a normal human readable number? Thanks!

\$\endgroup\$
  • \$\begingroup\$ Normally you'd create a DINT (double-int, 16-bit) and sum = ADCH * 256 + ADCL. \$\endgroup\$ – Transistor Jul 23 '16 at 19:13
  • 2
    \$\begingroup\$ You state: "I'm reading a sensor value and passing it to TX...". How are your "passing" this variable value to TX, and what is "TX"? Do you mean you are using printf? TX is the UART? I don't see where this is happening in the code snippet you are showing us. Please edit your question to include this information. \$\endgroup\$ – FiddyOhm Jul 23 '16 at 19:18
  • \$\begingroup\$ What kind of MCU are you using? And which development tools? \$\endgroup\$ – Lorenzo Donati supports Monica Jul 23 '16 at 19:35
  • \$\begingroup\$ @FiddyOhm I'm asking question purely about binary conversion, not serial communication. The code is just there to demonstrate what registers I'm reading. \$\endgroup\$ – K666 Jul 23 '16 at 20:38
  • 1
    \$\begingroup\$ K666, you are not giving us enough information. If you are reading an A-D converter, please tell us how many bits of resolution it has. Also, what processor are you using and is the ADC integral to the processor, or is it an external unit? If the latter please give at least a part number, perhaps a data sheet. It looks like you may be getting your MS & LS mixed up. This can happen in certain A/D's if you do not read the registers in correct order or timing. \$\endgroup\$ – FiddyOhm Jul 23 '16 at 21:40
0
\$\begingroup\$

Typically, an "int" is 16 bits, except when it is 32 bits. An 8-bit value would be a "char", or possibly a "short". It depends on your compiler. In any case, the most efficient way to combine the two would be:

ADCresult = (ADCH<<8) + ADCL;

A good optimizing compiler might interpret (ADCH * 256) as multiplying by a power of two, but I doubt your compiler does. A multiply on an 8-bit MCU is typically expensive, while a shift is fast and cheap.

I notice that you have a sync problem. It starts out with ADCL in the low byte, and then they get out of sync, and ADCH is in the low byte. 17 readings later, they get back in sync.

\$\endgroup\$
  • \$\begingroup\$ thanks for the reply. I tried the (ADCH<<8) + ADCL but got different results on my computers serial port, still not sure why. About the out of sync, I was moving the light around the photoresistor, that's why the readings differ. \$\endgroup\$ – K666 Jul 23 '16 at 20:05
  • \$\begingroup\$ But it appears more than that. If you have a 10-bit ADC, then the high byte can never be greater than 00000011. Whenever you see a value greater than that, it would have to be the low byte. \$\endgroup\$ – Mark Jul 23 '16 at 20:07
  • \$\begingroup\$ I'm sorry, I don't fully understand what you mean.. I noticed strange behavior at some distances when it jumps to 22.132 for example for a second. Does that mean my F_CPU is off? \$\endgroup\$ – K666 Jul 23 '16 at 20:08
  • \$\begingroup\$ Look at the table in your original post. The first column is an address, and the next two are your data. The 00000010 value is clearly the high-byte, ADCH. It starts out in the third column, switches to the second column, and then back to the third column. \$\endgroup\$ – Mark Jul 23 '16 at 20:56
0
\$\begingroup\$

Turns out, the number isn't an unsigned short after all, but two separate values, one indicating the value before and one after the comma. I was able to convert each of the numbers to integer and put them together as string

3.248
3.250
3.249
3.249
3.249
3.250
3.249
3.249
3.249
3.233
1.213
1.171
1.215
1.232
1.223
3.212
2.219
3.220
3.219
1.217
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.