Reputation: 311
I have some trouble using a PIC16F1824. I want to convert an value retrieve from the ADC converter and transmit it to an UART. I've used MCC to generate my code. When I debug my code step by step, the voltage value is similar that the one I've obtained with my scope. But when I want to print this value on the serial interface, I have an error with the argument %f (or %.2f) in printf.
C:\Program Files\Microchip\xc8\v2.20\pic\sources\c99\common\nf_fputc.c:16:: warning: (1498) pointer (unknown) in expression may have no targets C:\Program Files\Microchip\xc8\v2.20\pic\sources\c99\common\doprnt.c:66:: error: (1250) could not find space (80 bytes) for variable _dbuf (908) exit status = 1
Here is my code
#include "mcc_generated_files/mcc.h"
void main(void) {
SYSTEM_Initialize();
uint16_t convertedValue, convertedValue2;
float voltage, voltage2;
float temp = 0;
volatile float sensorRH = 0;
char buffer[5];
while (1) {
// ADC_SelectChannel(channel_AN0);
// ADC_StartConversion();
// while (!ADC_IsConversionDone());
// convertedValue = ADC_GetConversionResult();
// voltage = convertedValue * 0.0048875;
// temp = (voltage2 - 0.424) / 0.00625; // LM60
ADC_SelectChannel(channel_AN2);
ADC_StartConversion();
while (!ADC_IsConversionDone());
convertedValue2 = ADC_GetConversionResult();
voltage2 = convertedValue2 * 0.0048875; // Tension 5V - Résolution 10 bits (5/1023)
sensorRH = (voltage2 - 0.852) / 0.031483; // HIH-4000
printf("ADC converted value = %.2f\n", sensorRH);
sprintf(buffer, "%f",sensorRH);
}
}
I've also tried to :
#include <stdio.h>
volatile float sensorRH;
C:\Program Files\Microchip\xc8\v2.20\pic\sources\c99\common\nf_fputc.c:16:: warning: (1498) pointer (unknown) in expression may have no targets mcc_generated_files/eusart.c:64:: error: (1250) could not find space (8 bytes) for variable _eusartTxBuffer (908) exit status = 1
I'm using a PIC16F1824 with a PIC4kit debugger and XC8 compiler. Thanks in advance
Upvotes: 0
Views: 2369
Reputation: 311
Thanks a lot for the answers. I think I understand the advice, convert the value in integer and then divide it to get a float value in the serial interface. I just have a problem with this line
voltage2 = (uint16_t)( (convertedValue2 * VREF_VALUE + 0x8000ul) >> 16 );
I'm using the sensors
I've made the conversion with this code
voltage = convertedValue * 0.0048875; // VREF : 5V / 10 bits ADC
temp = (voltage - 0.424) / 0.00625; // LM60
sensorRH = (voltage - 0.852) / 0.031483; // HIH-4000
Thanks for your help
Upvotes: 0
Reputation: 1
The error you get means you have either not enough RAM or Flash, or in other words you use too much space. A very simple way to reduce space by a small amount is by enabling optimizer. A way to reduce more is by writing code that does not require so much space. The printf()
family takes a significant amount of space and floating point also. If you can do not use printf()
or sprintf()
and replace the floating point operations with integer operations, this should be possible but it may give you a bit less precise calculations which should not matter since your ADC is not very precise to begin with.
Upvotes: 2
Reputation: 311
Finally, I send my ADC values in millivolt over the UART and make the conversion on the PC software. It's not really clean, but it do the job... Thanks
int i = 0;
int j = 0;
while (1) {
ADC_SelectChannel(channel_AN2);
ADC_StartConversion();
while (!ADC_IsConversionDone());
convertedValue = ADC_GetConversionResult();
voltage = convertedValue * 0.0048875;
i = voltage * 100;
__delay_ms(500);
ADC_SelectChannel(channel_AN3);
ADC_StartConversion();
while (!ADC_IsConversionDone());
convertedValue2 = ADC_GetConversionResult();
voltage2 = convertedValue2 * 0.0048875;
j = voltage2 * 100;
printf("ADC voltage = %1u - %1u\r\n", i, j);
}
Upvotes: 0
Reputation: 1225
To address the diagnostic message from the compiler:
C:\Program Files\Microchip\xc8\v2.20\pic\sources\c99\common\nf_fputc.c:16:: warning: (1498) pointer (unknown) in expression may have no targets
C:\Program Files\Microchip\xc8\v2.20\pic\sources\c99\common\doprnt.c:66:: error: (1250) could not find space (80 bytes) for variable _dbuf (908) exit status = 1
The first one "warning: (1498)" is a generated because the XC8 compiler is stupid when handling what's sometimes called opaque pointers. But since this is in reference to Microchip library code that you should not change and the code is in fact correct just ignore this warning.
The second one "error: (1250)" is an error in your code. You have declared more object than there is available RAM for.
This is code I just created for you that uses only integer math:
#include "mcc_generated_files/mcc.h"
/*
Main application
*/
void main(void)
{
#define VREF_VALUE (500) // ADC VREF voltage in 1/100 of a volt
uint32_t convertedValue2;
uint16_t voltage2;
// initialize the device
SYSTEM_Initialize();
// When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
// Use the following macros to:
// Enable the Global Interrupts
//INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
//INTERRUPT_PeripheralInterruptEnable();
// Disable the Global Interrupts
//INTERRUPT_GlobalInterruptDisable();
// Disable the Peripheral Interrupts
//INTERRUPT_PeripheralInterruptDisable();
while (1)
{
// Add your application code
ADC_SelectChannel(channel_AN2);
__delay_ms(1000);
ADC_StartConversion();
while (!ADC_IsConversionDone());
convertedValue2 = ADC_GetConversionResult();
voltage2 = (uint16_t)( (convertedValue2 * VREF_VALUE + 0x8000ul) >> 16 );
printf("ADC voltage = %1u.%02u\r\n", voltage2/100, voltage2%100);
}
}
As you have not provided any details on the sensor that you are using I cannot show you the integer math to do scaling and offset specific to your sensor.
The complete MPLABX v5.40 project an be found on my git hub repository here.
Upvotes: 1