Undefined switch-cse function problem???

General discussion on mikroC PRO for PIC.
Post Reply
Author
Message
SerpentInst
Posts: 4
Joined: 18 Jun 2021 20:13

Undefined switch-cse function problem???

#1 Post by SerpentInst » 20 Jun 2021 14:06

Hi there, I'm new to this forum and relatively new to programming in general since my primary work was in RF.
I bought mikroC licence two years ago and got quite into PIC series chips projects, building about 20 different projects in that time, mostly in field of automatics and industrial control (temperature, pressure, DC servo motor drivers and stuff like that). But here is my new problem, and the one I could not solve.
I'm designing PID temperature controller for 5kW induction crucible (also of my design). Since I have 10-11 16F877 obsolete controllers laying around, but the design is not demanding at all, and I need to build seven crucibles, I opted for designing simple controller with PIC16F877, HD44780 4x20 LCD display, MAX31855 K-type probe temperature reader and one CP2102 UART-USB converter so I could simply send commands and receive back parameters from controller. Only non-uart controls are simple rotary encoder for setting the temperature, and two pushbuttons for start and stop of heating. I'm also using the pushbutton on the encoder connected to RB0 interrupt for saving set temperature to EEPROM. All functions in code I wrote, and the only one from mikroC library I'm using is the LCD one. Also I'm using 8 digital inputs (for reading possible faults in induction crucible) and 7 outputs (for turning on/off high frequency generator, AC and softstart relays, cooling FAN and alarm buzzer, and two lamps inside START and STOP pushbuttons).

Here's the main idea. Interrupt handler is handling 4 interrupts. RBIF interrupt for encoder reading (A and B inputs connected to RB4 and RB7 pins), INTF interrupt for reading the encoder button (it saves set temperature value to EEPROM) and timer1 interrupt generating precize 50ms ticker I'm using for timing MAX31855 reading (on every 20th tick), PID routine (on every 200th tick), and also simple generation of 10sec periode PWM with 0...200 input for turning on and off the high frequency generator. Also there is RCIF interrupt for UART reception.

So every second I read MAX31855 and display the temperature value on the LCD. Every 10th second I find error, sum error and difference error for my PID routine and also initiate one, in the same time i refresh duty cycle value to the new PID value. And all of this is working like charm. But there is a problem with UART control of the system.

Idea is quite simple, to send to controller different commands via UART and got it to do stuff, here is the manual:
1. send "P?" (CRLF) and controller returns value of Kp (via UART) in form long vlaue from 00000 to 99999.
2.sned "P=xxxxx" (CRLF) [xxxxx is a number from 00000 to 99999] and controller reads send number saves it to EEPROM, change Kp to new value and returns "OK" via UART.
3. same for I
4. same for D
5. send "RY"(CRLF), activates UART returning temperature value on every MAX31855 read (every second, controlled via timer interrupt as I mentioned above), and saves activation bit for that function to EEPROM, also returns "Activated" via UART.
6. send "RN"(CRLF), terminates UART returning temperature value, saves the activation bit value to EEPROM and returns "Terminated" via UART.

So, RCIF interrupt activates the function that receives 7 bytes of information and if those are followed by CRLF saves those 7 to array 'receive[0...7]' and sets 'rcv' bit. Next in while(1) loop where I'm rolling my code again and again I have if statement where I check 'rcv' bit and if it is high I start 'work_prim()' function and resets te rcv bit.
And finally I got to my problem, I wrote work_prim() function as stacked switch case, and I'm sending you here the code that is actually working but I have strange problem. So ccode works as it supposed to everything is fine before I add the piece you are about to see in attached text file with the function. If someone has the idea why is that please help me since I've tried everything and after simple adding 'default:' to third switch case statement code fails. Also I have to mention here that the same code is working perfectly fine with this piece added if I rewrote it to MPLab IDE version 2.30, and compile it via XC8 version 1.34, but in mikroC it compiles, but fails working.
Attachments
function work_prim().pdf
(108 KiB) Downloaded 55 times

paulfjujo
Posts: 1544
Joined: 24 Jun 2007 19:27
Location: 01800 St Maurice de Gourdans France
Contact:

Re: Undefined switch-cse function problem???

#2 Post by paulfjujo » 21 Jun 2021 14:17

hello,




if you encounter defaut :
you must go out of the switch loopwith a break (inside switch loop)

Code: Select all

......
  default: //If receive[1] is not recognised:
      UART_write_string(2,"??"); //Return "??" via serial port.
     break;
     }
   case 73: //If receive[0] = "I"
....

SerpentInst
Posts: 4
Joined: 18 Jun 2021 20:13

Re: Undefined switch-cse function problem???

#3 Post by SerpentInst » 23 Jun 2021 01:37

@ paulfjujo
I did as you recommended but then code stopped working at all. Controller just displays opening message and then stops doing anything.
I also tried checking mikroC manual for using switch-case statement, and there isn't anything about 'break' after 'default'.
Scheme they give (also used in other C languages) is:

switch (parameter) {
case parameter value 1: code; break;
case parameter value 2: code; break;
default: code;
}

And I double checked my code, every of switch-case I used, I used in this exact way. Also there is the thing that the code works in MPLab but not MikroC.

paulfjujo
Posts: 1544
Joined: 24 Jun 2007 19:27
Location: 01800 St Maurice de Gourdans France
Contact:

Re: Undefined switch-cse function problem???

#4 Post by paulfjujo » 23 Jun 2021 17:33

hello,

Difficult to read a source in PDF ..

you are using interrupts and
switch case loop enlosed other sub switch case loop .. with a 16F MCU


i think you get stack problems ...
a PIC18F could be more flexible.

