What is the effect of ' \n'? - c

I have caused an effect which I really don't understand:
char buffer[6];
UINT i = adc_getADCValue(6);
int j = 0;
for ( j = 0 ;j <4;j++){
buffer[3-j] = (UINT) ((i%10UL)+'0');
i /=10;
}
buffer[4] = '\n';
buffer[5] = '\0';
localprint(buffer); // print messages on terminal using COM port
it works
my question is why is the output by using \n oblique? I was hopping simulating theprintf function . I'm using STM32f103xx uC.

\nis next line (Line Feed - LF) and \r is carriage return (CR) on old printers.
Your terminal is configured to behave "à la" windows, where next line is CR+LF. Hence sending only LF goes to next line, but not to the begin.
Unix usually uses only LF.
Either change the configuration of your terminal or change the code to use \n\r

It's all question of backwards compatibility. In Windows you need to use \r\n instead of simply n, which is the UNIX way of doing the same thing.
See this link as well as #Bruce's post for more information.

Related

Enabling Newline or Carriage return

I am reading some robotic code and i came across something like Newline and Carriage. What are those two things? I could not find any useful usage related the code itself.
Here is the code
// !! make sure you have enabled Newline or Carriage return
#define _mode 0 // (0) used for calibration and testing, (1) uses serial as input
void handle_serial() {
//: reads and stores the serial data
int i = 0; float buff[3] = {0, 0, 0};
String s_buff = "";
while (Serial.available()) {
char c = Serial.read();
if (c == 13 || c == 32 || c == '\n') {
buff[i] = s_buff.toFloat();
s_buff = "";
i++;
} else
s_buff += c;
}
if (_mode == 0)
commands_exe(buff[0], buff[1], buff[2]);
else if (_mode == 1)
if (state == 4) {
_direction = {buff[0], buff[1]};
turn = buff[2];
}
}
Newline and Carriage. What are those two things?
That's two control characters. Usually expressed as the escape sequence "\n" (new line) and "\r" (carriage return)
https://en.wikipedia.org/wiki/Carriage_return
https://en.wikipedia.org/wiki/Newline
Both have historic reasons. Carriage return moved the printhead back to the beginning of the line. New line moved to the next line.
This is still used in computers to move the cursor around or to make linebreaks when reading text files.
The idea of it in this code is to read bytes until newline, space or carriage return are received. then the bytes received till then is converted to a float.
But as the comments suggest this implementation is bad for many reasons. mainly it is very error prone.
For example you risk to exceeed the boudnaries of your buffer if you don't receive space, newline or carriage return in time.
It is also often used to terminate serial commands so the computer knows when he received a full command, which at the same time allows to display them nicely in a terminal. It is up to the sender to make sure the correct data is sent which in gerneral is a very bad idea.
The only thing you can learn from this snippet is how not do to do it.

Reading serial port faster

