Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
10 years 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
10 years 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.
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 12 Feb 2015There 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 12 Feb 2015Ok 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 12 Feb 201510 years 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 12 Feb 201510 years 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 13 Feb 2015Dear 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
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 13 Feb 2015