AVR UART Получено повреждение данных - PullRequest
1 голос
/ 27 апреля 2020

У меня есть связь UART между AVR (Atmega16) и модулем GSM. Обычно все, кажется, работает правильно. Проблема в том, что когда я отправляю SMS (например, SMS: «H = 0,95») на модуль GSM, в программе после каждого полученного SMS-сообщения появляется ответ SMS. Ответ (SMS) отправляется на мобильный телефон правильно, но происходит перезапись случайными числами других переменных. Когда я пытался отладить его с помощью терминала, я предполагаю, что это вызвано получением большого количества байтов в UART (переменная ser_re c, вероятно, повреждена), но я не могу найти, где в программе это могло произойти. Во время обработки ISR существует условие, которое должно избежать этой проблемы, когда максимальное количество байтов записывается в буфер, буфер очищается после.



#include<avr/io.h>       // Header file for basic avr input/output
//#define F_CPU 8000000UL
#include<util/delay.h>   // header file for delay generation    
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <util/atomic.h> 



#include "rf22.h"
#include "lcd.h"


# define USART_BAUDRATE 9600
# define BAUD_PRESCALE ((( F_CPU / ( USART_BAUDRATE * 16UL))) - 1)



volatile unsigned char INTERRUPT=0;
volatile unsigned char DECODE_SMS=0;

uint16_t EEMEM HumidityLowRange=0;
uint16_t EEMEM HumidityHighRange=100;
int16_t EEMEM TemperatureLowRange=-40;
int16_t EEMEM TemperatureHighRange=80;
uint8_t EEMEM SMS_tel_number[14]="+421911243160";

unsigned char sms_index=0;
volatile int out=0;
int Temperature_low_range=-40;
int Temperature_high_range=80;
int Humidity_low_range=0;
int Humidity_high_range=100;
char tel_num[14];
//debugging tel num changing
unsigned char SMS_alert=0; //shows if SMS has been already sent


