NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Support Forum » Converting a string var to float var and back to string var?

June 23, 2010
by Jer
Jer's Avatar

How do I convert a float variable to a string var and a string variable back to a float variable?

main(void)

{

 char myNumStr[10] = {"12.345"};
 float myFloat = 0.0;

 // Convert my string to a float var.
 myFloat = StrToFloat(myNumStr); // myFloat = 12.345

 // Add the value of 86.42 to the current value of myFloat.
 myFloat += 86.42; // myFloat = (12.345 + 86.42) = 98.765

 // Convert myFloat variable to a string var.
 myNumStr = FloatToStr(myFloat); // myNumStr = {"98.765"}

}

June 23, 2010
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Jer,

I think you are looking for the sscanf and sprintf functions that are part of stdio.h. Check out the documentation in the avr-libc docmetnation of stdio.h.

These are variants of the printf and scanf functions, which we went over in the printf and scanf video tutorial. scanf will take input from a string, and based and turn into a datatype based on the format string. sprintf will output the data to a string.

As a design note, I would recommend keeping all your data internally as floats or integers and just using fprintf to print to LCD (or serial port) when required. If you design your system well, it is very unlikely you will need to convert back and forth.

Humberto

June 23, 2010
by Jer
Jer's Avatar

Hi Hevans

Can you please make a simple program example to preform the same functionality as my fake code? Sorry about bugging you but I learn better through examples.

Jer

June 24, 2010
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Jer,

The teacher in me really wants to let you figure this one out on your own (because I'm positive you can). Learning how to go from the specification of a function to how to use is it is an invaluable skill you will slowly hone as a programmer.

However, I certainly don't want you to feel frustrated with the C code since I know it does have a rather steep learning curve, so what do you way I meet you halfway. Here is half of your code, turning a float into a string.

int main(void) {

 char myNumStr[10];
 float myFloat = 42.0;

 // Convert myFloat variable to a string var.
 myNumStr = sprintf_P(myNum,PSTR("%.2f"),myFloat)

}

Here I used the sprintf_P() function to take a float and format it into a string. The thing to remember about flipping back and forth between strings and other data types is that the string is just a representation of the data. The number 42 can be written down in many different ways, be it decimal, binary, hex, or something somebody made up. The format string is how you specify how you want it to be written out, in this case I chose .2f which means it is a float with 2 decimal places of precision. My string after this will have "42.00" in it. Depending on what you make the format string you can have different representations of the number in your string!

The print and scanf family of functions is extremely useful, and it is a very good idea for you to get familiar with it. Give the other half of your function a shot, and let us know how it turns out. Don't hesitate to ask if you have any questions.

Humberto

June 24, 2010
by Jer
Jer's Avatar

Thank you!

Just to let you know why I (think) need this ability.

I'm working on a function generator. witch is about 2/3 is built. It will take direct user input via a 16key keypad. It when complete, will enable the user to enter a desired frequency, amplitude, Vdc offset, Duty cycle and wave type(Sine, Tri and Sqr.)

It uses the uC's (ATmega328) 16bit counter to measure the period then invert f=(1/t) and add it to the running average to get a more accurate frequency value in this way I can then calculate a more precise error correction for a at least 3 digits of freq. control. I'm using a MAX038 to generate the wave forms so it requires about six DAC channels and a about 7 relays to select the timing capacitor.

Can't wait to show you guys the schematics and pictures of it.

Jer

September 14, 2012
by Jer
Jer's Avatar

Hi Humberto

Im having some trouble with getting the ISR(USART_RX_vect) to fire. Below is my code, can you take a look at it and see what Im doing wrong.

Thanks!

Jer

// ZSenSim.c is based on tempsensor.c // for NerdKits with ATmega328 // mrobbins@mit.edu // VER: 1.2012.0521 // PATH = c:WinAVR-20090313avrZSenSim

define F_CPU 14745600

include <stdio.h>

include <math.h>

include <string.h>

//#include "c:WinAVR-20090313avrincludemath.h"

include <avr/io.h>

include <avr/interrupt.h>

include <avr/pgmspace.h>

include <inttypes.h>

include "../libnerdkits/delay.h"

include "../libnerdkits/lcd.h"

include "../libnerdkits/uart.h"

include "../libnerdkits/io_328p.h"

char RxBuf[20]; //uint8_t FlagSerComndRdy = 0; uint8_t FlagSerComndRdy = 0;
uint8_t CharIndex =0;
char InpChar;

//============================================================================================= //============================================================================================= ISR(USART_RX_vect) {

// Store local copy of new char from the UART-Rx.
//InpChar = uart_read();
InpChar = UDR0;

FlagSerComndRdy = 1; // Added this just for debuging!

//Check if tc == EOL char.
if((InpChar == 10) || (InpChar == 13))
{
    CharIndex = 0;

    FlagSerComndRdy = 1;

}
else
{
    // Build ser-command string.
    RxBuf[CharIndex] = InpChar;

    // INC Char index.
    if(CharIndex < 18)
    {
        ++CharIndex;
        RxBuf[CharIndex] = '\0';

    }
    else
    {
        // RST CharIndex.
        CharIndex = 0 ;

    }
}

}

//--------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- void set_SPI_mode(uint8_t ModeIndex) {

// Initiate the SPI module in master mode, data rate clk/128
// Bit 7 – SPIE: SPI Interrupt Enable = TRUE
// Bit 4 – MSTR: Master = TRUE /Slave Select = FALSE
// Bit[1,0] - SPR1,SPR0
//               0,0 = clk/4
//               0,1 = clk/16
//               1,0 = clk/24
//           ==> 1,1 = clk/128

switch(ModeIndex)
{
    case 0:
        //   SPI MODE: 0, CPOL=0, CPHA=0, Sample (Rising) Setup (Falling).
        SPCR |= (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (1<<SPR0);

        break;

    case 1:
        //   SPI MODE: 1, CPOL=0, CPHA=1, Setup (Rising) Sample (Falling).
        SPCR |= (1<<SPE) | (1<<MSTR) | (1<<CPOL) | (1<<SPR1) | (1<<SPR0);// <= For keypad (74HC165).

        break;

    case 2:
        //   SPI MODE: 2, CPOL=1, CPHA=0, Sample (Falling) Setup (Rising).
        SPCR |= (1<<SPE) | (1<<MSTR) | (1<<CPHA) | (1<<SPR1) | (1<<SPR0);

        break;

    case 3:
        //   SPI MODE: 3, CPOL=1, CPHA=1, Setup (Falling) Sample (Rising).
        SPCR |= (1<<SPE) | (1<<MSTR) | (1<<CPOL) | (1<<CPHA) | (1<<SPR1) | (1<<SPR0);

        break;

    default:
        //   SPI MODE: 1, CPOL=0, CPHA=1, Setup (Rising) Sample (Falling).
        SPCR |= (1<<SPE) | (1<<MSTR) | (1<<CPOL) | (1<<SPR1) | (1<<SPR0);// <= For keypad (74HC165).

        break;
}

}

//--------------------------------------------------------------------------------------------- void master_SPI_init() {

// Set MOSI,SCK,SS as outputs.
// Pins  17,         19,         16
DDRB |= (1<<PB3) | (1<<PB5) | (1<<PB2);

set_SPI_mode(1);

// Set the SS pins we are using as outputs
// PINS=>    23,        24,         25,         26,        27,         28         
DDRC = (1<<PC1) | (1<<PC2) | (1<<PC3) | (1<<PC4) | (1<<PC5);

