Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

PIC Code Check Help

Status
Not open for further replies.

electronicnoob

Junior Member level 1
Joined
Jul 4, 2019
Messages
19
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
142
Hi, I'm doing a project which is an etching tank. I'm using a PIC16F887 and a RTC 3231 to keep time. I plan to control the temperature by controlling the phase firing delay. I am using IOC on pin RB2 to read the zero crossing circuit and sending a pulse to RB3 to turn on the heater. I am also using external interrupt on pin RB0 to turn on/off the air pump for agitation connected to a relay with the output at RB1. I am monitoring the temperature using a lm35 temperature sensor and ADC on pin RA5. I have more code on the matrix keypad but I don't have any problem with it.

C:
#pragma config CONFIG1 = 0x2CD2
#pragma config CONFIG2 = 0x0700
#include <xc.h>
#define _XTAL_FREQ 20000000
#include <stdint.h>        // include stdint header
#include "LCD_Lib.c"       // include LCD driver source file

// variables declaration
uint8_t  i, second, minute, hour, m_day, month, year;
int mintemp, maxtemp, midtemp;
uint8_t templvl;
uint16_t  duration = 0;
uint32_t  StartTime, TimeNow, EndTime;
static int td = 0;
uint16_t AN0RES=0;
int Temp;
char TempSTR[16];
static char TempPrint[] = "     \337C";
int a,b,c,d,t,u;

void RTC()
{
  // convert data from BCD format to decimal format
  second = bcd_to_decimal(second);
  minute = bcd_to_decimal(minute);
  hour   = bcd_to_decimal(hour);
  m_day  = bcd_to_decimal(m_day);
  month  = bcd_to_decimal(month);
  year   = bcd_to_decimal(year);
  // end conversion
  TimeNow = (hour*3600)+(minute*60)+second;
}

void CheckCurrentTime(void)
{
    I2C_Init(100000);   // initialize I2C bus with clock frequency of 100kHz

    // read current time and date from the RTC chip
    I2C_Start();           // start I2C
    I2C_Write(0xD0);       // RTC chip address
    I2C_Write(0);          // send register address
    I2C_Repeated_Start();  // restart I2C
    I2C_Write(0xD1);       // initialize data read
    second = I2C_Read(1);  // read seconds from register 0
    minute = I2C_Read(1);  // read minutes from register 1
    hour   = I2C_Read(1);  // read hour from register 2
    I2C_Read(1);           // read day from register 3 (not used)
    m_day  = I2C_Read(1);  // read date from register 4
    month  = I2C_Read(1);  // read month from register 5
    year   = I2C_Read(0);  // read year from register 6
    I2C_Stop();            // stop I2C

    RTC();    // print time & date
}
/**************************  end RTC chip functions ***************************/
/*************************** Phase Firing Functions ***************************/
void initPhase(void);
void Pause(int);

void initPhase(void)
{
    PORTB  = 0;
    ANSELH = 0x00;
    TRISBbits.TRISB0 = 1;
    TRISBbits.TRISB2 = 1;
    TRISBbits.TRISB3 = 0;
    WPUB = 0b00000001;
    IOCB = 0x04;
    OPTION_REGbits.nRBPU = 1;            // clear RBPU bit (OPTION_REG.7)
    OPTION_REGbits.INTEDG = 1;
   
    INTCONbits.GIE = 1; //global interrupt enable
    INTCONbits.PEIE = 0; //disable peripheral interrupts (PEIE)
    INTCONbits.RBIE = 1;
    INTCONbits.INTE = 1;//For external interrupt (RB0/INT)PORTB  = 0;
}

void light(int X)
{
    Pause(X);
    PORTBbits.RB3 = 1;
    __delay_ms(0.5);
    PORTBbits.RB3 = 0;
}

void Pause(int microseconds)
{
    while(microseconds > 0)
    {
      __delay_us(100);
      microseconds = microseconds - 100;
    }
}

void __interrupt () isr()
{
    if (INTCONbits.RBIF == 1)
    {
        if (PORTBbits.RB1 == 1)
        {
            __delay_ms(1);
            light(td);
        }
        else
            light(td);
    }
    if (INTCONbits.INTF == 1)
    {
        if(PORTBbits.RB1 == 1)
        {
            PORTBbits.RB1 = 0;
        }
        else if (PORTBbits.RB1 == 0)
        {
            PORTBbits.RB1 = 1;
        }
        INTCONbits.INTF = 0;
    }    
}
/************************* End Phase Firing Functions *************************/
/************************* Temperature ADC Functions  *************************/
void InitADC(void);
uint16_t ADC_Read(void);
void CheckCurrentTemp(void);