typedef struct
{
   int Humidity_value;
   int Temperature_value;
} BH;

   BH BeeHive[5]; //for all BeeHives, ambient sensor included (considered as BeeHive without Heater)

   void UART_Transmit_char( unsigned char data )
   {
   /* Wait for empty transmit buffer */
   while ( !( UCSRA & (1<<UDRE)) );
   /* Put data into buffer, sends the data */
   UDR = data;
   }



   void UART_Transmit_string( char string[] )
   {
   int i=0;
   while ( string[i] > 0)
   {
   UART_Transmit_char(string[i]);
   i++;        
   }
   }

   unsigned char rx_tmp[40];   


   volatile char ser_rec[95]="";
   volatile unsigned char a=0;

   void clear_sec_rec()
   {
   int i=0;
   while(i<sizeof(ser_rec))
   { 
   ser_rec[i]=0;
   i++;
   }
   i=0;
   a=0;
   }

   char sms_index1()
   {
       int i=0;
       char index=0;
       while( i<(sizeof(ser_rec)-4))
       {
           i++; //check if gsm sends SM",
           if(ser_rec[i]==((char) 'S'))
           {
           i++; 
               if(ser_rec[i]==((char) 'M'))
               {
                   i++;
                 if(ser_rec[i]==((char) '"'))
                 {
                        i++;
                   if(ser_rec[i]==((char) ','))
                   {
                           i++; 
                           index=ser_rec[i]; //return index  
                   }
                  }
               }
           }
           }//returns it
           if(index) clear_sec_rec();  //clears the ser_rec buffer if there was index
           return index;
   }

   void sms_decode()
   {
       int i=0;
       char TemporaryString[95];
       int Humidity_low_range_temp;
       int Humidity_high_range_temp;
       int Temperature_low_range_temp;
       int Temperature_high_range_temp;
       char SMS_text[80];

       //clear buffers
       strcpy(SMS_text, "");
       strcpy(TemporaryString, "");
       while( i<sizeof(ser_rec))
       {
       if(ser_rec[i]==((char) 'H'))
           {
           if(i<(sizeof(ser_rec)-4)) i++; //go forward only when there is a place for numbers =x,y, therefore number 4
               if(ser_rec[i]==((char) '='))
               {
                   i++;    
                   memcpy(TemporaryString, &ser_rec[i], ((strlen(ser_rec))-i));
                   TemporaryString[(strlen(ser_rec)-i)]='\0';  
                   if((sscanf(TemporaryString,"%d,%d",&Humidity_low_range_temp,&Humidity_high_range_temp)==2))
                       {
                           if(Humidity_low_range_temp<Humidity_high_range_temp)
                           {
                               if((Humidity_low_range_temp>=0)&&(Humidity_high_range_temp<=100))
                               {
                               Humidity_high_range=Humidity_high_range_temp;
                               Humidity_low_range=Humidity_low_range_temp; 
                               //and finally send the notification about changed limits
                               clear_sec_rec();                
                               UART_Transmit_string("AT+CMGS=");
                               _delay_ms(50);
                               UART_Transmit_char(34);
                               _delay_ms(50);
                               UART_Transmit_string(tel_num);//the phone number
                               _delay_ms(50);
                               UART_Transmit_char(34);
                               _delay_ms(50);                          
                               UART_Transmit_string("\r");
                               _delay_ms(50);
                               clear_sec_rec(); //clears the buffer                        
                               sprintf(SMS_text,"Humidity range is set: Low=%d%% High=%d%%\r",Humidity_low_range, Humidity_high_range);
                               UART_Transmit_string(SMS_text);
                               _delay_ms(50);
                               UART_Transmit_char(0x1A);
                               _delay_ms(50);
                               clear_sec_rec();                        
                               _delay_ms(1000); //wait until response about credit will come
                               eeprom_update_word(&HumidityHighRange,Humidity_high_range);
                               eeprom_update_word(&HumidityLowRange,Humidity_low_range);
                               }
                           }
                       }
               }
           }
           i++;
       }
           //clear buffers
           strcpy(SMS_text, "");
           strcpy(TemporaryString, "");            
           i=0;
           //Temperature range set     
           while( i<(sizeof(ser_rec)-4))
               {
                   if(ser_rec[i]==((char) 'T'))
                   {
                        i++; 
                       if(ser_rec[i]==((char) '='))
                       {
                           if(i<(sizeof(ser_rec)-1)) i++;
                           memcpy(TemporaryString, &ser_rec[i], ((strlen(ser_rec))-i));
                           if((sscanf(TemporaryString,"%d,%d",&Temperature_low_range_temp,&Temperature_high_range_temp))==2)
                               {
                                   if(Temperature_low_range_temp<Temperature_high_range_temp)
                                   {
                                       if((Temperature_low_range_temp>=-40)&&(Temperature_high_range_temp<=80))
                                       {
                                       Temperature_high_range=Temperature_high_range_temp;
                                       Temperature_low_range=Temperature_low_range_temp;
                                       //and finally send the notification about changed limits
                                       clear_sec_rec();//clears the buffer
                                       UART_Transmit_string("AT+CMGS=");
                                       UART_Transmit_char(34);
                                       _delay_ms(50);                                  
                                       UART_Transmit_string(tel_num);//the phone number
                                       UART_Transmit_char(34);
                                       UART_Transmit_string("\r");
                                       _delay_ms(50);
                                       clear_sec_rec();//clears the buffer
                                       sprintf(SMS_text,"Temperature range is set: Low=%d C High=%d C\r",Temperature_low_range, Temperature_high_range);
                                       UART_Transmit_string(SMS_text);
                                       _delay_ms(50);
                                       UART_Transmit_char(0x1A);
                                       _delay_ms(50);
                                       clear_sec_rec();
                                       _delay_ms(1000); //wait until response about credit will come
                                       eeprom_update_word(&TemperatureHighRange,Temperature_high_range);
                                       eeprom_update_word(&TemperatureLowRange,Temperature_low_range);                                     
                                       }
                                   }
                               }
                           }

                   }
               i++;
               }
               //clear buffers
           strcpy(SMS_text, "");
           strcpy(TemporaryString, "");
                   i=0;
               //Info SMS  
               while( i<(sizeof(ser_rec)-2)) //go forward only when there is a place for at least 3 characters
               {
                   if(ser_rec[i]==((char) 'I'))
                   {
                       i++; 
//                      b1=1;
                       if(ser_rec[i]==((char) 'N'))
                       {
                           i++;
//                          b1=2;
                           if(ser_rec[i]==((char) 'F'))
                           {
//                              b1=3;
                           i++;
                               if(ser_rec[i]==((char) 'O'))
                               {
                                   //send info about all sensor values
                                   clear_sec_rec();
                                   _delay_ms(200);//clears the buffer
                                   UART_Transmit_string("AT+CMGS=");
                                   UART_Transmit_char(34);
                                   UART_Transmit_string(tel_num);//the phone number
                                   UART_Transmit_char(34);
                                   UART_Transmit_char('\r');
                                   _delay_ms(500);
                                   clear_sec_rec();
                                   _delay_ms(200);//clear the buffer
                                   //T2=%dC H0=%d%%\nH3=%d%% T3=%dC T0=%dC\nH4=%d%% T4=%dC add , BeeHive[2].Temperature_value,BeeHive[0].Humidity_value, BeeHive[3].Humidity_value,BeeHive[3].Temperature_value, BeeHive[0].Temperature_value,BeeHive[4].Humidity_value, BeeHive[4].Temperature_value
                                   sprintf(SMS_text,"H1=%d%% T1=%dC  Amb:\nH2=%d%% T2=%dC H0=%d%%\nH3=%d%% T3=%dC T0=%dC\nH4=%d%% T4=%dC",BeeHive[1].Humidity_value, BeeHive[1].Temperature_value,BeeHive[2].Humidity_value, BeeHive[2].Temperature_value,BeeHive[0].Humidity_value, BeeHive[3].Humidity_value,BeeHive[3].Temperature_value, BeeHive[0].Temperature_value,BeeHive[4].Humidity_value, BeeHive[4].Temperature_value);
//                                  c1=strlen(SMS_text);
                                   UART_Transmit_string(SMS_text);
                                   _delay_ms(50);
                                   UART_Transmit_char(0x1A); //CTRL-Z - required by datasheet
                                   _delay_ms(50);
//                                  UART_Transmit_char('\n');
//                                  d1=strlen(ser_rec);
                                   clear_sec_rec();
                                   _delay_ms(1000); //wait until response about credit will come                                   
                               }
                           }
                       }
                   }
                   i++;                    
               }
                   //Telephone number changing SMS
               //clear buffers
               i=0;
               strcpy(SMS_text, "");
               strcpy(TemporaryString, "");
                   while( i<(sizeof(ser_rec)-15))
                   {
                       if(ser_rec[i]==((char) 'T'))
                       {
                           i++; //go forward only when there is a place for 16 characters
                           if(ser_rec[i]==((char) 'E'))
                           { 
                               i++;
                               if(ser_rec[i]==((char) 'L'))
                               {
                                   i++;
                                   if(ser_rec[i]==((char) ':'))
                                   {
                                       i++;
                                       memcpy(TemporaryString, &ser_rec[i], 13);
                                       TemporaryString[13]='\0';
                                       if((strlen(TemporaryString)==strlen(tel_num))&&(strlen(tel_num)==13))
                                       {
                                       memcpy(tel_num,&TemporaryString[0],strlen(TemporaryString));
                                       //send info about changing number
                                       clear_sec_rec();
                                       _delay_ms(200);//clears the buffer
                                       UART_Transmit_string("AT+CMGS=");
                                       UART_Transmit_char(34);
                                       UART_Transmit_string(tel_num);//the phone number
                                       UART_Transmit_char(34);
                                       UART_Transmit_string("\r");
                                       _delay_ms(50);
                                       clear_sec_rec();
                                       _delay_ms(200);//clear the buffer
                                       sprintf(SMS_text,"This is my new telephone number. BeeHiveMonitor");
                                       UART_Transmit_string(SMS_text);
                                       _delay_ms(50);
                                       UART_Transmit_char(0x1A);
                                       _delay_ms(50);
                                       clear_sec_rec();
                                       _delay_ms(1000); //wait until response about credit will come
                                       eeprom_update_block((void*)&tel_num, (const void*)&SMS_tel_number, 13);
                                       }
                                   }
                               }
                           }
                       }
                       i++;
                   }
                   //Alert turn on SMS
                       //clear buffers
                       strcpy(SMS_text, "");
                       strcpy(TemporaryString, "");
                       i=0;
                       //Info SMS
                       while( i<sizeof(ser_rec))
                       {
                           if(ser_rec[i]==((char) 'K'))
                           {
                               if(i<(sizeof(ser_rec))) i++;
                               if(ser_rec[i]==((char) 'K'))
                               {
                                           SMS_alert=0;
                                           //send info alert turning on 
                                           clear_sec_rec();
                                           _delay_ms(200);//clears the buffer
                                           UART_Transmit_string("AT+CMGS=");
                                           UART_Transmit_char(34);
                                           UART_Transmit_string(tel_num);//the phone number
                                           UART_Transmit_char(34);
                                           UART_Transmit_string("\r");
                                           _delay_ms(50);
                                           clear_sec_rec();
                                           _delay_ms(200);//clear the buffer
                                           UART_Transmit_string("Alerts are turned on\r");
                                           _delay_ms(50);
                                           UART_Transmit_char(0x1A);
                                           _delay_ms(50);
                                           clear_sec_rec();
                                           _delay_ms(1000); //wait until response about credit will come


                               }
                           }
                           i++;
                       }


                   i=0;
                   clear_sec_rec(); //clears the buffer
                   if(sms_index!=0)//deleting SMS
                   {
                   UART_Transmit_string("AT+CMGD=");
                   _delay_ms(50);
                   UART_Transmit_string("1,4\r"); //clear all SMSs in inbox
                   _delay_ms(50);
                   }
                   clear_sec_rec();
   }




    int main(void)
    {
   Humidity_high_range = eeprom_read_word(&HumidityHighRange);  //get init values of previously set limits both Humidity and Temperature
   Humidity_low_range  = eeprom_read_word(&HumidityLowRange);  
   Temperature_high_range = eeprom_read_word(&TemperatureHighRange);    
   Temperature_low_range  = eeprom_read_word(&TemperatureLowRange);
   eeprom_read_block((void*)&tel_num, (const void*)&SMS_tel_number, 13);
   sei();   

   char Text[80]; //character array for writing on the display
   char SMS_text[80]; // character array for writing via SMS
   char ATCommand[20];
   int flag=0;
   MCUCSR = (1<<JTD);  // no -O0, interrupts disabled
   MCUCSR = (1<<JTD);  // do not use read-modify-write
   DDRC=0xFF;
   DDRD=0b11111010;
   DDRB=0b10111111;
   PORTB = PORTB | (1 << PB3); // Reset pin of SIM800L
   _delay_ms(200);
   DDRA=0xFF;   
   PORTC = PORTC | (1 << PC7); // turn on LCD backlight
   //UART INIT
   UCSRB = (1 << RXEN ) | (1 << TXEN );
   UCSRC = (1 << URSEL ) | (1 << UCSZ0 ) | (1 << UCSZ1 );
   UBRRH = (unsigned char)( BAUD_PRESCALE >> 8);
   UBRRL = (unsigned char) BAUD_PRESCALE&0xFF ;
   UCSRB |= (1 << RXCIE );

   lcd_init(LCD_DISP_ON); // display initialization
   rf22_init();
   rf22_setfreq(RF22FREQ(869.545));

   rf22_rxmode();


   //GSM init 3 times AT
   UART_Transmit_string("ATE0\r");
   _delay_ms(200);

   UART_Transmit_string("AT\r");
       _delay_ms(200);
   UART_Transmit_string("AT\r");
       _delay_ms(200);
   UART_Transmit_string("AT\r");   
       _delay_ms(200);
   clear_sec_rec();
   UART_Transmit_string("AT+CMGF=1\r");//set text mode
//  while(!(strstr((char*)ser_rec,"OK")));
   _delay_ms(200);
//  while(!(strstr((char*)ser_rec,"OK")));
   clear_sec_rec();
   UART_Transmit_string("AT+CNMI=1,1,0,0,0\r");
//  while(!(strstr((char*)ser_rec,"OK")));
   _delay_ms(200);
   clear_sec_rec();
   UART_Transmit_string("AT+CMGD=1,4\r"); //delete all SMS in inbox
   _delay_ms(100); 
//  UART_Transmit_string("1,4\r"); 
//  while(!(strstr((char*)ser_rec,"OK")));
   _delay_ms(200);
   clear_sec_rec();

   while(1)     
   {
       if((INTERRUPT==1)&&(DECODE_SMS==0))
       {   
       sms_index=sms_index1();
       INTERRUPT=0;

       if(sms_index!=0)
       {
       //if index exists - ready for decoding SMS  
       DECODE_SMS=1;
       sprintf(ATCommand,"AT+CMGR=%c\r",sms_index); 
       UART_Transmit_string(ATCommand); //request for reading SMS with sms index   
       }
       }


       if((INTERRUPT==1)&&(DECODE_SMS==1))//decodes the sms
       {
       sms_decode(); 
       DECODE_SMS=0; //finally clear both flags
       INTERRUPT=0;
       }   



for(int x=0;x<5;++x)
{
       rf22_getpacket(rx_tmp);
       _delay_ms(10);   
       sscanf(rx_tmp,"_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d",&BeeHive[0].Humidity_value, &BeeHive[0].Temperature_value,&BeeHive[1].Humidity_value, &BeeHive[1].Temperature_value,&BeeHive[2].Humidity_value, &BeeHive[2].Temperature_value,&BeeHive[3].Humidity_value, &BeeHive[3].Temperature_value,&BeeHive[4].Humidity_value, &BeeHive[4].Temperature_value);      
       _delay_ms(10);
       lcd_clrscr();
       _delay_ms(10);
       lcd_gotoxy(0,0);
       sprintf(Text,"H1=%02d T1=%+03d  Amb:\nH2=%02d T2=%+03d H0=%02d\nH3=%02d T3=%+03d T0=%+03d\nH4=%02d T4=%+03d",BeeHive[1].Humidity_value, BeeHive[1].Temperature_value,BeeHive[2].Humidity_value, BeeHive[2].Temperature_value,BeeHive[0].Humidity_value, BeeHive[3].Humidity_value,BeeHive[3].Temperature_value, BeeHive[0].Temperature_value,BeeHive[4].Humidity_value, BeeHive[4].Temperature_value);
   //  sprintf(Text,"a:%d b:%d c:%d d:%d\n tel:%s\n index: %d",a1,b1,c1,d1,tel_num,sms_index);
   //  sprintf(Text,"HL:%d HH:%d\n tel:%s\n TL:%d TH:%d",Humidity_low_range,Humidity_high_range,tel_num, Temperature_low_range, Temperature_high_range);
   //  sprintf(Text,"High Limit:%d\nLow Limit:%d",Humidity_high_range, Humidity_low_range);
       //UART_Transmit_string("AT+CMGF=1\r");
       //_delay_ms(100);       
       //sprintf(Text,"%s",ser_rec);
       //ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
       //{
       //UART_Transmit_string("AT\r");
       //_delay_ms(1000);  
       //sprintf(Text,"%s",ser_rec);           
       //}
//
       //UART_Transmit_string("AT\r");
       //clear_sec_rec();
       lcd_puts(Text);
       _delay_ms(2000);
}   
//SMS alert condition
   for(int j=1;j<5;j++)
       {
       if(!SMS_alert)
       {
       if(BeeHive[j].Humidity_value>Humidity_high_range || BeeHive[j].Humidity_value<Humidity_low_range || BeeHive[j].Temperature_value>Temperature_high_range ||BeeHive[j].Temperature_value<Temperature_low_range) 
       {
           //sending SMS alert
           SMS_alert=1;
           UART_Transmit_string("AT+CMGS=");
           _delay_ms(100);
           UART_Transmit_char(34);
           _delay_ms(100);
           UART_Transmit_string(tel_num);//the phone number
           _delay_ms(100);
           UART_Transmit_char(34);
           _delay_ms(100);
           UART_Transmit_string("\r");
           _delay_ms(100);
           clear_sec_rec();
           sprintf(SMS_text,"Alert: H%d=%d%% T%d=%+d C\r",j,BeeHive[j].Humidity_value,j,BeeHive[j].Temperature_value);
           UART_Transmit_string(SMS_text);
           _delay_ms(100);
           UART_Transmit_char(0x1A);
           _delay_ms(100);
           clear_sec_rec();
       }
       }
       }   
       _delay_ms(100);
   }
        return 0;

    }