DDRB |= (1<<PB1);

// set the SS pins logic high (slave not active)
// PINS=>     23,        24,         25,         26,        27,         28  
PORTC = (1<<PC1) | (1<<PC2) | (1<<PC3) | (1<<PC4) | (1<<PC5);

PORTB |= (1<<PB1);

//set up timer, when this fires all the slave panels are updated
//timer set to clk/1024 - aprox 56Hz

// TCCR0B |= (1<<CS02) | (1<<CS00); // TIMSK0 |= (1<<TOIE0); DDRD |= 0x7E;// Set dir for pin used for the RS-232 PORTD = 0x3F;// Set dir for pin used for the RS-232

}

//--------------------------------------------------------------------------------------------- uint16_t SPI_MasterReceive() { // Initz Return value. uint16_t data = 0;

// Pull SS line Low to initiate data transmission. 
PORTB &= ~(1<<PB2);

// Delay to alow SS to go low.
delay_us(50);

// Dummy write a byte of data to SPDR to startup SCLK. 
SPDR = 0xFF;

// Wait for reception to complete, MSB 
while (!(SPSR & (1<<SPIF)))  
{
    // do nothing.
}

// Record byte, shifted 8 bits to left. 
data = (SPDR<<8);

// Dummy write a byte of data to SPDR to startup SCLK. 
SPDR = 0xFF;

// Wait for reception to complete, LSB   
while ( !(SPSR & (1<<SPIF)))   
{
    // do nothing.
}

// Record byte add it to current data value.
data = data + SPDR;

// Pull SS high to synchronise Slave 
PORTB |= (1<<PB2);

// Delay after making SS High for some time to garranty setup before next SPI I/O.
delay_us(50);

// Return Data Register 
return data;

}

//--------------------------------------------------------------------------------------------- void SPI_Outp16(uint16_t OutWord,uint8_t byte_count) {

// Pull SS line Low to initiate data transmission. 
PORTB &= ~(1<<PB2);

// Delay to alow SS to go low.
delay_us(50);

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

if (byte_count == 2 ) 
{   
    // write the High byte 1st to SPDR to SPI-output.
    SPDR = (OutWord>>8);

    // Wait for reception to complete, MSB 
    while (!(SPSR & (1<<SPIF)))  
    {

    }
}

// write the LOW byte 2nd to SPDR to SPI-output.
SPDR = (OutWord & 255);

// Wait for reception to complete, LSB   
while ( !(SPSR & (1<<SPIF)))   
{

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// Pull SS high to synchronise Slave 
PORTB |= (1<<PB2);

// Delay after making SS High for some time to garranty setup before next SPI I/O.
delay_us(50);

}

//--------------------------------------------------------------------------------------------- void SET_VDAC(uint8_t Chnl, float Vout, float Vref) { uint16_t DAC_Word = 0;

if((Chnl>=0) && (Chnl<4))
{

    // Vref = 0 then set Vref to a default value.
    if(Vref==0)
    {
        Vref = 2.5;// Volts.
    }

    if(Vout<0)
    {
        Vout = 0;
    }
    else
    {

        if(Vout>2.5)
        {
            Vout = 2.5;
        }

    }

    // Chnl = 0 to 3.
    DAC_Word = (Chnl<<14);

    // Calculate the 16bits for the DAC = (ADDRESS + COUNT).
    DAC_Word |= (uint16_t)((Vout/Vref) * 4095);

    // Set SIP mode for the DAC.
    set_SPI_mode(3);

    // 1) Select DAC's SPI-ADDRESS = 2.
    PORTC = (2<<3);

    // Delay after selecting the DAC's SPI address and delay to allow it to settle.
    delay_us(20);

    // SPI-Outp DAC_Word.
    SPI_Outp16(DAC_Word,2);

    delay_us(20);

    // 6) Select DAC's Load Reg ADDRESS = 3.
    PORTC = (3<<3);

    // Delay after deselection of the SPI-ADDRESS.
    delay_us(10);

    // Pull MSTR_SS line Low to initiate data transmission. 
    PORTB &= ~(1<<PB2);

    // Delay after deselection of the SPI-ADDRESS.
    delay_us(10);

    // 1) LATCH DAC's new value. Make DAC_Load HIGH.
    // Pull SS high to synchronise Slave 
    PORTB |= (1<<PB2); 
}

}

//--------------------------------------------------------------------------------------------- int8_t Inp_Keypad() {

uint16_t cKeyValue = 65535;

//   SPI MODE: 1, CPOL=0, CPHA=1, Setup (Rising) Sample (Falling).
set_SPI_mode(1);// <= For keypad (74HC165).

// Parrallel Load Keypad data.
// Make 74HC165.PL go Lo then back to High.

// 1) Select Keypad ADDRESS = 0
PORTC = 0;

// 2) Make  KeyPad_LD Low to load key data into 74hc165.
PORTB &= ~(1<<PB2);

// 2) Delay, holding KeyPad_LD low.
delay_us(25);

// 3) Make  KeyPad_LD High to load key data into 74hc165.
PORTB |= (1<<PB2);

// 4) Let KeyPad_LD stay High before Reading SPI.
delay_us(25);

// 5) Select Keypad SPI address = 1.
PORTC = (1<<3);

// 6) Read in the 16bits of the Keypad SPI.
cKeyValue = SPI_MasterReceive();

// Allow SS Address to be deselected.
delay_us(10);

//cKeyValue !=cKeyValue;

//return (65535 - cKeyValue);
switch(65535 - cKeyValue)
{
    case 0:
        // No Key.
        return -1;
        break;
    case 1:
        // [*]
        return 10;
        break;
    case 2:
        // [7]
        return 7;
        break;
    case 4:
        // [4]
        return 4;
        break;
    case 8:
        // [1]
        return 1;
        break;
    case 16:
        // [0]
        return 0;
        break;  
    case 32:
        // [8] 
        return 8;
        break;
    case 64:
        // [5] 
        return 5;
        break;
    case 128:
        // [2] 
        return 2;
        break;
    case 256:
        // [#] 
        return 11;
        break;
    case 512:
        // [9] 
        return 9;
        break;
    case 1024:
        // [6] 
        return 6;
        break;
    case 2048:
        // [3] 
        return 3;
        break;
    case 4096:
        // [C] 
        return 12;
        break;
    case 8192:
        // [D] 
        return 13;
        break;
    case 16384:
        // [E] 
        return 14;
        break;
    case 32768:
        // [F] 
        return 15;
        break;
    default:
        // Invalid Key.
        return -1;
        break;
}

}

//--------------------------------------------------------------------------------------------- void adc_init() { // set analog to digital converter // for external reference (5v), single ended input ADC0 ADMUX = 0;

// Set analog to digital converter to 
// be enabled, with a clock prescale of 1/128
// so that the ADC clock runs at 115.2kHz.
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);

// fire a conversion just to get the ADC warmed up
ADCSRA |= (1<<ADSC);

}

//--------------------------------------------------------------------------------------------- uint16_t Inp_ADC() { // read from ADC, waiting for conversion to finish // (assumes someone else asked for a conversion.) // wait for it to be cleared while(ADCSRA & (1<<ADSC)) { // do nothing... just hold your breath. } // bit is cleared, so we have a result.

// read from the ADCL/ADCH registers, and combine the result
// Note: ADCL must be read first (datasheet pp. 259)
uint16_t result = ADCL;
uint16_t temp = ADCH;
result = result + (temp<<8);

