Page 1 of 1

Code not doing as supposed?

PostPosted: Wed Apr 26, 2006 3:29 am
by Code_Nerd
Just wondering if anyone can give me a hand with my code?
It is supposed to simulate a traffic intersection.
~ Main road gets green for 10 second before changing
~ Side road gets green for 10 seconds, but a switch connected to INT0 is counting the cars that cross
~ If more than 10 cars have crossed the side road gets an extra 5 seconds
~ Back to start again..

The tasks are not performing correctly and I am getting no lights on at all atm..
Any ideas would be great

Thankyou

code:
#include <salvo.h>
#include <timers.h>

#define TASK_LIGHTS_P OSTCBP(3)
#define TASK_CARS_P OSTCBP(2)
#define TASK_DELAY_P OSTCBP(1)

#define cnt_msg OSECBP(1)
#define car_val OSECBP(2)
#define car_sig_sem OSECBP(3)
#define time_delay OSECBP(4)
#define delay OSECBP(5)

#define mainR PORTCbits.RC0
#define mainY PORTCbits.RC1
#define mainG PORTCbits.RC2
#define sideR PORTCbits.RC3
#define sideY PORTCbits.RC4
#define sideG PORTCbits.RC5

#define INT0IE INTCONbits.INT0IE
#define INT0IF INTCONbits.INT0IF
#define TMR0IE INTCONbits.TMR0IE
#define TMR0IF INTCONbits.TMR0IF
#define GIE INTCONbits.GIE
#define RBPU INTCON2bits.RBPU

void Lights(void)
{
static char cars, time1;
OStypeMsgP msgP;
TMR0IF = 0;
GIE = 1;

OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_1);

while(1)
{
mainG = 1;
sideR = 1; //Green on Main, Red on Side
OS_Delay(1000, lights1);
time1 = 10;
mainG = 0;
mainY = 1;
OS_Delay(300, lights6);

mainY = 0;
mainR = 1;
sideG = 1;
OSSignalMsg(cnt_msg, (OStypeMsgP)&time1);
OS_Yield(lights2);

OS_WaitMsg(car_val, &msgP, OSNO_TIMOUT, lights3);
cars = *(char *)msgP;

if(cars > 10)
{
time1 = 5;
OSSignalMsg(cnt_msg, (OStypeMsgP) &time1);
OS_Yield(lights4);
OS_WaitMsg(car_val, &msgP, OSNO_TIMOUT, lights5);
}
sideG = 0;
sideY = 1;
OS_Delay(300, lights7);


}
}

void Cars_Count()
{
static unsigned char x, count, tmrcnt;
static char time2;
OStypeMsgP msgP;

msgP = OSTryMsg(cnt_msg);
count = tmrcnt = 0;
if(msgP)
{
time2 = *(char *)msgP;
OSSignalMsg(time_delay, (OStypeMsgP) &time2);
OS_Yield(car_count1);
while(!OSTryBinSem(delay)) //Test for Sem from Delay to signal time is up
{
if(OSTryBinSem(car_sig_sem)) //Sem from RB0 int
count++;
}
}
OSSignalMsg(car_val, (OStypeMsgP) &count); //MessageBox with car count in it
OS_Yield(car_count2); //Yield needed so count value is not altered.
}

void My_Delay(void)
{
OStypeMsgP msgP;
static char time3;

OS_WaitMsg(time_delay, &msgP, OSNO_TIMEOUT, delay1);
time3 = *(char *)msgP;

OS_Delay((100*time3), delay2);
OSSignalBinSem(delay);
}
#pragma interrupt ISR


void main(void)
{
OSInit();
OSCreateTask(My_Delay, TASK_DELAY_P, 1);
OSCreateTask(Cars_Count, TASK_CARS_P, 1);
OSCreateTask(Lights, TASK_LIGHTS_P, 1);


OSCreateMsg(car_val, (OStypeMsgP)0);
OSCreateMsg(time_delay, (OStypeMsgP)0);
OSCreateMsg(cnt_msg, (OStypeMsgP)0);

OSCreateBinSem(car_sig_sem, 0);
OSCreateBinSem(delay, 0);

ADCON1 = 0x07;
TRISB = 0xFF;
TRISC = 0x00;
PORTC = 0;
RBPU = 0;

while(1)
{
OSSched();
}
}