I have a computer software that sends RGB color codes to Arduino using USB. It works fine when they are sent slowly but when tens of them are sent every second it freaks out. What I think happens is that the Arduino serial buffer fills out so quickly that the processor can't handle it the way I'm reading it.
#define INPUT_SIZE 11
void loop() {
if(Serial.available()) {
char input[INPUT_SIZE + 1];
byte size = Serial.readBytes(input, INPUT_SIZE);
input[size] = 0;
int channelNumber = 0;
char* channel = strtok(input, " ");
while(channel != 0) {
color[channelNumber] = atoi(channel);
channel = strtok(0, " ");
channelNumber++;
}
setColor(color);
}
}
For example the computer might send 255 0 123 where the numbers are separated by space. This works fine when the sending interval is slow enough or the buffer is always filled with only one color code, for example 255 255 255 which is 11 bytes (INPUT_SIZE). However if a color code is not 11 bytes long and a second code is sent immediately, the code still reads 11 bytes from the serial buffer and starts combining the colors and messes them up. How do I avoid this but keep it as efficient as possible?
It is not a matter of reading the serial port faster, it is a matter of not reading a fixed block of 11 characters when the input data has variable length.
You are telling it to read until 11 characters are received or the timeout occurs, but if the first group is fewer than 11 characters, and a second group follows immediately there will be no timeout, and you will partially read the second group. You seem to understand that, so I am not sure how you conclude that "reading faster" will help.
Using your existing data encoding of ASCII decimal space delimited triplets, one solution would be to read the input one character at a time until the entire triplet were read, however you could more simply use the Arduino ReadBytesUntil() function:
#define INPUT_SIZE 3
void loop()
{
if (Serial.available())
{
char rgb_str[3][INPUT_SIZE+1] = {{0},{0},{0}};
Serial.readBytesUntil( " ", rgb_str[0], INPUT_SIZE );
Serial.readBytesUntil( " ", rgb_str[1], INPUT_SIZE );
Serial.readBytesUntil( " ", rgb_str[2], INPUT_SIZE );
for( int channelNumber = 0; channelNumber < 3; channelNumber++)
{
color[channelNumber] = atoi(channel);
}
setColor(color);
}
}
Note that this solution does not require the somewhat heavyweight strtok() processing since the Stream class has done the delimiting work for you.
However there is a simpler and even more efficient solution. In your solution you are sending ASCII decimal strings then requiring the Arduino to spend CPU cycles needlessly extracting the fields and converting to integer values, when you could simply send the byte values directly - leaving if necessary the vastly more powerful PC to do any necessary processing to pack the data thus. Then the code might be simply:
void loop()
{
if( Serial.available() )
{
for( int channelNumber = 0; channelNumber < 3; channelNumber++)
{
color[channelNumber] = Serial.Read() ;
}
setColor(color);
}
}
Note that I have not tested any of above code, and the Arduino documentation is lacking in some cases with respect to descriptions of return values for example. You may need to tweak the code somewhat.
Neither of the above solve the synchronisation problem - i.e. when the colour values are streaming, how do you know which is the start of an RGB triplet? You have to rely on getting the first field value and maintaining count and sync thereafter - which is fine until perhaps the Arduino is started after data stream starts, or is reset, or the PC process is terminated and restarted asynchronously. However that was a problem too with your original implementation, so perhaps a problem to be dealt with elsewhere.
First of all, I agree with #Thomas Padron-McCarthy. Sending character string instead of a byte array(11 bytes instead of 3 bytes, and the parsing process) is wouldsimply be waste of resources. On the other hand, the approach you should follow depends on your sender:
Is it periodic or not
Is is fixed size or not
If it's periodic you can check in the time period of the messages. If not, you need to check the messages before the buffer is full.
If you think printable encoding is not suitable for you somehow; In any case i would add an checksum to the message. Let's say you have fixed size message structure:
typedef struct MyMessage
{
// unsigned char id; // id of a message maybe?
unsigned char colors[3]; // or unsigned char r,g,b; //maybe
unsigned char checksum; // more than one byte could be a more powerful checksum
};
unsigned char calcCheckSum(struct MyMessage msg)
{
//...
}
unsigned int validateCheckSum(struct MyMessage msg)
{
//...
if(valid)
return 1;
else
return 0;
}
Now, you should check every 4 byte (the size of MyMessage) in a sliding window fashion if it is valid or not:
void findMessages( )
{
struct MyMessage* msg;
byte size = Serial.readBytes(input, INPUT_SIZE);
byte msgSize = sizeof(struct MyMessage);
for(int i = 0; i+msgSize <= size; i++)
{
msg = (struct MyMessage*) input[i];
if(validateCheckSum(msg))
{// found a message
processMessage(msg);
}
else
{
//discard this byte, it's a part of a corrupted msg (you are too late to process this one maybe)
}
}
}
If It's not a fixed size, it gets complicated. But i'm guessing you don't need to hear that for this case.
EDIT (2)
I've striked out this edit upon comments.
One last thing, i would use a circular buffer. First add the received bytes into the buffer, then check the bytes in that buffer.
EDIT (3)
I gave thought on comments. I see the point of printable encoded messages. I guess my problem is working in a military company. We don't have printable encoded "fire" arguments here :) There are a lot of messages come and go all the time and decoding/encoding printable encoded messages would be waste of time. Also we use hardwares which usually has very small messages with bitfields. I accept that it could be more easy to examine/understand a printable message.
Hope it helps,
Gokhan.
If faster is really what you want....this is little far fetched.
The fastest way I can think of to meet your needs and provide synchronization is by sending a byte for each color and changing the parity bit in a defined way assuming you can read the parity and bytes value of the character with wrong parity.
You will have to deal with the changing parity and most of the characters will not be human readable, but it's gotta be one of the fastest ways to send three bytes of data.

Can't open a file with unicode chars in the file name using CLion

