Home » Arduino Engineering Projects » Arduino SPWM Generator Circuit – Code Details and Diagram
Arduino SPWM Generator Circuit – Code Details and Diagram

Arduino SPWM Generator Circuit – Code Details and Diagram

In this post we learn how to generate sine wave pulse-width-modulation or SPWM through Arduino, which can be used for making a pure sine wave inverter circuit or similar gadgets.

The Arduino code is developed by me, and it is my first Arduino code, ...and it looks pretty good 🙂

What is SPWM

I have already explained how to generate SPWM using opamps in one of my earlier articles, you could go through it for understanding how it can be created using discrete components and regarding its importance.

Basically, SPWM which stands for sine wave pulse width modulation, is a type of pulse modulation where the pulses are modulated to simulate a sinusoidal waveform, so that the modulation is able to attain properties of a pure sine wave.



To implement a SPWM the pulses are modulated with an initial narrower widths which gradually get broader at the center of the cycle, and finally end being narrower at the end to finish the cycle.

To be more precise, the pulses begin with narrowest widths which gradually get broader with each subsequent pulses, and gets broadest at the center pulse, after this, the sequence continues on but with an opposite modulation, that is the pulses now gradually begin getting narrower until the cycle finishes.

Video Demo

This constitutes one SPWM cycle, and this repeats throughout at a particular rate as determined by the application frequency (usually 50Hz or 60Hz). Typically, SPWM is used for driving power devices such as mosfets or BJTs in inverters or converters.

This special modulation pattern ensures that the frequency cycles are executed with a  gradually changing average voltage value (also called the RMS value) , instead of throwing sudden Hi/low voltage spikes as normally witnessed in flat square wave cycles.

This gradually modifying PWMs in a SPWM is purposely enforced so that it closely replicates the exponentially rising/falling pattern of a standard sinewaves or sinusoidal waveform, hence the name sinewave PWM or SPWM.

Generating SPWM with Arduino

The above explained SPWM can be easily implemented using a few discrete parts, and also using Arduino which will probably enable you to get more accuracy with the waveform periods.

The following Arduino code can be used for implementing the intended SPWM for a given application.

Gosh!! that looks awfully big, if you know how to shorten it, you may certainly feel free to do it at your end.

// By Swagatam (my first Arduino Code)
void setup(){
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
}
void loop(){
digitalWrite(8, HIGH);
delayMicroseconds(500);
digitalWrite(8, LOW);
delayMicroseconds(500);
digitalWrite(8, HIGH);
delayMicroseconds(750);
digitalWrite(8, LOW);
delayMicroseconds(500);
digitalWrite(8, HIGH);
delayMicroseconds(1250);
digitalWrite(8, LOW);
delayMicroseconds(500);
digitalWrite(8, HIGH);
delayMicroseconds(2000);
digitalWrite(8, LOW);
delayMicroseconds(500);
digitalWrite(8, HIGH);
delayMicroseconds(1250);
digitalWrite(8, LOW);
delayMicroseconds(500);
digitalWrite(8, HIGH);
delayMicroseconds(750);
digitalWrite(8, LOW);
delayMicroseconds(500);
digitalWrite(8, HIGH);
delayMicroseconds(500);
digitalWrite(8, LOW);
//......
digitalWrite(9, HIGH);
delayMicroseconds(500);
digitalWrite(9, LOW);
delayMicroseconds(500);
digitalWrite(9, HIGH);
delayMicroseconds(750);
digitalWrite(9, LOW);
delayMicroseconds(500);
digitalWrite(9, HIGH);
delayMicroseconds(1250);
digitalWrite(9, LOW);
delayMicroseconds(500);
digitalWrite(9, HIGH);
delayMicroseconds(2000);
digitalWrite(9, LOW);
delayMicroseconds(500);
digitalWrite(9, HIGH);
delayMicroseconds(1250);
digitalWrite(9, LOW);
delayMicroseconds(500);
digitalWrite(9, HIGH);
delayMicroseconds(750);
digitalWrite(9, LOW);
delayMicroseconds(500);
digitalWrite(9, HIGH);
delayMicroseconds(500);
digitalWrite(9, LOW);
}
//-------------------------------------//

In the next post I'll explain how to use the above Arduino based SPWM generator to make a pure sinewave inverter circuit....keep reading!

The above SPWM code was further improved by Mr Atton for enhancing its performance, as given below:

