Guru Meditation Error: Core 0 panic'ed (LoadProhibited),(Interrupt wdt timeout on CPU1) - interrupt

I was trying to record light intensity values for a Li-Fi project.
This is my code:
#include <soc/sens_reg.h>
#include <soc/sens_struct.h>
#include <driver/adc.h>
#include <SD.h>
#define ADC1_GPIO36_CHANNEL ADC1_CHANNEL_0
#include <adc_channel.h>
const char filename1[] = "/part1.dat";
const char filename2[] = "/part2.dat";
File file1, file2;
int local_adc1_read(int channel) {
uint16_t adc_value;
SENS.sar_meas_start1.sar1_en_pad = (1 << channel); // Only one channel is selected
while (SENS.sar_slave_addr1.meas_status != 0)
;
SENS.sar_meas_start1.meas1_start_sar = 0;
SENS.sar_meas_start1.meas1_start_sar = 1;
while (SENS.sar_meas_start1.meas1_done_sar == 0)
;
adc_value = SENS.sar_meas_start1.meas1_data_sar;
return adc_value;
}
#define ADC_SAMPLES_COUNT 1000
int16_t abuf[ADC_SAMPLES_COUNT];
int16_t abufPos = 0;
portMUX_TYPE DRAM_ATTR timerMux = portMUX_INITIALIZER_UNLOCKED;
TaskHandle_t complexHandlerTask;
hw_timer_t * adcTimer = NULL; // Our timer
void complexHandler(void *param) {
timerAlarmDisable(adcTimer);
timerDetachInterrupt(adcTimer);
timerEnd(adcTimer);
adcTimer = NULL;
file1 = SD.open(filename1, FILE_WRITE);
file2 = SD.open(filename2, FILE_WRITE);
file1.write((const byte*)abuf, abufPos);
file2.write((const byte*)abuf, abufPos);
file1.close();
file2.close();
}
int counter;
void IRAM_ATTR onTimer() {
portENTER_CRITICAL_ISR(&timerMux);
abuf[abufPos++] = local_adc1_read(ADC1_CHANNEL_0);
//abuf[abufPos++] = adc1_get_raw(ADC1_CHANNEL_0);
if (abufPos >= 8) {
if (abuf[abufPos-7] ==
abuf[abufPos-6] ==
abuf[abufPos-5] ==
abuf[abufPos-4] ==
abuf[abufPos-3] ==
abuf[abufPos-2] ==
abuf[abufPos-1] ==
abuf[abufPos])
{
// Notify adcTask that the buffer is full.
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
vTaskNotifyGiveFromISR(complexHandlerTask, &xHigherPriorityTaskWoken);
if (xHigherPriorityTaskWoken) {
portYIELD_FROM_ISR();
}
}
portEXIT_CRITICAL_ISR(&timerMux);
}
}
void setup() {
setCpuFrequencyMhz(240);
xTaskCreate(complexHandler, "Handler Task", 8192, NULL, 1, &complexHandlerTask);
adcTimer = timerBegin(3, 80, true); // 80 MHz / 80 = 1 MHz hardware clock for easy figuring
timerAttachInterrupt(adcTimer, &onTimer, true); // Attaches the handler function to the timer
timerAlarmWrite(adcTimer, 100, true); // Interrupts when counter == 45, i.e. 22.222 times a second
timerAlarmEnable(adcTimer);
Serial.begin(115200);
pinMode(2, OUTPUT);
//pinMode(36, INPUT);
if (!SD.begin())
Serial.println("SD begin failed");
while(!SD.begin()) {
Serial.print(".");
//delay(500);
SD.remove(filename1);
SD.remove(filename2);
}
}
void loop() {
}
I got this error:
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1100
load:0x40078000,len:10900
load:0x40080400,len:6388
entry 0x400806b4
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x400f095f PS : 0x00060030 A0 : 0x800d1019 A1 : 0x3ffb3f80
A2 : 0x00000000 A3 : 0x3ffb2080 A4 : 0x00000020 A5 : 0x80000020
A6 : 0x00000000 A7 : 0x00000000 A8 : 0x00000005 A9 : 0x00000020
A10 : 0x00000020 A11 : 0x3ffbc0d0 A12 : 0x80087259 A13 : 0x3ffbc0d0
A14 : 0x00000000 A15 : 0x00000000 SAR : 0x00000000 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
ELF file SHA256: 0000000000000000
Backtrace: 0x400f095f:0x3ffb3f80 0x400d1016:0x3ffb3fa0 0x40088269:0x3ffb3fe0
I tried decreasing the interrupt frequency, using a huge app (3 MB), increasing the CPU clock to 240 Hz, but nothing changed.
By outcommenting
vTaskNotifyGiveFromISR(complexHandlerTask, &xHigherPriorityTaskWoken);
and
xTaskCreate(complexHandler, "Handler Task", 8192, NULL, 1, &complexHandlerTask);
now the error is
Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1)
And some register dumps of core 1 and core 0. There isn't any change doing something in the loop.