maybe in Maplab version somme parameters are not the same as in mikroC

MPLABX is more consise with the use of volatile or static ram variable used in interrupts ,or main program..

using "state machine" style could give a more light program ..

SerpentInst
Posts: 4
Joined: 18 Jun 2021 20:13

Re: Undefined switch-cse function problem???

#5 Post by SerpentInst » 23 Jun 2021 23:53

It seems my first idea (before I even posted first post to this forum) was right. 16F is quite poor, but with good enough programing skills it can do quite a few things.
I surpassed mentioned problem in MikroC in quite brutal way and that is I threw all of those default messages and entered a bit in code I'm setting to one in every default case. Then outside of stacked switch-case I have if statement checking the state of mentioned bit. If it's HI then i activate UART response. It's so subtle way like killing the house spider with a nuclear bomb :mrgreen: but I couldn't find any better. Yet this is first version of the code for mentioned control. I'm gonna make it better in few more days, in means of using less RAM, less ROM, and speeding up the code. As I mentioned It is working now with about 66% RAM used and 57% ROM used. Also yesterday I connected my first prototype form bench testing to induction crucible to set and test PID action, and I'm quite pleased how it worked. It is regulating temperature in the band of +/-2C in ~1000C range (crucible is primary used for melting gold and silver scrap) and that is better than needed. Maybe I implement 'take back half' regulation method instead of PID, since it is less complicated to operate and adjust and gives just fine performance especially for temperature regulation.

hibakhouloud.baadech@esprit.tn
Posts: 1
Joined: 08 Dec 2023 20:39

i see that when i add dispaly_ms in void interrupt the program don't run in isis so i add flag variable and dislay messa

#6 Post by hibakhouloud.baadech@esprit.tn » 08 Dec 2023 20:43

//config

sbit LCD_D7 at RD7_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_RS at RD1_bit;
sbit LCD_EN at RD0_bit;



sbit LCD_D7_Direction at TRISD7_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_RS_Direction at TRISD1_bit;
sbit LCD_EN_Direction at TRISD0_bit;

sbit validerA at RB0_bit;
sbit validerC at RB1_bit;
sbit CanetteButton at RB4_bit;
sbit BiscuitButton at RB5_bit;
sbit remplirC at RB6_bit;
sbit remplirB at RB7_bit;

sbit CanetteMotor at RA5_bit;
sbit BiscuitMotor at RA4_bit;

sbit Buzzer at RA3_bit;

sbit capteurLum at RA2_bit;

sbit LEDlum at RC0_bit;
sbit LEDcanette at RC1_bit;
sbit LEDbiscuit at RC2_bit;

unsigned int stockC ;
unsigned int stockB ;


void delay_ms(unsigned int ms) {
unsigned int i, j;
for(i = 0; i < ms; i++) {
for(j = 0; j < 46; j++) {
}
}
}

char flag=0;
int NB;
void main() {

//EEPROM_Init();

TRISA = 0b111100;
TRISB = 0b11110011;
TRISC = 0b00000111;
TRISD = 0;

intcon.GIE = 1;
intcon.RBIE = 1;
intcon.RBIF = 0;
intcon.INTE = 1;
intcon.T0IE= 1;
TMR0=0;
option_reg= 0b01000111;

NB=152; //5000000/(256*4/8*256)


PORTA = 0;
PORTB = 0;
PORTC = 0;
PORTD = 1;

LEDlum = 0;
LEDcanette = 0;
LEDbiscuit = 0;
CanetteMotor = 0;
BiscuitMotor = 0;
Buzzer = 0;

Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
while(1){


Lcd_Out(1, 1, "Sélectionner un");
Lcd_Out(2, 1, "produit.");
Lcd_Cmd(_LCD_CLEAR);
if(flag==1){
Lcd_Out(2, 1, "Canette");
Delay_ms(2000);
}
if(flag==2){
Lcd_Out(2, 1, "Biscuit");
Delay_ms(2000);
}
if(flag==3){
Delay_ms(5000);
Lcd_Cmd(_LCD_CLEAR);
}
if(flag==4){
Delay_ms(2000);
}
if(flag==5){
Delay_ms(5000);
}
if(flag==6){
Lcd_Out(2, 1, "Annuler");
Lcd_Cmd(_LCD_CLEAR);
}

if(capteurLum==1){
LEDlum==1;
delay_ms(1000);
}
if(capteurLum==0){
LEDlum==0;
delay_ms(1000);
}
}
}






void interrupt (){


if(intcon.INTF==1){

if(stockC > 0) {
EEPROM_Write(0x00, stockC);
stockC = 0;
}

if(stockB > 0) {

EEPROM_Write(0x01, stockB);
stockB = 0;
}

intcon.INTF=0;}


if(intcon.RBIF==1){
if(CanetteButton==1){
flag=1;
}

if(BiscuitButton==1){
flag=2;
}

if(validerC==1){
flag=3;
intcon.T0IE=0;
if(CanetteButton==1){
LEDcanette=1;
flag=4;
LEDcanette=0;
CanetteMotor = 1;
stockC--;}

if(BiscuitButton==1){
LEDbiscuit=1;
flag=4;
LEDbiscuit=0;
BiscuitMotor = 1;
stockB--;}
}
if(stockC==0 || stockB==0){
Buzzer=1;
flag=5;}




// ajustement du stock
if(remplirC == 1) {
stockC++;
}

if(remplirB == 1) {
stockB++;
}

intcon.RBIF=0;}




if(intcon.T0IF==1){
NB--;
if(nb==0){
if(validerC==0){
flag=6; }
NB=152;
TMR0=0; }
intcon.T0IF=0;}


}

Post Reply

Return to “mikroC PRO for PIC General”