/*
This code was based on Swagatam SPWM code with changes made to remove errors. Use this code as you would use any other Swagatam’s works.
Atton Risk 2017
*/
const int sPWMArray[] = {500,500,750,500,1250,500,2000,500,1250,500,750,500,500}; // This is the array with the SPWM values change them at will
const int sPWMArrayValues = 13; // You need this since C doesn’t give you the length of an Array
// The pins
const int sPWMpin1 = 10;
const int sPWMpin2 = 9;
// The pin switches
bool sPWMpin1Status = true;
bool sPWMpin2Status = true;
void setup()
{
pinMode(sPWMpin1, OUTPUT);
pinMode(sPWMpin2, OUTPUT);
}
void loop()
{
// Loop for pin 1
for(int i(0); i != sPWMArrayValues; i++)
{
if(sPWMpin1Status)
{
digitalWrite(sPWMpin1, HIGH);
delayMicroseconds(sPWMArray[i]);
sPWMpin1Status = false;
}
else
{
digitalWrite(sPWMpin1, LOW);
delayMicroseconds(sPWMArray[i]);
sPWMpin1Status = true;
}
}
// Loop for pin 2
for(int i(0); i != sPWMArrayValues; i++)
{
if(sPWMpin2Status)
{
digitalWrite(sPWMpin2, HIGH);
delayMicroseconds(sPWMArray[i]);
sPWMpin2Status = false;
}
else
{
digitalWrite(sPWMpin2, LOW);
delayMicroseconds(sPWMArray[i]);
sPWMpin2Status = true;
}
}
}

SHARING IS CARING!


About the Author

I am an electronic engineer (dipIETE ), hobbyist, inventor, schematic/PCB designer, manufacturer. I am also the founder of the website: https://www.homemade-circuits.com/, where I love sharing my innovative circuit ideas and tutorials. If you have any circuit related query, you may interact through comments, I'll be most happy to help!