Related

ESP32 Arduino: Guru Meditation Error: Core 1 panic'ed (StoreProhibited)

Sending data from (mesh network)smoke sensors to AWS. I am storing the node data using linked list.After passing data to AWS,i am try to de-allocate the memory and coming across following two errors in free().
#include <stdio.h>
#include<stdlib.h>
typedef struct Node
{
uint8_t node_data[15]; //stores node infomation
struct Node* next; //pointer to next node
}node;
node *head=NULL;
node*current=NULL;
static uint8_t k[15]; //this array keeps track of data received on UART port
static uint8_t node_count=0; //keeps the track of no. of nodes added to the system
void push_data(int []); /*this function pushes data present in array into
a node(memory allocated to node dynamically)*/
void delete_node(node*); //this function deletes the memory allocated to node
void pack_data(void); // send node data to aws
void loop()
{
if(Serial2.available()>0)
{
for( uint8_t i=0;i<15;i++)
{
k [i]= Serial2.read();
}
push_data(k);
}
delay(5000);
}
void push_data(uint8_t arr[])
{
if(head==NULL)
{
head=(node*)malloc(sizeof(node));
current=(node*)malloc(sizeof(node));
for(uint8_t i=0;i<15;i++)
{
head->node_data[i]=arr[i];
}
head->next=current;
node_count++;
return;
}
else
{
for(uint8_t i=0;i<15;i++)
{
current->node_data[i]=arr[i];
}
current->next=(struct Node*)malloc(sizeof(struct Node));
current=current->next;
current->next=NULL;
node_count++;
pack_data();
return;
}
}
void pack_data()
{
/*this function converts node data into data format
* and sends the data to aws.*/
/* Once the data is send to aws ,
the memory allocated to nodes is freed
*/
delete_node(head);
return;
}
void delete_node(node* n)
{
node* m=NULL;
while(n!=NULL)
{
m=n->next;
free(n);
n=NULL;
n = m;
}
// return;
}
Whenever is am trying to free the dynamically allocated memory,the delete_node function causes problem.Throwing the following errors
ERROR 1
assert failed: multi_heap_realloc multi_heap_poisoning.c:289 (head != NULL)
ERROR 2
Guru Meditation Error: Core 1 panic'ed (LoadStoreError). Exception was unhandled.
Core 1 register dump:
PC : 0x400f3fc4 PS : 0x00060330 A0 : 0x800efca4 A1 : 0x3ffb1920
A2 : 0x00000000 A3 : 0x3ffcc800 A4 : 0x00000005 A5 : 0x00000000
A6 : 0x00000005 A7 : 0x40000014 A8 : 0x800f3ff4 A9 : 0x3ffb1910
A10 : 0x3ffcc800 A11 : 0x88000028 A12 : 0x00000000 A13 : 0x3ffcc800
A14 : 0x00000008 A15 : 0x00000000 SAR : 0x00000004 EXCCAUSE: 0x00000003
EXCVADDR: 0x4000001e LBEG : 0x40088f8c LEND : 0x40088fa2 LCOUNT : 0xffffffff

How to auto increment in Arduino Mega Board while loop?

