Go Down

Topic: Problem with USART communication in low-level (Read 172 times) previous topic - next topic

danulduzu_f

Apr 21, 2018, 08:25 pm Last Edit: Apr 21, 2018, 08:58 pm by danulduzu_f
Hi. I would like to ask question related to USART in low-level. I am working with Arduino Uno and did all setup configurations; however, I am not able to print float data on serial monitor, it prints question marks. When I use "Serial.println" it works fine, so I do not have problems with setup. I could not find where is the problem. Could anyone, please, help me? Here is the code:

#include <stdio.h>


void setup() {

  //analogReference(EXTERNAL);
  //Serial.begin(9600);
 
  UCSR0A = 0;
  UCSR0A |= (1 << U2X0);
  UCSR0B = 0;
 // UCSR0B |= (1 << RXCIE0); //enable receiver interrupt
  //UCSR0B |= (1 << TXCIE0); //enable transmitter interrupt
  //UCSR0B |= (1 << UDRIE0);
  //UCSR0B |= (1 << RXEN0); //enable recieving
  UCSR0B |= (1 << TXEN0); //enable transmitting
  UCSR0C |= (1 << UCSZ00);  //8 bit
  UCSR0C |= (1 << UCSZ01); //8 bit
  UCSR0C |= (1 << UPM01); //odd parity
  UCSR0C |= (1 << UPM00); //odd parity
  UBRR0L  =  B11001111; //9600 baud rate

}

void print_ln(float * string ){

    while ( !( UCSR0A & (1<<UDRE0)) );

    UDR0 = string; //send the data

 

}



void loop() {

float data = 5;

print_ln(&data);

//delay(2000);
}






Thank you in advance

Edit 1: I tried with another way, it seems it prints int and char with the same code( data types changed only) but cannot print float

ieee488

however, I am not able to print float data on serial monitor,
Have no clue what you are doing.


Printing float with Serial.print( ) is very simple.
https://www.arduino.cc/en/Serial/Print



.

danulduzu_f

#2
Apr 21, 2018, 08:56 pm Last Edit: Apr 21, 2018, 08:56 pm by danulduzu_f
Thank you for your answer. I am trying to make USART in register level programming, I do not want to use Serial.println(float), but want to make my own print function

AWOL

Code: [Select]
void print_ln(float * string ){

    while ( !( UCSR0A & (1<<UDRE0)) );

    UDR0 = string; //send the data

 

}
What do you notice about the size of the register UDR0?
What do you notice about the size of the pointer "string"?
"Pete, it's a fool (who) looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.

danulduzu_f

UDR0 is 1 byte and float is 4 bytes, it is the matter of size, thank you. However, I tried this code and it worked for int but does not for float again I got question marks

Code: [Select]
void transmit(unsigned char data){

while ( !( UCSR0A & (1<<UDRE0)) );
UDR0 = data;

}

void print_ln(const char* str)
{
int length = strlen(str);
int i;
for (i = 0; i < length; i++) {
transmit(str[i]);
}
}


I use this method with sprintf function

Code: [Select]

char str[32];
void loop(){
float data = 5;
sprintf(str, "%f", data);
print_ln(str);
}

danulduzu_f

I solved it using the last code and adding these lines:

Code: [Select]
  int d_num = (int) num;
  float frac = num - d_num;
  int frac1 = frac * 100;
  sprintf(str, "%d.%0.2d\n", d_num, frac1);


I refered to here

westfw

The normal printf() function loaded in avr-gcc programs does not support floating point (to save space.)
See http://forum.arduino.cc/index.php?topic=124809.0

This has nothing to do with the "low level" drivers, which handle essentially only "chars", and your initial messages attempting to put floats (or even ints) directly into uart registers were very wrong.  Formatting/converting various data types for printing (printf/sprintf/etc) and actually sending the resulting characters to the USART are two different tasks.

Go Up