I've been programming my atmega 328p to automate my coffe machine. The timer is set using the bluetooth module HC-06, or by a set of configuration buttons that I'm gonna develop yet (the full code is on my github: https://github.com/andrehrema/Cafeteira).
I've faced some problems with serial communication, so right now I'm trying to establish a communication between the microcontroller and my pc.
To send data I'm using putty and python with serial package, both with baudrate equal to 9600.
The data is stored in the queue buffer_rx_bth, and each queue's node is of type BT_node (BT = bluetooth).
The character '|' symbolyzes the end of the string and It allows the ATmega response.
Below is the piece of code used in UART communication:
#include<avr/io.h>
#include<avr/interrupt.h>
typedef struct node_BT BT_node;
typedef struct queue_BT_data BT_data;
struct node_BT{
char byte;
BT_node *next;
};
struct queue_BT_data{
BT_node *hd;
int index;
BT_node *tl;
};
volatile BT_data * add_inst(volatile BT_data *buffer_bth, char command){
BT_node *inst = malloc(sizeof(BT_node));
inst->byte = command;
if (buffer_bth->hd == 0){
buffer_bth->hd = inst;
buffer_bth->hd->next = 0;
buffer_bth->tl = buffer_bth->hd;
return buffer_bth;
}
else{
inst->next = buffer_bth->tl->next;
buffer_bth->tl->next = inst;
buffer_bth->tl = inst;
}
return buffer_bth;
}
volatile BT_data * remove_inst(volatile BT_data *buffer_bth){
while(buffer_bth->hd->byte != '|'){
BT_node *delete = buffer_bth->hd;
buffer_bth->hd=buffer_bth->hd->next;
free(delete);
}
BT_node *delete = buffer_bth->hd;
if(buffer_bth->hd == buffer_bth->tl)
buffer_bth->tl = buffer_bth->tl->next;
buffer_bth->hd=buffer_bth->hd->next;
free(delete);
return buffer_bth;
}
volatile BT_data *buffer_rx_bth;
ISR(USART_RX_vect){ //interruption handler
UCSR0B &= ~(1<<TXCIE0); // transmition interruption disabled
char result = UDR0;
buffer_rx_bth = add_inst(buffer_rx_bth, result);
UCSR0B |= (1<<TXCIE0); // transmition interruption enabled
}
int main (void){
buffer_rx_bth = malloc(sizeof(BT_data));
buffer_rx_bth->hd=0; // queue head
buffer_rx_bth->tl=0; // tail head
BT_node * pointer = 0;
while(1){
sei()
set_sleep_mode(SLEEP_MODE_IDLE);
sleep_mode();
if (buffer_rx_bth->tl->byte == '|'){ //verify if it is the final character
if (pointer == 0){
PORTB ^= 4;
pointer = buffer_rx_bth->hd;
}
if ( (UCSR0A & (1<<UDRE0)) && pointer!=0){
UDR0 = pointer->byte;
if(pointer->byte == '|'){
remove_inst(buffer_rx_bth);
ponteiro = 0;
}
else
pointer = pointer->next;
}
}
}
When data is sent byte per byte, as shown below, the microcontroller send an equal response, as I expected.
import serial
uc = serial.Serial("/dev/ttyACM0",9600)
uc.write('A')
uc.write('B')
uc.write('C')
uc.write('|')
uc.stop()
response: ABC|
However, when more than one byte is sent, with the method write, the answer is completely random.
import serial
uc = serial.Serial("/dev/ttyACM0",9600)
uc.write("ABC|")
response: random string
Why is this happening? How can I solve it?
pointer = pointer->prox;
do? \$\endgroup\$