Arduino output SPWM using Matlab - Robotics Stack Exchange most recent 30 from robotics.stackexchange.com 2019-12-11T19:22:49Z https://robotics.stackexchange.com/feeds/question/11545 https://creativecommons.org/licenses/by-sa/4.0/rdf https://robotics.stackexchange.com/q/11545 0 Arduino output SPWM using Matlab Ammar Atef https://robotics.stackexchange.com/users/14985 2017-02-04T15:58:29Z 2017-02-04T16:44:34Z <p>I have Arduino and Matlab which has hardware support package for Arduino. I want to create SPWM signal (sinusoidal pulse width modulation) to be the output of the Arduino board. I could generate the signal required in Matlab using this code</p> <pre><code>function spwm = SinWave(frequency) nsamples = 1250 * frequency; t = linspace(0,1,nsamples); sn = sin(2*pi*frequency*t); st = sawtooth(2*pi*frequency*10*t); spwm = abs(sn) &gt; abs(st); plot(t, sn); hold on; plot(t, st); plot(t,spwm); axis([0,1,-1.2,1.2]); </code></pre> <p>Now SPWM has the samples for the signal, I tried sending it on pin 13 using the following function</p> <pre><code>function writeSPWM(arduino, spwm) for k=1:length(spwm) writeDigitalPin(arduino, 'D13' ,spwm(k)) end </code></pre> <p>Then I used the following two lines in command window</p> <pre><code>a = arduino() writeSPWM(a, SinWave(5)) </code></pre> <p>I getting my signal shape with very low frequency(it is really much bigger) Is there a better way to achieve my goal? using Matlab is necessary but I have no problem if I have to combine coding throw Matlab and Arduino C.</p> https://robotics.stackexchange.com/questions/11545/-/11546#11546 1 Answer by 50k4 for Arduino output SPWM using Matlab 50k4 https://robotics.stackexchange.com/users/10748 2017-02-04T16:07:01Z 2017-02-04T16:44:34Z <p>It seems that all the code you wrote is in Matlab, and at each cycle it should communicate via the USB port with arduino to turn the pin on or off. This take a lot of time. </p> <p>The fastest solution would be to write the whole algorithm as an Arduino sketch, and only get the current desired frequency via the Serial (USB) connection from Matlab. Matlab would set the desired frequency, send it via serial to the arduino. From there the latency of the USB (Serial) connection would not intervene. </p> <p>When you do the Arduino programming, make sure to use the PWM pins in PWM mode and not as a simple digital output turned on or off. </p> <p>EDIT:</p> <p><a href="https://www.arduino.cc/en/Tutorial/PWM" rel="nofollow noreferrer">Here</a> is a PWM tutorial for the arduino. </p> <p>for SPWM the duty cycle has to be changed frequently. You will not be able to change it for each cycle, but maybe for every 10 cycles. It will be still ok. </p> <p>You could start by calculating a sinus on the arduino using an interrupt that is set for maybe every 2 milliseconds. That interrupt should increment your time variable (make sure that it does not overflow, or it overlfows in a controlled manner and make sure to use some sort of scaling to get seconds). </p> <p>This will be the t from the sinus time signal equation: $SPWM(t) = A\sin (\omega t + \phi)$</p> <p>A (amplitude) I think in this case is irrelevant. probably the phase shift ($\phi$) is also irrelevant. $\omega$ you can calculate form your frequency. </p> <p>$\omega = 2 \pi f$, where $f$ is the frequency. You set to constant value at first, afterwards you make function that gets it form the serial port form Matlab (make sure NOT to include this in the interrupt, because it is slow)</p> <p>At the end of the interrupt you update the PWM duty cycle basted on the SPWM(t) value the interrupt calculated.</p> <p>I am sure there are many other approaches, but for me this seems the simplest one which delivers acceptable performance. Also, please make sure that the cycle time of the interrupt is longer than the runtime of the code in the interrupt. </p>