Please understand that the tone is awkward using a translator
I coded the below code for Arduino Mega Board.
However, the value of buf_i is not increasing in the second while loop.
char buf[] = {0, };
if (Serial3.available()) {
int inByte = Serial3.read();
int nextChar = 0;
if (inByte == 90) { //find Header 1
nextChar = Serial3.read();
if (nextChar == 165) { // find Header 2
int buf_i = 0;
int dataLen = Serial3.read(); // get Message Length
//save data [ char buf[] ] ---> works well!
while (buf_i < dataLen) {
buf[buf_i] = Serial3.read();
buf_i++;
}
buf_i = 0;
//print data to Serial ---> not work (Does not increase buf_i)
while (buf_i < dataLen) {
Serial.print(" ");
Serial.println(buf[buf_i]);
buf_i++;
}
}
}
Serial.write(inByte);
}
and this is Serial Moniter Log
in Serial3 Message
5A A5 06 83 21 00 01 00 11
in Serial Message
enter image description here
Thank you for your help :)
The buffer you created has only one element. If you try to insert more than one, then the behavior is undefined.
char buf[] = {0, };
You must make this buffer large enough for the largest message.
char buf[maximum_data_length] = {0};

fgoto on binary variable length protocol with ragel

I tried to write a parser to a simple binary protocol
0 or more out of frame bytes
Start of frame with STX (0x02)
Two messaje length bytes for messaje length.
One command byte .
0 or more data bytes.
One checksun byte.
The ragel script
static int len;
static unsigned char command;
static int indexx;
static unsigned char data[0x10000];
static unsigned char checksum;
%%{
machine themachine;
action out_of_frame_action { }
action start_of_frame_action {}
action first_byte_len_action { len = fc *256; }
action second_byte_len_action { len += fc; }
action command_action { command = fc; indexx=0; len--;}
action data_action {
if(!len)
fgoto check;
else
{
data[indexx++];
len --;
}
}
action checksum_action { checksum = fc; }
stx = 0x02;
first_byte_len = any;
second_byte_len = any;
command = any;
data = any*;
checksum = any;
main := (^stx* $ out_of_frame_action)
(stx > start_of_frame_action)
(first_byte_len > first_byte_len_action)
(second_byte_len > second_byte_len_action)
(command > command_action)
(data $ data_action) ;
check := (checksum % checksum_action) ;
}%%
machine state
But the result machine don't jump to check (5) status so doesn't execute checksum_action and don't return to the first state to continue parsing.
What is wrong?
Follow #Roman recomendations I post a full example. This example doesn't work either because get a wrong checksum.
#include <stdint.h>
#include <stdio.h>
static int len;
static unsigned char command;
static int indexx;
static unsigned char data[0x10000];
static unsigned char checksum;
%%{
machine themachine;
stx = 0x02;
action out_of_frame_action
{
printf("OOF %02X\n",fc);
}
action start_of_frame_action
{
printf("STX ");
}
action first_byte_len_action
{
printf("fbl[%d] ",(int)(fc));
len = 256*((unsigned char)fc);
}
action second_byte_len_action
{
len += (unsigned char )fc ;
printf("sbl[%d] Len=%d ",(int)(fc),len);
indexx=0;
len-=2; // Checksum and command are included on message len
}
action command_action
{
command = fc;
printf("CMM=%02X ", command);
}
action check_len
{
len > 0
}
action data_action
{
data[indexx++]=fc;
printf("[%02X]",(unsigned char) fc);
len--;
}
action checksum_action
{
checksum = fc;
printf(" Chk=%02X \n",checksum);
}
first_byte_len = any ;
second_byte_len = any;
command = any;
data = any*;
checksum = any;
check = (checksum % checksum_action);
main := ((^stx* $ out_of_frame_action)
(stx > start_of_frame_action)
(first_byte_len > first_byte_len_action)
(second_byte_len > second_byte_len_action)
(command > command_action)
(data when check_len $ data_action)
check
)**;
}%%
%% write data;
int main(void)
{
uint8_t buf[] = {
0x00, // OOF 00
0x00, // OOF 00
0x02,0x00,0x03,0x20,0x01,0x21, // STX fbl[0] sbl[3] Len = 3 CMM=20 [01] Chk=21
0x00, // OOF 00
0x00, // OOF 00
0x02,0x00,0x05,0x81,0x01,0x02,0x03,0x87, // STX fbl[0] sbl[5] Len = 5 CMM=81 [01][02][03] Chk=87
0x02,0x00,0x03,0x03,0x01,0x04, // STX fbl[0] sbl[3] Len = 3 CMM=03 [01] Chk=04
0x02,0x00,0x05,0x07,0x01,0x02,0x03,0x0D // STX fbl[0] sbl[5] Len = 5 CMM=07 [01][02][03] Chk=0D
};
int cs;
uint8_t *p, *pe, *eof;
p = buf;
eof = pe = buf + sizeof(buf)/sizeof(uint8_t);
%% write init;
%% write exec;
}
I change
check = (checksum % checksum_action);
by
check = (checksum > checksum_action);
but is not a solution.
It would be really nice if you have provided us with a sample input and a full source to verify the program as a whole
I'm not sure why your goto doesn't work, but I'd probably simplify things by not using fgoto at all. There is no need for it here, you can just use semantic condition (when)
Your machine doesn't return to the initial state because nothing tells it to.
So I've made these little changes to your original code:
--- main.c.orig 2017-12-17 11:48:49.369200291 +0300
+++ main.c 2017-12-20 22:51:11.096283379 +0300
## -12,14 +12,12 ##
action first_byte_len_action { len = fc *256; }
action second_byte_len_action { len += fc; }
action command_action { command = fc; indexx=0; len--;}
+ action check_len {
+ len
+ }
action data_action {
- if(!len)
- fgoto check;
- else
- {
- data[indexx++];
- len --;
- }
+ data[indexx++];
+ len--;
}
action checksum_action { checksum = fc; }
## -30,13 +28,13 ##
data = any*;
checksum = any;
-main := (^stx* $ out_of_frame_action)
+ check = (checksum % checksum_action);
+main := ((^stx* $ out_of_frame_action)
(stx > start_of_frame_action)
(first_byte_len > first_byte_len_action)
(second_byte_len > second_byte_len_action)
(command > command_action)
- (data $ data_action) ;
+ (data when check_len $ data_action) check)**;
-check := (checksum % checksum_action) ;
}%%
Notice how when is used for data simplifying its action and also notice the longest-match kleene star operator ** in the main that instructs it to loop back to the start after successful frame parsing. This gets us to this nice diagram, which is probably closer to what you want:
In your first example, fgoto consumes the checksum data so it's not available later when you want the checksum. You can use fhold to prevent it from being consumed. The checksum_action should also go back to main (and use a $ transition instead of '%', which will only occur if it's EOF.).
action data_action {
if(!len) {
fhold;
fgoto check;
} else {
data[indexx++] = fc;
len --;
}
}
action checksum_action { checksum = fc; fnext main; }
(or you could put the checksum logic in the data_action code).

