View previous topic :: View next topic |
Author |
Message |
arelone
Joined: 06 Dec 2015 Posts: 42
|
Sample & hold triggering for observation time |
Posted: Sun Dec 13, 2015 8:02 am |
|
|
Hi,
I am not good in C programming, however with great help from the members in previous forum I have improved. Currently, I have a problem to generate 9 trigger signals which have different observation times due to the sensor location. The sensor is located at outer wall of a pipe. The observation times are calculated upon triggering the excitation signal at HIGH logic level (+5V). The command is located in line 39. The following are the observations time of the trigger signals:
S&H5=45us; S&H6=48us; S&H7=52us; S&H8=55uS, S&H9=59us, S&H10=55us; S&H11=52us; S&H12=48us; S&H13=45us
I referred to my colleagues about these problems but none of them can help. What I can see is that I need a timer that will measure the current time and when the value reached is the value which is same as the observation time, the program will execute & trigger the designated S&H signal to the LOW level. I still have no idea where to start and advice from the experts is very much appreciated.
Regards
Code: |
#include <S&H.h>
void main()
{
setup_adc(ADC_CLOCK_DIV_64 | ADC_TAD_MUL_8);
//I/O ports configurations(1:input, 0:output)
set_tris_a(0x0000); //set port_a as output
//set_tris_b(0xFFFF); //set port_b as analog input/ADC
set_tris_c(0x0000); //set port_c as output
set_tris_d(0x0000); //set port_d as output
set_tris_f(0x0000); //set port_f as output
set_tris_g(0x0000); //set port_g as output
output_a(0x0000); //clear port_a to 0s
output_c(0x0000); //clear port_c to 0s
output_d(0x0000); //clear port_d to 0s
output_f(0x0000); //clear port_f to 0s
output_g(0x0000); //clear port_g to 0s
while(TRUE)
{
//Tx1 as transmitter
output_low(pin_G15); //mCA1; Tx1 Select as transmitter (Tx) mode
//2_pulses excitation signal:
output_high(pin_G14); //Excitation signal to generate 2_pulses (+5V/0) for transmitter signal at approx.328kHz
delay_us(1.5);
output_low(pin_G14);
delay_us(1.5);
output_high(pin_G14);
delay_us(1.5);
output_low(pin_G14);
//Rx2 to Rx16 functions as receiver
//output_high(pin_C1); //mCA2; Rx2 Select as receiver (Rx) mode
//output_high(pin_C2); //mCA3; Rx3 Select as receiver (Rx) mode
//output_high(pin_C3); //mCA4; Rx4 Select as receiver (Rx) mode
//output_high(pin_C4); //mCA5; Rx5 Select as receiver (Rx) mode
output_c(0b0000000000011110);
//output_high(pin_G6); //mCA6; Rx6 Select as receiver (Rx) mode
//output_high(pin_G7); //mCA7; Rx7 Select as receiver (Rx) mode
//output_high(pin_G8); //mCA8; Rx8 Select as receiver (Rx) mode
//output_high(pin_G13); //mCA9; Rx9 Select as receiver (Rx) mode
output_g(0b0010000111000000);
// output_high(pin_D1); //mCA10; Rx10 Select as receiver (Rx) mode
// output_high(pin_D14); //mCA11; Rx11 Select as receiver (Rx) mode
// output_high(pin_D15); //mCA12; Rx12 Select as receiver (Rx) mode
output_d(0b11000000000000010);
//output_high(pin_F4); //mCA13; Rx13 Select as receiver (Rx) mode
//output_high(pin_F5); //mCA14; Rx14 Select as receiver (Rx) mode
//output_high(pin_F8); //mCA15; Rx15 Select as receviver (Rx) mode
//output_high(pin_F7); //mCA16; Rx16 Select as receiver (Rx) mode
output_f(0b0000000110110000);
//sample & hold signals at SNH5 to SNH13
//sample & hold for SNH5
delay_us(45); //delay = toF (measured from the beginning of excitation signal)
output_low(pin_A10); //hold (LOW) for peak; RA10- SNH5
delay_us(20);
output_high(pin_A10); //sample (HIGH) at all times
//sample & hold for SNH6
delay_us(48); //delay = toF (measured from the beginning of excitation signal)
output_low(pin_F6); //hold (LOW) for peak; RF6- SNH6
delay_us(20);
output_high(pin_F6); //sample (HIGH) at all times
//sample & hold for SNH7
delay_us(52); //delay = toF (measured from the beginning of excitation signal)
output_low(pin_G2); //hold (LOW) for peak; RG2- SNH7
delay_us(20);
output_high(pin_G2); //sample (HIGH) at all times
//sample & hold for SNH8
delay_us(55); //delay = toF (measured from the beginning of excitation signal)
output_low(pin_G3); //hold (LOW) for peak; RG3- SNH8
delay_us(20);
output_high(pin_G3); //sample (HIGH) at all times
//sample & hold for SNH9
delay_us(59); //delay = toF (measured from the beginning of excitation signal)
output_low(pin_A14); //hold (LOW) for peak; RA14- SNH9
delay_us(20);
output_high(pin_A14); //SNH5; sample (HIGH) at all times
//sample & hold for SNH10
delay_us(55); //delay = toF (measured from the beginning of excitation signal)
output_low(pin_A15); //hold (LOW) for peak; RA15- SNH10
delay_us(20);
output_high(pin_A15); //sample (HIGH) at all times
//sample & hold for SNH11
delay_us(52); //delay = toF (measured from the beginning of excitation signal)
output_low(pin_D8); //SNH5; hold (LOW) for peak; RD8- SNH11
delay_us(20);
output_high(pin_D8); //SNH5; sample (HIGH) at all times
//sample & hold for SNH12
delay_us(48); //delay = toF (measured from the beginning of excitation signal)
output_low(pin_D9); //SNH5; hold (LOW) for peak; RD9- SNH12
delay_us(20);
output_high(pin_D9); //SNH5; sample (HIGH) at all times
//sample & hold for SNH13
delay_us(45); //delay = toF (measured from the beginning of excitation signal)
output_low(pin_D10); //SNH5; hold (LOW) for peak; RD10- SNH13
delay_us(20);
output_high(pin_D10); //SNH5; sample (HIGH) at all times
}
} |
|
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sun Dec 13, 2015 11:16 am |
|
|
I'm confused, and can't follow what you're trying to do. (Maybe I'm just thick)
I suggest you:-
1) Read the forum guidelines.
2) Learn to use the code button. (Preserves formatting and makes code easier to follow)
3) Start simple with just 2 sensors.
4) Quote chip, and compiler version.
5) Post SHORT, complete, compilable code we can copy and paste to test.
6) Avoid references of the "line 39" variety.
7) Show us your fuses.
8) Tell us what's in <S&H.h>
9) ......................
Mike
++++++++++++++
Code block added per request.
-Forum Moderator
++++++++++++++ |
|
|
arelone
Joined: 06 Dec 2015 Posts: 42
|
|
Posted: Mon Dec 14, 2015 12:54 am |
|
|
Hi,
Thank you for the advice and I would like to apologize for making everyone confuse with my problem. Actually I am using a dspic30F6014a oscillator 20MHz and with ccs PCWHD compiler v.5.010. My objective is, I want to trigger sample & hold signal at specific observation time. The observation is obtained from calculation from speed of sound in a specific medium. Therefore, different sensor location will results different observation time. A trigger of the sample & hold is required to hold the highest peak value from the receiving signals which arrived at the receiving sensors (in this case is sensor 5 and sensor 6). For sensor 5 and sensor 6 the observation time are 45us and 48us respectively. The problem which I encountered is to trigger the sample & hold (SNH) at the specific observation time for each sensors. The observation time is measured from the beginning of the excitation signal pumped to the transmitter. As a beginner in c it is difficult for me but I am willing to learn. Any examples or ideas from the members is very much appreciated.
Another problem is how to insert image in the discussion? I would like to attach the timing diagram.
Thank you |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19551
|
|
Posted: Mon Dec 14, 2015 1:52 am |
|
|
Does the timing begin from the start of the excitation signal, the middle, or the end?. You need accuracy in your 'thinking' here. Generally for most things it'll be the start, plus the latency time in the receive circuit.
Your big problem is that you probably need to be working from one point. Each instruction takes time, so instead of using cumulative 'delay' statements, you need to start a timer at the point when you need to be working 'from', and then work totally from this timer. This is not a simple little bit of code, but something that requires a fairly solid understanding of the PIC hardware, the latencies in this, and your transmission and reception hardware, and the errors this introduces. As posted, timings have major problems. Overlap.
As currently described, in the case of sample 5 for example, you start the S&H at 45uSec, but then take 20uSec before you turn it off. This then overlaps part of the time to the next reading.
You need to describe your times accurately from one point.
Now I'm 'guessing', but hoping that your times are in fact the delta's, not the total. So in fact the sequence looks something like:
Code: |
Trig start - time 0
Trig+45uSec - start SN5
Trig+65uSec - end SN5
Trig +93uSec - start SN6
Trig + 113uSec - stop SN6
etc.
|
Straight away if so, your existing code will be badly wrong, since it is ignoring the 20uSec (plus the actual instruction times), being used for each sample.
Draw a 'timeline' giving the correct points in time when things have to happen, and post this. We can then possibly help you on 'how to do this'. |
|
|
guy
Joined: 21 Oct 2005 Posts: 297
|
unconventional solution |
Posted: Mon Dec 14, 2015 6:25 am |
|
|
Hi arelone!
I have an unconventional approach for you, specifically because you are not an experienced programmer. I'm sure others in the forum will be critical...
I wrote this for a PIC24 just to test. Change this to whatever PIC you are using.
The idea is to follow Ttelmah's tip and draw a waveform on paper. Once you have all signals written along time, turn it directly into hard code. Each output_d line represents the state of the outputs on a specific timing. The delay between states can be adjusted very accurately. I hope you have a good logic analyzer.
Code: | #include <24FJ64GA308.h>
#fuses HS,PR_PLL,BROWNOUT,NOWDT
#use delay(CLOCK=20000000)
void main() {
output_d(0b0000000000000000); // startup state
// wait for trigger:
while(input(PIN_B0)==0) ; // wait as long as PIN_B0 is low
// PIN_B0 high - trigger received:
output_d(0b0000000000000000); // t+0
delay_cycles(8); // may be adjusted for accurate timing
output_d(0b0000000000000000); // t+1us
delay_cycles(8);
output_d(0b0000000000001000); // t+2us
delay_cycles(8);
output_d(0b0000100000001000); // t+3us
delay_cycles(8);
output_d(0b0000100000001000); // t+4us
delay_cycles(8);
output_d(0b0000100000000000); // t+5us
delay_cycles(8);
output_d(0b0000000010000000); // t+6us
delay_cycles(8);
output_d(0b0000000010000000); // t+7us
delay_cycles(8);
output_d(0b0000000010000000); // t+8us
delay_cycles(8);
output_d(0b0000000000000000); // t+9us
while(1) ; // endless wait
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19551
|
|
Posted: Mon Dec 14, 2015 7:39 am |
|
|
I think he needs an 'on', then after an interval, an 'off', for each sample channel. The sample and hold.
It is though very unclear. A nice little timing diagram from the pulse, with when each thing has to happen, is what is needed.
Also (honestly), I'd consider moving the pins involved. If the first sample and hold to be used, can be put on the first pin of a port, then the second on the second etc., it'd make it much easier to just have a single mask word, and move the bit along it. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 14, 2015 9:35 am |
|
|
arelone wrote: |
Another problem is how to insert image in the discussion? I would like to
attach the timing diagram.
|
How to post an image on the CCS forum:
Go to this website: http://postimage.org/
Upload your image. Select family safe. Then click the first button for
"Hotlink to Forum" to get a link to the image.
Then go to the CCS forum and type Ctrl-V to paste the link into a post.
If postimage.org doesn't work in your country, then use Google to find
another free image hosting site for forums. |
|
|
arelone
Joined: 06 Dec 2015 Posts: 42
|
|
Posted: Mon Dec 14, 2015 10:48 am |
|
|
Hi,
Thank you very much for all your response. It is true that i am inexperienced programmer. I attached a timing diagram which I missed earlier for your convenience. The 20us is estimation time to convert the peak value with the ADC. I really don't know how fast the conversion time will take however shortest conversion time is better. There will be 16 projections and each projection consists of 9 measurement (peak) values. A total of 144 measurements can be obtained from 16 projection which is equivalent to 1 frame. I estimate for 1 frame it would take less than 450us. The location of the sensor is arranged in array around a 100mm diameter pipe, therefore at certain observation time 2 sensors will received the signal and obtained the highest peak values. For example the observation time of each sensor in projection#1:
Sensor5=Sensor13=45us
Sensor6=Sensor12=48us
Sensor7=Sensor11=52us
Sensor8=Sensor10=56us
Sensor9=60us
Thank you.
http://s19.postimg.org/bgmpeb6yb/Observation_time_timing_diagram.jpg |
|
|
arelone
Joined: 06 Dec 2015 Posts: 42
|
|
Posted: Mon Dec 14, 2015 11:25 am |
|
|
hi all
let me correct about the 20us hold in my earlier posts. It is the duration to hold the peak value and convert the value with the ADC. I really sorry for the unclear information.
regards. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19551
|
|
Posted: Mon Dec 14, 2015 2:02 pm |
|
|
Straight away, we can see the problem of overlap. What ADC are you using?. The point is that if you look at your diagram, the second read is required to start while you are still inside the time interval for the first read. Can your ADC do this?. What you are currently doing is sequential with delays after each earlier read is completed. Completely different...
Now how often is the trigger generated?. If it is at a reasonably quick interval, then consider a different approach.
Trigger
Wait for first interval.
Make reading for first sensor.
Trigger again
Wait for second interval.
Make reading for second sensor.
Trigger again.
Wait for third interval.
Make reading for third sensor.
Repeat for all the sensors
You'll only get one reading every 9 cycles, but then the system can work. |
|
|
arelone
Joined: 06 Dec 2015 Posts: 42
|
|
Posted: Mon Dec 14, 2015 8:54 pm |
|
|
Hi,
I'm using the 12-bit ADC. I am just thinking, what if during the HOLD trigger the peak value is stored in a register/buffer and at the end of each frame all the 9 peak value are converted using the ADC or when complete 16 frames then all the 144 peak values are converted using ADC. Can this improve the situation?
Thank you. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19551
|
|
Posted: Tue Dec 15, 2015 2:18 am |
|
|
You would need an external hardware sample and hold to do this. These are expensive, and generally have very limited 'hold' times. Do a search, and be prepared for just how much these cost....
Multiple transmissions is going to be enormously cheaper.
Other alternative, add multiple ADC's. Though the PIC ADC, has multiple inputs, it is a single ADC (double on some chips, at lower resolution). Can only be reading one signal at a time. Because of the overlap you show, this can't be done on the single ADC, in one go.
Consider adding (say) a PIC12F1840 to each input channel. Set each up as an I2C slave, with a different address on each. Have a single input pin on each to signal 'start conversion'. Then your master chip simply operates the pin to each in turn at the required times, then just reads the results back using I2C.
You are going to need an integrator circuit on each sensor to feed the ADC's. The PIC ADC, won't integrate the voltage pulse you show (it will a little, 'by accident', because of the internal capacitance, but the voltage you record will depend on what moment in the pulse you start the reading...). You need hardware to turn the envelope into a readable form. |
|
|
|