// set ADSC bit to get the *next* conversion started
ADCSRA |= (1<<ADSC);

return result;

}

//--------------------------------------------------------------------------------------------- float Calc_VZout(float Read_Sim, float Ik, float Vofs, float Vref_uut, float Zout) {

float Isim = 0;
float Vzsim = 0;
float temp = 1;
float temp_read;

temp_read = (temp - Read_Sim);

if (temp_read > 0)
{   
    Isim = log(temp_read) * Ik;

}
else
{
    Isim = 0;
}

Vzsim = (Isim * Zout) + Vofs;//added offset 20120910 JBF.

return (Vref_uut - Vzsim);

}

//--------------------------------------------------------------------------------------------- void lcd_display(uint8_t displayOn, uint8_t cursorShow, uint8_t cursorBlink) {

uint8_t LCD_CMD = 8;

if(cursorBlink>0)
{
    LCD_CMD += 1;
}

if(cursorShow>0)
{
    LCD_CMD += 2;
}

if(displayOn>0)
{
    LCD_CMD += 4;
}

lcd_write_byte(LCD_CMD);

}

//--------------------------------------------------------------------------------------------- int8_t Get_Key_Pressed() {
// NOTE: variable "IsWaitingKeyPress" was a global but now is a local static. static int8_t IsWaitingKeyPress = 0;

int8_t curKey;

// Get the current key pressed.
curKey = Inp_Keypad();

if (IsWaitingKeyPress > 0) 
{
    if (curKey >= 0)
    {
        // SET PRESSED STATE to = Waiting for button to be Releas.
        IsWaitingKeyPress = 0;

        return curKey;
    }
    else
    {
        return -2;

    }
}
else
{
    // Check if button has been released?
    if (curKey < 0)
    {
        // YES! BUTTON HAS BEEN Released.

        // Set STATE FLAG to = Waitting for Button Press.
        IsWaitingKeyPress = 1;

        // Debounce Delay.
        delay_ms(150);

        return -4;
    }
    else
    {
        return -8;
    }
}

}

//--------------------------------------------------------------------------------------------- void SOutPortA(uint8_t port_val) {

// 1) Select SOutPortA SPI-ADDRESS = 2.
PORTC = (4<<3);

// 2)  SPI MODE: 1, CPOL=0, CPHA=1, Setup (Rising) Sample (Falling).
set_SPI_mode(1);// <= For keypad (74HC165) and 74HC595.