void ISR(void)
{
static char t = 98;

if((TMR0IE == 1) && (TMR0IF == 1))
{
TMR0IF = 0;
--t;

if(t == 0)
{
t = 98;
OSTimer();
}
}
if((INT0IE == 1)&&(INT0IF == 1)) //If RB0 ints enabled and flag is set
{
INT0IF = 0; //Clear RB0 flag
OSSignalBinSem(car_sig_sem); //Set flag variable
}
}

#pragma code IntVectorHigh = 0x08

void IntVectorHigh(void)
{
_asm
goto ISR
_endasm
}


[This message has been edited by Code_Nerd (edited April 26, 2006).]


Re: Code not doing as supposed?

PostPosted: Wed Apr 26, 2006 3:48 am
by aek
A couple of thoughts.

1) Run your tasks at different priorities. That's what priorities are for.

2) When you do 1) above, you must stop using OS_Yield() because o/wise the highest-priority task will always yield to ... itself. There's no need for OS_Yield() in this app -- use OS_Delay() or OS_WaitXyz(). Also, there's no need to / no point in OS_Yield() before OS_WaitXyz() -- it's redundant.

3) The Salvo libraries for the PIC are limited to 8-bit delays, e.g. OS_Delay(1) to OS_Delay(255). OS_Delay(256) is the same as OS_Delay(0) which is the same as OS_Stop(). IOW the delay argument is modulo 256.

4) My_delay() is invalid because it has no infinite loop.

5) #pragma interrupt ISR is in the wrong place.

6) I forget which compiler you're using, but if it's PICC/PICC-18, you need to review the Salvo Compiler Reference Manual for your compiler before you call OSSignalXyz() from an ISR ... Alternately, you can follow the method shown on page 24 of http://www.pumpkininc.com/content/doc/press/pumpkin_supsi2005.pdf in order to avoid callgraph conflicts.

------------------

[This message has been edited by aek (edited April 26, 2006).]


Re: Code not doing as supposed?

PostPosted: Wed Apr 26, 2006 3:52 am
by aek
You can probably implement your algorithm more simply.

And you may be able to use timeouts (change the lib and salvocfg.h entries accordingly) intelligently. E.g. Wait for a certain time, if signaled "early", you're done, o/wise change states when the delay expires.

------------------


Re: Code not doing as supposed?

PostPosted: Wed Apr 26, 2006 8:10 am
by Code_Nerd
Thanks for your reply Aek..
I am just beginning with Salvo RTOS so please forgive some mistakes I may have!

I was under the imnpression that you can create your own length of time for delays? I am creating a 10ms delay using TMR0 and OSTimer() and using this with OS_Delay() (Sorry if my explaination is bad..)

I am using the C18 compiler..

Also I have not come across OS_WaitXyz() in my studies yet, also I was told you need to yield after sending a Message so that the data does not get altered before it is read by the task waiting for the message..

I have not covered timeouts yet either..

Thanks mate


Re: Code not doing as supposed?

PostPosted: Wed Apr 26, 2006 8:54 am
by aek
Yes, you create the basic system tick (in your case, 10ms). But with 8-bit delays, you can delay from 10ms out to 2.55s. Sounds likem you should set your system tick period to, say, 50ms, in which case you can delay out to 12.75s.

The C18 compiler will make your task simpler.

Try to use OS_WaitXyz() -- it'll make your life a lot simpler. But read the manual FAQ about messages and persistence.

------------------


Re: Code not doing as supposed?

PostPosted: Wed Apr 26, 2006 9:05 am
by Code_Nerd
Ahhh ok I got what your saying about the OS_Delay().. So what is happenning when I put 1000 in there? Why is it even compiling?

I will read up on OSWaitxyz() however this is a lab for Uni and we havent covered that yet, so I wont be able to use it..


Re: Code not doing as supposed?

PostPosted: Wed Apr 26, 2006 9:11 am
by aek
It just modulo's your 1000 to 232. No reason to complain, because the argument to OS_Delay() is defined to be 8-bit for the libraries. Some compilers might issue a warning ...

------------------