void InitADC(void)
{
    ADCON0 = 0x91;
    ADCON1 = 0x80;
    PORTA  = 0x00;
    TRISA  = 0x20;
    ANSEL  = 0x10;
}

uint16_t ADC_Read(void)
{
    ADCON0 = 0x91;
    __delay_us(30);  
    GO_DONE = 1;               // Start A/D Conversion
    while(ADCON0bits.GO_DONE); // Polling GO_DONE Bit
    return ((ADRESH<<8)+ADRESL);
}

void CheckCurrentTemp(void)
{
    AN0RES = ADC_Read();               // Read Analog Channel 4
    Temp = AN0RES * 48.828;
    Temp = Temp + 200;
    sprintf(TempSTR, "%4d", Temp); // Convert The Temperature From Float To String
    LCD_Cmd(LCD_CLEAR);
   
    TempPrint[0]=TempSTR[0];
    TempPrint[1]=TempSTR[1];
    TempPrint[2]= '.';
    TempPrint[3]=TempSTR[2];
    TempPrint[4]=TempSTR[3];
     
    LCD_Goto(1, 1);
    LCD_Print("Temperature");  
    LCD_Goto(1, 2);  
    LCD_Print(TempPrint);
}
/************************* Temperature ADC Functions  *************************/

void main(void)
{
    a = b = t = c = d = 0;
    templvl = 10;
    static char Duration[3];
    static char TempLVL[16];
    char Key = 'n';
   
    LCD_Begin();
    Clock();
   
    InitKeypad();
   
    LCD_Cmd(LCD_CLEAR);
   
    // enter etching temperature
    while (templvl > 3)
    {
        c = 0;
        LCD_Cmd(LCD_CLEAR);
        LCD_Goto(1, 1);
        LCD_Print("Set Temp level");
        LCD_Goto(1, 2);
        LCD_Print(" 0 , 1 , 2 , 3 ");
        Key = switch_press_scan_num();  
        TempLVL[0] = Key;
        LCD_Cmd(LCD_CLEAR);
        LCD_Goto(1, 1);
        LCD_Print("Set Temp level");

        LCD_Goto(1, 2);
        LCD_Print(TempLVL);
        __delay_ms(750);
        LCD_Cmd(LCD_CLEAR);
        templvl = atoi(TempLVL);
        if (templvl >= 4)
        {
            LCD_Goto(1, 1);
            LCD_Print("Invalid Input");
            __delay_ms(750);
            while (c<=1)
            {
                TempLVL[c]=' ';
                c++;
            }
            continue;
        }    
    }
    LCD_Cmd(LCD_CLEAR);
    if (templvl == 0)
    {
        LCD_Goto(1,1);
        LCD_Print("Please turn OFF");
        LCD_Goto(1,2);
        LCD_Print("the Heater");
        __delay_ms(1000);
        LCD_Cmd(LCD_CLEAR);
    }
    // end etching temperature input
   
    if(templvl == 1)
    {
        mintemp = 3500;  // minimum temp of Temperature Level 1
        midtemp = 3600;
        maxtemp = 3800;
        td = 5100;
    }
    if(templvl == 2)
    {
        mintemp = 3900;
        midtemp = 4000;
        maxtemp = 4100;
        td = 5800;
    }
    if(templvl == 3)
    {
        mintemp = 4200;
        midtemp = 4300;
        maxtemp = 4500;
        td = 6200;
    }

    // enter etching duration
    LCD_Goto(1, 1);
    LCD_Print("Enter Duration");
    while(t<2){
        Key = switch_press_scan_num();
        if ((Key == '#')&&(t>0))
        {  
            Duration[t-1]=' ';
            LCD_Goto(1, 2);
            LCD_Printr(Duration);
            __delay_ms(200);
            t--;
        }
        else if (Key != '#')
        {
            LCD_Goto(1, 2);
            Duration[t] = Key;
            LCD_Printr(Duration);
            __delay_ms(200);
            t++;
        }
    }
    //end etching duration input
    duration = atoi(Duration);
    duration = duration * 60;
    LCD_Cmd(LCD_CLEAR);
   
    CheckCurrentTime();
    StartTime = TimeNow;
    EndTime = StartTime + duration;
   
    LCD_Goto(1,1);
    LCD_Print("Starting Etching");
    LCD_Goto(1,2);
    LCD_Print("Process");
    __delay_ms(1000);
    InitADC();
    PORTBbits.RB1 = 0;                  //turn on air pump

    LCD_Cmd(LCD_CLEAR);
   
    CheckCurrentTemp();
   
    /*while((Temp <= midtemp)&&(TimeNow <= EndTime))
    {
        PORTBbits.RB3 = 1;
        __delay_ms(1000);
        CheckCurrentTemp();
    }
    PORTBbits.RB3 = 0;
   
    while((Temp >= midtemp)&&(TimeNow <= EndTime))
    {
        PORTBbits.RB3 = 0;
        __delay_ms(1000);
        CheckCurrentTemp();
    }*/
   
    PORTBbits.RB3 = 0;
   
    initPhase();
    while (TimeNow <= EndTime)
    {
        d = 0;
        while((d<=200)&&(TimeNow <= EndTime))
        {
            CheckCurrentTime();
            __delay_ms(100);
            d++;
        }
        CheckCurrentTemp();
        if (Temp > maxtemp)
        {
            td -= 100;
        }
        else if (Temp < maxtemp)
        {
            td += 100;
        }
        else
        {
            td = td;
        }
        CheckCurrentTime();
    }
    INTCONbits.GIE = 0;
    PORTBbits.RB1 = 1;                  //turn off air pump      
   
    LCD_Goto(1,1);
    LCD_Print("Etching Process");
    LCD_Goto(1,2);
    LCD_Print("Complete");

However, when programmed an turned on, the code sometimes freezes after I run the CheckCurrentTemp(), for the first time. I am still able to turn on and off the air pump via RB) interrupt but other than that the program isn't running. By that time, the program doesn't even check the time and keep on running even though the time is supposed to be over. For now, my duration is set in seconds instead of minutes because for testing purposes.

