Sending messae with SERIAL port

Hi,

please can anyone help me with the serial port comunication? I dont have any experience with serial port comunication, so please try to understand my probably silly questions :) what i need:

I want to send message consisting of the letter (char) and number. For example something like this : K1002

Is it possible? How to do it? I have device that is controled by serial port and there is predefined some messages, that control the unit. But the controling messages consists always of some letter and numbers...

What is the syntax of this type of message?

Thank you very much!!!!!!! :)

Hi Jura, perhaps something like this will help you get started:

void sendMessage(char letter, int number){ Serial.print(letter); Serial.print(number,DEC); //Serial.println(number,DEC); // use this instead of the above if a carriage return/ line feed is expected by your device }

example: sendMessage('K', 1002);

A read of the the Arduino Serial documention will explain what these commands do

Thanks a lot! ;) Works perfectly. Now I undertsand a little bit more. :)

But now I have other problem that I cannot solve now (its hard way...)ú:

I want to send by serial port the number that alway consist of 4 numbers, even it means zero. Like 0000. But I want to increase/decrease this number (by button) and always I need to be there all 4 numbers.

What happens now is, that it prints simple numbers without zeros before it - like this: 0, 2, 33, 455, 1024 but I need to print this: 0000, 0002, 0033, 0455, 1024

(its just example of the numbers...)

Is it possible to do it? HOW? :-X Thank you very much!!!! ;)

here is a modified version that pads leading zeros

void sendMessage(char letter, int number){
  // this version pads leading zeros so all numbers are four digits
  // number must be less than or equal to 9999
 Serial.print(letter);

 int padding = 4;
 int temp = number;
   
 while( temp /= 10 )
      padding--;
 while(  padding--)
    Serial.print("0");
 Serial.print(number,DEC);
//Serial.println(number,DEC); // use this instead of the above if a carriage return/ line feed is expected by your device
}

It's not tested so may need a little work But i hope it give you an idea of how to solve yr problem

Great :D! Iwill check it. Thanks

Nice padding algorithm, mem. A small fix, since we never pad more than 3 zeros:

int padding = 3;

(Note: this scheme breaks if you send numbers greater than 9999.)

Mikal

mikalhart: yes, I´ve found it also. with 4 there were always 5 digits.

Yes it works good! thanks a lot!

But anyway I dont understand the structure of this program well, please can you describe me little bit how it works?

exactly this part:

int padding = 3; int temp = number;

while( temp /= 10 ) padding--; while( padding--) Serial.print("0");

Thanks a lot. I am newbie with programming...

I love mem's code, but it is just a little subtle. Let me see if I can annotate.

/* We're going to assume we want to pad with three zeros to start with */ int padding = 3;

/* Make a copy of the number, because we are going to dissect it. */ int temp = number;

/* In C, a while loop continues as long as the expression in parentheses is non-zero. The expression "temp /= 10" divides temp by 10. The value of the expression is temp after the division. So for example, if temp started out as 89, the value of the expression would first be 8 and then 0. So for a 2-digit number, the loop executes once. For a 3-digit number, it executes twice. For a 1-digit number, not at all. Each time through it reduces the number of pad characters (padding--) */ while( temp /= 10 ) padding--;

/* This loop prints a leading zero once for each "padding". Each time through "padding" is reduced by one and the loop terminates once padding reaches 0. So if padding is 3, three 0's will be printed. */ while( padding--) Serial.print("0");

Hope that helps.

Mikal

Great! Its subtle but very effective! Nice code ;)

Hi JURA, glad its helped.

Thanks Mikal for adding the annotation.

Oh yes it helped! Thank you ;)

Now I have another special problem :P

Is it possible to send and array by serial port???

something like this:

int zones[] = (zone1, zone2, zone3......,zone 10); // the array of all zones values - the zone values are read on 10 digital input pins

