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);
}
char *s = { ... }bit. It wantedchar s[5] = { ... }instead. – Majenko Dec 12 '16 at 19:09sundefined, then allocate in your concat routine, and then assign that allocated tos. You then pass that back to concat, allocating again, copying the data, and leaving the old allocation in place. By the end of it you have allocated (and lost) loads of memory - that is if it even starts, since the first pointer you pass to copy memory from is complete junk. – Majenko Dec 12 '16 at 19:16char *s = "Toets";. Then you have a properly terminated string (the compiler adds a NULL byte at the end) that you can safely pass tostrlen(). – Edgar Bonet Dec 12 '16 at 21:09