 |
 |
| View previous topic :: View next topic |
| Author |
Message |
aldina
Joined: 09 Oct 2009 Posts: 26
|
|
Posted: Mon Sep 28, 2015 4:41 pm |
|
|
It could be a fault with WDT? I don't know more I should think or make.
Code seems so easier... and I can't see where is the problem.
I appreciate all of your help and thoughts.
Really thank you |
|
 |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 28, 2015 4:45 pm |
|
|
I didn't see much that was wrong with your compiler version, compared
to vs. 5.049. The little differences would not affect your problem.
I noticed one thing about the logic of your program. In Pisca(), you
call the Right(), Left(), and SpeedH() functions and get values, and then
you execute an if() or else-if() statement based on those values. You
then in some cases, call another function. Example:
You said that the 101 case is one of the problem cases.
| Code: | // 101 *** PROBLEM ***
else if(RH_Signal >= 400 && LH_Signal < 400 && Hex >= 400) // 101
{
OUTPUT_HIGH(PIN_A5); // ON direito
OUTPUT_HIGH(PIN_A4); // ON esquerdo
printf("Case:011, Picsa: 1 1 \r");
T_OFF_RC();
}
|
The code above then calls the function below. But I noticed these things:
1. The function below calls Right() again. What if the value returned
by Right() is different than the value that caused case 101 to be executed ?
2. To execute case 101, RH_Signal must be >= 400.
But in the code below, you are checking to see if RH_Signal is < 400.
Why ? What if the first call to Right() in Pisca() gets a RH value of 400
but then in case 101 it calls Right() again and gets 399 ? Or what if it
gets 401 ? What is the purpose of this code ?
3. You report problems only when the relay is energised (I assume).
A relay has contacts that have noise. The relay coil stores energy.
If you are missing the diode across the relay, you will get a voltage spike
that could damage the relay driver chip. Or even if you have diode, it
will dump the spike into the power supply rail. If your voltage regulator
can't regulate the load voltage very well, you power rail (+5v ?) will be
affected. This may be a cause of your problem.
| Code: |
// The following function is only called for these input levels:
// else if(RH_Signal >= 400 && LH_Signal < 400 && Hex >= 400) // 101
void T_OFF_RC()
{
int16 RH_OFF;
int16 x = 0;
while (true)
{
restart_wdt();
RH_OFF = 0;
RH_OFF = Right(); // *** Calls the Right() function AGAIN. Why ?
delay_us(10);
if (RH_OFF < 400) // *** Why the OPPOSITE of RH_Signal above ?
{
OUTPUT_LOW(PIN_A5); // OFF direito
OUTPUT_HIGH(PIN_A4); // ON esquerdo
printf("T_OFF_RC: 1 0 \r");
delay_ms(20);
x++;
if (x>=35) break; // 35*20ms = 700ms --> SAI
}
else
{
break;
}
}
} |
|
|
 |