66 thoughts on “Arduino SPWM Generator Circuit – Code Details and Diagram”


  1. Howdy, Friend! Interested to Learn Circuit Designing? Let's Start Discussing below!
  2. hello engr. Swagatam!
    I really appreciate this post. But I have a question regarding soft-start functionality.
    is there any available code for implementing soft-start functionality to control the ontime switching of the SPWM ?
    Please i will be very glad if this can be included with the code.
    Thank you.

    • Thank you Kingsley, I really wish I could help, however I do not have much idea regarding how to implement a soft start on the PWMs. I think you can take this issue to Arduino.cc forums and ask them for a solution…. they might help you!

  3. Hi Mr. Swagatam,
    is that posibble to apply your code for 3 phase SPWM with small changes? I mean, by adding new pwm pins to the code, like pin 11, pin 6, pin 5, and pin 3. So there is 6 sPWMpin for 3 phase SPWM inverter. Is that possible? I’ve found an article that mentioned Arduino Uno can’t generate 6 pwm signal because one pin is used for interrupt .

    • Hi Fitrah, If you generate them with proper 120 degrees separation then it will work, however I am not sure exactly which Arduino board would be able to implement this.

      • Thanks for your reply, Mr. Swagatam.
        So about the 120 degrees phase shift, an article mentioned that to get 120 degrees phase shift, the second signal must start 6.66 ms after the first signal, and the third signal must start 6.66 ms after the second signal. So, should i put some delay into the code? Or could you show me the better way?

        Best Regards.

        • yes that’s right, but I don’t remember the calculations for the frequency delay across the the 3 phase waves, if you are sure you can try implementing the mentioned amount of delay and check the response.

          • Thank You Mr. Swagatam.
            I appreciate your help, thank you very much. I’ll try the method. And soon i’ll post the code through the comments to make sure the program is correct or not, so you or the readers can improve it to better code.

  4. Hi Swag.
    i just try to upload your code to my arduino UNO. in the lcd i can get on full black digits only. this code is correct or it has to modify?

    regards.

    • Hi Paaker, all Arduino codes published in this website are perfect and tested….however since the author of the above circuit is not associated at the moment so troubleshooting your issue will be difficult for me….but you can put this question in any online Arduino forum….they might help to solve it for you….

  5. Compacted code:

    /* This code was based on Swagatam SPWM code with changes made to remove errors. Use this code as you would use any other Swagatam’s works.
    Atton Risk 2017 + Yves.Hacha @ tresco.eu, 22/6/2018: more compacte code */

    // choose 1 of the SPWM tables below:
    const int sPWMArray[] = {500,500,750,500,1250,500,2000,500,1250,500,750,500,500}; // this is the array with the 50Hz SPWM values; change them at will
    // const int sPWMArray[] = {416,416,625,416,1041,416,1666,416,1041,416,625,416,416,7}; // use this table to obtain 60Hz
    // const int sPWMArray[] = {124,464,245,349,359,244,463,153,552,80,630,29,1880,29,630,80,552,153,463,244,359,349,245,464,124,586}; // more detailed 50Hz SPWM

    const int sPWMArrayValues = sizeof(sPWMArray)/sizeof(sPWMArray[0]);

    // The pins
    const int sPWMpin1 = 10;
    const int sPWMpin2 = 9;

    void setup()
    {
    pinMode(sPWMpin1, OUTPUT);
    pinMode(sPWMpin2, OUTPUT);
    }

    void loop()
    {
    const int pinArray[] = {sPWMpin1,sPWMpin2};
    for (int pin(0); pin<2; pin++)
    {
    bool sPWMpinStatus = true;
    for(int i(0); i<sPWMArrayValues; i++)
    {
    digitalWrite(pinArray[pin], (sPWMpinStatus)?HIGH:LOW);
    delayMicroseconds(sPWMArray[i]);
    sPWMpinStatus = !sPWMpinStatus;
    }
    digitalWrite(pinArray[pin], LOW);
    }
    }

    • Thank you Yves, I would appreciate if you could tell us regarding the errors that you have removed in your code.

      • 1. offer 3 separate tables to choose from
        2. automatically get the correct PWM table size
        3. reuse the first half sinewave loop code also for the second half sinewave loop
        4. make sure each output pin stays low during the time that the other pin is ‘pulsing’

        (I’m sorry to see that the indentation of the code got lost while pasting…)

  6. Use

    const int sPWMArrayValues = sizeof(sPWMArray)/sizeof(sPWMArray[0])

    to automatically get the table size, in stead of

    const int sPWMArrayValues = 13; // You need this since C doesn’t give you the length of an Array

    • Hi Uthaya, You can get any desired output voltage depending on your transformer specification, Here the primary must be selected by calculating the ON time from the Arduino, check ratio of HIGH and LOW outputs across each channel from the Arduino, divide the total numbers of Highs + Lows in the code with number of Highs, now divide the battery voltage with this result to get the transformer primary voltage spec.

          • Circuit is H bridge design, using 4 mosfet. Mosfet model are irf520. Transformer 12/240V 3A. Input is 14Vdc. Currently im supplying input from dc supply not a battery.

            I only getting output around 5V before connect to transformer.

            Can I get your email. So i can send my circuit diagram and some details

  7. hi, can you make the code that can change the frequency ( 0 – 50Hz), shift, triangular wave, and modulation. thanks

  8. Yes, I think that the array count on each waveform cycle should be an even number.

    I’ve had some more thoughts on this, and I now feel that there should be a slight delay between the 2 halves of the waveform, so I suggest the following:

    sPWMArray[] = {496,500,750,500,1250,500,2000,500,1250,500,750,500,496,8}

    As you can see, I have reduced the start and end ON times by 4uS to provide an 8uS guard band, so that there is no chance of both transistors being on at the same time.

    When I have built the full inverter, I will experiment further with the delay in order to optimise the sine wave shape.

    Incidentally, if a 60Hz version is required, scaling the numbers gives the following:

    sPWMArray[] = {416,416,625,416,1041,416,1666,416,1041,416,625,416,416,7}

    • OK, that makes sense, I indeed appreciate your modifications and inputs.

      however according to me the number of arrays which form the “PWM pillars” across the AC cycle waveforms, will actually not affect the sinewave outcome by much, if their’s any other adverse effect, then I am not sure about it.

      and as far as the the “dead time” is concerned, you will see that the code on each channel ends with a “low” to be precise with this value: digitalWrite(8, LOW)

      so the “low” makes sure that during the transition both the devices are completely OFF, although the delay on this value can be perhaps increased to some higher level to ensure a better dead time delay…this is what I have assumed while designing the code, not sure whether this will be effective during the actual implementation or not 🙂

      • Having built a low power version of the inverter, I found that it was difficult to filter the AC output. So after more research I have come up with a version using more pulses (use in the sketch above):

        const int sPWMArray[] = {124,464,245,349,359,244,463,153,552,80,630,29,1880,29,630,80,552,153,463,244,359,349,245,464,124,586}; // This is the array with the SPWM values
        const int sPWMArrayValues = 26; // You need this since C doesn’t give you the length of an Array

        You’ll notice that this varies the delays as well as pulse widths. Also note the much longer delay at the end of the sequence to provide a long OFF time at the polarity switchover. The sequence was derived using Don Lancaster’s Guru’s Lair Magic Sinewaves Library:

        I’m currently using a series 100uH inductor on the transformer output and a 1uF X2 capacitor. This helps, but I think it needs a bigger inductor, so I have ordered a 560uH.

  9. Swagatam, thanks for your work on this project. Your code at the top of this page produces the correct waveform; whereas the “enhanced performance” version below it does not. Unfortunately I’m not sufficiently proficient with Arduino coding to see how to fix it. But as your less elegant solution takes up so little space, I’m happy to use that.

    By experimentation, I found that by adding a ,0 to the end of the sPWMArray and changing the sPWMArrayValues to 14, the code worked as it should. I suspect that the problem was that each loop increments by 2 (1 HIGH, 1 LOW), so having an odd number in the array caused it to go out of step.

    • Thank you Andy, I am glad I could help!
      Can you please explain a little more regarding the “odd number” issue, do you mean to say the array count on each waveform cycle should be ideally an even number?
      Thanks for visiting my site and enlightening us all.

  10. Nice work one Swagatem, you have officially made it to my Top 5 911 Engineering List, I appreciate all your hard work to this blog.
    I have 2 questions:
    1. Will the circuit give regulated VAC output constantly?
    2. How can i better the circuit to carry things like fan etc?
    Thanks again

    • Thanks Miebaka, I am so glad you liked my site!

      Since the PWM delays would be constant from the Arduino or may be tweaked as per the users preference and transformer winding rating, the output can be expected to be very accurate and no external regulator would be required for fixing the RMS.

      as for the fan operation, a properly calculated filter circuit at the output of the trafo will be quite sufficient to allow you to operate inductive loads efficiently.

  11. only the switching frequency is 30KHz. but the main output is 60Hz. as my appliances needed. i am using SPWM right now generated by arduino UNO.

    • there should not be more than 4 to 6 pillars on each waveform, as implemented in my SPWM, I think you are using some other code not the above one.

    • yes i am having different codes. i am using interrupt. since arduino loop function is very slow. because it has other code executed because of translating the code. it will affect the code inside the loop like speed.

      • OK, but make sure the pillars on each waveform does not exceed 6, but anyway your issue is current(amp) related not waveform.

  12. :100000000C946C000C9494000C9494000C94940048
    :100010000C9494000C9494000C9494000C94940010
    :100020000C9494000C9494000C9494000C94940000
    :100030000C9494000C94EE030C9494000C94940093
    :100040000C94A4030C9494000C9472030C944C0331
    :100050000C9494000C9494000C9494000C949400D0
    :100060000C9494000C94940005A84CCDB2D44EB9D5
    :100070003836A9020C50B9918688083CA6AAAA2A4B
    :10008000BE000000803F00000008000201000003E5
    :100090000407000000000000000000000000250030
    :1000A00028002B0000000000240027002A00040480
    :1000B0000404040404040202020202020303030310
    :1000C00003030102040810204080010204081020EC
    :1000D000010204081020B50411241FBECFEFD8E0A0
    :1000E000DEBFCDBF11E0A0E0B1E0E0E4F2E102C08C
    :1000F00005900D92A033B107D9F726E0A0E3B1E057
    :1001000001C01D92A630B207E1F710E0CCE6D0E0C6
    :1001100004C02197FE010E941309CB36D107C9F70D
    :100120000E9401050C941E090C94000090E0FC0153
    :10013000EE53FF4F2491FC01E255FF4F8491882339
    :1001400099F090E0880F991FFC01EC55FF4FA591A5
    :10015000B491FC01E656FF4F859194918FB7F894C6
    :10016000EC91E22BEC938FBF0895CF92DF92EF9248
    :10017000FF920F931F93CF93DF936C017A018B0152
    :10018000C0E0D0E0CE15DF0589F0D8016D918D017A
    :10019000D601ED91FC910190F081E02DC601099509
    :1001A000892B11F47E0102C02196ECCFC701DF91AB
    :1001B000CF911F910F91FF90EF90DF90CF90089516
    :1001C000FC01538D448D252F30E0842F90E0821B5D
    :1001D000930B541710F0CF96089501970895FC01E2
    :1001E000918D828D981761F0828DDF01A80FB11D6E
    :1001F0005D968C91928D9F5F9F73928F90E0089592
    :100200008FEF9FEF0895FC01918D828D981731F04B
    :10021000828DE80FF11D858D90E008958FEF9FEF9F
    :100220000895FC01918D228D892F90E0805C9F4F75
    :10023000821B91098F739927089581E595E00E94AB
    :10024000110121E0892B09F420E0822F0895FC019F
    :10025000848DDF01A80FB11DA35ABF4F2C91848D4F
    :1002600090E001968F739927848FA689B7892C9384
    :10027000A089B1898C9180648C93938D848D98131F
    :1002800006C00288F389E02D80818F7D80830895E8
    :10029000EF92FF920F931F93CF93DF93EC0181E0D6
    :1002A000888F9B8D8C8D981305C0E889F989808192
    :1002B00085FD24C0F62E0B8D10E00F5F1F4F0F73CE
    :1002C0001127E02E8C8DE8120CC00FB607FCFACF78
    :1002D000E889F989808185FFF5CFCE010E94270149
    :1002E000F1CF8B8DFE01E80FF11DE35AFF4FF08235
    :1002F0000B8FEA89FB898081806207C0EE89FF89C4
    :100300006083E889F98980818064808381E090E05E
    :10031000DF91CF911F910F91FF90EF900895CF93B0
    :10032000DF93EC01888D8823C9F0EA89FB898081FD
    :1003300085FD05C0A889B9898C9186FD0FC00FB6CF
    :1003400007FCF5CF808185FFF2CFA889B9898C9110
    :1003500085FFEDCFCE010E942701E7CFDF91CF913E
    :10036000089580E090E0892B29F00E941D01811101
    :100370000C940000089590E0FC01EA57FF4F34917F
    :10038000FC01EE53FF4F2491FC01E255FF4FE49135
    :10039000EE2309F43BC0332339F1333091F038F4C4
    :1003A0003130A9F0323001F584B58F7D12C037307D
    :1003B00091F03830A1F03430B9F4809180008F7D15
    :1003C00003C0809180008F77809380000DC084B53A
    :1003D0008F7784BD09C08091B0008F7703C0809172
    :1003E000B0008F7D8093B000F0E0EE0FFF1FE65667
    :1003F000FF4FA591B4918FB7F894EC91611103C0B0
    :1004000020952E2301C02E2B2C938FBF0895CF93C0
    :10041000DF93EC0160E08E810E94BB0161E08E8180
    :100420000E94BB0160E08E810E94BB018BE891E0DD
    :100430000197F1F7DF91CF910895CF92DF92EF927C
    :10044000FF920F931F93CF93DF937C016C0187E0A2
    :10045000C80ED11CC0E0D0E0062F10E0B8010C2E71
    :1004600002C0759567950A94E2F76170F601819173
    :100470006F010E94BB012196C430D10579F7C701F5
    :10048000DF91CF911F910F91FF90EF90DF90CF9070
    :100490000C940702CF92DF92EF92FF920F931F937B
    :1004A000CF93DF93EC01F62E642F8C810E94BB0169
    :1004B0008D818F3F19F060E00E94BB018F850F2D69
    :1004C00010E084FF25C06E0187E0C80ED11CE12C2E
    :1004D000F12CB8010E2C02C0759567950A94E2F7CD
    :1004E0006170F60181916F010E94BB01FFEFEF1A6D
    :1004F000FF0A88E0E816F10461F7CE01DF91CF91A1
    :100500001F910F91FF90EF90DF90CF900C94070216
    :10051000B80184E0759567958A95E1F7CE010E9450
    :100520001D026F2DCE01DF91CF911F910F91FF9092
    :10053000EF90DF90CF900C941D0241E00E944A02A0
    :1005400081E090E0089540E00C944A02EF92FF921F
    :100550000F931F93CF93DF93EC01423018F08F85F8
    :1005600088608F874B8B1C8A80E48D8B6E8B70E04C
    :10057000605C7F4F6F8B8C810E9496008D818F3FD6
    :1005800011F00E9496008E810E9496007E0187E005
    :10059000E80EF11C00E010E08F8584FD03C084E0CC
    :1005A00090E002C088E090E00817190744F4F701D2
    :1005B00081917F010E9496000F5F1F4FEDCF8BE36B
    :1005C0009DE00197F1F760E08C810E94BB0160E043
    :1005D0008E810E94BB018D818F3F19F060E00E94E7
    :1005E000BB016F8564FD1DC063E0CE010E941D024A
    :1005F0000BE416E4C8010197F1F763E0CE010E9415
    :100600001D02C8010197F1F763E0CE010E941D02AF
    :1006100083E592E00197F1F762E0CE010E941D02AE
    :1006200016C06062CE010E94A3028BE496E401979B
    :10063000F1F76F856062CE010E94A30283E592E02C
    :100640000197F1F76F856062CE010E94A3026F856A
    :100650006062CE010E94A30284E0888B6CE0CE0130
    :100660000E94A30261E0CE010E94A3028BE39FE1FE
    :100670000197F1F782E0898B66E0CE01DF91CF919F
    :100680001F910F91FF90EF900C94A302089580E0CA
    :1006900090E008950E9419091F920F920FB60F92D1
    :1006A00011242F933F934F935F936F937F938F9377
    :1006B0009F93AF93BF93EF93FF9381E595E00E94E3
    :1006C0002701FF91EF91BF91AF919F918F917F9102
    :1006D0006F915F914F913F912F910F900FBE0F90AF
    :1006E0001F9018951F920F920FB60F9211242F93FF
    :1006F0008F939F93EF93FF93E0916105F0916205D3
    :100700008081E0916705F091680582FD12C09081BB
    :1007100080916A058F5F8F7320916B05821751F06E
    :10072000E0916A05F0E0EF5AFA4F958F80936A05E1
    :1007300001C08081FF91EF919F918F912F910F9038
    :100740000FBE0F901F9018951F920F920FB60F9229
    :1007500011242F933F938F939F93AF93BF938091D7
    :100760004D0590914E05A0914F05B09150053091E7
    :100770003E0123E0230F2D3720F40196A11DB11D6A
    :1007800005C026E8230F0296A11DB11D20933E014E
    :1007900080934D0590934E05A0934F05B09350055F
    :1007A00080913A0190913B01A0913C01B0913D01B3
    :1007B0000196A11DB11D80933A0190933B01A09336
    :1007C0003C01B0933D01BF91AF919F918F913F91BB
    :1007D0002F910F900FBE0F901F9018951F920F92A0
    :1007E0000FB60F921124CF92DF92EF92FF922F93C8
    :1007F0003F934F935F936F937F938F939F93AF93A9
    :10080000BF93EF93FF93409143055091440560914E
    :100810004505709146058091360190913701A09170
    :100820003801B0913901840F951FA61FB71F80931F
    :10083000360190933701A0933801B093390120918C
    :100840003501213059F49091020180EA8927809383
    :10085000020180938000109235012AC0409131013D
    :10086000509132016091330170913401442777FD3A
    :1008700043955527662777276C017D01CC24F7FC2B
    :10088000C394DD24EE24FF24C416D506E606F7063D
    :1008900079F0B7FD0DC02F5F2093350161E08091A5
    :1008A0003001811160E0609330018DE00E94BB0156
    :1008B0008091360190913701A0913801B0913901B2
    :1008C0008093310190933201A0933301B0933401AE
    :1008D00027E1B695A795979587952A95D1F7880F23
    :1008E000991FFC01E15CFE4FA081B18120913F0581
    :1008F0003091400540914105509142050E94A1066A
    :100900009B01AC016CE055954795379527956A9505
    :10091000D1F7A0910001B09101010E94AC06DC0169
    :10092000CB017AE0B595A795979587957A95D1F7FC
    :1009300090938B0080938A00909389008093880025
    :10094000FF91EF91BF91AF919F918F917F916F91A7
    :100950005F914F913F912F91FF90EF90DF90CF905B
    :100960000F900FBE0F901F901895E1E5F5E01382F0
    :10097000128288EE93E0A0E0B0E084839583A683A2
    :10098000B78387E091E09183808385EC90E0958741
    :10099000848784EC90E09787868780EC90E0918B49
    :1009A000808B81EC90E0938B828B82EC90E0958B36
    :1009B000848B86EC90E0978B868B118E128E138E33
    :1009C000148EEEEEF5E01382128289E191E09183BC
    :1009D000808387E084838FEF858386E0868385E04C
    :1009E000878384E0808783E0818782E08287138623
    :1009F000148615861686178641E060E1CF010C94B7
    :100A0000A602CF93DF93CDB7DEB7A1970FB6F894C8
    :100A1000DEBF0FBECDBF789484B5826084BD84B53F
    :100A2000816084BD85B5826085BD85B5816085BDE9
    :100A300080916E00816080936E00109281008091A1
    :100A40008100826080938100809181008160809329
    :100A50008100809180008160809380008091B1004E
    :100A600084608093B1008091B00081608093B00079
    :100A700080917A00846080937A0080917A0082600D
    :100A800080937A0080917A00816080937A008091CF
    :100A90007A00806880937A001092C100E09161052D
    :100AA000F091620592E09083E0915D05F0915E0522
    :100AB0001082E0915F05F09160058FEC80831092C9
    :100AC0006905E0916505F091660586E08083E09117
    :100AD0006305F0916405808180618083E091630506
    :100AE000F0916405808188608083E0916305F091D6
    :100AF0006405808180688083E0916305F0916405DE
    :100B000080818F7D8083F894909380005FE3C52E71
    :100B100051E0D52E00E010E0B801012E000C880B4A
    :100B2000990B0E948A072BED3FE049E450E40E94B4
    :100B3000160820E030E040E05BE30E9416080E94C7
    :100B4000830820E030E040E855E40E94160820E0E9
    :100B500030E040E05FE30E94E6060E945207F601A3
    :100B6000619371936F010F5F1F4F0115F2E01F0733
    :100B700099F6809102018093800078948CE390E054
    :100B800090934C0580934B05609147057091480503
    :100B90008091490590914A050E9459079B01AC013B
    :100BA000ACE3B0E00E94A106609343057093440556
    :100BB000809345059093460580E094E09093010171
    :100BC00080930001809102018093800089E18093ED
    :100BD000810081E080936F008091B100887F816007
    :100BE0008093B100789486E084B98DE00E949600ED
    :100BF00044E064E18EEE95E00E94A6024DE050E0F4
    :100C000061E271E08EEE95E00E94B50081E9282E48
    :100C100080E0382E94E6C92ED12C24E6F22E38EE50
    :100C2000432E33E0532E612C712C4AE0842E912CFC
    :100C3000A12CB12C8BE00E949600F10184918330AD
    :100C4000F9F048F48130B9F08230A1F584B58062C2
    :100C500084BDF8BC33C08730E9F0883019F18430A6
    :100C600049F580918000806280938000D0928B0053
    :100C7000C0928A0023C084B5806884BDF7BC1EC0C2
    :100C800080918000806880938000D0928900C0921B
    :100C9000880014C08091B00080688093B000F0920A
    :100CA000B3000CC08091B00080628093B000F092DD
    :100CB000B40004C060E08BE00E94BB01E09101063B
    :100CC000E23010F4E15001C0E1E0F0E0E251FA4F0F
    :100CD000648960688EEE95E00E94A3022FB7F894B5
    :100CE00060914D0570914E0580914F059091500592
    :100CF0002FBFA30192010E94B40619A28E010F5DBD
    :100D00001F4FCA01B901A50194010E94B406605D9C
    :100D1000F80162938F01211531054105510589F7CD
    :100D2000309761F001900020E9F73197AF01401B47
    :100D3000510BB8018EEE95E00E94B5000E94B10102
    :100D400079CF0E94D606A59F900DB49F900DA49FC9
    :100D5000800D911D11240895B7FF0C94A1060E94E7
    :100D6000A106821B930B0895A1E21A2EAA1BBB1B9E
    :100D7000FD010DC0AA1FBB1FEE1FFF1FA217B30767
    :100D8000E407F50720F0A21BB30BE40BF50B661F7D
    :100D9000771F881F991F1A9469F760957095809541
    :100DA00090959B01AC01BD01CF010895A29FB001B8
    :100DB000B39FC001A39F700D811D1124911DB29F8F
    :100DC000700D811D1124911D08955058BB27AA272D
    :100DD0000E94FD060C94DC070E94CE0738F00E94AA
    :100DE000D50720F039F49F3F19F426F40C94CB0773
    :100DF0000EF4E095E7FB0C94C507E92F0E94ED0780
    :100E000058F3BA17620773078407950720F079F43F
    :100E1000A6F50C940F080EF4E0950B2EBA2FA02D1A
    :100E20000B01B90190010C01CA01A0011124FF2797
    :100E3000591B99F0593F50F4503E68F11A16F04092
    :100E4000A22F232F342F4427585FF3CF4695379591
    :100E50002795A795F0405395C9F77EF41F16BA0B56
    :100E6000620B730B840BBAF09150A1F0FF0FBB1F04
    :100E7000661F771F881FC2F70EC0BA0F621F731F4D
    :100E8000841F48F4879577956795B795F7959E3FAA
    :100E900008F0B0CF9395880F08F09927EE0F97953B
    :100EA000879508950E9459076894B1110C94100811
    :100EB00008950E94F50788F09F5798F0B92F992759
    :100EC000B751B0F0E1F0660F771F881F991F1AF035
    :100ED000BA95C9F714C0B13091F00E940F08B1E083
    :100EE00008950C940F08672F782F8827B85F39F082
    :100EF000B93FCCF3869577956795B395D9F73EF4CE
    :100F000090958095709561957F4F8F4F9F4F089575
    :100F1000E89409C097FB3EF4909580957095619593
    :100F20007F4F8F4F9F4F9923A9F0F92F96E9BB2749
    :100F30009395F695879577956795B795F111F8CFC5
    :100F4000FAF4BB0F11F460FF1BC06F5F7F4F8F4F30
    :100F50009F4F16C0882311F096E911C0772321F026
    :100F60009EE8872F762F05C0662371F096E8862FBE
    :100F700070E060E02AF09A95660F771F881FDAF715
    :100F8000880F9695879597F9089597F99F6780E858
    :100F900070E060E008959FEF80EC089500240A94CB
    :100FA0001616170618060906089500240A94121644
    :100FB0001306140605060895092E0394000C11F477
    :100FC000882352F0BB0F40F4BF2B11F460FF04C024
    :100FD0006F5F7F4F8F4F9F4F089557FD9058440F7D
    :100FE000551F59F05F3F71F04795880F97FB991F88
    :100FF00061F09F3F79F08795089512161306140645
    :10100000551FF2CF4695F1DF08C0161617061806D1
    :10101000991FF1CF86957105610508940895E894AC
    :10102000BB2766277727CB0197F908950E942908E7
    :101030000C94DC070E94CE0738F00E94D50720F000
    :10104000952311F00C94C5070C94CB0711240C9434
    :1010500010080E94ED0770F3959FC1F3950F50E0C3
    :10106000551F629FF001729FBB27F00DB11D639F5A
    :10107000AA27F00DB11DAA1F649F6627B00DA11D00
    :10108000661F829F2227B00DA11D621F739FB00DA6
    :10109000A11D621F839FA00D611D221F749F332716
    :1010A000A00D611D231F849F600D211D822F762FAF
    :1010B0006A2F11249F5750409AF0F1F088234AF08C
    :1010C000EE0FFF1FBB1F661F771F881F91505040F8
    :1010D000A9F79E3F510580F00C94C5070C941008A9
    :1010E0005F3FE4F3983ED4F3869577956795B7957F
    :1010F000F795E7959F5FC1F7FE2B880F911D969599
    :10110000879597F908959F930E948D080F9007FC8B
    :10111000EE5F0C94B6080C94CB070E94F507D8F349
    :10112000E894E0E0BB279F57F0F02AED3FE049EC60
    :1011300006C0EE0FBB0F661F771F881F28F0B23A5C
    :1011400062077307840728F0B25A620B730B840B93
    :10115000E3959A9572F7803830F49A95BB0F661F25
    :10116000771F881FD2F790480C94CC08EF93E0FFCC
    :1011700007C0A2EA2AED3FE049EC5FEB0E94FD06C2
    :101180000E94DC070F90039401FC9058E8E6F0E021
    :101190000C94D8089F3F31F0915020F487957795B3
    :1011A0006795B795880F911D9695879597F908953E
    :1011B0009F938F937F936F93FF93EF939B01AC016A
    :1011C0000E941608EF91FF910E94EC082F913F9129
    :1011D0004F915F910C941608DF93CF931F930F9359
    :1011E000FF92EF92DF927B018C01689406C0DA2EA9
    :1011F000EF010E942908FE01E894A59125913591FF
    :1012000045915591A6F3EF010E94FD06FE0197015D
    :10121000A801DA9469F7DF90EF90FF900F911F918A
    :10122000CF91DF910895EE0FFF1F0590F491E02D0F
    :10123000099481E090E0F8940C941E09F894FFCF93
    :10124000000482000000004801B500E0008F011199
    :1012500001EF000301000000009D02B500470346B6
    :101260000368656C6C6F2C20776F726C64210000D2
    :00000001FF

    high swatagam, could you help me designing an filter for this?
    here is my spwm, i used arduino uno. could you try simulate?
    switching freq is 31Khz
    freq:60 Hz

    • Hi Isak, I am sorry I am not good at simulating circuits, since I mostly depend on my brain simulation for all my designs.

        • Hi Isak, that looks misleading, that’s why I never depend on simulators….if you check it practically you will find that a much smaller capacitor doing the job perfectly, because the transformer secondary itself will act like a filter and to a great extent smoothen the waveform even without a capacitor…

          by the way you can try putting a load in the simulation and check the effect

        • its hard to tell weather i put a right caps because i don’t have oscilloscope. i tried this with 2.2uf and it can run the stand fan. but not at great speed. i think it is not smooth as i expect because trying to switch at low speed the fan turn at very low speed. tried to compare the output at the grid. it has a big difference.

          • i can use an 8v – 230v transformer since i have a high switching frequency. now i set it to 30KHz. voltage drop is not much the problem.. the transformer is just a salvage from old ups. my code can change amplitude so that i can stabilize the voltage output. i can also change the switching frequency while system is running. but the main problem is the filter for 230 out.

            • you mean to say instead of 50Hz or 60Hz you are using 30kHz for driving the fan? That’s highly not recommended, and moreover the current consumption is the main aspect, check your battery current it must fulfill the fan’s rated consumption.

              your transformer output must produce an AC that matches your grid AC characteristic in every respect.

    • could you please throw some light regarding how this modification would help to improve the performance of the PWM output, I am sure the readers will love to know about it.

  13. // Some changes made by Atton Risk for Swagatam
    const int sPWMArray[] = {500,500,750,500,1250,500,2000,500,1250,500,750,500,500}; // This is the array with the SPWM values change them at will
    const int sPWMArrayValues = 13; // You need this since C doesn’t give you the length of an Array
    // The pins
    const int sPWMpin1 = 8;
    const int sPWMpin2 = 9;
    // The pin switches
    bool sPWMpin1Status = true;
    bool sPWMpin2Status = true;

    void setup()
    {
    pinMode(sPWMpin1, OUTPUT);
    pinMode(sPWMpin2, OUTPUT);
    }

    void loop()
    {
    // Loop for pin 1
    for(int i(0); i != sPWMArrayValues; i++)
    {
    if(sPWMpin1Status)
    {
    digitalWrite(sPWMpin1, HIGH);
    delayMicroseconds(sPWMArray[i]);
    sPWMpin1Status = false;
    }
    else
    {
    digitalWrite(sPWMpin1, LOW);
    delayMicroseconds(sPWMArray[i]);
    sPWMpin1Status = true;
    }
    }

    // Loop for pin 2
    for(int i(0); i != sPWMArrayValues; i++)
    {
    if(sPWMpin1Status)
    {
    digitalWrite(sPWMpin1, HIGH);
    delayMicroseconds(sPWMArray[i]);
    sPWMpin1Status = false;
    }
    else
    {
    digitalWrite(sPWMpin1, LOW);
    delayMicroseconds(sPWMArray[i]);
    sPWMpin1Status = true;
    }
    }
    }

    • Thank you very much Atton, I hope the readers will benefit immensely from this information! I appreciate it a lot!

    • for(int i(0); i != sPWMArrayValues; i++)
      {
      if(sPWMpin1Status)
      {
      digitalWrite(sPWMpin1, HIGH);
      delayMicroseconds(sPWMArray[i]);
      sPWMpin1Status = false;
      }
      else
      {
      digitalWrite(sPWMpin1, LOW);
      delayMicroseconds(sPWMArray[i]);
      sPWMpin1Status = true;
      }
      }

      In this code , I think LOW and HIGH should be interchanged.
      Because at the starting of the sine wave we have a small voltage .

  14. Halo sir.

    I will try your code and the driver as pure sine wave inverter.
    If I successful to make it, may I re-post this article?
    at least for arduino code only.

    Thank you.
    Yogi S.

    • Hello Yoyo,
      you can submit the details to me, I'll post it in the above article with your credentials in it, but if you use it for your own website then that could be a copyright violation….

  15. Hi,
    as per the given code pin8/9 will alternately produce SPWM pulses at the rate of 50Hz. The total delay periods across the two pins are calculated to produce 50Hz frequency

    The SPWM waveform rate (delays) is arbitrarily set in the code, you can tweak it to create a different RMS value depending upon your transformers primary voltage rating.

    alternatively the Arduino code could be further upgraded for responding to a feedback from the transformer output and for achieving an automatic RMS adjustment

  16. Hi sir,

    Its good to see you involving in arduino projects, I hope you will soon master in this field too 🙂

    I would like to point some errors in the code:

    1) we must not use pin 13 in arduino, unless we run out of pins, since it is always connected with LED, it will deviate our results. we can use other pins say 8 and 9.

    2) we cannot use delay for less than 1ms and we can't use decimal place in delay function like delay(1.25); . Instead use delayMicroseconds(); for instance delayMicroseconds(500); for 500us and delayMicroseconds(1250); for 1.25ms. You may replace all delay with this function.

    The above errors won't show up while compiling but, it affects our end result.

    Regards

    • Thank you Girish,

      Although I hardly find time, I did this just to have some fun … 🙂

      I will surely correct the above code as per your suggestions, as soon as possible..

      I appreciate your help very much and I am sure the readers will also get an opportunity to learn from this discussion.

      Thanks again, and keep up the good work!

Comments are closed.

Do NOT follow this link or you will be banned from the site!