Thank you for your time and I would really appreciate your help. Thanks in advance.
 

hello,

one IF to remove...
check also if this PIC use LAT instead PORT for output
or maybe problem with consecutive Read/write on same port can occurs

Code:
if (INTCONbits.INTF == 1)
    {
        if(PORTBbits.RB1 == 1)   //  reading 
        {
            _asm NOP;
           PORTBbits.RB1 = 0;    //   writing     LATBbits.RB1=0 ?
        }
        else
        {
           _asm NOP;
         PORTBbits.RB1 = 1;
        }
        INTCONbits.INTF = 0;
    }
 
Last edited:

Hello I have a question, is this a correct way to make sure I make sure the etchant liquid heats up the fastest while monitoring the temperature and time? RB3 is the pin that is connected to the optocoupler for phase firing.

C:
while((Temp < midtemp)&&(TimeNow <= EndTime))
    {
        PORTBbits.RB3 = 1;
        __delay_ms(1000);
        CheckCurrentTemp();
        CheckCurrentTime();
    }
    PORTBbits.RB3 = 0;

    while((Temp > midtemp)&&(TimeNow <= EndTime))
    {
        PORTBbits.RB3 = 0;
        __delay_ms(1000);
        CheckCurrentTemp();
        CheckCurrentTime();
    }

Do I have to use if(Temp> midtemp) and If(Temp<midtemp)?

Thanks in advance!
 

Hi,

It depends what you want to achieve.

I guess this rather is what you want: (pseudocode)

Code:
CheckCurrentTime();
While timenow < timeend
{
   CheckCurrentTemp();
   If (Temp < midtemp)
  {PORTBbits.RB3 = 1;}
    __delay_ms(1000);
    CheckCurrentTime();
    PORTBbits.RB3 = 0;
}

If not, show your flow chart. You should have drawn it already ;-)

Klaus
 

Actually the main reason I do this is because I want to speed up the heating of the etchant by turning on the optocoupler without checking for the zero volt crossing, until it reaches Midtemp. And if the temperature of the etchant is already higher than midtemp, then I want to make sure it is turned off until I reach midtemp. thats why I call my initPhase function later to maintain the temperature.
Annotation 2020-07-26 221759.jpg
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top