aldina
Joined: 09 Oct 2009 Posts: 26
|
|
Posted: Mon Sep 28, 2015 5:42 pm |
|
|
The logic i'm thinking is:
If input speed is >= 400 (about 2V) then A4 and A5 outputs are High and they will be HIGH while not Right() or Left(),
As soon as Right() or Left() return a value >= 400, it means that relay is ON, then outputs (A5 andor A4) stay High while relay is ON, That's why I call T_OFF function and see again the value or Right() ou Left() to know when the ralay is OFF and turn OFF outputs according.
Maybe I'm not thinking correct, but was the way I found to know when relay is ON or OFF when it has input speed high.
I know that when it has no speed signal input is easier because as soon as is has relay signal it goes up (HIGH) and then goes down (LOW) when relay turns OFF,
You ask:
| Quote: |
The code above then calls the function below. But I noticed these things:
1. The function below calls Right() again. What if the value returned
by Right() is different than the value that caused case 101 to be executed ? |
Yes, above code tests 101 status, then in the T_OFF_RC() tests 001. It means Right input LOW because relay is OFF, so A5 output should be LOW until a new rise up of relay or untill time < 700ms.
| Quote: | 2. To execute case 101, RH_Signal must be >= 400.
But in the code below, you are checking to see if RH_Signal is < 400.
Why ? What if the first call to Right() in Pisca() gets a RH value of 400
but then in case 101 it calls Right() again and gets 399 ? Or what if it
gets 401 ? What is the purpose of this code ? |
Input is always >>> 400 (it is a voltage near to 5V) when relay is On, or <<<<400 (near to 0V) when relay is off.
| Quote: | 3. You report problems only when the relay is energised (I assume).
A relay has contacts that have noise. The relay coil stores energy.
If you are missing the diode across the relay, you will get a voltage spike
that could damage the relay driver chip. Or even if you have diode, it
will dump the spike into the power supply rail. If your voltage regulator
can't regulate the load voltage very well, you power rail (+5v ?) will be
affected. This may be a cause of your problem. |
You mean I should have a diode across the contacts of the relay? I have no one. I know it is necessary when we have relays or motors (coil) in the microcontroler outputs, so is logic that the same effect could happen when we use it to microcontroler inputs, So I will try with a diode accross coil terminals of the relay.
Thank you again |
|
 |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 28, 2015 5:54 pm |
|
|
There are two types of relay protection circuits:
1. Flywheel diode across the coil.
2. RC snubber circuit across the contacts.
I was talking about #1. |
|
 |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Mon Sep 28, 2015 6:18 pm |
