Skip to main content
edited tags
Link
VE7JRO
  • 2.5k
  • 19
  • 28
  • 31
Tweeted twitter.com/StackArduino/status/808607425720946689
Source Link
JVDM92
  • 63
  • 1
  • 6

Arduino to arduino serial communication without a library

So I'm trying to send an array from one arduino to another through serial communication, without using the software serial library. The arduinos are wired rx->tx, tx->rx and ground to ground. I have a struct which holds the array of data and 2 test characters. The entire struct is then sent 1 char at a time. The receiver then receives 1 char at a time, re-calculates the test chars and if the xor of the sent and calculated tests chars is 1 then we assume an error exists and turn on a red LED. If no error exists then we turn on a green LED. I'm having some issues with my code however. It never sends any data to the 2nd arduino. Can anyone see any reason why?

Sender:

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

#define F_CPU 16000000L
#define BAUD_RATE 9600
#define MYUBRR (F_CPU / 16 / BAUD_RATE) - 1
#define END_OF_MESSAGE 47
#define END_OF_SECTION 35
#define START_OF_MESSAGE 2
#define _BV(bit) (1<<(bit))

struct packet{
    /*Packet to send a part of the message. */
    char *data;
    char vert_check;
    char horz_check;    
};

void serialInit()
{
    UBRR0H = (char) (MYUBRR>>8);
    UBRR0L = (char) MYUBRR;
    UCSR0C = (3 << UCSZ00);
    UCSR0B = (1 << RXEN0) | (1 << TXEN0);
}

unsigned char serialCheckTx()
{
    return(UCSR0A & _BV(UDRE0));
}

void serial_send(unsigned char DataOut)
{
    while(serialCheckTx() == 0){;}
    UDR0 = DataOut;
}

int isOddParity(unsigned char myChar) {
    int parity = 0;
    for (myChar &= ~0x80;  myChar != 0;  myChar >>= 1) {
        parity ^= (myChar & 1);   // Toggle parity on each '1' bit.
    }
    return parity;
}

int main(void)
{
    serialInit();
    char hozcheck, vertcheck;
    /* Add message to array below to send 
     * Initialised to toets.
     */
    char *s = {'T', 'o', 'e', 't', 's'};
    struct packet sendpacket;
    sendpacket.data = s;
    hozcheck = 0;
    for(int i=0; i<strlen(s); i++){
        hozcheck += s[i];
    }
    vertcheck = (isOddParity(s[0]) + '0');

    sendpacket.horz_check = hozcheck;
    sendpacket.vert_check = vertcheck;

    serial_send(START_OF_MESSAGE);
    serial_send(sendpacket.horz_check);
    serial_send(END_OF_SECTION);
    serial_send(sendpacket.vert_check);
    serial_send(END_OF_SECTION);
    for(int j=0; j<strlen(s); j++){
        serial_send(s[j]);
    }
    serial_send(END_OF_MESSAGE);
}

Receiver:

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

#define END_OF_MESSAGE 47
#define START_OF_MESSAGE 2
#define F_CPU 20000000L
#define BAUD_RATE 9600
#define MYUBRR (F_CPU / 16 / BAUD_RATE) - 1
#define _BV(bit) (1<<(bit))
#define START_OF_MESSAGE 2
#define END_OF_MESSAGE 47
#define END_OF_SECTION 35

struct packet{
    char *data;
    char vert_check;
    char horz_check;    
};

void serialInit()
{
    UBRR0H = (char) (MYUBRR>>8);
    UBRR0L = (unsigned) MYUBRR;
    UCSR0C = (3 << UCSZ00);
    UCSR0B = (1 << RXEN0) | (1 << TXEN0);
}

unsigned char serialCheckRx()
{
    return(UCSR0A & _BV(RXC0));
}

unsigned char serialReceive()
{
    while (serialCheckRx() == 0){;}
    return UDR0;
}

void *array_concat(char *a, int an, char b){
    int s = sizeof(char);
    char *p = malloc(s * (an + 1));
    memcpy(p, a, an*s);
    memcpy(p + an*s, b, s);
    return p;
}

int isOddParity(unsigned char myChar) {
    int parity = 0;

    for (myChar &= ~0x80;  myChar != 0;  myChar >>= 1) {
        parity ^= (myChar & 1);   // Toggle parity on each '1' bit.
    }
    return parity;
}

int main(void)
{
    DDRB = 0b111111;
    serialInit();
    char tmp = 0, recvert = 0, rechoz = 0, *s, testhoz, testvert;
    int testbit = 0;
    /*to rebuild our packages*/
    struct packet packet1;
wait:
    while((tmp = serialReceive()) != 2){
        goto wait;
    }

    while((tmp = serialReceive()) != 35){
        /*Should be a single char for horizontal*/
        rechoz = tmp;
    }
    while((tmp = serialReceive()) != 35){
        /*Should be a single char for "vert" parity*/
        recvert = tmp;
    }
    while((tmp = serialReceive()) != 47){
        /*While input is not end of message grow s*/
        s = array_concat(s, strlen(s), tmp);
    }

    packet1.data = s;
    packet1.vert_check = recvert;
    packet1.horz_check = rechoz;
    testhoz = 0;
    for(int i=0; i<strlen(s); i++){
        testhoz += s[i];
    }
    testvert = ((isOddParity(s[0])) + '0');
    if((packet1.vert_check ^ testvert) == 1)
        testbit = 1;
    if((packet1.horz_check ^ testhoz) == 1)
        testbit = 1;
    if(testbit == 1){
        /*RED LED*/
        PORTB = 0b100000;
    } else {
        PORTB = 0b010000;
    }
    free(s);
}