I’ve written a C++ application to transmit a character from my PC to ATmega8A and from it to my PC once again using USB to serial cable. I’ve attached LCD HD44780 to the microcontroller to display the sent and received characters.
The connection between the two devices is established successfully, but I have a problem in encoding and decoding the character. For example:
- If I send (using serial terminal) from PC the character ‘1’, it displays ‘g’ on LCD and once received by my PC again as ‘L’.
- Send from PC the character ‘A’ it displays ‘_’ on LCD and once received by my PC again as ‘P’.
- Send from PC the character ‘a’ it displays ‘o’ on LCD and once received by my PC again as ‘x’.
And so on, I tried different serial terminal apps and got the same result, I’ve tried many times to make it work but without success. So here’s my code:
#define DP4 PC5
#define DP5 PC4
#define DP6 PD7
#define DP7 PD4
#define DE PD6 //! Display Enable pin
#define DRS PB0 //! Display Registers select pin
#define DRW PD5 //! Display Read/Write pin
#define BAUD_RATE 19200
#include "KH_Atmega8.hpp"
#include <Arduino.h>
#include "KH_USART_CPP.hpp"
#include "LCDHD44780_AVRLib.hpp"
// LCD Setup
LCD_HD44780 * ptrLCD;
LineNumber myLine ; //Line number to write in
Page myPage=Page_1; //The page number
char pos =1 ; // //chacter postion on the LCD
//Setup output file stream
FILE Usart_WR_Stream;
int WriteByteToStdout(char u8Data, FILE *stream);
char strStream[25]={' '};
int main()
{
LCD_HD44780 myDisplay (DP4,DP5,DP6,DP7,PORT_C_,PORT_C_,PORT_D_,PORT_D_,DRS,DE,DRW,PORT_B_,PORT_D_,PORT_D_);
ptrLCD = &myDisplay;
//baud rate 19200 ,8 data bits no parity, 1 start bit, 1 stop bit
ATMG8A_USART my_Serial(BAUD_RATE,true,true); //(Baud rate , Enable Rx,Enable Tx)
char cv = 'V' ;
Usart_WR_Stream.put = WriteByteToStdout;
Usart_WR_Stream.flags = _FDEV_SETUP_WRITE;
Usart_WR_Stream.buf=strStream;
stdout = &Usart_WR_Stream;
myDisplay.LCD_SHOW_String(Page_1,6,Line_1,"Welcome PIO");
_delay_ms(300);
myDisplay.LCD_Clear();
myDisplay.LCD_SHOW_String(Page_1,1,Line_1,"Tx: ");
myDisplay.LCD_SHOW_String(Page_1,1,Line_2,"Rx: ");
while(1)
{
//If there is a received data
if (UCSRA & (1 << RXC))
{
//! Receive char
my_Serial.Receive_Char(cv);
myLine= Line_2;
pos =5;
printf("%d : %c ",cv,cv);
_delay_ms(700) ;
//!Send char
my_Serial.Transmit_Char(cv);
myLine= Line_1;
pos =5;
printf("%d : %c ",cv,cv);
}
return 0;
}
int WriteByteToStdout(char u8Data, FILE *stream)//(char u8Data, __file *stream)//int ATMG8A_USART::USART_SendByte(char u8Data, FILE *stream)
{
if( pos<17)
{
ptrLCD-> LCD_Show_Character (Page_1,pos,myLine,u8Data);
pos+=1;
}
return pos;
}
and my serial class definition
#include "KH_Atmega8.hpp"
#include "KH_USART_CPP.hpp"
#include "util/delay.h"
#include <stdlib.h>
ATMG8A_USART::ATMG8A_USART (unsigned long ubrr,bool en_tx,bool en_rx)
{
Rx_Tx_BufferPtr= Rx_Tx_Buffer;
index=0;
#define MYUBRR ((F_CPU/(ubrr * 16UL))-1)
//Set the Baud rate
UBRRH = (unsigned char ) (MYUBRR >> 8);
UBRRL = (unsigned char ) MYUBRR;
//Set data frame formate 8 Data bits 1 stop pits , no parity check
UCSRC= 0b10000110;
// Enable Transmitter
if(en_tx) UCSRB |= (1 << TXEN);
//Enable Receiver
if(en_rx) UCSRB |= (1 << RXEN) ;
// General index variable to store the current index
index=0;
DDRC |= 1 << DDC0; //set for led tx
DDRD |= 1<< PD2; // utpur for the led rx
}
void ATMG8A_USART::Clear_RX_TX_Buffer()
{
for(uint8_t i=0;i<=19;i++)
{
Rx_Tx_Buffer[0]='\0';
}
}
void ATMG8A_USART::ResetPtr()
{
Rx_Tx_BufferPtr = Rx_Tx_Buffer;
}
ATMG8A_USART::~ATMG8A_USART()
{
}
//! For test
bool ATMG8A_USART::Transmit_Char ( char & data)
{
//$ Wait for Empty Transmit buffer (UDR)/ UDRE UART Data Transmit Buffer empty flag
while (! (UCSRA & (1 << UDRE))); //Do nothing
// return false;
UDR = data;
PORTC ^= 1<< PC0;
return true;
}
bool ATMG8A_USART::Receive_Char( char & data)
{
//wait for data to be received
while (! (UCSRA & (1 << RXC)));
// return false;
data = (unsigned char)UDR;
PORTD ^= 1 << PD2;
return true;
}
and my python script is
import serial
import keyboard
import time
import kh_Serial_comm_Py as kh_ser
import Py_AVR_DecIncod as kh_avr
#import My_Py_Functions.py as mfn
#Setup the serial port
my_SPort = serial.Serial()
my_SPort.port = kh_ser.Select_Ser_Port() #mpf.Select_Ser_Port()
my_SPort.baudrate = 19200
my_SPort.parity = 'N'
my_SPort.stopbits = 1
my_SPort.bytesize = 8
try:
my_SPort.open()
except:
pass
#Store read data
In_Data_List = []
#source of sent data
#out_Data=[]
out_Data =[b'A',b'a',b'B',b'b',b'C',b'c',b'D',b'd']
indx=0
if my_SPort.is_open :
print("Port: {0} is opend".format(my_SPort.port))
while 1:
while my_SPort.in_waiting: # a received data is unread yet
print('reciving bytes in ' )
data_In = my_SPort.read()
In_Data_List.append((data_In))
print('\t',"Data recived --> ",(data_In))
else:
print(f'Sending data {out_Data[indx]})
my_SPort.write(out_Data[indx]
if indx <7:
indx+=1
if indx==7 :
indx =0
break
if keyboard.is_pressed('q'):
my_SPort.close()
print("Port is closed")
break
time.sleep(3)
else:
print(f"Can't open port {my_SPort.port}")
#keyboard.parse_hotkey_combinations({'Ctrl','C'})
print('Sent Charcters','\n',out_Data ,'\n','Received charcaters',"\n",In_Data_List)
Tx_Rx = [out_Data,In_Data_List]
datafile = open("SavedData.txt",mode='w')
datafile.write(str(Tx_Rx))
datafile.close()
print('SavedData.txt has been created','\n',Tx_Rx)