void setup() {

Serial1.begin(9600); etc... declare all input pins void loop () {

zone1 = digitalRead (zone1Pin); // here I expect, that if the value on pin will be HIGH, the value zone1 will be 1, else 0 / is it right? zone2 = digitalRead (zone1Pin); etc......

Serial1.print (zones); // now I expect that this will send the whole array if numbers - something like (1,0,0,0,1,0,1,0,1,1) - is it right?

delay (25); // here I expect, that the values will be hold and sending about 25ms untill new measure loop / is it right? }


Is it possible somehow? There is not the array not written as a possible data for serial.print in reference :-/

What I want is to send the packet of all 10 values at once - each digit might represent the state of the input pin. Maybe very simple, but I am still beginner :P

Thanks a lot :)

I think the best way to send the array would be again to write your own helper function as in:

void WriteSerialIntArray(int *array, int count)
{
  while (count--)
    Serial.println(*array++);
}

Then in the loop body:

...
  WriteSerialIntArray(zones, 10);
...

ADDENDUM: Or, to get the (0,1,1,0,0,1,1,0,1,0) string you hope for:

void WriteSerialIntArray(int *array, int count)
{
  Serial.print("(");
  while (count--)
  {
    Serial.print(*array++);
    if (count) 
      Serial.print(",");
  }
  Serial.println(")");
}

Mikal

Thanks! I ll try. Whats not clear for me is the * before array. What does it mean? Thank you.

In C, you cannot pass an array to a function. The best you can do is pass a pointer (memory address). "int *array" means that array is a pointer to an integer, i.e. the first element of the array. Later, the "Serial.println(*array++)" means "print the integer that 'array' is currently pointing to and then point it to the next one in the array". This concept usually takes some time to understand, so don't be disillusioned if you don't immediately get it.

Cheers,

Mikal

so the * prints the array value as int? Whats the problem of this code, that it prints each digits on a new line. So I need Serial.print (*array++); // but here must be somehow condition to do it untill the 9th number in array / HOW? but the last 10th digit must be: Serial.println(*array[9]);

Becouse I want to send the whole number at once like 0111000010

Thanks very much!

void WriteSerialIntArray(int *array, int count)
{
  while (count--)
    Serial.print(*array++);
  Serial.println();
}

Thanks :) Its nice.

Now I have little problem with Serial.read().

How does it work? It just return the first byte of the information - not everything???? :P

I would like to do two things with Serial reading:

1.) just read the incoming serial data (sending with 9600baud) and identicaly reprint them (in speed 115200baud). Is it possible?

I thought its just very simple like:

Serial.print (Serial1.read() );

  • but will this do also new lines? -is it even possible?

2.) I want to read incoming messages and when condition is true than set the digital pin HIGH.

Something like:

if ( Serial1.read() == Z09) { digitalWrite(pin9, HIGH); }

but now I am not sure if it can work like this. :-?

Please help me. Thank you very much :)

just read the incoming serial data (sending with 9600baud) and identicaly reprint them (in speed 115200baud).

The UART in the Arduino can't operate at split speeds. You would have to make one serial port using the software serial port extensions.

if ( Serial1.read() == Z09)

It depends what Z09 is. If it is a variable that contains an ASCII byte you want to trigger on then yes it will work. However, if it is an ASCII string then no it won't. You need to gather your string using multiple serial reads and then do a string compare.

Z09 or to be more exatact Z1 is a message sended by this code (from other board).

Serial.print ("Z"); Serial.println (1,DEC);

so it is not string( I hope - I am not common with string...).

Will this work?

AD 1.] So the reading and reprinting is not possible in differnet speeds? The setup is like this:

arduino 1 is sending serial messgaes atd speed 9600 baud. This speed is chosen because the distance to second arduino is about 40m and its better to use slower speed.

arduino2 read this messages (if it possible it can read at 115200 / the Serial.begin (115200) will be set) and than indeticla z reprint this messages in speed 115200 to serial output.

The reason is simple - the driven unit need 115200badu speed, but the distance from the first arduino is cca 40m and I am afraid of some errors in hiugh speed....

Is it possible to do it somehow ?

Thanks a lot

Will this work?

No. You only have one byte in the read and you have sent two bytes. You have to convert them into a string or pack them into a single variable. (you can get two bytes in an int) like this:-
pack = byte1 | (byte2 <<8);
Then you can compare the ints.

So the reading and reprinting is not possible in differnet speeds

If you have something coming in when you are at a different speed sending out you will miss it or get some corruption. The simplest way is to use a soft serial port.

Anyway, I can’t see how the fast unit needs to be fast as it can only send data at the speed (data rate) it receives from the slow sender. So there is no advantage in sending it quickly the number of bytes per second is limited to how fast they come in.