• AVR Freaks

AnsweredHot!How to send packets using uart

Page: 12 > Showing page 1 of 2
Author
parkcoding
Starting Member
  • Total Posts : 54
  • Reward points : 0
  • Joined: 2019/03/13 16:17:10
  • Location: 0
  • Status: offline
2019/06/24 19:26:11 (permalink)
0

How to send packets using uart

Hi,
 
I'm trying to make code what send packets using uart in PIC18F87J60
 
 In other words,
 
By sending packets between the two boards, I try to control the 2 LEDS and transfer the adc value.
 
A board(tx)    ------------------    B board(rx)
put RB0         ------------------    LED D0 ON
put RB1         ------------------    LED D1 ON
swing RA0 ADC ----------------    receive ADC value
 
 
I have studied uart and adc, but I don't know how to approach packet transmission, or protocol.
 
If you have a good example or code to study, I want you to help me.
 
thanks!
 
#1
parkcoding
Starting Member
  • Total Posts : 54
  • Reward points : 0
  • Joined: 2019/03/13 16:17:10
  • Location: 0
  • Status: offline
Re: How to send packets using uart 2019/06/24 19:38:02 (permalink)
0
here are my adc / uart code.
 
I think, should I add packet code..?
 
haha
 
thanks!
 
 
#include <xc.h> //header

#include <stdbool.h> //logic data type
#include <stdint.h> //Integer data type
#include <stdio.h> //standard I/O
 
#pragma config DEBUG = OFF //Debug off
#pragma config XINST = OFF //Extended Instruction off
#pragma config WDT = OFF //Watchdog Timer off
#pragma config FOSC = HS //oscillator
 
#define _XTAL_FREQ 25000000 //crystal oscillation period
#define Baud_rate 9600 //Baudrate : Transmit bits per second
#define ADC_10BIT //ADC 10bit Indication
#define ADC_VOLT //ADC_VOLT Indication
#define ADC_HEX //ADC_HEX Indication
 
unsigned int adc_value_A = 0; //adc_value1 Initilaize
unsigned int adc_value_F = 0; //adc_value2 Initilaize

void Initial_PORT(void) //Port Initialize Function
{
    TRISAbits.TRISA0 = 1; //set up TRISA as Input
    PORTAbits.RA0 = 1; //set up RA0 as analog Input
    TRISGbits.RG3 = 0; //RA0 LED OUT

    TRISCbits.RC7 = 1; //Transmmit
    TRISCbits.RC6 = 0; //Receive
}
 
void Initial_UART(void) //Uart Initialize Function
{
    TXSTA1bits.TX9 = 0; //9Bit Transmit Enable bit
    TXSTA1bits.TXEN = 1; //Transmit Enable bit
    TXSTA1bits.SYNC = 0; //EUSARTx Mode select bit
    TXSTA1bits.BRGH = 1; //High Baud Rate Select bit

    RCSTA1bits.SPEN = 1; //Serial Port Enable bit
    RCSTA1bits.RX9 = 0; //9Bit Receive Enable bit
    RCSTA1bits.CREN = 1; //Continuous Erceive Enable bit

    BAUDCON1bits.BRG16 = 0; //16Bit Baud Rate Resister Enable bit

    SPBRG = 0xA2; //25MHz/(16*9600) - 1 = 162
}
 
void Initial_Timer(void)
{
//TIMER2 setting for RA ADC
    CCPR4L = 5;
    CCP4CON = 0x0C; //10bit duty cycle and PWM mode ON
    PR2 = 249;
    TMR2 = 35535;
    T2CON = 0x06;
}

void Initial_Interrupts(void) //Interrupt Initialize Function
{
    RCONbits.IPEN = 1; //Interrupt Priority enable
    INTCONbits.GIE = 0; //Global Interrupt enable
     INTCONbits.PEIE = 1; //Peripheral Interrupt enable
    PIE1bits.RCIE = 1; //RX enable
    PIE1bits.TX1IE = 1; //TX enable

    PIR1bits.ADIF = 0; //A/D unable
    PIE1bits.ADIE = 1; //A/D enable
}