ISR ( USART_RXC_vect )
{
   if(a<(sizeof(ser_rec)))
   {
   ser_rec[a]=UDR;
   if((ser_rec[a]!=0xd)&&(ser_rec[a]!=0xa)) //we do not need these bytes 0xd,0xa
   {
       a++;
       INTERRUPT=1;
   }
   }
   else
   {
   out=UDR;
   clear_sec_rec();
   }
}


1 Ответ

3 голосов
/ 27 апреля 2020

Предостережение: Это не столько решение, сколько очистка вашего кода, чтобы вы могли найти решение. Это потому, что ваш код имеет так много ненужной сложности, что его трудно анализировать.

Однако, есть некоторые [очевидные] ошибки ...


Ваш ISR скачок с вашим уровнем задач

Ваш ISR syn c с уровнем задач для вашего буфера является подозрительным, несмотря на volatile.

Когда вы пытаетесь получить доступ к нему на уровне задач, вам необходимо отключить прерывания на время доступа на уровне задач.

Вы должны заключить доступ в пары cli/sti. Сделайте это для любого уровня доступа к ser_rec или a. И, не только вокруг одиночной выборки байтов в пределах l oop. Вы должны поставить cli в качестве первого элемента функции уровня задачи и sti в качестве последнего элемента в функции.