I'm having trouble opening a file that has Unicode characters in its name.
I created a file on my desktop with just a couple lines of text.
c:\users\james\desktop\你好世界.txt
EDIT: I'm using CLion. CLion is passing parameters in unicode.
When I put that string into the Windows run dialog, it finds the file and opens it.
Something interesting, though, is that I get double L'\\' L'\\' in the folder name from my call to CommandLineToArgvW:
L"c:\\\\users\\\\james\\\\desktop\\\\你好世界.txt"
So I wrote a small routine to copy the filename to another wchar_t * and strip the slashes. Still doesn't work.
errno == 2 and f == NULL.
size_t filename_max_len = wcslen(filename);
//strip double slashes
wchar_t proper_filename[MAX_PATH + 1];
wchar_t previous = L'\0';
size_t proper_filename_location = 0;
for(int x = 0; x < filename_max_len; ++x)
{
if(previous == L'\\' && filename[x] == L'\\')
continue;
previous = filename[x];
proper_filename[proper_filename_location++] = filename[x];
}
proper_filename[proper_filename_location] = L'\0';
//Read in binary mode to prevent the C system from screwing with line endings
FILE *f = _wfopen(proper_filename, L"rb");
int le = errno;
if (f == NULL)
{
perror(strerror(le));
if(le == ERROR_FILE_NOT_FOUND)
{
return DUST_ERR_FILE_NOT_FOUND;
}
else {
return DUST_ERR_COULD_NOT_OPEN_FILE;
}
}
I have figured out the issue. My hunch was correct. CLion appears to be providing unicode as input to the program. Using the Windows run dialog and passing it as a parameter to my program, I was able to open and process the file without an issue.
My first guess is that 228, 189, 160 represents the first character of your filename encoded as a UTF-8 byte sequence since it looks like such a sequence to me. E4 BD A0 (228, 189, 160) decodes as U+4F60, which is indeed the Unicode code point corresponding to the first character.
I modified the output section of main in my sample program here to print each argument as a hex-encoded byte sequence. I copied and pasted your path as an argument to the program, and the Han characters are encoded in UTF-8 as:
E4 BD A0
E5 A5 BD
E4 B8 96
E7 95 8C
Your comment mentions slightly different numbers (specifically 8211/U+2013, 8226/U+2022, and 338/U+0152). Looking at code pages Windows 1250 and Windows 1252, bytes 0x96, 0x95, and 0x8C in both code pages correspond exactly to U+2013, U+2022, and U+0152 respectively. I'm guessing your original program goes wrong somewhere when it encounters Unicode input (you are using GetCommandLineW and passing that to CommandLineToArgvW, right?)
Here's a screenshot of my output that I've edited to highlight the relevant character sequences (the ¥ glyphs are meant to be \ glyphs, but I use code page 932 for cmd.exe):

Send a backslash using C socket for iso8583 message

I am building a POS application verifone (C-language) which should communicate with m2m switch from Morocco but I'm stuck when sending initialization message which should have a backslash like this (08\00) but when sending this I'm having 08\5c00.
It converts backslash by its value in hex(5c). The tool I'm using is socket workbench to simulate the server.
How can I send a backslash without being converted into \5c?
It needs to be done in C Language.
EDIT
This is the data I want to send to the server with the header but when trying to print \00 I get \5C00
sprintf(data,"%s%s%s%s%s%s%s%s%s%s%s%s%s","\x30\x60\x60\x20\x15\x35\x35","\x08",‌"\\00","\x0x00","\x01\x30\x30\x30\x30\xC0\x30\x30\x30\x30","\x97","\\00","\x30\x30"‌,"\x00\x00\x01\x00","\x02",idTerminal,idCommercant,"\x20\x20\x20\xA4\xBC");
If I'm understanding correctly, the first part of your example:
sprintf(data,"%s%s",
"\x30\x60\x60\x20\x15\x35\x35",
"\x08");
is doing exactly what you want. The problem is that on the next %s, you are using "\\00" and you want to server to receive ASCII \00 (which would be 0x5c, 0x30, 0x30), but instead the server reports that it is receiving ASCII \5c00 (which would be 0x5c, 0x,35, 0x43, 0x30, 0x30).
I agree with Klas Lindbäck in that it sounds like the VeriFone terminal is doing the correct thing, but the server is displaying it wrong. There are 2 things I would consider doing in order to troubleshoot this in order to prove that this is correct (and you can do just one or the other or you can do both together).
First: You can use LOG_PRINTF (or print to paper or the screen if you prefer) to print the values of each byte just before you send it off. Below is a quick-and-dirty function I wrote to do just that when I was troubleshooting a similar sort of problem once. Note that I only cared about the beginning of the string (as is the case with you, it seems) so I don't print the end if I run out of buffer space.
void LogDump(unsigned char* input, int expectedLength)
{
#ifdef LOGSYS_FLAG
char buffer[100];
int idx, bfdx;
memset(buffer, 0, sizeof(buffer));
bfdx = 0;
for (idx = 0; idx < expectedLength && bfdx < sizeof(buffer); idx++)
{
//if it is a printable character, print as is
if (input[idx] > 31 && input[idx] < 127)
{
buffer[bfdx++] = (char) input[idx];
continue;
}
//if we are almost out of buffer space, show that we are truncating
// the results with a ~ character and break. Note we are leaving 5 bytes
// because we expand non-printable characters like "<121>"
if (bfdx + 5 > sizeof(buffer))
{
buffer[bfdx++] = '~';
break;
}
//if we make it here, then we have a non-printable character, so we'll show
// the value inside of "<>" to visually denote it is a numeric representation
sprintf(&buffer[bfdx], "<%d>", (int) input[idx]);
//advance bfdx to the next 0 in buffer. It will be at least 3...
bfdx += 3;
//... but for 2 and 3 digit numbers, it will be more.
while (buffer[bfdx] > 0)
bfdx++;
}
//I like to surround my LOG_PRINTF statements with short waits because if there
// is a crash in the program directly after this call, the LOG_PRINTF will not
// finish writing to the serial port and that can make it look like this LOG_PRINTF
// never executed which can make it look like the problem is elsewhere
SVC_WAIT(5);
LOG_PRINTF(("%s", buffer));
SVC_WAIT(5);
#endif
}
Second: try assigning each position in your char array an explicit value. If you already used my LOG_PRINTF suggestion above and found it was not sending what you thought it should be, this would be one way to fix it so that it DOES send EXACTLY what you want. This method is a bit more tedious, but since you are spelling it out each value, anyway, it shouldn't be too much more overhead:
data[0] = 0x30;
//actually, I'd probably use either the decimal value: data[0] = 48;
// or I'd use the ASCII value: data[0] = '0';
// depending on what this data actually represents, either of those is
// likely to be more clear to whomever has to read the code later.
// However, that's your call to make.
data[1] = 0x60;
data[2] = 0x60;
data[3] = 0x20;
data[4] = 0x15;
data[5] = 0x35;
data[6] = 0x35;
data[7] = 0x08;
data[8] = 0x5C; // This is the '\'
data[9] = 0x48; // The first '0'
data[10]= 0x48; // The second '0'
data[11]= 0;
//for starters, you may want to stop here and see what you get on the other side
After you have proven to yourself that it IS or IS NOT the VeriFone code causing the problem, you will know whether you need to focus on the terminal or on the server side.

