USART MULTIPLE BYTE TRANSMISSION PROBLEM

Go To Last Post
16 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was trying to send multiple bytes by atmega328p. I used *x != '\0' to stop transmission but the whole ARRAY IS NOT SEND. another thing if I replace *x != '\0' by i<15 (run 15 times )  then whole array is send. can you please find error i have googled it but found no answer. i have attached both pics and code

thanks for helpblush

 

c code

#include <avr/io.h>
#include <string.h>

#define  is_bit_set(byte,bit) (byte & (1<<bit))
#define  is_bit_clr(byte,bit) (!(byte & (1<<bit)))

void txbyte(uint8_t *x)
{
    for(int i= 0 ;  *x != '\0' ; i++)
    {
        UDR0 = *x++;
        while(is_bit_clr(UCSR0A,UDRE0));
    }
}
int main(void)
{

    uint8_t y[15] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x13,0x00,0x00,0x00,0x00,0x05};
    //unsigned char y[15]={0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x13,0x00,0x00,0x00,0x00,0x05};
    UBRR0 = 12;
    UCSR0A &= ~(1<<U2X0);

    UCSR0B |= (1<<TXEN0) ;
    UCSR0C |= (1<<UCSZ00) | (1<<UCSZ01);
    //y={0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x13,0x00,0x00,0x00,0x00,0x05};
    txbyte(y);
    while (1)
    {
    }
}

 

Attachment(s): 

Last Edited: Fri. Jun 1, 2018 - 08:26 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please do not double-post. One is quite enough.

 

Jim

 

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ka7ehk wrote:

Please do not double-post. One is quite enough.

 

 

i just posted one

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hassan6432 wrote:
I was trying to send multiple bytes

So why did you call your function, "txbyte" ?

 

That name suggests that it sends just a single byte!

 

I used *x != '\0' to stop transmission but the whole ARRAY IS NOT SEND.

So how far does it get?

 

Note that your array has many zero bytes in it:

    uint8_t y[15] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x13,0x00,0x00,0x00,0x00,0x05};

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

txbyte is just a name I can change it. Yeah I have many 0x00 because I am interfacing atmega328p with r305(fingerprint sensor) and this is a command for verify password

u can see attachment 3.png (it ends on 0x01).

thanks for reply

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Other thread locked.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But the whole point of naming functions is that the name clearly indicates what the function does!

 

Otherwise, you might just as well call it Doris().

 

frown

 

Hassan6432 wrote:
u (sic) can see attachment 3.png (it ends on 0x01)

It would be a lot easier if you put the image in your post where we can actually see it - like this (see Tip #1):

 

and that is exactly what you'd expect if you stop transmitting when you find a zero!

  uint8_t y[15] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x13,0x00,0x00,0x00,0x00,0x05};

so your code is working perfectly correctly!

 

What did you expect to happen?

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Fri. Jun 1, 2018 - 10:21 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your send function needs a length parameter as you can’t use the C string convention of 0 being the end of string.
Eg:

void mabel(uint8_t *msg, uint8_t length)
{
while(length)
{
send(*msg++);
length—;
}
}

Last Edited: Fri. Jun 1, 2018 - 10:56 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks for giving suggestion it will really help me in future.

so I understand that in unit8_t data type 0x00 and '\0' (null) are same (Am I right). I think in char array (string) '\0' tells that array end I changed unit8_t to char and run the program it gives me the same result.

Can you suggest some way that I can send the whole array without knowing how much elements are in it so I do not need to use i<15 like statements? 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Edit: Deleted

Stefan Ernst

Last Edited: Fri. Jun 1, 2018 - 10:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Consider the problem - the values 0 to 255 are all valid values that you want to send, so using one of those values to determine the end of your message is not going to work. Therefore you need to determine the length.
Note that char and uint8_t are essentially the same.

Last Edited: Fri. Jun 1, 2018 - 10:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hassan6432 wrote:
so I understand that in unit8_t data type 0x00 and '\0' (null) are same (Am I right)

Correct.

 

I think in char array (string) '\0' tells that array end

Only if you write you code to treat it that way (or use pre-written code which treats it that way)

 

We had this only the other day - the 'C' language has no specific string type.

 

EDIT: Here: https://www.avrfreaks.net/commen...

 

 I changed unit8_t to char and run the program it gives me the same result.

 

Of course it does!  How do you think that would make any difference?

 

Zero is zero !

 

Can you suggest some way that I can send the whole array without knowing how much elements are in it

You would would need to have some sort of "marker" that can never be a real data value.

 

eg, you could make each array element 16 bits wide, and use the "spare" 8 bits in each element as a marker ...

 

 

 

EDIT

 

The other common approach is to use some sort of "escape sequence"

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Fri. Jun 1, 2018 - 10:56 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 Kartman said:

you need to determine the length

 but how can I find this length? I have to send several commands of different length so I don't want to write length manually. is there any way that it finds length automatically?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sizeof()

Eg: length =sizeof(y);

Sizeof computes the number of bytes for the given variable. It does this a compile time NOT run time.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

just to confirm if my array is this

uint8_t y[] = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x07,0x13,0x00,0x00,0x00,0x00,0x05};

sizeof(y) =15? and is it apply for all arrays (different data types) 

 

Another thing I want to ask is as I am interfacing atmega328p with r305 (fingerprint sensor) so some bytes and same for every command 

header = 0xEF01

module address=0xFFFFFFFF

password = 0x00000000 

so I can 

#define header  0xEF01

and then 

uint16_t x=header; in every command function

now, how can I send uint16_t and uint32_t as I can only send 1 byte at a time?

and as the last 2 bytes are checksum in this command it will be the sum of 0x01, 0x0017, and password(0x00000000) so how can we add them one is in uint8_t,uint16_t, and uint32_t?

thanks for help smiley

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Google sizeof() you’ll find all there is to know about it.
As for splitting up variables that are larger than a byte, this is a common question.
You have a number of choices.
The two popular ones are a union (Google that in relation to C)
And shifting.
To send a 32bit variable:
uint32_t varby;

Send(varby); //low 8 bits
Send(varby>>8); // next 8 bits
Send(varby>>16);
Send(varby>>24);

This assumes the function Send expects a uint8_t parameter.

To calculate the crc or checksum, i would normally have a fixed size array where i assemble the message. I can then call the checksum function to compute the checksum of that array and then append the checksum to that array. If you keep a count of the values you’ve stored in the array, then that is your length.
Alternately, you can call the checksum function for each byte you send and then send the checksum byte(s).

Last Edited: Sat. Jun 2, 2018 - 12:40 AM