|
|
WHAT FREE version?
| Code: |
#include <12F1822.h>
#device ADC=10
#fuses INTRC_IO,WDT,NOMCLR,PROTECT,BROWNOUT,NOPUT
#use delay(clock=4000000)
#BYTE OSCCON = 0x119 //OSCCON register (pg 26 datasheet)
//#BYTE WDTCON = 0x117 //WDTCON (pg 26 datasheet)
#include <stdlib.h>
#include <math.h>
// Ler speed
int16 Speed_H()
{
int8 i;
int16 speed;
int16 speed_sum;
int16 speed_average;
speed = 0;
speed_sum = 0;
speed_average = 0;
set_adc_channel(2);
delay_us(5);
for(i=0;i<16;i++)
{
speed = read_adc();
speed_sum += speed;
}
speed_average = speed_sum/16;
return speed_average;
}
// Ler sinal Direito
int16 Right()
{
int8 i;
int16 RH;
int16 RH_sum;
int16 RH_average;
RH = 0;
RH_sum =0;
RH_average = 0;
set_adc_channel(0);
delay_us(5);
for(i=0;i<16;i++)
{
RH = read_adc();
RH_sum += RH;
}
RH_average = RH_sum/16;
return RH_average;
}
// Ler sinal Esquerdo
int16 Left()
{
int8 i;
int16 LH;
int16 LH_sum;
int16 LH_average;
LH = 0;
LH_sum = 0;
LH_average = 0;
set_adc_channel(1);
delay_us(5);
for(i=0;i<16;i++)
{
LH = read_adc();
LH_sum += LH;
}
LH_average = LH_sum/16;
return LH_average;
}
// Função TOFF 4
void T_OFF4()
{
int16 LH_OFF, RH_OFF;
int8 x = 0;
while (true)
{
restart_wdt();
LH_OFF = 0;
RH_OFF = 0;
LH_OFF = Left();
RH_OFF = Right();
//delay_us(10);
if(RH_OFF < 400 || LH_OFF < 400)
{
OUTPUT_LOW(PIN_A5); // OFF direito
OUTPUT_LOW(PIN_A4); // OFF esquerdo
delay_ms(20);
x++;
if (x>=35) break; // 35*20ms = 700ms --> SAI
}
return;
} // while
} // main
// Função TOFF R
void T_OFF_RS()
{
int16 RH_OFF;
int8 x = 0;
while (true)
{
restart_wdt();
RH_OFF = 0;
RH_OFF = Right();
//delay_us(10);
if (RH_OFF < 400)
{
OUTPUT_LOW(PIN_A5); // OFF direito
OUTPUT_LOW(PIN_A4); // OFF esquerdo
delay_ms(20);
x++;
if (x>=35) break; // 35*20ms = 700ms --> SAI
}
return;
} // While
} // main
void T_OFF_RC()
{
int16 RH_OFF;
int8 x = 0;
while (true)
{
restart_wdt();
RH_OFF = 0;
RH_OFF = Right();
//delay_us(10);
if (RH_OFF < 400)
{
OUTPUT_LOW(PIN_A5); // OFF direito
OUTPUT_HIGH(PIN_A4); // ON esquerdo
delay_ms(20);
x++;
if (x>=35) break; // 35*20ms = 700ms --> SAI
}
return;
} // While
} // main
// Função TOFF L
void T_OFF_LS()
{
int16 LH_OFF;
int8 x = 0;
while (true)
{
restart_wdt();
LH_OFF = 0;
LH_OFF = Left();
//delay_us(10);
if (LH_OFF < 400)
{
OUTPUT_LOW(PIN_A5);
OUTPUT_LOW(PIN_A4);
delay_ms(20);
x++;
if (x>=35) break; // 35*20ms = 700ms --> SAI
}
return;
} // while
} // main
// Função TOFF L
void T_OFF_LC()
{
int16 LH_OFF;
int8 x = 0;
while (true)
{
restart_wdt();
LH_OFF = 0;
LH_OFF = Left();
//delay_us(10);
if (LH_OFF < 400)
{
OUTPUT_HIGH(PIN_A5);
OUTPUT_LOW(PIN_A4);
delay_ms(20);
x++;
if (x>=35) break; // 35*20ms = 700ms --> SAI
}
return;
} // while
} // main
// Função pisca C
void PiscaC()
{
int16 RH_Signal, LH_Signal;
while (true)
{
RH_Signal = 0;
LH_Signal = 0;
RH_Signal = Right();
LH_Signal = Left();
if(RH_Signal >= 400 && LH_Signal >= 400) // 111
{
OUTPUT_HIGH(PIN_A5); // ON direito
OUTPUT_HIGH(PIN_A4); // ON esquerdo
T_OFF4();
}
else if(RH_Signal >= 400 && LH_Signal < 400) // 101
{
OUTPUT_HIGH(PIN_A5); // ON direito
OUTPUT_HIGH(PIN_A4); // ON esquerdo
T_OFF_RC();
}
else if(RH_Signal < 400 && LH_Signal >= 400) // 011
{
OUTPUT_HIGH(PIN_A5); // ON direito
OUTPUT_HIGH(PIN_A4); // ON esquerdo
T_OFF_LC();
}
else // 000
{
break;
}
}
}
// Função pisca S
void PiscaS()
{
int16 RH_Signal, LH_Signal;
while (true)
{
RH_Signal = 0;
LH_Signal = 0;
RH_Signal = Right();
LH_Signal = Left();
if(RH_Signal >= 400 && LH_Signal >= 400) // 110
{
OUTPUT_HIGH(PIN_A5); // ON direito
OUTPUT_HIGH(PIN_A4); // ON esquerdo
T_OFF4();
}
else if(RH_Signal >= 400 && LH_Signal < 400) // 100
{
OUTPUT_HIGH(PIN_A5); // ON direito
OUTPUT_LOW(PIN_A4); // OFF esquerdo
T_OFF_RS();
}
else if(RH_Signal < 400 && LH_Signal >= 400) // 010
{
OUTPUT_LOW(PIN_A5); // OFF direito
OUTPUT_HIGH(PIN_A4); // ON esquerdo
T_OFF_LS();
}
else // 000
{
break;
}
}
}
// ****** MAIN ******* //
void main(void)
{
int16 HEXA;
OSCCON=0x61; //registo OSCCON 61->4MHZ, 71->8MHZ
setup_adc_ports(SAN0 | SAN1 | SAN2);
setup_adc(ADC_CLOCK_DIV_16); // ver pág.143 datasheet - Tconv = 16/4M = 4us por amostra
//setup_adc(ADC_CLOCK_INTERNAL);
// Configuração das saídas
output_low(PIN_A5); //Saida para sector Lateral Direito
output_low(PIN_A4); //Saida para sector Lateral Esquerdo
// Configuração das entradas
// A0 - Entrada AN0 para leitura do sinal lado Direito
// A1 - Entrada AN1 para leitura do sinal lado Esquerdo
// A2 - Entrada Digital para leitura do sinal Speed
// A3 - Entrada Digital para leitura do sinal de presença
SET_TRIS_A(0x07); // 00000111 - 0x07 - ainda sem entrada de SM no MCLR (A3)
while (true)
{
restart_wdt();
HEXA = 0;
HEXA = Speed_H();
if(HEXA >= 400) // A2 - HIGH
{
OUTPUT_HIGH(PIN_A5); // OFF direito
OUTPUT_HIGH(PIN_A4); // OFF esquerdo
PiscaC();
}
if(HEXA < 400) // A2 - LOW
{
OUTPUT_LOW(PIN_A5); // OFF direito
OUTPUT_LOW(PIN_A4); // OFF esquerdo
PiscaS();
}
} // while
} // main
|
Is it possible that problem will be in my free version? Can someone compile my code to try?
I have a .exe version - 4.128, I can try it |
|
 |