Sensor reading communication via bluetooth

I have two bluetooth modules(HC05) connected to separate arduinos. One acting as master and other as slave. One LDR is connected to the slave part which will be taking continuous readings and sending it to master via bluetooth.
The modules are successfully paired.I could even control an led connected to master using a pushbutton connected to slave.
Since 4 days I am struggling to get the readings of LDR on the serial monitor of master.
The slave part of the project(having the LDR):
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
#define ldrPin A0
int ldrValue = 0;
void setup() {
pinMode(9, OUTPUT); // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
digitalWrite(9, HIGH);
pinMode(ldrPin, INPUT);
BTSerial.begin(9600);
Serial.begin(9600);
}
void loop()
{
ldrValue = analogRead(ldrPin);
BTSerial.println(ldrValue);
Serial.println(ldrValue);
delay(1000);
}
The master part of the project which will be getting the reaings and displaying on serial monitor:
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
const byte numChars = 1024;
char receivedChars[numChars]; // an array to store the received data
boolean newData = false;
void setup() {
pinMode(9, OUTPUT); // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
digitalWrite(9, HIGH);
BTSerial.begin(9600);
Serial.begin(9600);
Serial.println("<Arduino is ready>");
}
void loop() {
recvWithEndMarker();
showNewData();
}
void recvWithEndMarker() {
static byte ndx = 0;
char endMarker = '\n';
char rc;
while (BTSerial.available() > 0 && newData == false) {
rc = BTSerial.read();
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
ndx = 0;
newData = true;
}
}
}
void showNewData() {
if (newData == true) {
Serial.print("This just in ... ");
Serial.println(receivedChars);
newData = false;
}
}
But the problem is that in the serial monitor only the highest digit ( 3 in 392) is displayed in the serial monitor. The readings are correct but the complete readings are not displayed.
The serial monitor showed something like this:
<Arduino is ready>
This just in ... 1
This just in ... 1
This just in ... 1
This just in ... 1
This just in ... 1
This just in ... 3
This just in ... 3
This just in ... 3
This just in ... 3
This just in ... 3
Ifin the Slave part instead of LDR readings if I am sending a string "hello", then it is printing as :
<Arduino is ready>
This just in ... h
This just in ... h
This just in ... h
This just in ... h
This just in ... h
This just in ... h
I have referred this link for serial communications Serial input basics
Can someone please help me out as I am new to arduino.
To read a string directly into a variable you can use:
BTSerial.readString()
instead of:
BTSerial.read()
like in the official documentation