void Initial_ADC() //A/D Initialize Function
{
    ADCON2 = 0xB4;
    ADCON1 = 0x07;
    ADCON0bits.ADON = 1;
}
 
void interrupt ISR(void)
{
    if(PIR1bits.TMR2IF == 1)
    {
        PIR1bits.TMR2IF = 0;
     }
    if(PIR1bits.ADIF == 1)
    {
       PIR1bits.ADIF = 0;
    }
}
 
void putch(char txData) //TX Function
{
    TXREG1 = txData; //save txData in TXREG1
    while(!TXSTA1bits.TRMT); //wait TRMT is TRUE/FALSE
    }
      char getch(void) //RX Function
    {
    while(!RC1IF); //RC1IF TRUE/FALSE
    return RCREG1; //return RCREG1
}
 
unsigned int adc_read(unsigned int AN_channel) //adc_read_RA0
{
    unsigned int adc_buf;
    ADCON0bits.CHS = AN_channel;
    ADCON0bits.GO = 1;
    while(ADCON0bits.GODONE);
    adc_buf= (unsigned int)(ADRESH << 8) + ADRESL; //right adjusted


    return adc_buf; //return adc_buf_A;
}
 
void main(void) //Main Function
{
    Initial_PORT(); //Run Initial_PORT
    Initial_UART(); //Run Initial_UART
    Initial_Interrupts(); //Run Initial Interrupts
    Initial_ADC(); //Run Initial_ADC_RF1
    Initial_Timer(); //Run Initial_Timer
 
    OSCCON = 0xF2;
    RCON = 0x80; //setting for interrupt priority set : IPEN

    while(1)
    {
      adc_value_A = adc_read(0); //adc_read_RA0() injected '0'
      CCPR4L = adc_value_A/4; // value from adc_value
      printf("ADC_Value_RA0 = %d\r\n", CCPR4L); // adc_value_A
    }
}
 
post edited by parkcoding - 2019/06/24 19:41:19
#2
ric
Super Member
  • Total Posts : 22758
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: How to send packets using uart 2019/06/24 20:04:14 (permalink)
+2 (2)
Do yourself a favor and change
void putch(char txData) //TX Function
{
    TXREG1 = txData; //save txData in TXREG1
    while(!TXSTA1bits.TRMT); //wait TRMT is TRUE/FALSE
    }

to
void putch(char txData) //TX Function
{
    while(!PIR1.TX1IF); //wait until TXREG1 is free
    TXREG1 = txData; //save txData in TXREG1
    }

so you are not wasting all your time waiting for the transfer to finish.
 
One common way to send packets is to use a unique character to mark the start and end of each packet.
A common choice is
SOH (0x01) for start of packet, and
EOT (0x04) for end of packet
 
Another way is just to send lines of text, terminated with <CR><LF>
 
 
post edited by ric - 2019/06/24 20:05:56

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#3
parkcoding
Starting Member
  • Total Posts : 54
  • Reward points : 0
  • Joined: 2019/03/13 16:17:10
  • Location: 0
  • Status: offline
Re: How to send packets using uart 2019/06/24 21:00:17 (permalink)
0
Instead of using the start and end packet, does it have any ways to solve this using the length of the data packet?
 
1. start
2. data  - LED 1 
            - LED 2
            - ADC value
3. length
4. checksum
 
.... 
#4
ric
Super Member
  • Total Posts : 22758
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: How to send packets using uart 2019/06/24 21:04:56 (permalink)
+2 (2)
You can do whatever you want, but how will the receiver know WHICH is the length byte if you put it AFTER the data?
It would make more sense to put the length byte straight after the start byte.
If your length is fixed, then you don't need to send it at all.
 
post edited by ric - 2019/06/24 21:06:27

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#5
parkcoding
Starting Member
  • Total Posts : 54
  • Reward points : 0
  • Joined: 2019/03/13 16:17:10
  • Location: 0
  • Status: offline