И я бы переименовал a во что-то более описательное, например ser_len.


Обрабатывать только те данные, которые вы знаете у вас есть

И на уровне задач (например, sms_decode) ваш l oop предел равен sizeof(ser_rec), поэтому вы получаете доступ к мусорным / случайным значениям или частичным устаревшим значениям из предыдущего входящего сообщения.

Вместо:

while (i < sizeof(ser_rec))

Возможно, вы захотите:

while (i < a)

Или, если вы переименуете:

while (i < ser_len)

Если вы сделаете это, функция clear_sec_rec больше не будет нужна обнулить буфер, но просто сбросить ser_len. Обнуление было попыткой смягчить нарушенный предел l oop.


На уровне задачи необходимо "сдвинуть" буфер

То есть если текущая входящая запись имеет (например) 8 символов, но ser_len равна (например) 12, уровень задачи должен «сдвинуть» буфер для удаления обработанной записи:

memmove(&ser_rec[0],&ser_rec[8],ser_len - 8);
ser_len -= 8;

ISR должен не сбросить буфер, если он переполнен

Ваш ISR "сбрасывает" буфер, если приходит слишком много символов. Это, вероятно, нарушает обработку на уровне задачи, потому что вы может выполнить сброс в середине обработки.

Если буфер / кольцо заполняется, ISR должен установить флаг «переполнения», который может проверять уровень задачи [и просто отбрасывать символ], а не вытаскивая коврик из-под уровня задачи со сбросом.


