9 years, 2 months ago.

Creating Signal with variable Period (Matlab)

Hello.

I recently started programming with Matlab and a mbed lpc1768. Due to an internship I need to programm a control for a test structure. The structure contains 1 DC Motor and 2 stepping motors. To control the DC motor I use the PwmOut() Functionof the mbed and vary the Duty Cycle. (which works just fine) For the stepping motors my plan was to use a matlab timer and toggle the Output pin on the mbed each time the Timer fires. So I would get a squarewave signal with a duty cycle of 50% and a Period of twice the time I set the timer.

Unfortunately I'm only able to get a max. Signal of 10 Hz. That is far from the 50kHz I actually need.

So I searched for the cause of this problem and discovered that my Program (or the mbed) needs around 40ms to set or reset the Pin. But I wasn't able to figure out why a controller with around 95MHz needs this long to simply set or reset a Pin. The only possible explanation I could imagine would be that the communication between matlab and the mbed takes this much time.

For more Details, here is the Test Code I was running:

import mbed.*

mymbed= SerialRPC('COM49',9600);
dout2 = DigitalOut(mymbed,p21);     %I tried it on various Pins
status = 0;

while 1
    if status == 0
        tic 
        dout2.write(0);
        status = 1;
        toc
    else
        dout2.write(1);
        status = 0;
    end
    pause(0.005);  %Also tried various counts
end

The elapsed time between the tic toc is around 0.04 seconds. And with this in mind it's logical that I only get a 10Hz Signal...

So my Questions now are:

1. Is there something wrong with my mbed or matlab that it takes this much time to simply set/reset a Pin?

2. If this is normal how do I implement a squarewave control signal on a Pin with a Duty Cycle of 50% and a variable Period up to 50kHz?

I'm grateful for any help/explanation/suggestion because I really come to a dead end here.

Thanks and Greetings Florian

3 Answers

9 years, 2 months ago.

You should be able to go a lot faster, I'm guessing the serial coms are the issue. If nothing else serial links are slow. Send the control information over the link but keep the real time control loops local to the mbed.

Have the mbed run a ticker at a rate of twice the required frequency (or half the period since you set tickers using a period not a frequency) and toggle the IO pin on each tick.

You can then set the rate by having the matlab code send the required period to the mbed, in the background loop the mbed waits for new rate information and changes the ticker period accordingly.

Alternatively if it gives you the frequency range you need you could use a pwm output, set the duty cycle to 50% and vary the period as required.

Accepted Answer

Thank you for the answer :) To avoid this dragging on to long here I wrote you a Message because I have a bit trouble with the Syntax and how to initialise a Ticker in Matlab. I wouldn't mind if you post your answer here so that other people with a similiar problem could see it too.

Greetings Florian

posted by Florian B 12 Feb 2015

There is a slight misunderstanding here. Run the ticker on the mbed not in matlab. All matlab does is send the required period whenever it changes.

posted by Andy A 12 Feb 2015

Ok now I'm a bit confused.

How do I tell the mbed to run a Ticker without initialise or programm something with matlab? I have at least to tell the mbed somehow that he has to start running a ticker or how do I start one?

For Example if I want to tell a MSP430 G2553 that he should start a hardware timer and call an interrupt every time a specific value is reached and execute something when this happens I need to write in the Timer Register and set some specific Bits to activate this function. It looks something like this: (in C)

  TACTL = TASSEL_2 + ID_2;      //SMCLK + Div. 4 => 250kHz -- TACTL = Timer A COntrol Register
  TACCTL0 |= CCIE;				//Timer Interrupt enable
  TACCR0 = 25000;				// Count for 100ms
.
.
.
#pragma vector=TIMER1_A0_VECTOR         //ISR für Timer 2. Reset des Radar-Sensors alle 4sek          
  __interrupt void Timer_A1 (void)		
  { 
    //ISR Routine
    
   TA1CCTL0 &= ~CCIFG; // Flag reset
      }

If I need to do something similar for the ticker I have no Idea how to set the registers with matlab (How the Syntax works)...

Thank you for your help. Florian

Need to leave the office now but I'll be back as soon as I come back tomorrow.

posted by Florian B 12 Feb 2015
9 years, 2 months ago.

A 9600 baud serial connection needs 1ms to send a single character. So 40ms would mean 40 characters, which might very well be how much RPC needs (no idea though).

Also I don't think a matlab timer will get anywhere near the toggling speed you require. And even if it would get there, windows (or linux or whatever you run it on) isn't a real-time OS: There is no guarantee whatsoever that the timer is handled at the required speed. It might suddenly realise it is time to run a virus scan, and there goes your performance.

It would be way better to just run it directly on your mbed.

The problem with your requirements is a bit the LPC1768: Its PWM output pins can only run on a single period. Some targets can use multiple periods (generally a few pins then share the same period).

Thank you for the Answer :)

So my guess regarding the communicationspeed was right...

Unfortunately I have to use the LPC1768 and can't get a Controller which can use multiple periods :( I hope the Ticker-thing from Andy works.

Still I'm grateful for other advices/suggestions towards this problem.

Greetings Florian

posted by Florian B 12 Feb 2015
9 years, 2 months ago.

I just tried with my FRDM-KL25Z, for 48MHz MCU 20us seems to be a little bit tough.
The wave was not very stable, a lot of jitters, beside pwm worked just fine, though.

#include "mbed.h"

DigitalOut dout2(PTA13) ; // D8
PwmOut dout3(PTD0) ; // D10

int sample_time = 10 ; // 10us for 50kHz 50% 
Ticker *timer ;

void tick_it(void)
{
    dout2 = !dout2 ;
}

int main() {
// to use ticker uncomment following 2 lines    
    timer = new Ticker() ;    
    timer->attach_us(&tick_it, sample_time) ;
    // to stop timer->detach() ;
    
// to use pwm uncomment following 2 lines    
//    dout3 = 0.5 ; // duty 50%
//    dout3.period(0.00002) ;
    
    while(1) {
        wait(0.5) ;
    }
}

moto

Hello moto! Thank you for your answer.

The PwmOut Function works just fine unfortunately all PWM Pins share the same Period (as Erik mentioned) and I need two Signals with independend Periods.

I already found out that the LPC1768 has a hardware timer & ticker. But my Problem is that I don't know how to set them up using matlab. I think I have to do something with the RPCFunction but I have no clue how this works and I can't find any matlab code examples. Found this Tutorial on Timer and Interrupts http://developer.mbed.org/media/uploads/robt/mbed_course_notes_-_timers_and_interrupts.pdf but lines like "Ticker flipper;" won't work with matlab :(

Greetings Florian

posted by Florian B 13 Feb 2015

Dear Florian-san,
Thank you for your response and I'm sorry for my pointless answer.
The pdf you pointed seems pretty helpful for me.

but lines like "Ticker flipper;" won't work with matlab :(

I'm really sorry for my ignorance.
Anyway, I'm hoping that you can find solution(s) soon.
Best Regards, moto

posted by Motoo Tanaka 13 Feb 2015

Hello Moto-san.

Your answer wasn't pointles I take every help I can get :)

I wrote some messanges with Andy and will now take his approach by writing a C Program on the mbed and give values via matlab. Because I'm not very used to C++ Syntax (I only programmed in C and only for a MSP430 G2553) your Programm could be a big help. I'm currently trying to program some simple test Programs on the mbed. If I'm not able to figure out how to communicate with matlab and the C programm I'll be back.

Thank you for your help.

Best regards, Florian

posted by Florian B 13 Feb 2015