Re: How to send packets using uart 2019/06/24 21:12:07 (permalink)
0
I'd like to send 2 LED and ADC values using UART,
 
 
but I'm having trouble because there are no similar examples.

I don't know how to send an UART packet using the length of the data.
 
How do I set the data length or checksums in PIC18F?

Do you have an example or a similar type of code?
 
thanks! ric!
 
p.s I would set length 5
post edited by parkcoding - 2019/06/24 21:18:51
#6
pcbbc
Super Member
  • Total Posts : 1104
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: How to send packets using uart 2019/06/24 23:56:40 (permalink) ☄ Helpfulby parkcoding 2019/06/25 00:36:41
+2 (2)
parkcoding
How do I set the data length or checksums in PIC18F?

Write them to TXREG1, just like you do any other data.


I would set length 5

If your packets are fixed length, it is not necessary, and somewhat pointless, to send a fixed length.

One possible solution...

checksum=0; //initialise checksum
putch(0x01); //start frame
putch(0x05); //hardcoded “length”
//write your 5 characters of data here using putch!
putch(checksum); //however you are calculating your checksum while sending data
//would make sense to include checksum code in a special “putch” routine
putch(0x04); //optional end frame


Edit: Please learn how to put [​code]code tags[​/code] around your program code when posting to make your source code readable.
post edited by pcbbc - 2019/06/25 00:02:21
#7
ric
Super Member
  • Total Posts : 22758
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: How to send packets using uart 2019/06/24 23:59:46 (permalink)
+2 (2)
I suspect parkcoding is expecting the PIC to do some of this work for them.
Once they realise that they have to write all the code themself, then they will actually think about how to do it productively.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#8
pcbbc
Super Member
  • Total Posts : 1104
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: How to send packets using uart 2019/06/25 00:04:34 (permalink)
+2 (2)
ric
I suspect parkcoding is expecting the PIC to do some of this work for them.Once they realise that they have to write all the code themself, then they will actually think about how to do it productively. 

PIC = us
some = all
think about how = not be able to
#9
parkcoding
Starting Member
  • Total Posts : 54
  • Reward points : 0
  • Joined: 2019/03/13 16:17:10
  • Location: 0
  • Status: offline
Re: How to send packets using uart 2019/06/25 00:34:07 (permalink)
0
wow, Mr.pcbbc!
 
thanks!
 
I'm trying it in a different way now.
 
                      start    cmd   length  data  data  data   data   data   data   data   data  checksum
int Darr[12] = {0xA0, 0xB1, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3}; //PORTD packet
int Earr[12] = {0xA0, 0xB1, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3}; //PORTE packet
                         start   cmd    length  data  data   checksum
int ADCarr[6] = {0xA0, 0xAD, 0x03, 0x~~, 0x~~, 0x~~ }; //ADC packet
 
and
 
for(int i = 0 ; i < 12 ; i ++)
{
   putch(Darr);
   putch(Earr);
   for(int j = 0 ;  j < 6 ; j ++)
   {
     putch(ADCarr[j]);
    }
}
 
I have some question.
 
first, how do I write those values(ADCarr data, checksum) when they are variable?
second, can this effectively transmit the packet value via UART?
 
thanks!.
 
I'm trying hard.
 
Thank you all for your help.
post edited by parkcoding - 2019/06/25 00:38:21
#10
pcbbc
Super Member
  • Total Posts : 1104
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: How to send packets using uart 2019/06/25 02:32:14 (permalink) ☼ Best Answerby parkcoding 2019/06/25 19:18:58
+3 (3)
Please learn to put [​code]code tags[​/code] around your program code when posting.  People will get tired of helping you very quickly if you cannot follow this very basic rule of forum etiquette.
 
Your loop to send your data packet is broken.  Presumably you want to send Darr and then Earr and then ADCarr packets?
 
Something like this...
//                  start cmd   len   data  data  data  data  data  data  data  data  cs
uint8_t Darr[12] = {0xA0, 0xB1, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3}; //PORTD packet
uint8_t Earr[12] = {0xA0, 0xB1, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3}; //PORTE packet
uint8_t ADCarr[6] = {0xA0, 0xAD, 0x03, 0x~~, 0x~~, 0x~~ }; //ADC packet