// 3) Write the new value of 'port_val' to the SPortA
SPI_Outp16( port_val, 1);

}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ int main() {

// Z simulator vars
float Read_sim_inp = .2090;
float         Vref = 2.5085;//<= Common value.
float     Vref_uut = 1.098;
float        VZout = 0;
float     Range[3] = {.25,.5,.95};
float      Zout[3] = {13600,28600,6800};
//float        Ik[3] = {-0.0002649,0.0002649,-0.0002649};// Zsim
//float        Ik[3] = {-0.00025543,-0.00005052,-0.000048155};// Zsim
float        Ik[3] = {-0.00025543,-0.000050,-0.000050};// Zsim
float        ZVofs[3] = {0,0,0};
float      Ippm[7] = {0,0,0,0,0,0,0};

// char tempChar ;

// G simulator vars
float VGout = 0;
double IGmax[7];
double VGm[7];
double VGb[7];
uint8_t GRelay[7];

int8_t       KeyValue = 0;
int8_t    Press_Count = 0;
int8_t    Press_Limit = 4;
int8_t         pos_dp = 0;
int8_t       dspl_row = 0;
int8_t       dspl_col = 0;
int8_t     Edit_State = 0;
int8_t    UserInpMode = 1;

uint8_t   Sensor_Type = 0;
uint8_t   Range_index = 0;
uint8_t    main_state = 0;
uint8_t       ZRelays = 0;
uint8_t       GRelays = 0;
uint8_t       ManCtrl = 0;

uint16_t  temp_uint16 = 0;
uint16_t  last_sample = 0;
uint16_t   adc_sample = 0;

long   Read_sim_ppm = 0;

// double temp_double = 0; long temp_long = 0; // uint32_t temp32int = 0;

char tempStr[20];
char KeyStr[2];

Read_sim_ppm = (Read_sim_inp * 1000000);

// Start up the LCD.
lcd_init();
FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
lcd_home();

// Enable Interupts.
UCSR0B = (1 << RXCIE0);

sei();

// Start up the serial port.
uart_init();
FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
stdin = stdout = &uart_stream;

// Enable Interupts.
UCSR0B = (1 << RXCIE0);

//=============================================================================================
void Get_Ser_Command()
{

    // FlagSerComndRdy = '0' Is waiting for a complete ser-command string.
    // FlagSerComndRdy = '1' Is prossesing RQSTed ser-command string.
    if (FlagSerComndRdy==0) 
    {

        // returns 1 if a character is waiting
        // returns 0 if not
        while ( uart_char_is_waiting() )
        {
            // Read in CHAR.
            InpChar = uart_read();

            //Check if InpChar == EOL char.
            if((InpChar == 10) || (InpChar == 13))
            {
                CharIndex = 0;

                FlagSerComndRdy = 1;

                break;
            }
            else
            {
                // Build ser-command string.
                RxBuf[CharIndex] = InpChar;

                // INC Char index.
                if(CharIndex < 18)
                {
                    ++CharIndex;
                    RxBuf[CharIndex] = '\0';

                }
                else
                {
                    // RST CharIndex.
                    CharIndex = 0 ;
                    break;
                }
            }
        }
    }

    //return FlagSerComndRdy;

}

//=============================================================================================
float Set_IG_DAC(long sim_ppm, double Ippm, float Vref_dac)
{
    uint8_t r = 0;
    double Isim = 0;
    double Vsim = 0;

// double tempDBL = 0; double tempVar = 0; uint8_t NewRelay=0; //sim_ppm = 7.5;

    Isim = (sim_ppm * Ippm);
    //Isim = (10 * Ippm);
    ZRelays = 0;
    r =  0;

    // float IGmax[6];
    // float VGm[6];
    // float VGb[6];

    for(r=0;r<7; ++r)
    {

        if (Isim < IGmax[r])
        {

            // Calculate Vsim.  
            // Vsim = ((Isim * VGm[r]) + VGb[r]);
            //tempDBL = (Isim * VGm[r] );

            //tempDBL = (Isim * 7.35099E+07 );
            Vsim = ((Isim * VGm[r] ) + VGb[r] );

            if ((Vsim > .001) && (Vsim <= 2.5))
            {

                // Set relays that need to be selected. 
                GRelays = GRelay[r];

                NewRelay = GRelay[r];

                // Set the Relays.
                SOutPortA(GRelay[r]);

                tempVar = Vsim;

                // Set GDAC.
                SET_VDAC(1, tempVar ,Vref_dac);

                break;  
            }
        }

    }

    return tempVar;

}

//=============================================================================================

void UpdateDSPLYRow(uint8_t DSPLY_Index)
{

    switch (DSPLY_Index)
    {
        case 0: 
            // CLR LINE.            
                                 //00000000001111111111
                                 //01234567890123456789
            lcd_write_string(PSTR("                   "));

            break;

        case 1:
            // TITLE.
            lcd_write_string(PSTR("  Sensor Simulator  "));

            break;

        case 2:
            // Version.
            lcd_write_string(PSTR("Ver: 1.2012.0913p  "));

            break;

        case 3:
            // Author.
            lcd_write_string(PSTR("Author: Jerome Ford "));

            break;

        case 4:
            // Show Selected Sensor Type = 0 'Z'.
            lcd_write_string(PSTR(" Sensor = Z1, Z2    "));

            break;

        case 5:
            // Show Selected Sensor Type = 1 'T2'.
            lcd_write_string(PSTR(" Sensor = T1,T2     "));

            break;

        case 6:

            // DSPL Selected Z-Output Range.
            fprintf_P(&lcd_stream, PSTR("  Range = %4.2f"), (Range[Range_index] * 100));
            lcd_write_string(PSTR("% "));
            fprintf_P(&lcd_stream, PSTR("%u %u"), FlagSerComndRdy,main_state);
            break;

        case 7:
            // Display Z-Sim Reading.
            fprintf_P(&lcd_stream, PSTR(" Read = %5.2f"), Read_sim_inp * 100); 
            lcd_write_string(PSTR("%   "));
            break;

        case 8:
            // VZout.
            fprintf_P(&lcd_stream, PSTR("VZout = %4.3f"), VZout);
            lcd_write_string(PSTR("V   "));
            break;

        case 9:
            // Show 'z' AUX INFO.
            fprintf_P(&lcd_stream, PSTR("ADC=%u"), last_sample);

            fprintf_P(&lcd_stream, PSTR(" Key=%2d"), KeyValue);

            fprintf_P(&lcd_stream, PSTR(" P=%2u"), Press_Count);

            break;

        case 10:
            // Display Z-Sim Reading.
            fprintf_P(&lcd_stream, PSTR(" Read = %5.2f"), Read_sim_inp * 100); 
            lcd_write_string(PSTR("%  *"));
            break;

        case 11:
            // Show Selected Sensor Type = 0 'Manualy Control DAC.1 & GRelay's'.
            lcd_write_string(PSTR(" Sensor = Man-Ctrl. "));

            break;

        case 12:
            // VGout.
            fprintf_P(&lcd_stream, PSTR("VGout = %4.3f"), VGout);
            lcd_write_string(PSTR("V   "));
            break;

        case 13:
            // Relays.
            fprintf_P(&lcd_stream, PSTR("Relay = %03u        "), (ZRelays+GRelays) );
            break;

        case 14:
            // DSPL Selected G-Output Range.
            lcd_write_string(PSTR("  Range = PPM       "));
            break;

        case 15:
            // DSPL Selected G-Output Range.
            lcd_write_string(PSTR("  Range = %         "));
            break;

        case 16:
            // Display G-Sim Reading(ppm).
            fprintf_P(&lcd_stream, PSTR(" Read = %06lu"), (Read_sim_ppm)); 
            lcd_write_string(PSTR("ppm"));
            break;

        case 17:
            // Display G-Sim Reading(ppm).
            fprintf_P(&lcd_stream, PSTR(" Read = %5.2f"), ((float)Read_sim_ppm/10000)); 
            lcd_write_string(PSTR("%     "));
            break;

        case 18:
            // Display G-Sim Reading(ppm).
            lcd_write_string(PSTR("  AMI's             "));
            break;

        case 19:
            // Show Selected Sensor Type = 1 'T2'.
            lcd_write_string(PSTR(" Sensor = P2        "));
            break;

        case 20:
            // Show Selected Sensor Type = 1 'T2'.
            lcd_write_string(PSTR(" Sensor = P3,P4     "));
            break;

        case 21:
            // Show Selected Sensor Type = 1 'T2'.
            lcd_write_string(PSTR(" Sensor = P5        "));
            break;

        case 22:
            // Show Selected Sensor Type = 1 'T2'.
            lcd_write_string(PSTR(" Sensor = H2s-B1     "));
            break;

        case 23:
            // Show Selected Sensor Type = 1 'T2'.
            lcd_write_string(PSTR(" Sensor = H2S-BE    "));
            break;

    }

}

void CLR_RxBuffer()
{
    uint8_t i = 0;

    for(i = 0; i < 19 ; i++)
    {
        RxBuf[i] = '\0';
    }

}

//=============================================================================================

/////////////////////////////////////////////////////////////////////////////////////////////
// Main Loop. ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
while(1) 
{

    //Get_Ser_Command();

    if (FlagSerComndRdy > 0)
    {
        // RST Flag.
        FlagSerComndRdy = 0;

        // Process the serial command RQST.
        main_state = 4;
    }

    switch (main_state)
    {
        case 0:/* INITZ-Hardware. main_state = 0 */

            //Set next State.
            main_state = 1;

            Edit_State = 1;

            // Initz SPI hardware.
            master_SPI_init();

            // Start up the Analog to Digital Converter.
            adc_init();

            Sensor_Type = 0; // Z=0 , T2=1.
            //RE-INITZ Values
            Read_sim_inp = .2090;

            ZRelays = 2;
            GRelays = 0;

            Vref = 2.509;
            Vref_uut = 1.097;// Typical Value 20120409 JBF

            Press_Limit = 4;

            Range[0] = .25;
            Range[1] = .50;
            Range[2] = .95;

            Zout[0] = 13460;//<= Measured values 20120910 jbf
            Zout[1] = 28240;//<= Measured values 20120910 jbf
            Zout[2] =  6740;//<= Measured values 20120910 jbf

            Ik[0] = -.0002553504;
            Ik[1] = -.0000500;
            Ik[2] = -.00004780;

            ZVofs[0] = .0035;// Zero offset mV
            ZVofs[1] = .004;
            ZVofs[2] = .004;

            // Galvanic Sinsor Simulator Vars. Use DAC-B

            Read_sim_ppm = (Read_sim_inp * 1000000);

            Ippm[0] = 2.5359e-9;// T1,T2
            Ippm[1] = 2.5359e-9;// T1,T2
            Ippm[2] = 1.6746e-9;// P2
            Ippm[3] = 1.1962e-9;// P3, p4
            Ippm[4] = 143.54e-12;// P5
            Ippm[5] = 6.136569e-7;// H1 SPAN (699/450) = 1.55333 x 375e-9 = 0.0000005825
            Ippm[6] = 97.5e-9;// H2

            // Ig-Range[0]
            GRelay[0] = 0;
            VGm[0] = 7.350987E+07;
            VGb[0] = -1.843413E-02;
            IGmax[0] = 3.425981E-08;

            // Ig-Range[1]
            GRelay[1] = 4;
            VGm[1] = 7.33418E+06;
            VGb[1] = 7.78107E-03;
            IGmax[1] = 3.39809E-07;

            // Ig-Range[2]
            GRelay[2] = 68;
            VGm[2] = 7.32168E+05;
            VGb[2] = -1.76765E-2;
            IGmax[2] = 3.43866E-06;

            // Ig-Range[3]
            GRelay[3] = 100;
            VGm[3] = 7.379149E+04;
            VGb[3] = -4.075647E-2;
            IGmax[3] = 3.443157E-05;

            // Ig-Range[4]
            GRelay[4] = 108;
            VGm[4] = 7.3564143E+03;
            VGb[4] = -4.04192E-3;
            IGmax[4] = 3.40389e-04;

            // Ig-Range[5]
            GRelay[5] = 116;
            VGm[5] = 8.28444585E+02;
            VGb[5] = 0;
            IGmax[5] = 3.01770E-03;

            // Ig-Range[6]
            GRelay[6] = 124;
            VGm[6] = 7.4093097E+01;
            VGb[6] = 1.35699e-4;
            IGmax[6] = 3.37395e-02;

            //GRelay[0] = 0;
            //VGm[0] = 7.350987E+07;
            //VGb[0] = -1.843413E-02;
            //IGmax[0] = 3.425981E-08;

            //SET DAC-1
            SET_VDAC(1,0,Vref);
            SET_VDAC(2,1.3,Vref);
            SET_VDAC(3,1.5,Vref);

            lcd_display(1,0,0);

            RxBuf[0] = 0;
            RxBuf[1] = 0;
            RxBuf[2] = 0;
            RxBuf[3] = 0;
            RxBuf[4] = 0;
            RxBuf[5] = 0;
            RxBuf[6] = 0;
            RxBuf[7] = 0;
            RxBuf[8] = 0;
            RxBuf[9] = 0;

            RxBuf[10] = 0;
            RxBuf[11] = 0;
            RxBuf[12] = 0;
            RxBuf[13] = 0;
            RxBuf[14] = 0;
            RxBuf[15] = 0;
            RxBuf[16] = 0;
            RxBuf[17] = 0;
            RxBuf[18] = 0;
            RxBuf[19] = 0;

            // Set to next State.
            main_state = 3;//<= Update_DSPL

            /////////////////////////////////////////////////////

            //------------------------------------------------
            // Product Presentation.
            // Top Line
            lcd_home();
                // Show Company Name.
                UpdateDSPLYRow(18);

            // 2nd Line: 
            lcd_line_two();
                // Show Blank Line.
                UpdateDSPLYRow(0);

            // 3rd Line:  
            lcd_line_three();

                // Show Product Title.  
                UpdateDSPLYRow(1);

            // 4th Line: 
            lcd_line_four();
                // Show Blank Line.
                UpdateDSPLYRow(0);

            delay_ms(2000);

            // 2nd Line: 
            lcd_line_two(); 
                // Show Product Title.  
                UpdateDSPLYRow(1);

            // 3rd Line:  
            lcd_line_three();   
                // Show Blank Line.
                UpdateDSPLYRow(0);

            delay_ms(500);

            // 3rd Line:  
            lcd_line_three();
                // Show Version.
                UpdateDSPLYRow(2);

            // 4th Line: 
            lcd_line_four();
                // Show Author.
                UpdateDSPLYRow(3);

            delay_ms(2000);

            // 4th Line: 
            lcd_line_four();
                // Show Blank Line.
                UpdateDSPLYRow(0);

            //-------------------------------------------------

            lcd_display(1,1,1);
            dspl_row = 1;
            dspl_col = 11;

            // Position Cursor to show user where editting point is.
            lcd_goto_position(dspl_row,dspl_col);

            //zRange 25%, Zo = 13.6Kohms, [ K1=Off, K2=On ]
            SOutPortA(ZRelays|GRelays);

            // write message to serial port.
            printf_P(PSTR("Ready %1d \r\n"), 0);

            //tempChar = uart_read();
            //tempChar = uart_read();

            break;

        case 1:/*  Input User RQSTs via Keypad., main_state = 1*/

            // Get Key Pressed.
            KeyValue = Get_Key_Pressed();

            // Check if RQST for Input Mode Change. 
            if((KeyValue == 10) || (KeyValue == 11)) // key = '#'
            {

                // UserInpMode = 0 EQLs Set-RANGE.
                // UserInpMode = 1 EQLs Set-VzSimOut via Keypad.
                // UserInpMode = 2 EQLs Set-VzSimOut via ADC.
                // UserInpMode = 3 EQLs Set-SensorType or Manual Mode.

                if (KeyValue == 10)
                {
                    // The '*' Key is used for moveing curser up.
                    // MOVE CURSER UP ^.
                    Edit_State -= 1;

                    if(Edit_State < 0)
                    {
                        Edit_State = 3;
                    }

                }
                else
                {
                    // The '#' Key is used for moveing curser down.
                    // MOVE CURSER Down v.
                    Edit_State += 1;

                    if(Edit_State > 3)
                    {
                        Edit_State = 0;
                    }

                }

                switch(Edit_State)//(UserInpMode)
                {
                    case 0:

                        UserInpMode = 0;

                        // Enter new Sensor Type 1,2 or 0.
                        dspl_row = 0;
                        dspl_col = 10;

                        // Position Cursor to show user where editting point is.
                        lcd_goto_position(dspl_row,dspl_col);

                        lcd_display(1,1,1);

                        break;

                    case 1:

                        if(ManCtrl==1)
                        {
                            UserInpMode = 4;

                            // Enter new VZout.
                            dspl_row = 1;
                            dspl_col = 8;

                            // Position Cursor to show user where editting point is.
                            lcd_goto_position(dspl_row,dspl_col);

                            lcd_display(1,1,1);
                        }
                        else
                        {
                            UserInpMode = 1;

                            // Line 1
                            // Enter new range 1,2 or 3.
                            dspl_row = 1;
                            dspl_col = 10;

                            // Position Cursor to show user where editting point is.
                            lcd_goto_position(dspl_row,dspl_col);

                            lcd_display(1,1,1);

                        }

                        break;

                    case 2:

                        if(ManCtrl == 1)
                        {
                            UserInpMode = 5;

                            // Enter new VGout.
                            dspl_row = 2;
                            dspl_col = 8;

                            // Position Cursor to show user where editting point is.
                            lcd_goto_position(dspl_row,dspl_col);

                            lcd_display(1,1,1);

                        }
                        else
                        {
                            if (Sensor_Type == 0)
                            {
                                UserInpMode = 2;// 'Z' = Sensor
                            }
                            else
                            {
                                UserInpMode = 7;// 'T2' = Sensor
                            }

                            // Enter new Simulator Value ##.##% via Keypad.
                            dspl_row = 3;
                            dspl_col = 8;

                            // Position Cursor to show user where editting point is.
                            lcd_goto_position(dspl_row,dspl_col);

                            lcd_display(1,1,1);

                        }
                        break;

                    case 3:

                        if(ManCtrl == 1)
                        {
                            UserInpMode = 6;

                            // Enter new Relay Value.
                            dspl_row = 3;
                            dspl_col = 8;

                            // Position Cursor to show user where editting point is.
                            lcd_goto_position(dspl_row,dspl_col);

                            lcd_display(1,1,1);

                        }
                        else
                        {
                            UserInpMode = 3;

                            // Enter new Simulator Value ##.##% Via the ADC Inp-Adj.
                            dspl_row = 3;
                            dspl_col = 18;

                            // Position Cursor to show user where editting point is.
                            lcd_goto_position(dspl_row,dspl_col);

                            lcd_display(1,0,0);
                        }

                        break;
                }

                // Set to next State.
                main_state = 5;//<= Update_DSPL

            }
            else
            {

                // Preform the selecte User input.
                switch(UserInpMode)
                {

                    case 0:

                        // (Sensor-Type) OR (Manual Mode CTRL) ?
                        switch (KeyValue)
                        {
                            case 0:
                                // Manual CTRL.
                                ManCtrl = 1;

                                // Set main_state = Update Display.
                                main_state = 5;

                                break;

                            case 1:

                                ManCtrl = 0;

                                Sensor_Type = 0;// Z = sensor

                                // Set main_state = Calculate Vzout.
                                main_state = 3;

                                break;

                            case 2:

                                ManCtrl = 0;

                                Sensor_Type = 1;// T1,T2 = Sensor

                                // Set main_state = Calculate VGout.
                                main_state = 2;

                                break;

                            case 3:

                                ManCtrl = 0;

                                Sensor_Type = 2;// P2 = Sensor

                                // Set main_state = Calculate VGout.
                                main_state = 2;

                                break;

                            case 4:

                                ManCtrl = 0;

                                Sensor_Type = 3;// P3,P4 = Sensor

                                // Set main_state = Calculate VGout.
                                main_state = 2;

                                break;

                            case 5:

                                ManCtrl = 0;

                                Sensor_Type = 4;// P5 = Sensor

                                // Set main_state = Calculate VGout.
                                main_state = 2;

                                break;

                            case 6:

                                ManCtrl = 0;

                                Sensor_Type = 5;// H2S-B1 = Sensor

                                // Set main_state = Calculate VGout.
                                main_state = 2;

                                break;

                            case 7:

                                ManCtrl = 0;

                                Sensor_Type = 6;// H2S-BE = Sensor

                                // Set main_state = Calculate VGout.
                                main_state = 2;

                                break;      
                        }

                        // Position Cursor to show user where editting point is.
                        lcd_goto_position(dspl_row,dspl_col);

                        break;

                    case 1:

                        if (Sensor_Type == 0)
                        {
                            // SELECT NEW RANGE[0-2].
                            switch(KeyValue)
                            {
                                case 1:

                                    // Select the 25% Output Range.
                                    Range_index = 0;

                                    // zRange 25%, Zo = 13.6Kohms, [ K1=Off, K2=On ]
                                    ZRelays = 2;

                                    // Set Z range relays.
                                    SOutPortA(ZRelays | GRelays);

                                    // Set main_state= Calculate Vzout.
                                    main_state = 3;

                                    break;

                                case 2:

                                    // Select the 50% Output Range.
                                    Range_index = 1;

                                    //zRange 50%, Zo = 28.6Kohms, [ K1=Off, K2=Off ]
                                    ZRelays = 0;

                                    // Set Z range relays.
                                    SOutPortA(ZRelays | GRelays);

                                    // Set main_state= Calculate Vzout.
                                    main_state = 3;

                                    break;

                                case 3:

                                    // Select the 95% Output Range.
                                    Range_index = 2;

                                    //zRange 95%, Zo = 6.8Kohms, [ K1 = Off, K2 = Off ]

                                    // 
                                    ZRelays = 1;

                                    // Set Z range relays.
                                    SOutPortA(ZRelays | GRelays);

                                    // Set main_state= Calculate Vzout.
                                    main_state = 3;

                                    break;
                            }
                        }
                        else
                        {

                            // SELECT NEW Range_Is_PPM = [0,1]

                            switch(KeyValue)
                            {
                                case 1:

                                    // Set the Range = Trace 'ppm' .
                                    Range_index = 0;

                                    // Range_Is_PPM = 1;

                                    // Set main_state = Calculate VGout.
                                    main_state = 2;

                                    break;

                                case 2:

                                    // Set the Range = Percent '%' .
                                    Range_index = 1;

                                    // Range_Is_PPM = 0;

                                    // Set main_state = Calculate VGout.
                                    main_state = 2;
                                    break;

                            }
                        }

                        break;

                    case 2:
                        // User Input Z-Sim Reading Out.
                        // Check if button has been PRESSED?
                        if ((KeyValue >= 0) && (KeyValue < 10))
                        {
                            Press_Limit = 4;

                            // Store the simulated reading value.
                            temp_uint16 = (uint16_t)(Read_sim_inp * 10000);

                            // store it as a string "2090" <= (.2090)
                            sprintf_P(tempStr, PSTR("%04d"), temp_uint16);

                            // Convert and store key pressed as a char['0' to '9'].
                            sprintf_P(KeyStr, PSTR("%1d"), KeyValue);

                            // Place new key char into postion.
                            tempStr[Press_Count] =  KeyStr[0];

                            // Convert and Store newly edited string value as a uint16.
                            sscanf_P(tempStr, PSTR("%04d"), &temp_uint16);

                            // Rescale the new temp value to the Read_sim_inp.
                            Read_sim_inp = ((float)temp_uint16/10000);

                            // INC edititing point. [0 to 3]
                            if (Press_Count<(Press_Limit-1))
                            {
                                // INC Char index.
                                Press_Count += 1;
                            }
                            else
                            {
                                Press_Count = 0;
                            }

                            //Set Cursor Row.
                            dspl_row = 3;

                            // Set Cursor Col.
                            if(Press_Count < 2)
                            {
                                dspl_col = (8 + Press_Count);
                            }
                            else
                            {
                                dspl_col = (8 + Press_Count + 1);
                            }

                            // Position Cursor to show user where editting point is.
                            lcd_goto_position(dspl_row,dspl_col);

                            // Set main_state = Calculate Vzout.
                            main_state = 3;
                        }

                        break;

                    case 3:
                        /* Get User's Desired Reading from ADC input. */

                        // Get ADC Data.
                        adc_sample = Inp_ADC()-30;

                        if (last_sample != adc_sample)
                        {
                            // Set main_state = Calculate Vzout.
                            main_state = 3;

                            last_sample = adc_sample;

                            if(last_sample < 0 )
                            {
                                last_sample = 0;
                            }
                            else if(last_sample > 1024)
                            {
                                last_sample = 0 ;
                            }

                            // Calculate the desired Simulated Reading.
                            Read_sim_inp = Range[Range_index] * (last_sample/(float)980);

                            //Set Cursor Row.
                            dspl_row = 3;
                            dspl_col = 18;

                            // Position Cursor to show user where editting point is.
                            lcd_goto_position(dspl_row,dspl_col);
                        }

                        break;

                    case 4:
                        // Manualy Enter the VDac.0 for Z-Simulator.
                        // Check if button has been PRESSED?
                        if ((KeyValue >= 0) && (KeyValue < 10))
                        {
                            Press_Limit = 4;

                            // Store the simulated reading value.
                            temp_uint16 = (uint16_t)(VZout * 1000);

                            // store it as a string "2090" <= (.2090)
                            sprintf_P(tempStr, PSTR("%04d"), temp_uint16);

                            // Convert and store key pressed as a char['0' to '9'].
                            sprintf_P(KeyStr, PSTR("%1d"), KeyValue);

                            // Place new key char into postion.
                            tempStr[Press_Count] =  KeyStr[0];

                            // Convert and Store newly edited string value as a uint16.
                            sscanf_P(tempStr, PSTR("%04d"), &temp_uint16);

                            // Rescale the new temp value to the Read_sim_inp.
                            VZout = ((float)temp_uint16/1000);

                            //SET DAC[0] = VZout.
                            SET_VDAC(0,VZout*2,Vref);

                            // INC edititing point. [0 to 3]
                            if (Press_Count<(Press_Limit-1))
                            {
                                // INC Char index.
                                Press_Count += 1;
                            }
                            else
                            {
                                Press_Count = 0;
                            }

                            //Set Cursor Row.
                            dspl_row = 1;

                            // Set Cursor Col.
                            if(Press_Count < 1)
                            {
                                dspl_col = (8 + Press_Count);
                            }
                            else
                            {
                                // Skip over '.'
                                dspl_col = (8 + Press_Count + 1);
                            }

                            // Position Cursor to show user where editting point is.
                            lcd_goto_position(dspl_row,dspl_col);

                            // Set main_state = Calculate Vzout.
                            main_state = 5;

                        }

                        break;

                    case 5:
                        // Manualy Enter the VDac.1 for Galvanic Simulator.
                        // Check if button has been PRESSED?
                        if ((KeyValue >= 0) && (KeyValue < 10))
                        {
                            Press_Limit = 4;

                            // Store the simulated reading value.
                            temp_uint16 = (uint16_t)(VGout * 1000);

                            // store it as a string "2090" <= (.2090)
                            sprintf_P(tempStr, PSTR("%04d"), temp_uint16);

                            // Convert and store key pressed as a char['0' to '9'].
                            sprintf_P(KeyStr, PSTR("%1d"), KeyValue);

                            // Place new key char into postion.
                            tempStr[Press_Count] =  KeyStr[0];

                            // Convert and Store newly edited string value as a uint16.
                            sscanf_P(tempStr, PSTR("%04d"), &temp_uint16);

                            // Rescale the new temp value to the Read_sim_inp.
                            VGout = ((float)temp_uint16/(float)1000);

                            //SET DAC[0] = VZout.
                            SET_VDAC(1,VGout,Vref);

                            // INC edititing point. [0 to 3]
                            if (Press_Count<(Press_Limit-1))
                            {
                                // INC Char index.
                                Press_Count += 1;
                            }
                            else
                            {
                                Press_Count = 0;
                            }

                            //Set Cursor Row.
                            dspl_row = 2;

                            // Set Cursor Col.
                            if(Press_Count < 1)
                            {
                                dspl_col = (8 + Press_Count);
                            }
                            else
                            {
                                // Skip over '.'
                                dspl_col = (8 + Press_Count + 1);
                            }

                            // Position Cursor to show user where editting point is.
                            lcd_goto_position(dspl_row,dspl_col);

                            // Set main_state = Calculate Vzout.
                            main_state = 5;

                        }

                        break;

                    case 6:

                        // Manualy Enter the Relay value.
                        // Check if button has been PRESSED?

                        if ((KeyValue >= 0) && (KeyValue < 10))
                        {
                            Press_Limit = 3;

                            // Store the simulated reading value.
                            temp_uint16 = (uint16_t)(ZRelays | GRelays);

                            // store it as a string "0-255"
                            sprintf_P(tempStr, PSTR("%03d"), temp_uint16);

                            // Convert and store key pressed as a char['0' to '9'].
                            sprintf_P(KeyStr, PSTR("%1d"), KeyValue);

                            // Place new key char into postion.
                            tempStr[Press_Count] =  KeyStr[0];

                            // Convert and Store newly edited string value as a uint16.
                            sscanf_P(tempStr, PSTR("%03d"), &temp_uint16);

                            // Set the new temp value to the Relay vars.
                            ZRelays = (temp_uint16 & 3);
                            GRelays = (temp_uint16 & 252);

                            SOutPortA(ZRelays|GRelays);

                            // INC edititing point. [0 to 3]
                            if (Press_Count<(Press_Limit-1))
                            {
                                // INC Char index.
                                Press_Count += 1;
                            }
                            else
                            {
                                Press_Count = 0;
                            }

                            //Set Cursor Row.
                            dspl_row = 3;

                            // Set Cursor Col.
                            if(Press_Count < 3)
                            {
                                dspl_col = (8 + Press_Count);
                            }

                            // Position Cursor to show user where editting point is.
                            lcd_goto_position(dspl_row,dspl_col);

                            // Set main_state = Calculate Vzout.
                            main_state = 5;

                        }
                        break;

                    case 7:

                        // User Input G-Sim Reading Out.
                        // Check if button has been PRESSED?
                        if ((KeyValue >= 0) && (KeyValue < 10))
                        {

                            Press_Limit = 6;
                            pos_dp = 7;

                            // Copy the simulated reading value into the working var.
                            temp_long = Read_sim_ppm; //000012.5

                            // Convert it into a string "000007.5" 
                                                     ////209000.0

                            sprintf_P(tempStr, PSTR("%06lu"), temp_long);

                            // Convert and store key pressed as a char['0' to '9'].
                            sprintf_P(KeyStr, PSTR("%1u"), KeyValue);

                            // Place new key char into postion.
                            tempStr[Press_Count] =  KeyStr[0];

                            // Convert and Store newly edited string value as a number.
                            sscanf_P(tempStr, PSTR("%06lu"), &temp_long);

                            // Copy the new temp value to the Read_sim_ppm.
                            Read_sim_ppm = temp_long;

                            // INC edititing point. [0 to n]
                            if (Press_Count <  (Press_Limit-1))
                            {
                                // INC Char index.
                                Press_Count += 1;

                                if (Press_Count == pos_dp)
                                {
                                    // INC Char index.
                                    Press_Count += 1;

                                }

                            }
                            else
                            {
                                Press_Count = 0;

                            }

                            dspl_col = (8 + Press_Count);

                            //Set Cursor Row.
                            dspl_row = 3;

                            // Position Cursor to show user where editting point is.
                            lcd_goto_position(dspl_row,dspl_col);

                            // Set main_state = Calculate VGout.
                            main_state = 2;
                        }

                        break;
                }

            }

            break;

        case 2: /* Update VgDAC, main_state = 2 */

            // Set to next State.
            main_state = 5;

            //Set_IG_DAC(long sim_ppm, float Ippm, float Vref_dac)
            VGout = Set_IG_DAC( Read_sim_ppm, Ippm[Sensor_Type], Vref);

            break;

        case 3:/* Calculate Vzout. main_state = 3 */

            // Set to next State.
            main_state = 5;

            // Recalculate the simulators VZsensor output.
            VZout = Calc_VZout( Read_sim_inp, Ik[Range_index], ZVofs[Range_index], Vref_uut, Zout[Range_index]);

            //SET DAC[0] = VZout.
            SET_VDAC(0,VZout*2,Vref);

            break;

        case 4:/* Preform Serial Command, main_state = 4 */

            printf_P(PSTR("%s D\r\n"), RxBuf);

            if (sscanf_P(RxBuf, PSTR("SOWA0 %06lu"), &temp_long) > 0)   
            {
                // "A0" Set new value for the Simulated Reading.

                // Copy the new temp value to the Read_sim_ppm.
                //Read_sim_inp = temp_long;
                Read_sim_ppm = temp_long;

                Read_sim_inp =((float)temp_long/1000000);

                if (Sensor_Type == 0)
                {
                    UpdateDSPLYRow(7);

                    // Recalculate the simulators VZsensor output.
                    VZout = Calc_VZout( Read_sim_inp, Ik[Range_index], ZVofs[Range_index], Vref_uut, Zout[Range_index]);

                    //SET DAC[0] = VZout.
                    SET_VDAC(0,VZout*2,Vref);
                }
                else
                {
                    //Set_IG_DAC(long sim_ppm, float Ippm, float Vref_dac)
                    VGout = Set_IG_DAC( Read_sim_ppm, Ippm[Sensor_Type], Vref);
                }
            }
            else
            {

                // Else If: RANGE?
                if (sscanf_P(RxBuf, PSTR("SOWB0 %06lu"), &temp_long) > 0) 
                {

                    if(Sensor_Type==0)
                    {
                        // "B0" Set new Simulated Range.
                        switch(temp_long)
                        {
                            case 0:
                                Range_index = 0;
                                // Select the 25% Output Range.
                                Range_index = 0;

                                // zRange 25%, Zo = 13.6Kohms, [ K1=Off, K2=On ]
                                    ZRelays = 2;

                                // Set Z range relays.
                                SOutPortA(ZRelays | GRelays);

                                break;
                            case 1:
                                Range_index = 1;

                                //zRange 50%, Zo = 28.6Kohms, [ K1=Off, K2=Off ]
                                ZRelays = 0;

                                // Set Z range relays.
                                SOutPortA(ZRelays | GRelays);

                                break;
                            case 2:

                                Range_index = 2;
                                //zRange 95%, Zo = 6.8Kohms, [ K1 = Off, K2 = Off ]
                                ZRelays = 1;

                                // Set Z range relays.
                                SOutPortA(ZRelays | GRelays);
                                break;
                        }
                    }
                    else
                    {
                        // "B0" Set new Simulated Range.
                        switch(temp_long)
                        {
                            case 0:
                                Range_index = 0;

                                //Set_IG_DAC(long sim_ppm, float Ippm, float Vref_dac)
                                VGout = Set_IG_DAC( Read_sim_ppm, Ippm[Sensor_Type], Vref);

                                break;
                            case 1:
                                Range_index = 1;

                                //Set_IG_DAC(long sim_ppm, float Ippm, float Vref_dac)
                                VGout = Set_IG_DAC( Read_sim_ppm, Ippm[Sensor_Type], Vref);

                                break;
                        }
                    }
                }
                else
                {
                    // Else-If: Sensor-Type?
                    if (sscanf_P(RxBuf, PSTR("SOWJ0 %06lu"), &temp_long) > 0) 
                    {
                        // "J0" Set new value for the Sensor Type.
                        // 1 = Z1 or Z2 //
                        // 2 = T1 or T2 //
                        // 3 = P2       //
                        // 4 = P3 or P4 //
                        // 5 = P5       //
                        // 6 = H2S-B1   //
                        // 7 = H2S-Be   //

                        switch(temp_long)
                        {
                            case 1:// 1 = Z1 or Z2.
                                Sensor_Type = 0;

                                switch(Range_index)
                                {
                                    case 0:
                                        // Set Z range relays.
                                        ZRelays = 2;
                                        break;
                                    case 1:
                                        // Set Z range relays.
                                        ZRelays = 0;
                                        break;

                                    case 2:
                                        // Set Z range relays.
                                        ZRelays = 1;
                                        break;

                                }

                                // Set Z range relays.
                                SOutPortA(ZRelays | GRelays);

                                break;
                            case 2:// 2 = T1 or T2.
                                Sensor_Type = 1;
                                //Set_IG_DAC(long sim_ppm, float Ippm, float Vref_dac)
                                VGout = Set_IG_DAC( Read_sim_ppm, Ippm[Sensor_Type], Vref);

                                break;
                            case 3:// 3 = P2.
                                Sensor_Type = 2;

                                //Set_IG_DAC(long sim_ppm, float Ippm, float Vref_dac)
                                VGout = Set_IG_DAC( Read_sim_ppm, Ippm[Sensor_Type], Vref);

                                break;
                            case 4:// 4 = P3 or P4.
                                Sensor_Type = 3;

                                //Set_IG_DAC(long sim_ppm, float Ippm, float Vref_dac)
                                VGout = Set_IG_DAC( Read_sim_ppm, Ippm[Sensor_Type], Vref);

                                break;
                            case 5:// 5 = P5.
                                Sensor_Type = 4;

                                //Set_IG_DAC(long sim_ppm, float Ippm, float Vref_dac)
                                VGout = Set_IG_DAC( Read_sim_ppm, Ippm[Sensor_Type], Vref);

                                break;
                            case 6:// 6 = H2S-B1.
                                Sensor_Type = 5;

                                //Set_IG_DAC(long sim_ppm, float Ippm, float Vref_dac)
                                VGout = Set_IG_DAC( Read_sim_ppm, Ippm[Sensor_Type], Vref);

                                break;
                            case 7:// 7 = H2S-Be.
                                Sensor_Type = 6;

                                //Set_IG_DAC(long sim_ppm, float Ippm, float Vref_dac)
                                VGout = Set_IG_DAC( Read_sim_ppm, Ippm[Sensor_Type], Vref);

                                break;
                        }
                    }
                }
            }

            // Set to next State.
            main_state = 5;

            break;

        case 5:/* Update Display. */

            // Set Main STATE.
            main_state = 1;

            // Start message to LCD at the top.
            lcd_line_one();

            if (ManCtrl == 1)
            {

                // Show User in Op-Mode is 'Manual-CTRL' is currently selected.
                UpdateDSPLYRow(11);

                // 2nd Line:
                lcd_line_two();

                // SHOW VZout.
                UpdateDSPLYRow(8);

                // 3rd Line:
                lcd_line_three();

                // SHOW VGout.
                UpdateDSPLYRow(12);

                // 4th Line: 
                lcd_line_four();

                // SHOW Relay Value.
                UpdateDSPLYRow(13);

            }
            else
            {

                switch(Sensor_Type)
                {
                    case 0:
                        // Show 'Z1' sensor type currently selected.
                        UpdateDSPLYRow(4);
                        break;

                    case 1:
                        // Show 'Z2' sensor type currently selected.
                        UpdateDSPLYRow(5);
                        break;

                    case 2:
                        // Show 'Z' sensor type currently selected.
                        UpdateDSPLYRow(19);
                        break;

                    case 3:
                        // Show 'Z' sensor type currently selected.
                        UpdateDSPLYRow(20);
                        break;

                    case 4:
                        // Show 'P5' sensor type currently selected.
                        UpdateDSPLYRow(21);
                        break;

                    case 5:
                        // Show 'H2S-B1' sensor type currently selected.
                        UpdateDSPLYRow(22);
                        break;

                    case 6:
                        // Show 'H2S-BE' sensor type currently selected.
                        UpdateDSPLYRow(23);
                        break;

                }

                // 2nd Line:
                lcd_line_two();

                if (Sensor_Type == 0)
                {
                    // DSPL Selected 'Z' Output Range.
                    UpdateDSPLYRow(6);
                }
                else
                {
                    // DSPL Selected 'G' Output Range.
                    if (Range_index == 0)
                    {

                        // 'G' Output Range = 'PPM'
                        UpdateDSPLYRow(14);
                    }
                    else
                    {
                        // 'G' Output Range = '%'
                        UpdateDSPLYRow(15);

                    }

                }

                // 3rd Line:
                lcd_line_three();

                // Blank Line.
                UpdateDSPLYRow(0);

                // 4th Line: 
                lcd_line_four();
                if (Sensor_Type == 0)
                {

                    // DSPL Selected 'Z' Output Value.
                    //if ((dspl_col == 18) && (dspl_row == 3))
                    if (UserInpMode == 3)
                    {
                        //Show Simulated Output.
                        UpdateDSPLYRow(10);

                    }
                    else
                    {
                        //Show Simulated Output.
                        UpdateDSPLYRow(7);
                    }

                }
                else
                {
                    // DSPL Selected 'G' Output Value.
                    if (Range_index == 0)
                    {

                        // 'G' Output Range = 'PPM'
                        UpdateDSPLYRow(16);
                    }
                    else
                    {
                        // 'G' Output Range = '%'
                        UpdateDSPLYRow(17);
                    }
                }

            }

            // Position Cursor to show user where editting point is.
            lcd_goto_position(dspl_row,dspl_col);

            break;

        default:

            main_state = 0;

            break;

        break;

    }// END switch main_state(main_state)

    //Get_Ser_Command();

} // END Main Loop.

return 0;

} //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Post a Reply

Please log in to post a reply.

Did you know that you can impress a loved one with a digitally-controlled Valentine's Day Card with randomly twinkling LEDs? Learn more...