Go Down

Topic: how to convert byte HEX to int (Read 530 times) previous topic - next topic

rymanvw

I am using a library the return a "byte HEX" value via I2C from a DS3231 real time clock chip then I am storing the value in an "int registerValue" but the value is in HEX.

When I display the value on the LCD it prints the HEX value not the int value.

Code: [Select]
int registerValue = RTC.readRTC(ALM1hrReg);


I have tried using    int(RTC.readRTC(ALM1hrReg));     but it does not work. I have also tried atoi(); and that doesn't work either.

I can get the value to display properly as an int if I put the HEX in my Serial.println(registerValue, HEX); function but the value is still a HEX stored in the variable and I do many operations with it later on.

How can I convert the value before storing it do I don't need the HEX in my Serial.print(); function?

Thanks.

AWOL

All values are in binary.

How you print them defines how you see them

rymanvw

This is the output on the serial monitor.


ALM1 = 23:15
ALM2 = 34:19


Below is my test code. ALM1 prints the correct integer values I entered in the setAlarm(); function

ALM2 prints the HEX representation of the values I entered in the setAlarm(); function.

How can I make the output be the same as what I input without using the "HEX" input of the Serial.print() function?

Code: [Select]
#include <DS3232RTC.h>        //http://github.com/JChristensen/DS3232RTC
#include <Wire.h>             //http://arduino.cc/en/Reference/Wire

//Alarm 1 hour/minute registers
int ALM1hrReg = ALM1_MATCH_HOURS+1;
int ALM1minReg = ALM1_MATCH_HOURS;

//Alarm 2 hour/minute registers
int ALM2hrReg = 0x0C;
int ALM2minReg = 0x0B;



void setup(void)
{
    Serial.begin(9600);

    // Set alarms in DS3231 Alarm registers
    RTC.setAlarm(ALM1_MATCH_HOURS, 0, 15, 23, 0);
    RTC.setAlarm(ALM2_MATCH_HOURS, 13, 22, 0);
   
    //clear the alarm flags
    RTC.alarm(ALARM_1);
    RTC.alarm(ALARM_2);

    // Read Alarm 1 registers
    int ALM1hrVal;
    int ALM1minVal;
    ALM1hrVal = RTC.readRTC(ALM1hrReg);
    ALM1minVal = RTC.readRTC(ALM1minReg);

    // Print Alarm 1 values via Serial
    Serial.print("ALM1 = ");
    Serial.print(ALM1hrVal, HEX);
    Serial.print(":");
    Serial.println(ALM1minVal, HEX);

    delay(100); // for some reason the compiler craps out without this delay

    // Read Alarm 1 registers
    int ALM2hrVal;
    int ALM2minVal;
    ALM2hrVal = RTC.readRTC(ALM2hrReg);
    ALM2minVal = RTC.readRTC(ALM2minReg);

    // Print Alarm 2 values via Serial
    Serial.print("ALM2 = ");
    Serial.print(ALM2hrVal);
    Serial.print(":");
    Serial.println(ALM2minVal);

    delay(1000);

}

void loop(void)
{
}

larryd

Serial.print(78, BIN) gives "1001110"
Serial.print(78, OCT) gives "116"
Serial.print(78, DEC) gives "78"
Serial.print(78, HEX) gives "4E"
Serial.println(1.23456, 0) gives "1"
Serial.println(1.23456, 2) gives "1.23"
Serial.println(1.23456, 4) gives "1.2346"


No technical PMs.
If you are asked a question, please respond with an answer.
If you are asked for more information, please supply it.
If you need clarification, ask for help.

david_2018

It appears that RTC.readRTC returns the number in binary coded decimal, not hexidecimal.
The first hex digit is the 10's digit, the second is the 1's, in decimal format, so to convert back to binary take the first hex digit, multiply by 10, and add the second hex digit.

I added this to your code, see if it works:

Code: [Select]
   // RTC.readRTC returns a byte in BCD (binary coded decimal)
    // convert from BCD to Binary
    ALM2hrVal = (ALM2hrVal / 16 * 10) + ALM2hrVal % 16;
    ALM2minVal = (ALM2minVal / 16 * 10) + ALM2minVal % 16;