aldina
Joined: 09 Oct 2009 Posts: 26
|
|
Posted: Mon Sep 28, 2015 6:26 pm |
|
|
I will try with diode.
And, did you understand my explanation about your 3 questions?? |
|
 |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Sep 29, 2015 2:50 am |
|
|
I find the program very difficult to understand, here are some tips to make it easier for other people read your code:
- Write your program in English (comments and variable names).
- Write a short comment at the head of your program about what it is doing.
- Do not duplicate code. Two times almost identical code is allowed, but when you have three times the same code sequence it should be replaced by 1 generic function.
- Be consistent with the use of upper and lower case. A general guideline is to use lower case for function names and variables. A constant is written with all upper case. Bad examples in your code: LH_OFF, true, OUTPUT_LOW() and others.
- Try to write code that documents itself (this will get better when you have more experience). One great help here is to avoid 'magic numbers'. Example: | Code: | output_low(PIN_A5); //Saida para sector Lateral Direito
output_low(PIN_A4); //Saida para sector Lateral Esquerdo
| Can be rewritten as: | Code: | #define MOTOR_LEFT PIN_A5
#define MOTOR_RIGHT PIN_A4
output_low(MOTOR_LEFT); // Left off
output_low(MOTOR_RIGHT); // right off | or, really nice:
| Code: | #define MOTOR_LEFT PIN_A5
#define MOTOR_RIGHT PIN_A4
#define STAND_STILL output_low(MOTOR_LEFT); output_low(MOTOR_RIGHT);
#define GO_LEFT output_high(MOTOR_LEFT); output_low(MOTOR_RIGHT);
#define GO_RIGHT output_low(MOTOR_LEFT); output_high(MOTOR_RIGHT);
#define GO_STRAIGHT output_high(MOTOR_LEFT); output_high(MOTOR_RIGHT); | Do this for your other pins as well.
Avoid unnecessary comments: | Code: | | SET_TRIS_A(0x07); // 00000111 - 0x07 - ainda sem entrada de SM no MCLR (A3) | Can be rewritten as: | Code: | | set_tris_a(0b00000111); // ainda sem entrada de SM no MCLR (A3) |
Also, get rid of the the watchdog. It's a great feature for life critical systems, but in all other products a watchdog introduces more problems than it solves. When needed, you can always add it later when everything else is working. |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|