I have modified the code attempting to follow some of the suggestions. I have listed two versions below.
This is the full version that compiles and uploads to the mc fine. It use 17% of program space which is great. Unfortunately it does not work. I can't tell if the error is an overflow issue or if it's hiding in the ADC_Read() function.
/**
Included files
*/
#include "mcc_generated_files/mcc.h"
#include "lcd_jerry.h"
#include <stdio.h>
#include "app.h"
//*************************Declare Global Variables******************
char Buffer[20];
int ADC_Read(uint16_t channel);
uint32_t GET_Voltage(uint16_t resistorRatio, uint16_t convertedValue);
void LCD_Display(uint32_t cellVoltage, uint8_t row, uint8_t column);
void Lcd4_Clear(void);
void Lcd4_Init(void);
/*
Main application
*/
void main(void)
{
//Initialize functions
SYSTEM_Initialize();
Lcd4_Init();
ADCC_Initialize();
APP_LED_Initialize();
// Enable the Global Interrupts
INTCONbits.GIE = 1;
// Enable the Peripheral Interrupts
INTCONbits.PEIE = 1;
//Resistor Ratios
/**
The value of resistorRatioCelln calculated as follows:
(1/(resistorTwoCelln / (resistorOneCelln + resistorTwoCelln))) * 100
*/
uint16_t resistorRatioCell[4] = {496, 367, 245, 123};
uint16_t cellVoltage[4] = {0,0,0,0};
uint16_t voltage[4] = {0, 0, 0, 0};
// LCD Greeting
Lcd4_Clear();
Lcd4_Set_Cursor(1, 1);
Lcd4_Write_String("Battery");
Lcd4_Set_Cursor(2, 1);
Lcd4_Write_String("Simulation");
led4_Toggle();
__delay_ms(1500);
led4_Toggle();
Lcd4_Clear();
// Turn on the ADC module
ADCON0bits.ADON = 1;
//Main while loop
while (1)
{
APP_LED_Tasks();
//Get Voltage at balance wires
for (uint8_t i = 0; i < 4; i++)
{
voltage[i] = GET_Voltage(resistorRatioCell[i], ADC_Read(5 - i));
}
/* Used to confirm loops working
*
voltage[0] = GET_Voltage(resistorRatioCell[0], ADC_Read(5));
voltage[1] = GET_Voltage(resistorRatioCell[1], ADC_Read(4));
voltage[2] = GET_Voltage(resistorRatioCell[2], ADC_Read(3));
voltage[3] = GET_Voltage(resistorRatioCell[3], ADC_Read(2));
*/
//Converts readings at the balance wires to individual cell voltage
for (uint8_t i = 0; i < 3; i++)
{
cellVoltage[i] = voltage[i] - voltage[i+1];
}
cellVoltage[3] = voltage[3];
/*Used to confirm loops working
*
cellVoltage[0] = voltage[0] - voltage[1];
cellVoltage[1] = voltage[1] - voltage[2];
cellVoltage[2] = voltage[2] - voltage[3];
cellVoltage[3] = voltage[3];
*/
//Display the results
LCD_Display(cellVoltage[0], 1, 0);
LCD_Display(cellVoltage[1], 1, 8);
LCD_Display(cellVoltage[2], 2, 0);
LCD_Display(cellVoltage[3], 2, 8);
}
}
//Function Definitions
int ADC_Read(uint8_t channel)
{
uint16_t convertedValue = 0;
// select the A/D channel
ADPCH = channel;
__delay_ms(10);
// Start the conversion
ADCON0bits.ADGO = 1;
while (ADCON0bits.ADGO);
convertedValue = ((adc_result_t) ((ADRESH << 8) + ADRESL));
ADCON0bits.ADGO = 0;
return convertedValue;
}
uint32_t GET_Voltage(uint16_t resistorRatio, uint16_t convertedValue)
{
uint32_t voltage = 0;
voltage = ((convertedValue) * 4) * resistorRatio;
return voltage;
}
void LCD_Display(uint32_t cellVoltage, uint8_t row, uint8_t column)
{
char volt[] = "1.11";
char *volt_ptr = volt;
volt_ptr[0] = look((cellVoltage / 100000) % 10);
volt_ptr[2] = look((cellVoltage / 10000) % 10);
volt_ptr[3] = look((cellVoltage / 1000) % 10);
Lcd4_Set_Cursor(row, column);
Lcd4_Write_String(volt);
Lcd4_Write_String(" V");
}
/**
End of File
*/
This is test code that I compiled with gcc and it works just fine. I have to feed it the ADC values and have used a typical voltage read at the ADC pin of 2.6V or convertedValue = 650 using FVR of 4.096V.
/**
Included files
*/
#include <stdio.h>
#include <stdint.h>
//*************************Declare Global Variables******************
char Buffer[20];
char look(int a);
uint32_t GET_Voltage(uint16_t resistorRatio, uint16_t convertedValue);
void LCD_Display(uint32_t cellVoltage);
/*
Main application
*/
int main(void)
{
uint16_t resistorRatioCell[4] = {496, 367, 245, 123};
uint16_t ADC_Values[4] = {650, 650, 650, 650};
uint32_t cellVoltage[4] = {0,0,0,0};
uint32_t voltage[4] = {0, 0, 0, 0};
for (uint8_t i = 0; i < 4; i++)
{
voltage[i] = GET_Voltage(resistorRatioCell[i], ADC_Values[i]);
}
//Converts readings at the balance wires to individual cell voltage
for (uint8_t i = 0; i < 3; i++)
{
cellVoltage[i] = voltage[i] - voltage[i + 1];
printf("cellVoltage = %d\n", cellVoltage[i]);
}
cellVoltage[3] = voltage[3];
//Display the results
LCD_Display(cellVoltage[0]);
LCD_Display(cellVoltage[1]);
LCD_Display(cellVoltage[2]);
LCD_Display(cellVoltage[3]);
}
//Function Definitions
uint32_t GET_Voltage(uint16_t resistorRatio, uint16_t convertedValue)
{
int voltage = 0;
printf("convertedValue = %d\n", convertedValue);
printf("resistorRatio = %d\n", resistorRatio);
voltage = ((convertedValue) * 4) * resistorRatio;
return voltage;
}
void LCD_Display(uint32_t cellVoltage)
{
char volt[] = "0.00";
char *volt_ptr = volt;
//volt_ptr[0] = look(cellVoltage / 10000000);
//volt_ptr[1] = look((cellVoltage / 1000000) % 10);
volt_ptr[0] = look((cellVoltage / 100000) % 10);
printf("%c\n",volt[0] );
volt_ptr[2] = look((cellVoltage / 10000) % 10);
printf("%c\n",volt[2] );
volt_ptr[3] = look((cellVoltage / 1000) % 10);
printf("%c\n",volt[3] );
//printf("%c\n",volt[6] );
//volt_ptr[5] = look(cellVoltage / 100 % 10);
//volt_ptr[6] = look(cellVoltage / 10 % 10);
//volt_ptr[7] = look(cellVoltage / 1 % 10);
printf("volt_ptr = %s\n",volt);
}
char look(int a)
{
switch(a)
{
case 0:
return '0';
case 1:
return '1';
case 2:
return '2';
case 3:
return '3';
case 4:
return '4';
case 5:
return '5';
case 6:
return '6';
I have checked the FVR related control register settings and they seem correct and are as follows.
ADREF = 0x03;
FVRCON = 0x83;
I do appreciate the help which has been amazing but if anyone can see how I might have stalled out feel free to give me a kick in the right direction.
Jerry