View previous topic :: View next topic |
Author |
Message |
Sid2286
Joined: 12 Aug 2010 Posts: 119
|
Multi threading |
Posted: Thu Oct 28, 2010 3:39 am |
|
|
I have developed a code where my ADC channels are been scanned.
It is working fine as of now. However I want to generate a clock pulse irrespective of scanning.
Basically I need to multi thread my clock along with the channel scan.
Please help me out!
regards,
sid |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Thu Oct 28, 2010 4:23 am |
|
|
It'd help if you gave an idea of frequencies involved....
Three basic approaches:
1) If clock needs to be fast, use the hardware. CCP.
2) If the clock is slow, then 'time slice'. Generate a 'tick' interrupt (say 100Hz), then have a state machine in the ticks. So for example:
Code: |
enum operations {PULSE_LOW,START_ADC,PULSE_HIGH,READ_ADC,CALC};
operations state=PULSE_LOW;
int16 val;
int1 calc_required=FALSE;
#int_timer2
void tick(void) {
//Arrive here every 100th sec
static int8 wait_for;
switch (state) {
case PULSE_LOW:
output_low(PIN_A0); //Generate low edge
state++;
break;
case START_ADC:
read_adc(ADC_START_ONLY); //Start the ADC conversion
state++;
break;
case PULSE_HIGH:
output_high(PIN_A0); //Generate high edge - 2/100th sec after low
state++;
break;
case READ_ADC:
val=read_adc(ADC_READ_ONLY); //Read the ADC value
state++;
wait_for=20; //20/100ths second pause
break;
case CALC:
calc_required=TRUE;
if (wait_for) --wait_for;
else state=PULSE_LOW; //restart the state machine
break;
}
}
//Then in the main
while(TRUE) {
if (calc_required) {
//Here the state machine is in the 20/100th second pause
//perform the calculations on val
calc_required=FALSE;
}
}
|
Obviously the number of states, timings and operations will need to be adjusted for your needs. Notice though the key thing. Each path through the interrupt, is _quick_. Slow things like arithmetic are done in the external code. The ADC hardware performs the conversion, while other things are going on. etc..
3) Look at the RTOS instructions in the compiler. More flexible, but more overhead.....
Best Wishes |
|
|
Sid2286
Joined: 12 Aug 2010 Posts: 119
|
thank you for your reply |
Posted: Thu Oct 28, 2010 10:25 pm |
|
|
I have pic18f452. Right now I'm only able to use 4 channel out of 8 channels of ADC.
My problem is I'm falling short on ports and I'm clueless on how to utilize them.
The reason I'm falling short is as follows:-
1. Port D is dedicated to display( sevent segment).
2. 3 pins of port B and 2 pins of port c are used for transistor of segment.
3. For each channel I need two LED indications so another port down :(
4. Four pins of port B are utilized for buttons.
I'm left with nothing :(
I was wondering using a decoder but I'm not confident about it.
So please suggest something I can work on.
Thanks alot
Regards,
Sid |
|
|
arunb
Joined: 08 Sep 2003 Posts: 492 Location: India
|
RE |
Posted: Fri Oct 29, 2010 11:06 am |
|
|
Use a 8 channel ADC such as the MCP 3208, the device is SPI based one. |
|
|
Sid2286
Joined: 12 Aug 2010 Posts: 119
|
|
Posted: Thu Nov 25, 2010 11:30 am |
|
|
OK I tried working with MCP3208 and its working fine...thanks alot!
...
But I'm into another problem and it sounds quite critical, for every channel I have two LED indications, for alarm1 and alarm2.
I don't have as many ports(in all 16 pins of micro-controller) and even from designing point of view doesn't look good.
So I used a 4:16 decoder IC 74HC4514. Now I scan every channel and when the condition is high. for eg. channel 1 and alarm1 it shows LED indication but as soon as it scans channel2 my LED indication switches off, which i don't want. :(
For alarm condition I used a switch case.
Is there any way wherein, I can generate a signal from a pulse, I thought about astable mode of 555 but it won't work because in that case I would have to use 16 IC 555s. :(
Or some other way to solve this problem.
Please suggest something,
Eagerly waiting.
Regards,
Sid |
|
|
Sid2286
Joined: 12 Aug 2010 Posts: 119
|
|
Posted: Thu Nov 25, 2010 11:52 am |
|
|
the code is as follows
Code: |
if(alarmflag[i]==0)
{
if((f>(ax[i]-hax[i])&& f<(ax[i]+hax[i]))) // f is analog input
{
//Enable the Decoder
output_low(pin_A0);
switch(i) // i is channel number
{
case 0:
output_low(pin_b3); //A0
output_low(pin_b4); //A1
output_low(pin_b5); //A2
output_low(pin_b6);//A3
break;
case 1:
output_high(pin_b3);
output_low(pin_b4);
output_low(pin_b5);
output_low(pin_b6);
break;
case 2:
output_low(pin_b3);
output_high(pin_b4);
output_low(pin_b5);
output_low(pin_b6);
break;
case 3:
output_high(pin_b3);
output_high(pin_b4);
output_low(pin_b5);
output_low(pin_b6);
break;
case 4:
output_low(pin_b3);
output_low(pin_b4);
output_high(pin_b5);
output_low(pin_b6);
break;
case 5:
output_high(pin_b3);
output_low(pin_b4);
output_high(pin_b5);
output_low(pin_b6);
break;
case 6:
output_low(pin_b3);
output_high(pin_b4);
output_high(pin_b5);
output_low(pin_b6);
break;
case 7:
output_high(pin_b3);
output_high(pin_b4);
output_high(pin_b5);
output_low(pin_b6);
break;
}
}
else if((f>(ay[i]-hay[i])&& f<(ay[i]+hay[i])))
{
//Enable the Decoder
output_low(pin_A0);
delay_ms(50);
switch(i)
{
case 0:
output_low(pin_b3); //A0
output_low(pin_b4); //A1
output_low(pin_b5); //A2
output_low(pin_b6);//A3
break;
delay_ms(50);
case 1:
output_high(pin_b3);
output_low(pin_b4);
output_low(pin_b5);
output_low(pin_b6);
break;
delay_ms(50);
case 2:
output_low(pin_b3);
output_high(pin_b4);
output_low(pin_b5);
output_low(pin_b6);
break;
delay_ms(50);
case 3:
output_high(pin_b3);
output_high(pin_b4);
output_low(pin_b5);
output_low(pin_b6);
break;
delay_ms(50);
case 4:
output_low(pin_b3);
output_low(pin_b4);
output_high(pin_b5);
output_low(pin_b6);
break;
delay_ms(50);
case 5:
output_high(pin_b3);
output_low(pin_b4);
output_high(pin_b5);
output_low(pin_b6);
break;
delay_ms(50);
case 6:
output_low(pin_b3);
output_high(pin_b4);
output_high(pin_b5);
output_low(pin_b6);
break;
delay_ms(50);
case 7:
output_high(pin_b3);
output_high(pin_b4);
output_high(pin_b5);
output_low(pin_b6);
break;
delay_ms(50);
}
}
else
{
output_high(pin_A0); //DISABLE DECODER
delay_ms(50);
}
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Thu Nov 25, 2010 1:21 pm |
|
|
To use lots of LEDs on few I/O pins, Google 'Charliplexing'.
It's a great way to freeup pins ! |
|
|
Sid2286
Joined: 12 Aug 2010 Posts: 119
|
|
Posted: Thu Nov 25, 2010 10:27 pm |
|
|
thanks alot temtronic!!
its an amazing concept...
but still my problem is not getting solved here...
for eg:- If i take an example of 2LEDs switching between 2 Pins, at a given time i can switch only 1 LED ON but not both of them.
here in my circuit i need to provide a facility to ON all the 16 LEDs if there is an alarm condition.
I doubt if that is possible using charlieplexing :(
Regards,
Sid |
|
|
arunb
Joined: 08 Sep 2003 Posts: 492 Location: India
|
RE: |
Posted: Thu Nov 25, 2010 11:08 pm |
|
|
you could break up the job into several tasks and use another PIC for doing some of the tasks.
I am not sure how this can be done for your project but I think you can work it out better.
I know this sounds vague..
thanks
a |
|
|
Sid2286
Joined: 12 Aug 2010 Posts: 119
|
|
Posted: Thu Nov 25, 2010 11:19 pm |
|
|
hmm,
I'm not sure how to do that...can you put a little light on it.
I don't know, how to proceed with that.
thanks,
Sid |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Fri Nov 26, 2010 3:45 pm |
|
|
Ok....another thought.
Why not just use an LCD ? Minimally only 6 I/O pins are needed, so hopefully that's less that the LED approach.
No extra ICs like decoders (4511s)..no extra wiring..less power required!
LCDs are cheap( 2x16 LCDs are $5 !)
Allows for future expansion (always a plus), Names instead of alarm LEDs.
..just another way to look at it. |
|
|
Sid2286
Joined: 12 Aug 2010 Posts: 119
|
thanks! |
Posted: Sun Dec 05, 2010 11:14 pm |
|
|
Hi,
thank you all for your help... however I eventually made to glow the leds using 74HCT574!
It did work fine...
Thank you all once again.
Regards,
Siddhesh |
|
|
|