Atmega 32, Program to drive motor , How to take input integer from user

I am trying to write a simple program to take input from user by hterm, when User enters "motor" & "25" the motor will rotate in 25 clockwise and 25 anticlockwise direction
//Define clock-speed and include necessary headers
#define F_CPU 1000000
#include <avr/io.h>
#include <util/delay.h>
#include <inttypes.h>
#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdint.h>
#include <util/delay.h>
#include <ctype.h>
#define F_CPU 16000000UL
#define BAUD 9600UL
char cmd[40];
void uart_init(void) // initializing UART
{
UBRRH = 0;
UBRRL = ((F_CPU+BAUD*8)/(BAUD*16)-1);
UCSRC |= 0x86; // 8N1 Data
UCSRB = 0x18; // Receiving and Transmitting
}
int uart_putch(char ch, FILE *stream) // Function for sending Data to PC
{
if (ch == '\n')
uart_putch('\r', stream);
while (!(UCSRA & (1<<UDRE)));
UDR=ch;
return 0;
}
int uart_getch(FILE *stream) // Function for receiving Data from PC
{
unsigned char ch; while (!(UCSRA & (1<<RXC)));
ch=UDR;
uart_putch(ch,stream); // Echo the output back to the terminal
return (tolower(ch));
}
FILE uart_str = FDEV_SETUP_STREAM(uart_putch, uart_getch, _FDEV_SETUP_RW); // Important, not deleting
void loeschen() // Delete the String
{
int strnglen = 0;
while (strnglen < 41 && cmd[strnglen] != 0)
{
cmd[strnglen]= 0;
strnglen++;
}
}
// Define the stepping angle
// Note: Divide by 2 if you are doing half-stepping. for filter test 1.8 defult
#define MIN_STEP 1.8
/* Define an array containing values to be sent at the required Port - for Full-stepping
<first four bits> - <last four bits> = <decimal equivalent>
00000001 = 1 ; 01000000 = 4
00000100 = 4 ; 00010000 = 16
00000010 = 2 ; 00001000 = 8
00001000 = 8 ; 00100000 = 32
*/
unsigned short control_array_full[4] = {4,16,8,32};
/* Define an array containing values to be sent at the required Port - for Half-stepping
<first four bits> - <last four bits> = <decimal equivalent>
0000-1001 = 8 + 1 = 9 ; 0010-0100 = 32 + 4 =36
0000-0001 = 1 ; 0000-0100 = 4
0000-0101 = 4 + 1 = 5 ; 00010100 = 16 + 4 = 20
00000100 = 4 ; 00010000 = 16
00000110 = 4 + 2 = 6 ; 00011000 = 16+8=24
0000-0010 = ; 00-001000 = 8
0000-1010 = 8 + 2 = 10 ; 00-101000 = 40
0000-1000 = 8 ; 00-100000 = 32
*/
unsigned short control_array_half[8] = {36,4,20,16,24,8,40,32};
// Adjust this delay to control effective RPM
// Do not make it very small as rotor will not be able to move so fast
// Currently set at 100ms
void delay()
{
_delay_ms(100);
}
void move_clockwise(unsigned short revolutions){
int i=0;
for (i=0; i < (revolutions* 360 /MIN_STEP) ; i++)
{
//Note: Take modulo (%) with 8 when half-stepping and change array too
PORTD = control_array_half[i % 4];
delay();
}
}
void move_anticlockwise(unsigned short revolutions){
int i;
for (i = (revolutions* 360 /MIN_STEP); i > 0 ; i--){
//Note: Take modulo (%) with 8 when half-stepping and change array too
PORTD = control_array_half[i % 4];
delay();
}
}
int main()
{
// Enter infinte loop
// Make changes here to suit your requirements
uart_init(); // initializing UART
stdout = stdin = &uart_str; // Necessary to compare whole Strings
while(1){
scanf("%s",&cmd); // Read String from Data Register
printf ("Please enter number of motor rotation for clockwise and anticlockwise");
items_read = scanf ("%d", &numbers[i]); // Read integer for motor revolution
if(strcmp(cmd, "motor") == 0)
{
DDRD = 0b00111110; //Set PORTD 4 bits for output
//Enter number of revolutions required in brackets
move_clockwise(items_read);
move_anticlockwise(items_read);
}
DDRD = 0b00000000;
}
loeschen();
}
Now, The problem is that when I will delete these lines from main()
items_read = scanf ("%d", &numbers[i]);
scanf ("%d",&i);
& make items_read in move_clockwise(items_read); as:
move_clockwise(25);
move_anticlockwise(25);
Then when user enters "motor" then motor is running move_clockwise(25); but move_anticlockwise(25); is not running, what I would like is to take both "motor", number for clockwise and number for anticlockwise....
I would really appreciate if anyone can help me with this!
Thanks in advance!
First, in my opinion you're only clearing "cmd" in loeschen(), but you never assining any value.
Second "cmd" is NOT any type of UART dataregister.
DDRD is DataDirectionRegister D, that means you can set some pin to input or output mode.
Use PORTD to set a pin high or low, in example PORTD |= 1<<PD0; to set Port D Pin 0 to high.
I guess you prefer german documentation, because you named one function "loeschen()" ;-), so why don't you visit mikrocontroller.net AVR GCC Tutorial (UART)?
If you like more technic detailed youtube-stuff, et voila: Introduction to UART
RXT (ATMEGA16) - for example:
//////////////////////////////////////////////////////////////////////////
// Definitions
//////////////////////////////////////////////////////////////////////////
#define BAUD 9600UL
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
#error Baud to high
#endif
#define UART_MAX_STRING_LENGHT 20 // Max lenght
//////////////////////////////////////////////////////////////////////////
// UART-Receive-Variables
//////////////////////////////////////////////////////////////////////////
volatile uint8_t uart_str_complete = 0; // FLAG - String received
volatile uint8_t uart_str_count = 0; // Current position
volatile char uart_string[UART_MAX_STRING_LENGHT + 1] = ""; // received string
//////////////////////////////////////////////////////////////////////////
// ISR-UART
//////////////////////////////////////////////////////////////////////////
ISR(USART_RXC_vect)
{
unsigned char nextChar;
nextChar = UDR; // read data from buffer
if(uart_str_complete == 0) // UART-String is currently usen
{
if(nextChar != '\n' && nextChar != '\r' && uart_str_count < UART_MAX_STRING_LENGHT)
{
uart_string[uart_str_count] = nextChar;
uart_str_count++;
}
else
{
uart_string[uart_str_count] = '\0';
uart_str_count = 0;
uart_str_complete = 1;
}
}
}
//////////////////////////////////////////////////////////////////////////
// Init UART
//////////////////////////////////////////////////////////////////////////
void Init_UART_Async()
{
UBRRH = UBRR_VAL >> 8;
UBRRL = UBRR_VAL & 0xFF;
UCSRB |= (1<<TXEN); // UART TX high
UCSRB |= (1<<RXEN); // UART RX high
UCSRB |= (1<<RXCIE); // UART RX Interrupt enable
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // Asynchron 8N1
sei(); // Enable interrups
}
//////////////////////////////////////////////////////////////////////////
// Main
//////////////////////////////////////////////////////////////////////////
int main(void)
{
Init_UART_Async();
while(1)
{
HandleCommunication(); // <-- Handle your communication ;-)
// and to some other cool stuff here
}
}
//////////////////////////////////////////////////////////////////////////
// Handle Communication
//////////////////////////////////////////////////////////////////////////
void HandleCommunication()
{
if(uart_str_complete == 1)
{
strcpy(received_string, uart_string); // copy received string
strcpy(uart_string, ""); // empty uart-string
uart_str_complete = 0; // set flag to 0
// handle your communication
}
}
After understanding how UART is working, you should check your codeparts
like "scanf("%s",&cmd);" in an console-application - that's easier to find some errors.
I hope this helps you a little, but I guess the best solution is when you're knowing what you're doing.
-Crazy