Forum Discussion
NiosV and juart-terminal
I had a project which works fine under niosII. I upgrade all the project with niosv and all seems fine except printing values in juart-terminal.
Here is the main code :
#include <stdio.h>
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include <altera_avalon_i2c.h>
#include <unistd.h>
#include <string.h>
int main()
{
//*
ALT_AVALON_I2C_DEV_t *i2c_dev; //pointer to instance structure
alt_u8 txbuffer[20];
alt_u8 rxbuffer[20];
float co2Concentration = 0;
float temperature = 0;
float humidity = 0;
alt_u32 co2U32 = 0;
alt_u32 tempU32 = 0;
alt_u32 humU32 = 0;
ALT_AVALON_I2C_STATUS_CODE status;
i2c_dev = alt_avalon_i2c_open("/dev/i2c"); //Ouverture du périphérique i2c et récupération d'un pointeur
if (NULL==i2c_dev)
{
printf("Error: Cannot find /dev/i2c\n");
return 1;
}
//set the address of the device using
alt_avalon_i2c_master_target_set(i2c_dev,0x61); //Définition de l'adresse du composant adressé 0x61 pour le SCD30
txbuffer[0]=0x00; txbuffer[1]=0x10; txbuffer[2]=0x00; txbuffer[3]=0x00; txbuffer[4]=0x81; //Remplissage du buffer pour configurer le SDC30 en Continous measurement
status=alt_avalon_i2c_master_tx(i2c_dev,txbuffer, 5,ALT_AVALON_I2C_NO_INTERRUPTS); //Envoi du buffer au composant
if (status!=ALT_AVALON_I2C_SUCCESS) return 1; //FAIL
while(1)
{
txbuffer[0]=0x02; txbuffer[1]=0x02; //Remplissage du buffer pour déterminer si les données sont prêtes
alt_avalon_i2c_master_tx(i2c_dev,txbuffer, 2,ALT_AVALON_I2C_NO_INTERRUPTS); //Envoi du buffer au composant
rxbuffer[1]=0x00;
usleep(3000); // Il faut attendre au moins 3ms avant de demander la réponse
alt_avalon_i2c_master_rx(i2c_dev,rxbuffer, 3,ALT_AVALON_I2C_NO_INTERRUPTS); //Récupération de la réponse du composant si rxbuffer[1]==0x01 alors les données sont prêtes
if(rxbuffer[1]==0x01)
{
txbuffer[0]=0x03; txbuffer[1]=0x00; //Remplissage du buffer pour la lecture des données
alt_avalon_i2c_master_tx(i2c_dev,txbuffer, 2, ALT_AVALON_I2C_NO_INTERRUPTS); //Envoi du buffer de lecture et récupération des données
usleep(3000); //Wait 3ms before data available
alt_avalon_i2c_master_rx(i2c_dev,rxbuffer, 18,ALT_AVALON_I2C_NO_INTERRUPTS); //Read datas
co2U32 = (alt_u32)((((alt_u32)rxbuffer[0]) << 24) | (((alt_u32)rxbuffer[1]) << 16) | (((alt_u32)rxbuffer[3]) << 8) | ((alt_u32)rxbuffer[4]));
tempU32 = (alt_u32)((((alt_u32)rxbuffer[6]) << 24) | (((alt_u32)rxbuffer[7]) << 16) | (((alt_u32)rxbuffer[9]) << 8) | ((alt_u32)rxbuffer[10]));
humU32 = (alt_u32)((((alt_u32)rxbuffer[12]) << 24) | (((alt_u32)rxbuffer[13]) << 16) | (((alt_u32)rxbuffer[15]) << 8) | ((alt_u32)rxbuffer[16]));
memcpy(&co2Concentration, &co2U32, sizeof(co2Concentration));
memcpy(&temperature, &tempU32, sizeof(temperature));
memcpy(&humidity, &humU32, sizeof(humidity));
}
printf("---------------------------------------------------------\n");
printf("SCD30\n");
printf("Concentration de CO2 : %f ppm\n",co2Concentration);
printf("Température : %.1f °C\n",temperature);
printf("Humidité relative : %.1f %% \n",humidity);
usleep(500000);
}
}
I put a breakpoint just before the printf and the values are good :
but when i print the values in the juart-terminal :
I can't figure out why the printf does not work as i expect.
Someone could help me to understand this problem ?
Thanks
Eric
Summary:
- printf(%f) always prints 0, even if the variable contains valid floating-point number.
Change the On-Chip Ram size from decimal (such as 167.5KB / 167500 bytes) to binary (such as 167KiB / 171008 bytes). - Character é is printed wrongly.
Change the active code page of Windows's command prompt from 437 to 65001 (UTF-8)
- printf(%f) always prints 0, even if the variable contains valid floating-point number.
14 Replies
- LiangYuG_Altera
Contributor
Hi ETang2 ,
Can you add this line of code after the %f prints?
I wonder if your system's printf (%f) is affected by newlib library configuration.printf("Raw Decimal: %ld\n", *(alt_u32*)&co2Concentration);Example result:
Regards,
Liang Yu - LiangYuG_Altera
Contributor
Hi ETang2 ,
The problem is when after this breakpoint i execute the code step by step the printf print the wrong values in juart-terminal.
Noted, sorry for misinterpreting your first post.
You are right that there is something fishy here.- Breakpoint before printf shows printed variables are memcpy correctly from intermediary value.
- Execute the code step-by-step, and yet the printed variables shows 0.
Please allow me some time to think this through.
On the 2nd issue:
It seems also that there is print problem as the accentuated character "é for example" are not printed correctly.
I believe it is due to the default code page of your Windows Command Prompt. Nios V Command Shell follows the default code page.
Can you check your code page by typing this command in the niosv-shell?
If the results is 437, then this code page is unable to print é. The character é is stored as two bytes (0xC3 0xA9). Code Page 437 tries to read these as two separate characters (like ├⌐).
To change from Code Page 437 to UTF-8,
In my previous comment, I was running my experiment in Linux.
And Linux terminal supports UTF-8 by default (unlike Windows Command Prompt).Regards,
Liang Yu - ETang2
Occasional Contributor
Thank you for your reply.
I think it's not a problem with rxbuffer[1] = 0x01 because the values in the debug window are good. So that seems that the memcopy were right.
As i put the first breakpoint at the first printf("SCD30\n"); the code before this brekpoint should be executed with the same time as usual and the values are good. The problem is when after this breakpoint i execute the code step by step the printf print the wrong values in juart-terminal. It seems also that there is print problem as the accentuated character "é for example" are not printed correctly.
Regards
Eric
- LiangYuG_Altera
Contributor
Hi ETang2
I copied and ran similar code as yours.
However, rather than I2C access (which I don't have), my code directly initialize the numbers in your example.The memcpy is successful in replacing the values from 0 to valid values.
And juart-terminal prints the correct values.
Could it be possible that you need to changeusleep(3000);
alt_avalon_i2c_master_rx(i2c_dev,rxbuffer, 3,ALT_AVALON_I2C_NO_INTERRUPTS);to
while(1) {
usleep(3000);
alt_avalon_i2c_master_rx(i2c_dev,rxbuffer, 3,ALT_AVALON_I2C_NO_INTERRUPTS);
if(rxbuffer[1]==0x01) break;
}When you use breakpoint, there is sufficient delay for alt_avalon_i2c_master_rx() to return rxbuffer[1] = 0x01 at the first attempt.
However, when you let the application to run normally, usleep(3000) is not enough to get rxbuffer[1] = 0x01.
Perhaps it is only possible after a few attempts.
Thus, co2U32, tempU32, and humU32 remains at 0 due to rxbuffer[1] = 0x0.
Which leads to memcpy 0 into the printed variables, that is also 0.To proof this phenomena, you can define different initial value between the printed variables & intermediary variables. This can help to understand whether it is a memcpy or rxbuffer issue.
float co2Concentration = 888;
float temperature = 888;
float humidity = 888;
alt_u32 co2U32 = 0;
alt_u32 tempU32 = 0;
alt_u32 humU32 = 0;Regards,
Liang Yu