Question

Arduino project using the 'Arduino language' (C++ wrapper) -

I have an 8-char array which gives 24Hr clock in the form {'H','H',':','M','M',':','S,'S'} and I need to convert this to BCD. I thought I understood the idea well enough but I get an unexpected result.

As a base example I'd like to convert {'1','2'} to BCD - the theory is on the left and my code result is on the right of the image below. I suspect the issue is with buff[0] being a 'number char', I tried atoi(buff[0]) but this still failed (I had the same result):

How may I do this correctly? My baseline code is:

char buff[8] = {'1','2',':','3','4',':','5','5'};    
uint8_t HourTens  = buff[0] && 0b11110000; // && 0xF0, should be 1
uint8_t HourUnits = buff[1] && 0b00001111; // && 0x0F, should be 2
uint8_t HourBCD   = HourTens + HourUnits;

Serial.println( buff );
Serial.print("'"); Serial.print( buff[0] ); Serial.print( "', HourTens:  " );   Serial.println( HourTens );
Serial.print("'"); Serial.print( buff[1] ); Serial.print( "', HourUnits: " ); Serial.println( HourUnits );
Serial.print( "HourBCD: " ); Serial.println( HourBCD );
Serial.println("***");

enter image description here

Was it helpful?

Solution

The problem with your code is that the data in the buff is ASCII characters, not the individual binary digits. You need to subtract '0' from each digit before performing a conversion to BCD:

uint8_t HourTens  = (buff[0] - '0'); // && 0xF0, will be 1

Note that each element takes its own byte, so you don't need to mask anything.

uint8_t HourBCD = ((buff[0] - '0') << 4) | (buff[1] - '0');

Also note that since the digits are from zero to nine, all you need to do is to shift the upper digit by four to get a valid BCD representation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top