What could cause a Labwindows/CVI C program to hate the number 2573?

Using Windows
So I'm reading from a binary file a list of unsigned int data values. The file contains a number of datasets listed sequentially. Here's the function to read a single dataset from a char* pointing to the start of it:
function read_dataset(char* stream, t_dataset *dataset){
//...some init, including setting dataset->size;
for(i=0;i<dataset->size;i++){
dataset->samples[i] = *((unsigned int *) stream);
stream += sizeof(unsigned int);
}
//...
}
Where read_dataset in such a context as this:
//...
char buff[10000];
t_dataset* dataset = malloc( sizeof( *dataset) );
unsigned long offset = 0;
for(i=0;i<number_of_datasets; i++){
fseek(fd_in, offset, SEEK_SET);
if( (n = fread(buff, sizeof(char), sizeof(*dataset), fd_in)) != sizeof(*dataset) ){
break;
}
read_dataset(buff, *dataset);
// Do something with dataset here. It's screwed up before this, I checked.
offset += profileSize;
}
//...
Everything goes swimmingly until my loop reads the number 2573. All of a sudden it starts spitting out random and huge numbers.
For example, what should be
...
1831
2229
2406
2637
2609
2573
2523
2247
...
becomes
...
1831
2229
2406
2637
2609
0xDB00000A
0xC7000009
0xB2000008
...
If you think those hex numbers look suspicious, you're right. Turns out the hex values for the values that were changed are really familiar:
2573 -> 0xA0D
2523 -> 0x9DB
2247 -> 0x8C7
So apparently this number 2573 causes my stream pointer to gain a byte. This remains until the next dataset is loaded and parsed, and god forbid it contain a number 2573. I have checked a number of spots where this happens, and each one I've checked began on 2573.
I admit I'm not so talented in the world of C. What could cause this is completely and entirely opaque to me.
You don't specify how you obtained the bytes in memory (pointed to by stream), nor what platform you're running on, but I wouldn't be surprised to find your on Windows, and you used the C stdio library call fopen(filename "r"); Try using fopen(filename, "rb");. On Windows (and MS-DOS), fopen() translates MS-DOS line endings "\r\n" (hex 0x0D 0x0A) in the file to Unix style "\n", unless you append "b" to the file mode to indicate binary.
A couple of irrelevant points.
sizeof(*dataset) doesn't do what you think it does.
There is no need to use seek on every read
I don't understand how you are calling a function that only takes one parameter but you are giving it two (or at least I don't understand why your compiler doesn't object)

Resources