Byte to Char

Hey Guys,
I'm attempting to take bytes that contain time and date and make them into a string for the purpose of naming a file on an openlog. My clock produces: month, dayOfMonth, hour, and minute in bytes. I tried char() but had no joy. Lots of ascii spaces.

Suppose it was October 28th at 14:12. I would want my file name to be "10281412." Problem is, I have no idea how to make:

byte minute 12;

turn into:

char minute[2] = "12";

I've seen in some examples people using springf(). I liked the one instance where I saw it, but I can't figure out how it works exactly.

Any guidance much appreciated!

  • Hunter

I included some (marginal) code below to help you understand what I'm trying to do.

#include "string.h"

// bytes each of the components
byte minute;
byte hour;
byte dayOfMonth;
byte month;

// strings for each of the four components
char Cmonth[2];
char CdayOfmonth[2];
char Chour[2];
char Cminute[2];

char TimeDate[8];  // will contain all of the four components in a string

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

  // Data as it arrives off the clock   
  minute = 12;
  hour = 14;
  dayOfMonth = 28;
  month = 10; 

    //**** need something here that will turn bytes into integers
  
 // I have no idea if this is legal, or how I'd go about putting all of my CHAR's into one long string. 
  TimeDate[8] = {month, dayOfMonth, hour, minute};
  
  Serial.print(TimeDate);
  
    //**** I want to see: "10281412";  That's month dayOfMonth hour minute.
     
   }

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

does

byte minute =12;
byte hour=14;
byte dayOfMonth=28;
byte month=10;
char TimeDate[9];
sprintf (TimeDate, "%02u%02u%02u%02u",month,dayOfMonth,hour,minute);

work ?

"%02u" means unsigned 2digits with leading zero.

  • You need space for a trailing 0 as end of string indicator, so TimeDate has to be at least 9 chars wide .
  • You don't need string.h
  • If it's just to create a file name, you can do that in one shot:
      sprintf (TimeDate, "%02u%02u%02u%02u.log",month,dayOfMonth,hour,minute); should produce "10281412.log"

Michael,
That pretty much worked. Thanks!

Your explanation of sprintf combined with what I saw in an openlog example were the magic trick. The line that ultimately worked was:

sprintf(buff, "new L%02d%02d%02d.txt\r", month, dayOfMonth, fileNumber);

I didn't mention any of it in the first post, but I needed "new" to initiate the new file. I replaced hour and minute with fileNumber to keep the name under the size 8.3 limit. Then I added \r, and I have no idea what it means or why it's necessary, but it works.

Thanks a ton for your good explanation and quick response.

  • Hunter

I didn't mention any of it in the first post, but I needed "new" to initiate the new file. I replaced hour and minute with fileNumber to keep the name under the size 8.3 limit. Then I added \r, and I have no idea what it means or why it's necessary, but it works.

What, exactly, are you doing with the resulting buffer? The SD library does not expect that "new " in there, nor will it operate correctly with it there.

The \r is a new line, often used to indicate the end of a command, which implies that the array you are populating defines some kind of command.

I'm sending it straight to the OpenLog. I got it from this example:
https://github.com/sparkfun/OpenLog/blob/master/OpenLog_CommandTest/OpenLog_CommandTest.ino
Lines 76-90.

Here's my implementation:

  sprintf(buff, "new L%02d%02d%02d.txt\r", month, dayOfMonth, fileNumber);
  Serial.print(buff); //\r in string + regular print works with older v2.5 Openlogs


  delay(500);
  
  sprintf(buff, "append L%02d%02d%02d.txt\r", month, dayOfMonth, fileNumber);
  Serial.print(buff);
 
  delay(500);

I wish I could get Serial.read to work so I could see that the OpenLog is alive before I start sending data (as Nate does in the example). It stopped working last night (hence no while loops). I don't know what failed, I suspect hardware.

  • Hunter

int minute 12;

Char minute[2];

//into char minute[2] = "12";

minute[0] =(minute/10 + 48);
minute[1] =(minute%10 + 48);

that's OK

The sprintf() function is very powerful and brings a lot to the table. Alas, it eats a lot while it's there. In the code below:

void setup()
{
  byte minute = 12;
  byte hour = 14;
  byte dayOfMonth = 28;
  byte month = 10;
  char temp[5];
  char TimeDate[12];
  
  Serial.begin(9600);

//  sprintf (TimeDate, "%02u/%02u %02u:%02u", month, dayOfMonth, hour, minute);

  strcpy(TimeDate, itoa(month, temp, 10));
  strcat(TimeDate,"/");
  strcat(TimeDate, itoa(dayOfMonth, temp, 10));
  strcat(TimeDate," ");
  strcat(TimeDate, itoa( hour, temp, 10));
  strcat(TimeDate,":");
  strcat(TimeDate, itoa( minute, temp, 10));
  
  Serial.print(TimeDate);
}

void loop()
{


}

the (now commented-out) version with sprintf() uses 3290 bytes of code space. The alternative code which uses a family of str*() calls, and looks larger, uses only 2056 bytes. You can see a number of str*() and mem*() functions here:

and they are worth adding to your programming toolkit.

anddmt:
int minute 12;

Char minute[2];

//into char minute[2] = "12";

minute[0] =(minute/10 + 48);
minute[1] =(minute%10 + 48);

that's OK

I doubt that that is OK. You create a non-null terminated character string.

Anyway, this thread is nearly 4 years old.

Hi,
I have a similar issue. I was writing some code in the online IDE and it compiled fine. When I downloaded it and tried to compile it with the Windows version of the IDE it throws an error that it can't convert byte to char. What I was doing is basically trying to copy byte array to char array. Those bytes are actually ASCII characters so I wouldn't need any conversion.

It looks something like that:

void CopyCharArrayPart(char CharArrayIn[], char CharArrayOut[], unsigned int Start, unsigned int Length)
{
    unsigned int cnt; // Counter variable
    for (cnt = 0; cnt <= Length; ++cnt)
    {
        CharArrayOut[cnt] = CharArrayIn[cnt + Start];
    };
}

byte RDBuf[18];
char Name[4];
Serial.readBytes(RDBuf,18);
CopyCharArrayPart(RDBuf,Name,6,4);

If I try to cast it like this:

CopyCharArrayPart((char)RDBuf,Name,6,4);

It tells me that it loses precision. I guess it's trying to put a termination character at the end, which I don't need.

Any idea why this compiles online and not on Windows and how to fix it without adding a tone of code? I use IDE 1.6.6.

It tells me that it loses precision. I guess it's trying to put a termination character at the end, which I don't need.

No, it is because a char on some systems, like the Arduino is a signed type, with a range of values from -128 to 127. Byte is an unsigned type, with a range of 0 to 255. Trying to store a value like 200, which is perfectly valid in a byte, in a char could result in a loss of precision.

Any idea why this compiles online and not on Windows and how to fix it without adding a tone of code?

Create another function that takes a byte array as the first argument.

Didn't have that kind of char problem with C compilers for PIC so it was unexpected. I just changed the input of the function to byte array since that what I will use it for and save memory. Thanks for the info.

Today create this function, and is working for me.

char* byte9ToChars(byte b) {

 char* r = "0";
 r[0] += b;
 return r;
}