void send_packet(uint8_t* packet)
{
    uint8_t len = packet[2] + 3;
    uint8_t i;
    for (i = 0; i < len; i++)
    {
        putch((char)packet[i]);
    }
}
 
 
 
//And then to send your data packets...
send_packet(Darr);
send_packet(Earr);
send_packet(ADCarr);
 

 
Storing the start cmd and length bytes in the array is probably not the best way of doing it.  You will also need to calcualte your CRC in advance when you could more easily calculate it as you send each byte out.  You will have to iterate over the data packet anyway to calcualte the checksum anyway - might as well combine it in the sending loop.  Why have you "decided" that your checksum is always 0xA3?
 
Your arrays are very wasteful because they use int type (2 bytes) for storing only single byte data.  I have replaced with uint8_t type.
post edited by pcbbc - 2019/06/25 02:34:42
#11
parkcoding
Starting Member
  • Total Posts : 54
  • Reward points : 0
  • Joined: 2019/03/13 16:17:10
  • Location: 0
  • Status: offline
Re: How to send packets using uart 2019/06/25 17:02:48 (permalink)
0
thanks! Mr.pcbbc!
Thank you for your advice.
It's not easy to add a code tag because I still don't have a good understanding of this. X(
I'll try hard to add detailed notes when I ask you to learn like this.
 
You said array wasn't the best way,
(I'm sure you're right, but I don't know much about this yet.
I think it was best for me to come up with an array
Can you let me know if there's any other way....? thanks!)
but what I'm trying to implement is, when I'm sending packets,
I'm trying to transmit PORTD and PORTE value and the ADC value,
taking into account (cmd length data), not the end bit.
 
I've been thinking about this all day,
I think the most accurate answer is to make two functions.
 
I mean,
Darr and Earr have different cmd values,
so I need to create a function to output by receiving cmd value as parameters
and ADC and the rest of the array have different length and data values (Darr, Earr / ADCarr)
so this is also thought to be a function to receive two parameters and output them.
Is it my approach correct?
 
 
                           // start   cmd    len  data    data    data  data   data   data  data    data   cs
uint8_t Darr[12] = {0xA0, 0xB1, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3}; //PORTD packet
uint8_t Earr[12] = {0xA0, 0xC2, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3}; //PORTE packet
uint8_t ADCarr[6] = {0xA0, 0xAD, 0x03, 0x~~, 0x~~, 0x~~ }; //ADC packet
 
(It's my mistake to write about cmd in Earr. I'm sorry....)
 
 p.s Thank you for always teaching and helping me.
      I keep studying about checksum.....
post edited by parkcoding - 2019/06/25 17:07:05
#12
ric
Super Member
  • Total Posts : 22758
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: How to send packets using uart 2019/06/25 17:32:53 (permalink)
+2 (2)
parkcoding
It's not easy to add a code tag because I still don't have a good understanding of this. X(

It is easy. Just type this into your post, on a line before your block of code
[code]
and this on a line after your block of code
[/code]
post edited by ric - 2019/06/25 17:34:13

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#13
pcbbc
Super Member
  • Total Posts : 1104
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: How to send packets using uart 2019/06/25 18:47:04 (permalink) ☄ Helpfulby parkcoding 2019/06/25 19:19:12
+2 (2)
I posted another way in post 7. That is still roughly the way I would code this.

Difficult to help without knowing what data you want to put in the PORTD and PORTE messages.
For example, why are you sending 8 bytes? Are these just one byte for each the 8 pins of each port?
If they are just digital ON/OFF values (one per byte) you might as well send the port value directly in a single byte and make your messages shorter and quicker to transmit.

Rather than describing what you want and asking the best way to code it, instead try writing some code yourself, try to debug it, and then post if you cannot understand why it is not working. You will learn more that way.
#14
ric
Super Member
  • Total Posts : 22758
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: How to send packets using uart 2019/06/25 18:54:10 (permalink) ☄ Helpfulby parkcoding 2019/06/25 19:19:07
+2 (2)
Also be careful sending raw binary values, as they could look like your START character...
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#15
parkcoding
Starting Member
  • Total Posts : 54
  • Reward points : 0
  • Joined: 2019/03/13 16:17:10
  • Location: 0
  • Status: offline
Re: How to send packets using uart 2019/06/25 19:22:11 (permalink)
0
Now I'm studying about checksum.
Is there a link to study data packets?
Thanks to Mr.pcbbc and ric.
I'm very motivated to study this part.
I'll give it a try.
#16
davea
Senior Member
  • Total Posts : 123
  • Reward points : 0
  • Joined: 2016/01/28 13:12:13
  • Location: 0
  • Status: offline
Re: How to send packets using uart 2019/06/25 20:41:22 (permalink)
+1 (1)
here is the standard CRC 16
 
void CRC_16(void) { 
        uint8_t cnt = 16; // # of bytes to CRC
        uint16_t  crc = -1;
        uint8_t ptr = 0;
        uint8_t i;
        while(cnt!=0){
           cnt--;
           crc=crc^(uint16_t)CRC_buff[ptr++];
           for(i=0;i<8;i++){
              if((crc&0x0001)!=0){
                 crc = (crc>>1)^0x8408;
            } else {crc = crc>>1;
        }
     }
   }
     CRC_nsC=~crc;  // NOTE: high and low byte's need swapping
     uint16_t Swap;
     Swap = CRC_nsC<<8;
     CRC_val = Swap + (CRC_nsC>>8);
}

#17
parkcoding
Starting Member
  • Total Posts : 54
  • Reward points : 0
  • Joined: 2019/03/13 16:17:10
  • Location: 0
  • Status: offline
Re: How to send packets using uart 2019/06/25 21:59:17 (permalink)
0
thanks, Mr.davea!
Before I see your comment,
I wrote Checksum code like this,
Is it wrong?
 
 
/* If a value other than '0' is entered as a return value, it is ignored,
and only recognized as normal data when a value of '0' is entered. */
 
unsigned int Checksum(unsigned char *ptr, unsigned int len)
{
        unsigned char csum;

        csum = 0xFF;
        for(len = 0 ; len > 0 ; len--)
       {
            csum += *ptr++;
        }
    return ~csum;
}
#18
pcbbc
Super Member
  • Total Posts : 1104
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: How to send packets using uart 2019/06/26 00:26:28 (permalink) ☄ Helpfulby parkcoding 2019/06/26 16:33:20
+3 (3)
For the third (and final time) please use [​code]code tags[/​code] around your code. In which case the thus enclosed code in your post will appear correctly formatted:
code tags


Where did you get that from? That code is not going to work, or not do what you think it should. You have reset the len parameter to zero inside the for loop. The for loop will never do anything as len starts at zero and immediately fails the continuation condition len > 0, so it immediately stops with no work being done. As a result the checksum returned is always zero.

Rather than calculating the checksum up front, you can very easily calculate it as you send each byte. You have to iterate over the bytes anyway to send them. This removes the need to have to construct the entire message in a buffer before you send it.

Also the function could return unsigned char, or better still uint8_t. And len probably doesn’t need to be int type either. Are you ever going to be sending more than 256 bytes in a packet? Almost certainly not.

Learning to size and type your variables correctly is very important on a 8 bit microcontroller. On any sizeable project you will find you run out of resources (RAM) very quickly if you do not.
#19
skruegel1
Starting Member
  • Total Posts : 73
  • Reward points : 0
  • Joined: 2017/02/04 03:32:13
  • Location: 0
  • Status: offline
Re: How to send packets using uart 2019/06/26 12:32:41 (permalink)
+1 (1)
Both checksums cannot be the same in post #11.
#20
Page: 12 > Showing page 1 of 2
Jump to:
© 2019 APG vNext Commercial Version 4.5