Not that I know dink about cardiology of course...but a heatbeat is
about 180/min (3/sec) at fastest unless you're in defib or something.
So a sample rate of 100/sec gives you at least 16 harmonics of the
original. Also the 3 electrodes are spaced around the chest so you
get overlapping phases of the pulse?
I guess I should go talk to my doctor...
Anyway...assuming the tmote has about the same xmit rate as micaz,
you were probably getting less than 100 samples/sec at your receiver
and this works out to a 'clean' 50Hz signal, which is right on the
money in your 40-60hz measurement.
Of course my mathematics, statistics, and lies may be indistinguishable.
For the x=signal problem, my only suggestion is...did you actually
measure the frequency of the received signal? Unless you had _exactly_
the same signal freq as sample rate you would see some kind of alias
that {pre,pro}cessed through the samples. What you might have seen is
a way-low harmonic of the nice high-freq sinewave. Also see my comment
in previous paragraph...
You would have to look at the spec sheet for the controller to see how
fast the ADC can go. On the mica's the absolute minimum is 13 clock ticks,
or 25 if you constantly switch it on and off like the standard ADC code...
Of course if you are using the regular Timer to run it, the minimum is 1ms,
because that's the Timer's resolution. There is some example code for
doing High Speed Sampling to capture audio, someplace, I think.
I don't know about DMA. That sounds like something that no decent
micro-Controller should have intercourse with. Assuming you are trying
to run continuously, your system is limited by the message rate. DMA
would run way fast if you were capturing and storing a buffer, but
you still have to keep transmitting the data.
good luck with it
MS
Alexandros Karagiannis wrote:
Hello and thank you for the reply,
My previous post was a little bit confusing and i have to apologize for
this. We suspected that there must be data overwrites before the RF and
from your reply we are certain that the "limited" capacity of sending
messages may be tha cause.
I meant that the 'x' argument of Timer.start(TIMER_REPEAT, *x) *sets the
timeout and because i call getData() in the body of Timer.fired(...), in
this way i have the sampling rate i want.
The sampling rate for an ECG signal is approximately 200-300Hz beacause
the frequency range of an ECG signal is 0-100Hz. So we can set the
timeout constant to 4,or 3 or 2,or 1 ms in order to have a sampling rate
of ADC high enough.Testing for frequencies *higher than 40-60Hz* signal
input we got *signal distorted even if we set the timeout interval to
4ms or lower values*.
We have cosntructed an electrocardiogram circuit of 3 electrodes and we
get the output signal to a signle ADC pin.Do you know what is the
*maximum supported sampling rate for ADC* without using any other method
to increase the sampling rate?
Another strange thing we noticed is that when we set the x value (thus
define a specific sampling rate) and connect to the appropriate input
pin a signal o*f the same frequency* as the sampling rate, we *get a
perfect signal plotted in matlab*. This is strange because we thought we
violated the sampling theorem.
**Any ideas about enabling DMA? Do you think this could help in this
case? Is there any source where we could find sample codes and help
about DMA?
Michael Schippling wrote:
A few suggestions....
I'm not entirely clear from your message if you understand that the
Timer.start() 'x' argument is the number of millisec to timeout.
Therefore 1 is the shortest and should give about 1khz sample rate
in your program. With a value of 4 you should see 250Hz which matches
your 120Hz non-aliased measurement pretty good.
But what is probably your problem is that you are sending one message
per sample, and you are never going to get to 1000 msgs/sec...I don't
know about the Tmote, but I just measured the micaz at about 100/sec
in the best of all possible worlds. You should collect a number of
readings before sending them off and use alternating buffers, like
the Oscilloscope demo app.
Even with that I'm not sure you can maintain a solid sample rate
because the message send will take some time...hopefully most of
it will be in short interrupts to reload the send register. You'll
just have to see how much timing jitter your data can stand.
What is the useful upper freq limit on an ECG anyway (I assume we
are talking about Cardio-grams)? Since you're only talking one ADC
I guess it's a single electrode, so phase relationships are not of
interest...do you really need to go over 100Hz?
MS
Alexandros Karagiannis wrote:
Hello,
I'm novice in this field so I have to apologize in advance if any of
the questions following seem to be not adnanced.
I use Tmote sky and my primary target is to trasmit a ECG to a WSN
and receive it to a host in order to process it with matlab.I read
tutorials and any other helping stuff and I found an application
report including sample code which I tried to modify in order to fit
my needs. I haven't actually connected the ECG output to the
appropriate pin of the Tmote sky (Analog Input 0 ADC0 pin 3 from
Tmote sky datasheet) and at the first tests i use a sinus input of
variable frequency.
The problem is that for low frequencies (5 - 10Hz) to approximately
120-160Hz i get a signal in matlab which i believe is satisfactory
but when i set the Timer.start( TIMER_REPEAT, x) where x is the value
i modify in order to set the sapling rate, i get a signal that is
distorted even if the input sinus is much lower in frequency.
I thought that the x value in Timer.start( TIMER_REPEAT, x) sets the
sampling rate of ADC because in the body of Timer.start(
TIMER_REPEAT,x) i check if data have been set and i call the
getData() to take the next sample. I have to stress that x is higher
than 1ms which i believe is the higher sampling rate (1KHz). Of
course i 've read that i can set the sampling rate even higher but i
don't know the way to do it. I assume that when i set the sapling
rate in higher frequencies, there must be simultaneous events fired
that overwrite data queued to be sent. This doesn't happen in lower
frequencies. But i have to know if this x value actually sets the
sapling rate. Another strange thing i noticed is that when i set the
x value and connect to the appropriate input pin a signal of the same
frequency, i get a perfect signal plotted in matlab. This is strange
beacause in my mind i thought i violated the sampling theorem.
Another thing i'd like to know is the time between the sampling and
the signal transmission from the mote.I don't have a clue about it.
Is it possible data to be overwritten by another sampling task and to
lose data before transmitting them?
I read in this forum that enabling DMA is very helpful. Is it to
avoid data losses and fast transmission to the RF part? How can i do
it ?
I've tested a code that counts Timer.fired events and
SendMsg.sendDone and set the absolute value of the subtraction of the
two counters to the data field in ADC.dataReady. After testing
different sampling rates i noticed that for low sampling rates this
value is constant.For sampling rates above 160-170Hz this value was
constantly rising.
The code i run is
*EcgSenseM.nc*
includes IntMsg;
module EcgSenseM
{
provides interface StdControl;
uses interface Timer;
uses interface SendMsg;
uses interface Leds;
uses interface ADC;
uses interface ADCControl;
}
implementation
{
TOS_Msg m_msg;
int m_int;
bool m_sending;
command result_t StdControl.init()
{
atomic m_int = 0;
m_sending = FALSE;
call Leds.init();
call Leds.redOn();
call ADCControl.init();
call ADCControl.bindPort( TOS_ADC_ADC0_PORT,
TOSH_ACTUAL_ADC_ADC0_PORT );
return SUCCESS;
}
command result_t StdControl.start()
{
call Timer.start( TIMER_REPEAT, 4);
call ADC.getData();
return SUCCESS;
}
command result_t StdControl.stop()
{
return SUCCESS;
}
event result_t Timer.fired()
{
if( m_sending == FALSE )
{
int n;
IntMsg* body = (IntMsg*)m_msg.data;
atomic n = m_int;
body->val = n;
body->src = TOS_LOCAL_ADDRESS;
if( call SendMsg.send( TOS_BCAST_ADDR, sizeof(IntMsg), &m_msg )
== SUCCESS )
{
m_sending = TRUE;
//call SendMsg.send(TOS_BCAST_ADDR, sizeof(IntMsg), &m_msg );
call Leds.greenToggle();
}
}
call ADC.getData();
call Leds.yellowToggle();
return SUCCESS;
}
async event result_t ADC.dataReady( uint16_t data )
{
atomic m_int = data;
return SUCCESS;
}
event result_t SendMsg.sendDone( TOS_MsgPtr msg, result_t success )
{
m_sending = FALSE;
return SUCCESS;
}
}
.
*EcgSense.nc*
includes adc0;
includes IntMsg;
configuration EcgSense
{
provides {
interface StdControl;
}
}
implementation
{
components Main, EcgSenseM, TimerC, GenericComm, LedsC, ADCC;
Main.StdControl -> EcgSenseM;
Main.StdControl -> GenericComm.Control;
Main.StdControl -> ADCC;
Main.StdControl -> TimerC;
StdControl = EcgSenseM;
EcgSenseM.Timer -> TimerC.Timer[unique("Timer")];
EcgSenseM.SendMsg -> GenericComm.SendMsg[AM_INTMSG];
EcgSenseM.Leds -> LedsC;
EcgSenseM.ADC -> ADCC.ADC[TOS_ADC_ADC0_PORT];
EcgSenseM.ADCControl -> ADCC;
}
Thank you and sorry for the extended post.
------------------------------------------------------------------------
_______________________________________________
Tinyos-help mailing list
Tinyos-help@Millennium.Berkeley.EDU
<mailto:Tinyos-help@Millennium.Berkeley.EDU>
https://mail.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help
_______________________________________________
Tinyos-help mailing list
Tinyos-help@Millennium.Berkeley.EDU
https://mail.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help