Использовать очередь звонков

Но, вы можете преобразовать буфер в очередь звонков , Это немного сложнее, но позволяет непрерывно передавать информацию из ISR в задачу. (то есть) Это устранит необходимость для ISR сбрасывать буфер. Кроме того, на уровне задач можно обрабатывать несколько записей без потери.

Может помочь установка слишком большого размера буфера (например, char ser_rec[10000]). Но делайте это только после исправления синхронизации.

Вы могли бы даже иметь возможность использовать атомарность (например, stdatomic.h в индексах кольцевого буфера) и устранить необходимость в cli/sti в задача [хотя последняя медленнее, но проще].


Устранить ненужную сложность

Вы используете N уровня if/else лестницы вместо простого memcmp:

char
sms_index1()
{
    int i = 0;
    char index = 0;

#if 0
    while (i < (sizeof(ser_rec) - 4)) {
        i++;                            // check if gsm sends SM",
        if (ser_rec[i] == ((char) 'S')) {
            i++;
            if (ser_rec[i] == ((char) 'M')) {
                i++;
                if (ser_rec[i] == ((char) '"')) {
                    i++;
                    if (ser_rec[i] == ((char) ',')) {
                        i++;
                        index = ser_rec[i]; // return index
                    }
                }
            }
        }
    }                                   // returns it
#else
    while (i < (sizeof(ser_rec) - 4)) {
        // return index
        if (memcmp(&ser_rec[i],"SM\",",4) == 0) {
            i += 4;
            index = ser_rec[i];
        }
        i += 1;
    }
#endif

    // clears the ser_rec buffer if there was index
    if (index)
        clear_sec_rec();

    return index;
}

