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

Reply via email to