Code: [Select]
#include <DS3232RTC.h>        //http://github.com/JChristensen/DS3232RTC
#include <Wire.h>             //http://arduino.cc/en/Reference/Wire

//Alarm 1 hour/minute registers
int ALM1hrReg = ALM1_MATCH_HOURS+1;
int ALM1minReg = ALM1_MATCH_HOURS;

//Alarm 2 hour/minute registers
int ALM2hrReg = 0x0C;
int ALM2minReg = 0x0B;



void setup(void)
{
    Serial.begin(9600);

    // Set alarms in DS3231 Alarm registers
    RTC.setAlarm(ALM1_MATCH_HOURS, 0, 15, 23, 0);
    RTC.setAlarm(ALM2_MATCH_HOURS, 13, 22, 0);
    
    //clear the alarm flags
    RTC.alarm(ALARM_1);
    RTC.alarm(ALARM_2);

    // Read Alarm 1 registers
    int ALM1hrVal;
    int ALM1minVal;
    ALM1hrVal = RTC.readRTC(ALM1hrReg);
    ALM1minVal = RTC.readRTC(ALM1minReg);

    // Print Alarm 1 values via Serial
    Serial.print("ALM1 = ");
    Serial.print(ALM1hrVal, HEX);
    Serial.print(":");
    Serial.println(ALM1minVal, HEX);

    delay(100); // for some reason the compiler craps out without this delay

    // Read Alarm 1 registers
    int ALM2hrVal;
    int ALM2minVal;
    ALM2hrVal = RTC.readRTC(ALM2hrReg);
    ALM2minVal = RTC.readRTC(ALM2minReg);
    
    // RTC.readRTC returns a byte in BCD (binary coded decimal)
    // convert from BCD to Binary
    ALM2hrVal = (ALM2hrVal / 16 * 10) + ALM2hrVal % 16;
    ALM2minVal = (ALM2minVal / 16 * 10) + ALM2minVal % 16;

    // Print Alarm 2 values via Serial
    Serial.print("ALM2 = ");
    Serial.print(ALM2hrVal);
    Serial.print(":");
    Serial.println(ALM2minVal);

    delay(1000);

}

void loop(void)
{
}



david_2018

Another method, without having to use the math equations, would be to do the math in the print statements, but you seemed to want to avoid complications in the print statements themselves. 

Code: [Select]

  Serial.print("ALM2 = ");
  Serial.print(ALM2hrVal/16);
  Serial.print(ALM2hrVal%16);
  Serial.print(":");
  Serial.print(ALM2minVal/16);
  Serial.println(ALM2minVal%16);



The BCD actually makes it a bit easier if you are working with something like a 7-segment display.

GolamMostafa

#6
Mar 25, 2019, 02:13 am Last Edit: Mar 25, 2019, 02:24 am by GolamMostafa
It appears that RTC.readRTC returns the number in binary coded decimal, not hexidecimal.
The first hex digit is the 10's digit, the second is the 1's, in decimal format, so to convert back to binary take the first hex digit, multiply by 10, and add the second hex digit.
Yes! The data sheets also say that the value of 'hour alarm' is in BCD format:
Code: [Select]

20H   10H       <---------1H---------->
bit-5  bit-4      bit-3  bit-2  bit-1  bit-0          decimal value
0       0           0       0       0       0               00
-------------------------------------------------------
0       0           1       0        0      1               09
0       1           0       0        0      0               10
-------------------------------------------------------
1       0           0       0        1      1               23


How to print the value in Serial Monitor (say 23)?

Code: [Select]
byte registerValue = RTC.readRTC(ALM1hrReg);  //registerValue = xx10 0011
Serial.print((registerValue & 0b00111111)>>4);          //shows: (00000010) 2

Serial.print((registerValue & 0b00001111));                //shows: (00000011) 3 ----> 23



rymanvw

I also figured out if I convert the returned data to a string with a HEX type, then convert it to an int that works as well.


Code: [Select]


int registerValue = String(RTC.readRTC(ALM2hrReg), HEX).toInt();



thanks for the other suggestions. I will try them out but they look a little more advanced/complicated than my shitty non-efficient multiple conversion method but it would be good to understand for the future!

THANKS!

Go Up