Сохранять код до 80 символов в строке

Разбивать длинные строки в логических точках

Изменить ( например):

if (BeeHive[j].Humidity_value > Humidity_high_range || BeeHive[j].Humidity_value < Humidity_low_range || BeeHive[j].Temperature_value > Temperature_high_range || BeeHive[j].Temperature_value < Temperature_low_range)

Into:

if ((BeeHive[j].Humidity_value > Humidity_high_range) ||
    (BeeHive[j].Humidity_value < Humidity_low_range) ||
    (BeeHive[j].Temperature_value > Temperature_high_range) ||
    (BeeHive[j].Temperature_value < Temperature_low_range)) {

Избегайте [длинных] комментариев на «боковой панели» в коде. Вместо этого поместите их в строку выше. (например)

Изменить (например):

i++;                        // go forward only when there is a place for 16 characters

На:

// go forward only when there is a place for 16 characters
i++;

Использовать #define/enum для специальных значений

Вы также делаете (например) UART_Transmit_char(34); 34 является «аппаратным» значением. Что это значит / представляет? Сделайте что-то вроде: #define STARTCHAR 34 // framing char, а затем выполните: UART_Transmit_char(STARTCHAR);


Отдельные блоки связанного / несвязанного кода с пустыми строками

Добавьте несколько пустых строк в групповые вещи. Например, вы делаете UART_Transmit_char, а затем делаете: _delay_ms(50). Добавьте пустую строку после _delay_ms. Или, что еще лучше, создайте функцию, которая выполняет обе функции и вызывает функцию .


Исправление неработающих комментариев

Некоторые из ваших комментариев неверно / неуместно:

_delay_ms(200); // clear the buffer

Компиляция кода с предупреждениями включает и исправляет все предупреждения

Поскольку у меня нет доступа к файлам AVR (например, avr/interrupt.h), я не могу скомпилировать ваш код. Но вы должны скомпилировать с -Wall -O2, чтобы генерировать предупреждения и исправлять их. И я подозреваю, что у вас есть несколько.

...